Monday 18 May 2015

Eastings/Northings to LatLngs conversion

The remit here is to take Eastings/Northings (A UK based Ordnance Survey Gridreferencing system) and convert to LatLngs (the grid-referencing done by most GPS systems, and most importantly, Google Maps).

The algorithms for doing these conversions are here, and the accompanying guide I found really interesting. Basically, it comes down to Eastings/Northings are based on a 2-dimensional grid (assuming that England is roughly flat), but LatLngs are based on a 3-dimensional sphere (I'm looking at you, planet Earth...)

This call for me had the perfect storm of lots of complicated maths, knowledge of 2 programming languages, and the sexy prospect of overlaying the results on Google Maps. 

Total trophy moment when I got it to work....

*&---------------------------------------------------------------------*
*& Report  YPD_PL1_LATLNG
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  YPD_PL1_LATLNG.


datapi type f,
      radPHI0 type f,
      radLAM0 type f,
      af0 type f,
      bf0 type f,
      e2 type f,
      Et type f,
      phi0 type f,
      lam0 type f,
      w_deciPhi0 type f,
      w_DeciLam0 type f,
      o_lat type f,
      o_lng type f.


constantsc_a type value '6377563.396',
           c_b type value '6356256.909',
           c_e0 type value '400000',
           c_n0 type value '100000-',
           c_f0 type value '0.9996012717',
           c_deciPhi0 type value '49.00000000',
           c_deciLam0 type value '2.00000000-',
           c_Phi0 type VALUE '0.855211333',
           C_Lam0 type value '0.034906585-'.

parametersp_east type int4 default '359536',
            p_north type int4 default '403646'.


start-of-selection.

write'East:'p_east', North'p_north.


perform initialise_vars.
perform E_N_to_LAT using p_east p_north c_n0 c_f0 changing o_lat.
perform E_N_to_LNG using p_east p_north c_n0 c_f0 changing o_lng.


form E_N_to_Lat using p_East type int4
                          p_North type int4
                          p_n0 type f
                          p_f0 type f
                 changing e_n_to_lat type f.

dataaf0 type f,
      bf0 type f,
      e2 type f,
      n type f,
      Et type f,
      VII type f,
      VIII type f,
      IX type f,
      PHid type f,
      nu type f,
      rho type f,
      eta2 type f.


*'Un-project Transverse Mercator eastings and northings back to latitude.
*'Input: - _
* eastings (East) and northings (North) in meters; _
* ellipsoid axis dimensions (a & b) in meters; _
* eastings (e0) and northings (n0) of false origin in meters; _
* central meridian scale factor (f0) and _
* latitude (PHI0) and longitude (LAM0) of false origin in decimal degrees.

"'REQUIRES THE "Marc" AND "InitialLat" FUNCTIONS



*'Compute af0, bf0, e squared (e2), n and Et
    af0 c_a * p_f0.
    bf0 c_b * p_f0.
    e2 af0 ** bf0 ** af0 ** .
    n af0 bf0 af0 + bf0 ).
    Et p_East c_e0.

*'Compute initial value for latitude (PHI) in radians
  perform InitialLat using p_north c_n0 af0 RadPHI0 n bf0 changing PHId.



*'Compute nu, rho and eta2 using value for PHId
    nu af0 / Sqrte2 * SinPHId )  ** ).
    rho nu * e2 )  e2 * SINPHId ** ).
    eta2 nu / rho 1.

*'Compute Latitude
    VII TanPHId * rho * nu ).
    VIII TanPHId 24 * rho * nu ** TanPHId ** + eta2 * eta2 * TanPHId ** ).
    IX TanPHId )  720 * rho * nu ** 61 90 TanPHId )  ** 45 TanPHId ** ).

    E_N_to_Lat 180 / Pi PHId Et ** * VII Et ** * VIII Et ** * IX ).

  WRITE:'Lat Calculation'.
  write:'Lat:'e_n_to_lat.
  write:'VII'VII.
  write:'IX'IX.


endform.



form initialise_vars.

    Pi '3.14159265358979' .

