PLM->SAP bom主数据

12 篇文章 0 订阅
10 篇文章 0 订阅

按需开发,实现plm同步bom数据至sap,实现覆盖式增删改

核心逻辑,bom bapi修改和创建是不一致的,创建的时候需要将组创建出来的,对应bapi也不一致,通过读取标准表是否生成数据来判断是否创建/修改

其中接口框架不建议参考,无奈之举,反馈都改了N次,反正常思维,其中自建表存储就不列举了

接口搭建

功能实现

FUNCTION ZFM_PLM_003.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(INPUT) TYPE  ZSTPLM_003_INPUT
*"  EXPORTING
*"     VALUE(OUTPUT) TYPE  ZSTPLM_003_OUTPUT
*"----------------------------------------------------------------------

*--init
  PERFORM frm_init USING 'ZFM_PLM_003'.

*--json in
  gv_json_in = zcl_common=>abap_to_json( input ).

*--if active check
  PERFORM frm_check_active USING gc_i.

  IF gv_active EQ abap_true.

*--input check
    IF input[] IS INITIAL.

      APPEND VALUE #( code = 'E' msg = '输入数据为空,请检查!') TO output.

      gv_type = gc_e.

    ELSE.

      PERFORM frm_bom_handle TABLES input output.

    ENDIF.

  ELSE.

    PERFORM frm_003_ret_e TABLES input output.

  ENDIF.

*--json out
  gv_json_out = zcl_common=>abap_to_json( output ).

*--set log
  PERFORM frm_set_log USING gc_i.

ENDFUNCTION.

核心框架


*&---------------------------------------------------------------------*
*& Form FRM_BOM_HANDLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> INPUT
*&      --> OUTPUT
*&---------------------------------------------------------------------*
FORM frm_bom_handle  TABLES  pt_input  TYPE zstplm_003_input
                             pt_output TYPE zstplm_003_output.

  DATA: lv_tabix TYPE sy-tabix,
        lv_msg   TYPE string.

  DATA: ls_marc TYPE marc.

  LOOP AT pt_input.

    CLEAR:lv_tabix,lv_msg.

    "初始化反馈
    APPEND INITIAL LINE TO pt_output ASSIGNING FIELD-SYMBOL(<fs_output>).

    <fs_output>-matnr = pt_input-matnr.

    material_input pt_input-matnr.

    "工厂子表必输校验
    IF pt_input-it_werks IS INITIAL.

      PERFORM frm_set_bom_ret TABLES <fs_output>-ot_werks
                               USING gc_e
                                     '工厂数据必输,请检查'
                            CHANGING <fs_output>.
      CONTINUE.
    ENDIF.

    "工厂层级循环
    LOOP AT pt_input-it_werks INTO DATA(ls_werks).

      "初始化工厂反馈
      APPEND INITIAL LINE TO <fs_output>-ot_werks ASSIGNING FIELD-SYMBOL(<fs_owerks>).

      <fs_owerks>-werks = ls_werks-werks.

      CLEAR:ls_marc.

      "工厂层级数据检查
      PERFORM frm_bom_input_check_01 USING pt_input ls_werks ls_marc CHANGING <fs_owerks>.

      IF ls_marc-beskz EQ 'E' OR ls_marc-beskz EQ 'X' OR ( ls_marc-beskz EQ 'F' AND ls_marc-sobsl EQ '30' ).

        "检查反馈处理
        IF <fs_owerks>-code NE gc_e.

          READ TABLE <fs_owerks>-ot_bom INTO DATA(ls_obom) WITH KEY code = gc_e.
          IF sy-subrc EQ 0.

            <fs_owerks>-code = gc_e.
            <fs_owerks>-msg  = ls_obom-msg.

            "组件无可选物料,不反馈 <fs_owerks>-ot_bom
            IF ls_obom-zmatnr IS INITIAL.
              MODIFY <fs_owerks>-ot_bom  FROM VALUE #( matnr = '' zmatnr = '' code = '' msg = '')
                                         TRANSPORTING matnr zmatnr code msg
                                         WHERE matnr  IS NOT INITIAL
                                            OR zmatnr IS NOT INITIAL
                                            OR code   IS NOT INITIAL
                                            OR msg    IS NOT INITIAL .

            ENDIF.

          ENDIF.

        ENDIF.

        "继续执行则情况bom检查,方便后续bapi执行结果写入
        IF <fs_owerks>-code NE gc_e.
          "CLEAR:<fs_owerks>-ot_bom .
        ELSE.
          CONTINUE.
        ENDIF.

        "获取工厂物料 bom 清单
        PERFORM frm_get_mast USING ls_werks pt_input.

        PERFORM frm_bom_maintain  USING ls_werks pt_input CHANGING <fs_owerks>.

        READ TABLE <fs_owerks>-ot_bom INTO ls_obom INDEX 1.

        "组件无可选物料,不反馈 <fs_owerks>-ot_bom
        IF ls_obom-zmatnr IS INITIAL.
          CLEAR:<fs_owerks>-ot_bom .
        ENDIF.

      ELSE.
        <fs_owerks>-code = gc_s.
        <fs_owerks>-msg  = |采购类型为{ ls_marc-beskz },特殊采购类为{ ls_marc-sobsl }无需扩展BOM|.
      ENDIF.

    ENDLOOP.

    READ TABLE <fs_output>-ot_werks INTO DATA(ls_ot_werks) WITH KEY code = gc_e.
    IF sy-subrc EQ 0.
      <fs_output>-code = ls_ot_werks-code.
      <fs_output>-msg  = ls_ot_werks-msg.
    ELSE.
      <fs_output>-code = gc_s.
      <fs_output>-msg  = '物料BOM维护成功'.
    ENDIF.

  ENDLOOP.

  READ TABLE pt_output TRANSPORTING NO FIELDS WITH KEY code = gc_e.
  IF sy-subrc EQ 0.
    gv_type = gc_e.
  ELSE.
    gv_type = gc_s.
  ENDIF.

