API 同步创建 SAP 员工供应商

704 阅读10分钟

公司之前的业务是通过导入 Excel 来导入 SAP 员工供应商,方便员工的报销流程,现在对接了企业微信和 Odoo 系统,因此需要开发一个 Odoo 传过来的员工信息,然后同步创建 SAP 员工供应商。因此,在开发完成这个需求之后,写下来本篇笔记。

一共涉及到如下几个 BAPI:

BAPI 名称BAPI 描述
BAPI_BUPA_CREATE_FROM_DATA  SAP BP, BAPI: Create Business Partner
BAPI_BUPA_CENTRAL_CHANGESAP BP, BAPI: Change Central Data
BAPI_BUPA_ADDRESS_ADDSAP BP, BAPI: Add Address
BAPI_BUPA_ADDRESS_CHANGE  SAP BP, BAPI: Change Address
BAPI_BANK_CREATESAP BP,BAPI: Create Bank
BAPI_BUPA_BANKDETAIL_ADDSAP BP,BAPI: Create BP Bank Details
BAPI_BUPA_BANKDETAIL_NUMBERS
BAPI_BUPA_ROLE_ADD_2

数据定义

************************************************************************************  
* 数据定义部分  
  DATA: l_bpartner                    TYPE bapibus1006_head-bpartner,  "业务伙伴编码  
        l_partn_cat                   TYPE bapibus1006_head-partn_cat,  "业务伙伴类别  
        l_partn_grp                   TYPE bapibus1006_head-partn_grp,  "业务伙伴分组  
        ls_central                    TYPE bapibus1006_central,         "一般 BP 数据,与业务伙伴类别无关  
        ls_central_person             TYPE bapibus1006_central_person,  " 个人数据的  
        ls_central_organ              TYPE bapibus1006_central_organ,   "SAP BP: 组织数据的 BAPI 结构  
        ls_address                    TYPE bapibus1006_address,         "SAP BP: 地址数据的 BAPI 结构  
        ls_bapibus1006_industrysector TYPE bapibus1006_industrysector,  
        ls_bapibus1006_bankdetail     TYPE bapibus1006_bankdetail,  
        ls_bapibus1006_bankdetailx    TYPE bapibus1006_bankdetail_x,  
  
  
        ls_bankdetailidout            TYPE but0bk-bkvid,  
        ls_externalbankdetailidout    TYPE but0bk-bkext,  
  
        ls_bapi2021_bank              TYPE bapi2021_bank,  
  
        wa_customer                   TYPE cmds_ei_extern,  
        lt_master_data                TYPE vmds_ei_main,  
        ls_master_data                TYPE vmds_ei_extern,  
        ls_company                    TYPE vmds_ei_company,  
        ls_purchasing                 TYPE vmds_ei_purchasing,  
        ls_functions                  TYPE vmds_ei_functions,  
        wa_customers                  TYPE cmds_ei_main,  
        wa_correct                    TYPE cmds_ei_main,  
        wa_defective                  TYPE cmds_ei_main,  
        wa_mes_correct                TYPE cvis_message,  
        wa_mes_error                  TYPE cvis_message,  
        l1                            TYPE vmds_ei_main,  
        l2                            TYPE cvis_message,  
        l3                            TYPE vmds_ei_main,  
        l4                            TYPE cvis_message,  
        lt_bapiadtel                  LIKE bapiadtel  OCCURS 0 WITH HEADER LINE,            "电话号码的 BAPI 结构(办公地址服务)  
        lt_bapiadfax                  LIKE bapiadfax  OCCURS 0 WITH HEADER LINE,            "传真号码的 BAPI 结构(办公地址服务)  
        lt_bapiadsmtp                 LIKE bapiadsmtp OCCURS 0 WITH HEADER LINE,            "电子邮件地址的 BAPI 结构(办公地址服务)  
        lt_return1                    LIKE bapiret2   OCCURS 0 WITH HEADER LINE,            "返回参数  
        lt_return2                    LIKE bapiret2   OCCURS 0 WITH HEADER LINE,            "返回参数  
        lt_return3                    LIKE bapiret2   OCCURS 0 WITH HEADER LINE,            "返回参数  
        lt_return4                    LIKE bapiret2   OCCURS 0 WITH HEADER LINE,            "返回参数  
        lt_return5                    LIKE bapiret2   OCCURS 0 WITH HEADER LINE,            "返回参数  
        lt_bankdetails                TYPE STANDARD TABLE OF bapibus1006_bankdetail,  
        l_bp_employee                 TYPE  zodoo_bp_return  
        .  
  
  " 取自 SAP 的部分数据定义  
  DATA:  
    bu_group(4),                          " 分组  
    partner(10),                          " 供应商代码,自动创建  
    title_medi(4),                        " 称谓  
    f_name(40),                           " 名  
    l_name(40),                           " 姓  
    street(60),                           " 街道  
    city(40),                             " 城市  
    land1(3),                             " 国家  
    po_box(10),                           " 邮政编码  
  
    bank_land(3),                         " 银行国家  
    bank_name(60),                        " 银行名称  
    acc_holder(60),                       " 账户持有人:  
    bank_no(40),                          " 银行账号:  
    bank_key(15),                         " 银行代码  
    bank_ref(20),                         " 参考明细  
    lv_bukrs(4),                          " 公司代码  
    lv_swift(15),                         " Swift  
    lv_iban(34),                          " IBAN  
    lv_zrn(15),                           " 外部标识  
    lv_bnkey          TYPE t005-bnkey     " 银行代码的名称,1位数字  
    .  
  
  " Bapi 返回消息  
  DATA: l_msg1(255)   TYPE c,                          "返回消息  
        l_msg1_1(255) TYPE c,                          "返回消息  
        l_msg2(255)   TYPE c,                          "返回消息  
        l_msg3(255)   TYPE c,                          "返回消息  
        l_msg4(255)   TYPE c,                          "返回消息  
        l_msgl4(255)  TYPE c                           "返回消息  
        .  
  
  " 银行返回信息  
  DATA:  
    b1(255) TYPE c,  
    b2(255) TYPE c,  
    b3(255) TYPE c,  
    b4(255) TYPE c,  
    b5(255) TYPE c,  
    b6(255) TYPE c,  
    b7(255) TYPE c.  
  
  DATA: c_str TYPE string.  
  DATA: opcode_usr_attr(1) TYPE x VALUE 5,  
        terminal           TYPE usr41-terminal.  
  
  DATA: flag(1) TYPE c.  