"Convert angle measures to radians
    RadPHI0 c_DeciPhi0 * Pi / 180 ).
    RadLAM0 c_DeciLam0 * Pi / 180 ).


endform.


form marc using p_bf0 type f
                   p_n type f
                   p_phi0 type f
                   p_phi type f
          changing p_marc type f.

  dataphi_minus_phi0 type f,
        phi_plus_phi0 type f,
        phi_minus_phi0_times_2 type f,
        phi_plus_phi0_times_2 type f,
        phi_minus_phi0_times_3 type f,
        phi_plus_phi0_times_3 type f.

  datal_test1 type f,
        l_line1 type f,
        l_line2 type f,
        l_line3 type f,
        l_line4 type f.

  DATAL_MARC2 TYPE F.

"Copied from VB Macro Calculation; They can nest function calculations, ABAP can't... stupid ABAP.
  phi_minus_phi0 p_phi p_phi0.
  phi_plus_phi0 p_phi + p_phi0.
  phi_minus_phi0_times_2 phi_minus_phi0 * 2.
  phi_plus_phi0_times_2 phi_plus_phi0 * 2.
  phi_minus_phi0_times_3 phi_minus_phi0 * 3.
  phi_plus_phi0_times_3 phi_plus_phi0 * 3.

  l_test1 SinPhi_minus_phi0 ).

    l_line1 p_bf0.
    l_line1 + p_n + p_n ** p_n ** p_PHI p_PHI0 ).
    l_line2 * p_n p_n ** 21 p_n ** Sinphi_minus_phi0 COSphi_plus_phi0 ).
    l_line3 15 p_n ** 15 p_n ** Sinphi_minus_phi0_times_2 Cosphi_plus_phi0_times_2 ).
    l_line4 35 24 p_n ** Sinphi_minus_phi0_times_3 )  Cosphi_plus_phi0_times_3 ).

*    Marc = bf0 * (((1 + n + ((5 / 4) * (n ^ 2)) + ((5 / 4) * (n ^ 3))) * (PHI - PHI0)) _
*    - (((3 * n) + (3 * (n ^ 2)) + ((21 / 8) * (n ^ 3))) * (Sin(PHI - PHI0)) * (Cos(PHI + PHI0))) _
*    + ((((15 / 8) * (n ^ 2)) + ((15 / 8) * (n ^ 3))) * (Sin(2 * (PHI - PHI0))) * (Cos(2 * (PHI + PHI0)))) _
*    - (((35 / 24) * (n ^ 3)) * (Sin(3 * (PHI - PHI0))) * (Cos(3 * (PHI + PHI0)))))


L_MARC2 p_bf0 * l_line1 l_line2 + l_line3 l_line4 ).

p_marc l_marc2.

*      p_Marc = p_bf0 * ( ( ( 1 + p_n + ( ( 5 / 4 ) * ( p_n ** 2 ) ) + ( ( 5 / 4 ) * ( p_n ** 3 ) ) ) * ( p_PHI - PHI0 ) )
*    - ( ( ( 3 * p_n ) + ( 3 * ( p_n ** 2 ) ) + ( ( 21 / 8 ) * ( p_n ** 3 ) ) ) * ( Sin( phi_minus_phi0 ) ) * ( COS( phi_plus_phi0 ) ) )
*    + ( ( ( ( 15 / 8 ) * ( p_n ** 2 ) ) + ( ( 15 / 8 ) * ( p_n ** 3 ) ) ) * ( Sin( phi_minus_phi0_times_2 ) ) * ( Cos( phi_plus_phi0_times_2 ) ) )
*    - ( ( ( 35 / 24 ) * ( p_n ** 3 ) ) * ( Sin( phi_minus_phi0_times_3 ) )  * ( Cos( phi_plus_phi0_times_3 ) ) ) ) .




endform.


form InitialLat using p_North type int4
                      p_n0 type f
                      P_afo type f
                      p_PHI0 type f
                      p_n type f
                      p_bfo type f
               changing p_InitialLat type f.

