ABAP:ME21N/ME22N采购订单增强

ME21N/ME22N增强:

BADI名称:ME_PROCESS_PO_CUST


 

SE18找到BADI创建实施

 

 

 

 

 

 

 

 


找到对应的方法:

PROCESS_HEADER:

  method IF_EX_ME_PROCESS_PO_CUST~PROCESS_HEADER.
  INCLUDE MM_MESSAGES_MAC.
  DATA:l_head TYPE mepoheader.
  DATA:l_item TYPE mepoitem.

  DATA:L_BANFN TYPE EBAN-BANFN,
        wa_EBAN TYPE eban."采购申请头

  DATA:items TYPE purchase_order_items,
        item_obj TYPE  purchase_order_item,
        l_land1 type LAND1_GP.


  l_head = IM_HEADER->get_data( ).
  SELECT single land1 into l_land1 FROM LFA1 WHERE lifnr = l_head-lifnr.
  IF l_land1 = 'CN' .
    IF l_head-bsart = 'ZPSU' and l_head-waers <> 'CNY'.
      MESSAGE '采购订单类型为ZPSU时,货币必须是CNY!' TYPE 'I'.
      l_head-waers = 'CNY'.
      IM_HEADER->set_data( IM_DATA = L_HEAD ).
    ENDIF.

    IF l_head-bsart = 'ZPTO' and l_head-waers <> 'USD'."
      MESSAGE '采购订单类型为ZPTO时,货币必须是USD!' TYPE 'I'.
      l_head-waers = 'USD'.
      IM_HEADER->set_data( IM_DATA = L_HEAD ).
    ENDIF.
  ENDIF.

*  items = im_header->get_items( ) .
*
*  CLEAR:wa_EBAN.
*  LOOP AT items INTO item_obj .
*    l_item = item_obj-item->get_data(  ).
*    IF l_item-BANFN <> ''.
*      SELECT SINGLE * INTO wa_EBAN FROM EBAN WHERE BANFN = l_item-BANFN AND BNFPO = l_item-BNFPO.
*      CASE wa_EBAN-BSART.
*      WHEN 'ZPR1' OR 'ZPR2' OR 'ZPR8'.
*        L_HEAD-SUBMI = '90'.
*        IM_HEADER->set_data( IM_DATA = L_HEAD ).
*        CONTINUE.
*      WHEN 'NB' OR 'NB1' OR 'NB2' OR 'NB3'.
*        IF wa_EBAN-MENGE <> l_item-MENGE.
*          L_HEAD-SUBMI = '90'.
*          IM_HEADER->set_data( IM_DATA = L_HEAD ).
*          CONTINUE.
*        ENDIF.
*      ENDCASE.
*    ENDIF.
*  ENDLOOP.
*  BREAK zhangdq.
*  IF sy-TCODE = 'ME21N' .
*    IF l_head-BSART = 'ZPO1' OR l_head-BSART = 'ZPO2' OR l_head-BSART = 'ZPO3'
*    OR l_head-BSART = 'ZPO4' OR l_head-BSART = 'ZPO5' OR l_head-BSART = 'ZPO6'
*    OR l_head-BSART = 'ZPO7' OR l_head-BSART = 'ZPO8' OR l_head-BSART = 'ZPO9'.
*      IF L_HEAD-SUBMI = '' .
*        L_HEAD-SUBMI = '80'.
*        IM_HEADER->set_data( IM_DATA = L_HEAD ).
*      ENDIF.
*    ENDIF.
*  ENDIF.

  endmethod.

 


PROCESS_ITEM:

CALL FUNCTION 'ZMM_BADI_ITEM_DEFAULT'
  EXPORTING
     im_item = im_item
     i_tcode = sy-tcode.

FUNCTION zmm_badi_item_default.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(IM_ITEM) TYPE REF TO  IF_PURCHASE_ORDER_ITEM_MM OPTIONAL
*"     VALUE(I_TCODE) TYPE  SY-TCODE OPTIONAL
*"----------------------------------------------------------------------

  DATA:ls_header TYPE mepoheader,
       ls_item   TYPE mepoitem,
       lo_header TYPE REF TO if_purchase_order_mm.

  CLEAR:gv_price,gs_cond.
  REFRESH:gt_cond.

  lo_header = im_item->get_header( ).     " 获取采购订单抬头对象
  ls_header = lo_header->get_data( ).     " 获取采购订单抬头
  ls_item   = im_item->get_data( ).       " 获取采购订单行项目

  CALL METHOD im_item->get_conditions
    IMPORTING
      ex_conditions = gt_cond[].

  CASE ls_header-bsart.
    WHEN 'ZCUS'.
      ls_item-umson = 'X'.
      IF ls_item-werks NE '1230' AND ls_item-werks NE '4200'."如果美国墨西哥工厂则不填写税码
        ls_item-mwskz = 'A9'.
      ENDIF.
    WHEN 'ZITO'.
      IF ls_item-werks NE '1230' AND ls_item-werks NE '4200'.
        ls_item-mwskz = 'A9'.
      ENDIF.
    WHEN OTHERS.
  ENDCASE.

*====================================================================*
  "*== add Tuq 18.11.2022 12:03:10
  "*== 重新计算价格
  SELECT SINGLE ebeln
    FROM ekpo
    INTO @DATA(lv_ekpo)
   WHERE ebeln = @ls_item-ebeln
     AND ebelp = @ls_item-ebelp.
  IF sy-subrc <> 0.

    SORT:gt_cond BY kschl.

    READ TABLE gt_cond ASSIGNING FIELD-SYMBOL(<gs_cond>) WITH KEY kschl = 'PB00' BINARY SEARCH.
    IF <gs_cond> IS ASSIGNED.

      gs_cond = <gs_cond>.

      PERFORM frm_get_price USING ls_header CHANGING ls_item.

      IF gv_abap = abap_true.