***************************************************************************************

BAPI_BUPA_CREATE_FROM_DATA

在创建商业伙伴时,需要用到 SAP 提供的一个函数模块 BAPI_BUPA_CREATE_FROM_DATA,利用 BAPI 来创建商业伙伴,属于 BUPA_3 函数组,这个模块支持远程调用

Importing 参数

Parameter NameTypeAssociated TypeDefault ValueShort Text
ACCEPT_ERRORLIKEBAPI4001_1-ACCEPT_ERRSPACEAccept regional structure check errors with warnings
ADDRESSDATALIKEBAPIBUS1006_ADDRESSAddress
BUSINESSPARTNEREXTERNLIKEBAPIBUS1006_HEAD-BPARTNERBusiness Partner Number
CENTRALDATALIKEBAPIBUS1006_CENTRALCentral Data
CENTRALDATAGROUPLIKEBAPIBUS1006_CENTRAL_GROUPCentral Data, Group
CENTRALDATAORGANIZATIONLIKEBAPIBUS1006_CENTRAL_ORGANCentral Data, Organization
CENTRALDATAPERSONLIKEBAPIBUS1006_CENTRAL_PERSONCentral Data, Person
DUPLICATE_MESSAGE_TYPELIKEBAPIBUS1006_HEAD-CONTROLDUPLICATEMESSAGEMessage Type Control
PARTNERCATEGORYLIKEBAPIBUS1006_HEAD-PARTN_CATBusiness Partner Category
PARTNERGROUPLIKEBAPIBUS1006_HEAD-PARTN_GRPBusiness Partner Grouping

Exporting 参数

也就是生成的商业伙伴编号:

Parameter NameTypeAssociated TypeDefault ValueShort Text
BUSINESSPARTNERLIKEBAPIBUS1006_HEAD-BPARTNERBusiness Partner Number

Changing 参数

这个函数模块没有定义 Changing 参数

Table 参数

Parameter NameTypeAssociated TypeDefault ValueShort Text
ADDRESSDUPLICATESLIKEBAPIBUS1006_ADDRESS_DUPLICATESAddress Duplicates
ADDRESSNOTESLIKEBAPIAD_REMAddress Notes
COMMUNICATIONNOTESLIKEBAPICOMREMNotes on Communication
COMMUNICATIONNOTESNONADDRESSLIKEBAPICOMREMNotes on Communication Types (Address-Independent)
COMMUNICATIONUSAGELIKEBAPIADUSECommunication Use (BAS)
COMMUNICATIONUSAGENONADDRESSLIKEBAPIADUSECommunication Use (Address-Independent, BAS)
E_MAILDATALIKEBAPIADSMTPInternet Addresses
E_MAILDATANONADDRESSLIKEBAPIADSMTPE-Mail Addresses (Address-Independent)
FAXDATALIKEBAPIADFAXFax Numbers
FAXDATANONADDRESSLIKEBAPIADFAXFax Numbers (Address-Independent)
PAGADDRESSDATALIKEBAPIADPAGPager Numbers
PAGADDRESSDATANONADDRESSLIKEBAPIADPAGPager Numbers (Address-Independent)
PRTADDRESSDATALIKEBAPIADPRTPrinter Addresses
PRTADDRESSDATANONADDRESSLIKEBAPIADPRTPRT Addresses (Address-Independent)
RETURNLIKEBAPIRET2Messages
RFCADDRESSDATALIKEBAPIADRFCRFC Addresses
RFCADDRESSDATANONADDRESSLIKEBAPIADRFCRFC Addresses (Address-Independent)
RMLADDRESSDATALIKEBAPIADRMLRemoteMail Addresses
RMLADDRESSDATANONADDRESSLIKEBAPIADRMLRML Addresses (Address-Independent)
SSFADDRESSDATALIKEBAPIADSSFSSF Addresses
SSFADDRESSDATANONADDRESSLIKEBAPIADSSFSSF Addresses (Address-Independent)
TELEFONDATALIKEBAPIADTELTelephone Numbers
TELEFONDATANONADDRESSLIKEBAPIADTELTelephone Numbers (Address-Independent)
TELETEXDATALIKEBAPIADTTXTeletex Numbers
TELETEXDATANONADDRESSLIKEBAPIADTTXTeletex Numbers (Address-Independent)
TELEXDATALIKEBAPIADTLXTelex Numbers
TELEXDATANONADDRESSLIKEBAPIADTLXTelex Numbers (Address-Independent)
URIADDRESSDATALIKEBAPIADURIURI Addresses
URIADDRESSDATANONADDRESSLIKEBAPIADURIURI Addresses (Address-Independent)
X400ADDRESSDATALIKEBAPIADX400X400 Addresses
X400ADDRESSDATANONADDRESSLIKEBAPIADX400X.400 Addresses (Address-Independent)

