PLM->SAP 工艺路线接口

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

按需开发,plm与sap进行工艺路线同步,实现目的为通过plm 传输实现工艺路线同步创建修改工艺路线;

其中公司业务背景为 plm 工艺路线无工厂概念,与物料主数据一样,实现为工艺路线层级下挂接物料,导致程序逻辑和业务逻辑难受的一批,甲方也说服不了plm,主要是plm项目已经交了,要是plm改框架属于新开发项,,,你懂的,其中就涉及利益问题了,导致sap遭无妄灾,接口层级反人类,写反馈都是问题

言归正传,公司业务为以下情况,plm 工艺路线 对应工序 维护设备组,且一个工序允许配置多个多个设备,每一个设备下包含多个工作中心/加工机台

设备组对应到 实际加工机台,在sap 存在一张对应 工厂/工作中心/机台/设备组 的配置表,所以在sap 处理时,需要sap 按照设备组拆分工作中心逻辑 排列组合,这样plm一个工艺路线id 在sap会生成多条工艺路线,且每次plm 数据同步,需要按照最新的plm配置的设备组再次拆分,与sap现有业务数据匹配,匹配一致则修改,sap无匹配项则新增,plm减少,则plm删除对应工艺路线,其中匹配规则为对应工作中心拼串,因为所有的规则都是动态的,没有办法定位到具体哪一条工艺路线,生成的工艺路线组反馈给plm,plm下次同步将数据同步回来,这样sap就有了操作清单,sap做一个拆分匹配处理规则

核心逻辑为工艺路线拆分,通过递归一个工序一个工序处理,其中还涉及一些相邻工序设备组一致的话工作中心跟随等细致逻辑

核心代码设计 递归处理,增删改查工艺路线

个性化逻辑较多,仅供参考,自定义表存储就不列出了

接口搭建

功能实现

FUNCTION zfm_plm_005.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(INPUT) TYPE  ZSTPLM_005_INPUT
*"  EXPORTING
*"     VALUE(OUTPUT) TYPE  ZSTPLM_005_OUTPUT
*"----------------------------------------------------------------------

*--init
  PERFORM frm_init USING 'ZFM_PLM_005'.

*--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.

    ELSE.

      PERFORM frm_routine_handle TABLES input output.

    ENDIF.

  ELSE.

    PERFORM frm_005_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_routine_handle TABLES pt_input  TYPE zstplm_005_input
                               pt_output TYPE zstplm_005_output.

  DATA:ls_oplant TYPE zsplm_005_oplant,
       ls_msg    TYPE string.

  "总消息反馈
  APPEND INITIAL LINE TO pt_output ASSIGNING FIELD-SYMBOL(<fs_output>).

  LOOP AT pt_input.

    "输入检查
    PERFORM frm_routine_input_check USING pt_input CHANGING <fs_output>.

    "检查通过
    CHECK <fs_output>-code NE gc_e.
    CLEAR:<fs_output>-ot_matreial.

    LOOP AT pt_input-it_plant INTO DATA(ls_plant).

      CLEAR:ls_plant-plnnr.

      LOOP AT pt_input-it_matreial INTO DATA(ls_material).

        "反馈写入
        READ TABLE <fs_output>-ot_matreial TRANSPORTING NO FIELDS WITH KEY ktext = ls_material-ktext zgylxbb = ls_material-zgylxbb.
        IF sy-subrc NE 0.
          APPEND INITIAL LINE TO <fs_output>-ot_matreial ASSIGNING FIELD-SYMBOL(<fs_ot_material>).
          <fs_ot_material> = CORRESPONDING #( ls_material ).
        ENDIF.

        "数据初始化
        PERFORM frm_routine_init.

        "根据PLM输入工艺路线PK查找sap 工艺路线
        PERFORM frm_routine_get_his USING ls_plant ls_material.

        "按照工厂下 拆分规则进行工艺路线拆分
        PERFORM frm_routine_split USING ls_plant ls_material CHANGING <fs_ot_material>.

        CHECK <fs_ot_material>-code NE gc_e.

        "工艺路线工序组匹配处理
        PERFORM frm_routine_compare USING ls_plant ls_material.

        "工艺路线 创建/修改/删除 分类
        PERFORM frm_routine_split_mode USING ls_plant ls_material.

        "工艺路线处理
        PERFORM frm_routine_process USING ls_plant ls_material CHANGING <fs_ot_material>.

      ENDLOOP.

    ENDLOOP.

    READ TABLE <fs_output>-ot_matreial INTO DATA(ls_omaterial) WITH KEY code = gc_e.
    IF sy-subrc EQ 0.
      <fs_output>-code = gc_e.
      <fs_output>-msg  = ls_omaterial-msg.

    ELSE.
      <fs_output>-code = gc_s.
      <fs_output>-msg  = '工艺路线维护成功'.
    ENDIF.

  ENDLOOP.

  gv_type = <fs_output>-code.

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.


DATA: gv_lines_plant TYPE i,
      gs_plant       TYPE zsplm_005_plant.

DATA:gr_sbzbh TYPE RANGE OF zppt004-sbzbh,
     gr_fz    TYPE RANGE OF string.

TYPES:BEGIN OF typ_plpo.
    INCLUDE TYPE zsplm_005_procedure.
TYPES:zjtdl     TYPE zppt004-zjtdl,
      arbpl_str TYPE string,
      zjtdl_str TYPE string,
      bs        TYPE string, "工艺路线级别数据标识
      fz        TYPE string, "按照每一层数拼接,后续排序
      link      TYPE i, "整理工艺路线与工序关联
      matnr     TYPE mapl-matnr,
      plnty     TYPE mapl-plnty,
      plnnr     TYPE mapl-plnnr,
      plnal     TYPE mapl-plnal,
      END OF typ_plpo,

      BEGIN OF typ_plas,
        plnnr TYPE plas-plnnr,
        plnal TYPE plas-plnal,
        plnfl TYPE plas-plnfl,
        plnty TYPE plas-plnty,
        vornr TYPE plpo-vornr,
        arbpl TYPE crhd-arbpl,
      END OF typ_plas.

DATA:gt_plpo_all TYPE STANDARD TABLE OF typ_plpo,
     gs_plpo_all TYPE typ_plpo,
     gt_plpo_his TYPE STANDARD TABLE OF typ_plpo,
     gs_plpo_his TYPE typ_plpo,
     gt_plpo_crt TYPE STANDARD TABLE OF typ_plpo,
     gs_plpo_crt TYPE typ_plpo,
     gt_plpo_chg TYPE STANDARD TABLE OF typ_plpo,
     gs_plpo_chg TYPE typ_plpo,
     gt_plpo_del TYPE STANDARD TABLE OF typ_plpo,
     gs_plpo_del TYPE typ_plpo.

DATA:gt_plpo_sbz   TYPE zstplm_005_procedure,
     gt_plpo_vornr TYPE STANDARD TABLE OF typ_plpo,
     gt_plas       TYPE STANDARD TABLE OF typ_plas.

DATA:gt_mapl_his   TYPE STANDARD TABLE OF mapl,
     gt_mapl_his01 TYPE STANDARD TABLE OF mapl,
     gs_mapl_his01 TYPE mapl,
     gs_mapl_his   TYPE mapl.

DATA:gs_mara_his TYPE mara.

"创建
DATA:gt_mapl TYPE STANDARD TABLE OF bapi1012_mtk_c,
     gt_plko TYPE STANDARD TABLE OF bapi1012_tsk_c,
     gt_plpo TYPE STANDARD TABLE OF bapi1012_opr_c,
     gt_plfl TYPE STANDARD TABLE OF bapi1012_seq_c,
     gt_plfh TYPE STANDARD TABLE OF bapi1012_prt_c,
     gt_segm TYPE STANDARD TABLE OF bapi1012_tsk_segment
     .
DATA:gv_group        TYPE bapi1012_tsk_c-task_list_group, "任务清单组键值
     gv_groupcounter TYPE bapi1012_tsk_c-group_counter.   "组计数器

DATA:gs_chkim TYPE zpp_s_routing_check,
     gs_chkex TYPE bapiret2.

TYPES:BEGIN OF typ_plpo_map,
        plnfl     TYPE string,
        vornr_in  TYPE string,
        vornr_out TYPE string,
      END OF typ_plpo_map.

DATA:gt_plpo_map TYPE STANDARD TABLE OF typ_plpo_map,
     gs_plpo_map TYPE typ_plpo_map.

"读取
TYPES:BEGIN OF typ_plfh,
        plnty TYPE plfh-plnty,
        plnnr TYPE plfh-plnnr,
        pzlfh TYPE plfh-pzlfh,
        zaehl TYPE plfh-zaehl,
        plnfl TYPE plfh-plnfl,
        plnkn TYPE plfh-plnkn,
        psnfh TYPE plfh-psnfh,
        matnr TYPE crvm_b-matnr,
        werks TYPE crvm_b-werks,
        objty TYPE crvm_b-objty,
        objid TYPE crvm_b-objid,
      END OF typ_plfh.

DATA:gt_tsk_tab  TYPE STANDARD TABLE OF capp_tsk,
     gs_tsk_tab  TYPE capp_tsk,
     gt_seq_tab  TYPE STANDARD TABLE OF capp_seq,
     gs_seq_tab  TYPE capp_seq,
     gt_opr_tab  TYPE STANDARD TABLE OF capp_opr,
     gs_opr_tab  TYPE capp_opr,
     gt_plfh_tab TYPE STANDARD TABLE OF typ_plfh,
     gs_plfh_tab TYPE typ_plfh.

"修改
DATA:gs_chg_plko  TYPE cps_task_list_maint_tsk,
     gs_chg_plkox TYPE cps_task_list_maint_tsk_x,
     gt_chg_mapl  TYPE STANDARD TABLE OF cps_task_list_maint_mtk   WITH HEADER LINE,
     gt_chg_maplx TYPE STANDARD TABLE OF cps_task_list_maint_mtk_x WITH HEADER LINE,
     gt_chg_plfh  TYPE STANDARD TABLE OF cps_task_list_maint_prt   WITH HEADER LINE,
     gt_chg_plfhx TYPE STANDARD TABLE OF cps_task_list_maint_prt_x WITH HEADER LINE,
     gt_chg_plfl  TYPE STANDARD TABLE OF cps_task_list_maint_seq   WITH HEADER LINE,
     gt_chg_plflx TYPE STANDARD TABLE OF cps_task_list_maint_seq_x WITH HEADER LINE,
     gt_chg_plpo  TYPE STANDARD TABLE OF cps_task_list_maint_opr   WITH HEADER LINE,
     gt_chg_plpox TYPE STANDARD TABLE OF cps_task_list_maint_opr_x WITH HEADER LINE,
     gs_del_plko  TYPE cps_task_list_maint_tsk,
     gs_del_plkox TYPE cps_task_list_maint_tsk_x,
     gt_del_plfh  TYPE STANDARD TABLE OF cps_task_list_maint_prt,
     gt_del_plfhx TYPE STANDARD TABLE OF cps_task_list_maint_prt_x,
     gt_del_plfl  TYPE STANDARD TABLE OF cps_task_list_maint_seq,
     gt_del_plflx TYPE STANDARD TABLE OF cps_task_list_maint_seq_x,
     gt_del_plpo  TYPE STANDARD TABLE OF cps_task_list_maint_opr,
     gt_del_plpox TYPE STANDARD TABLE OF cps_task_list_maint_opr_x,
     gt_del_mapl  TYPE STANDARD TABLE OF cps_task_list_maint_mtk,
     gt_del_maplx TYPE STANDARD TABLE OF cps_task_list_maint_mtk_x.


DATA:gv_num_gx TYPE numc10,
     gv_num_sx TYPE numc10,
     gv_numprt TYPE numc10.

*--删除
DATA:gt_mast TYPE STANDARD TABLE OF mast.

子例程


*&---------------------------------------------------------------------*
*& Form FRM_INIT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> P_
*&---------------------------------------------------------------------*
FORM frm_init  USING  VALUE(p_funcn).

  CLEAR:gv_sysid,gv_id,gv_zname,gv_guid,gv_active,
        gv_type,gv_matnr,gv_msg,
        gv_json_in,gv_json_out.

  gv_guid  = zcl_common=>get_guid( ).
  gv_sysid = p_funcn+4(3).
  gv_id    = p_funcn+4(7).
  gv_zname = p_funcn.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_CHECK_ACTIVE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_check_active USING pv_if_type.

  CLEAR gs_zif_001.

  SELECT SINGLE *
    FROM zif_001
    INTO gs_zif_001
   WHERE zsysid EQ gv_sysid
     AND id     EQ gv_id
     AND active EQ abap_on.

  IF gs_zif_001 IS NOT INITIAL.

    IF pv_if_type EQ gc_i.

      gv_active = abap_true.

    ELSEIF pv_if_type EQ gc_o.

      IF gs_zif_001-url IS NOT INITIAL.

        gv_active = abap_true.

      ELSE.

        CLEAR:gv_active.

      ENDIF.

    ENDIF.

  ELSE.

    CLEAR:gv_active.

  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_004_RET_E
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> INPUT
*&      --> OUTPUT
*&---------------------------------------------------------------------*
FORM frm_005_ret_e  TABLES   pt_input  TYPE zstplm_005_input
                             pt_output TYPE zstplm_005_output.

  APPEND VALUE #( code  = gc_e msg   = '接口未启用,请联系SAP管理人员'   ) TO pt_output.

  gv_type = gc_e.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_LOG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_set_log USING lv_if_type.

  MODIFY zif_log FROM @( VALUE #( zguid     = gv_guid   "操作唯一性标识
                                  zsysid    = gv_sysid  "外围系统
                                  zid       = gv_id     "接口业务ID
                                  zname     = gv_zname  "函数名称
                                  zietype   = lv_if_type"接口传输类型(I传入SAP,O传出到外部系统)
                                  zerdat    = sy-datum
                                  zerzet    = sy-uzeit
                                  zernam    = sy-uname
                                  type      = COND #( WHEN gv_type IS NOT INITIAL THEN gv_type ELSE gc_s )
                                  json_in   = gv_json_in
                                  json_out  = gv_json_out ) ).

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

  DATA(lv_datum) = sy-datum - 120.
  DELETE FROM zif_log WHERE zerdat LE lv_datum.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_HANDLE1
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> INPUT
*&      --> OUTPUT
*&---------------------------------------------------------------------*
FORM frm_routine_handle TABLES pt_input  TYPE zstplm_005_input
                               pt_output TYPE zstplm_005_output.

  DATA:ls_oplant TYPE zsplm_005_oplant,
       ls_msg    TYPE string.

  "总消息反馈
  APPEND INITIAL LINE TO pt_output ASSIGNING FIELD-SYMBOL(<fs_output>).

  LOOP AT pt_input.

    "输入检查
    PERFORM frm_routine_input_check USING pt_input CHANGING <fs_output>.

    "检查通过
    CHECK <fs_output>-code NE gc_e.
    CLEAR:<fs_output>-ot_matreial.

    LOOP AT pt_input-it_plant INTO DATA(ls_plant).

      CLEAR:ls_plant-plnnr.

      LOOP AT pt_input-it_matreial INTO DATA(ls_material).

        "反馈写入
        READ TABLE <fs_output>-ot_matreial TRANSPORTING NO FIELDS WITH KEY ktext = ls_material-ktext zgylxbb = ls_material-zgylxbb.
        IF sy-subrc NE 0.
          APPEND INITIAL LINE TO <fs_output>-ot_matreial ASSIGNING FIELD-SYMBOL(<fs_ot_material>).
          <fs_ot_material> = CORRESPONDING #( ls_material ).
        ENDIF.

        "数据初始化
        PERFORM frm_routine_init.

        "根据PLM输入工艺路线PK查找sap 工艺路线
        PERFORM frm_routine_get_his USING ls_plant ls_material.

        "按照工厂下 拆分规则进行工艺路线拆分
        PERFORM frm_routine_split USING ls_plant ls_material CHANGING <fs_ot_material>.

        CHECK <fs_ot_material>-code NE gc_e.

        "工艺路线工序组匹配处理
        PERFORM frm_routine_compare USING ls_plant ls_material.

        "工艺路线 创建/修改/删除 分类
        PERFORM frm_routine_split_mode USING ls_plant ls_material.

        "工艺路线处理
        PERFORM frm_routine_process USING ls_plant ls_material CHANGING <fs_ot_material>.

      ENDLOOP.

    ENDLOOP.

    READ TABLE <fs_output>-ot_matreial INTO DATA(ls_omaterial) WITH KEY code = gc_e.
    IF sy-subrc EQ 0.
      <fs_output>-code = gc_e.
      <fs_output>-msg  = ls_omaterial-msg.

    ELSE.
      <fs_output>-code = gc_s.
      <fs_output>-msg  = '工艺路线维护成功'.
    ENDIF.

  ENDLOOP.

  gv_type = <fs_output>-code.