*        <gs_cond>-kbetr = ls_item-netpr.
        <gs_cond>-kbetr = gv_price.
        <gs_cond>-waers = gs_cond-waers.
        <gs_cond>-kkurs = gs_cond-kkurs.
        <gs_cond>-kumza = gs_cond-kumza.
        <gs_cond>-kumne = gs_cond-kumne.
        CALL METHOD im_item->set_conditions
          EXPORTING
            im_conditions = gt_cond.

        REFRESH:gt_cond.

      ENDIF.

    ENDIF.

  ENDIF.

  "*== end Tuq 18.11.2022 12:03:10

  im_item->set_data( ls_item ).

ENDFUNCTION.

*----------------------------------------------------------------------*
***INCLUDE LZ_MM_ENH_BADIF02.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_PRICE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LS_HEADER  text
*      <--P_LS_ITEM  text
*----------------------------------------------------------------------*
FORM frm_get_price  USING ps_header TYPE mepoheader
                 CHANGING ps_item TYPE mepoitem.

  CLEAR:gs_header,gs_item,gs_008,gv_date,gv_abap.

  gs_header = ps_header.
  gs_item   = ps_item.

  SELECT SINGLE * FROM zsdt008
    INTO gs_008
   WHERE objkey = ps_item-ebeln
     AND objtype = 'PO'
     AND canum   IN ( '0010','10' ).
  IF sy-subrc = 0.

    gv_date = gs_header-bedat.
*    IF gs_item-eeind IS NOT INITIAL.
*      IF strlen( gs_item-eeind ) = 10.
*        gv_date = |{ gs_item-eeind(4) }{ gs_item-eeind+5(2) }{ gs_item-eeind+8(2) }|.
*      ELSE.
*        gv_date = gs_item-eeind.
*      ENDIF.
*    ENDIF.

    CASE ps_header-bsart.
      WHEN 'ZITO' OR 'ZFTO'.

        PERFORM frm_price_type1.

*        ps_item-netpr = gs_item-netpr.

        gv_abap = abap_true.

      WHEN 'ZIMP' OR 'ZAIM'
        OR 'ZFAI' OR 'ZPTO'.

        PERFORM frm_price_type2.

        ps_item-netpr = gs_item-netpr.
        ps_item-mwskz = gs_item-mwskz.
        gv_price = gs_item-netpr.

        gv_abap = abap_true.

      WHEN OTHERS.
    ENDCASE.
  ENDIF.

  CLEAR:gs_header,gs_item,gs_008.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_ZSCALE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_LV_ZSCALE  text
*----------------------------------------------------------------------*
FORM frm_get_zscale CHANGING lv_zscale TYPE zsdt006-zscale
                              lv_err TYPE c.

  DATA:ls_zsdt006 TYPE zsdt006,
       lt_zsdt006 TYPE TABLE OF zsdt006.

  SELECT * INTO TABLE lt_zsdt006
    FROM zsdt006
   WHERE bsart = gs_header-bsart
     AND datab <= gv_date
     AND datbi >= gv_date.
  IF sy-subrc <> 0.
    lv_err = 'E'.
    RETURN.
  ENDIF.

  READ TABLE lt_zsdt006 INTO ls_zsdt006
        WITH KEY lifnr = gs_header-lifnr
                 werks = gs_item-werks
                 matnr = gs_item-matnr.
  IF sy-subrc = 0.
    lv_err = 'S'.
    lv_zscale = ls_zsdt006-zscale / 100.
    RETURN.
  ENDIF.

  READ TABLE lt_zsdt006 INTO ls_zsdt006
    WITH KEY lifnr = gs_header-lifnr
             werks = gs_item-werks
             matnr = ''.
  IF sy-subrc = 0.
    lv_err = 'S'.
    lv_zscale = ls_zsdt006-zscale / 100.
    RETURN.
  ENDIF.

  READ TABLE lt_zsdt006 INTO ls_zsdt006
    WITH KEY lifnr = gs_header-lifnr
             werks = ''
             matnr = ''.
  IF sy-subrc = 0.
    lv_err = 'S'.
    lv_zscale = ls_zsdt006-zscale / 100.
    RETURN.
  ENDIF.

  READ TABLE lt_zsdt006 INTO ls_zsdt006
    WITH KEY bsart = gs_header-bsart
             lifnr = ''
             werks = ''
             matnr = ''.
  IF sy-subrc = 0.
    lv_err = 'S'.
    lv_zscale = ls_zsdt006-zscale / 100.
    RETURN.
  ENDIF.

  lv_err = 'E'.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_PRICE_TYPE1
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_price_type1 .


  DATA:lv_netpr   TYPE bprei,
       ls_zsdt001 TYPE zsdt001,
       ls_zsdt035 TYPE zsdt035,
       ls_zsdt011 TYPE zsdt011,
       ls_eine    TYPE eine,
       ls_eina    TYPE eina,
       ls_a017    TYPE a017,
       ls_a018    TYPE a018,
       ls_konp    TYPE konp,
       lv_zscale  TYPE zsdt006-zscale,
       lv_err     TYPE c LENGTH 1.

  CLEAR:ls_zsdt001,ls_zsdt035,ls_zsdt011,lv_zscale,
        lv_err,ls_eine,ls_eina,ls_a017,
        ls_konp,ls_a018.

  SELECT SINGLE * INTO ls_zsdt001
    FROM zsdt001
   WHERE zrfcid = gs_008-zrfcid
     AND canum = '0040'.