Exceptions

这个函数同样没有定义任何 Exceptions

代码:

CALL FUNCTION 'BAPI_BUPA_CREATE_FROM_DATA'  
      EXPORTING  
        businesspartnerextern   = l_bpartner  
        partnercategory         = l_partn_cat  
        partnergroup            = l_partn_grp  
        centraldata             = ls_central  
        centraldataperson       = ls_central_person  
        centraldataorganization = ls_central_organ  
*       CENTRALDATAGROUP        =  
        addressdata             = ls_address  
*       DUPLICATE_MESSAGE_TYPE  =  
*       ACCEPT_ERROR            = ' '  
      IMPORTING  
        businesspartner         = l_bpartner  
      TABLES  
*       telefondata             = lt_bapiadtel  
*       faxdata                 = lt_bapiadfax  
*       TELETEXDATA             =  
*       TELEXDATA               =  
*       e_maildata              = lt_bapiadsmtp  
*       RMLADDRESSDATA          =  
*       X400ADDRESSDATA         =  
*       RFCADDRESSDATA          =  
*       PRTADDRESSDATA          =  
*       SSFADDRESSDATA          =  
*       URIADDRESSDATA          =  
*       PAGADDRESSDATA          =  
*       ADDRESSNOTES            =  
*       COMMUNICATIONNOTES      =  
*       COMMUNICATIONUSAGE      =  
*       TELEFONDATANONADDRESS   =  
*       FAXDATANONADDRESS       =  
*       TELETEXDATANONADDRESS   =  
*       TELEXDATANONADDRESS     =  
*       E_MAILDATANONADDRESS    =  
*       RMLADDRESSDATANONADDRESS           =  
*       X400ADDRESSDATANONADDRESS          =  
*       RFCADDRESSDATANONADDRESS           =  
*       PRTADDRESSDATANONADDRESS           =  
*       SSFADDRESSDATANONADDRESS           =  
*       URIADDRESSDATANONADDRESS           =  
*       PAGADDRESSDATANONADDRESS           =  
*       COMMUNICATIONNOTESNONADDRESS       =  
*       COMMUNICATIONUSAGENONADDRESS       =  
        return                  = lt_return1  
*       ADDRESSDUPLICATES       =  
      .  
  
    CLEAR l_msg1.  
    LOOP AT lt_return1 WHERE type = 'E' OR type = 'A'.  
      CONCATENATE lt_return1-message l_msg1 INTO l_msg1 SEPARATED BY ';'.  
      CONDENSE l_msg1.  
    ENDLOOP.  
    IF l_msg1 = ''.  
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'             "commit--信息提交  
        EXPORTING  
          wait = 'X'.                                     "地址信息提交  
  
      CLEAR l_msg1_1.  
      CONCATENATE '业务伙伴地址信息创建成功,编号为' l_bpartner INTO l_msg1_1.  
      CONDENSE l_msg1_1.  
    ELSE.  
      zmsg = l_msg1.  
      zstas = 'E'.  
      zpartner = i_bu_partner.  
    ENDIF.

银行信息扩展

*****************************************************************************************  
* 银行信息  
  DATA: lv_bankl                  TYPE bnka-bankl.  
*        LS_BANK  TYPE CVIS_EI_CVI_BANKDETAIL,  
*        LT_BANK  TYPE CVIS_EI_BANKDETAIL_T.  
  DATA: ls_bankdetailid TYPE but0bk-bkext.  
  
  CLEAR lv_bankl.  
  CLEAR: bank_key, ls_bankdetailid.  
  
**----------------------------------------------------------------------*  
****银行信息的取数逻辑  
  IF i_bukrs(2) EQ 'CN'. " 国家=CN时取PA0009-BANKS,其他取PA9012-BANKS;  
  
    " 银行国家、银行代码、账户持有人、参考明细、银行账号、Swift、IBAN  
    SELECT SINGLE banks bankl emftx bkref bankn swift iban FROM pa0009  
      INTO ( bank_land, bank_key, acc_holder, bank_ref, bank_no, lv_swift, lv_iban )  
      WHERE pernr = i_bu_partner.  
  
    SELECT SINGLE banka INTO  bank_name FROM bnka WHERE bankl = bank_key. " 银行名称  
  
  ELSE.  
  
    " 海外银行表:取银行国家、账户持有人、银行账号、Swift、IBAN  
    SELECT SINGLE banks emftx bankn zswift zrn ziban FROM pa9012  
      INTO ( bank_land, acc_holder, bank_no, lv_swift, lv_zrn, lv_iban )  
      WHERE pernr = i_bu_partner.  
  
    " 取银行代码  
    IF i_swift IS NOT INITIAL.  
      SELECT SINGLE bankl FROM bnka INTO bank_key WHERE swift = i_swift  
                                                  AND banks = bank_land.  
  
    ELSE.  
      SELECT SINGLE bankl FROM bnka INTO bank_key WHERE swift = '' " 随机一条  
                                                  AND banks = bank_land.  
    ENDIF.  
    " 银行名称  
    SELECT SINGLE banka INTO bank_name FROM bnka WHERE bankl = bank_key.  
  
  ENDIF.  