ENDFORM.

定义


CONSTANTS:gc_i TYPE zietype    VALUE 'I',
          gc_o TYPE zietype    VALUE 'O',
          gc_w TYPE zietype    VALUE 'W',
          gc_e TYPE zietype    VALUE 'E',
          gc_s TYPE zietype    VALUE 'S'.

DATA: gv_sysid    TYPE ze_sysid01,
      gv_id       TYPE ze_zid01,
      gv_zname    TYPE rs38l_fnam,
      gv_guid     TYPE sysuuid_c,
      gv_active   TYPE c,
      gv_msg      TYPE string,
      gv_type     TYPE c,
      gv_json_in  TYPE string,
      gv_json_out TYPE string.

DATA:gv_matnr TYPE char18.


*--003
DATA:gt_bomgroup          TYPE TABLE OF bapi1080_bgr_c,
     gs_bomgroup          TYPE bapi1080_bgr_c,
     gt_variants          TYPE TABLE OF bapi1080_bom_c,
     gs_variants          TYPE bapi1080_bom_c,
     gt_items             TYPE TABLE OF bapi1080_itm_c,
     gs_items             TYPE bapi1080_itm_c,
     gt_materialrelations TYPE TABLE OF bapi1080_mbm_c,
     gs_materialrelations TYPE bapi1080_mbm_c,
     gt_itemassignments   TYPE TABLE OF bapi1080_rel_itm_bom_c,
     gs_itemassignments   TYPE bapi1080_rel_itm_bom_c,
     gs_testrun           TYPE bapiflag,
     gt_return            TYPE TABLE OF bapiret2,
     gs_return            TYPE bapiret2.

DATA:gt_stko_old TYPE STANDARD TABLE OF stko_api02,
     gt_stpo_old TYPE STANDARD TABLE OF stpo_api02.
DATA:gt_stpo_new TYPE STANDARD TABLE OF stpo_api03,
     gs_stko_new TYPE stko_api01.

DATA:gv_stlal TYPE numc2,
     gv_tabix TYPE sy-tabix.

DATA:gt_zplm_t_007 TYPE STANDARD TABLE OF zplm_t_007,
     gt_zplm_t_006 TYPE STANDARD TABLE OF zplm_t_006,
     gt_zplm_t_001 TYPE STANDARD TABLE OF zplm_t_001

子例程