ENDFORM.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_INPUT_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_INPUT
*&      <-- PT_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_routine_input_check  USING    ps_input  TYPE zsplm_005_input
                              CHANGING cs_output TYPE zsplm_005_output.

  TYPES:BEGIN OF typ_sbz,
          zdevgrp TYPE string,
        END OF typ_sbz.

  DATA: lt_sbz_vornr_list TYPE STANDARD TABLE OF typ_sbz,
        lt_sbz_bef_list   TYPE STANDARD TABLE OF typ_sbz.

  DATA:ls_ot_plant  TYPE zsplm_005_oplant,
       lt_plpo_chk  TYPE STANDARD TABLE OF typ_plpo,
       lv_werks_msg TYPE string, "工厂级别数据校验
       lv_msg       TYPE string,
       lv_tabix     TYPE i,
       lv_vornr     TYPE numc4.
  DATA:lv_lines     TYPE i.

*--物料编码必填
  IF ps_input-matnr IS INITIAL.
    cs_output = VALUE #( BASE cs_output code = gc_e ). RETURN.
  ELSE.
    PERFORM frm_inzero USING 'CHAR18' CHANGING ps_input-matnr.

    IF sy-subrc NE 0.
      cs_output = VALUE #( BASE cs_output code = gc_e msg = '物料编码SAP转换失败,请检查!' ). RETURN.
    ENDIF.
  ENDIF.

  DELETE ps_input-it_plant WHERE werks EQ '2000'.
  DELETE ps_input-it_plant WHERE werks EQ '9000'.

*--工厂数据检查
  IF ps_input-it_plant IS INITIAL.
    cs_output = VALUE #( BASE cs_output code = gc_e msg = '工厂数据必填' ). RETURN.
  ELSE.

    " "物权工厂标识在对应工厂必须输入.
    " CLEAR lv_lines.
    " lv_lines = lines( ps_input-it_plant ).
    "
    " READ TABLE ps_input-it_plant TRANSPORTING NO FIELDS WITH KEY zwqgc = abap_true.
    " IF sy-subrc NE 0 .
    "   IF lv_lines > 1.
    "     cs_output = VALUE #( BASE cs_output code = gc_e msg = '物权工厂标识必填' ).RETURN.
    "   ENDIF.
    " ENDIF.

    LOOP AT ps_input-it_plant INTO DATA(ls_plant).

      CLEAR:lv_werks_msg.

      SELECT COUNT(*) FROM mara WHERE matnr EQ ps_input-matnr.
      IF sy-subrc NE 0.
        lv_werks_msg = |物料在工厂{ ls_plant-werks }不存在,请检查!|.
        cs_output = VALUE #( BASE cs_output code = gc_e msg = lv_werks_msg ). RETURN.
      ENDIF.

    ENDLOOP.
  ENDIF.

*--工艺路线输入检查
  IF ps_input-it_matreial IS INITIAL.

    cs_output = VALUE #( BASE cs_output code = gc_e msg = '工艺路线信息必填!' ). RETURN.

  ELSE.

    LOOP AT ps_input-it_matreial ASSIGNING FIELD-SYMBOL(<fs_material>).

      "写入工艺路线级别反馈
      APPEND INITIAL LINE TO cs_output-ot_matreial ASSIGNING FIELD-SYMBOL(<fs_omaterial>).

      <fs_omaterial> = CORRESPONDING #( <fs_material> ).

      CLEAR:<fs_material>-plnal.

      IF <fs_material>-matnr IS INITIAL.
        <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '物料编码必填!' ).
        CONTINUE.
      ELSE.

        PERFORM frm_inzero USING 'CHAR18' CHANGING <fs_material>-matnr.

        IF sy-subrc NE 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '物料编码SAP转换失败,请检查!' ).
          CONTINUE.
        ENDIF.
      ENDIF.

      IF <fs_material>-plnty IS INITIAL.
        <fs_material>-plnty = 'N'.
      ENDIF.

      IF <fs_material>-verwe IS INITIAL.
        <fs_material>-verwe = '1'.
      ENDIF.

      IF <fs_material>-ktext IS INITIAL.
        <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工艺路线ID必填!' ).
        CONTINUE.
      ENDIF.

      IF <fs_material>-datuv IS INITIAL.
        <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '起始有效期必填!' ).
        CONTINUE.
      ENDIF.

*--IT_SAP_PK check
      IF <fs_material>-it_sap_pk IS NOT INITIAL .

        READ TABLE <fs_material>-it_sap_pk TRANSPORTING NO FIELDS WITH KEY werks = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'SAP工艺路线PK-工厂必填!' ).
          CONTINUE.
        ENDIF.

        READ TABLE <fs_material>-it_sap_pk TRANSPORTING NO FIELDS WITH KEY matnr = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'SAP工艺路线PK-物料必填!' ).
          CONTINUE.
        ENDIF.

        READ TABLE <fs_material>-it_sap_pk TRANSPORTING NO FIELDS WITH KEY plnnr = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'SAP工艺路线PK-组号必填!' ).
          CONTINUE.
        ENDIF.

        READ TABLE <fs_material>-it_sap_pk TRANSPORTING NO FIELDS WITH KEY plnal = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'SAP工艺路线PK-组计数器必填!' ).
          CONTINUE.

        ENDIF.

        LOOP AT <fs_material>-it_sap_pk ASSIGNING FIELD-SYMBOL(<fs_osappk>).

          PERFORM frm_inzero USING 'CHAR8'  CHANGING <fs_osappk>-plnnr.
          PERFORM frm_inzero USING 'CHAR18' CHANGING <fs_osappk>-matnr.
          PERFORM frm_inzero USING 'CHAR2'  CHANGING <fs_osappk>-plnal.

          "工艺路线有效性校验
          SELECT COUNT( * )
            FROM plko
           INNER JOIN mapl
              ON plko~plnnr EQ mapl~plnnr
             AND plko~plnal EQ mapl~plnal
           WHERE plko~plnnr EQ <fs_osappk>-plnnr
             AND plko~plnal EQ <fs_osappk>-plnal
             AND mapl~matnr EQ <fs_osappk>-matnr
             AND mapl~werks EQ <fs_osappk>-werks
             AND plko~delkz NE abap_true
             AND plko~loekz NE abap_true.

          IF sy-subrc NE 0.
            <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = |{ <fs_osappk>-plnnr ALPHA = OUT } | && '/' && |{ <fs_osappk>-plnal ALPHA = OUT } | && 'SAP没有有效的工艺路线!' ).
            EXIT.
          ENDIF.


        ENDLOOP.

      ENDIF.

      IF <fs_omaterial>-code = gc_e.
        CONTINUE.
      ENDIF.

*--IT_VERS check
      IF <fs_material>-it_vers IS INITIAL .

        <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '版本数据必填!' ).
        CONTINUE.

      ELSE.

        READ TABLE <fs_material>-it_vers TRANSPORTING NO FIELDS WITH KEY materev = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '版本数据-物料版本(版次)必填!' ).
          CONTINUE.
        ENDIF.

      ENDIF.

      SELECT SINGLE *  FROM mara INTO @DATA(ls_mara_tmp) WHERE matnr EQ @ps_input-matnr." AND  mtart IN ('LD01','LD03').

*--it_sequence check
      IF <fs_material>-it_plfl IS INITIAL.

        IF ls_mara_tmp-mtart EQ 'LD20' OR ls_mara_tmp-mtart EQ 'LD21'.

          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '顺序数据必填!' ).

        ELSEIF ls_mara_tmp-mtart EQ 'LD01' OR ls_mara_tmp-mtart EQ 'LD03'.

          APPEND VALUE #( plnfl = '000000' ltxa1 = '标准顺序') TO <fs_material>-it_plfl.

        ENDIF.

      ELSE.

        LOOP AT  <fs_material>-it_plfl ASSIGNING FIELD-SYMBOL(<fs_sequence>).

          IF <fs_sequence>-plnfl IS INITIAL.
            <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '顺序数据-序列编码必填!' ).
            EXIT.
          ELSE.

            PERFORM frm_inzero USING 'CHAR6' CHANGING <fs_sequence>-plnfl.

            IF <fs_sequence>-plnfl EQ '000000'.

            ELSE.

              IF <fs_sequence>-bezfl IS INITIAL.
                <fs_sequence>-bezfl = '000000'.
              ELSE.
                PERFORM frm_inzero USING 'CHAR6' CHANGING <fs_sequence>-bezfl.
              ENDIF.

            ENDIF.

          ENDIF.

          IF <fs_sequence>-ltxa1 IS INITIAL.
            <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '顺序数据-顺序描述必填!' ).
            EXIT.
          ENDIF.

        ENDLOOP.

        IF <fs_omaterial>-code EQ 'E'.
          CONTINUE.
        ENDIF.

      ENDIF.