**----------------------------------------------------------------------*    
  
**----------------------------------------------------------------------*  
  " 开始银行 BAPI 赋值  
  IF bank_key IS NOT INITIAL.  
*      SELECT SINGLE bankl FROM bnka INTO lv_bankl WHERE banka = bank_name.  
*      IF lv_bankl <> ''.  
    ls_bapibus1006_bankdetail-bank_key = bank_key. " 银行代码不为空,直接使用  
    ls_bapibus1006_bankdetailx-bank_key = 'X'.  
  ELSE.  
    "创建银行代码  
    DATA: lv_bank_ctry    LIKE bapi1011_key-bank_ctry,  
          lt_bank_address LIKE bapi1011_address OCCURS 0 WITH HEADER LINE,  
          lt_return_bk    LIKE bapiret2   OCCURS 0 WITH HEADER LINE,  
          l_msg_bk(255)   TYPE c,  
          bankkey         LIKE ls_bapibus1006_bankdetail-bank_key.  
  
  
    IF bank_land IS INITIAL.  
      lv_bank_ctry = i_bukrs(2).  
    ELSE.  
      lv_bank_ctry              = bank_land. " 银行国家  
    ENDIF.  
  
    " 银行名称, ODoo 传值  
    IF i_banka IS NOT INITIAL.  
      lt_bank_address-bank_name = i_banka.  
    ELSE.  
      lt_bank_address-bank_name = bank_name.  
    ENDIF.  
  
    " 查看是否内部给号银行  
    SELECT SINGLE bnkey FROM t005 INTO lv_bnkey WHERE land1 = lv_bank_ctry.  
  
    APPEND lt_bank_address.  
  
    " 内部给号银行会可以自动创建银行代码  
    IF bank_key IS INITIAL  AND lv_bnkey EQ '3'.  
  
      CLEAR: lt_return_bk,lt_return_bk[],bankkey.  
      CALL FUNCTION 'BAPI_BANK_CREATE'  
        EXPORTING  
          bank_ctry    = lv_bank_ctry  
*         bank_key     = bank_key  
          bank_address = lt_bank_address  
*         BANK_METHOD  =  
*         BANK_FORMATTING                    =  
*         BANK_ADDRESS1                      =  
*         I_XUPDATE    = 'X'  
*         I_CHECK_BEFORE_SAVE                =  
*         BANK_IBAN_RULE                     =  
*         BANK_B2B_SUPPORTED                 =  
*         BANK_COR1_SUPPORTED                =  
*         BANK_R_TRANSACTION_SUPPORTED       =  
        IMPORTING  
          return       = lt_return_bk  
*         BANKCOUNTRY  =  
          bankkey      = bankkey.  
  
    ELSE.  
      CLEAR: lt_return_bk,lt_return_bk[],bankkey.  
      CALL FUNCTION 'BAPI_BANK_CREATE'  
        EXPORTING  
          bank_ctry    = lv_bank_ctry  
          bank_key     = bank_key  
          bank_address = lt_bank_address  
        IMPORTING  
          return       = lt_return_bk  
*         BANKCOUNTRY  =  
          bankkey      = bankkey.  
    ENDIF.  
  
    CLEAR l_msg_bk.  
    LOOP AT lt_return_bk WHERE type = 'E' OR type = 'A'.  
      CONCATENATE lt_return_bk-message l_msg_bk INTO l_msg_bk SEPARATED BY ';'.  
      CONDENSE l_msg_bk.  
    ENDLOOP.  
  
    IF l_msg_bk = '' OR l_msg_bk IS INITIAL.  
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'             "commit--信息提交  
        EXPORTING  
          wait = 'X'.                                     "银行创建提交  
  
      ls_bapibus1006_bankdetail-bank_key = bankkey.  
      ls_bapibus1006_bankdetailx-bank_key = 'X'.  
    ENDIF.  
  
  ENDIF.  
  
  IF bank_land IS INITIAL.  
    lv_bank_ctry = i_bukrs(2).  
  ELSE.  
    lv_bank_ctry              = bank_land. " 银行国家  
  ENDIF.  
  
  ls_bapibus1006_bankdetail-bank_ctry       = lv_bank_ctry.  "银行国家  
  ls_bapibus1006_bankdetailx-bank_ctry = 'X'.  
  
  " 账户持有人  
  IF i_koinh IS NOT INITIAL. " 1、来自Odoo:Account Holder  
    ls_bapibus1006_bankdetail-accountholder   = i_koinh.      "账户持有人  
    ls_bapibus1006_bankdetailx-accountholder = 'X'.  
  ELSE.   
    ls_bapibus1006_bankdetail-accountholder   = acc_holder.  
    ls_bapibus1006_bankdetailx-accountholder = 'X'.  
  ENDIF.  
  
  
  " 银行账号  
  DATA: lv_len TYPE i.  
  IF i_bankn IS NOT INITIAL.  