*&---------------------------------------------------------------------*
*& Form FRM_BOM_HANDLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> INPUT
*&      --> OUTPUT
*&---------------------------------------------------------------------*
FORM frm_bom_handle  TABLES  pt_input  TYPE zstplm_003_input
                             pt_output TYPE zstplm_003_output.

  DATA: lv_tabix TYPE sy-tabix,
        lv_msg   TYPE string.

  DATA: ls_marc TYPE marc.

  LOOP AT pt_input.

    CLEAR:lv_tabix,lv_msg.

    "初始化反馈
    APPEND INITIAL LINE TO pt_output ASSIGNING FIELD-SYMBOL(<fs_output>).

    <fs_output>-matnr = pt_input-matnr.

    material_input pt_input-matnr.

    "工厂子表必输校验
    IF pt_input-it_werks IS INITIAL.

      PERFORM frm_set_bom_ret TABLES <fs_output>-ot_werks
                               USING gc_e
                                     '工厂数据必输,请检查'
                            CHANGING <fs_output>.
      CONTINUE.
    ENDIF.

    "工厂层级循环
    LOOP AT pt_input-it_werks INTO DATA(ls_werks).

      "初始化工厂反馈
      APPEND INITIAL LINE TO <fs_output>-ot_werks ASSIGNING FIELD-SYMBOL(<fs_owerks>).

      <fs_owerks>-werks = ls_werks-werks.

      CLEAR:ls_marc.

      "工厂层级数据检查
      PERFORM frm_bom_input_check_01 USING pt_input ls_werks ls_marc CHANGING <fs_owerks>.

      IF ls_marc-beskz EQ 'E' OR ls_marc-beskz EQ 'X' OR ( ls_marc-beskz EQ 'F' AND ls_marc-sobsl EQ '30' ).

        "检查反馈处理
        IF <fs_owerks>-code NE gc_e.

          READ TABLE <fs_owerks>-ot_bom INTO DATA(ls_obom) WITH KEY code = gc_e.
          IF sy-subrc EQ 0.

            <fs_owerks>-code = gc_e.
            <fs_owerks>-msg  = ls_obom-msg.

            "组件无可选物料,不反馈 <fs_owerks>-ot_bom
            IF ls_obom-zmatnr IS INITIAL.
              MODIFY <fs_owerks>-ot_bom  FROM VALUE #( matnr = '' zmatnr = '' code = '' msg = '')
                                         TRANSPORTING matnr zmatnr code msg
                                         WHERE matnr  IS NOT INITIAL
                                            OR zmatnr IS NOT INITIAL
                                            OR code   IS NOT INITIAL
                                            OR msg    IS NOT INITIAL .

            ENDIF.

          ENDIF.

        ENDIF.

        "继续执行则情况bom检查,方便后续bapi执行结果写入
        IF <fs_owerks>-code NE gc_e.
          "CLEAR:<fs_owerks>-ot_bom .
        ELSE.
          CONTINUE.
        ENDIF.

        "获取工厂物料 bom 清单
        PERFORM frm_get_mast USING ls_werks pt_input.

        PERFORM frm_bom_maintain  USING ls_werks pt_input CHANGING <fs_owerks>.

        READ TABLE <fs_owerks>-ot_bom INTO ls_obom INDEX 1.

        "组件无可选物料,不反馈 <fs_owerks>-ot_bom
        IF ls_obom-zmatnr IS INITIAL.
          CLEAR:<fs_owerks>-ot_bom .
        ENDIF.

      ELSE.
        <fs_owerks>-code = gc_s.
        <fs_owerks>-msg  = |采购类型为{ ls_marc-beskz },特殊采购类为{ ls_marc-sobsl }无需扩展BOM|.
      ENDIF.

    ENDLOOP.

    READ TABLE <fs_output>-ot_werks INTO DATA(ls_ot_werks) WITH KEY code = gc_e.
    IF sy-subrc EQ 0.
      <fs_output>-code = ls_ot_werks-code.
      <fs_output>-msg  = ls_ot_werks-msg.
    ELSE.
      <fs_output>-code = gc_s.
      <fs_output>-msg  = '物料BOM维护成功'.
    ENDIF.

  ENDLOOP.

  READ TABLE pt_output TRANSPORTING NO FIELDS WITH KEY code = gc_e.
  IF sy-subrc EQ 0.
    gv_type = gc_e.
  ELSE.
    gv_type = gc_s.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_BOM_RET
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> <FS_OUTPUT>_IT_WERKS
*&      --> <FS_OUTPUT>_OT_BOM
*&      --> <FS_OUTPUT>_CODE
*&      --> <FS_OUTPUT>_MSG
*&      <-- <FS_OUTPUT>
*&---------------------------------------------------------------------*
FORM frm_set_bom_ret  TABLES   pt_owerks TYPE zstplm_003_owerks
                      USING    ps_code
                               ps_msg
                      CHANGING cs_output TYPE zsplm_003_output.

  IF pt_owerks[] IS NOT INITIAL.
    cs_output-ot_werks = pt_owerks[].
  ENDIF.

  IF ps_code IS NOT INITIAL.
    cs_output-code = ps_code.
  ENDIF.

  IF ps_msg IS NOT INITIAL.
    cs_output-msg = ps_msg.
  ENDIF.

  "总体接口记录标识
  IF gv_type NE gc_e AND cs_output-code IS NOT INITIAL.
    gv_type = cs_output-code.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BOM_INPUT_CHECK_01
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_WERKS
*&      <-- <FS_OWERKS>
*&---------------------------------------------------------------------*
FORM frm_bom_input_check_01  USING    ps_input  TYPE zsplm_003_input
                                      ps_iwerks TYPE zsplm_003_iwerks
                                      ps_marc   TYPE marc
                             CHANGING cs_owerks TYPE zsplm_003_owerks.

  CLEAR:ps_marc.

  "工厂代码必输
  IF ps_iwerks-werks IS INITIAL.
    cs_owerks = VALUE #( code = gc_e  msg =  '工厂代码必输,请检查' ).
    RETURN.
  ENDIF.

  "新增/修改标识
  "IF ps_iwerks-wflag IS INITIAL.
  "  cs_owerks = VALUE #( code = gc_e  msg =  '新增/修改标识必输,请检查' ).
  "  RETURN.
  "ENDIF.


  SELECT SINGLE * FROM marc INTO ps_marc WHERE matnr EQ ps_input-matnr AND werks EQ ps_iwerks-werks.

  IF ps_marc IS INITIAL.
    cs_owerks = VALUE #( code = gc_e  msg =  '物料:' && |{ ps_input-matnr ALPHA = OUT }| && '不存在于工厂:' && ps_iwerks-werks ).
    RETURN.
  ENDIF.

  "BOM子表必输校验
  IF ps_input-it_bom IS INITIAL.

    cs_owerks = VALUE #( code = gc_e  msg =  'BOM信息必输,请检查' ).
    RETURN.

  ELSE.

    "BOM数据校验
    LOOP AT ps_input-it_bom ASSIGNING FIELD-SYMBOL(<fs_ibom>).

      APPEND INITIAL LINE TO cs_owerks-ot_bom ASSIGNING FIELD-SYMBOL(<fs_obom>).

      <fs_obom>-matnr = <fs_ibom>-matnr.

      "物料编号必输
      IF <fs_ibom>-matnr IS INITIAL.
        <fs_obom> = VALUE #( code = gc_e msg =  '物料编号必输,请检查' ).
        RETURN.
      ELSE.
        material_input <fs_ibom>-matnr.
      ENDIF.

      "用途必输
      IF <fs_ibom>-stlan IS INITIAL.
        <fs_obom> = VALUE #( code = gc_e msg =  '用途必输,请检查' ).
        RETURN.
      ELSE.

      ENDIF.

      "可选的 BOM必输
      IF <fs_ibom>-stlal IS INITIAL.
        <fs_obom> = VALUE #( code = gc_e msg =  'BOM必输,请检查' ).
        RETURN.
      ELSE.
        PERFORM frm_inzero USING 'CHAR2' CHANGING <fs_ibom>-stlal.
      ENDIF.

      "物料版本
      IF <fs_ibom>-materev IS INITIAL.
        <fs_obom> = VALUE #( code = gc_e msg =  '物料版本必输,请检查' ).
        RETURN.
      ENDIF.

      "基本数量必输
      IF <fs_ibom>-bmeng IS INITIAL.
        <fs_obom> = VALUE #( code = gc_e msg =  '基本数量必输,请检查' ).
        RETURN.
      ENDIF.

      "组件可选物料回写
      READ TABLE <fs_ibom>-i_item INTO DATA(ls_bom_item) WITH KEY zsfkx = 'Y'.
      IF sy-subrc EQ 0.
        <fs_obom>-zmatnr = ls_bom_item-idnrk.
      ENDIF.

      "行项目-BOM 组件 校验
      READ TABLE <fs_ibom>-i_item TRANSPORTING NO FIELDS WITH KEY idnrk = space.
      IF sy-subrc EQ 0.
        <fs_obom> = VALUE #( code = gc_e msg =  'BOM组件物料必输,请检查' ).
        RETURN.
      ELSE.

        LOOP AT <fs_ibom>-i_item ASSIGNING FIELD-SYMBOL(<fs_item>).

          CLEAR gv_matnr.
          gv_matnr = |{ <fs_item>-idnrk ALPHA = IN }|.

          SELECT SINGLE * FROM marc INTO @DATA(ls_marc) WHERE matnr EQ @gv_matnr AND werks EQ @ps_iwerks-werks.
          IF sy-subrc NE 0 OR ls_marc IS INITIAL.
            <fs_obom> = VALUE #( code = gc_e msg =  '组件物料:' && <fs_item>-idnrk && '不存在于工厂:' && ps_iwerks-werks ).
            RETURN.
          ELSE.
            "财务冻结
            IF <fs_item>-postp EQ 'L' AND ls_marc-mmsta EQ '03'.
              <fs_obom> = VALUE #( code = gc_e msg =  '组件物料:' && <fs_item>-idnrk && '于工厂:' && ps_iwerks-werks && '财务冻结,创建BOM失败' ).
              RETURN.
            ELSE.
              <fs_item>-idnrk = gv_matnr.
            ENDIF.

          ENDIF.
          CLEAR ls_marc.

        ENDLOOP.

      ENDIF.

      "行项目-组件数量
      READ TABLE <fs_ibom>-i_item TRANSPORTING NO FIELDS WITH KEY menge = space.
      IF sy-subrc EQ 0.
        <fs_obom> = VALUE #( code = gc_e msg =  'BOM组件物料数量必输,请检查' ).
        RETURN.
      ENDIF.

    ENDLOOP.

  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_MATERIAL_DEL_SINGLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_MARC_WERKS