*--it_procedure check

      IF <fs_material>-it_plpo IS INITIAL.
        <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据必填!' ).
        CONTINUE.
      ELSE.

        READ TABLE <fs_material>-it_plpo INTO DATA(ls_procedure) WITH KEY vornr = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-操作/活动编号必填!' ).
          CONTINUE.
        ENDIF.

        CLEAR ls_procedure.
        READ TABLE <fs_material>-it_plpo INTO ls_procedure WITH KEY ltxa1 = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-工序短文本必填!' ).
          CONTINUE.
        ENDIF.

        CLEAR ls_procedure.
        READ TABLE <fs_material>-it_plpo INTO ls_procedure WITH KEY zgxid = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-工序ID必填!' ).
          CONTINUE.
        ENDIF.

        CLEAR ls_procedure.
        READ TABLE <fs_material>-it_plpo INTO ls_procedure WITH KEY bmsch = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-基本数量必填!' ).
          CONTINUE.
        ENDIF.

        CLEAR ls_procedure.
        READ TABLE <fs_material>-it_plpo INTO ls_procedure WITH KEY zdevgrp = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-设备组必填!' ).
          CONTINUE.
        ENDIF.

        CLEAR ls_procedure.
        READ TABLE <fs_material>-it_plpo INTO ls_procedure WITH KEY meinh = space.
        IF sy-subrc EQ 0.
          <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-作业的计量单位必填!' ).
          CONTINUE.
        ELSE.

          DATA(lt_plpo) = <fs_material>-it_plpo.
          SORT lt_plpo BY vornr ASCENDING.
          READ TABLE lt_plpo INTO DATA(ls_plpo) INDEX 1.

          LOOP AT <fs_material>-it_plpo ASSIGNING FIELD-SYMBOL(<fs_procedure>).

            IF <fs_procedure>-ltxa1 CS '装配'.
              DELETE <fs_material>-it_plpo INDEX sy-tabix.
              CONTINUE.
            ENDIF.

            IF <fs_procedure>-ltxa1 CS '单作工序'.
              DELETE <fs_material>-it_plpo INDEX sy-tabix.
              CONTINUE.
            ENDIF.

            DATA(lv_meinh) = <fs_procedure>-meinh.
            meins_input <fs_procedure>-meinh.

            IF <fs_procedure>-umren IS INITIAL.
              <fs_procedure>-umren = '1'.
            ENDIF.

            PERFORM frm_inzero USING 'CHAR4' CHANGING <fs_procedure>-vornr.

            SELECT COUNT(*) FROM mara WHERE matnr EQ ps_input-matnr AND  mtart IN ('LD01','LD03').
            IF sy-subrc EQ 0.
              <fs_procedure>-plnfl = '000000'.
            ENDIF.

            IF <fs_procedure>-plnfl IS INITIAL.
              <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = '工序数据-序列编码必填!' ).
              EXIT.
            ELSE.

              PERFORM frm_inzero USING 'CHAR6' CHANGING <fs_procedure>-plnfl.

            ENDIF.

            "校验plm传输的数据设备组在sap 获取工作中心校验,获取失败则退回
            SELECT SINGLE zjtdl FROM zppt004 INTO @DATA(lv_zjtdl) WHERE sbzbh EQ @<fs_procedure>-zdevgrp.
            IF sy-subrc NE 0.

              <fs_omaterial> = VALUE #( BASE <fs_omaterial>
                                        code = gc_e
                                        msg  = '序列' && |{ <fs_procedure>-plnfl }| && '/' &&
                                               '工序' && |{ <fs_procedure>-vornr ALPHA = OUT } | &&
                                               '设备组' && <fs_procedure>-zdevgrp &&
                                               '在SAP读取失败,请在SAP维护ZPPT004设备组信息').

              EXIT.
            ELSE.
              "相同序列+工序编号对应所有传入的设备组所属大类 校验
              READ TABLE lt_plpo_chk INTO DATA(ls_plpo_chk) WITH KEY plnfl = <fs_procedure>-plnfl
                                                                     vornr = <fs_procedure>-vornr.
              IF sy-subrc EQ 0.
                IF lv_zjtdl NE ls_plpo_chk-zjtdl.
                  <fs_omaterial> = VALUE #( BASE <fs_omaterial>
                                            code = gc_e
                                            msg  = '序列' && |{ <fs_procedure>-plnfl }| && '/' &&
                                                   '工序' && |{ <fs_procedure>-vornr ALPHA = OUT } | &&
                                                   '的设备组不在同一个大类内,请检查设备组!').
                  EXIT.
                ENDIF.
              ENDIF.
            ENDIF.


            APPEND VALUE #( zjtdl = lv_zjtdl zdevgrp = <fs_procedure>-zdevgrp plnfl =  <fs_procedure>-plnfl vornr = <fs_procedure>-vornr ) TO lt_plpo_chk.
            SORT lt_plpo_chk BY plnfl vornr.

            CLEAR:lv_zjtdl.

            LOOP AT <fs_procedure>-it_prt ASSIGNING FIELD-SYMBOL(<fs_prt>) WHERE zlzjlx EQ  '工装' OR zlzjlx EQ  '模具' OR zlzjlx EQ '组合刀具' .

              IF <fs_prt>-psnfh IS INITIAL.
                <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'PRT-生产资源/工具项目号必填!' ).
                EXIT.
              ELSE.
                PERFORM frm_inzero USING 'CHAR4' CHANGING <fs_prt>-psnfh.
              ENDIF.

              IF <fs_prt>-mgvgw IS INITIAL.
                <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'PRT-数量必填!' ).
                EXIT.
              ENDIF.

              IF <fs_prt>-fhmnr IS INITIAL.
                <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = 'PRT-ID号必填!' ).
                EXIT..
              ENDIF.

              "物料替换
              IF <fs_prt>-zlzjlx EQ '组合刀具' .
                SELECT SINGLE * FROM mara INTO @DATA(ls_mara) WHERE wrkst EQ @<fs_prt>-fhmnr.
                IF sy-subrc EQ 0.
                  <fs_prt>-fhmnr = ls_mara-matnr.
                ELSE."第二个工厂第二次检查数据已改,需直接按照matnr取数
                  SELECT SINGLE * FROM mara INTO ls_mara WHERE matnr EQ <fs_prt>-fhmnr.
                  IF sy-subrc NE 0.
                    gv_msg =  'PRT-生产资源 SAP没有' && <fs_prt>-fhmnr && '的整刀物料号' .
                    <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = gv_msg ).
                    EXIT.
                  ENDIF.
                ENDIF.
              ELSE.

                PERFORM frm_inzero USING 'CHAR18' CHANGING <fs_prt>-fhmnr.

                SELECT SINGLE * FROM mara INTO ls_mara WHERE matnr EQ <fs_prt>-fhmnr.
              ENDIF.

              IF <fs_prt>-mgeinh IS NOT INITIAL.
                meins_input <fs_prt>-mgeinh.
              ELSE.
                <fs_prt>-mgeinh = ls_mara-meins.
              ENDIF.

              CLEAR:ls_mara.

            ENDLOOP.

            IF <fs_omaterial>-code EQ 'E'.
              EXIT.
            ENDIF.

          ENDLOOP.

          "相邻工序同属于一大类,其包含设备组要一致
          "lt_plpo = <fs_material>-it_plpo.
          "SORT lt_plpo BY plnfl vornr.
          "DELETE ADJACENT DUPLICATES FROM lt_plpo COMPARING  plnfl vornr.
          "
          "LOOP AT lt_plpo INTO ls_plpo.
          "
          "  IF  sy-tabix NE 1.
          "
          "    READ TABLE lt_plpo INTO DATA(ls_plpo_bef) INDEX sy-tabix - 1.
          "    CHECK sy-subrc EQ 0.
          "
          "    "当前工序设备组
          "    DATA(lt_sbz_vornr) = lt_plpo_chk.
          "    DELETE lt_sbz_vornr WHERE plnfl NE ls_plpo-plnfl OR vornr NE ls_plpo-vornr.
          "    READ TABLE lt_sbz_vornr INTO DATA(ls_sbz_vornr) INDEX 1.
          "
          "    "前道工序设备组
          "    DATA(lt_sbz_bef) = lt_plpo_chk.
          "    DELETE lt_sbz_bef WHERE plnfl NE ls_plpo_bef-plnfl OR vornr NE ls_plpo_bef-vornr.
          "    READ TABLE lt_sbz_bef INTO DATA(ls_sbz_bef) INDEX 1.
          "
          "    "属于同一大类
          "    CHECK ls_sbz_vornr IS NOT INITIAL AND ls_sbz_bef IS NOT INITIAL.
          "    CHECK ls_sbz_vornr-zjtdl EQ ls_sbz_bef-zjtdl.
          "
          "    "设备组清单需一致
          "    lt_sbz_vornr_list = CORRESPONDING #( lt_sbz_vornr ).
          "    SORT lt_sbz_vornr_list BY zdevgrp.
          "    DELETE ADJACENT DUPLICATES FROM lt_sbz_vornr_list COMPARING zdevgrp.
          "
          "    lt_sbz_bef_list = CORRESPONDING #( lt_sbz_bef ).
          "    SORT lt_sbz_bef_list BY zdevgrp.
          "    DELETE ADJACENT DUPLICATES FROM lt_sbz_bef_list COMPARING zdevgrp.
          "
          "    IF lt_sbz_vornr_list NE lt_sbz_bef_list.
          "
          "      lv_msg = |序列{ ls_plpo-plnfl ALPHA = OUT }中工序{ ls_plpo_bef-vornr }、{ ls_plpo-vornr }的设备组不一致,请检查!|.
          "      <fs_omaterial> = VALUE #( BASE <fs_omaterial> code = gc_e msg = lv_msg ).
          "      EXIT.
          "
          "    ENDIF.
          "
          "  ENDIF.
          "
          "  CLEAR:lt_sbz_vornr,lt_sbz_bef,ls_sbz_vornr,ls_sbz_bef,lt_sbz_vornr_list,lt_sbz_bef_list.
          "
          "ENDLOOP.
          "
          "IF <fs_omaterial>-code EQ 'E'.
          "  EXIT.
          "ENDIF.

        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDIF.

  cs_output = VALUE #( BASE cs_output
                       code = COND #( WHEN <fs_omaterial>-msg IS INITIAL THEN gc_s ELSE gc_e )
                       msg  = <fs_omaterial>-msg ).

  CLEAR:ls_ot_plant ,
        lt_plpo_chk ,
        lv_werks_msg,
        lv_tabix    ,
        lv_vornr    ,
        lv_lines    .

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_ROUTINE_INIT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_routine_init .

  CLEAR:gt_plpo_all,
        gs_plpo_all,
        gt_plpo_his,
        gt_mapl_his,
        gt_plpo_crt,
        gt_plpo_chg,
        gt_plpo_del,
        gs_mara_his,
        gt_plpo_sbz,
        gt_plpo_vornr,
        gt_plas
        .

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_routine_get_his
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_PLANT
*&      --> PT_INPUT_IT_material
*&---------------------------------------------------------------------*
FORM frm_routine_get_his  USING ps_plant    TYPE zsplm_005_plant
                                ps_material TYPE zsplm_005_material.

  DATA lt_014 TYPE STANDARD TABLE OF zplm_t_014.

  lt_014 = CORRESPONDING #( ps_material-it_sap_pk ).
  DELETE lt_014 WHERE werks NE ps_plant-werks.

  CHECK lt_014 IS NOT INITIAL.
  MODIFY lt_014 FROM VALUE #( plnty = 'N' ) TRANSPORTING plnty WHERE plnty IS INITIAL.

*--读取 工艺路线 工序工作中心
  SELECT DISTINCT
         plas~plnnr
         plas~plnal
         plas~plnfl
         plas~plnty
         plpo~vornr
         crhd~arbpl
    FROM plas
   INNER JOIN plpo
      ON plpo~plnnr EQ plas~plnnr
     AND plpo~plnty EQ plas~plnty
     AND plpo~plnkn EQ plas~plnkn
   INNER JOIN plko
      ON plko~plnnr EQ plas~plnnr
     AND plko~plnty EQ plas~plnty
     AND plko~plnal EQ plas~plnal
     AND plko~delkz EQ space
     AND plko~loekz EQ space
   INNER JOIN crhd
      ON plpo~arbid EQ crhd~objid
    INTO TABLE gt_plas
    FOR ALL ENTRIES IN lt_014
   WHERE plas~plnnr EQ lt_014-plnnr
     AND plas~plnal EQ lt_014-plnal
     AND plas~plnty EQ lt_014-plnty.

  SORT gt_plas BY plnfl vornr arbpl .

  DATA(lt_plas_tmp) = gt_plas.
  DELETE ADJACENT DUPLICATES FROM lt_plas_tmp COMPARING plnnr plnal plnty.

  IF lt_plas_tmp IS NOT INITIAL.

    SELECT *
      FROM mapl
      INTO TABLE gt_mapl_his
       FOR ALL ENTRIES IN lt_plas_tmp
     WHERE plnnr EQ lt_plas_tmp-plnnr
       AND plnal EQ lt_plas_tmp-plnal
       AND plnty EQ lt_plas_tmp-plnty
       AND loekz EQ space.

  ENDIF.

  SORT gt_mapl_his BY matnr werks.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_SPLIT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_PLANT
*&      --> PT_INPUT_IT_material
*&---------------------------------------------------------------------*
FORM frm_routine_split  USING ps_plant    TYPE zsplm_005_plant
                              ps_material TYPE zsplm_005_material
                     CHANGING cs_omaterial TYPE zsplm_005_omaterial.

  DATA:lt_plpo     TYPE STANDARD TABLE OF typ_plpo,
       ls_plpo     TYPE typ_plpo,
       ls_plpo_bef TYPE typ_plpo,
       lt_plpo_01  TYPE STANDARD TABLE OF typ_plpo,
       lv_link     TYPE i VALUE '1',
       lv_fzbs     TYPE numc2.

  DATA:lt_sbzbh TYPE STANDARD TABLE OF zppt004.

*--整理设备组
  lt_sbzbh = CORRESPONDING #( ps_material-it_plpo[] MAPPING sbzbh = zdevgrp ).
  DELETE lt_sbzbh WHERE sbzbh EQ space.

  SORT lt_sbzbh BY sbzbh.
  DELETE ADJACENT DUPLICATES FROM lt_sbzbh COMPARING sbzbh.

  CHECK lt_sbzbh IS NOT INITIAL.

*--根据设备组读取sap 工作中心
  SELECT *
    FROM zppt004
    INTO TABLE @DATA(lt_004)
     FOR ALL ENTRIES IN @lt_sbzbh
   WHERE sbzbh EQ @lt_sbzbh-sbzbh.

  MODIFY lt_004 FROM VALUE #( werks = ps_plant-werks ) TRANSPORTING werks WHERE sbzbh = '外协' .

  CHECK lt_004 IS NOT INITIAL.

  SORT lt_004 BY sbzbh.

*--删除不符合业务的工作中心
  LOOP AT lt_004 INTO DATA(ls_004).

    DATA(lv_tabix) = sy-tabix.

    IF ls_004-werks EQ ps_plant-werks.
      IF ls_004-arbpl_cbhs+0(2) EQ 'XN' AND ls_004-arbpl_cbhs+2(2) EQ ls_004-werks+0(2).
        DELETE lt_004 INDEX lv_tabix.
      ENDIF.
    ELSE.
      IF ls_004-arbpl_cbhs+0(2) NE 'XN' AND ls_004-arbpl_cbhs+2(2) NE ls_004-werks+0(2)..
        DELETE lt_004 INDEX lv_tabix .
      ENDIF.
    ENDIF.

  ENDLOOP.

  SORT lt_004 BY sbzbh arbpl_cbhs.
  DELETE ADJACENT DUPLICATES FROM lt_004 COMPARING sbzbh arbpl_cbhs.

*--工序-PLM传输多道,需要按照工序删重
  lt_plpo = CORRESPONDING #( ps_material-it_plpo[] ).
  SORT lt_plpo BY plnfl vornr.
  DELETE ADJACENT DUPLICATES FROM lt_plpo COMPARING plnfl vornr ."vgw01 vgw02 vgw03 vgw04.
  READ TABLE lt_plpo INTO ls_plpo INDEX 1.
  CHECK ls_plpo-vornr IS NOT INITIAL.

  gt_plpo_vornr = lt_plpo[].
  SORT gt_plpo_vornr BY plnfl vornr.
  DELETE ADJACENT DUPLICATES FROM gt_plpo_vornr COMPARING plnfl vornr.

*--按照设备组对工序分配工作中心

  "整理工序设备组清单
  gt_plpo_sbz = CORRESPONDING #( ps_material-it_plpo[] ).
  "SORT gt_plpo_sbz BY vornr vgw01 vgw02 vgw03 vgw04 zdevgrp.
  SORT gt_plpo_sbz BY vornr zdevgrp.
  "DELETE ADJACENT DUPLICATES FROM gt_plpo_sbz COMPARING vornr vgw01 vgw02 vgw03 vgw04 zdevgrp.
  DELETE ADJACENT DUPLICATES FROM gt_plpo_sbz COMPARING vornr zdevgrp.

  LOOP AT lt_plpo INTO ls_plpo WHERE plnfl = ls_plpo-plnfl AND vornr = ls_plpo-vornr.
    lv_fzbs = lv_fzbs + 1 .
    PERFORM frm_routine_list_set TABLES lt_004 lt_plpo gt_plpo_all USING lv_fzbs '' ''  ls_plpo ls_plpo_bef .
  ENDLOOP.

  SORT gt_plpo_all BY fz.

  CLEAR:lt_004,lt_plpo,lt_plpo_01,ls_004,lv_link,ls_plpo,ls_plpo_bef.

