BP的心得
BP的概念
从后勤物流角度来看,后勤主要主数据是客户主数据和供应商主数据。我们在S/4HANA中学到的第一件事是客户 - 供应商集成(CVI),也称为业务合作伙伴(BP)。
在传统SAP ERP中,客户和供应商是作为两个不同的功能存在的。而在SAP S/4 HANA中,将两者统一维护为Business partner。所以传统的ERP系统中的事务代码都将被废弃,在SAP S/4 HANA 中统一通过事务代码BP使用角色的方式来实现的。
所以,传统SAP ERP 用户在转换为SAP S/4 HANA时,是需要对客户和供应商的主数据做调整的。
以上的官方解释。
个人理解就是不管组织还是个人,都是企业的一个伙伴,也就是BP,当与他发生采购业务时,那么就分配采购角色,维护供应商信息;客户同理;类似的还有UKM信贷角色,房地产管理的各类结算单位,零售业务的SITE角色之类。
业务都基于角色开展,BP是统筹的意思。当然非公司的个人也差不多。
业务方案实践
基于以上BP的个人理解,我个人倾向与把BP/客户/供应商的编码统一处理。当然有些升级项目可能旧数据存在两边的冲突,但还是建议变革做统一。
最简化的配置方案如下:
1.BP分组示例规划:
分组 | 描述 |
---|---|
C001 | 客户分组1 |
C002 | 客户分组2 |
C003 | 客户分组3 |
V001 | 供应商分组1 |
V002 | 供应商分组2 |
V003 | 供应商分组3 |
核心点,客户与供应商的分组也是6个组,两边组1 1对应。
当然如果要做一些字段状态组控制或合作伙伴控制,还可以在客户/供应商账户组层配置。
2.号码段规划如下:
客户/供应商全部一个号码段,号码段为1-ZZZZZZZZZZ,所有的客户/供应商账户组都对应这个无意义的全号分组。
在BP层对BP的分组进行号码段规划,设置合适的编号范围。
在配置 跨应用组件->主数据同步->客户/供应商集成->业务伙伴设置->供应商集成的设置->供应商集成的字段分配->分配键值->定义方向业务伙伴到供应商的编号分配
设置供应商账户组与BP分组的关系,1比1就OK,同时配置相同号码。
客户类似。
实现业务规则就是建BP统一的跨模块的方案,不论是供应商偶尔有销售也许需要扩客户,还是反过来,都可以用统一的BP编码扩充对应角色。
基于这样,才能发挥BP集成角色的意义。
**当然系统支持BP角色与供应商/客户有不同的编码。**那么结果就是BP是多余的,客户供应商还分属不同领域。也就没有BP存在的意义,仅仅是系统要求的。这样不符合BP设计的初衷,不建议。
数据处理
在做批量数据处理时,其实传统的LSMW录屏/MASS批修改还是可以使用的。但是录屏体验其实比较差。
这里如果做期初的数据批处理,如果没有ABAP开发独立程序,建议使用LTMC新功能,用WEB端实现导入。
网上文档有一些,晚点在整理。
关于ABAP实现,下一部分。
BP对象的ABAP实现
目前没发现SAP有对BP的BAPI或者EDI接口,过去客户/供应商的方式基本也无法使用了。
很多项目还是需要这方面的接口,批处理程序,甚至自定义的维护界面,系统内审批功能生效等等业务需求。
下面部分贴些BP处理的代码仅供参考。
1.用到的类型对象
DATA:
lt_data TYPE cvis_ei_extern_t
, ls_data TYPE cvis_ei_extern
, ls_address_help TYPE bus_ei_bupa_address
, ls_address_usages TYPE bus_ei_bupa_addressusage
, ls_vend_company TYPE vmds_ei_company
, ls_with_tax TYPE vmds_ei_wtax_type
, ls_role TYPE bus_ei_bupa_roles
, lt_return2 TYPE TABLE OF bapiret2
.
DATA: lv_guid TYPE bu_partner_guid.
DATA:
ls_return TYPE cvis_bp_return,
lv_task TYPE c, " I新建 U 更新
lv_task_v TYPE c, " 供应商逻辑处理
lv_task_c TYPE c, " 客户逻辑处理
ls_but000 TYPE but000,
ls_kna1 TYPE kna1,
ls_lfa1 TYPE lfa1,
ls_alv TYPE zscmt0001,
lt_bapiret2 TYPE TABLE OF bapiret2,
ls_bapiret2 TYPE bapiret2,
lv_bp TYPE bu_partner,
lv_create_applog TYPE boolean.
2.BP维护主题流程```
*—判断创建还是修改
"信贷限额
SELECT SINGLE * INTO ls_but000
FROM but000 WHERE partner = cs_data-partner.
IF sy-subrc = 0.
lv_task = 'U'.
ELSE.
lv_task = 'I'.
ENDIF.
lv_bp = cs_data-partner.
*--- 清空全局参数
CALL FUNCTION 'BUP_MEMORY_CENTRAL_INIT'.
*--- 生成或者获取全局GUID
CASE lv_task.
WHEN 'I'.
CALL FUNCTION 'GUID_CREATE'
IMPORTING
ev_guid_32 = ls_data-partner-header-object_instance-bpartnerguid.
WHEN 'U'.
SELECT SINGLE partner_guid
FROM but000
INTO lv_guid
WHERE partner = lv_bp.
ls_data-partner-header-object_instance-bpartnerguid = lv_guid.
ls_data-partner-header-object_instance-bpartner = lv_bp.
WHEN OTHERS.
ENDCASE.
ls_data-partner-header-object_task = lv_task.
"BP 角色
PERFORM f_add_role USING lv_bp
cs_data
CHANGING ls_data.
"基本视图
PERFORM f_add_bp_general USING lv_bp
lv_task
cs_data
CHANGING ls_data.
"一般地址信息/电话 /传真/邮箱
PERFORM f_add_bp_address USING lv_bp
lv_task
cs_data
CHANGING ls_data.
"银行信息
PERFORM F_BANK_ACC USING LV_BP
CS_DATA
CHANGING LS_DATA.
"供应商信息
PERFORM f_add_sup_general USING lv_bp
lv_task
cs_data
CHANGING ls_data.
"客户信息
PERFORM f_add_cust_general USING lv_bp
lv_task
cs_data
CHANGING ls_data.
"信贷限额
PERFORM f_add_ukm_general USING lv_bp
lv_task
cs_data
CHANGING ls_data.
"整合处理
IF lv_task = 'I'.
IF lv_task_v = 'X'.
SELECT COUNT(*) FROM lfa1 WHERE lifnr = lv_bp.
IF sy-subrc <> 0.
ls_data-ensure_create-create_vendor = abap_true.
ENDIF.
ENDIF.
IF lv_task_c = 'X'.
SELECT COUNT(*) FROM kna1 WHERE kunnr = lv_bp.
IF sy-subrc <> 0.
ls_data-ensure_create-create_customer = abap_true.
ENDIF.
ENDIF.
ENDIF.
APPEND ls_data TO lt_data.
"全局数据校验
cl_md_bp_maintain=>validate_single(
EXPORTING i_data = ls_data
IMPORTING et_return_map = DATA(lt_return_map) ).
"数据校验消息处理
LOOP AT lt_return_map ASSIGNING FIELD-SYMBOL(<ls_return_map>)
WHERE type = 'E' OR type = 'A'.
MOVE-CORRESPONDING <ls_return_map> TO et_return.
APPEND et_return.
ev_status = 'E'.
ENDLOOP.
"数据提交处理
IF ev_status = 'E'.
RETURN.
ELSE.
cl_md_bp_maintain=>maintain(
EXPORTING i_data = lt_data
IMPORTING e_return = DATA(lt_return) ).
ENDIF.
3.角色信息
FORM f_add_role USING
u_bp TYPE char10
u_alv TYPE zscmt0001
CHANGING
c_data TYPE cvis_ei_extern.
DATA: lt_but100 TYPE TABLE OF but100,
ls_but100 TYPE but100,
lt_roles TYPE bus_ei_bupa_roles_t,
ls_roles TYPE bus_ei_bupa_roles.
SELECT *
INTO TABLE lt_but100
FROM but100
WHERE partner = u_bp.
"财务供应商角色
READ TABLE lt_but100 INTO ls_but100 WITH KEY partner = u_bp
rltyp = 'FLVN00'.
IF sy-subrc <> 0.
IF u_alv-flvn00 = 'X'.
CLEAR ls_roles.
ls_roles-task = 'I'.
ls_roles-data_key = 'FLVN00'.
ls_roles-data-valid_from = sy-datum .
ls_roles-data-valid_to = '99991231' .
APPEND ls_roles TO lt_roles.
ENDIF.
ENDIF.
"财务客户角色
READ TABLE lt_but100 INTO ls_but100 WITH KEY partner = u_bp
rltyp = 'FLCU00'.
IF sy-subrc <> 0.
IF u_alv-flcu00 = 'X'.
CLEAR ls_roles.
ls_roles-task = 'I'.
ls_roles-data_key = 'FLCU00'.
ls_roles-data-valid_from = sy-datum .
ls_roles-data-valid_to = '99991231' .
APPEND ls_roles TO lt_roles.
ENDIF.
ENDIF.
"客户角色
READ TABLE lt_but100 INTO ls_but100 WITH KEY partner = u_bp
rltyp = 'FLCU01'.
IF sy-subrc <> 0.
IF u_alv-flcu01 = 'X' .
CLEAR ls_roles.
ls_roles-task = 'I'.
ls_roles-data_key = 'FLCU01'.
ls_roles-data-valid_from = sy-datum .
ls_roles-data-valid_to = '99991231' .
APPEND ls_roles TO lt_roles.
ENDIF.
ENDIF.
"采购角色
READ TABLE lt_but100 INTO ls_but100 WITH KEY partner = u_bp
rltyp = 'FLVN01'.
IF sy-subrc <> 0 .
IF u_alv-flvn01 = 'X' .
CLEAR ls_roles.
ls_roles-task = 'I'.
ls_roles-data_key = 'FLVN01'.
ls_roles-data-valid_from = sy-datum .
ls_roles-data-valid_to = '99991231' .
APPEND ls_roles TO lt_roles.
ENDIF.
ENDIF.
"信用角色
READ TABLE lt_but100 INTO ls_but100 WITH KEY partner = u_bp
rltyp = 'UKM000'.
IF sy-subrc <> 0 .
IF u_alv-fukm000 = 'X' .
CLEAR ls_roles.
ls_roles-task = 'I'.
ls_roles-data_key = 'UKM000'.
ls_roles-data-valid_from = sy-datum .
ls_roles-data-valid_to = '99991231' .
APPEND ls_roles TO lt_roles.
ENDIF.
ENDIF.
IF lt_roles IS NOT INITIAL.
c_data-partner-central_data-role-roles = lt_roles.
ENDIF.
ENDFORM.
4.BP基本信息
FORM f_add_bp_general USING
u_bp TYPE char10
u_task TYPE char1
u_alv TYPE zscmt0001
CHANGING c_data TYPE cvis_ei_extern.
c_data-partner-header-object_instance-bpartner = u_bp.
c_data-partner-header-object_task = u_task.
c_data-partner-central_data-common-data-bp_control-category = '2'."类别
c_data-partner-central_data-common-data-bp_control-grouping = u_alv-bu_group."分组 控制视图 号码段
c_data-partner-central_data-common-data-bp_centraldata-searchterm1 = u_alv-bu_sort1_txt ."搜索项1
* c_data-partner-central_data-common-data-bp_centraldata-searchterm2 = u_alv-sortl2 ."名称2 ."搜索项2
c_data-partner-central_data-common-data-bp_centraldata-partnerlanguage = u_alv-langu ."语言
c_data-partner-central_data-common-data-bp_centraldata-centralblock = u_alv-zdelete."集中冻结
c_data-partner-central_data-common-data-bp_organization-name1 = u_alv-name1."' ."名称1
c_data-partner-central_data-common-data-bp_organization-name2 = u_alv-name2 ."名称2
* c_data-partner-central_data-common-data-bp_organization-name3 = u_alv-name3 ."名称3
IF u_task = 'U' .
c_data-partner-central_data-common-datax-bp_centraldata-searchterm1 = abap_true ."搜索项1
* c_data-partner-central_data-common-datax-bp_centraldata-searchterm2 = abap_true ."名称2 ."搜索项2
c_data-partner-central_data-common-datax-bp_centraldata-partnerlanguage = abap_true .
c_data-partner-central_data-common-datax-bp_centraldata-centralblock = abap_true.
c_data-partner-central_data-common-datax-bp_organization-name1 = abap_true.
c_data-partner-central_data-common-datax-bp_organization-name2 = abap_true ."名称2
* c_data-partner-central_data-common-datax-bp_organization-name3 = abap_true ."名称3
ENDIF.
ENDFORM.
5.BP地址信息
FORM f_add_bp_address USING u_bp TYPE char10
u_task TYPE char1
u_alv TYPE zscmt0001
CHANGING c_data TYPE cvis_ei_extern.
DATA:
lv_guid TYPE bu_partner_guid,
ls_but000 TYPE but000,
ls_address_help TYPE bus_ei_bupa_address,
ls_address_usages TYPE bus_ei_bupa_addressusage,
ls_phone TYPE bus_ei_bupa_telephone,
lt_phone TYPE bus_ei_bupa_telephone_t,
ls_fax TYPE bus_ei_bupa_fax,
lt_fax TYPE bus_ei_bupa_fax_t,
ls_smtp TYPE bus_ei_bupa_smtp,
lt_smtp TYPE bus_ei_bupa_smtp_t.
ls_address_help-task = u_task.
CLEAR lv_guid.
CASE u_task.
WHEN 'U'.
SELECT SINGLE address_guid
FROM but020
INTO lv_guid
WHERE partner = u_bp.
ls_address_help-data_key-guid = lv_guid.
WHEN 'I'.
CALL FUNCTION 'GUID_CREATE'
IMPORTING
ev_guid_32 = ls_address_help-data_key-guid.
WHEN OTHERS.
ENDCASE.
ls_address_help-task = u_task.
ls_address_help-data-postal-data-city = u_alv-zshi ."城市
ls_address_help-data-postal-data-standardaddress = 'X'.
ls_address_help-data-postal-data-postl_cod1 = u_alv-post_code1."邮政编码/城市
ls_address_help-data-postal-data-street = u_alv-zdizhi.
* LS_ADDRESS_HELP-DATA-POSTAL-DATA-HOUSE_NO = U_ALV-HSNM1 ."门牌号
ls_address_help-data-postal-data-country = u_alv-country ."国家
ls_address_help-data-postal-data-countryiso = u_alv-country ."国家
* LS_ADDRESS_HELP-DATA-POSTAL-DATA-REGION = U_ALV-REGIO ."地区
ls_address_help-data-postal-data-time_zone = 'UTC+8' ."defalut
ls_address_help-data-postal-data-langu = u_alv-langu ."语言
ls_address_help-data-postal-data-languiso = u_alv-langu ."语言
* IF U_ALV-POBXCTY IS NOT INITIAL.
* LS_ADDRESS_HELP-DATA-POSTAL-DATA-POBOX_CTRY = U_ALV-POBXCTY."通讯国家
* LS_ADDRESS_HELP-DATA-POSTAL-DATA-PO_BOX_REG = U_ALV-POBXREG."通讯地区
* LS_ADDRESS_HELP-DATA-POSTAL-DATA-POSTL_COD2 = U_ALV-PSTCD2."通讯邮编
* LS_ADDRESS_HELP-DATA-POSTAL-DATA-PO_BOX_CIT = U_ALV-POBXLOC."通讯城市
* ENDIF.
IF u_task = 'U'.
ls_address_help-data-postal-datax-city = abap_true.
ls_address_help-data-postal-datax-standardaddress = abap_true.
ls_address_help-data-postal-datax-postl_cod1 = abap_true.
ls_address_help-data-postal-datax-street = abap_true.
* LS_ADDRESS_HELP-DATA-POSTAL-DATAX-HOUSE_NO = ABAP_TRUE.
ls_address_help-data-postal-datax-country = abap_true.
ls_address_help-data-postal-datax-countryiso = abap_true.
* LS_ADDRESS_HELP-DATA-POSTAL-DATAX-REGION = ABAP_TRUE.
ls_address_help-data-postal-datax-time_zone = abap_true.
ls_address_help-data-postal-datax-langu = abap_true.
ls_address_help-data-postal-datax-langu_iso = abap_true.
* IF U_ALV-POBXCTY IS NOT INITIAL.
* LS_ADDRESS_HELP-DATA-POSTAL-DATAX-POBOX_CTRY = ABAP_TRUE.
* LS_ADDRESS_HELP-DATA-POSTAL-DATAX-PO_BOX_REG = ABAP_TRUE.
* LS_ADDRESS_HELP-DATA-POSTAL-DATAX-POSTL_COD2 = ABAP_TRUE.
* LS_ADDRESS_HELP-DATA-POSTAL-DATAX-PO_BOX_CIT = ABAP_TRUE.
* ENDIF.
ENDIF.
APPEND ls_address_help TO c_data-partner-central_data-address-addresses.
ENDFORM.
6.供应商信息
FORM f_add_sup_general USING u_bp TYPE char10
u_task TYPE c
u_alv TYPE zscmt0001
CHANGING c_data TYPE cvis_ei_extern.
DATA: lt_company TYPE vmds_ei_company_t,
ls_company TYPE vmds_ei_company,
lt_purchasing TYPE vmds_ei_purchasing_t,
ls_purchasing TYPE vmds_ei_purchasing,
lt_functions TYPE vmds_ei_functions_t.
"供应商基本数据
IF u_alv-flvn00 = 'X' OR u_alv-flvn01 = 'X'.
SELECT SINGLE *
INTO @DATA(ls_lfa1)
FROM lfa1
WHERE lifnr = @u_alv-partner.
IF sy-subrc EQ 0.
c_data-vendor-header-object_instance-lifnr = u_bp.
c_data-vendor-header-object_task = 'U'.
IF u_alv-bu_group = 'A001'.
c_data-vendor-central_data-central-datax-vbund = abap_true.
ENDIF.
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATAX-STENR = ABAP_TRUE."税号
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATAX-STCEG = ABAP_TRUE."增值税登记号 20位
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATAX-FITYP = ABAP_TRUE."税收类型
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATAX-STCDT = ABAP_TRUE."税号类型\
ELSE.
c_data-vendor-header-object_task = 'I'.
IF u_alv-bu_group = 'A001'.
c_data-vendor-central_data-central-data-vbund = u_alv-partner+4(6)."贸易伙伴
ENDIF.
ENDIF.
*
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATA-STCEG = U_ALV-STCEG."增值税登记号 20位
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATA-FITYP = U_ALV-AFITP."税收类型
* C_DATA-VENDOR-CENTRAL_DATA-CENTRAL-DATA-STCDT = U_ALV-ATOID."税号类型
ENDIF.
" 供应商公司数据
IF u_alv-flvn00 = 'X'.
SELECT SINGLE *
INTO @DATA(ls_lfb1)
FROM lfb1
WHERE lifnr = @u_alv-partner
AND bukrs = @u_alv-bukrs.
IF sy-subrc = 0.
ls_company-task = 'U'.
ls_company-datax-akont = abap_true."统御科目
ls_company-datax-zterm = abap_true."付款条件
* LS_COMPANY-DATAX-SPERR = ABAP_TRUE."所选公司代码 过账冻结
* LS_COMPANY-DATAX-GUZTE = ABAP_TRUE."信用记录条件
* LS_COMPANY-DATAX-ALTKN = ABAP_TRUE."先前的账户号
* LS_COMPANY-DATAX-ZWELS = ABAP_TRUE."付款方式
ELSE.
ls_company-task = 'I'.
ENDIF.
ls_company-data_key = u_alv-bukrs.
ls_company-data-akont = u_alv-akont_ven."统御科目
ls_company-data-zterm = u_alv-zterm_ven."付款条件
* LS_COMPANY-DATA-SPERR = U_ALV-SPERB_B."所选公司代码 过账冻结
* LS_COMPANY-DATA-GUZTE = U_ALV-GUZTE."信用记录条件
* LS_COMPANY-DATA-ALTKN = U_ALV-ALTKN."先前的账户号
* LS_COMPANY-DATA-ZWELS = U_ALV-ZWELS."付款方式
APPEND ls_company TO lt_company.
c_data-vendor-company_data-company = lt_company.
ENDIF.
"供应商采购数据
IF u_alv-flvn01 = 'X'.
SELECT SINGLE *
INTO @DATA(ls_lfm1)
FROM lfm1
WHERE lifnr = @u_bp
AND ekorg = @u_alv-ekorg.
IF sy-subrc = 0.
ls_purchasing-task = 'U'.
ls_purchasing-datax-waers = abap_true. "货币.
ls_purchasing-datax-kalsk = abap_true. "方案组.
* LS_PURCHASING-DATAX-LFABC = ABAP_TRUE. "供应商等级
ls_purchasing-datax-webre = abap_true. "基于收货的发票验证
* LS_PURCHASING-DATAX-SPERM = ABAP_TRUE. "采购冻结在采购组
ELSE.
ls_purchasing-task = 'I'.
PERFORM f_add_sup_purch_functions USING u_alv " 供应商合作伙伴功能
CHANGING lt_functions.
IF lt_functions IS NOT INITIAL.
ls_purchasing-functions-functions = lt_functions.
ENDIF.
ENDIF.
ls_purchasing-data_key = u_alv-ekorg.
ls_purchasing-data-waers = u_alv-waers. "货币.
ls_purchasing-data-kalsk = u_alv-kalsk. "方案组.
* LS_PURCHASING-DATA-LFABC = U_ALV-LFABC. "供应商等级
ls_purchasing-data-webre = u_alv-webre. "基于收货的发票验证
* LS_PURCHASING-DATA-SPERM = U_ALV-SPERM_M. "采购冻结在采购组
APPEND ls_purchasing TO lt_purchasing.
c_data-vendor-purchasing_data-purchasing = lt_purchasing.
ENDIF.
ENDFORM.
7.客户信息
FORM f_add_cust_general USING
u_bp TYPE char10
u_task TYPE c
u_alv TYPE zscmt0001
CHANGING c_data TYPE cvis_ei_extern.
DATA: lt_company TYPE cmds_ei_company_t,
ls_company TYPE cmds_ei_company,
lt_sales TYPE cmds_ei_sales_t,
ls_sales TYPE cmds_ei_sales,
lt_texts TYPE cvis_ei_text_t,
ls_texts TYPE cvis_ei_text,
lt_functions TYPE cmds_ei_functions_t,
lt_tax TYPE cmds_ei_tax_ind_t.
"客户销售组织数据
IF u_alv-flcu01 = 'X' OR u_alv-flcu00 = 'X'.
SELECT SINGLE *
INTO @DATA(ls_kna1)
FROM kna1
WHERE kunnr = @u_bp.
IF sy-subrc EQ 0.
c_data-customer-header-object_instance-kunnr = u_bp.
c_data-customer-header-object_task = 'U'.
* IF u_alv-bu_group = 'A001'.
* c_data-customer-central_data-central-datax-vbund = 'X'."贸易伙伴
* ENDIF.
ELSE.
c_data-customer-header-object_task = 'I'.
c_data-customer-header-object_instance-kunnr = u_bp.
* IF u_alv-bu_group = 'A001'.
* c_data-customer-central_data-central-data-vbund = u_alv-partner+4(6)."贸易伙伴
* ENDIF.
ENDIF.
IF u_alv-flcu01 = 'X'.
SELECT SINGLE *
INTO @DATA(ls_knvv)
FROM knvv
WHERE kunnr = @u_bp
AND vkorg = @u_alv-vkorg
AND vtweg = @u_alv-vtweg
AND spart = @u_alv-spart.
IF sy-subrc = 0.
ls_sales-task = 'U'.
* ls_sales-datax-kdgrp = abap_true."运营方式
ls_sales-datax-kalks = abap_true."定价过程
ls_sales-datax-konda = abap_true."客户定价组
ls_sales-datax-bzirk = abap_true."销售地区
ls_sales-datax-waers = abap_true."币种
ls_sales-datax-vsbed = abap_true."装运条件
ls_sales-datax-kkber = abap_true."信控范围
ls_sales-datax-vwerk = abap_true."交货工厂
* ls_sales-datax-ktgrd = abap_true."账户分配组
* ls_sales-datax-aufsd = abap_true."冻结
* ls_sales-datax-lifsd = abap_true."
* ls_sales-datax-faksd = abap_true."
ELSE.
ls_sales-task = 'I'.
PERFORM f_add_sale_functions USING u_alv " 客户伙伴功能
CHANGING lt_functions.
IF lt_functions IS NOT INITIAL.
ls_sales-functions-functions = lt_functions.
ENDIF.
ENDIF.
ls_sales-data_key-vkorg = u_alv-vkorg.
ls_sales-data_key-vtweg = u_alv-vtweg.
ls_sales-data_key-spart = u_alv-spart..
* ls_sales-data-kdgrp = u_alv-kdgrp."运营方式
ls_sales-data-kalks = u_alv-kalks."定价过程
ls_sales-data-konda = u_alv-konda."客户定价组
ls_sales-data-bzirk = u_alv-bzirk."销售地区
ls_sales-data-waers = u_alv-waers."币种
ls_sales-data-vsbed = u_alv-vsbed."装运条件
ls_sales-data-kkber = u_alv-kkber."信控范围
ls_sales-data-vwerk = u_alv-werks."交货工厂
ls_sales-data-ktgrd = u_alv-ktgrd."账户分配组
* ls_sales-data-aufsd = u_alv-aufsd."冻结
* ls_sales-data-lifsd = u_alv-lifsd."
* ls_sales-data-faksd = u_alv-faksd."
APPEND ls_sales TO lt_sales.
c_data-customer-sales_data-sales = lt_sales.
ENDIF.
" 客户公司代码
IF u_alv-flcu00 = 'X' .
SELECT SINGLE *
INTO @DATA(ls_knb1)
FROM knb1
WHERE kunnr = @u_bp
AND bukrs = @u_alv-bukrs.
IF sy-subrc = 0.
ls_company-task = 'U'.
ls_company-datax-akont = abap_true."统御科目
ls_company-datax-zterm = abap_true."付款条件
* ls_company-datax-sperr = abap_true."所选公司代码 过账冻结
ELSE.
ls_company-task = 'I'.
ENDIF.
ls_company-data_key = u_alv-bukrs.
ls_company-data-akont = u_alv-akont_cus."统御科目
ls_company-data-zterm = u_alv-zterm_cus."付款条件
* ls_company-data-sperr = u_alv-sperb_b_k."所选公司代码 过账冻结
APPEND ls_company TO lt_company.
c_data-customer-company_data-company = lt_company.
PERFORM f_add_sale_tax_typ USING u_alv " 客户伙伴功能
u_bp
CHANGING lt_tax.
c_data-customer-central_data-tax_ind-tax_ind = lt_tax.
ENDIF.
ENDIF.
ENDFORM.
合作伙伴信息:
FORM f_add_sale_functions USING u_alv TYPE zscmt0001
CHANGING ct_functions TYPE cmds_ei_functions_t.
DATA: ls_knvp TYPE knvp,
ls_functions TYPE cmds_ei_functions,
ls_cust_sales_functions TYPE cvis_customer_sales_func.
DATA: lv_part_up TYPE zscmt0010-partner.
CALL METHOD cvi_default_values_classic=>get_default_cust_functions
EXPORTING
i_account_group = u_alv-bu_group "账户组
RECEIVING
r_functions_list = DATA(lt_partner_function).
IF u_alv-zydc_sc_no IS NOT INITIAL.
lv_part_up = u_alv-zydc_sc_no.
SELECT SINGLE * FROM zscmt0010 INTO @DATA(ls_0010)
WHERE partner = @lv_part_up."店中店上上级
IF ls_0010-bu_group = 'K006' AND ls_0010-zydc_sc_no IS NOT INITIAL.
lv_part_up = ls_0010-zydc_sc_no.
ENDIF.
ENDIF.
LOOP AT lt_partner_function INTO ls_knvp.
ls_functions-task = 'I'.
ls_functions-data_key-parvw = ls_knvp-parvw.
ls_functions-data_key-parza = ls_knvp-parza.
* LS_FUNCTIONS-DATA-PARTNER = LS_KNVP-PARNR.
ls_functions-data-defpa = ls_knvp-defpa.
ls_functions-data-knref = ls_knvp-knref.
IF lv_part_up IS NOT INITIAL.
IF ls_functions-data_key-parvw = 'RE' OR ls_functions-data_key-parvw = 'RG' .
ls_functions-data-partner = lv_part_up.
* ELSE.
* ls_functions-data-partner = u_alv-partner.
ENDIF.
* ELSE.
* ls_functions-data-partner = u_alv-partner.
ENDIF.
APPEND ls_functions TO ct_functions.
CLEAR:ls_functions.
ENDLOOP.
ENDFORM.
税分类信息
FORM f_add_sale_tax_typ USING u_alv TYPE zscmt0001
u_bp TYPE char10
CHANGING ct_tax TYPE cmds_ei_tax_ind_t.
DATA: ls_knvi TYPE knvi,
ls_area TYPE cvis_sales_area,
ls_cust_sales_tax_typ TYPE cvis_customer_sales_func,
lt_knvi TYPE TABLE OF knvi,
ls_tax TYPE cmds_ei_tax_ind.
SELECT *
INTO TABLE lt_knvi
FROM knvi
WHERE kunnr = u_bp.
ls_area-sales_org = u_alv-vkorg.
ls_area-dist_channel = u_alv-vtweg.
ls_area-division = u_alv-spart.
CALL METHOD cvi_default_values_classic=>get_default_cust_tax_inds
EXPORTING
i_sales_area = ls_area "账户组
RECEIVING
r_tax_indicators = DATA(lt_partner_tax_typ).
LOOP AT lt_partner_tax_typ INTO DATA(ls_partner_tax_typ).
READ TABLE lt_knvi INTO ls_knvi WITH KEY aland = ls_partner_tax_typ-aland
tatyp = ls_partner_tax_typ-tatyp.
IF sy-subrc = 0.
ls_tax-task = 'U'.
ls_tax-data-taxkd = u_alv-taxkd.
ls_tax-datax-taxkd = abap_true.
DELETE lt_knvi WHERE aland = ls_partner_tax_typ-aland AND
tatyp = ls_partner_tax_typ-tatyp.
ELSE.
ls_tax-task = 'I'.
ENDIF.
ls_tax-data-taxkd = u_alv-taxkd.
ls_tax-data_key-aland = ls_partner_tax_typ-aland.
ls_tax-data_key-tatyp = ls_partner_tax_typ-tatyp.
APPEND ls_tax TO ct_tax.
CLEAR ls_tax.
ENDLOOP.
LOOP AT lt_knvi INTO ls_knvi.
ls_tax-task = 'D'.
ls_tax-data-taxkd = ls_knvi-taxkd.
ls_tax-data_key-aland = ls_knvi-aland.
ls_tax-data_key-tatyp = ls_knvi-tatyp.
APPEND ls_tax TO ct_tax.
CLEAR ls_tax.
ENDLOOP.
ENDFORM.
信贷限额信息
FORM f_add_ukm_general USING
u_bp TYPE char10
u_task TYPE c
u_alv TYPE zscmt0001
CHANGING c_data TYPE cvis_ei_extern.
DATA:ls_profile TYPE ukm_ei_bp_cms.
DATA:lt_segments TYPE ukmt_ei_bp_cms_sgm.
DATA:ls_segments TYPE ukm_ei_bp_cms_sgm.
IF u_alv-fukm000 = 'X' AND u_task = 'I'.
ls_profile-data-check_rule = '01'.
ls_profile-data-limit_rule = 'B2B-EXIST'.
ls_profile-data-risk_class = 'A'.
ls_profile-data-credit_group = '0001'.
ls_profile-datax-check_rule = 'X'.
ls_profile-datax-limit_rule = 'X'.
ls_profile-datax-risk_class = 'X'.
ls_profile-datax-credit_group = 'X'.
c_data-partner-ukmbp_data-profile = ls_profile.
* IF u_alv-credit > 0.
ls_segments-task = u_task.
ls_segments-data_key-partner = u_bp.
ls_segments-data_key-credit_sgmnt = 'Z001'.
ls_segments-data-credit_limit = u_alv-credit.
ls_segments-data-limit_valid_date = '99991231'.
APPEND ls_segments TO lt_segments.
c_data-partner-ukmbp_data-segments-segments = lt_segments.
* ENDIF.
ENDIF.
ENDFORM.
总结
以上代码基本OK,可能有时候客户/供应商有些值为空时获取消息有些异常。有明白的欢迎交流。
一些BP相关的方案设计心得
SAP的标准主数据设计的很全面,同号码授权/分配到组织很灵活。不过在一些行业也会显得很冗余。例如零售。
个人建议通过一些动态指针配置,简化BP的一些字段,不论对自定义界面还是接口还是批导入,可以采用字段配置默认或者映射逻辑去减少模板长度,减少错误可能。
例如如果我们分组配置合理,那么很多时候你的统御科目应该时按分组唯一的,那为什么还必须手填呢?
以下配置可以集成到程序里。
当然如果你的项目是客户手工维护BP,那请无视哈哈。其实屏幕增强也可以实现。
欢迎讨论奥。