前言
此文的示例同时可创建一般采购申请或服务采购申请,当采购类型为Z007时,触发服务采购申请相关字段填写
正文
创建服务类型采购申请的时候参数间互相绑定很绕,看了这篇博客才理明白,有兴趣的可以阅读原文
https://wiki.scn.sap.com/wiki/display/ABAP/BAPI_REQUISITION_CREATE?original_fqdn=wiki.sdn.sap.com
下面就尝试解释一下服务类型采购订单的参数对应关系
- requisition_items: preq_item和pckg_no将采购申请行项目和服务抬头互相绑定
- requisition_account_assignment: serial_no固定填入1即可
- requisition_service: pckg_no中同时有抬头和行项目,奇数代表服务抬头,偶数代表服务行项目;line_no代表抬头和行项目的流水号,同一个服务的抬头和行项目共享顺序流水;subpckg_no只有服务抬头需要填写,填入行项目的pckg_no;ext_line代表在前台显示时的流水号,默认10开始
- requisition_srv_accass_values:此处填入上一步服务行项目的值,pckg_no和line_no填入上一步服务行项目的值;serial_no和serno_line固定填入1即可
ps_head结构如下
采购申请创建bapi如下
*&---------------------------------------------------------------------*
*& Form frm_create_pr
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_create_pr USING ps_head TYPE zmms035
CHANGING ps_retinfo TYPE zmms037.
DATA: lv_subrc TYPE i,
lv_str TYPE string,
* lv_wbs_elem TYPE bapiebkn-wbs_elem.
* lv_ext_line TYPE esll-extrow,
lv_line_no TYPE esll-introw,
lv_pckg_no TYPE esll-packno VALUE '0000000001'.
DATA: lt_req_items TYPE TABLE OF bapiebanc,
ls_req_items TYPE bapiebanc,
lt_req_acc_assign TYPE TABLE OF bapiebkn,
ls_req_acc_assign TYPE bapiebkn,
lt_req_services TYPE TABLE OF bapiesllc,
ls_req_services TYPE bapiesllc,
lt_req_srv_acc TYPE TABLE OF bapiesklc,
ls_req_srv_acc TYPE bapiesklc,
lt_req_item_text TYPE TABLE OF bapiebantx,
ls_req_item_text TYPE bapiebantx,
lt_line TYPE TABLE OF /scmb/bif_delvry_map_shipto,
lt_return TYPE TABLE OF bapireturn,
ls_return TYPE bapireturn.
*--创建采购申请
LOOP AT ps_head-item INTO DATA(ls_item).
*----抬头数据
ls_req_items-doc_type = ps_head-bsart. " 采购申请凭证类型
*----行项目数据
ls_req_items-preq_item = |{ ls_item-bnfpo ALPHA = IN }|. " 采购申请项目编号
ls_req_items-acctasscat = ls_item-knttp. " 科目分配类别
ls_req_items-item_cat = ls_item-pstyp. " 项目类别
ls_req_items-material = ls_item-matnr. " 物料编号
ls_req_items-short_text = ls_item-txz01. " 短文本
ls_req_items-quantity = ls_item-menge. " 申请数量
ls_req_items-unit = ls_item-meins. " 计量单位
ls_req_items-deliv_date = ls_item-lfdat. " 项目交货日期
ls_req_items-mat_grp = ls_item-matkl. " 物料组
ls_req_items-plant = ls_item-werks. " 工厂
ls_req_items-store_loc = ls_item-lgort. " 库存地点
ls_req_items-pur_group = ls_item-ekgrp. " 采购组
ls_req_items-preq_name = ls_item-afnam. " 需求人
IF ps_head-bsart = 'Z007'.
ls_req_items-pckg_no = lv_pckg_no.
ENDIF.
APPEND ls_req_items TO lt_req_items.
*----行项目账户数据(每个行项目有且仅有一条)
ls_req_acc_assign-preq_item = |{ ls_item-bnfpo ALPHA = IN }|. " 采购申请项目编号
ls_req_acc_assign-serial_no = '01'. " 帐户分配的顺序编号
ls_req_acc_assign-asset_no = ls_item-anln1. " 资产
ls_req_acc_assign-cost_ctr = ls_item-kostl. " 成本中心
ls_req_acc_assign-order_no = ls_item-aufnr. " 订单号
ls_req_acc_assign-wbs_elem_e = ls_item-ps_psp_pnr. " WBS 元素
ls_req_acc_assign-g_l_acct = ls_item-sakto. " 总账科目
IF ps_head-bsart = 'Z007'.
ls_req_acc_assign-serial_no = '01'.
ENDIF.
APPEND ls_req_acc_assign TO lt_req_acc_assign.
*----行项目长文本
lv_str = ls_item-ztext01. " 长文本-项目文本
TRY.
cl_bcs_convert=>string_to_tab(
EXPORTING
iv_string = lv_str
IMPORTING
et_ctab = lt_line ).
CATCH cx_bcs.
ENDTRY.
LOOP AT lt_line INTO DATA(ls_line).
ls_req_item_text-preq_item = |{ ls_item-bnfpo ALPHA = IN }|. " 采购申请项目编号
ls_req_item_text-text_id = 'B01'. " 文本标识-项目文本
ls_req_item_text-text_form = '*'. " 文本格式
ls_req_item_text-text_line = ls_line-note. " 文本行
APPEND ls_req_item_text TO lt_req_item_text.
ENDLOOP.
*----服务类型采购申请
IF ps_head-bsart = 'Z007'.
" 初始化行号
* lv_ext_line = '0000000000'.
lv_line_no = '0000000001'.
" 服务类型抬头包
ls_req_services = VALUE #( pckg_no = lv_pckg_no " 包号
line_no = lv_line_no " 内部行号
subpckg_no = lv_pckg_no + 1 " 子包编号
).
APPEND ls_req_services TO lt_req_services.
" 服务类型行项目包
LOOP AT ls_item-service INTO DATA(ls_service).
" 递增行号
lv_line_no = lv_line_no + 1.
* lv_ext_line = lv_ext_line + 10.
" 行项目
ls_req_services = VALUE #( pckg_no = lv_pckg_no + 1 " 包号
line_no = lv_line_no " 内部行号
ext_line = ls_service-extrow " 外部行号
service = ls_service-srvpos " 服务编号
short_text = ls_service-ktext1 " 服务文本
quantity = ls_service-menge " 数量
base_uom = ls_service-meins " 单位
gr_price = ls_service-brtwr " 总价格
).
IF ls_service-meins IS INITIAL.
ls_req_services-base_uom = 'LE'. " 默认外码AU,内码LE
ENDIF.
APPEND ls_req_services TO lt_req_services.
" 行项目
ls_req_srv_acc = VALUE #( pckg_no = lv_pckg_no + 1
line_no = lv_line_no
serial_no = '01'
serno_line = '01'
).
APPEND ls_req_srv_acc TO lt_req_srv_acc.
ENDLOOP.
ENDIF.
lv_pckg_no = lv_pckg_no + 2.
ENDLOOP.
"采购申请创建
CALL FUNCTION 'BAPI_REQUISITION_CREATE'
IMPORTING
number = ps_retinfo-banfn
TABLES
requisition_items = lt_req_items
requisition_account_assignment = lt_req_acc_assign
requisition_services = lt_req_services
requisition_srv_accass_values = lt_req_srv_acc
requisition_item_text = lt_req_item_text
return = lt_return.
*----返回消息处理
lv_subrc = sy-subrc.
LOOP AT lt_return INTO ls_return WHERE type CA 'AEX'.
ps_retinfo-code = gc_e.
ps_retinfo-message = ps_retinfo-message && ls_return-message.
ENDLOOP.
IF sy-subrc = 0 OR lv_subrc NE 0.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = abap_true.
WAIT UP TO '0.5' SECONDS.
ENDIF.
IF ps_retinfo-code IS INITIAL.
ps_retinfo-code = gc_s.
ps_retinfo-message = TEXT-m10 && ps_retinfo-message. " 创建成功
ELSE.
ps_retinfo-message = TEXT-m11 && ps_retinfo-message. " 创建失败
ENDIF.
ENDFORM.
服务类型的的采购申请在行项目中,还有服务的行项目
在se16n当中服务类型的采购申请的行项目,是通过eban-packno = esll-packno关联的,在esll表中同时存储了服务的抬头和行项目,服务抬头项目字段中有一个sub_packno的字段,用于关联服务行项目的packno