ENDFORM.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_LIST_SET
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LV_VORNR
*&      --> LT_PLPO
*&---------------------------------------------------------------------*
FORM frm_routine_list_set  TABLES pt_004      STRUCTURE zppt004
                                  pt_plpo     LIKE gt_plpo_all
                                  pt_plpo_01  LIKE gt_plpo_all
                            USING pv_fzbs
                                  pv_fz
                                  pv_arbpl_last TYPE string
                                  ps_plpo       TYPE typ_plpo
                                  ps_plpo_bef   TYPE typ_plpo .

  DATA:lv_where  TYPE string,
       lv_where1 TYPE string,
       lv_arbpl  TYPE string.

  DATA:lv_gx_fz TYPE numc2.

  CLEAR:gr_sbzbh,lv_gx_fz.

  "限制传入工序设备组
  DATA(lt_plpo_sbz) = gt_plpo_sbz .
  LOOP AT gt_plpo_sbz INTO DATA(ls_plpo_sbz) WHERE vornr EQ ps_plpo-vornr.
    "AND vgw01 EQ ps_plpo-vgw01
    "AND vgw02 EQ ps_plpo-vgw02
    "AND vgw03 EQ ps_plpo-vgw03
    "AND vgw04 EQ ps_plpo-vgw04 .

    APPEND VALUE #( sign = 'I' option = 'EQ' low = ls_plpo_sbz-zdevgrp ) TO gr_sbzbh.

  ENDLOOP.

  CHECK gr_sbzbh IS NOT INITIAL.

  lv_where  = |SBZBH IN GR_SBZBH|.
  lv_where1 = |SBZBH NOT IN GR_SBZBH|.

  "当前工序设备组 对应004 可用工作中心组合
  DATA(lt_004) = pt_004[].
  DELETE lt_004 WHERE (lv_where1).
  SORT lt_004 BY arbpl_cbhs.
  DELETE ADJACENT DUPLICATES FROM lt_004 COMPARING arbpl_cbhs.
  LOOP AT lt_004 INTO DATA(ls_004).
    lv_arbpl = lv_arbpl && ls_004-arbpl_cbhs.
  ENDLOOP.

  DATA(lr_sbzbh) = gr_sbzbh.
  PERFORM frm_routine_list_allocation TABLES pt_004 pt_plpo pt_plpo_01 USING pv_arbpl_last lv_arbpl lv_where  pv_fzbs pv_fz  '' ps_plpo ps_plpo_bef CHANGING lv_gx_fz.

  IF ps_plpo_bef-werks EQ '3000' AND ps_plpo-ltxa1 CS '手枪钻'.
    gr_sbzbh = lr_sbzbh.    CLEAR:lr_sbzbh.
    lv_where = |{ lv_where } AND ZJTDL = '摇臂钻'|.
    PERFORM frm_routine_list_allocation TABLES pt_004 pt_plpo pt_plpo_01 USING pv_arbpl_last lv_arbpl lv_where  pv_fzbs pv_fz  'X' ps_plpo ps_plpo_bef CHANGING lv_gx_fz.
  ENDIF.

  CLEAR:lv_where,lv_arbpl,lv_where1.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_routine_list_allocation
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LV_VORNR
*&      --> LT_PLPO
*&---------------------------------------------------------------------*
FORM frm_routine_list_allocation  TABLES pt_004      STRUCTURE zppt004
                                         pt_plpo     LIKE gt_plpo_all
                                         pt_plpo_01  LIKE gt_plpo_all
                                   USING pv_arbpl_last TYPE string
                                         pv_arbpl      TYPE string
                                         pv_where
                                         pv_fzbs
                                         pv_fz
                                         pv_sqz
                                         ps_plpo     TYPE typ_plpo
                                         ps_plpo_bef TYPE typ_plpo
                                CHANGING pv_gx_fz.

  DATA:lv_fz   TYPE numc2,
       lv_fzbs TYPE numc2,
       lv_exit TYPE c.

  DATA(ls_plpo)     = pt_plpo.
  DATA(ls_plpo_01)  = pt_plpo_01.

  READ TABLE gt_plpo_vornr INTO DATA(ls_plpo_vornr) WITH KEY plnfl = ps_plpo-plnfl vornr = ps_plpo-vornr BINARY SEARCH.

  DATA(lv_tabix) = sy-tabix.

  CLEAR pt_004.

  LOOP AT pt_004 INTO pt_004 WHERE (pv_where) GROUP BY ( arbpl_cbhs = pt_004-arbpl_cbhs
                                                         werks      = pt_004-werks
                                                         zjtdl      = pt_004-zjtdl
                                                         index      = GROUP INDEX
                                                         size       = GROUP SIZE  )
                             REFERENCE INTO DATA(lr_arbpl) .

    pt_004-arbpl_cbhs = lr_arbpl->arbpl_cbhs.
    pt_004-werks      = lr_arbpl->werks.
    pt_004-zjtdl      = lr_arbpl->zjtdl.

    pv_gx_fz = pv_gx_fz + 1.

    ls_plpo_01 = CORRESPONDING #( ps_plpo ).


    "相邻工序设备组同属同一大类,跟随使用上一道工序工作中心,且每道工序可用工作中心一致
    IF ( ps_plpo_bef-zjtdl EQ lr_arbpl->zjtdl AND pv_arbpl_last = pv_arbpl )
       OR pv_sqz EQ abap_true."摇臂钻 手枪钻 3000

      ls_plpo_01-arbpl = ps_plpo_bef-arbpl.
      ls_plpo_01-werks = ps_plpo_bef-werks.

      lv_exit = abap_true.

    ELSE.
      ls_plpo_01-arbpl = lr_arbpl->arbpl_cbhs.
      ls_plpo_01-werks = lr_arbpl->werks.
    ENDIF.

    ls_plpo_01-zjtdl = lr_arbpl->zjtdl.
    ls_plpo_01-fz    = pv_fz && pv_fzbs && pv_gx_fz. CONDENSE ls_plpo_01-fz NO-GAPS.

    "工序描述
    IF ls_plpo_01-zgxbz IS NOT INITIAL.
      ls_plpo_01-ltxa1 = ls_plpo_01-ltxa1 && '_' && ls_plpo_01-zgxbz.
    ENDIF.

    "大类拼接
    SELECT SINGLE name1 FROM t001w INTO @DATA(lv_name1) WHERE werks = @ls_plpo_01-werks.

    LOOP AT GROUP lr_arbpl INTO DATA(ls_lr_arbpl).
      EXIT.
    ENDLOOP.

    "工艺路线描述
    IF ls_lr_arbpl-zjtlx EQ 'M' OR ls_lr_arbpl-zjtlx EQ 'P'  .

      "相邻工序工作中心一致,当前工序不拼接
      IF ps_plpo_bef-arbpl NE ls_plpo_01-arbpl.

        SELECT SINGLE ktext  FROM crtx INNER JOIN  crhd  ON crtx~objty = crhd~objty AND  crtx~objid = crhd~objid INTO @DATA(lv_crtx) WHERE crhd~arbpl = @ls_plpo_01-arbpl.
        IF sy-subrc EQ 0.

          SPLIT lv_crtx AT '工作中心' INTO DATA(lv_01) DATA(lv_02).

          ls_plpo_01-zjtdl_str = ps_plpo_bef-zjtdl_str && lv_name1+0(1) && lv_01 .
          CLEAR:lv_01.

        ELSE.

          ls_plpo_01-zjtdl_str = ps_plpo_bef-zjtdl_str.

        ENDIF.

      ELSE.

        ls_plpo_01-zjtdl_str = ps_plpo_bef-zjtdl_str.

      ENDIF.

    ELSEIF ls_lr_arbpl-sbzbh EQ '外协'.

      ls_plpo_01-zjtdl_str = ps_plpo_bef-zjtdl_str && ls_lr_arbpl-sbzbh .

      CLEAR:lv_name1.

    ELSE.

      ls_plpo_01-zjtdl_str = ps_plpo_bef-zjtdl_str.

    ENDIF.

    CLEAR:ls_lr_arbpl,lv_crtx.

    "工序工作中心拼串,后续用于与sap已创建工艺路线比较,区分 创建/修改/删除
    READ TABLE gt_plas INTO DATA(ls_plas) WITH KEY plnfl = ls_plpo_01-plnfl vornr = ls_plpo_01-vornr arbpl = ls_plpo_01-arbpl BINARY SEARCH.
    IF sy-subrc EQ 0.
      ls_plpo_01-arbpl_str = |{ ps_plpo_bef-arbpl_str }{ ls_plpo_01-plnfl }{ ls_plpo_01-vornr }{ ls_plpo_01-arbpl }|.
    ELSE.
      ls_plpo_01-arbpl_str = |{ ps_plpo_bef-arbpl_str }|.
    ENDIF.

    CONDENSE ls_plpo_01-arbpl_str NO-GAPS.

    "读取下道工序
    READ TABLE gt_plpo_vornr INTO ls_plpo_vornr INDEX lv_tabix + 1.
    IF sy-subrc EQ 0.

      LOOP AT pt_plpo INTO DATA(ls_plpo_next) WHERE plnfl = ls_plpo_vornr-plnfl AND vornr = ls_plpo_vornr-vornr.
        lv_fzbs = lv_fzbs + 1.
        PERFORM frm_routine_list_set TABLES pt_004 pt_plpo pt_plpo_01 USING lv_fzbs ls_plpo_01-fz  pv_arbpl ls_plpo_next ls_plpo_01.
      ENDLOOP.

    ELSE."最底层标记,方便后续判断为一条工艺路线

      ls_plpo_01-bs = abap_true.

    ENDIF.

    APPEND ls_plpo_01 TO pt_plpo_01.

    IF lv_exit EQ abap_true.
      EXIT.
    ENDIF.

  ENDLOOP.

  CLEAR:lv_exit,lv_tabix.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_COMPARE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_PLANT
*&      --> LS_MATERIAL
*&---------------------------------------------------------------------*
FORM frm_routine_compare  USING ps_plant    TYPE zsplm_005_plant
                                ps_material TYPE zsplm_005_material.

*--历史记录 pk 拼接
  DATA(lt_plpo_all) = gt_plpo_all.
  SORT lt_plpo_all BY plnfl vornr arbpl.

  LOOP AT gt_plas INTO DATA(ls_plas) GROUP BY ( plnnr = ls_plas-plnnr plnal = ls_plas-plnal plnty = ls_plas-plnty )
                                     REFERENCE INTO DATA(lr_01).

    APPEND INITIAL LINE TO gt_plpo_his ASSIGNING FIELD-SYMBOL(<fs_plpo_his>).

    <fs_plpo_his>-plnnr = lr_01->plnnr .
    <fs_plpo_his>-plnal = lr_01->plnal .
    <fs_plpo_his>-plnty = lr_01->plnty .

    LOOP AT GROUP lr_01 INTO DATA(ls_lr_01).

      READ TABLE lt_plpo_all INTO DATA(ls_plpo_all) WITH KEY plnfl = ls_lr_01-plnfl vornr = ls_lr_01-vornr BINARY SEARCH."arbpl = ls_lr_01-arbpl BINARY SEARCH.
      IF sy-subrc EQ 0.
        DATA(lv_arbpl_str) = <fs_plpo_his>-arbpl_str.
        <fs_plpo_his>-arbpl_str = |{ lv_arbpl_str }{ ls_lr_01-plnfl }{ ls_lr_01-vornr }{ ls_lr_01-arbpl }|.
      ENDIF.

    ENDLOOP.

  ENDLOOP.

  SORT gt_plpo_his BY arbpl_str.

  CLEAR:lt_plpo_all,ls_plpo_all.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_routine_split_mode
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_PLANT
*&      --> PT_INPUT_IT_material
*&---------------------------------------------------------------------*
FORM frm_routine_split_mode USING ps_plant    TYPE zsplm_005_plant
                                  ps_material TYPE zsplm_005_material.

*--分类
  DATA(lt_plpo_split) = gt_plpo_all.
  DELETE lt_plpo_split WHERE bs IS INITIAL.

  LOOP AT lt_plpo_split INTO DATA(ls_plpo_split).

    READ TABLE gt_plpo_his INTO gs_plpo_his WITH KEY arbpl_str = ls_plpo_split-arbpl_str.
    IF sy-subrc EQ 0."判断系统是否存在

      DELETE gt_plpo_his INDEX sy-tabix.

      "存在,数据修改
      ls_plpo_split-plnnr     = gs_plpo_his-plnnr.
      ls_plpo_split-plnal     = gs_plpo_his-plnal.
      ls_plpo_split-plnty     = gs_plpo_his-plnty.
      ls_plpo_split-matnr     = ps_material-matnr.
      ls_plpo_split-werks     = ps_plant-werks.
      APPEND ls_plpo_split TO gt_plpo_chg.

    ELSE."不存在,数据创建

      READ TABLE gt_mapl_his INTO gs_mapl_his WITH KEY matnr = ps_material-matnr werks = ps_plant-werks BINARY SEARCH.
      IF sy-subrc EQ 0.
        ls_plpo_split-plnnr     = gs_mapl_his-plnnr.
      ENDIF.

      ls_plpo_split-matnr = ps_material-matnr.
      ls_plpo_split-werks = ps_plant-werks.
      APPEND ls_plpo_split TO gt_plpo_crt.

    ENDIF.

  ENDLOOP.

  "存在 sap 工艺路线多于 拆分规则量,处理删除
  IF gt_plpo_his IS NOT INITIAL.

    LOOP AT gt_plpo_his INTO gs_plpo_his .

      gs_plpo_del-plnnr = gs_plpo_his-plnnr.
      gs_plpo_del-plnal = gs_plpo_his-plnal.
      gs_plpo_del-plnty = gs_plpo_his-plnty.
      gs_plpo_del-matnr = ps_material-matnr.
      gs_plpo_del-werks = ps_plant-werks.
      APPEND gs_plpo_del TO gt_plpo_del.

    ENDLOOP.

  ENDIF.

  CLEAR:lt_plpo_split,ls_plpo_split.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_routine_process
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_PLANT
*&      --> PT_INPUT_IT_material
*&---------------------------------------------------------------------*
FORM frm_routine_process USING ps_plant     TYPE zsplm_005_plant
                               ps_material  TYPE zsplm_005_material
                      CHANGING cs_omaterial TYPE zsplm_005_omaterial.

  DATA ls_omaterial TYPE zsplm_005_omaterial."记录全量pk,用于反写工艺路线层反馈

  SELECT SINGLE * FROM mara INTO gs_mara_his WHERE matnr EQ ps_material-matnr.

  PERFORM frm_routine_crt USING ps_plant ps_material CHANGING cs_omaterial ls_omaterial.

  PERFORM frm_routine_chg USING ps_plant ps_material CHANGING cs_omaterial ls_omaterial.

  PERFORM frm_routine_del USING ps_plant ps_material CHANGING cs_omaterial ls_omaterial.

  READ TABLE ls_omaterial-ot_sap_pk INTO DATA(ls_osappk) WITH KEY code = gc_e.
  IF sy-subrc EQ 0.
    cs_omaterial-code = gc_e.
    cs_omaterial-msg  = ls_osappk-matnr && '/' && ls_osappk-werks && '/' && ls_osappk-plnnr && '/' && ls_osappk-plnal && ':' && ls_osappk-msg.
  ELSE.
    cs_omaterial-code = gc_s.
    cs_omaterial-msg  = '工艺路线维护成功'.
  ENDIF.

  CLEAR:ls_omaterial.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_CRT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_INPUT
*&      <-- PT_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_routine_crt  USING  ps_plant         TYPE zsplm_005_plant
                             ps_material      TYPE zsplm_005_material
                    CHANGING cs_omaterial     TYPE zsplm_005_omaterial
                             cs_omaterial_tmp TYPE zsplm_005_omaterial.

  CHECK gt_plpo_crt IS NOT INITIAL.

  LOOP AT gt_plpo_crt INTO gs_plpo_crt.

    "初始化反馈
    APPEND INITIAL LINE TO cs_omaterial-ot_sap_pk ASSIGNING FIELD-SYMBOL(<fs_osappk>).
    DATA(lv_tabix) = sy-tabix.
    <fs_osappk> = CORRESPONDING #( gs_plpo_crt ).
    <fs_osappk>-zktext = ps_material-ktext.
    <fs_osappk>-matnr  = |{ <fs_osappk>-matnr ALPHA = OUT }|. CONDENSE <fs_osappk>-matnr NO-GAPS.

    IF ps_plant-plnnr IS INITIAL .
      ps_plant-plnnr = gs_plpo_crt-plnnr.
    ENDIF.

    PERFORM frm_routine_refresh.

*--set item
    PERFORM frm_set_routine_itemcrt USING ps_plant ps_material gs_plpo_crt.