*  SELECT SINGLE kschl
*    INTO ps_alv2-kschl
*    FROM zsdt001
*   WHERE zrfcid = r_zjylx
*     AND canum = '0010'.
*  IF sy-subrc <> 0.
*    ps_alv2-kschl = 'PB00'.
*  ENDIF.

*====================================================================*
  "*== add Tuq 16.11.2022 09:41:18
*     SELECT SINGLE * INTO ls_zsdt010 FROM zsdt010
*      WHERE werks = ls_zsdt001-werks"ps_alv2-zjhgc
*       AND matnr = ps_alv2-matnr
*       AND datab <= ps_alv2-bedat"sy-datum
*       AND datbi >= ps_alv2-bedat."sy-datum.

  SELECT SINGLE * INTO ls_zsdt035
    FROM zsdt035
   WHERE werks = ls_zsdt001-werks"ps_alv2-zjhgc
     AND matnr = gs_item-matnr
     AND datab <= gv_date"sy-datum
     AND datbi >= gv_date."sy-datum.

  IF sy-subrc <> 0.
    MESSAGE '转厂成本维护表未维护' TYPE 'E'.
    RETURN.
  ENDIF.

  SELECT SINGLE * INTO ls_zsdt011
    FROM zsdt011
   WHERE werks = ls_zsdt001-werks "ps_alv2-zjhgc
     AND datab <= gv_date"sy-datum
     AND datbi >= gv_date."sy-datum.
  IF sy-subrc <> 0.
    MESSAGE '转厂百分比维护表未维护' TYPE 'E'.
    RETURN.
  ENDIF.

  lv_netpr = ls_zsdt035-stprs * ( 1 + ls_zsdt011-zscale / 100 )." / ls_zsdt035-peinh.
****UPDATE BY ZJ 20221208 S ZFTO也从比例维护表取比例
*  IF gs_header-bsart <> 'ZFTO'.
  PERFORM frm_get_zscale CHANGING lv_zscale lv_err.
  IF lv_err = 'E'.
    MESSAGE '需求PO比例维护表未维护' TYPE 'E'.
    RETURN.
  ENDIF.
****UPDATE BY ZJ 20221208 E ZFTO也从比例维护表取比例
*          ps_alv2-brtwr_sc = ps_alv2-brtwr.
*          ps_alv2-waers_sc = ls_zsdt035-waers.
  lv_netpr = lv_netpr * ( 1 + lv_zscale ).
*  ENDIF.

  SELECT SINGLE * INTO ls_eina
    FROM eina
   WHERE matnr = gs_item-matnr
     AND lifnr = gs_header-lifnr.
  IF sy-subrc <> 0.
    MESSAGE '采购信息记录未维护' TYPE 'E'.
    RETURN.
  ENDIF.

  SELECT SINGLE * INTO ls_eine
    FROM eine
   WHERE infnr = ls_eina-infnr
     AND werks = gs_item-werks
     AND ekorg = gs_header-ekorg.
  IF sy-subrc <> 0.
    SELECT SINGLE * INTO ls_eine
      FROM eine
     WHERE infnr = ls_eina-infnr
*         AND werks = ps_alv2-werks
       AND ekorg = gs_header-ekorg.
    IF sy-subrc NE 0.
      MESSAGE '采购信息记录未维护' TYPE 'E'.
      RETURN.
    ENDIF.
  ENDIF.

*        CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
*          EXPORTING
*            input  = ps_alv2-lifnr
*          IMPORTING
*            output = lv_lifnr.

*        SELECT SINGLE * INTO ls_a017
*          FROM a017
*         WHERE lifnr = gs_header-lifnr
*           AND matnr = gs_item-matnr
*           AND ekorg = gs_header-ekorg
*           AND werks = gs_item-werks
*           AND esokz = '0'
*           AND datab <= sy-datum
*           AND datbi >= sy-datum.
*        SELECT SINGLE * INTO ls_konp
*          FROM konp
*         WHERE knumh = ls_a017-knumh
*           AND kschl = 'PB00'.
*        IF ls_konp-kbetr IS INITIAL.
*          SELECT SINGLE * INTO ls_a018
*            FROM a018
*           WHERE matnr = ps_alv2-matnr
*             AND ekorg = gs_header-ekorg
*             AND kschl = 'PB00'
*             AND datab <= sy-datum
*             AND datbi >=  sy-datum.
*          SELECT SINGLE * INTO ls_konp
*            FROM konp
*           WHERE knumh = ls_a018-knumh
*             AND kschl = 'PB00'.
*        ENDIF.

*    IF ls_konp-kbetr IS INITIAL.
*      ps_alv2-message = '该物料/供应商采购信息记录没有维护价格'.
*      RETURN.
*    ENDIF.

*        ps_alv2-koein = ls_konp-konwa.
*        ps_alv2-koein_y = ls_konp-konwa."*==原货币
*====================================================================*
  "*== add Tuq 16.11.2022 09:19:30
*        SELECT SINGLE waers_l FROM zsdt001
*          INTO @DATA(lv_waers_l)
*         WHERE zrfcid = @r_zjylx
*           AND canum  = '0010'.
*        IF lv_waers_l <> ls_konp-konwa
*          AND lv_waers_l IS NOT INITIAL."汇率转换
*          ps_item-waers = lv_waers_l."*==行项目条件币种
*        ENDIF.
*====================================================================*
  "*== add Tuq 18.11.2022 11:37:44
*  IF gs_item-waers <> ls_zsdt035-waers.
  IF gs_cond-waers <> ls_zsdt035-waers.
    CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
      EXPORTING
        date             = sy-datum
        foreign_amount   = lv_netpr
        foreign_currency = ls_zsdt035-waers
        local_currency   = gs_cond-waers
        type_of_rate     = 'M'
      IMPORTING
        local_amount     = lv_netpr
      EXCEPTIONS
        no_rate_found    = 1
        OTHERS           = 2.
  ENDIF.
  "*== end Tuq 16.11.2022 09:19:30

  "*==输出金额  PEINH