*'Compute initial value for Latitude (PHI) IN RADIANS.
*'Input: - _
* northing of point (North) and northing of false origin (n0) in meters; _
* semi major axis multiplied by central meridian scale factor (af0) in meters; _
* latitude of false origin (PHI0) IN RADIANS; _
* n (computed from a, b and f0) and _
* ellipsoid semi major axis multiplied by central meridian scale factor (bf0) in meters.

*'REQUIRES THE "Marc" FUNCTION
*'THIS FUNCTION IS CALLED BY THE "E_N_to_Lat", "E_N_to_Long" and "E_N_to_C" FUNCTIONS
*'THIS FUNCTION IS ALSO USED ON IT'S OWN IN THE  "Projection and Transformation Calculations.xls" SPREADSHEET

datal_phi1 type f,
      l_phi2 type f,
      type f,
      delta type f,
      l_myCounter type f.

"First PHI value (PHI1)
    l_PHI1 p_North p_n0 / p_afo + P_PHI0.

*'Calculate M
    perform marc using p_bfo
                       p_n
                       p_phi0
                       l_phi1
               changing M.


*'Calculate new PHI value (PHI2)
    l_PHI2 p_North p_n0 / p_afo + l_PHI1.

*'Iterate to get final value for InitialLat

    Do 10000 times.       "Prevent Infinity.
      delta p_North p_n0 M.
      if ABSdelta '0.00001'.
        exit.
      endif.

        l_PHI2 (  DELTA  / P_afo + l_PHI1.

    perform marc using p_bfo
                       p_n
                       p_phi0
                       l_phi2
               changing M.


        l_PHI1 l_PHI2.
        l_myCounter l_myCounter + 1.
    enddo.

    p_InitialLat l_PHI2.

endform.

form E_N_to_LNG using p_East type int4
                          p_North type int4
                          p_n0 type f
                          p_f0 type f
                 changing e_n_to_lng type f.


"Un-project Transverse Mercator eastings and northings back to longitude.

dataaf0 type f,
      bf0 type f,
      e2 type f,
      n type f,
      Et type f,
      VII type f,
      VIII type f,
      IX type f,
      PHid type f,
      nu type f,
      rho type f,
      eta2 type f,
      type f,
      XI type f,
      XII type f,
      XIIA type f.


"Compute af0, bf0, e squared (e2), n and Et
    af0 c_a * p_f0.
    bf0 c_b * p_f0.
    e2 af0 ** bf0 ** af0 ** ).
    n af0 bf0 af0 + bf0  ).
    Et p_East c_e0.

*'Compute initial value for latitude (PHI) in radians
  perform InitialLat using p_north c_n0 af0 RadPHI0 n bf0 changing PHId.

*'Compute nu, rho and eta2 using value for PHId
    nu af0 / Sqrte2 * SinPHId )  ** ).
    rho nu * e2 )  e2 * SINPHId ** ).
    eta2 nu / rho 1.

" Compute Longitude
    CosPHId ** -/ nu.
    XI CosPHId ** -nu ** nu / rho TanPHId ** ).
    XII CosPHId ** -120 nu ** 28 TanPHId ** 24 TanPHId ** ).
    XIIA CosPHId ** -5040 nu ** 61 662 TanPHId ** 1320 TanPHId ** 720 TanPHId ** ).

    E_N_to_Lng 180 / Pi RadLAM0 + Et * Et ** * XI Et ** * XII Et ** * XIIA ).

  WRITE:'Lng Calculation'.
  write:'Lat:'e_n_to_lng.

Endform.

Friday 15 May 2015

Multiple Payment / Clearing of FI Documents

In trying to find the equivalent of F-28, with the most promising best result being this one I've got a program that now can perform clearing of multiple invoices... It reads in a file with Invoice#s and Payment amounts, creates payment documents, then clears them against the SumTotalled Incoming Payment.

Header program here:

REPORT  YPD_INV_PAY_DEV.

include YPD_INV_PAY_DEV_data.
include YPD_INV_PAY_DEV_sels.

start-of-selection.
  perform load_file.