*--set head
    PERFORM frm_set_routine_bapicrt USING ps_plant ps_material CHANGING <fs_osappk> gs_plpo_crt.

    IF <fs_osappk>-code EQ gc_s.

      PERFORM frm_set_routine_savedata USING  '' gs_plpo_crt ps_plant ps_material.

    ELSE.

      "记录失败信息
      APPEND <fs_osappk> TO cs_omaterial_tmp-ot_sap_pk.

      "创建失败不返回
      DELETE cs_omaterial-ot_sap_pk INDEX lv_tabix.

    ENDIF.

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_REFRESH
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_routine_refresh .

  REFRESH:gt_plko    ,
          gt_mapl    ,
          gt_plfh    ,
          gt_plfl    ,
          gt_plpo    ,
          gt_segm    ,
          gt_return  .

  CLEAR:  gt_tsk_tab ,
          gs_tsk_tab ,
          gt_seq_tab ,
          gs_seq_tab ,
          gt_opr_tab ,
          gs_opr_tab ,
          gt_plfh_tab,
          gs_plfh_tab.

  CLEAR:  gv_num_gx,
          gv_num_sx,
          gv_numprt.

  CLEAR:  gs_chg_plko   ,
          gs_chg_plkox  .

  REFRESH:gt_chg_mapl[] ,
          gt_chg_maplx[],
          gt_chg_plfh[] ,
          gt_chg_plfhx[],
          gt_chg_plfl[] ,
          gt_chg_plflx[],
          gt_chg_plpo[] ,
          gt_chg_plpox[].

  REFRESH:gt_del_plfh  ,
          gt_del_plfhx ,
          gt_del_plfl  ,
          gt_del_plflx ,
          gt_del_mapl  ,
          gt_del_maplx ,
          gt_del_plpo  ,
          gt_del_plpox .

  CLEAR:gt_plpo_map,
        gs_plpo_map.

  CLEAR:gr_fz.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_set_routine_itemcrt
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&---------------------------------------------------------------------*
FORM frm_set_routine_itemcrt USING  ps_plant     TYPE zsplm_005_plant
                                    ps_material  TYPE zsplm_005_material
                                    ps_plpo_crt  TYPE typ_plpo.

  DATA:lv_tab_lines   TYPE sy-tabix,
       lv_tab_lines1  TYPE sy-tabix,
       lv_vornr_first TYPE plpo-vornr,
       lv_vornr       TYPE plpo-vornr,
       lv_mdgx_flag   TYPE c,
       lv_cx_yqql     TYPE c.

  DATA:lv_psnfh TYPE plfh-psnfh.

  "任务清单组信息
  APPEND INITIAL LINE TO gt_mapl ASSIGNING FIELD-SYMBOL(<fs_mapl>).

  <fs_mapl> = VALUE #( material         = ps_material-matnr
                       plant            = ps_plant-werks
                       task_list_group  = ps_plant-plnnr
                       group_counter    = ps_material-plnal
                       valid_from       = sy-datum
                       valid_to_date    = '99991231'
                      ).

  "任务清单抬头信息
  APPEND INITIAL LINE TO gt_plko ASSIGNING FIELD-SYMBOL(<fs_plko>).

  <fs_plko> = VALUE #( task_list_group       = ps_plant-plnnr    "任务清单组键值
                       group_counter         = ps_material-plnal "组计数器
                       plant                 = ps_plant-werks    "工厂
                       task_list_usage       = '1'               "用途
                       task_list_status      = ps_material-statu "状态
                       task_measure_unit     = gs_mara_his-meins "单位
                       task_measure_unit_iso = gs_mara_his-meins "单位
                       valid_from            = sy-datum"ps_material-datuv "起始有效期
                       valid_to_date         = '99991231'        "截止有效期
                       lot_size_from         = 0                 "批量下限
                       lot_size_to           = 99999999          "批量上限
                       description           = ps_plpo_crt-zjtdl_str"描述
                      ).

  "顺序
  LOOP AT ps_material-it_plfl INTO DATA(ls_sequence).

    APPEND INITIAL LINE TO gt_plfl ASSIGNING FIELD-SYMBOL(<fs_plfl>).

    "补零
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = ls_sequence-plnfl
      IMPORTING
        output = ls_sequence-plnfl.

    <fs_plfl> = VALUE #( task_list_group               = ps_plant-plnnr     "任务清单组键值
                         group_counter                 = ps_material-plnal  "组计数器
                         sequence_no                   = ls_sequence-plnfl  "序列
                         sequence_category             = COND #( WHEN  ls_sequence-plnfl = 0 THEN '0' ELSE '1' )   "顺序类别
                         description                   = ls_sequence-ltxa1  "顺序描述
                         reference_sequence            = COND #( WHEN  ls_sequence-plnfl = 0 THEN ' ' ELSE '0' )   "参照序列
                         branch_operation              = ls_sequence-vornr1 "参照工序开始于
                         return_operation              = COND #( WHEN  ls_sequence-plnfl = 0 THEN ' ' ELSE '9000' )"参照工序到
                         alignment_key_for_scheduling  = '2'                "校准码
                         valid_from                    = sy-datum"ps_material-datuv  "起始有效期
                         valid_to_date                 = '99991231'         "截止有效期
                         lot_sz_min                    = 0
                         lot_sz_max                    = 999999999
                         task_measure_unit             = gs_mara_his-meins
                         task_measure_unit_iso         = gs_mara_his-meins

                        ).

  ENDLOOP.

  CLEAR: lv_tab_lines,lv_cx_yqql,lv_tab_lines1.

  "工序-PLM传输多道,需要按照工序删重
  DATA(lt_plpo_01) = ps_material-it_plpo.
  SORT lt_plpo_01 BY vornr.
  DELETE ADJACENT DUPLICATES FROM lt_plpo_01 COMPARING  vornr.
  "最小工序
  lv_vornr_first = VALUE #( lt_plpo_01[ 1 ]-vornr OPTIONAL ).

  "按照标准工序计算最后一道工序
  DATA(lt_plpo_02) = lt_plpo_01.
  DELETE lt_plpo_02 WHERE plnfl NE '000000'.
  lv_tab_lines = lines( lt_plpo_02 ).
  SORT lt_plpo_02 BY vornr DESCENDING.

  "最大工序
  lv_vornr = VALUE #( lt_plpo_02[ 1 ]-vornr OPTIONAL ).

  PERFORM frm_set_fz USING ps_plpo_crt-fz.

  LOOP AT gt_plpo_all INTO DATA(ls_procedure) WHERE fz IN gr_fz.

    "由于后道工序自动添加放置最后,导致传输原数据与实际数据工序自定义表存储不一致,此处记录,保存时替换
    APPEND INITIAL LINE TO gt_plpo_map ASSIGNING FIELD-SYMBOL(<fs_plpo_map>).
    <fs_plpo_map> = VALUE  #( plnfl     = ls_procedure-plnfl
                              vornr_in  = ls_procedure-vornr
                              vornr_out = ls_procedure-vornr "默认一致
                              ).

    APPEND INITIAL LINE TO gt_plpo ASSIGNING FIELD-SYMBOL(<fs_plpo>).

    <fs_plpo> = VALUE #( task_list_group            = ps_plant-plnnr      "任务清单组键值
                         group_counter              = ps_material-plnal   "组计数器
                         work_cntr                  = ls_procedure-arbpl  "工作中心
                         plant                      = ls_procedure-werks  "工厂
                         activity                   = ls_procedure-vornr  "操作/活动编号
                         control_key                = ls_procedure-steus  "控制码
                         description                = ls_procedure-ltxa1  "工序短文本
                         denominator                = ls_procedure-umren  "用于转换工艺路线和工序单位的分母
                         nominator                  = ls_procedure-bmsch  "用于转换任务清单和工序计量单位的计数器
                         cost_relevant              = abap_true           "与成本核算相关标志
                         base_quantity              = ls_procedure-bmsch  "基本数量
                         operation_measure_unit     = ls_procedure-meinh  "作业的计量单位
                         "operation_measure_unit_iso = ls_procedure-meinh  "作业的计量单位
                         std_value_01               = ls_procedure-vgw01  "标准值
                         std_unit_01                = ls_procedure-vge01  "标准值单位
                         std_value_02               = ls_procedure-vgw02  "标准值
                         std_unit_02                = ls_procedure-vge02  "标准值单位
                         std_value_03               = ls_procedure-vgw03  "标准值
                         std_unit_03                = ls_procedure-vge03  "标准值单位
                         std_value_04               = ls_procedure-vgw04  "标准值
                         std_unit_04                = ls_procedure-vge04  "标准值单位
                         std_value_05               = ls_procedure-vgw05  "标准值
                         std_unit_05                = ls_procedure-vge05  "标准值单位
                         std_value_06               = ls_procedure-vgw06  "标准值
                         std_unit_06                = ls_procedure-vge06  "标准值单位
                         sequence_no                = ls_procedure-plnfl  "序列
                         valid_from                 = sy-datum"ps_material-datuv  "起始有效期
                         valid_to_date              = '99991231'         "截止有效期
                        ).

    "最后一道工序标识
    IF ls_procedure-plnfl = '000000'."末道工序在标准顺序下
      IF ls_procedure-ltxa1 = '擦洗' OR ls_procedure-ltxa1 = '油漆清理'.
        lv_mdgx_flag = abap_true.
        lv_cx_yqql = abap_true.
      ELSE.
        lv_tab_lines1 = lv_tab_lines1 + 1.
        IF lv_tab_lines = lv_tab_lines1 AND lv_cx_yqql NE abap_true.
          lv_mdgx_flag = abap_true.
        ENDIF.
      ENDIF.
    ENDIF.

    "控制码为空时,自动获取
    "IF <fs_plpo>-control_key IS INITIAL .
    PERFORM frm_set_control_key    USING gs_mara_his-mtart     "物料类型
                                         ps_plant-werks        "物权工厂
                                         <fs_plpo>-plant       "工序工厂
                                         lv_mdgx_flag          "末道工序
                                         <fs_plpo>-work_cntr   "工作中心
                                         <fs_plpo>-description "描述
                                CHANGING <fs_plpo>-control_key.
    "ENDIF.

    "成本核算标识
    PERFORM frm_set_cbhsbs USING <fs_plpo>-control_key CHANGING <fs_plpo>-cost_relevant.

    IF ( <fs_plpo>-description CS '擦洗' OR <fs_plpo>-description CS '油漆清理' ) AND ( <fs_plpo>-work_cntr = '3000BZ' OR <fs_plpo>-work_cntr = 'XN30BZ' )
        AND lv_vornr NE ls_procedure-vornr.

      ls_procedure-vornr = lv_vornr + 10.
      CONDENSE  ls_procedure-vornr NO-GAPS.
      PERFORM frm_inzero USING 'CHAR4' CHANGING ls_procedure-vornr.

      <fs_plpo>-activity = ls_procedure-vornr.

      <fs_plpo_map>-vornr_out  = ls_procedure-vornr.

    ENDIF.

*--针对外协进行外部加工字段默认赋值
    IF <fs_plpo>-work_cntr IS INITIAL AND <fs_plpo>-description CS '外协' AND ( <fs_plpo>-control_key = 'ZP03' OR <fs_plpo>-control_key = 'ZP06' ).

      <fs_plpo>-plant              = ps_plant-werks.

      "采购组织
      <fs_plpo>-purch_org          = '1000'.
      "物料组
      <fs_plpo>-matl_group         = 'Z102'.
      "采购组
      <fs_plpo>-purch_group        = '203'.
      "供应商
      <fs_plpo>-vendor_no          = '0000400000'.
      "价格单位
      <fs_plpo>-price_unit         = '1'.
      "成本要素
      <fs_plpo>-cost_elem          = '8004010000'.
      "净价
      <fs_plpo>-info_rec_net_price = '1'.
      "货币
      <fs_plpo>-currency           = 'CNY'.

    ENDIF.