*        ls_bapibus1006_bankdetail-bank_acct       = gs_alv-bank_no+0(18).    "银行账号  
    CLEAR lv_len.  
    lv_len = strlen( i_bankn ).  
    IF lv_len > 18.  
      ls_bapibus1006_bankdetail-bank_acct = i_bankn+0(18).  
      lv_len = lv_len - 18.  
      ls_bapibus1006_bankdetail-bank_ref = i_bankn+18(lv_len).  
  
      ls_bapibus1006_bankdetailx-bank_acct = 'X'.  
      ls_bapibus1006_bankdetailx-bank_ref = 'X'.  
    ELSE.  
      ls_bapibus1006_bankdetail-bank_acct       = i_bankn+0(18).    "银行账号  
      ls_bapibus1006_bankdetailx-bank_acct = 'X'.  
    ENDIF.  
  ELSE.  
    IF lv_bank_ctry = 'CN'.  
  
      IF bank_ref NE ''. " 如果参考明细不为空,先去参考明细前18位,后两位放到参考明细字段  
        IF strlen( bank_ref ) LT 18.  
          ls_bapibus1006_bankdetail-bank_acct = bank_ref.  
          ls_bapibus1006_bankdetailx-bank_acct = 'X'.  
        ELSE.  
          ls_bapibus1006_bankdetail-bank_acct = bank_ref+0(18). " 前 18 位  
          ls_bapibus1006_bankdetail-bank_ref = bank_ref+18(2). " 后两位  
  
          ls_bapibus1006_bankdetailx-bank_acct = 'X'.  
          ls_bapibus1006_bankdetailx-bank_ref = 'X'.  
        ENDIF.  
      ELSE. " 如果参考明细为空,直接取银行账号   
        ls_bapibus1006_bankdetail-bank_acct       = bank_no .  
        ls_bapibus1006_bankdetailx-bank_acct = 'X'.  
      ENDIF.  
  
    ELSE. " 非 CN 的国家,直接取银行账号  
      ls_bapibus1006_bankdetail-bank_acct       = bank_no .  
      ls_bapibus1006_bankdetailx-bank_acct = 'X'.  
    ENDIF.  
  ENDIF.  
  
  " Swift Code  
  IF i_swift IS NOT INITIAL.  
    ls_bapi2021_bank-swift_code = i_swift.  
  ELSE.  
    ls_bapi2021_bank-swift_code = lv_swift.  
  ENDIF.  
  
  " IBAN  
  IF i_iban IS NOT INITIAL.  
    ls_bapibus1006_bankdetail-iban = i_iban.  
    ls_bapibus1006_bankdetailx-iban = 'X'.  
  ELSE.  
    ls_bapibus1006_bankdetail-iban = lv_iban.  
    ls_bapibus1006_bankdetailx-iban = 'X'.  
  ENDIF.  
  
  
*  CLEAR: lt_return2, lt_return2[].  
*  CALL FUNCTION 'BAPI_BUPA_BANKDETAILS_GET'  
*    EXPORTING  
*      businesspartner = l_bpartner  
*      valid_date      = sy-datlo  
*    TABLES  
*      bankdetails     = lt_bankdetails  
*      return          = lt_return5.  
  
  IF lt_bankdetails[] IS NOT INITIAL.  
  
    CLEAR:lt_bankdetails,lt_return2[].  
    READ TABLE lt_bankdetails INTO ls_bapibus1006_bankdetail INDEX 1.  
    CALL FUNCTION 'BAPI_BUPA_BANKDETAIL_CHANGE'  
      EXPORTING  
        businesspartner  = i_bu_partner  
*       bankdetailid     = lt_bankdetails-bankdetailid  
        bankdetaildata   = ls_bapibus1006_bankdetail  
        bankdetaildata_x = ls_bapibus1006_bankdetailx  
      TABLES  
        return           = lt_return2.  
  
  ELSE.  
  
  
    CALL FUNCTION 'BAPI_BUPA_BANKDETAIL_ADD'  
      EXPORTING  
        businesspartner = i_bu_partner  
*       bankdetailid    = '0001'  
        bankdetaildata  = ls_bapibus1006_bankdetail  
*       BANKDETAILDATA_X       =  
      TABLES  
        return          = lt_return2.  
  ENDIF.  
  
  CLEAR l_msg2.  
  LOOP AT lt_return2 WHERE type = 'E' OR type = 'A'.  
    CONCATENATE lt_return2-message l_msg2 INTO l_msg2 SEPARATED BY ';'.  
    CONDENSE l_msg2.  
  ENDLOOP.  
  
  IF l_msg2 = ''.  
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'  
      EXPORTING  
        wait = 'X'.  
  
    IF ls_bapi2021_bank-swift_code IS NOT INITIAL.  
  
      SELECT COUNT(*) FROM bnka WHERE swift = ls_bapi2021_bank-swift_code  
                                  AND bankl = bank_key  
                                  AND banks = lv_bank_ctry.  
      IF sy-subrc NE 0. " 如果没找到 Swift 信息,就进行更新  
  
        UPDATE bnka SET swift = ls_bapi2021_bank-swift_code WHERE bankl = bank_key  
                                                             AND  banks =  lv_bank_ctry.  
        IF sy-subrc = 0.  
          COMMIT WORK AND WAIT.  
        ELSE.  
          ROLLBACK WORK.  
          RETURN.  
        ENDIF.  
      ENDIF.  
    ENDIF.  
  ELSE.   
  
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'  
*       IMPORTING  
*         RETURN        =  
      .  
  ENDIF.  
*  ENDIF.  
  