*&      <-- CS_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_inzero USING p_type CHANGING cv_field TYPE string.

  DATA: dyn_data TYPE REF TO data,
        lv_cd    TYPE i,
        lv_str   TYPE string,
        lv_pyl   TYPE i.

  FIELD-SYMBOLS: <fs_data> TYPE any.

  CREATE DATA dyn_data TYPE (p_type).

  ASSIGN dyn_data->* TO FIELD-SYMBOL(<fs_field>).

  CHECK <fs_field> IS ASSIGNED.

  DATA(lv_len) = strlen( p_type ).

  lv_pyl = lv_len - 4.

  lv_cd = p_type+4(lv_pyl).

  IF strlen( cv_field ) GT lv_cd.
    lv_str = cv_field+0(lv_cd).
  ELSE.
    lv_str = cv_field.
  ENDIF.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = lv_str
    IMPORTING
      output = <fs_field>.

  cv_field = <fs_field>.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_MAST
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_get_mast USING ps_iwerks TYPE zsplm_003_iwerks
                        ps_input  TYPE zsplm_003_input.

  DATA:lt_matnr TYPE STANDARD TABLE OF mast.

  CLEAR:gt_mast.

  lt_matnr = CORRESPONDING #( ps_input-it_bom ).

  CHECK lt_matnr[] IS NOT INITIAL.

  SELECT *
    FROM mast
    INTO TABLE gt_mast
     FOR ALL ENTRIES IN lt_matnr
   WHERE matnr EQ lt_matnr-matnr
     AND werks EQ ps_iwerks-werks.

  SORT gt_mast BY matnr werks stlan stlnr stlal.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_bom_maintain
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PT_INPUT
*&      <-- PT_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_bom_maintain     USING ps_iwerks TYPE zsplm_003_iwerks
                                ps_input  TYPE zsplm_003_input
                       CHANGING cs_owerks TYPE zsplm_003_owerks.

  DATA:lv_msg       TYPE string,
       lv_tabix_crt TYPE sy-tabix.

  LOOP AT ps_input-it_bom ASSIGNING FIELD-SYMBOL(<fs_bom>).

    "与检查时写入数据保持index 一致
    DATA(lv_tabix) = sy-tabix.

    PERFORM frm_bom_refresh.

    "获取历史行
    PERFORM frm_get_bom_item USING ps_iwerks <fs_bom> .

    "001 / 006 SAVE
    PERFORM frm_set_bom_t001 USING ps_iwerks <fs_bom> .

    IF gt_stko_old IS NOT INITIAL."修改

      "写bapi 行
      PERFORM frm_chg_bom_item USING ps_iwerks <fs_bom> .

      "bapi 修改
      PERFORM frm_bom_bapi_chg USING ps_iwerks lv_tabix CHANGING cs_owerks.

    ELSE."创建

      lv_tabix_crt = lv_tabix_crt + 1.

      "抬头写入
      PERFORM frm_set_bom_head USING ps_iwerks <fs_bom> lv_tabix_crt.

      "行项目写入
      PERFORM frm_set_bom_item USING ps_iwerks <fs_bom> lv_tabix_crt.

      "新组写入
      PERFORM frm_set_bom_group USING ps_iwerks <fs_bom>.

      "bapi 创建
      PERFORM frm_bom_bapi_crt USING ps_iwerks CHANGING cs_owerks.

    ENDIF.

  ENDLOOP.

  READ TABLE cs_owerks-ot_bom INTO DATA(ls_obom) WITH KEY code = gc_e.
  IF sy-subrc EQ 0.
    cs_owerks-code = ls_obom-code.
    cs_owerks-msg  = ls_obom-msg.
  ELSE.

    "PLM未传输可选bom删除
    PERFORM frm_del_mast CHANGING cs_owerks.

    IF cs_owerks-code IS INITIAL.
      cs_owerks-code = gc_s.
      cs_owerks-msg  = 'BOM维护成功'.
    ENDIF.

  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BOM_REFRESH
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_bom_refresh .

  CLEAR:gv_stlal,gv_tabix.

  CLEAR:gt_bomgroup          ,
        gt_variants          ,
        gt_items             ,
        gt_materialrelations ,
        gt_itemassignments   ,
        gs_itemassignments   ,
        gt_stpo_old          ,
        gt_stko_old          ,
        gt_stpo_new          ,
        gs_stko_new          ,
        gs_return            ,
        gt_return.

  CLEAR:gt_zplm_t_001,
        gt_zplm_t_006,
        gt_zplm_t_007.

  CLEAR:gs_mast.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_BOM_ITEM
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&---------------------------------------------------------------------*
FORM frm_get_bom_item USING  ps_iwerks TYPE zsplm_003_iwerks
                             ps_ibom   TYPE zsplm_003_ibom.

  "读取可选BOM 是否存在
  gs_mast = VALUE #( matnr = ps_ibom-matnr
                     werks = ps_iwerks-werks
                     stlan = ps_ibom-stlan
                     stlal = ps_ibom-stlal
                    ).

  SELECT SINGLE stlnr FROM mast INTO gs_mast-stlnr WHERE matnr = ps_ibom-matnr AND werks = ps_iwerks-werks.

  CHECK sy-subrc EQ 0.

  CALL FUNCTION 'CSAP_MAT_BOM_READ'
    EXPORTING
      material    = gs_mast-matnr
      plant       = gs_mast-werks
      bom_usage   = gs_mast-stlan
      alternative = gs_mast-stlal
    " valid_from  = sy-datum
    " valid_to    = sy-datum
    TABLES
      t_stpo      = gt_stpo_old
      t_stko      = gt_stko_old
    EXCEPTIONS
      error       = 1
      OTHERS      = 2.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_BOM_T001
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_IBOM
*&      --> PS_IWERKS
*&---------------------------------------------------------------------*
FORM frm_set_bom_t001  USING ps_iwerks TYPE zsplm_003_iwerks
                             ps_ibom   TYPE zsplm_003_ibom.

  TYPES: BEGIN OF typ_marc,
           matnr TYPE marc-matnr,
         END OF typ_marc,

         BEGIN OF typ_item,
           idnrk TYPE marc-matnr,
         END OF typ_item.

  DATA:lt_marc  TYPE SORTED   TABLE OF typ_marc   WITH UNIQUE KEY matnr,
       lt_idnrk TYPE STANDARD TABLE OF typ_item,
       lt_001   TYPE STANDARD TABLE OF zplm_t_001 WITH HEADER LINE.

  "读取是否组件行是否包含包装物料
  lt_idnrk[] = CORRESPONDING #( ps_ibom-i_item ).
  CHECK lt_idnrk[] IS NOT INITIAL.

  SELECT marc~matnr
    FROM marc
   INNER JOIN mara
      ON mara~matnr EQ marc~matnr
     AND mara~mtart EQ 'LD22'
    INTO TABLE lt_marc
     FOR ALL ENTRIES IN lt_idnrk
   WHERE marc~matnr EQ lt_idnrk-idnrk
    "AND marc~beskz EQ 'E'
    "AND marc~sobsl EQ '50'
     AND marc~werks EQ ps_iwerks-werks.

  IF lt_marc IS NOT INITIAL.

    "筛选处理数据
    lt_001[] = CORRESPONDING #( ps_ibom-i_item  ).

    lt_001[] = FILTER #( lt_001[] IN lt_marc WHERE idnrk EQ matnr ).

    IF lt_001[] IS NOT INITIAL.

      lt_001 = VALUE #( BASE CORRESPONDING #( ps_ibom ) werks = ps_iwerks-werks ).

      MODIFY lt_001 TRANSPORTING matnr werks stlan stlal WHERE matnr EQ space.

      APPEND LINES OF lt_001 TO gt_zplm_t_001.

    ENDIF.

  ENDIF.

  "PLM->SAP BOM抬头-版本储存表
  APPEND INITIAL LINE TO gt_zplm_t_006 ASSIGNING FIELD-SYMBOL(<fs_006>).
  <fs_006> = VALUE #( BASE CORRESPONDING #( ps_ibom )
                      werks   = ps_iwerks-werks
                      zenable = abap_true       ).

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CHG_BOM_ITEM
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_chg_bom_item USING  ps_iwerks TYPE zsplm_003_iwerks
                             ps_ibom   TYPE zsplm_003_ibom.

  DATA lv_item_no TYPE char4.

  gt_stpo_new = CORRESPONDING #( gt_stpo_old ) .
  MODIFY gt_stpo_new FROM VALUE #( fldelete = abap_true ) TRANSPORTING fldelete WHERE fldelete EQ space.

  LOOP AT ps_ibom-i_item INTO DATA(ls_item) WHERE zbxbs EQ space.

    "item no 按照每个 可选bom 独立排序
    lv_item_no = lv_item_no + 10. CONDENSE lv_item_no NO-GAPS.

    APPEND INITIAL LINE TO gt_stpo_new ASSIGNING FIELD-SYMBOL(<fs_stpo>).

    <fs_stpo> = VALUE #( item_no          = |{ lv_item_no  ALPHA = IN }|
                         component        = ls_item-idnrk
                         comp_qty         = ls_item-menge
                         item_categ       = 'L'
                         rel_cost         = abap_true
                         sortstring       = ls_item-sortf
                        ).

    APPEND INITIAL LINE TO gt_zplm_t_007 ASSIGNING FIELD-SYMBOL(<fs_007>).
    <fs_007> = VALUE #( idnrk      = ls_item-idnrk
                        postp      = ls_item-postp
                        posnr      = lv_item_no
                        zversion_s = ls_item-zversion_s
                        materev_s  = ls_item-materev_s
                        zjtzbc_s   = ls_item-zjtzbc_s
                        matnr      = ps_ibom-matnr
                        werks      = ps_iwerks-werks
                        stlan      = ps_ibom-stlan
                        stlal      = ps_ibom-stlal
                        zversion   = ps_ibom-zversion
                        materev    = ps_ibom-materev
                        zjtzbc     = ps_ibom-zjtzbc
                        zenable    = abap_true ).

  ENDLOOP.

  gs_stko_new = VALUE #( BASE CORRESPONDING #( VALUE #( gt_stko_old[ 1 ] OPTIONAL ) )
                         base_quan = ps_ibom-bmeng
                         bom_text  = ps_ibom-ztext
                         alt_text  = ps_ibom-ztext
                         ).

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BOM_BAPI_CHG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&      <-- CS_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_bom_bapi_chg  USING ps_iwerks TYPE zsplm_003_iwerks
                             pv_tabix
                    CHANGING cs_owerks TYPE zsplm_003_owerks.

  "删除本次传输修改数据
  DELETE gt_mast WHERE matnr = gs_mast-matnr
                   AND werks = gs_mast-werks
                   AND stlan = gs_mast-stlan
                   AND stlal = gs_mast-stlal.

  "有效起始日期转外部
  DATA(lv_datum) =  zcl_common=>date_out( ).

  CALL FUNCTION 'CSAP_MAT_BOM_MAINTAIN'
    EXPORTING
      material          = gs_mast-matnr
      plant             = gs_mast-werks
      bom_usage         = gs_mast-stlan
      alternative       = gs_mast-stlal
      i_stko            = gs_stko_new
      valid_from        = lv_datum