*--活动类型
    SELECT crhd~arbpl,
           crhd~werks,
           crco~objty,
           crco~objid,
           crco~lanum,
           crco~kostl,
           crco~lstar,
           crco~leinh
      FROM crhd
     INNER JOIN crco
        ON crco~objty EQ crhd~objty
       AND crco~objid EQ crhd~objid
      INTO TABLE @DATA(lt_crhd)
     WHERE crhd~arbpl EQ @<fs_plpo>-work_cntr
       AND crhd~werks EQ @<fs_plpo>-plant.

    SORT lt_crhd BY lanum.

    LOOP AT lt_crhd INTO DATA(ls_crhd) .

      DATA(lv_n2) = CONV numc2( sy-tabix ).

      ASSIGN COMPONENT 'ACTTYPE_' && lv_n2 OF STRUCTURE <fs_plpo> TO FIELD-SYMBOL(<fs_field>).
      IF <fs_field> IS ASSIGNED.
        <fs_field> = ls_crhd-lstar.
      ENDIF.

      ASSIGN COMPONENT 'STD_UNIT_' && lv_n2 OF STRUCTURE <fs_plpo> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        <fs_field> = ls_crhd-leinh.
      ENDIF.

    ENDLOOP.

    CLEAR:lt_crhd,lv_psnfh.

    "PRT
    LOOP AT ls_procedure-it_prt INTO DATA(ls_prt) WHERE zlzjlx EQ '工装' OR zlzjlx EQ '模具' OR zlzjlx EQ '组合刀具'.

      "生产资源/工具项目号
      lv_psnfh = lv_psnfh + 10.

      APPEND INITIAL LINE TO gt_plfh ASSIGNING FIELD-SYMBOL(<fs_plfh>).

      <fs_plfh> = VALUE #( task_list_group                 = ps_plant-plnnr     "任务清单组键值
                           group_counter                   = ps_material-plnal  "组计数器
                           activity                        = ls_procedure-vornr "操作/活动编号
                           sequence_no                     = ls_procedure-plnfl "序列
                           prt_category                    = 'M'                "生产资源/工具类别
                           material                        = ls_prt-fhmnr       "物料编号(18 个字符)
                           std_value_for_prt_qty           = ls_prt-mgvgw       "数量
                           prt_measure_unit                = ls_prt-mgeinh      "单位
                           prt_number                      = ls_prt-fhmnr       "生产资源/工具编号
                           item_no_of_production_resource  = lv_psnfh           "生产资源/工具项目号
                           ctrl_key                        = ls_prt-steuf       "生产资源工具控制参数
                           prt_plant                       = '9000'             "工厂中的生产资源/工具
                           valid_from                      = sy-datum"ps_material-datuv  "起始有效期
                           valid_to_date                   = '99991231'         "截止有效期
                          ).

    ENDLOOP.

    CLEAR:lv_mdgx_flag.

  ENDLOOP.

  "第一道ZP02工序,或没有ZP02但有ZP05的工序 仓库字段赋值
  READ TABLE gt_plpo ASSIGNING FIELD-SYMBOL(<gs_opr>) WITH  KEY control_key = 'ZP02'.
  IF sy-subrc EQ 0.

    PERFORM frm_set_plpo_field USING ps_plant-werks CHANGING <gs_opr>-userfields_keyword_id
                                                             <gs_opr>-userfield_ch20_00
                                                             <gs_opr>-userfield_ch20_01.
  ELSE.
    READ TABLE gt_plpo ASSIGNING <gs_opr> WITH  KEY control_key = 'ZP05'.
    IF sy-subrc EQ 0.

      PERFORM frm_set_plpo_field USING ps_plant-werks CHANGING <gs_opr>-userfields_keyword_id
                                                               <gs_opr>-userfield_ch20_00
                                                               <gs_opr>-userfield_ch20_01.
    ENDIF.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_CONTROL_KEY
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_MARA_MTART
*&      --> PS_PLANT_WERKS
*&      --> <FS_PLPO>_PLANT
*&      --> LV_MDGX_FLAG
*&      --> LOOP
*&      --> AT
*&      --> LS_PROCEDURE_IT_PRT
*&      --> INTO
*&      --> DATA(LS_PRT)
*&      --> WHERE
*&      --> ZLZJLX
*&      --> EQ
*&      --> P_
*&      --> OR
*&      --> ZLZJLX
*&      --> EQ
*&      --> P_
*&--------------------------------------------  -------------------------*
FORM frm_set_control_key  USING pv_mtart        "物料类型
                                pv_werks        "物权工厂
                                pv_plant        "工序工厂
                                pv_mdgx_flag    "末道工序
                                pv_work_cntr    "工作中心
                                pv_description  "描述
                       CHANGING cv_control_key TYPE bapi1012_opr_c-control_key.

  IF pv_werks EQ pv_plant."工作中心在物权工厂下

    IF pv_mdgx_flag EQ abap_true."末道工序
      cv_control_key = 'ZP04'."完全入库
    ELSE.
      cv_control_key = 'ZP01'."工序报工
    ENDIF.

  ELSE."工作中心不在物权工厂下

    IF pv_mdgx_flag EQ abap_true."末道工序
      cv_control_key = 'ZP05'."公司内工序委外
    ELSE.
      cv_control_key = 'ZP02'."公司内工序委外(自动收货)
    ENDIF.

  ENDIF.

  IF pv_work_cntr IS INITIAL AND pv_description CS '外协'.

    IF pv_mdgx_flag EQ abap_true."非末道工序
      cv_control_key = 'ZP06'."公司外工序委外(自动收货)
    ELSE.
      cv_control_key = 'ZP03'."公司外工序委外
    ENDIF.

  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_CBHSBS
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> <FS_PLPO>_CONTROL_KEY
*&      <-- <FS_PLPO>_COST_RELEVANT
*&---------------------------------------------------------------------*
FORM frm_set_cbhsbs    USING pv_control_key   TYPE bapi1012_opr_c-control_key
                    CHANGING cv_cost_relevant TYPE bapi1012_opr_c-cost_relevant.

  CASE gs_mara_his-mtart.
    WHEN 'LD01' OR 'LD03' .
      cv_cost_relevant = abap_true.
    WHEN 'LD20' OR 'LD21' .

      CASE pv_control_key.
        WHEN 'ZP02'  OR 'ZP05'  OR 'ZP03'  OR 'ZP06'.
          cv_cost_relevant = abap_true.
        WHEN 'ZP01'  OR 'ZP04'  .
          cv_cost_relevant = space.
        WHEN OTHERS.
      ENDCASE.
    WHEN OTHERS.
  ENDCASE.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_PLPO_FIELD
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      <-- <GS_OPR>
*&---------------------------------------------------------------------*
FORM frm_set_plpo_field     USING pv_werks
                         CHANGING cv_keyword_id   TYPE bapi1012_opr_c-userfields_keyword_id
                                  cv_ch20_00      TYPE bapi1012_opr_c-userfield_ch20_00
                                  cv_ch20_01      TYPE bapi1012_opr_c-userfield_ch20_01
                                  .

  SELECT SINGLE slwid
                usr00
                usr01
    FROM zplm_t_012
    INTO ( cv_keyword_id,cv_ch20_00, cv_ch20_01 )
   WHERE werks EQ pv_werks.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_ROUTINE_BAPICRT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&      <-- CS_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_set_routine_bapicrt    USING ps_plant     TYPE zsplm_005_plant
                                      ps_material  TYPE zsplm_005_material
                             CHANGING cs_osappk    TYPE zsplm_005_osappk
                                      cs_plpo_crt  TYPE typ_plpo.

  CLEAR:gt_return,gs_return.

  PERFORM frm_set_routine_bapi_chk USING ps_material.

  IF gt_return[] IS NOT INITIAL.

  ELSE.

    CALL FUNCTION 'BAPI_ROUTING_CREATE'
      IMPORTING
        group                  = gv_group
        groupcounter           = gv_groupcounter
      TABLES
        task                   = gt_plko
        materialtaskallocation = gt_mapl
        productionresource     = gt_plfh
        sequence               = gt_plfl
        operation              = gt_plpo
        task_segment           = gt_segm
        return                 = gt_return.

  ENDIF.

  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.

    CLEAR:gv_group,gv_groupcounter.

  ENDLOOP.

  "多条工艺路线下次使用同一组
  ps_plant-plnnr = gv_group.

  cs_plpo_crt-plnnr = gv_group.
  cs_plpo_crt-plnal = gv_groupcounter.

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

  zcl_common=>bapi_commit( gs_return-type ).

  cs_osappk =  VALUE #( BASE cs_osappk
                        code  = gs_return-type
                        msg   = COND #( WHEN gs_return-message+1 IS INITIAL THEN '工艺路线创建成功' ELSE gs_return-message )
                        plnnr = gv_group
                        plnal = gv_groupcounter
                       ) .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_ROUTINE_BAPI_CHK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_set_routine_bapi_chk USING ps_material  TYPE zsplm_005_material.

  "创建检查
  LOOP AT gt_plpo INTO DATA(ls_plpo).

    CLEAR:gs_chkim,gs_chkex.
    gs_chkim = VALUE #( matnr   = ps_material-matnr
                        loekz   = ''
                        steus   = ls_plpo-control_key
                        arbpl   = ls_plpo-work_cntr
                        werks   = ls_plpo-plant
                        ckselkz = ls_plpo-cost_relevant
                        ltxa1   = ls_plpo-description
                      ).

    CALL FUNCTION 'ZFM_ROUTING_CHECK'
      EXPORTING
        is_plpo = gs_chkim
      IMPORTING
        ls_ret  = gs_chkex.

    IF gs_chkex IS NOT INITIAL.
      APPEND gs_chkex TO gt_return.
    ENDIF.

  ENDLOOP.

  "修改检查
  LOOP AT gt_chg_plpo INTO DATA(ls_chg_plpo) WHERE maintain_mode NE 'D'.

    CLEAR:gs_chkim,gs_chkex.
    gs_chkim = VALUE #( matnr   = ps_material-matnr
                        loekz   = ''
                        steus   = ls_chg_plpo-control_key
                        arbpl   = ls_chg_plpo-work_cntr
                        werks   = ls_chg_plpo-plant
                        ckselkz = ls_chg_plpo-cost_relevant
                        ltxa1   = ls_chg_plpo-description
                      ).

    CALL FUNCTION 'ZFM_ROUTING_CHECK'
      EXPORTING
        is_plpo = gs_chkim
      IMPORTING
        ls_ret  = gs_chkex.

    IF gs_chkex IS NOT INITIAL.
      APPEND gs_chkex TO gt_return.
    ENDIF.

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_ROUTINE_PROCEDURE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&---------------------------------------------------------------------*
FORM frm_set_routine_savedata    USING pv_del      TYPE c
                                       ps_plpo     TYPE typ_plpo
                                       ps_plant    TYPE zsplm_005_plant
                                       ps_material TYPE zsplm_005_material.

  DATA:lt_009 TYPE STANDARD TABLE OF zplm_t_009,
       lt_010 TYPE STANDARD TABLE OF zplm_t_010,
       lt_011 TYPE STANDARD TABLE OF zplm_t_011 WITH HEADER LINE.

  SORT gt_plpo_map BY plnfl vornr_in.

  MODIFY zplm_t_014 FROM @( VALUE #( matnr   = ps_plpo-matnr
                                     werks   = ps_plpo-werks
                                     plnty   = 'N'
                                     plnnr   = ps_plpo-plnnr
                                     plnal   = ps_plpo-plnal
                                     ktext   = ps_material-ktext
                                     zgylxbb = ps_material-zgylxbb
                                     zdel    = pv_del
                                     zdate   = sy-datum
                                     ztime   = sy-uzeit
                                    )
                           ).


  "删除旧数据
  DELETE FROM zplm_t_010 WHERE plnnr = ps_plpo-plnnr
                           AND plnal = ps_plpo-plnal
                           AND plnty = 'N'
                           AND werks = ps_plant-werks
                           AND matnr = ps_material-matnr.

  DELETE FROM zplm_t_009 WHERE plnnr = ps_plpo-plnnr
                           AND plnal = ps_plpo-plnal
                           AND plnty = 'N'
                           AND werks = ps_plant-werks
                           AND matnr = ps_material-matnr.

  IF pv_del EQ abap_true."删除

    DELETE FROM zplm_t_011 WHERE plnnr = ps_plpo-plnnr
                             AND plnal = ps_plpo-plnal
                             AND plnty = 'N'
                             AND werks = ps_plant-werks
                             AND matnr = ps_plpo-matnr.

  ELSE."创建/修改



*--PLM->SAP 工艺路线-设备组存储表

    lt_009 = CORRESPONDING #( ps_material-it_plpo ).

    "调整vornr保持一致
    LOOP AT gt_plpo_map INTO gs_plpo_map.
      MODIFY lt_009 FROM VALUE #( vornr = gs_plpo_map-vornr_out ) TRANSPORTING vornr WHERE plnfl = gs_plpo_map-plnfl AND vornr = gs_plpo_map-vornr_in.
    ENDLOOP.

    MODIFY lt_009 FROM VALUE #( plnnr   = ps_plpo-plnnr
                                plnal   = ps_plpo-plnal
                                plnty   = 'N'
                                ktext   = ps_material-ktext
                                werks   = ps_plant-werks
                                matnr   = ps_material-matnr
                                zgylxbb = ps_material-zgylxbb
                              )
                  TRANSPORTING plnnr plnal plnty werks matnr ktext zgylxbb
                  WHERE plnnr IS INITIAL.

    IF lt_009[] IS NOT INITIAL .
      MODIFY zplm_t_009 FROM TABLE lt_009.
      COMMIT WORK AND WAIT .
    ENDIF.

*--PLM->SAP 工艺路线PRT数据储存表

    LOOP AT ps_material-it_plpo INTO DATA(ls_procedure).

      "调整vornr保持一致
      READ TABLE gt_plpo_map INTO gs_plpo_map WITH KEY plnfl = ls_procedure-plnfl vornr_in = ls_procedure-vornr BINARY SEARCH.
      IF sy-subrc EQ 0 .
        ls_procedure-vornr = gs_plpo_map-vornr_out.
      ENDIF.

      "PRT
      LOOP AT ls_procedure-it_prt INTO DATA(ls_prt) .

        APPEND INITIAL LINE TO lt_010 ASSIGNING FIELD-SYMBOL(<fs_010>).

        <fs_010> = CORRESPONDING #( ls_prt ).

        IF ls_prt-zlzjlx EQ '工装' OR ls_prt-zlzjlx EQ '模具' OR ls_prt-zlzjlx EQ '组合刀具' .

          SELECT SINGLE mtart FROM mara INTO @DATA(lv_mtart) WHERE matnr EQ @ls_prt-fhmnr.

          IF lv_mtart EQ 'LD21'.
            <fs_010>-zwdlx = '工装'.
          ELSEIF lv_mtart EQ 'LD18'.
            <fs_010>-zwdlx = '组合刀具'.
          ENDIF.

          CLEAR:lv_mtart.
        ENDIF.

        <fs_010> = VALUE #( BASE <fs_010>
                            plnnr   = ps_plpo-plnnr         "任务清单组键值
                            plnal   = ps_plpo-plnal         "组计数器
                            plnty   = 'N'                   "任务清单类型
                            werks   = ps_plant-werks        "工厂
                            matnr   = ps_material-matnr     "物料编号
                            plnfl   = ls_procedure-plnfl    "序列
                            vornr   = ls_procedure-vornr    "工序
                            zdevgrp = ls_procedure-zdevgrp  "设备组编号
                            ktext   = ps_material-ktext     "工艺路线ID
                            zgylxbb = ps_material-zgylxbb   "工艺路线版本
                            zgxid   = ls_procedure-zgxid    "工序ID
                            zgxbb   = ls_procedure-zgxbb    "工序版本
                            ).

        <fs_010>-plnfl = |{ <fs_010>-plnfl ALPHA = IN } |.
        <fs_010>-vornr = |{ <fs_010>-vornr ALPHA = IN } |.

      ENDLOOP.

    ENDLOOP.

    IF lt_010 IS NOT INITIAL.
      MODIFY zplm_t_010 FROM TABLE lt_010.
      COMMIT WORK AND WAIT .
    ENDIF.

*--PLM->SAP 工艺路线版本数据储存表

    IF sy-subrc EQ 0.

      lt_011 = VALUE #( BASE CORRESPONDING #( ps_material )
                        plnnr      = ps_plpo-plnnr        "任务清单组键值
                        plnal      = ps_plpo-plnal        "组计数器
                        plnty      = 'N'                  "任务清单类型
                        werks      = ps_plant-werks       "工厂
                        zversion   = VALUE #( ps_material-it_vers[ 1 ]-zverson OPTIONAL )    "物料零件版本
                        materev    = VALUE #( ps_material-it_vers[ 1 ]-materev OPTIONAL )    "物料版本(版次)
                        zjtzbc     = VALUE #( ps_material-it_vers[ 1 ]-zjtzbc  OPTIONAL )    "图纸版次
                        zenable    = abap_true "启用
                        ).
      IF lt_011 IS NOT INITIAL.

        "其他版本更新为非启用状态
        UPDATE zplm_t_011 SET zenable = space
                        WHERE zgylxbb <> lt_011-zgylxbb
                          AND ktext   =  lt_011-ktext.

        MODIFY zplm_t_011 FROM lt_011.

        COMMIT WORK AND WAIT .
      ENDIF.
    ENDIF.

  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_CHG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_INPUT
*&      <-- PT_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_routine_chg  USING  ps_plant     TYPE zsplm_005_plant
                             ps_material  TYPE zsplm_005_material
                    CHANGING cs_omaterial TYPE zsplm_005_omaterial
                             cs_omaterial_tmp TYPE zsplm_005_omaterial.

  CHECK gt_plpo_chg IS NOT INITIAL.

  LOOP AT gt_plpo_chg INTO gs_plpo_chg.

    "初始化反馈
    APPEND INITIAL LINE TO cs_omaterial-ot_sap_pk ASSIGNING FIELD-SYMBOL(<fs_osappk>).
    <fs_osappk> = CORRESPONDING #( gs_plpo_crt ).
    <fs_osappk>-zktext = ps_material-ktext.

    PERFORM frm_routine_refresh.

*--get item
    PERFORM frm_get_routine_item USING ps_plant ps_material gs_plpo_chg.

