通过 BAPI:BAPI_PO_CREATE1 创建 PO
TABLE 中的行项目参数 poitem 的货币字段 poitem-orderpr_un :行项目的货币类型是根据供应商自动带出,不需要传入。
实际业务中有可能创建 PO 的人员会变换货币的类型,通过设置抬头参数 poheader 的货币字段:poheader-currency = ‘货币’,这样即可实现对新建 PO 的货币类型的强制修改。
FUNCTION zcreate_po.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(CALLNO) TYPE ZCALLNO
*" VALUE(DOC_TYPE) LIKE BAPIMEPOHEADER-DOC_TYPE DEFAULT 'ZIPR'
*" VALUE(PURCH_ORG) LIKE BAPIMEPOHEADER-PURCH_ORG DEFAULT 'POIC'
*" VALUE(PUR_GROUP) LIKE BAPIMEPOHEADER-PUR_GROUP
*" VALUE(VENDOR) LIKE BAPIMEPOHEADER-VENDOR
*" VALUE(COMP_CODE) LIKE BAPIMEPOHEADER-COMP_CODE DEFAULT 'GF50'
*" VALUE(DZTERM) TYPE DZTERM DEFAULT '0001'
*" EXPORTING
*" VALUE(PO_NUMBER) LIKE BAPIMEPOHEADER-PO_NUMBER
*" VALUE(FLAG) LIKE BAPIRET2-TYPE
*" VALUE(MESSAGE) LIKE BAPIRET2-MESSAGE
*" TABLES
*" POITEM STRUCTURE ZPOITEM
*"----------------------------------------------------------------------
DATA: lv_currency TYPE bapimepoheader-currency VALUE 'RMB', "货币码"
ls_poitem TYPE zpoitem,
lv_message TYPE bapiret2-message,
lv_po_item TYPE bapimepoitem-po_item, "行项目号"
lv_pckg_no TYPE bapimepoitem-pckg_no. "PCKG_NO"
DATA: quantity(18),
net_price(37),
limit(27),
exp_value(27),
l_lifnr TYPE lfa1-lifnr,
lv_datano TYPE zdatano.
DATA: lt_eskl TYPE TABLE OF eskl WITH HEADER LINE.
CLEAR:gs_poheader,gs_poheaderx,gv_po_number, gt_return,gs_return,gt_poitem,gs_poitem,gt_poitemx,
gs_poitemx,gt_poschedule,gs_poschedule,gt_poschedulex,gs_poschedulex,gt_poaccount,gs_poaccount,
gt_poaccountx,gs_poaccountx,gt_polimits,gs_polimits.
*数据检查.
PERFORM frm_check_data USING doc_type purch_org pur_group vendor comp_code poitem[]
CHANGING flag message.
*补齐前导零
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = vendor
IMPORTING
output = l_lifnr.
*抬头数据
gs_poheader-doc_type = doc_type. "采购凭证类型
gs_poheader-purch_org = purch_org. "采购组织
gs_poheader-pur_group = pur_group. "采购组
gs_poheader-vendor = l_lifnr. "供应商帐户号
gs_poheader-comp_code = comp_code. "公司代码
gs_poheader-currency = lv_currency. "货币码
gs_poheader-pmnttrms = dzterm. "付款条件
"抬头数据标识"
gs_poheaderx-doc_type = g_flag.
gs_poheaderx-purch_org = g_flag.
gs_poheaderx-pur_group = g_flag.
gs_poheaderx-vendor = g_flag.
gs_poheaderx-comp_code = g_flag.
gs_poheaderx-currency = g_flag.
gs_poheaderx-pmnttrms = g_flag.
SELECT * INTO TABLE lt_eskl FROM eskl UP TO 500 ROWS
WHERE loekz = '' .
LOOP AT poitem INTO ls_poitem.
*行项目
READ TABLE lt_eskl INDEX sy-tabix.
lv_pckg_no = lt_eskl-packno.
lv_po_item = lv_po_item + 10.
PERFORM frm_poitem USING ls_poitem lv_po_item lv_pckg_no.
*计划行
PERFORM frm_poschedule USING ls_poitem lv_po_item.
*账户分配
PERFORM frm_poaccount USING ls_poitem lv_po_item.
*服务限制
PERFORM frm_polimits USING ls_poitem lv_po_item lv_pckg_no.
ENDLOOP.
*创建采购订单
CALL FUNCTION 'BAPI_PO_CREATE1'
EXPORTING
poheader = gs_poheader
poheaderx = gs_poheaderx
IMPORTING
exppurchaseorder = gv_po_number
TABLES
return = gt_return
poitem = gt_poitem
poitemx = gt_poitemx
poschedule = gt_poschedule
poschedulex = gt_poschedulex
poaccount = gt_poaccount
poaccountx = gt_poaccountx
polimits = gt_polimits.
READ TABLE gt_return INTO gs_return WITH KEY type = 'E'.
IF sy-subrc NE 0.
po_number = gv_po_number.
flag = 'S'.
CONCATENATE '生成PO:' po_number INTO message.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT gt_return INTO gs_return WHERE type CA 'AEX'.
MESSAGE ID gs_return-id
TYPE gs_return-type
NUMBER gs_return-number
WITH gs_return-message_v1 gs_return-message_v2
gs_return-message_v3 gs_return-message_v4
INTO lv_message.
CONCATENATE message lv_message INTO message SEPARATED BY '|'.
ENDLOOP.
SHIFT message LEFT DELETING LEADING '|'.
flag = 'E'.
ENDIF.
ENDFUNCTION.
根据 Purchase Request 创建 Purchase Order
LOOP AT PRITEM.
IF SY-TABIX = 1.
LS_POHEADER-DOC_TYPE = 'ZSTL'.
CONCATENATE '000000' PRITEM-PLANT INTO LS_POHEADER-VENDOR.
IF LS_WERKS = '1020'.
LS_POHEADER-PURCH_ORG = '1022'. "pritem-purch_org"
ELSEIF LS_WERKS = '1040'.
LS_POHEADER-PURCH_ORG = '1042'.
ENDIF.
LS_POHEADER-COMP_CODE = '1000'.
LS_POHEADER-PUR_GROUP = PRITEM-PUR_GROUP.
LS_POHEADER-DOC_DATE = SY-DATUM.
ENDIF.
LT_POITEM-PO_ITEM = PRITEM-PREQ_ITEM.
LT_POITEM-MATERIAL = PRITEM-MATERIAL.
LT_POITEM-PLANT = '1000'.
LT_POITEM-VEND_MAT = PRITEM-VEND_MAT.
LT_POITEM-QUANTITY = PRITEM-QUANTITY.
LT_POITEM-PO_UNIT = PRITEM-UNIT.
IF PRITEM-CURRENCY <> 'HKD'.
CLEAR:LT_TCURR,LT_TCURR[],LS_EXCHRATE.
SELECT * FROM TCURR INTO TABLE LT_TCURR
WHERE KURST = 'M'
AND FCURR = PRITEM-CURRENCY
AND TCURR = 'HKD'.
SORT LT_TCURR BY GDATU ASCENDING.
LOOP AT LT_TCURR.
LT_TCURR-GDATU = '99999999' - LT_TCURR-GDATU.
IF LT_TCURR-GDATU <= SY-DATUM.
LS_EXCHRATE = LT_TCURR-UKURS.
EXIT.
ENDIF.
ENDLOOP.
IF LS_EXCHRATE IS NOT INITIAL.
LT_POITEM-NET_PRICE = PRITEM-PREQ_PRICE * LS_EXCHRATE.
ELSE.
LT_POITEM-NET_PRICE = PRITEM-PREQ_PRICE.
ENDIF.
ELSE.
LT_POITEM-NET_PRICE = PRITEM-PREQ_PRICE.
ENDIF.
LT_POITEM-PRICE_UNIT = PRITEM-PRICE_UNIT.
LT_POITEM-ACCTASSCAT = 'F'.
APPEND LT_POITEM TO LT_POITEM.
LT_POCOND-ITM_NUMBER = PRITEM-PREQ_ITEM.
LT_POCOND-COND_TYPE = 'PBXX'.
LT_POCOND-COND_VALUE = LT_POITEM-NET_PRICE.
LT_POCOND-CURRENCY = 'HKD'.
LT_POCOND-CHANGE_ID = 'U'.
APPEND LT_POCOND TO LT_POCOND.
CLEAR:LT_POCOND,LT_POITEM.
CLEAR:PRITEM-ACCTASSCAT.
MODIFY PRITEM TRANSPORTING ACCTASSCAT.
ENDLOOP.
LOOP AT PRITEMX.
IF SY-TABIX = 1.
LS_POHEADERX-DOC_TYPE = 'X'.
LS_POHEADERX-VENDOR = 'X'.
LS_POHEADERX-PURCH_ORG = 'X'.
LS_POHEADERX-PUR_GROUP = 'X'.
LS_POHEADERX-DOC_DATE = 'X'.
ENDIF.
LT_POITEMX-PO_ITEM = PRITEMX-PREQ_ITEM.
LT_POITEMX-PO_ITEMX = 'X'.
LT_POITEMX-MATERIAL = 'X'.
LT_POITEMX-PLANT = 'X'.
LT_POITEMX-VEND_MAT = 'X'.
LT_POITEMX-QUANTITY = 'X'.
LT_POITEMX-NET_PRICE = 'X'.
LT_POITEMX-PRICE_UNIT = 'X'.
LT_POITEMX-ACCTASSCAT = 'X'.
APPEND LT_POITEMX TO LT_POITEMX.
CLEAR: LT_POITEMX.
LT_POCONDX-ITM_NUMBER = PRITEMX-PREQ_ITEM.
LT_POCONDX-COND_TYPE = 'X'.
LT_POCONDX-COND_VALUE = 'X'.
LT_POCONDX-CURRENCY = 'X'.
LT_POCONDX-CHANGE_ID = 'X'.
APPEND LT_POCONDX TO LT_POCONDX.
CLEAR:LT_POCONDX.
CLEAR PRITEMX-ACCTASSCAT.
MODIFY PRITEMX TRANSPORTING ACCTASSCAT.
ENDLOOP.
LOOP AT PRACCOUNT.
LT_POACCOUNT-PO_ITEM = PRACCOUNT-PREQ_ITEM.
LT_POACCOUNT-SERIAL_NO = PRACCOUNT-SERIAL_NO.
LT_POACCOUNT-GL_ACCOUNT = PRACCOUNT-GL_ACCOUNT.
LT_POACCOUNT-ORDERID = PRACCOUNT-ORDERID.
APPEND LT_POACCOUNT TO LT_POACCOUNT.
CLEAR: LT_POACCOUNT.
ENDLOOP.
LOOP AT PRACCOUNTX.
LT_POACCOUNTX-PO_ITEM = PRACCOUNTX-PREQ_ITEM.
LT_POACCOUNTX-SERIAL_NO = PRACCOUNTX-SERIAL_NO.
LT_POACCOUNTX-PO_ITEMX = 'X'.
LT_POACCOUNTX-GL_ACCOUNT = 'X'.
LT_POACCOUNTX-ORDERID = 'X'.
APPEND LT_POACCOUNTX TO LT_POACCOUNTX.
CLEAR: LT_POACCOUNTX.
ENDLOOP.
CLEAR:PRACCOUNT,PRACCOUNT[],PRACCOUNTX,PRACCOUNTX[].
LOOP AT PRHEADERTEXT.
LT_POTEXTHEADER-PO_NUMBER = PRHEADERTEXT-PREQ_NO.
LT_POTEXTHEADER-PO_ITEM = PRHEADERTEXT-PREQ_ITEM.
LT_POTEXTHEADER-TEXT_ID = PRHEADERTEXT-TEXT_ID.
LT_POTEXTHEADER-TEXT_LINE = PRHEADERTEXT-TEXT_LINE.
APPEND LT_POTEXTHEADER TO LT_POTEXTHEADER.
CLEAR: LT_POTEXTHEADER.
ENDLOOP.
CALL FUNCTION 'BAPI_PO_CREATE1'
EXPORTING
POHEADER = LS_POHEADER
POHEADERX = LS_POHEADERX
POADDRVENDOR = LS_POADDRVENDOR
TESTRUN = LS_TESTRUNPO
MEMORY_UNCOMPLETE = LS_MEMORY_UNCOMPLETE
MEMORY_COMPLETE = LS_MEMORY_COMPLETE
POEXPIMPHEADER = LS_POEXPIMPHEADER
POEXPIMPHEADERX = LS_POEXPIMPHEADERX
VERSIONS = LS_VERSIONS
NO_MESSAGING = LS_NO_MESSAGING
NO_MESSAGE_REQ = LS_NO_MESSAGE_REQ
NO_AUTHORITY = LS_NO_AUTHORITY
NO_PRICE_FROM_PO = LS_NO_PRICE_FROM_PO
IMPORTING
EXPPURCHASEORDER = LS_EXPPURCHASEORDER
EXPHEADER = LS_EXPHEADER
EXPPOEXPIMPHEADER = LS_EXPPOEXPIMPHEADER
TABLES
RETURN = LT_RETURNPO
POITEM = LT_POITEM
POITEMX = LT_POITEMX
POADDRDELIVERY = LT_POADDRDELIVERY
POSCHEDULE = LT_POSCHEDULE
POSCHEDULEX = LT_POSCHEDULEX
POACCOUNT = LT_POACCOUNT
POACCOUNTPROFITSEGMENT = LT_POACCOUNTPROFITSEGMENT
POACCOUNTX = LT_POACCOUNTX
POCONDHEADER = LT_POCONDHEADER
POCONDHEADERX = LT_POCONDHEADERX
POCOND = LT_POCOND
POCONDX = LT_POCONDX
POLIMITS = LT_POLIMITS
POCONTRACTLIMITS = LT_POCONTRACTLIMITS
POSERVICES = LT_POSERVICES
POSRVACCESSVALUES = LT_POSRVACCESSVALUES
POSERVICESTEXT = LT_POSERVICESTEXT
EXTENSIONIN = LT_EXTENSIONIN
EXTENSIONOUT = LT_EXTENSIONOUT
POEXPIMPITEM = LT_POEXPIMPITEM
POEXPIMPITEMX = LT_POEXPIMPITEMX
POTEXTHEADER = LT_POTEXTHEADER
POTEXTITEM = LT_POTEXTITEM
ALLVERSIONS = LT_ALLVERSIONS
POPARTNER = LT_POPARTNER
POCOMPONENTS = LT_POCOMPONENTS
POCOMPONENTSX = LT_POCOMPONENTSX
POSHIPPING = LT_POSHIPPING
POSHIPPINGX = LT_POSHIPPINGX
POSHIPPINGEXP = LT_POSHIPPINGEXP.
LOOP AT pr_return WHERE type = 'E' OR type = 'A'.
ENDLOOP.
IF sy-subrc = 0.
CLEAR: lv_message.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT pr_return INTO l_return WHERE type = 'E' .
CONCATENATE lv_message l_return-message ';'
INTO lv_message.
ENDLOOP.
CONCATENATE gt_data-bednr lv_message INTO gt_out-text.
APPEND gt_out.
CLEAR gt_out.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
CONCATENATE pr_no '创建成功' INTO gt_out-text.
APPEND gt_out.
CLEAR gt_out.
ENDIF.
FREE pr_item.
FREE pr_account.
FREE pr_item_id.
FREE pr_return.
ENDLOOP.
删除和修改 Purchase Order
FUNCTION zchange_po.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(CALLNO) TYPE ZCALLNO
*" VALUE(PO_NUMBER) LIKE BAPIMEPOHEADER-PO_NUMBER
*" EXPORTING
*" VALUE(FLAG) LIKE BAPIRET2-TYPE
*" VALUE(MESSAGE) LIKE BAPIRET2-MESSAGE
*" TABLES
*" ZPOITEM STRUCTURE ZPOITEM01
*"----------------------------------------------------------------------
DATA: ls_zpoitem TYPE zpoitem01,
lv_message TYPE bapiret2-message,
lv_datano TYPE zdatano.
DATA: gv_po_number LIKE bapimepoheader-po_number,
gt_return LIKE TABLE OF bapiret2,
gs_return LIKE LINE OF gt_return,
gt_poitem LIKE TABLE OF bapimepoitem,
gs_poitem LIKE LINE OF gt_poitem,
gt_poitemx LIKE TABLE OF bapimepoitemx,
gs_poitemx LIKE LINE OF gt_poitemx.
CLEAR:gv_po_number,gs_poitemx,gs_poitem,gs_return,gt_poitemx,gt_poitem,gt_return.
"准备BAPI数据"
gv_po_number = po_number.
LOOP AT zpoitem INTO ls_zpoitem.
gs_poitem-po_item = ls_zpoitem-po_item.
gs_poitem-delete_ind = ls_zpoitem-delete_ind.
APPEND gs_poitem TO gt_poitem.
gs_poitemx-po_item = ls_zpoitem-po_item.
gs_poitemx-po_itemx = g_flag.
gs_poitemx-delete_ind = g_flag.
APPEND gs_poitemx TO gt_poitemx.
CLEAR:gs_poitemx,gs_poitem.
ENDLOOP.
"执行BAPI BAPI_PO_CHANGE"
CALL FUNCTION 'BAPI_PO_CHANGE'
EXPORTING
purchaseorder = gv_po_number
TABLES
return = gt_return
poitem = gt_poitem
poitemx = gt_poitemx.
"判断执行结果,并记录错误信息"
READ TABLE gt_return INTO gs_return WITH KEY type = 'E'.
IF sy-subrc NE 0.
flag = 'S'.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
CONCATENATE 'PO:'gv_po_number '处理完成' INTO message .
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
LOOP AT gt_return INTO gs_return WHERE type CA 'AEX'.
MESSAGE ID gs_return-id
TYPE gs_return-type
NUMBER gs_return-number
WITH gs_return-message_v1 gs_return-message_v2
gs_return-message_v3 gs_return-message_v4
INTO lv_message.
CONCATENATE message lv_message INTO message SEPARATED BY '|'.
ENDLOOP.
SHIFT message LEFT DELETING LEADING '|'.
flag = 'E'.
ENDIF.
ENDFUNCTION.