**----------------------------------------------------------------------*  
** BP: 银行明细  
  
  IF i_bukrs(2) NE 'CN'.  
  
  
    SELECT SINGLE bkvid FROM but0bk INTO ls_bankdetailid WHERE partner = i_bu_partner.  
  
    IF i_zrn IS NOT INITIAL.  
      l_bkext = i_zrn.  
    ELSE.  
      l_bkext = lv_zrn.  
      IF l_bkext IS INITIAL.  
        SELECT SINGLE bkext FROM but0bk INTO l_bkext WHERE partner = i_bu_partner.  
      ENDIF.  
    ENDIF.  
  
    IF l_bkext IS NOT INITIAL.  
  
      UPDATE but0bk SET bkext = l_bkext WHERE partner = l_bpartner AND banks = lv_bank_ctry  
                                          AND bankl = bank_key.  
      IF sy-subrc = 0.  
        COMMIT WORK AND WAIT.  
      ELSE.  
        ROLLBACK WORK.  
        RETURN.  
      ENDIF.  
  
  
*      CALL FUNCTION 'BAPI_BUPA_BANKDETAIL_NUMBERS'  
*        EXPORTING  
*          businesspartner         = i_bu_partner  
*          bankdetailid            = ls_bankdetailid  
*          bankdetaildata          = l_bkext " but0bk-bkext  Bank Details ID in External System  
*        IMPORTING  
*          bankdetailidout         = ls_bankdetailidout  
*          externalbankdetailidout = ls_externalbankdetailidout  
*        TABLES  
*          return                  = lt_return3.  
*  
*      CLEAR l_msg3.  
*      LOOP AT lt_return3 WHERE type = 'E' OR type = 'A'.  
*        CONCATENATE lt_return3-message l_msg3 INTO l_msg3 SEPARATED BY ';'.  
*        CONDENSE l_msg3.  
*      ENDLOOP.  
*  
*      IF l_msg3 = ''.  
*        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'  
*          EXPORTING  
*            wait = 'X'.  
*      ELSE.  
*  
*        zstas = 'E'.  
*        zpartner = i_bu_partner.  
*        zmsg = '银行信息创建不完整,请检查!'.  
*  
*        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'  
**       IMPORTING  
**         RETURN        =  
*          .  
    ENDIF.  
  ENDIF.  
*ENDIF.  
*---------------------------供应商扩展开始---------------------------------*  
*  财务数据部分  
  
  SELECT SINGLE bukrs FROM lfb1 INTO lv_bukrs WHERE lifnr = l_bpartner AND  bukrs = i_bukrs.  
  IF sy-subrc NE 0. " 如果不存在,就创建财务数据  
    CLEAR: lt_return4,lt_return4[].  
    CALL FUNCTION 'BAPI_BUPA_ROLE_ADD_2'  
      EXPORTING  
        businesspartner             = l_bpartner  
        businesspartnerrolecategory = 'FLVN00'  
*       ALL_BUSINESSPARTNERROLES    = ' '  
        businesspartnerrole         = 'FLVN00'  
*       DIFFERENTIATIONTYPEVALUE    =  
*       VALIDFROMDATE               =  
*       VALIDUNTILDATE              = '99991231'  
      TABLES  
        return                      = lt_return4.  
  
    CLEAR l_msg4.                                           "20160721新增  
    LOOP AT lt_return4 WHERE type = 'E' OR type = 'A'.    " OR TYPE = 'W'.  
      CONCATENATE lt_return4-message l_msg4 INTO l_msg4 SEPARATED BY ';'.  
      CONDENSE l_msg4.  
    ENDLOOP.  
    IF l_msg4 = ''.  
***      IF LT_RETURN4[] IS INITIAL.                                      "20160721注销  
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'                                "角色信息提交(即角色创建成功)  
        EXPORTING  
          wait = 'X'.  
  
      l_vendor = l_bpartner.  
      CLEAR: ls_master_data,ls_company,lt_master_data.  
      ls_master_data-header-object_task              = 'M'.  
      ls_master_data-header-object_instance-lifnr    = l_vendor.  
  
      DATA:lv_ktokk1 TYPE tbc001-ktokk.  
      CLEAR lv_ktokk1.  
      SELECT SINGLE ktokk FROM tbc001 INTO lv_ktokk1 WHERE bu_group = 'V004'.  
      ls_master_data-central_data-central-data-ktokk  = lv_ktokk1.                    "供应商帐户组  
      ls_master_data-central_data-central-datax-ktokk = 'X'.                          "供应商帐户组  
  