"PD- this was the bit that did the process / clearing incrementally....
*  loop at lt_remittance_file into ls_remittance_file.
*      perform process_payment.
*      IF p_clear = 'X'.
*        perform do_clearing.
*      endif.
*  endloop.



  loop at lt_remittance_file into ls_remittance_file.
      perform process_payment.
  endloop.

  append ls_currencyamount1 to it_currencyamount.
  append ls_currencyamount2 to it_currencyamount.

perform call_bapi using '15'.

commit work and wait.

wait up to seconds.

      IF p_clear 'X'.
        perform do_clearing2.
      endif.


include YPD_INV_PAY_DEV_forms.


---------------------------------------------------------------------------------------
include YPD_INV_PAY_DEV_data.

dataw_bsid type bsid.


data:
  gd_documentheader    like bapiache09,
  gd_customercpd       like bapiacpa09,
  gd_fica_hd           like bapiaccahd,
  it_accountreceivable like table of bapiacar09 with header line,
  it_accountgl         like table of bapiacgl09 with header line,
  it_accounttax        like table of bapiactx09 with header line,
  it_criteria          like table of bapiackec9 with header line,
  it_valuefield        like table of bapiackev9 with header line,
  it_currencyamount    like table of bapiaccr09 with header line,
  ls_currencyamount1    type bapiaccr09,
  ls_currencyamount2    type bapiaccr09,

  it_return            like table of bapiret2   with header line,
  it_receivers         like table of bdi_logsys with header line,
  it_fica_it           like table of bapiaccait with header line,
  it_accountpayable    like table of bapiacap09 with header line,
  it_paymentcard       like table of bapiacpc09 with header line,
  it_ext               like table of bapiacextc with header line.
*  it_re                LIKE TABLE OF bapiacre09 WITH HEADER LINE,
*  it_ext2              LIKE TABLE OF bapiparex  WITH HEADER LINE.

  dataw_type like gd_documentheader-obj_type,
        w_key  like gd_documentheader-obj_key,
        w_sys  like gd_documentheader-obj_sys.

  dataw_difference type wrbtr,
        w_overpayment type wdy_boolean.