*--set item
    PERFORM frm_set_routine_itemchg USING ps_plant ps_material gs_plpo_chg.

    PERFORM frm_set_routine_bapichg USING ps_plant ps_material gs_plpo_chg CHANGING <fs_osappk>.

    CONDENSE <fs_osappk>-matnr NO-GAPS.

    IF <fs_osappk>-code EQ gc_s.

      PERFORM frm_set_routine_savedata USING '' gs_plpo_chg ps_plant ps_material.

    ELSE.

      "记录失败反馈
      APPEND <fs_osappk> TO cs_omaterial_tmp-ot_sap_pk.

    ENDIF.

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_ROUTINE_ITEMCHG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_PLANT
*&      --> PS_MATERIAL
*&---------------------------------------------------------------------*
FORM frm_set_routine_itemchg  USING  ps_plant     TYPE zsplm_005_plant
                                     ps_material  TYPE zsplm_005_material
                                     ps_plpo_chg  TYPE typ_plpo.

  DATA:lv_tab_lines     TYPE sy-tabix,
       lv_tab_lines1    TYPE sy-tabix,
       lv_vornr_first   TYPE plpo-vornr,
       lv_vornr         TYPE plpo-vornr,
       lv_vornr_prt     TYPE numc4,
       lv_mdgx_flag     TYPE c,
       lv_cx_yqql       TYPE c,
       lv_num           TYPE numc10,
       lv_num1          TYPE numc10,
       lv_maintain_mode TYPE c.


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

  "任务清单组信息
  gs_chg_plko = VALUE #( plant             = ps_plant-werks    "工厂
                         task_list_usage   = ps_material-verwe "用途
                         task_list_status  = ps_material-statu"状态
                         lot_size_from     = 0                 "批量下限
                         lot_size_to       = 99999999          "批量上限
                         description       = ps_plpo_chg-zjtdl_str "工艺描述
                         task_measure_unit = ls_mara-meins     "单位
                        ).

  gs_chg_plkox = VALUE #( plant             = abap_true "工厂
                          task_list_usage   = abap_true "用途
                          task_list_status  = abap_true "状态
                          lot_size_from     = abap_true "批量下限
                          lot_size_to       = abap_true "批量上限
                          description       = abap_true "工艺描述
                          task_measure_unit = abap_true "单位
                         ).

  "APPEND INITIAL LINE TO gt_chg_mapl ASSIGNING FIELD-SYMBOL(<fs_mapl>).
  "<fs_mapl> = VALUE #( maintain_mode    = 'M'
  "                     flag_bar_pointer = lv_num
  "                     material         = ps_material-matnr
  "                     plant            = ps_plant-werks    "工厂
  "
  "                    ).
  "

  CLEAR lv_num.

  "顺序
  LOOP AT ps_material-it_plfl INTO DATA(ls_sequence).

    gv_num_sx = gv_num_sx + 1.

    "补零
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = ls_sequence-plnfl
      IMPORTING
        output = ls_sequence-plnfl.

    READ TABLE gt_seq_tab TRANSPORTING NO FIELDS WITH KEY plnfl = ls_sequence-plnfl BINARY SEARCH.
    IF sy-subrc EQ 0.
      lv_maintain_mode = 'M'.
    ELSE.
      lv_maintain_mode = 'C'.
    ENDIF.

    APPEND INITIAL LINE TO gt_chg_plfl ASSIGNING FIELD-SYMBOL(<fs_chg_plfl>).

    <fs_chg_plfl> = VALUE #( maintain_mode                 = lv_maintain_mode
                             flag_bar_pointer              = gv_num_sx
                             sequence_no                   = ls_sequence-plnfl  "序列
                             sequence_category             = COND #( WHEN  ls_sequence-plnfl = 0 THEN '0' ELSE '1' )   "顺序类别
                             description                   = ls_sequence-ltxa1  "顺序描述
                             reference_sequence            = COND #( WHEN  ls_sequence-plnfl = 0 THEN ' ' ELSE '0' )   "参照序列
                             branch_operation              = ls_sequence-vornr1 "参照工序开始于
                             return_operation              = COND #( WHEN  ls_sequence-plnfl = 0 THEN ' ' ELSE '9000' )"参照工序到
                             alignment_key_for_scheduling  = '2'                "校准码
                             task_measure_unit             = ls_mara-meins      "单位
                             "task_measure_unit_iso         = ls_mara-meins      "单位
                             lot_sz_min                    = 0                  "最小批量
                             lot_sz_max                    = 99999999           "最大批量
                            ).

    APPEND INITIAL LINE TO gt_chg_plflx ASSIGNING FIELD-SYMBOL(<fs_chg_plflx>).

    <fs_chg_plflx> = VALUE #( description                   = abap_true "顺序描述
                              lot_sz_min                    = abap_true "最小批量
                              lot_sz_max                    = abap_true "最大批量
                              task_measure_unit             = abap_true "单位
                              "task_measure_unit_iso         = abap_true "单位
                              alignment_key_for_scheduling  = abap_true "校准码
                              branch_operation              = abap_true "参照工序开始于
                              return_operation              = abap_true "参照工序到
                             ).

  ENDLOOP.


  CLEAR:lv_tab_lines,lv_num,lv_cx_yqql,lv_tab_lines1..

  "工序-PLM传输多道,需要按照工序删重
  DATA(lt_plpo_01) = ps_material-it_plpo.
  SORT lt_plpo_01 BY vornr.
  DELETE ADJACENT DUPLICATES FROM lt_plpo_01 COMPARING  vornr.

  "按照标准工序计算最后一道工序
  DATA(lt_plpo_02) = lt_plpo_01.
  DELETE lt_plpo_02 WHERE plnfl NE '000000'.
  lv_tab_lines = lines( lt_plpo_02 ).
  SORT lt_plpo_02 BY vornr DESCENDING.

  "最大工序
  lv_vornr = VALUE #( lt_plpo_02[ 1 ]-vornr OPTIONAL ).

  PERFORM frm_set_fz USING ps_plpo_chg-fz.

  LOOP AT gt_plpo_all INTO DATA(ls_plpo_01) WHERE fz IN gr_fz.

    gv_num_gx = gv_num_gx + 1.

    "由于后道工序自动添加放置最后,导致传输元数据与实际数据工序自定义表存储不一致,此处记录,保存时替换
    APPEND INITIAL LINE TO gt_plpo_map ASSIGNING FIELD-SYMBOL(<fs_plpo_map>).
    <fs_plpo_map> = VALUE  #( plnfl     = ls_plpo_01-plnfl
                              vornr_in  = ls_plpo_01-vornr
                              vornr_out = ls_plpo_01-vornr "默认一致
                              ).


    APPEND INITIAL LINE TO gt_chg_plpo ASSIGNING FIELD-SYMBOL(<fs_chg_plpo>).

    <fs_chg_plpo> = VALUE #( "maintain_mode              = lv_maintain_mode   "维护任务清单:模式(C:创建)
                             sequence_no                = ls_plpo_01-plnfl "序列
                             flag_bar_pointer           = gv_num_gx
                             activity                   = ls_plpo_01-vornr  "操作/活动编号
                             activity_old               = ls_plpo_01-vornr  "工序编号
                             control_key                = ls_plpo_01-steus  "控制码
                             description                = ls_plpo_01-ltxa1  "工序短文本
                             denominator                = ls_plpo_01-umren  "用于转换工艺路线和工序单位的分母
                             nominator                  = ls_plpo_01-bmsch  "用于转换任务清单和工序计量单位的计数器
                             cost_relevant              = abap_true           "与成本核算相关标志
                             base_quantity              = ls_plpo_01-bmsch  "基本数量
                             operation_measure_unit     = ls_plpo_01-meinh  "作业的计量单位
                             std_value_01               = ls_plpo_01-vgw01  "标准值
                             std_unit_01                = ls_plpo_01-vge01  "标准值单位
                             std_value_02               = ls_plpo_01-vgw02  "标准值
                             std_unit_02                = ls_plpo_01-vge02  "标准值单位
                             std_value_03               = ls_plpo_01-vgw03  "标准值
                             std_unit_03                = ls_plpo_01-vge03  "标准值单位
                             std_value_04               = ls_plpo_01-vgw04  "标准值
                             std_unit_04                = ls_plpo_01-vge04  "标准值单位
                             std_value_05               = ls_plpo_01-vgw05  "标准值
                             std_unit_05                = ls_plpo_01-vge05  "标准值单位
                             std_value_06               = ls_plpo_01-vgw06  "标准值
                             std_unit_06                = ls_plpo_01-vge06  "标准值单位
                            ).


    "物权工厂
    SELECT SINGLE werks FROM crhd INTO @DATA(lv_werks) WHERE arbpl EQ @ls_plpo_01-arbpl.

    "工作中心/工厂 处理逻辑
    IF gv_lines_plant > 1."

      IF gs_plant IS NOT INITIAL.

        "物权工厂和当前工厂一致
        IF gs_plant-werks EQ ps_plant-werks.

          <fs_chg_plpo>-work_cntr = ls_plpo_01-arbpl.
          <fs_chg_plpo>-plant     = lv_werks.

        ELSE.

          "非物权工厂工作中心/工厂
          SELECT SINGLE *
            FROM zppt060
            INTO @DATA(ls_t060)
           WHERE arbpl  EQ @ls_plpo_01-arbpl
             AND werks  EQ @gs_plant-werks
             AND nwerks EQ @ps_plant-werks.

          IF sy-subrc EQ 0.

            SELECT SINGLE werks FROM crhd INTO @DATA(lv_werks1) WHERE arbpl EQ @ls_t060-narbpl.

            <fs_chg_plpo>-work_cntr = ls_t060-narbpl.
            <fs_chg_plpo>-plant     = lv_werks1.

          ENDIF.

        ENDIF.

      ELSE."未输入物权工厂标识


      ENDIF.

    ELSE."一个物料对应一个工厂,那么工作中心按照传入的赋值

      <fs_chg_plpo>-work_cntr = ls_plpo_01-arbpl.
      <fs_chg_plpo>-plant     = lv_werks.

    ENDIF.

    APPEND INITIAL LINE TO gt_chg_plpox ASSIGNING FIELD-SYMBOL(<fs_chg_plpox>).

    <fs_chg_plpox> = VALUE #( activity                   = abap_true "操作/活动编号
                              control_key                = abap_true "控制码
                              work_cntr                  = COND #( WHEN <fs_chg_plpo>-work_cntr IS INITIAL THEN space ELSE  abap_true ) "工作中心
                              plant                      = COND #( WHEN <fs_chg_plpo>-plant     IS INITIAL THEN space ELSE  abap_true ) "工作中心工厂
                              description                = abap_true "工序短文本
                              denominator                = abap_true "用于转换工艺路线和工序单位的分母
                              nominator                  = abap_true "用于转换任务清单和工序计量单位的计数器
                              cost_relevant              = abap_true "与成本核算相关标志
                              base_quantity              = abap_true "基本数量
                              operation_measure_unit     = abap_true "作业的计量单位
                              std_value_01               = abap_true "标准值
                              std_unit_01                = abap_true "标准值单位
                              std_value_02               = abap_true "标准值
                              std_unit_02                = abap_true "标准值单位
                              std_value_03               = abap_true "标准值
                              std_unit_03                = abap_true "标准值单位
                              std_value_04               = abap_true "标准值
                              std_unit_04                = abap_true "标准值单位
                              std_value_05               = abap_true "标准值
                              std_unit_05                = abap_true "标准值单位
                              std_value_06               = abap_true "标准值
                              std_unit_06                = abap_true "标准值单位
                             ).


    "最后一道工序标识
    IF ls_plpo_01-plnfl = '000000'."末道工序在标准顺序下
      IF ls_plpo_01-ltxa1 = '擦洗' OR ls_plpo_01-ltxa1 = '油漆清理'.
        lv_mdgx_flag = abap_true.
        lv_cx_yqql = abap_true.
      ELSE.
        lv_tab_lines1 = lv_tab_lines1 + 1.
        IF lv_tab_lines = lv_tab_lines1 AND lv_cx_yqql NE abap_true.
          lv_mdgx_flag = abap_true.
        ENDIF.
      ENDIF.
    ENDIF.

    "控制码为空时,自动获取
    "IF <fs_chg_plpo>-control_key IS INITIAL .
    PERFORM frm_set_control_key    USING ls_mara-mtart   "物料类型
                                         ps_plant-werks  "物权工厂
                                         <fs_chg_plpo>-plant "工序工厂
                                         lv_mdgx_flag        "末道工序
                                         <fs_chg_plpo>-work_cntr    "工作中心
                                         <fs_chg_plpo>-description  "描述
                                CHANGING <fs_chg_plpo>-control_key.
    "ENDIF.

    "成本核算标识
    PERFORM frm_set_cbhsbs USING <fs_chg_plpo>-control_key CHANGING <fs_chg_plpo>-cost_relevant.

    IF ( <fs_chg_plpo>-description CS '擦洗' OR <fs_chg_plpo>-description CS '油漆清理' ) AND ( <fs_chg_plpo>-work_cntr = '3000BZ' OR <fs_chg_plpo>-work_cntr = 'XN30BZ' )
        AND lv_vornr NE ls_plpo_01-vornr.

      ls_plpo_01-vornr = lv_vornr + 10.
      CONDENSE  ls_plpo_01-vornr NO-GAPS.
      PERFORM frm_inzero USING 'CHAR4' CHANGING ls_plpo_01-vornr.

      <fs_chg_plpo>-activity      = ls_plpo_01-vornr.
      <fs_chg_plpo>-activity_old  = ls_plpo_01-vornr.

      <fs_plpo_map>-vornr_out = ls_plpo_01-vornr.

    ENDIF.

    CLEAR:gs_opr_tab.

    READ TABLE gt_opr_tab INTO gs_opr_tab  WITH KEY plnfl = ls_plpo_01-plnfl vornr = ls_plpo_01-vornr BINARY SEARCH.
    IF sy-subrc EQ 0.
      <fs_chg_plpo>-maintain_mode = 'M'.
    ELSE.
      <fs_chg_plpo>-maintain_mode = 'C'.

*--针对外协进行外部加工字段默认赋值   <fs_chg_plpo>-work_cntr IS INITIAL AND
      IF  <fs_chg_plpo>-description CS '外协' AND ( <fs_chg_plpo>-control_key = 'ZP03' OR <fs_chg_plpo>-control_key = 'ZP06' ).

        <fs_chg_plpo>-plant = ps_plant-werks.

        "采购组织
        <fs_chg_plpo>-purch_org          = '1000'.
        "物料组
        <fs_chg_plpo>-matl_group         = 'Z102'.
        "采购组
        <fs_chg_plpo>-purch_group        = '203'.
        "供应商
        <fs_chg_plpo>-vendor_no          = '0000400000'.
        "价格单位
        <fs_chg_plpo>-price_unit         = '1'.
        "成本要素
        <fs_chg_plpo>-cost_elem          = '8004010000'.
        "净价
        <fs_chg_plpo>-info_rec_net_price = '1'.
        "货币
        <fs_chg_plpo>-currency           = 'CNY'.

        "采购组织
        <fs_chg_plpox>-purch_org          = abap_true.
        "物料组
        <fs_chg_plpox>-matl_group         = abap_true.
        "采购组
        <fs_chg_plpox>-purch_group        = abap_true.
        "供应商
        <fs_chg_plpox>-vendor_no          = abap_true.
        "价格单位
        <fs_chg_plpox>-price_unit         = abap_true.
        "成本要素
        <fs_chg_plpox>-cost_elem          = abap_true.
        "净价
        <fs_chg_plpox>-info_rec_net_price = abap_true.
        "货币
        <fs_chg_plpox>-currency           = abap_true.

      ENDIF.

    ENDIF.