*  gs_item-netpr = lv_netpr * gs_item-peinh.
  gv_price = lv_netpr." * gs_cond-kpein.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_PRICE_TYPE2
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_price_type2 .

  DATA:ls_zsdt008    TYPE zsdt008,
       ls_eine       TYPE eine,
       ls_eina       TYPE eina,
       ls_a017       TYPE a017,
       ls_a018       TYPE a018,
       ls_konp       TYPE konp,
       lv_kbetr      TYPE konp-kbetr,
       lv_knumh_a003 TYPE a003-knumh,
       lv_werks      TYPE werks_d,
       lv_zscale     TYPE zsdt006-zscale,
       lv_err        TYPE c LENGTH 1..

  CLEAR:ls_zsdt008,ls_eina,ls_eine,lv_kbetr,lv_knumh_a003,
        ls_a017,ls_konp,ls_a018,lv_zscale,lv_err.

  SELECT SINGLE * FROM zsdt008
    INTO ls_zsdt008
   WHERE zrfc_logid = gs_008-zrfc_logid
     AND canum = '0030'
     AND objtype = 'PO'.

  SELECT SINGLE lifnr
    FROM ekko
    INTO @DATA(lv_zlifnr)
   WHERE ebeln = @ls_zsdt008-objkey.

  SELECT SINGLE * INTO ls_eina
    FROM eina
   WHERE matnr = gs_item-matnr
     AND lifnr = lv_zlifnr.
  IF sy-subrc <> 0.
    MESSAGE '采购信息记录未维护' TYPE 'E'.
    RETURN.
  ENDIF.

  SELECT SINGLE * INTO ls_eine FROM eine
   WHERE infnr = ls_eina-infnr
     AND werks = gs_item-werks
     AND ekorg = gs_header-ekorg.
  IF sy-subrc <> 0.
    SELECT SINGLE * INTO ls_eine
      FROM eine
     WHERE infnr = ls_eina-infnr
       AND ekorg = gs_header-ekorg.
    IF sy-subrc NE 0.
      MESSAGE '采购信息记录未维护' TYPE 'E'.
      RETURN.
    ENDIF.
  ENDIF.
****校验采购信息记录单位转换是否与物料主数据中一致
  PERFORM frm_check_convert USING ls_eina ls_eine.
  gs_cond-kumza = ls_eine-bpumn.
  gs_cond-kumne = ls_eine-bpumz.
  SELECT SINGLE * FROM zsdt001
    INTO @DATA(ls_zsdt001)
   WHERE zrfcid = @gs_008-zrfcid
     AND canum = @gs_008-canum.

  SELECT SINGLE knumh
    INTO lv_knumh_a003
    FROM a003
   WHERE kappl = 'TX'
     AND aland = 'CN'
     AND mwskz = ls_eine-mwskz.

  SELECT SINGLE kbetr
    INTO lv_kbetr
    FROM konp
   WHERE knumh = lv_knumh_a003.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
    EXPORTING
      input  = gs_header-lifnr
    IMPORTING
      output = lv_werks.

  SELECT SINGLE * INTO ls_a017
    FROM a017
   WHERE lifnr = lv_zlifnr
     AND matnr = gs_item-matnr
     AND ekorg = gs_header-ekorg   ""待定
     AND werks = lv_werks
     AND esokz = '0'
     AND datab <= gv_date "sy-datum
     AND datbi >= gv_date." sy-datum.

  SELECT SINGLE * INTO ls_konp
    FROM konp
   WHERE knumh = ls_a017-knumh
     AND kschl = 'PB00'.
  IF ls_konp-kbetr IS INITIAL.
    SELECT SINGLE * INTO ls_a018
      FROM a018
     WHERE matnr = gs_item-matnr
       AND ekorg = gs_header-ekorg   ""待定
       AND lifnr = lv_zlifnr
       AND kschl = 'PB00'
       AND datab <= gv_date "sy-datum
       AND datbi >= gv_date. " sy-datum.
    CLEAR:ls_konp.
    SELECT SINGLE * INTO ls_konp
      FROM konp
     WHERE knumh = ls_a018-knumh
       AND kschl = 'PB00'.
  ENDIF.

  IF ls_konp-kbetr IS INITIAL.
    MESSAGE '该物料/供应商采购信息记录没有维护价格' TYPE 'E'.
    RETURN.
  ENDIF.

*    ps_alv2-kbetr1 = ls_konp-kbetr / ( 1 + lv_kbetr / 1000 ).
  lv_kbetr = ls_konp-kbetr.

  "*==当前采购订单供应商
  PERFORM frm_get_zscale CHANGING lv_zscale lv_err.
  IF lv_err = 'E'.
    MESSAGE '需求PO比例维护表未维护' TYPE 'E'.
    RETURN.
  ENDIF.

  lv_kbetr = lv_kbetr * ( 1 + lv_zscale ).

*  gs_item-netpr = lv_kbetr * gs_item-peinh.
  gs_item-netpr = lv_kbetr.
  gs_cond-waers = ls_konp-konwa.

  IF ls_zsdt001-mwskz IS INITIAL.
    gs_item-mwskz = ls_eine-mwskz.
  ELSE.
    gs_item-mwskz = ls_zsdt001-mwskz.
  ENDIF.

  DATA:lv_from_cur TYPE bapi1093_1-from_curr,
       lv_to_cur   TYPE bapi1093_1-to_currncy,
       ls_rate     TYPE bapi1093_0,
       ls_return   TYPE bapiret1.
  IF gs_cond-waers NE gs_header-waers.
    CLEAR:lv_from_cur,lv_to_cur,ls_rate,ls_return.
    lv_from_cur = gs_cond-waers.
    lv_to_cur = gs_header-waers.
    CALL FUNCTION 'BAPI_EXCHANGERATE_GETDETAIL'
      EXPORTING
        rate_type  = 'M'
        from_curr  = lv_from_cur
        to_currncy = lv_to_cur
        date       = sy-datum
      IMPORTING
        exch_rate  = ls_rate
        return     = ls_return.
    IF ls_return-type NE 'E'.
      gs_cond-kkurs = ls_rate-exch_rate.