*        LS_MASTER_DATA-COMPANY_DATA-COMPANY            = ''.                      "COMPANY关联类型即LS_COMPANY的关联类型  
      ls_company-task                                = 'M'.  
      ls_company-data_key-bukrs                      = i_bukrs.             " 来自Odoo,公司代码  
      ls_company-data-akont                          = '2202020100'.             "统驭科目  
      ls_company-datax-akont                         = 'X'.  
      ls_company-data-zterm                          = 'K201'.             "付款条件  
      ls_company-datax-zterm                         = 'X'.  
      ls_company-data-reprf                          = 'X'.              "检查重复发票  
      ls_company-datax-reprf                         = 'X'.  
  
      APPEND ls_company TO ls_master_data-company_data-company.  
      APPEND ls_master_data TO  lt_master_data-vendors[].  
  
  
      vmd_ei_api=>initialize( ).  
  
      CALL METHOD vmd_ei_api=>maintain_bapi                                      "VMD_EI_API=>MAINTAIN_DIRECT_INPUT  
        EXPORTING  
          is_master_data           = lt_master_data  
        IMPORTING  
          es_master_data_correct   = l1  
          es_message_correct       = l2  
          es_master_data_defective = l3  
          es_message_defective     = l4.  
  
      IF l4-is_error = ''.  
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'  
          EXPORTING  
            wait = 'X'.  
      ELSE.  
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.  
  
        DATA ls_l4 LIKE LINE OF l4-messages.  
        LOOP AT l4-messages INTO ls_l4 WHERE type = 'E' OR type = 'A'.  
          CONCATENATE l_msgl4 ls_l4-message INTO l_msgl4 SEPARATED BY ';'.  
          CONDENSE l_msgl4.  
        ENDLOOP.  
  
      ENDIF.  
  
    ELSE.  
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'  
*       IMPORTING  
*         RETURN        =  
        .  
    ENDIF.  
  ENDIF.  
  
*---------------------------供应商扩展结束---------------------------------*  
  IF l_msg1 = '' AND l_msg2 = '' AND l_msg4 = '' AND l_msg3 = '' AND l4-messages[] IS INITIAL.  
    zstas = 'S'.  
    CONCATENATE '员工供应商和银行创建成功,编号为' l_bpartner INTO zmsg.  
    CONDENSE zmsg.  
    zpartner = l_bpartner.  
  
  
    CALL METHOD cl_gui_frontend_services=>get_user_name  
      CHANGING  
        user_name            = c_str  
      EXCEPTIONS  
        cntl_error           = 1  
        error_no_gui         = 2  
        not_supported_by_gui = 3  
        OTHERS               = 4.  
  
    CALL METHOD cl_gui_cfw=>flush  
      EXCEPTIONS  
        cntl_system_error = 1  
        cntl_error        = 2.  
  
    CALL 'ThUsrInfo' ID 'OPCODE' FIELD opcode_usr_attr  
              ID'TERMINAL' FIELD terminal.  
  
  
    l_bp_employee-zpartner = zpartner.  
    l_bp_employee-erdat = sy-datum.  
    l_bp_employee-erzet = sy-uzeit.  
    l_bp_employee-ernam = c_str.  
    l_bp_employee-zmsg = zmsg.  
    l_bp_employee-zstas = 'S'.  
    l_bp_employee-zf_name = i_f_name.  
    l_bp_employee-bukrs = i_bukrs.  
    l_bp_employee-banka = i_banka.  
    l_bp_employee-koinh = i_koinh.  
    l_bp_employee-bankn = i_bankn.  
    l_bp_employee-zrn = i_zrn.  
    l_bp_employee-iban = i_iban.  
    l_bp_employee-swift = i_swift.  
    l_bp_employee-terminal = terminal.  
  
    MODIFY zodoo_bp_return FROM l_bp_employee.  
  ELSE.  
    zstas = 'E'.  
    CONCATENATE l_msg1 l_msg2 l_msg3 l_msgl4 l_msg4 INTO zmsg.  
    CONDENSE zmsg.  
    zpartner  = l_bpartner.  
  
  
    l_bp_employee-zpartner = zpartner.  
    l_bp_employee-erdat = sy-datum.  
    l_bp_employee-erzet = sy-uzeit.  
    l_bp_employee-ernam = c_str.  
    l_bp_employee-zmsg = zmsg.  
    l_bp_employee-zstas = 'E'.  
    l_bp_employee-zf_name = i_f_name.  
    l_bp_employee-bukrs = i_bukrs.  
    l_bp_employee-banka = i_banka.  
    l_bp_employee-koinh = i_koinh.  
    l_bp_employee-bankn = i_bankn.  
    l_bp_employee-zrn = i_zrn.  
    l_bp_employee-iban = i_iban.  
    l_bp_employee-swift = i_swift.  
    l_bp_employee-terminal = terminal.  
  
    MODIFY zodoo_bp_return FROM l_bp_employee.  
  ENDIF.

测试功能模块,结果如下:

图片.png

通过 CMD_EI_API 更新客户

*&---------------------------------------------------------------------*
*& Report zbp_create_simple
*&---------------------------------------------------------------------*
*& Create basic BP with vendor role via
*& Central API class CL_MD_BP_MAINTAIN
*&---------------------------------------------------------------------*
REPORT zbp_create_simple.

CONSTANTS:
  c_task_insert   TYPE bus_ei_object_task VALUE 'I'.

DATA:
  s_bp            TYPE cvis_ei_extern,
  t_bp            TYPE cvis_ei_extern_t,
  t_address       TYPE bus_ei_bupa_address_t,
  t_role          TYPE bus_ei_bupa_roles_t,
  t_ident_numbers TYPE bus_ei_bupa_identification_t,
  t_taxnumbers    TYPE bus_ei_bupa_taxnumber_t,
  t_return        TYPE bapiretm,
  v_bu_partner    TYPE bu_partner,
  v_error         TYPE abap_bool.

PARAMETERS:
  p_test TYPE abap_bool AS CHECKBOX.

START-OF-SELECTION.

*------------------------------------------------------------------------------
* Create GUID for new BP
*------------------------------------------------------------------------------
  TRY.
      DATA(v_guid) = cl_system_uuid=>if_system_uuid_static~create_uuid_c32( ).
    CATCH cx_uuid_error INTO DATA(r_uuid_exc).
      MESSAGE r_uuid_exc->get_text( ) TYPE 'E'.
  ENDTRY.