*--活动类型
    SELECT crhd~arbpl,
           crhd~werks,
           crco~objty,
           crco~objid,
           crco~lanum,
           crco~kostl,
           crco~lstar,
           crco~leinh
      FROM crhd
     INNER JOIN crco
        ON crco~objty EQ crhd~objty
       AND crco~objid EQ crhd~objid
      INTO TABLE @DATA(lt_crhd)
     WHERE crhd~arbpl EQ @<fs_chg_plpo>-work_cntr
       AND crhd~werks EQ @<fs_chg_plpo>-plant.

    SORT lt_crhd BY lanum.

    LOOP AT lt_crhd INTO DATA(ls_crhd) .

      DATA(lv_n2) = CONV numc2( sy-tabix ).

      ASSIGN COMPONENT 'ACTTYPE_' && lv_n2 OF STRUCTURE <fs_chg_plpo> TO FIELD-SYMBOL(<fs_field>).
      IF <fs_field> IS ASSIGNED.
        <fs_field> = ls_crhd-lstar.
      ENDIF.

      ASSIGN COMPONENT 'ACTTYPE_' && lv_n2 OF STRUCTURE <fs_chg_plpox> TO FIELD-SYMBOL(<fs_fieldx>).
      IF <fs_field> IS ASSIGNED.
        <fs_fieldx> = abap_true.
      ENDIF.

      ASSIGN COMPONENT 'STD_UNIT_' && lv_n2 OF STRUCTURE <fs_chg_plpo> TO <fs_field>.
      IF <fs_field> IS ASSIGNED.
        <fs_field> = ls_crhd-leinh.
      ENDIF.

      ASSIGN COMPONENT 'STD_UNIT_' && lv_n2 OF STRUCTURE <fs_chg_plpox> TO <fs_fieldx>.
      IF <fs_field> IS ASSIGNED.
        <fs_fieldx> = abap_true.
      ENDIF.

    ENDLOOP.

    CLEAR:lt_crhd.

    "删除PRT-现有生产资源行全部删除-再全部写入,否则对应行物料修改不了
    LOOP AT gt_plfh_tab INTO  gs_plfh_tab WHERE plnkn = gs_opr_tab-plnkn .

      lv_num1 = lv_num1 + 1.

      APPEND INITIAL LINE TO gt_chg_plfh ASSIGNING FIELD-SYMBOL(<fs_del_plfh>).

      <fs_del_plfh> = VALUE #( maintain_mode                 = 'D'               "维护任务清单:模式(C:创建)
                               flag_bar_pointer              = lv_num1
                               activity                      = gs_opr_tab-vornr  "操作/活动编号
                               sequence_no                   = gs_plfh_tab-plnfl "序列
                               item_no_of_prod_resource      = gs_plfh_tab-psnfh "生产资源/工具项目号
                               item_no_of_prod_resource_old  = gs_plfh_tab-psnfh "生产资源/工具项目号
                              ).

      APPEND INITIAL LINE TO gt_chg_plfhx ASSIGNING FIELD-SYMBOL(<fs_del_plfhx>).

      <fs_del_plfhx> = VALUE #( prt_category                  = abap_true "生产资源/工具类别
                                material                      = abap_true "物料编号(18 个字符)\
                               ).

    ENDLOOP.

    CLEAR:lv_vornr_prt.

    "PRT
    LOOP AT ls_plpo_01-it_prt INTO DATA(ls_prt) WHERE zlzjlx EQ '工装' OR zlzjlx EQ '模具' OR  zlzjlx EQ '组合刀具'.

      CLEAR:gt_chg_plfh,gt_chg_plfhx.

      lv_num1 = lv_num1 + 1.

      lv_vornr_prt = lv_vornr_prt + 10.

      lv_maintain_mode = 'C'.

      APPEND INITIAL LINE TO gt_chg_plfh ASSIGNING FIELD-SYMBOL(<fs_chg_plfh>).

      <fs_chg_plfh> = VALUE #( maintain_mode                 = lv_maintain_mode   "维护任务清单:模式(C:创建)
                               flag_bar_pointer              = lv_num1
                               activity                      = ls_plpo_01-vornr  "操作/活动编号
                               sequence_no                   = ls_plpo_01-plnfl  "序列
                               prt_category                  = 'M'                "生产资源/工具类别
                               material                      = ls_prt-fhmnr       "物料编号(18 个字符)\
                               std_value_for_prt_qty         = ls_prt-mgvgw       "数量
                               prt_measure_unit              = ls_prt-mgeinh      "单位
                               item_no_of_prod_resource      = lv_vornr_prt       "生产资源/工具项目号
                               item_no_of_prod_resource_old  = lv_vornr_prt       "生产资源/工具项目号
                               prt_plant                     = '9000'             "工厂中的生产资源/工具
                               ctrl_key                      = ls_prt-steuf       "生产资源工具控制参数
                              ).

      APPEND INITIAL LINE TO gt_chg_plfhx ASSIGNING FIELD-SYMBOL(<fs_chg_plfhx>).

      <fs_chg_plfhx> = VALUE #( prt_category                  = abap_true "生产资源/工具类别
                                material                      = abap_true "物料编号(18 个字符)\
                                std_value_for_prt_qty         = abap_true "数量
                                prt_measure_unit              = abap_true "单位
                                item_no_of_prod_resource      = abap_true "生产资源/工具项目号
                                prt_plant                     = abap_true "工厂中的生产资源/工具
                               ).


    ENDLOOP.

    CLEAR:lv_mdgx_flag.

  ENDLOOP.

  "工序删除
  SORT lt_plpo_01 BY plnfl vornr.
  LOOP AT gt_opr_tab INTO gs_opr_tab.

    READ TABLE gt_chg_plpo TRANSPORTING NO FIELDS WITH KEY sequence_no = gs_opr_tab-plnfl activity = gs_opr_tab-vornr.
    CHECK sy-subrc NE 0.

    gv_num_gx = gv_num_gx + 1.

    APPEND INITIAL LINE TO gt_chg_plpo ASSIGNING <fs_chg_plpo>.

    <fs_chg_plpo> = VALUE #( maintain_mode              = 'D'   "维护任务清单:模式(C:创建)
                             sequence_no                = gs_opr_tab-plnfl "序列
                             flag_bar_pointer           = gv_num_gx
                             activity                   = gs_opr_tab-vornr  "操作/活动编号
                             activity_old               = gs_opr_tab-vornr  "工序编号
                            ).

    APPEND INITIAL LINE TO gt_chg_plpox ASSIGNING <fs_chg_plpox>.

    <fs_chg_plpox> = VALUE #( activity                   = abap_true "操作/活动编号
                             ).

  ENDLOOP.

  SORT gt_chg_plpo BY activity ASCENDING.

  "第一道ZP02工序,或没有ZP02但有ZP05的工序 仓库字段赋值
  READ TABLE gt_chg_plpo ASSIGNING FIELD-SYMBOL(<gs_chg_opr>) WITH  KEY control_key = 'ZP02'.
  IF sy-subrc EQ 0.
    DATA(lv_tabix) = sy-tabix.
    PERFORM frm_set_plpo_field USING ps_plant-werks CHANGING <gs_chg_opr>-userfields_keyword_id
                                                             <gs_chg_opr>-userfield_ch20_00
                                                             <gs_chg_opr>-userfield_ch20_01.

    READ TABLE gt_chg_plpox ASSIGNING FIELD-SYMBOL(<gs_chg_plpox>) INDEX lv_tabix.
    IF sy-subrc EQ 0 AND <gs_chg_plpox> IS ASSIGNED.
      <gs_chg_plpox>-userfields_keyword_id = abap_true.
      <gs_chg_plpox>-userfield_ch20_00     = abap_true.
      <gs_chg_plpox>-userfield_ch20_01     = abap_true.
    ENDIF.

  ELSE.
    READ TABLE gt_chg_plpo ASSIGNING <gs_chg_opr> WITH  KEY control_key = 'ZP05'.
    IF sy-subrc EQ 0.
      lv_tabix = sy-tabix.
      PERFORM frm_set_plpo_field USING ps_plant-werks CHANGING <gs_chg_opr>-userfields_keyword_id
                                                               <gs_chg_opr>-userfield_ch20_00
                                                               <gs_chg_opr>-userfield_ch20_01.

      READ TABLE gt_chg_plpox ASSIGNING <gs_chg_plpox> INDEX lv_tabix.
      IF sy-subrc EQ 0 AND <gs_chg_plpox> IS ASSIGNED.
        <gs_chg_plpox>-userfields_keyword_id = abap_true.
        <gs_chg_plpox>-userfield_ch20_00     = abap_true.
        <gs_chg_plpox>-userfield_ch20_01     = abap_true.
      ENDIF.
    ENDIF.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_SET_FZ
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_PLPO_CRT_FZ
*&---------------------------------------------------------------------*
FORM frm_set_fz  USING pv_fz TYPE string.

  DATA: lv_pyl   TYPE i,
        lv_pylcd TYPE i,
        lv_pylwz TYPE i.

  CLEAR:gr_fz.

  DO strlen( pv_fz ) / 4 TIMES.

    "lv_pyl = ( sy-index - 1 ) * 2.
    lv_pylcd = sy-index  * 4.

    APPEND INITIAL LINE TO gr_fz ASSIGNING FIELD-SYMBOL(<fs_zf>).

    <fs_zf>-sign   = 'I'.
    <fs_zf>-option = 'EQ'.
    <fs_zf>-low    = pv_fz+0(lv_pylcd).

  ENDDO.

  CLEAR lv_pyl.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_set_routine_bapiCHG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&      <-- CS_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_set_routine_bapichg    USING ps_plant     TYPE zsplm_005_plant
                                      ps_material  TYPE zsplm_005_material
                                      ps_plpo_chg  TYPE typ_plpo
                             CHANGING cs_osappk    TYPE zsplm_005_osappk.

  CLEAR:gt_return,gs_return.

  PERFORM frm_set_routine_bapi_chk USING ps_material.

  IF gt_return[] IS NOT INITIAL.

  ELSE.

    DATA(lv_key_date) = CONV datum( ps_material-datuv ).
    CALL FUNCTION 'CPCC_S_TASK_LIST_MAINTAIN'
      EXPORTING
        key_date                     = sy-datum "lv_key_date
        task_list_type               = ps_plpo_chg-plnty
        task_list_group              = ps_plpo_chg-plnnr
        group_counter                = ps_plpo_chg-plnal
        task_maintain_mode           = 'M'
        task                         = gs_chg_plko
        task_x                       = gs_chg_plkox
      TABLES
        material_task_allocations    = gt_chg_mapl
        material_task_allocations_x  = gt_chg_maplx
        production_resources_tools   = gt_chg_plfh
        production_resources_tools_x = gt_chg_plfhx
        sequences                    = gt_chg_plfl
        sequences_x                  = gt_chg_plflx
        operations                   = gt_chg_plpo
        operations_x                 = gt_chg_plpox
        return                       = gt_return.

  ENDIF.

  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 ).

  cs_osappk =  VALUE #( BASE cs_osappk
                        code  = gs_return-type
                        plnnr = ps_plpo_chg-plnnr
                        plnal = ps_plpo_chg-plnal
                        werks = ps_plpo_chg-werks
                        matnr = |{ ps_plpo_chg-matnr ALPHA = OUT }|
                        msg   = COND #( WHEN gs_return-message+1 IS INITIAL THEN '工艺路线维护成功' ELSE gs_return-message )
                       ) .

ENDFORM.*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_DEL
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LS_INPUT
*&      <-- PT_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_routine_del  USING  ps_plant     TYPE zsplm_005_plant
                             ps_material  TYPE zsplm_005_material
                    CHANGING cs_omaterial TYPE zsplm_005_omaterial
                             cs_omaterial_tmp TYPE zsplm_005_omaterial..

  CHECK gt_plpo_del IS NOT INITIAL.

  LOOP AT gt_plpo_del INTO gs_plpo_del.

    "初始化反馈
    APPEND INITIAL LINE TO cs_omaterial-ot_sap_pk ASSIGNING FIELD-SYMBOL(<fs_osappk>).
    DATA(lv_tabix) = sy-tabix.

    <fs_osappk> = CORRESPONDING #( gs_plpo_crt ).
    <fs_osappk>-zktext = ps_material-ktext.
    <fs_osappk>-werks  = gs_plpo_del-werks.
    <fs_osappk>-matnr  = |{ gs_plpo_del-matnr ALPHA = OUT }|.
    <fs_osappk>-plnnr  = gs_plpo_del-plnnr.
    <fs_osappk>-plnal  = gs_plpo_del-plnal.

    PERFORM frm_routine_refresh.

    PERFORM frm_set_routine_bapidel USING gs_plpo_del CHANGING <fs_osappk>.

    IF <fs_osappk>-code EQ gc_s.

      "删除成功不反馈
      DELETE cs_omaterial-ot_sap_pk INDEX lv_tabix.
      PERFORM frm_set_routine_savedata USING 'X'  gs_plpo_del ps_plant ps_material.

    ELSE.

      "记录失败反馈
      APPEND <fs_osappk> TO cs_omaterial_tmp-ot_sap_pk.

    ENDIF.

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_set_routine_bapiCHG
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_INPUT
*&      <-- CS_OUTPUT
*&---------------------------------------------------------------------*
FORM frm_set_routine_bapidel    USING ps_plpo_del  TYPE typ_plpo
                             CHANGING cs_osappk TYPE zsplm_005_osappk.

  PERFORM frm_routine_loekz_bapi_single USING ps_plpo_del-matnr
                                              ps_plpo_del-werks
                                              ps_plpo_del-plnnr
                                              ps_plpo_del-plnal
                                              'X'
                                     CHANGING cs_osappk-code
                                              cs_osappk-msg.

  " DATA:lv_num TYPE numc10.
  "
  " LOOP AT gt_tsk_tab INTO DATA(ls_tsk_tab).
  "
  "   APPEND INITIAL LINE TO gt_del_mapl ASSIGNING FIELD-SYMBOL(<fs_del_mapl>).
  "
  "   lv_num = lv_num + 1.
  "
  "   <fs_del_mapl>-maintain_mode    = 'D'.
  "   <fs_del_mapl>-flag_bar_pointer = '0000000001'. "维护任务清单:复选框结构指针
  "   <fs_del_mapl>-material         = ps_plpo_del-matnr.
  "   <fs_del_mapl>-plant            = ps_plpo_del-werks.
  "
  " ENDLOOP.
  "
  " CALL FUNCTION 'CPCC_S_TASK_LIST_MAINTAIN'
  "   EXPORTING
  "     key_date                    = sy-datum
  "     task_list_type              = ps_plpo_del-plnty
  "     task_list_group             = ps_plpo_del-plnnr
  "     group_counter               = ps_plpo_del-plnal
  "     task_maintain_mode          = 'D'
  "     task                        = gs_del_plko
  "     task_x                      = gs_del_plkox
  "   TABLES
  "     material_task_allocations   = gt_del_mapl
  "     material_task_allocations_x = gt_del_maplx
  "     sequences                   = gt_del_plfl
  "     sequences_x                 = gt_del_plflx
  "     operations                  = gt_del_plpo
  "     operations_x                = gt_del_plpox
  "     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( cs_osappk-code ).
  "
  " cs_osappk =  VALUE #( BASE cs_osappk
  "                      code  = gs_return-type
  "                      msg   = COND #( WHEN gs_return-message IS INITIAL THEN '工艺路线删除成功' ELSE gs_return-message )
  "                     ) .

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ROUTINE_LOEKZ_BAPI_SINGLE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> PS_ISAPPK_MATNR
*&      --> PS_ISAPPK_WERKS
*&      --> PS_ISAPPK_PLNNR
*&      --> PS_ISAPPK_PLNAL
*&      --> PV_LOEKZ
*&      <-- CS_OSAPPK_CODE
*&      <-- CS_OSAPPK_MSG
*&---------------------------------------------------------------------*
FORM frm_routine_loekz_bapi_single  USING   ps_matnr
                                            ps_werks
                                            ps_plnnr
                                            ps_plnal
                                            pv_loekz TYPE char1
                                   CHANGING cs_code
                                            cs_msg.

  DATA:lv_mode    TYPE ctu_mode   VALUE 'N',
       lv_update  TYPE ctu_update VALUE 'S',
       lt_bdcdata TYPE TABLE OF bdcdata,
       ls_bdcdata TYPE bdcdata,
       lt_messtab TYPE TABLE OF bdcmsgcoll,
       ls_messtab TYPE bdcmsgcoll,
       lv_msg     TYPE bapi_msg.

  CLEAR:cs_code,cs_msg.

  bdc_dynpro       'SAPLCPDI' '1010'.
  bdc_field        'BDC_CURSOR'
                        'RC27M-MATNR'.
  bdc_field        'BDC_OKCODE'
                        '=ALD1'.
  bdc_field        'RC27M-MATNR'
                        ps_matnr.
  bdc_field        'RC27M-WERKS'
                        ps_werks.
  bdc_field        'RC271-PLNNR'
                        ps_plnnr.
  bdc_field        'RC271-PLNAL'
                        ps_plnal.

  bdc_dynpro       'SAPLCPDA' '1200'.
  bdc_field        'BDC_OKCODE'
                        '=BU'.
  bdc_field        'BDC_CURSOR'
                        'PLKOD-VERWE'.
  bdc_field        'PLKOD-DELKZ'
                        pv_loekz.

  CALL TRANSACTION 'CA02' USING lt_bdcdata
                   MODE   lv_mode
                   UPDATE lv_update
                   MESSAGES INTO lt_messtab.

  PERFORM frm_bdc_return TABLES lt_messtab CHANGING lv_msg.

  "成功后回写消息
  IF gv_msg IS INITIAL.
    cs_code = gc_s.
    cs_msg  = COND #( WHEN pv_loekz EQ abap_true THEN '工艺路线删除成功' ELSE '工艺路线启用成功' ) .
  ELSE.
    cs_code = gc_e.
    cs_msg  = gv_msg+1 .
  ENDIF.

  CLEAR:lv_mode   ,
        lv_update ,
        lt_bdcdata,
        ls_bdcdata,
        lt_messtab,
        ls_messtab,
        lv_msg.

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
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值