*        pocondx-conexchrat = 'X'.
    ENDIF.
  ENDIF.
*  ps_alv2-kpein = ls_konp-kpein.
*  ps_alv2-mwskz = ls_eine-mwskz.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_CHECK_CONVERT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_LS_EINA  text
*      -->P_LS_EINE  text
*----------------------------------------------------------------------*
FORM frm_check_convert  USING ps_eina TYPE eina
                              ps_eine TYPE eine.
  DATA:lv_num1  TYPE marm-umrez,
       lv_num2  TYPE marm-umren,
       lv_num3  TYPE marm-umren,
       lv_index TYPE i.
  SELECT SINGLE umrez,umren
    INTO @DATA(ls_marm)
    FROM marm
   WHERE matnr = @ps_eina-matnr
     AND meinh = @ps_eina-meins.
  IF ps_eina-umren NE ls_marm-umren OR
     ps_eina-umrez NE ls_marm-umrez.
    MESSAGE '采购信息记录订单单位转换与物料主数据中不一致' TYPE 'E'.
    RETURN.
  ENDIF.

  SELECT SINGLE umrez,umren
    INTO @DATA(ls_marm2)
    FROM marm
   WHERE matnr = @ps_eina-matnr
     AND meinh = @ps_eine-bprme.
  CLEAR:lv_num2,lv_num1,lv_num3,lv_index.
  lv_num1 = ls_marm-umren.
  lv_num2 = ls_marm2-umren.

  IF lv_num1 > lv_num2.
    lv_num3 = lv_num1.
  ELSE.
    lv_num3 = lv_num2.
  ENDIF.

  lv_index = lv_num3.
  "求最小公倍数
  WHILE lv_index > 0.
    IF lv_index MOD ls_marm-umren = 0 AND
       lv_index MOD ls_marm2-umren = 0 .
      EXIT.
    ELSE.
      lv_index = lv_index + 1.
    ENDIF.
  ENDWHILE.

  lv_num2 = ls_marm-umrez * lv_index / ls_marm-umren.
  lv_num1 = ls_marm2-umrez * lv_index / ls_marm2-umren.

  IF lv_num1 < lv_num2.
    lv_num3 = lv_num1.
  ELSE.
    lv_num3 = lv_num2.
  ENDIF.

  lv_index = lv_num3.

  "求最大公约数
  DO lv_num3 TIMES.
    IF lv_num2 MOD lv_index NE 0 OR
       lv_num1 MOD lv_index NE 0.
      lv_index = lv_index - 1.
    ELSE.
      EXIT.
    ENDIF.
  ENDDO.

  IF lv_index = 0.
    lv_index = 1.
  ENDIF.

  lv_num2 = lv_num2 / lv_index.
  lv_num1 = lv_num1 / lv_index.

  IF ps_eine-bpumn NE lv_num1 OR
     ps_eine-bpumz NE lv_num2.
    MESSAGE '采购信息记录订单价格单位转换与物料主数据中不一致' TYPE 'E'.
    RETURN.
  ENDIF.
ENDFORM.

CHECK:

  METHOD if_ex_me_process_po_cust~check.
****ADD BY ZJ 采购订单保存增强 开关限制 START
    DATA:ls_head       TYPE  mepoheader,
         ls_zsdt031    TYPE zsdt031,
         lv_canum      TYPE zcanum,
         lv_zrfcid     TYPE zrfcid,
         lt_zsdt008    TYPE TABLE OF zsdt008,
         ls_zsdt008    TYPE zsdt008,
         gl_tabix      TYPE sy-tabix,
         gl_subrc      TYPE sy-subrc,
         gl_handle     TYPE REF TO cl_handle_mm,
         gl_dummy      TYPE string,
         lv_zrfc_logid TYPE  zrfc_logid, "
         wa_bukrs      TYPE ekko-bukrs. "
    IF ( sy-tcode = 'ME22N' OR sy-tcode = 'ME23N' ).
      ls_head = im_header->get_data( ).
      SELECT SINGLE zrfc_logid INTO lv_zrfc_logid FROM zsdt008
                                                    WHERE objkey = ls_head-ebeln
                                                     AND objtype = 'PO'.
      "                                                  AND canum = '0010'
      IF sy-subrc = 0.
        "找源头po
        SELECT SINGLE * FROM zsdt008 INTO ls_zsdt008 WHERE zrfc_logid =  lv_zrfc_logid
                                                      AND canum = '0010'.
        IF  sy-subrc = 0.
          IF ls_zsdt008-objkey = ls_head-ebeln. "是源头订单可以修改
          ELSEIF ls_zsdt008-objkey <> ls_head-ebeln.
            SELECT SINGLE bukrs INTO wa_bukrs FROM ekko WHERE ebeln =  ls_zsdt008-objkey .

            SELECT SINGLE zbs INTO @DATA(lv_zbs) FROM zsdt031 WHERE bukrs = @wa_bukrs
            AND objtype = 'PO'.
            IF lv_zbs = 'Y'.
              MESSAGE '不可以修改自动创建的采购订单(非源头订单)' TYPE 'E'.
            ENDIF.
          ENDIF.
        ENDIF.      ENDIF.
    ENDIF.
  ENDMETHOD.