*     FL_BOM_CREATE     = 'X'
      fl_new_item       = 'X'
      fl_complete       = 'X'
      fl_default_values = 'X'
    TABLES
      t_stpo            = gt_stpo_new
    EXCEPTIONS
      error             = 1
      OTHERS            = 2.

  DATA(lv_type) = COND char1( WHEN sy-subrc EQ 0 THEN gc_s ELSE gc_e ).

  MODIFY cs_owerks-ot_bom FROM VALUE #( code = lv_type
                                        msg  = COND #( WHEN sy-subrc NE 0 THEN zcl_common=>write_message( )  ELSE 'BOM修改成功' )
                                      )
                          INDEX pv_tabix TRANSPORTING code msg.

  zcl_common=>bapi_commit( lv_type ).

  CHECK lv_type EQ gc_s.

  "保存数据
  PERFORM frm_bom_save USING ps_iwerks gs_mast-stlnr.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BOM_SAVE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&      --> LV_STLNR
*&---------------------------------------------------------------------*
FORM frm_bom_save  USING ps_iwerks TYPE zsplm_003_iwerks
                         pv_stlnr  TYPE mast-stlnr.

*--包装方案储存表
  IF gt_zplm_t_001 IS NOT INITIAL.

    MODIFY gt_zplm_t_001 FROM VALUE #( stlnr = pv_stlnr ) TRANSPORTING stlnr WHERE stlnr IS INITIAL.

    "删除历史存储数据
    LOOP AT gt_zplm_t_001 INTO DATA(ls_001).

      DELETE FROM zplm_t_001 WHERE matnr EQ ls_001-matnr
                               AND werks EQ ls_001-werks
                               AND stlan EQ ls_001-stlan
                               AND stlal EQ ls_001-stlal.

      IF sy-subrc EQ 0.
        COMMIT WORK AND WAIT.
      ENDIF.

    ENDLOOP.

    "保存数据
    MODIFY zplm_t_001 FROM TABLE gt_zplm_t_001.
    IF sy-subrc EQ 0.
      COMMIT WORK AND WAIT.
    ENDIF.

  ENDIF.

