接到一个需求,说是创建一个RFC接口,能够创建供应商主数据,然后还要把这个接口封装成API发布。
之前写接口都是在系统本来就有的程序上修改,从来没有自己从头到尾写过一个代码,幸好网上有善心网友分享的代码,我也是在他们的基础上修改的。
参考文档:
SAP SD CMD_EI_API=>MAINTAIN 创建客户主数据_sap bapi 确认pod-CSDN博客
网上大部分的例程好像都是给的程序而不是接口,我定义的表是这样的:
这个是根据自己的情况修改吧,很多时候为了方便大概只会输入必填数据,一般不会一次传这么多字段的数据
代码:
FUNCTION ZRFC_MM_027.
*"----------------------------------------------------------------------
*"*"Local interface:
*" EXPORTING
*" VALUE(L_RETUN) TYPE CHAR1
*" VALUE(L_RTMSG) TYPE Z_RTMSG
*" TABLES
*" GT_ITAB STRUCTURE ZST_VENDOR_BASIS
*"----------------------------------------------------------------------
DATA: LS_RETURN TYPE BAPIRET2."返回消息结构
DATA: LS_MASTER_DATA TYPE VMDS_EI_MAIN."供应商主数据结构
DATA: LS_MASTER_DATA_CORRECT TYPE VMDS_EI_MAIN,"成功处理的供应商主数据
LS_MESSAGE_CORRECT TYPE CVIS_MESSAGE,"成功消息
LS_MASTER_DATA_DEFECTIVE TYPE VMDS_EI_MAIN,"处理失败的供应商主数据
LS_MESSAGE_DEFECTIVE TYPE CVIS_MESSAGE."失败消息
DATA: LS_VMDS_EI_EXTERN TYPE VMDS_EI_EXTERN ."外部数据接口
DATA: LS_CORRECT_EXTERN TYPE VMDS_EI_EXTERN."存储已验证通过的外部数据
DATA: LS_REMARKS TYPE CVIS_EI_REM."供应商备注或附加说明信息
DATA: LS_BANK TYPE CVIS_EI_CVI_BANKDETAIL."存储供应商银行账户信息
DATA: LS_COMMUNICATION_PHONE TYPE CVIS_EI_PHONE_STR,"存储电话
LS_COMMUNICATION_FAX TYPE CVIS_EI_FAX_STR,"传真
LS_COMMUNICATION_SMTP TYPE CVIS_EI_SMTP_STR."邮箱
DATA: LV_STRING TYPE STRING .
DATA: LV_APPROVED_DATE TYPE STRING,
LV_APPROVED_DATE1 TYPE STRING.
DATA: LV_ADRNR TYPE ADRNR,"存储地址编号
LS_KNVK TYPE KNVK,"存储供应商联系人
LV_RETCODE TYPE NRRETURN,"存储操作返回代码
LV_PERSON_NUMBER TYPE AD_PERSNUM."存储联系人的人员编号(?)
DATA: LS_CVI_BANKDETAIL TYPE CVIS_EI_CVI_BANKDETAIL,
LS_BANKDETAIL_KEY TYPE CVIS_EI_BANKDETAIL_KEY,
LS_BANKDETAIL_DATA TYPE CVIS_EI_BANKDETAIL_DATA,
LS_BANKDETAIL_DATAX TYPE CVIS_EI_BANKDETAIL_DATAX.
DATA: LV_MAX_LIFNR TYPE LIFNR."存储系统中当前最大的供应商编号
DATA: LS_VMDS_CMP TYPE VMDS_EI_COMPANY,"存储供应商在公司代码视图(Company Code View)的财务数据
LS_VMDS_PUR TYPE VMDS_EI_PURCHASING."存储供应商在采购组织视图(Purchasing Organization View)的采购数据
* LS_VMDS_FUN TYPE VMDS_EI_FUNCTIONS."定义供应商的合作伙伴功能(Partner Functions)
DATA: ZLFBK TYPE LFBK.
DATA:IV_FLAG TYPE C .
DATA:LT_MSG TYPE BAPIRET2_T,
LS_MSG TYPE BAPIRET2.
DATA:lt_get TYPE vmds_ei_extern_t,
ls_get TYPE vmds_ei_extern.
CLEAR:LS_RETURN ,
LS_MASTER_DATA ,
LS_MASTER_DATA_CORRECT ,
LS_MESSAGE_CORRECT ,
LS_MASTER_DATA_DEFECTIVE ,
LS_MESSAGE_DEFECTIVE ,
LS_VMDS_EI_EXTERN ,
LS_CORRECT_EXTERN ,
LS_REMARKS ,
LS_BANK ,
LS_COMMUNICATION_PHONE ,
LS_COMMUNICATION_FAX ,
LS_COMMUNICATION_SMTP ,
LV_STRING ,
LV_APPROVED_DATE ,
LV_APPROVED_DATE1 ,
LV_ADRNR ,
LS_KNVK ,
LV_RETCODE ,
LV_PERSON_NUMBER ,
LS_CVI_BANKDETAIL ,
LS_BANKDETAIL_KEY ,
LS_BANKDETAIL_DATA ,
LS_BANKDETAIL_DATAX ,
LV_MAX_LIFNR ,
LS_VMDS_CMP ,
LS_VMDS_PUR ,
* LS_VMDS_FUN ,
ZLFBK ,
IV_FLAG .
CLEAR LS_VMDS_EI_EXTERN.
LOOP AT gt_itab.
* 维护标识:插入、更新
IV_FLAG = 'I' .
LS_VMDS_EI_EXTERN-HEADER-OBJECT_TASK = IV_FLAG.
IF gt_itab-lifnr IS NOT INITIAL.
LS_VMDS_EI_EXTERN-HEADER-OBJECT_INSTANCE-LIFNR = gt_itab-lifnr. "供应商
ENDIF.
**处理公司层面的数据
* CLEAR LS_VMDS_CMP.
* LS_VMDS_CMP-TASK = IV_FLAG.
* LS_VMDS_CMP-DATA_KEY-BUKRS = gt_itab-bukrs.
* LS_VMDS_CMP-DATA-AKONT = gt_itab-akont."统御科目
* LS_VMDS_CMP-DATA-ZTERM = gt_itab-zterm."付款条件
* LS_VMDS_CMP-DATA-ZWELS = gt_itab-zwels."付款方式
* LS_VMDS_CMP-DATAX-AKONT = 'X'.
* LS_VMDS_CMP-DATAX-ZTERM = 'X'.
* LS_VMDS_CMP-DATAX-ZWELS = 'X'.
* APPEND LS_VMDS_CMP TO LS_VMDS_EI_EXTERN-COMPANY_DATA-COMPANY.
*
**处理采购组织层面的数据
* CLEAR LS_VMDS_PUR.
* LS_VMDS_PUR-TASK = IV_FLAG.
* LS_VMDS_PUR-DATA_KEY-EKORG = gt_itab-ekorg.
* LS_VMDS_PUR-DATA-WAERS = gt_itab-waers.
* LS_VMDS_PUR-DATA-ZTERM = gt_itab-zterm1.
* LS_VMDS_PUR-DATA-INCO1 = gt_itab-inco1.
* LS_VMDS_PUR-DATA-INCO2 = gt_itab-inco2.
* LS_VMDS_PUR-DATA-WEBRE = gt_itab-webre.
* LS_VMDS_PUR-DATA-EKGRP = gt_itab-ekgrp.
* LS_VMDS_PUR-DATAX-WAERS = 'X'.
* LS_VMDS_PUR-DATAX-ZTERM = 'X'.
* LS_VMDS_PUR-DATAX-INCO1 = 'X'.
* LS_VMDS_PUR-DATAX-INCO2 = 'X'.
* LS_VMDS_PUR-DATAX-WEBRE = 'X'.
* LS_VMDS_PUR-DATAX-EKGRP = 'X'.
* APPEND LS_VMDS_PUR TO LS_VMDS_EI_EXTERN-PURCHASING_DATA-PURCHASING.
*处理基础层的数据
LS_VMDS_EI_EXTERN-CENTRAL_DATA-CENTRAL-DATA-KTOKK = gt_itab-ktokk.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-CENTRAL-DATAX-KTOKK = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-TASK = IV_FLAG.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-TITLE = gt_itab-title_medi.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-NAME = gt_itab-name1.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-NAME_2 = gt_itab-name2.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-NAME_3 = gt_itab-name3.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-SORT1 = gt_itab-sort1.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-SORT2 = gt_itab-sort2.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-STREET = gt_itab-street.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-POSTL_COD1 = gt_itab-post_code1.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-CITY = gt_itab-city1.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-COUNTRY = gt_itab-country.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-REGION = gt_itab-region.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATA-LANGU = gt_itab-langu.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-TITLE = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-NAME = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-NAME_2 = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-NAME_3 = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-SORT1 = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-SORT2 = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-STREET = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-POSTL_COD1 = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-CITY = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-COUNTRY = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-REGION = 'X'.
LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-POSTAL-DATAX-LANGU = 'X'.
*处理电话
LS_COMMUNICATION_PHONE-CONTACT-TASK = IV_FLAG.
LS_COMMUNICATION_PHONE-CONTACT-DATA-TELEPHONE = gt_itab-tel_number.
LS_COMMUNICATION_PHONE-CONTACT-DATAX-TELEPHONE = 'X'.
APPEND LS_COMMUNICATION_PHONE TO LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-COMMUNICATION-PHONE-PHONE.
*处理传真
LS_COMMUNICATION_FAX-CONTACT-TASK = IV_FLAG.
LS_COMMUNICATION_FAX-CONTACT-DATA-FAX = gt_itab-fax_number.
LS_COMMUNICATION_FAX-CONTACT-DATAX-FAX = 'X'.
APPEND LS_COMMUNICATION_FAX TO LS_VMDS_EI_EXTERN-CENTRAL_DATA-ADDRESS-COMMUNICATION-FAX-FAX.
**处理银行数据
* LS_BANK-TASK = IV_FLAG.
* LS_BANK-DATA_KEY-BANKS = gt_itab-banks.
* LS_BANK-DATA_KEY-BANKL = gt_itab-bankl.
* LS_BANK-DATA_KEY-BANKN = gt_itab-bankn.
* LS_BANK-DATA-KOINH = gt_itab-koinh.
* LS_BANK-DATA-BVTYP = gt_itab-bvtyp.
* LS_BANK-DATAX-KOINH = 'X'.
* LS_BANK-DATAX-BVTYP = 'X'.
* APPEND LS_BANK TO LS_VMDS_EI_EXTERN-CENTRAL_DATA-BANKDETAIL-BANKDETAILS.
APPEND LS_VMDS_EI_EXTERN TO LS_MASTER_DATA-VENDORS.
SET UPDATE TASK LOCAL.
* 调用api维护供应商
CALL METHOD VMD_EI_API=>MAINTAIN_BAPI
EXPORTING
IV_COLLECT_MESSAGES = 'X'
IS_MASTER_DATA = LS_MASTER_DATA
IMPORTING
ES_MASTER_DATA_CORRECT = LS_MASTER_DATA_CORRECT
ES_MESSAGE_CORRECT = LS_MESSAGE_CORRECT
ES_MASTER_DATA_DEFECTIVE = LS_MASTER_DATA_DEFECTIVE
ES_MESSAGE_DEFECTIVE = LS_MESSAGE_DEFECTIVE.
* 返回结果处理
LT_MSG = LS_MESSAGE_DEFECTIVE-MESSAGES.
LOOP AT LT_MSG INTO LS_MSG.
CONCATENATE gt_itab-msg_err LS_MSG-TYPE ':' LS_MSG-MESSAGE '。' INTO gt_itab-msg_err.
MODIFY gt_itab.
ENDLOOP.
lt_get[] = LS_MASTER_DATA_CORRECT-VENDORS.
LOOP AT LS_MESSAGE_DEFECTIVE-MESSAGES
TRANSPORTING NO FIELDS
WHERE TYPE CA 'EA'.
EXIT.
ENDLOOP.
IF SY-SUBRC = 0. "失败
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
* IT_LIFNR-FLAG = 'N' .
CONCATENATE '供应商创建失败' gt_itab-msg_err INTO gt_itab-msg_err.
MODIFY gt_itab.
l_retun = 'E'.
l_rtmsg = 'E:查询数据为空'.
ELSE."成功
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
WAIT = 'X'.
READ TABLE lt_get INTO ls_get INDEX 1.
gt_itab-lifnr = ls_get-header-object_instance-lifnr.
CONCATENATE '供应商创建成功,供应商编号是:' gt_itab-lifnr INTO gt_itab-msg_err.
MODIFY gt_itab.
l_retun = 'S'.
l_rtmsg = 'S:数据获取成功'.
* IT_LIFNR-FLAG = 'Y' .
ENDIF.
ENDLOOP.
ENDFUNCTION.
封装成API接口
接下来介绍一下API接口的相关操作
事务码SE24创建类
输入类的名称:
点击保存:
在interface这加上 IF_HTTP_EXTENSION
在方法这加上GET 和 POST方法
点击一下GET方法这一栏,再点击parameters
加上 SERVER
POST也是同样的操作
然后双击post方法,进入编写代码,这个接口我只在POST写了代码,有需要的在GET那也可以写代码
method POST.
INCLUDE <icon>.
DATA:lv_content_type TYPE string.
DATA:lv_json_in TYPE string.
DATA:lv_json_out TYPE string.
DATA:lv_res TYPE string.
DATA:lv_len TYPE i.
DATA gt_itab TYPE TABLE OF ZST_VENDOR_BASIS.
DATA:BEGIN OF gt_json,
l_retun TYPE char1,
l_rtmsg TYPE z_rtmsg,
gt_itab TYPE TABLE OF ZST_VENDOR_BASIS,
END OF gt_json.
DATA: BEGIN OF data,
gt_itab TYPE TABLE OF ZST_VENDOR_BASIS,
END OF data.
lv_content_type = 'application/json'.
CALL METHOD server->request->get_cdata
RECEIVING
data = lv_json_in.
CALL METHOD zcl_json=>deserialize
EXPORTING
json = lv_json_in
CHANGING
data = data.
gt_itab[] = data-gt_itab[].
CALL FUNCTION 'ZRFC_MM_027'
IMPORTING
l_retun = gt_json-l_retun
l_rtmsg = gt_json-l_rtmsg
TABLES
gt_itab = gt_itab.
gt_json-gt_itab[] = gt_itab[].
CALL METHOD zcl_json=>serialize
EXPORTING
data = gt_json
RECEIVING
r_json = lv_json_out.
server->response->set_status( code = 200 reason = '执行成功' ).
server->response->set_content_type( 'application/json' ).
server->response->set_cdata( data = lv_json_out ).
* lv_res = '{ "L_RETUN":"E","L_RTMSG":"供应商创建失败"}'.
* lv_len = STRLEN( lv_res ).
* CALL METHOD server->response->set_cdata
* EXPORTING
* data = lv_res
* length = lv_len.
endmethod.
然后就是创建服务 事务码SICF
右击SAP这一栏,点击新增子元素
这里填写刚刚创建的类
右击刚刚创建的服务,点击“激活服务”
再次右击,点击测试服务,弹出的网页链接就是我们要的api
测试:用POSTMAN测试
输入登录SAP程序的用户名和密码,如果输错的话会报错
在这里输入要传的数据,网上搜json转换有很多能够把要输入的数据换成json格式的网页,我用的那个链接突然打不开了所以就不推荐了hh,注意不要把数据放到输出那一栏那里了,会报错
结果就是顺利返回
以上就是我操作的全过程了,当然这是我第一次做这种需求很多地方说的或者做的还有很多不专业的地方,欢迎各位友友讨论