types:
  begin of ty_li_remittance_file,
    bschl(2)  type c,               "posting key
    belnr(10type c,               "doc number
    wrbtr(17type c,               "amount
    hkont(10type c,               "GL account
    kunnr(10type c,               "customer
    kostl(10type c,               "cost centre
    prctr(10type c,               "profit centre
    zuonr(18type c,               "allocation
    sgtxt(50type c,               "text
  end   of ty_li_remittance_file.


data:
  lt_remittance_file type standard table of ty_li_remittance_file,
  ls_remittance_file type ty_li_remittance_file.


"PD+ for multiple invoice / payment clearances in 1 clearing doc't.
datat_ausz1 type table of ausz1,
      w_ausz1 type ausz1,
      t_ausz2 type table of ausz2,
      w_ausz2 type ausz2.

dataw_bsid2 type bsid,
      w_bkpf type bkpf,
      w_bkpf2 type bkpf,
      l_belnr type belnr_d,
      l_bukrs type bukrs,
      l_gjahr type gjahr.


typesbegin of tty_payments,
        belnr type belnr_d,
        bukrs type bukrs,
        gjahr type gjahr,
       end of tty_payments.

dataw_payments type tty_payments,
      t_payments type table of tty_payments.

dataw_invoices type tty_payments,
      t_invoices type table of tty_payments.



---------------------------------------------------------------------------------------
include YPD_INV_PAY_DEV_sels.

parametersp_bukrs type bukrs default '2000',
*            p_belnr type belnr_d default '1800000016',
            p_gjahr type gjahr default '2015',
            p_hkont type hkont default '113108'.
*            P_AMT TYPE WRBTR default '100.00'.



parameterp_clear type wdy_boolean as checkbox default 'X'.
parametersp_hkontD type hkont default '140000'.



parameterp_file type char80 default 'C:\Users\Patrick.Dean\Desktop\test.txt'.


---------------------------------------------------------------------------------------
include YPD_INV_PAY_DEV_forms.

form do_clearing2.

loop at t_invoices into w_invoices.


select single from bsid into w_bsid where belnr w_invoices-belnr
                                        and gjahr w_invoices-gjahr
                                        and bukrs w_invoices-bukrs.

select single from bkpf into w_bkpf where belnr w_invoices-belnr
                                        and gjahr w_invoices-gjahr
                                        and bukrs w_invoices-bukrs.
check sy-subrc 0.

"Invoice
move-corresponding w_bsid to w_AUSZ1.
move-corresponding w_bkpf to w_ausz1.

w_ausz2-aktio 'A'.
append w_AUSZ1 to T_AUSZ1.

endloop.

loop at t_payments into w_payments.

select single into w_bsid2 from bsid where belnr w_payments-belnr
                                         and bukrs w_payments-bukrs
                                         and gjahr w_payments-gjahr.
  check sy-subrc 0.

select single from bkpf into w_bkpf2 where belnr w_bsid2-belnr
                                         and gjahr w_bsid2-gjahr
                                         and bukrs w_bsid2-bukrs.


clearw_ausz1w_ausz2.
move-corresponding w_bsid2 to w_AUSZ1.
move-corresponding w_bkpf2 to w_ausz1.
append w_AUSZ1 to T_AUSZ1.


w_AUSZ2-augbl w_bkpf2-belnr.
w_AUSZ2-augdt w_bkpf2-budat.
w_AUSZ2-BUKRS w_bsid2-BUKRS.
append w_AUSZ2 to T_AUSZ2.

endloop.

  CALL FUNCTION 'CLEAR_DOCUMENTS'
    TABLES
      T_AUSZ1       t_ausz1
      T_AUSZ2       t_ausz2.


COMMIT WORK AND WAIT.


endform.


form process_payment.

datal_wrbtr type wrbtr,
      l_initialised.

select single from bsid into w_bsid where gjahr p_gjahr
                                        and belnr ls_remittance_file-BELNR
                                        and bukrs p_bukrs.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      INPUT         w_bsid-kunnr
    IMPORTING
      OUTPUT        w_bsid-kunnr.


l_wrbtr ls_remittance_file-wrbtr.

if l_initialised is initial.
 perform fill_header.
 perform fill_accountgl using p_hkont.
 perform fill_accountar.
 l_initialised 'X'.
endif.


perform fill_currencyamount using L_WRBTR.



w_invoices-gjahr p_gjahr.
w_invoices-belnr ls_remittance_file-belnr.
w_invoices-bukrs p_bukrs.
append w_invoices to t_invoices.


endform.

form fill_header.

  gd_documentheader-username   sy-uname.
  gd_documentheader-header_txt 'BAPI Test'.               "#EC NOTEXT
  gd_documentheader-comp_code  w_bsid-bukrs.
  gd_documentheader-fisc_year  sy-datum(4).
  gd_documentheader-doc_date   sy-datum.
  gd_documentheader-pstng_date sy-datum.
  gd_documentheader-doc_type   'DZ'.
  gd_documentheader-ref_doc_no 'xxxx'.
  gd_documentheader-bus_act    'RFBU'.

endform.

form fill_accountgl using lp_hkont type hkont.

  REFRESH IT_ACCOUNTGL.

  clear it_accountgl.
  it_accountgl-itemno_acc     1.
  it_accountgl-gl_account     lp_hkont.
  it_accountgl-item_text      'BAPI Test G/L line item'.  "#EC NOTEXT
  it_accountgl-comp_code      w_bsid-bukrs.
  append it_accountgl.

endform.

form fill_accountar.
  REFRESH it_accountreceivable.

 CLEAR it_accountreceivable.
  it_accountreceivable-itemno_acc 2.
  it_accountreceivable-customer   w_bsid-kunnr.
  IT_ACCOUNTRECEIVABLE-PMNTTRMS   w_bsid-zterm.
  IT_ACCOUNTRECEIVABLE-GL_ACCOUNT w_bsid-hkont.
  it_accountreceivable-comp_code w_bsid-bukrs.
 APPEND it_accountreceivable.


endform.                    "fill_accountar


form fill_currencyamount using lp_amt type wrbtr.

  ls_currencyamount1-itemno_acc   1.
  ls_currencyamount1-curr_type    '00'.
  ls_currencyamount1-currency     w_bsid-waers.
  ls_currencyamount1-CURRENCY_ISO w_bsid-waers.
  ls_currencyamount1-amt_doccur   lp_amt + ls_currencyamount1-amt_doccur.


  ls_currencyamount2-itemno_acc   2.
  ls_currencyamount2-curr_type    '00'.
  ls_currencyamount2-currency     w_bsid-waers.
  ls_currencyamount2-CURRENCY_ISO w_bsid-waers.
  ls_currencyamount2-amt_doccur   ls_currencyamount1-amt_doccur  * -1.


endform.

form call_bapi using p_bschl type bschl.

data it_BAPIACEXTC type table of BAPIACEXTC,
         wa_BAPIACEXTC  type BAPIACEXTC.

"     Populate the Extension table
      wa_BAPIACEXTC-field1  'POSTING_KEY'.
      wa_BAPIACEXTC-field2 '2'.            " Item number
      wa_BAPIACEXTC-field3 p_bschl.
      APPEND wa_BAPIACEXTC TO it_BAPIACEXTC.



   call function 'BAPI_ACC_DOCUMENT_POST'
      exporting
        documentheader    gd_documentheader
      importing
        obj_type          w_type
        obj_key           w_key
        obj_sys           w_sys
      tables
        accountgl         it_accountgl
        accountreceivable it_accountreceivable
        currencyamount    it_currencyamount
        extension1        it_BAPIACEXTC
        return            it_return.

commit work and wait.

loop at it_return.
  write:/ it_return-message.
endloop.

w_payments-belnr w_key(10).
w_payments-bukrs w_key+10(4).
w_payments-gjahr w_key+14(4).
append w_payments to t_payments.


endform.


form do_clearing.




  wait up to seconds.



l_belnr w_key(10).
l_bukrs w_key+10(4).
l_gjahr w_key+14(4).

select single into w_bsid2 from bsid where belnr l_belnr
                                         and bukrs l_bukrs
                                         and gjahr l_gjahr.

select single from bkpf into w_bkpf where belnr w_bsid-belnr
                                        and gjahr w_bsid-gjahr
                                        and bukrs w_bsid-bukrs.

select single from bkpf into w_bkpf2 where belnr w_bsid2-belnr
                                         and gjahr w_bsid2-gjahr
                                         and bukrs w_bsid2-bukrs.

"Invoice
move-corresponding w_bsid to w_AUSZ1.
move-corresponding w_bkpf to w_ausz1.

w_ausz2-aktio 'A'.
append w_AUSZ1 to T_AUSZ1.
*append w_AUSZ2 to T_AUSZ2.
*
"Payment
clearw_ausz1w_ausz2.
move-corresponding w_bsid2 to w_AUSZ1.
move-corresponding w_bkpf2 to w_ausz1.
append w_AUSZ1 to T_AUSZ1.

"Difference.

*append w_AUSZ1 to T_AUSZ1.


w_AUSZ2-augbl w_bkpf2-belnr.
w_AUSZ2-augdt w_bkpf2-budat.
w_AUSZ2-BUKRS w_bsid2-BUKRS.
append w_AUSZ2 to T_AUSZ2.

  CALL FUNCTION 'CLEAR_DOCUMENTS'
    TABLES
      T_AUSZ1       t_ausz1
      T_AUSZ2       t_ausz2.


COMMIT WORK AND WAIT.


endform.

form clear_bapi_tabs.
  refreshit_accountglit_accountreceivableit_currencyamountit_return.

endform.

form load_file.

  datal_filename type RLGRAP-FILENAME.

  l_filename p_file.


  call function 'WS_UPLOAD'
    exporting
      filename                      l_filename
      filetype                      'DAT'
    tables
      data_tab                      lt_remittance_file.



commit work and wait.



endform.



---------------------------------------------------------------------------------------


---------------------------------------------------------------------------------------