POST:

    DATA:ls_header  TYPE mepoheader,
         lt_poitem  TYPE purchase_order_items,
         ls_poitem  LIKE LINE OF lt_poitem,
         lv_message TYPE char255,
         ls_item    TYPE mepoitem.

    DATA:lt_schedules_data TYPE purchase_order_schedules,
         ls_schedules_data LIKE LINE OF lt_schedules_data.

    DATA:lv_menge_check TYPE menge_d.

    DATA:ls_komv TYPE komv,
         lt_komv TYPE TABLE OF komv.

    DATA:ls_meposchedule TYPE meposchedule.

    DATA:ls_zsdt024 TYPE zsdt024,
         lt_zsdt024 TYPE TABLE OF zsdt024.

    DATA:ls_zsdt008 TYPE zsdt008.

    DATA:ls_zsdt025 TYPE zsdt025.

    DATA:lv_zposnr TYPE zzposnr.

    DATA:BEGIN OF ls_konv,
           kbetr TYPE konv-kbetr,
           kpein TYPE konv-kpein,
           waers TYPE konv-waers,
         END OF ls_konv.

    DATA:lv_kposn TYPE konv-kposn.

    CONSTANTS:lc_appli TYPE c LENGTH 1 VALUE 'P'.

    DATA:ls_ekpa TYPE ekpa,
         lt_ekpa TYPE mmpur_t_ekpa.

    IF ( sy-tcode = 'ME22N' OR sy-tcode = 'ME23N' )." AND sy-uname = 'BASIS2'.
      lt_poitem = im_header->get_items( ).
      ls_header = im_header->get_data( ).

      CLEAR:ls_zsdt008.
      SELECT SINGLE * INTO ls_zsdt008 FROM zsdt008 WHERE objkey = ls_header-ebeln AND objtype = 'PO' AND canum = '0010'.   """查询订单订单流程
      IF sy-subrc = 0."" 修改源头订单
        SELECT COUNT(*) FROM zsdt031 WHERE objtype = 'PO' AND bukrs = ls_header-bukrs AND zbs = 'Y'.
        IF sy-subrc = 0.
          SELECT SINGLE * INTO ls_zsdt025 FROM zsdt025 WHERE zzrfcid = ls_zsdt008-zrfcid." AND zcanum = ls_zsdt008-canum.
          REFRESH:lt_zsdt024[].
          LOOP AT lt_poitem INTO ls_poitem.
            CLEAR:ls_item,ls_zsdt024,ls_ekpo,lv_kposn,ls_konv.
            ls_item = ls_poitem-item->get_data( ).
            lv_zposnr = lv_zposnr + 1.
            ls_zsdt024-zposnr = lv_zposnr.
            CLEAR:ls_ekpo.
            SELECT SINGLE * INTO ls_ekpo FROM ekpo WHERE ebeln = ls_item-ebeln AND ebelp = ls_item-ebelp.
            lv_kposn = ls_ekpo-ebelp.
            SELECT SINGLE kbetr kpein a~waers INTO CORRESPONDING FIELDS OF ls_konv FROM konv AS a
              INNER JOIN ekko AS b ON b~knumv = a~knumv
              WHERE ebeln = ls_ekpo-ebeln
              AND kposn = lv_kposn.
            IF ls_ekpo IS INITIAL.
              ls_zsdt024-zbs = 'I'.
            ELSE.

              IF ls_ekpo-loekz = 'L' AND ls_item-loekz = 'L'.
                CONTINUE.
              ELSEIF ls_ekpo-loekz = 'L' AND ls_item-loekz NE 'L'.
                ls_zsdt024-flag = 'X'.
              ENDIF.
              IF ls_item-loekz = 'L'. "" AND ls_ekpo-loekz <> 'L'.
                ls_zsdt024-zbs = 'D'.
              ELSE.
                ls_zsdt024-zbs = 'U'.
              ENDIF.
            ENDIF.
            ls_zsdt024-bsart = ls_header-bsart.
            ls_zsdt024-ebeln = ls_item-ebeln.
            ls_zsdt024-ebelp = ls_item-ebelp.
            ls_zsdt024-lifnr = ls_header-lifnr.
            ls_zsdt024-mcod1 = ''.
            ls_zsdt024-ekorg = ls_header-ekorg.
            ls_zsdt024-ekgrp = ls_header-ekgrp.
            ls_zsdt024-bukrs = ls_header-bukrs.
            ls_zsdt024-ihrez = ls_header-ihrez.
            ls_zsdt024-matnr = ls_item-matnr.
            ls_zsdt024-menge = ls_item-menge.
            ls_zsdt024-vrkme = ls_item-meins.
            ls_zsdt024-koein = ls_header-waers.
            ls_zsdt024-werks = ls_item-werks.
            ls_zsdt024-kpein = ls_item-peinh.
            ls_zsdt024-brtwr = ls_item-brtwr.
            ls_zsdt024-netwr = ls_item-netwr * ls_item-umren / ls_item-bpumz.
            ls_zsdt024-netpr = ls_item-netpr.
            ls_zsdt024-zterm = ls_header-zterm.
            ls_zsdt024-mwskz = ls_item-mwskz.
            ls_zsdt024-banfn = ls_item-banfn.
            ls_zsdt024-bnfpo = ls_item-bnfpo.
            ls_zsdt024-retpo = ls_item-retpo.
            ls_zsdt024-bedat = ls_header-bedat.
            ls_zsdt024-uebpo = ls_item-uebpo.
            ls_zsdt024-uptyp = ls_item-uptyp.
            ls_zsdt024-erdat = sy-datum.
            ls_zsdt024-erzet = sy-uzeit.
            ls_zsdt024-ernam = sy-uname.
*--------------获取交期
            REFRESH:lt_schedules_data[].
            CLEAR:ls_schedules_data.
            lt_schedules_data = ls_poitem-item->get_schedules( ).
            LOOP AT lt_schedules_data INTO ls_schedules_data.
              CLEAR:ls_meposchedule.
              ls_meposchedule = ls_schedules_data-schedule->get_data( ).
              ls_zsdt024-eindt = ls_meposchedule-eindt.
              CLEAR:ls_schedules_data.
            ENDLOOP.
*--------------获取交期
*--------------获取条件记录
            REFRESH:lt_komv[].
            CLEAR:ls_komv.
            CALL METHOD ls_poitem-item->get_conditions
              IMPORTING
                ex_conditions = lt_komv.
            LOOP AT lt_komv INTO ls_komv WHERE kschl = 'PB00' OR kschl = 'PBXX'.
              CLEAR:ls_meposchedule.
              IF ls_komv-kbetr <> ls_konv-kbetr OR ls_komv-waers <> ls_konv-waers OR ls_komv-kpein <> ls_konv-kpein.
                ls_zsdt024-kbetr = ls_komv-kbetr.
                ls_zsdt024-koein = ls_komv-waers.
                ls_zsdt024-kpein = ls_komv-kpein.
              ENDIF.
              CLEAR:ls_schedules_data.
            ENDLOOP.
*--------------获取条件记录

            SELECT SINGLE mcod1 INTO ls_zsdt024-mcod1 FROM lfa1 WHERE lifnr = ls_zsdt024-lifnr.
            SELECT SINGLE maktx INTO ls_zsdt024-maktx FROM makt WHERE matnr = ls_zsdt024-matnr AND spras = sy-langu.
            ls_zsdt024-zrfcid = ls_zsdt025-zrfcid.
            APPEND ls_zsdt024 TO lt_zsdt024[].
            CLEAR:ls_zsdt024.
          ENDLOOP.

          IF lt_zsdt024[] IS NOT INITIAL.
            DATA:ls_ekbe TYPE ekbe,
                 lt_ekbe TYPE TABLE OF ekbe.
            DATA:ls_ekpo_check TYPE ekpo,
                 lt_ekpo_check TYPE TABLE OF ekpo.
            DATA:lv_emsg TYPE c LENGTH 255.

            SELECT * INTO TABLE lt_ekbe FROM ekbe
              FOR ALL ENTRIES IN lt_zsdt024[]
              WHERE ebeln = lt_zsdt024-ebeln
              AND ebelp = lt_zsdt024-ebelp
              AND bwart IN ('101','102').

            SELECT * INTO TABLE lt_ekpo_check FROM ekpo
              FOR ALL ENTRIES IN lt_zsdt024[]
              WHERE ebeln = lt_zsdt024-ebeln
              AND ebelp = lt_zsdt024-ebelp.

            LOOP AT lt_zsdt024 INTO ls_zsdt024.
              LOOP AT lt_ekbe INTO ls_ekbe WHERE ebeln = ls_zsdt024-ebeln AND ebelp = ls_zsdt024-ebelp.
                CASE ls_ekbe-bwart.
                  WHEN '101'.
                    lv_menge_check = lv_menge_check + ls_ekbe-menge.
                  WHEN '102'.
                    lv_menge_check = lv_menge_check - ls_ekbe-menge.
                  WHEN OTHERS.
                ENDCASE.
              ENDLOOP.
              IF lv_menge_check > 0.
                READ TABLE lt_ekpo_check INTO ls_ekpo_check WITH KEY ebeln = ls_zsdt024-ebeln ebelp = ls_zsdt024-ebelp.
                IF sy-subrc = 0.
                  IF ls_zsdt024-netpr <> ls_ekpo_check-netpr.
                    lv_emsg = '行项目' && ls_zsdt024-ebelp && '已经做过收货,不允许修改单价!!'.
                    MESSAGE lv_emsg TYPE 'E'.
                  ENDIF.
                ENDIF.
              ENDIF.
            ENDLOOP.
            IF ls_zsdt025-zrfcid IS NOT INITIAL.
              CALL FUNCTION 'ZMMFU008'
                EXPORTING
                  iv_zjylx   = ls_zsdt025-zrfcid
                TABLES
                  it_zsdt024 = lt_zsdt024[].
            ENDIF.
          ENDIF.
        ENDIF.
      ENDIF.
    ENDIF.

ME21N增强报警告或错误消息

需要用到宏:mmpur_message

  METHOD if_ex_me_process_po_cust~process_item.
    DATA:ls_item   TYPE mepoitem.
    DATA: gl_subrc TYPE sy-subrc,
          gl_tabix TYPE sy-tabix,
          gl_dummy TYPE char72,
          r_items  TYPE purchase_order_items,
          r_item   TYPE purchase_order_item.
    ls_item   = im_item->get_data( ).       " 获取采购订单行项目

    IF sy-mandt = '320' OR sy-mandt = '620' OR sy-mandt = '820'.
      IF ls_item-banfn IS NOT INITIAL
     AND ls_item-bnfpo IS NOT INITIAL
     AND ls_item-zdepart IS INITIAL.
        SELECT SINGLE zdepart FROM eban
          INTO ls_item-zdepart
          WHERE banfn = ls_item-banfn
            AND bnfpo = ls_item-bnfpo.
      ENDIF.

      IF ls_item-knttp = 'F'
      AND ls_item-matnr = ''
      AND ls_item-infnr <> ''.
        SELECT SINGLE * FROM eina
          INTO @DATA(ls_eina)
          WHERE infnr = @ls_item-infnr.
        IF ls_eina-txz01 IS INITIAL.
          MESSAGE '未取到工序虚拟料号,请检查采购信息记录' TYPE 'E'.
        ELSEIF ls_eina-matnr IS INITIAL.
          ls_item-zmatnr_w = ls_eina-txz01.
        ENDIF.

      ENDIF.

      "报警告消息
      DEFINE mmpur_message.
        SET EXTENDED CHECK OFF.
        gl_tabix = sy-tabix.
        gl_subrc = sy-subrc.

        MESSAGE ID &2 TYPE &1 NUMBER &3 WITH &4 &5 &6 &7 INTO gl_dummy.

        CALL METHOD cl_message_mm=>create
          EXPORTING
            im_msgid = &2
            im_msgty = &1
            im_msgno = &3
            im_msgv1 = sy-msgv1
            im_msgv2 = sy-msgv2
            im_msgv3 = sy-msgv3
            im_msgv4 = sy-msgv4
          EXCEPTIONS
            failure  = 01
            dialog   = 02.
        IF sy-subrc = 1 OR sy-subrc = 2.
          MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
                  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        ENDIF.
        sy-subrc = gl_subrc.
        sy-tabix = gl_tabix.
        SET EXTENDED CHECK ON.
      END-OF-DEFINITION.
      "取MARC托盘物料信息,如果不为空,报警告消息
      SELECT SINGLE zxpal
        INTO @DATA(lv_zxpal)
        FROM marc
       WHERE matnr EQ @ls_item-matnr
         AND werks EQ @ls_item-werks.

      IF lv_zxpal IS NOT INITIAL.
        mmpur_message 'W' 'ZMM001' '002' ls_item-matnr lv_zxpal ls_item-menge ''.
      ENDIF.
      CLEAR:lv_zxpal.
    ENDIF.

    im_item->set_data( ls_item ).
  ENDMETHOD.

ME21N/ME22N/ME23N屏幕增强

采购订单抬头增强结构:CI_EKKODB

 采购订单行项目增强结构:CI_EKPODB

 增强点-->SMOD:MM06E005(CMOD:已被分配到ZMM_01中)

EXIT_SAPMM06E_006 为子屏幕参数传入出口(抬头)

EXIT_SAPMM06E_008 为子屏幕参数传出出口(抬头)

EXIT_SAPMM06E_016 为子屏幕参数传入出口(项目)

EXIT_SAPMM06E_018 为子屏幕参数传出出口(项目)

0101为采购订单抬头屏幕  0111为采购订单行项目屏幕

转到全局主数据创建数据结构

 抬头屏幕Dialog

数据传入:EXIT_SAPMM06E_006

*&---------------------------------------------------------------------*
*& 包含               ZXM06U36
*&---------------------------------------------------------------------*

  GS_EKKO_CI = I_CI_EKKO.
  GV_TRTYP   = I_TRTYP.

数据传出:EXIT_SAPMM06E_008

*&---------------------------------------------------------------------*
*& 包含               ZXM06U37
*&---------------------------------------------------------------------*

  E_CI_EKKO = GS_EKKO_CI.

 逻辑流:

PROCESS BEFORE OUTPUT.

  MODULE STATUS_0101.

PROCESS AFTER INPUT.

  MODULE USER_COMMAND_0101.
*&---------------------------------------------------------------------*
*& Module STATUS_0101 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_0101 OUTPUT.

  IF gv_trtyp = 'A'.
    LOOP AT SCREEN.
      IF screen-group1 = 'G1'.
        screen-input = 0.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.
  ENDIF.
*---  取域ZDM_MARKOA的描述
  SELECT SINGLE
         ddtext
    FROM dd07t
    INTO gv_text
   WHERE domname = 'ZDM_MARKOA'
     AND ddlanguage = sy-langu
     AND domvalue_l = gs_ekko_ci-markoa.
  "取域ZDM_MARKSRM的描述
  SELECT SINGLE
         ddtext
    FROM dd07t
    INTO gv_text2
   WHERE domname = 'ZDM_MARKSRM'
     AND ddlanguage = sy-langu
     AND domvalue_l = gs_ekko_ci-marksrm.
ENDMODULE.
*----------------------------------------------------------------------*
***INCLUDE ZXM06I01.
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0101  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_0101 INPUT.

  CASE SY-UCOMM.
    WHEN 'ZHT'.
    WHEN OTHERS.
  ENDCASE.

ENDMODULE.

行项目屏幕Dialog

数据传入:EXIT_SAPMM06E_016

*&---------------------------------------------------------------------*
*& 包含               ZXM06U41
*&---------------------------------------------------------------------*
  MOVE-CORRESPONDING i_ci_ekpo TO gs_ekpo_ci.
  gv_aktyp   = i_aktyp.

数据传出:EXIT_SAPMM06E_018

*&---------------------------------------------------------------------*
*& 包含               ZXM06U40
*&---------------------------------------------------------------------*

  MOVE-CORRESPONDING GS_EKPO_CI TO E_CI_EKPO.

逻辑流:

PROCESS BEFORE OUTPUT.
  MODULE STATUS_0111.

PROCESS AFTER INPUT.
* MODULE USER_COMMAND_0111.
*&---------------------------------------------------------------------*
*& Module STATUS_0111 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_0111 OUTPUT.

  IF gv_aktyp = 'A'.
    LOOP AT SCREEN.
      IF screen-group1 = 'G1'.
        screen-input = 0.
        MODIFY SCREEN.
      ENDIF.
    ENDLOOP.
  ENDIF.

ENDMODULE.

结果展示:

posted @ 2022-12-19 10:51  阿胖的阿多  阅读(2901)  评论(0编辑  收藏  举报