*--PLM->SAP BOM抬头-版本储存表
  IF gt_zplm_t_006 IS NOT INITIAL.

    MODIFY gt_zplm_t_006 FROM VALUE #( stlnr = pv_stlnr ) TRANSPORTING stlnr WHERE stlnr IS INITIAL.

    "更新其他版本为非启用
    LOOP AT gt_zplm_t_006 INTO DATA(ls_006).

      UPDATE zplm_t_006 SET zenable = space
                      WHERE matnr    EQ ls_006-matnr
                        AND werks    EQ ls_006-werks
                        AND stlan    EQ ls_006-stlan
                        AND stlnr    EQ ls_006-stlnr
                        AND stlal    EQ ls_006-stlal.

      IF sy-subrc EQ 0.
        COMMIT WORK AND WAIT.
      ENDIF.

    ENDLOOP.

    "保存数据
    MODIFY zplm_t_006 FROM TABLE gt_zplm_t_006.
    IF sy-subrc EQ 0.
      COMMIT WORK AND WAIT.
    ENDIF.

  ENDIF.

*--PLM->SAP BOM项目-版本储存表
  IF gt_zplm_t_007 IS NOT INITIAL.

    MODIFY gt_zplm_t_007 FROM VALUE #( stlnr = pv_stlnr ) TRANSPORTING stlnr WHERE stlnr IS INITIAL.

    "更新其他版本为非启用
    LOOP AT gt_zplm_t_007 INTO DATA(ls_007).

      UPDATE zplm_t_007 SET zenable = space
                      WHERE matnr = ls_007-matnr
                        AND werks = ls_007-werks
                        AND stlan = ls_007-stlan
                        AND stlnr = ls_007-stlnr
                        AND stlal = ls_007-stlal.

      IF sy-subrc EQ 0.
        COMMIT WORK AND WAIT.
      ENDIF.

    ENDLOOP.

    "保存数据
    MODIFY zplm_t_007 FROM TABLE gt_zplm_t_007.
    IF sy-subrc EQ 0.
      COMMIT WORK AND WAIT.
    ENDIF.

  ENDIF.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_BOM_HEAD
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&      --> PV_INDEX
*&---------------------------------------------------------------------*
FORM frm_set_bom_head  USING  ps_iwerks TYPE zsplm_003_iwerks
                              ps_ibom   TYPE zsplm_003_ibom
                              pv_tabix  ."TYPE sy-tabix.


  SELECT SINGLE * FROM mara INTO @DATA(ls_mara) WHERE matnr EQ @ps_ibom-matnr.

  APPEND INITIAL LINE TO gt_variants ASSIGNING FIELD-SYMBOL(<fs_variants>).

  <fs_variants> = VALUE #(  bom_group_identification = 'BOMGROUP2'
                            object_type              = 'BOM'
                            object_id                = |SIMPLE{ pv_tabix ALPHA = IN }| "bom head  object_id,存在创建多个 bom可选清单,按照汇总下创建多个可选bom累加拼接
                            bom_status               = '01'
                            alternative_bom          = ps_ibom-stlal  "备选物料清单
                            base_qty                 = ps_ibom-bmeng  "父项基本数量
                            base_unit                = ls_mara-meins  "父项基本计量单位
                            valid_from_date          = sy-datum       "有效起始日期
                            alt_text                 = ps_ibom-ztext  "物料清单描述
                            function                 = 'NEW'          "创建
                          ).

  APPEND INITIAL LINE TO gt_materialrelations ASSIGNING FIELD-SYMBOL(<fs_materialrelations>).

  <fs_materialrelations> = VALUE #(  bom_group_identification = 'BOMGROUP2'
                                     material                 = ps_ibom-matnr  "父项物料编码
                                     material_long            = ps_ibom-matnr  "父项物料编码
                                     bom_usage                = ps_ibom-stlan  " BOM 用途
                                     alternative_bom          = ps_ibom-stlal  "可选BOM
                                     plant                    = ps_iwerks-werks"工厂
                                   ).

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_BOM_ITEM
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&---------------------------------------------------------------------*
FORM frm_set_bom_item  USING ps_iwerks TYPE zsplm_003_iwerks
                             ps_ibom   TYPE zsplm_003_ibom
                             pv_tabix  ."TYPE tabix.

  DATA lv_item_no TYPE char4.

  LOOP AT ps_ibom-i_item INTO DATA(ls_item) WHERE zbxbs EQ space.

    gv_tabix = gv_tabix + 1.

    "item no 按照每个 可选bom 独立排序
    lv_item_no = lv_item_no + 10. CONDENSE lv_item_no NO-GAPS.

    "item  object_id  按照所有item 行累加拼接 SIMPLE
    DATA(lv_object_id) = |SIMPLE{ gv_tabix }|. CONDENSE lv_object_id NO-GAPS.

    "item  item_id  按照所有item 行累加
    DATA(lv_item_id) = CONV cs_itmid( gv_tabix ). CONDENSE lv_item_id NO-GAPS.
    lv_item_id = |{ lv_item_id  ALPHA = IN }|.

    APPEND INITIAL LINE TO gt_items ASSIGNING FIELD-SYMBOL(<fs_item>).

    <fs_item> = VALUE #( bom_group_identification = 'BOMGROUP2'
                         object_type              = 'ITM'
                         object_id                = lv_object_id
                         item_no                  = |{ lv_item_no  ALPHA = IN }|
                         item_id                  = lv_item_id
                         item_cat                 = 'L'"COND #( WHEN ps_input-zkxbs EQ 'Y' THEN 'T' ELSE 'L' )"BOM行项目类别
                         component                = ls_item-idnrk
                         component_long           = ls_item-idnrk
                         comp_qty                 = ls_item-menge
                         ltxt_lang                = sy-langu
                         valid_from_date          = sy-datum
                         cost_rel                 = abap_true
                         sort_string              = ls_item-sortf
                      ).

    APPEND INITIAL LINE TO gt_itemassignments ASSIGNING FIELD-SYMBOL(<fs_itemassignments>).

    <fs_itemassignments> = VALUE #( bom_group_identification = 'BOMGROUP2'
                                    sub_object_type          = 'ITM'
                                    sub_object_id            = lv_object_id
                                    super_object_type        = 'BOM'
                                    super_object_id          = |SIMPLE{ pv_tabix  ALPHA = IN }| "bom head  object_id
                                    valid_from_date          = sy-datum"有效起始日期
                                    function                 = 'NEW'
                                   ).

    APPEND INITIAL LINE TO gt_zplm_t_007 ASSIGNING FIELD-SYMBOL(<fs_007>).
    <fs_007> = VALUE #( idnrk      = ls_item-idnrk
                        postp      = ls_item-postp
                        posnr      = lv_item_no
                        zversion_s = ls_item-zversion_s
                        materev_s  = ls_item-materev_s
                        matnr      = ps_ibom-matnr
                        werks      = ps_iwerks-werks
                        stlan      = ps_ibom-stlan
                        stlal      = ps_ibom-stlal
                        zversion   = ps_ibom-zversion
                        zenable    = abap_true
                       ).

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_BOM_GROUP
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&---------------------------------------------------------------------*
FORM frm_set_bom_group USING  ps_iwerks TYPE zsplm_003_iwerks
                              ps_ibom   TYPE zsplm_003_ibom.

  APPEND INITIAL LINE TO gt_bomgroup ASSIGNING FIELD-SYMBOL(<fs_bomgroup>).

  <fs_bomgroup> = VALUE #(  bom_group_identification = 'BOMGROUP2'    "标识物料单组
                            object_type              = 'BGR'          "BOM 组中的对象类型
                            object_id                = |SIMPLE1|      "BOM 组中对象的标识 "bom group  object_id,只创建一个组,所以写死
                            technical_type           = 'M'            "技术类型
                            ltxt_lang                = sy-langu
                            bom_usage                = ps_ibom-stlan  "BOM 用途
                            created_in_plant         = ps_iwerks-werks"工厂
                            bom_text                 = ps_ibom-ztext  "物料清单描述
                          ).

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BOM_BAPI_CRT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      <-- CS_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_bom_bapi_crt    USING ps_iwerks TYPE zsplm_003_iwerks
                      CHANGING cs_owerks TYPE zsplm_003_owerks.

  DATA:lv_stlnr TYPE mast-stlnr,
       ls_bom   TYPE zsplm_003_ibom.

  CALL FUNCTION 'BAPI_MATERIAL_BOM_GROUP_CREATE'
    EXPORTING
      all_error         = 'X'
    TABLES
      bomgroup          = gt_bomgroup
      variants          = gt_variants
      items             = gt_items
      materialrelations = gt_materialrelations
      itemassignments   = gt_itemassignments
      return            = gt_return.

  LOOP AT gt_return INTO DATA(ls_return) WHERE type = 'E' OR type = 'A'.

    gs_return-message = gs_return-message && '/' && ls_return-message.
    gs_return-type    = gc_e.

  ENDLOOP.

  gs_return-type = COND #( WHEN gs_return-type EQ space THEN gc_s ELSE gs_return-type ).

  zcl_common=>bapi_commit( gs_return-type ).

  LOOP AT gt_return INTO ls_return WHERE message CS '创建' AND message_v1 EQ 'BOMGroup'.
    lv_stlnr = ls_return-message_v2+0(8).
    EXIT.
  ENDLOOP.

  cs_owerks-code = gs_return-type.
  cs_owerks-msg  = COND #( WHEN gs_return-type = gc_s THEN  'BOM创建成功' ELSE 'BOM创建失败:' && gs_return-message ).

  MODIFY cs_owerks-ot_bom FROM VALUE #( code = cs_owerks-code
                                        msg  = cs_owerks-msg  )
                          TRANSPORTING code msg WHERE code  IS INITIAL.

  CHECK gs_return-type EQ gc_s.

  CHECK lv_stlnr IS NOT INITIAL.

  "数据保存
  PERFORM frm_bom_save USING ps_iwerks lv_stlnr.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DEL_MAST
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      <-- CS_OWERKS
*&---------------------------------------------------------------------*
FORM frm_del_mast CHANGING cs_owerks TYPE zsplm_003_owerks.

  CHECK gt_mast IS NOT INITIAL.

  LOOP AT gt_mast INTO DATA(ls_mast).

    CALL FUNCTION 'CSAP_MAT_BOM_DELETE'
      EXPORTING
        material           = ls_mast-matnr
        plant              = ls_mast-werks
        bom_usage          = ls_mast-stlan
        alternative        = ls_mast-stlal
        fl_commit_and_wait = 'X'
      EXCEPTIONS
        error              = 1
        OTHERS             = 2.

    IF sy-subrc <> 0.

      cs_owerks-code = gc_e.
      cs_owerks-msg  = |可选bom| && ls_mast-stlal && |移除失败:| && zcl_common=>write_message( ).

      EXIT.
    ENDIF.

  ENDLOOP.