*------------------------------------------------------------------------------
* Header and common central data
*------------------------------------------------------------------------------
  s_bp-partner-header-object_task = c_task_insert. "'I' for new BP
  s_bp-partner-header-object_instance-bpartnerguid = v_guid.

* Category: 1 for Person, 2 for Organization, 3 for Group
  s_bp-partner-central_data-common-data-bp_control-category = '2'.
* The grouping depends on the system settings
  s_bp-partner-central_data-common-data-bp_control-grouping = 'ZCRE'.

  s_bp-partner-central_data-common-data-bp_centraldata-searchterm1 = 'SAP SE'.
  s_bp-partner-central_data-common-data-bp_organization-name1  = 'SAP SE'.
  s_bp-partner-central_data-common-data-bp_organization-name2  = 'Test BP'.
* Mark as changed
  s_bp-partner-central_data-common-datax-bp_organization-name1 = abap_true.
  s_bp-partner-central_data-common-datax-bp_organization-name2 = abap_true.

*------------------------------------------------------------------------------
* VAT number (needed for BPs located in the EU)
*
* Number is normally validated by function module VAT_REGISTRATION_NUMBER_CHECK
* Tax types are stored in table TFKTAXNUMTYPE
*------------------------------------------------------------------------------
  APPEND INITIAL LINE TO t_taxnumbers ASSIGNING FIELD-SYMBOL(<fs_taxnumbers>).
  <fs_taxnumbers>-task               = c_task_insert.
  <fs_taxnumbers>-data_key-taxtype   = 'DE0'.
  <fs_taxnumbers>-data_key-taxnumber = 'DE143454214'. "SAP SE VAT reg. number
  s_bp-partner-central_data-taxnumber-taxnumbers = t_taxnumbers.

*------------------------------------------------------------------------------
* Address data
*------------------------------------------------------------------------------
  APPEND INITIAL LINE TO t_address ASSIGNING FIELD-SYMBOL(<fs_address>).
  <fs_address>-task = c_task_insert.
* Operations are store in table TB008S
  <fs_address>-data_key-operation           = 'XXDFLT'. "Standard operation
  <fs_address>-data-postal-data-city        = 'Walldorf'.
  <fs_address>-data-postal-data-postl_cod1  = '69190'.
  <fs_address>-data-postal-data-street      = 'SAP street'.
  <fs_address>-data-postal-data-country     = 'DE'.
  <fs_address>-data-postal-data-langu       = 'E'.

* Mark as changed
  <fs_address>-data-postal-datax-city       = abap_true. 
  <fs_address>-data-postal-datax-postl_cod1 = abap_true.
  <fs_address>-data-postal-datax-street     = abap_true.
  <fs_address>-data-postal-datax-country    = abap_true.
  <fs_address>-data-postal-datax-region     = abap_true.
  <fs_address>-data-postal-datax-langu      = abap_true.

* Add address to main structure
  s_bp-partner-central_data-address-addresses = t_address.

*------------------------------------------------------------------------------
* Roles
*------------------------------------------------------------------------------
  APPEND INITIAL LINE TO t_role ASSIGNING FIELD-SYMBOL(<fs_role>).
  <fs_role>-task              = c_task_insert.
  <fs_role>-data_key          = 'FLVN01'. "Role key - Vendor
*<fs_role>-data_key          = 'FLCU01'. "Role key - customer

* Add role to main structure
  s_bp-partner-central_data-role-roles = t_role.

*------------------------------------------------------------------------------
* Validate data
*------------------------------------------------------------------------------
  cl_md_bp_maintain=>validate_single(
    EXPORTING
      i_data        = s_bp
    IMPORTING
      et_return_map = DATA(t_return_map)
  ).

  IF line_exists( t_return_map[ type = 'E' ] ) OR
     line_exists( t_return_map[ type = 'A' ] ).
    LOOP AT t_return_map INTO DATA(s_return_map).
      WRITE:/ s_return_map-message.
    ENDLOOP.
    EXIT.
  ENDIF.

*------------------------------------------------------------------------------
* Call API
*------------------------------------------------------------------------------
* Add single BP to IMPORTING table
  INSERT s_bp INTO TABLE t_bp.

  cl_md_bp_maintain=>maintain(
    EXPORTING
      i_data     = t_bp
      i_test_run = p_test
    IMPORTING
      e_return   = t_return
  ).

* Check result
  LOOP AT t_return INTO DATA(s_return).
    LOOP AT s_return-object_msg INTO DATA(s_msg).
      IF s_msg-type = 'E' OR s_msg-type = 'A'.
*       Error occurred
        v_error = abap_true.
      ENDIF.
      WRITE:/ s_msg-message.
    ENDLOOP.
  ENDLOOP.
  IF v_error IS INITIAL.
    CASE p_test.
      WHEN abap_true.
*       Test mode
        WRITE:/ |BP data is ok.|.
      WHEN abap_false.
*       Non-test mode => Perform COMMIT
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
*       Get number of new BP (it's not returned by the API)
        IMPORT lv_partner TO v_bu_partner FROM MEMORY ID 'BUP_MEMORY_PARTNER'.
        WRITE:/ |Business Partner { v_bu_partner } has been created.|.
    ENDCASE.
  ENDIF.

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情