I create bapi to track the date PO reach full release, since PO release date is only tracked on header change and its takes long time to pull it from SAP directly. To minimize data extracted from CDHDR, only history data of 'ME21N', 'ME22N', 'ME23N', 'ME29N', 'ME28' are pulled. User reporting some release dates of PO is invalid. Debugging shows that some user is approving PO via PR approval page ME54N and ME55.
SELECT objectid changenr udate tcode objectid
into (i_cdhdr-ebeln, i_cdhdr-changenr, i_cdhdr-frgdt, i_cdhdr-tcode, i_cdhdr-objectid)
FROM CDHDR
WHERE udate in p_erdat AND OBJECTCLAS = 'EINKBELEG'
AND TCODE in ('ME21N','ME22N','ME23N','ME29N','ME28','ME54N','ME55').
append i_cdhdr.
endselect.
---------------------
FUNCTION ZBAPI_PO .
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(DATELO) TYPE ZBAPIPOSTR-BEDAT OPTIONAL
*" VALUE(DATEHI) TYPE ZBAPIPOSTR-BEDAT OPTIONAL
*" VALUE(DOCLO) TYPE ZBAPIPOSTR-EBELN OPTIONAL
*" VALUE(DOCHI) TYPE ZBAPIPOSTR-EBELN OPTIONAL
*" VALUE(DATETY) TYPE ZBAPIPRSTR-LOEKZ OPTIONAL
*" EXPORTING
*" VALUE(RETURN) TYPE BAPIRET2
*" TABLES
*" TBLPO STRUCTURE ZBAPIPOSTR OPTIONAL
*"----------------------------------------------------------------------
*
* CHANGES :
* 20-04-2010 Creation Imam F
* 15-07-2010 Farid
* ADD FRGDT > RELEASE DATE
* NETWR2 > TOTAL VALUE IN LOCAL PRICE
* EINDT > TARGET DELIV DATE
* BLDAT > GR DOCUMENT DATE
* BLDAT2 > IR DOCUMENT DATE
* BUDAT > GR POSTING DATE
* BUDAT2 > IR POSTING DATE
* Parameter based on docno or amend date (from table history)
*DATA DEFINITION
data: begin of p_badat occurs 0,
sign type char1,
option type char2,
low like ekko-bedat,
high like ekko-bedat,
end of p_badat.
data: begin of p_erdat occurs 0,
sign type char1,
option type char2,
low like ekko-aedat,
high like ekko-aedat,
end of p_erdat.
data: begin of p_ebeln occurs 0,
sign type char1,
option type char2,
low like ekko-ebeln,
high like ekko-ebeln,
end of p_ebeln.
data: begin of i_po occurs 0.
include structure ZBAPIPOSTR.
data: OBJECTID9 like cdhdr-objectid.
data: frggr like ekko-frggr.
data: frgsx like ekko-frgsx.
data: end of i_po.
data : begin of i_t001k occurs 0,
bwkey like t001k-bwkey,
bukrs like t001k-bukrs,
end of i_t001k.
data : begin of i_t024 occurs 0,
ekgrp like t024-ekgrp,
eknam like t024-eknam,
end of i_t024.
DATA : BEGIN OF IT16FS OCCURS 0,
FRGGR LIKE T16FS-FRGGR, "Release group
FRGSX LIKE T16FS-FRGSX, "Release code
FRGC1 LIKE T16FS-FRGC1, "Release code
FRGC2 LIKE T16FS-FRGC2, "Release code
FRGC3 LIKE T16FS-FRGC3, "Release code
FRGC4 LIKE T16FS-FRGC4, "Release code
FRGC5 LIKE T16FS-FRGC5, "Release code
END OF IT16FS.
DATA: frg like T16FS-FRGC2.
DATA : tp_name like THEAD-TDNAME,
lines type TLINE occurs 0 with header line.
DATA : BEGIN OF i_ekkn OCCURS 0,
EBELN like ekkn-ebeln,
EBELP like ekkn-EBELP,
KOSTL like ekkn-kostl,
AUFNR like ekkn-aufnr,
SAKTO like ekkn-sakto,
GSBER like ekkn-gsber,
end of i_ekkn.
DATA : BEGIN OF i_ekbe OCCURS 0,
EBELN like ekbe-ebeln,
EBELP like ekbe-EBELP,
BEWTP like ekbe-bewtp,
BELNR like ekbe-belnr,
ELIKZ like ekbe-elikz,
BUDAT like ekbe-budat,
BLDAT like ekbe-bldat,
end of i_ekbe.
DATA : BEGIN OF i_eket OCCURS 0,
EBELN like eket-ebeln,
EBELP like eket-EBELP,
EINDT like eket-eindt,
end of i_eket.
DATA : objnr type COBRB-OBJNR.
DATA : xbewtp like i_ekbe-bewtp.
DATA : BEGIN OF i_cdhdr occurs 0,
ebeln like ekko-ebeln,
changenr like cdhdr-changenr,
FRGDT like cdhdr-udate,
tcode like cdhdr-tcode,
objectid like cdhdr-objectid,
tabname like cdpos-tabname,
fname like cdpos-fname,
value_new like cdpos-value_new,
end of i_cdhdr.
FIELD-SYMBOLS: <fs> like i_cdhdr.
DATA: i_hdrrel like table of i_cdhdr with header line.
*DATA: i_cdhdr type sorted table of t_cdhdr with non-unique key changenr objectid with header line.
data : begin of i_t16fw occurs 0,
frggr like t16fw-frggr,
frgco like t16fw-frgco,
werks like t16fw-werks,
bname like usr21-bname,
smtp_addr like adr6-smtp_addr,
end of i_t16fw.
data : begin of i_lfa1 occurs 0,
lifnr like lfa1-lifnr,
name1 like lfa1-name1,
name2 like lfa1-name2,
anred like lfa1-anred,
end of i_lfa1.
DATA : loc_amount TYPE EKPO-NETWR, opt(3) type c.
*only DATE or DOC, not both
if not DATELO is initial.
if DATEHI is initial.
DATEHI = DATELO.
endif.
p_erdat-sign = 'I'.
p_erdat-option = 'BT'.
p_erdat-low = datelo.
p_erdat-high = datehi.
append p_erdat.
opt = 'DAT'.
elseif ( not DOCLO is initial ).
if DOCHI is initial.
DOCHI = DOCLO.
endif.
p_ebeln-sign = 'I'.
p_ebeln-option = 'BT'.
p_ebeln-low = doclo.
p_ebeln-high = dochi.
append p_ebeln.
opt = 'DOC'.
endif.
* PO selection based on PO history
if ( opt = 'DAT' ).
SELECT objectid changenr udate tcode objectid
into (i_cdhdr-ebeln, i_cdhdr-changenr, i_cdhdr-frgdt, i_cdhdr-tcode, i_cdhdr-objectid)
FROM CDHDR
WHERE udate in p_erdat AND OBJECTCLAS = 'EINKBELEG'
AND TCODE in ('ME21N','ME22N','ME23N','ME29N','ME28','ME54N','ME55').
append i_cdhdr.
endselect.
i_hdrrel[] = i_cdhdr[].
sort i_cdhdr by ebeln.
delete adjacent duplicates from i_cdhdr comparing ebeln.
if not i_cdhdr is initial.
SELECT a~ebeln b~ebelp b~loekz b~aedat txz01 matnr werks lgort matkl
infnr menge meins netpr peinh netwr wepos weunb repos webre mtart
a~bstyp bsart a~statu lponr zterm zbd1t ekorg ekgrp waers wkurs bedat
knumv unsez procstat bednr frgke frgzu lifnr a~ebeln as objectid9
frggr frgsx banfn bnfpo a~mandt a~ernam elikz
INTO CORRESPONDING FIELDS OF TABLE i_po
FROM EKKO as a inner join EKPO as b on a~EBELN = b~EBELN
for all entries in i_cdhdr
WHERE
a~ebeln = i_cdhdr-ebeln.
endif.
* PO selection based on input PO doc
elseif ( opt = 'DOC' ) and ( not p_ebeln is initial ).
SELECT a~ebeln b~ebelp b~loekz b~aedat txz01 matnr werks lgort matkl
infnr menge meins netpr peinh netwr wepos weunb repos webre mtart
a~bstyp bsart a~statu lponr zterm zbd1t ekorg ekgrp waers wkurs bedat
knumv unsez procstat bednr frgke frgzu lifnr a~ebeln as objectid9
frggr frgsx banfn bnfpo a~mandt ernam elikz
INTO CORRESPONDING FIELDS OF TABLE i_po
FROM EKKO as a inner join EKPO as b on a~EBELN = b~EBELN
WHERE
a~ebeln in p_ebeln.
if not i_po[] is initial.
SELECT objectid changenr udate tcode objectid
into (i_hdrrel-ebeln, i_hdrrel-changenr, i_hdrrel-frgdt, i_hdrrel-tcode, i_hdrrel-objectid)
FROM CDHDR
for all entries in i_po
WHERE objectid = i_po-objectid9 AND OBJECTCLAS = 'EINKBELEG'
AND TCODE in ('ME21N','ME22N','ME23N','ME29N','ME28','ME54N','ME55').
append i_hdrrel.
endselect.
endif.
endif.
*if not i_po is initial. this fail
IF not i_po[] is initial.
* populate detail change (cdpos) only from ME29N and ME28 (approval)
delete i_hdrrel where tcode = 'ME21N' or tcode = 'ME22N' or tcode = 'ME23N'.
loop at i_hdrrel assigning <fs>.
select fname value_new into (<fs>-fname, <fs>-value_new)
from cdpos
where changenr = <fs>-changenr and fname = 'PROCSTAT' and value_new = '5'.
endselect.
endloop.
*get last full release approval history
sort i_hdrrel by ebeln changenr descending.
delete adjacent duplicates from i_hdrrel comparing ebeln.
* DATA SELECTON
select bwkey bukrs into table i_t001k
from T001K order by BWKEY BUKRS.
select ekgrp eknam into table i_t024
from T024 order by ekgrp eknam.
select FRGGR FRGSX FRGC1 FRGC2 FRGC3 FRGC4 FRGC5
into table IT16FS
from T16FS.
sort IT16FS by FRGGR FRGSX.
if sy-subrc = 0.
SELECT EBELN EBELP KOSTL AUFNR SAKTO into table i_ekkn
from EKKN for all entries in i_po
where EBELN = i_po-EBELN
and EBELP = i_po-EBELP.
sort i_ekkn by ebeln ebelp.
*farid: get target delivery status and actual deliv date
SELECT EBELN EBELP BEWTP BELNR ELIKZ BUDAT BLDAT into table i_ekbe
from EKBE for all entries in i_po
where EBELN = i_po-EBELN
and EBELP = i_po-EBELP.
*E > GR, Q > MIRO, sort belnr asc so catch first gr
sort i_ekbe by ebeln ebelp bewtp belnr.
*farid: get target delivery date
SELECT EBELN EBELP EINDT into table i_eket
from EKET for all entries in i_po
where EBELN = i_po-EBELN
and EBELP = i_po-EBELP.
sort i_eket by ebeln ebelp.
SELECT frggr frgco werks bname smtp_addr into table i_t16fw
from T16FW as a inner join USR21 as b on a~objid = b~bname
left outer join ADR6 as c on c~addrnumber = b~addrnumber
and c~persnumber = b~persnumber
order by werks frggr frgco.
SELECT lifnr name1 name2 anred into table i_lfa1
from LFA1 for all entries in i_po
where lifnr = i_po-lifnr.
sort i_lfa1 by lifnr.
endif.
endif.
*DATA PROCESSING
loop at i_po.
read table i_t001k with key BWKEY = i_po-werks
binary search.
if sy-subrc = 0.
i_po-BUKRS = i_t001k-bukrs.
endif.
read table i_t024 with key EKGRP = i_po-ekgrp
binary search.
if sy-subrc = 0.
i_po-eknam = i_t024-eknam.
endif.
*-> Change PO status
clear xbewtp.
*search GR, bewtp = E, get the first because sort by belnr asc
read table i_ekbe with key EBELN = i_po-ebeln
EBELP = i_po-ebelp BEWTP = 'E' binary search.
if sy-subrc = 0.
i_po-bldat = i_ekbe-bldat.
i_po-budat = i_ekbe-budat.
xbewtp = i_ekbe-bewtp.
CASE i_ekbe-bewtp.
WHEN 'E'.
if i_ekbe-elikz = 'X'.
i_po-STATUS = 'GR Total'.
else.
i_po-STATUS = 'GR Partial'.
endif.
WHEN 'Q'.
i_po-STATUS = 'Invoiced'.
WHEN OTHERS.
i_po-STATUS = i_ekbe-bewtp.
ENDCASE.
endif.
*search IR, bewtp = Q, get the first because sort by belnr asc
read table i_ekbe with key EBELN = i_po-ebeln
EBELP = i_po-ebelp BEWTP = 'Q' binary search.
if sy-subrc = 0.
i_po-bldat2 = i_ekbe-bldat.
i_po-budat2 = i_ekbe-budat.
endif.
IF i_po-LOEKZ = 'X' or i_po-LOEKZ = 'L'.
i_po-STATUS = 'Deleted'.
ENDIF.
*get target deliv date
read table i_eket with key EBELN = i_po-ebeln
EBELP = i_po-ebelp binary search.
if sy-subrc = 0.
i_po-eindt = i_eket-eindt.
endif.
* Release Status
IF i_po-FRGKE = '2'.
i_po-rlssts = 'Released'.
ELSE.
read table IT16FS with key
FRGGR = i_po-FRGGR
FRGSX = i_po-FRGSX
binary search.
if sy-subrc = 0.
if i_po-FRGZU = 'X'.
frg = IT16FS-FRGC2.
elseif i_po-FRGZU = 'XX'.
frg = IT16FS-FRGC3.
elseif i_po-FRGZU = 'XXX'.
frg = IT16FS-FRGC4.
elseif i_po-FRGZU = 'XXXX'.
frg = IT16FS-FRGC5.
else.
frg = IT16FS-FRGC1.
endif.
if frg = 'H1'.
i_po-rlssts = 'WAppr HOD'.
elseif frg = 'M1'.
i_po-rlssts = 'WAppr GM'.
elseif frg = 'D1'.
i_po-rlssts = 'WAppr Director'.
elseif frg = 'P1'.
i_po-rlssts = 'WAppr President'.
else.
if xbewtp = 'E' or xbewtp = 'Q'.
i_po-rlssts = 'Released'.
else.
i_po-rlssts = 'WAppr'.
endif.
endif.
* reading next approval id & email
read table i_t16fw with key frggr = i_po-frggr
frgco = frg binary search.
if sy-subrc = 0.
i_po-bname = i_t16fw-bname.
i_po-smtp_addr = i_t16fw-smtp_addr.
endif.
else.
i_po-rlssts = 'WAppr'.
endif.
ENDIF.
*-> get PR item text
refresh lines.
concatenate i_po-banfn i_po-bnfpo into tp_name.
call function 'READ_TEXT'
EXPORTING
id = 'B01'
language = sy-langu
name = tp_name
object = 'EBAN'
TABLES
lines = lines
EXCEPTIONS
id = 1
language = 2
name = 3
not_found = 4
object = 5
reference_check = 6
wrong_access_to_archive = 7.
read table lines index 1.
move lines-tdline to i_po-itemtxt.
clear lines.
*get cost center & IO
read table i_ekkn with key ebeln = i_po-ebeln
ebelp = i_po-ebelp
binary search.
if sy-subrc = 0.
i_po-sakto = i_ekkn-sakto.
i_po-aufnr = i_ekkn-aufnr.
i_po-kostl = i_ekkn-kostl.
i_po-gsber = i_ekkn-gsber.
endif.
if not i_po-AUFNR is initial.
if i_po-BSART = 'ZWOR'.
concatenate 'OR' i_po-AUFNR into objnr.
select single KOSTL into i_po-KOSTL from COBRB
where OBJNR = objnr.
else.
select single KOSTV into i_po-KOSTL from COAS
where AUFNR = i_po-AUFNR.
endif.
endif.
* calculate amount
* if i_pr-peinh = 0 or i_pr is initial.
* i_pr-peinh = 1.
* endif.
* i_pr-AMOUNT = i_pr-menge * i_pr-preis / i_pr-peinh.
*-> get PO release date from changes table
*farid: if full release, get date from i_hdrrel
clear i_po-frgdt.
read table i_hdrrel with key ebeln = i_po-ebeln.
if ( sy-subrc = 0 ) and ( i_po-frgke = '2' ).
i_po-frgdt = i_hdrrel-frgdt.
endif.
*-> get PO Status
read table i_lfa1 with key lifnr = i_po-lifnr
binary search.
if sy-subrc = 0.
i_po-name1 = i_lfa1-name1.
i_po-name2 = i_lfa1-name2.
i_po-anred = i_lfa1-anred.
endif.
*farid: Get PO Value at Local Currency
CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
EXPORTING
CLIENT = i_po-MANDT
DATE = i_po-BEDAT
FOREIGN_AMOUNT = i_po-NETWR
FOREIGN_CURRENCY = i_po-WAERS
LOCAL_CURRENCY = 'USD'
RATE = 0
TYPE_OF_RATE = 'M'
READ_TCURR = 'X'
IMPORTING
LOCAL_AMOUNT = loc_amount
EXCEPTIONS
NO_RATE_FOUND = 1
OVERFLOW = 2
NO_FACTORS_FOUND = 3
NO_SPREAD_FOUND = 4
DERIVED_2_TIMES = 5.
IF SY-SUBRC = 0.
i_po-NETWR2 = loc_amount.
ENDIF.
* MODIFY i_po.
if i_po-ebeln ne space.
MOVE-CORRESPONDING i_po to TBLPO.
APPEND TBLPO.
endif.
CLEAR i_po.
CLEAR TBLPO.
endloop. "i_po
ENDFUNCTION.