ENDFORM.

 涉及公共方法

zcl_common=>abap_to_json

ABAP	TYPE ANY	输入abap数据
PRETTY_NAME	TYPE CHAR1 OPTIONAL	j输出json格式
value( JSON )	TYPE STRING	输出json数据

  METHOD abap_to_json.

    TRY.
        json = /ui2/cl_json=>serialize( data = abap pretty_name = pretty_name ).

      CATCH cx_root INTO DATA(lr_root).
        DATA(l_str) = lr_root->get_text( ).
        MESSAGE l_str TYPE 'S'.
    ENDTRY.

  ENDMETHOD.

zcl_common=>abap_to_json

ABAP	TYPE ANY	输入abap数据
PRETTY_NAME	TYPE CHAR1 OPTIONAL	j输出json格式
value( JSON )	TYPE STRING	输出json数据

  METHOD abap_to_json.

    TRY.
        json = /ui2/cl_json=>serialize( data = abap pretty_name = pretty_name ).

      CATCH cx_root INTO DATA(lr_root).
        DATA(l_str) = lr_root->get_text( ).
        MESSAGE l_str TYPE 'S'.
    ENDTRY.

  ENDMETHOD.
    

zcl_common=>get_guid

  METHOD get_guid.

    TRY.
        rv_guid = cl_system_uuid=>create_uuid_c32_static( ).
      CATCH cx_uuid_error.
        rv_guid = cl_fdt_uuid=>get_uuid( ).
    ENDTRY.

  ENDMETHOD.

zcl_common=>bapi_commit

  METHOD bapi_commit.

    IF type <> 'S'.

      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

    ELSE.

      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait = 'X'.
    ENDIF.

  ENDMETHOD.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值