採購訂單查詢BAPI封裝

小胖噜噜仔仔發表於2024-11-22

標準BAPI:BAPI_PO_GETDETAIL1

FUNCTION zbapi_po_getdetail1.
*"----------------------------------------------------------------------
*"*"本地介面:
*"  IMPORTING
*"     VALUE(PURCHASEORDER) TYPE  BAPIMEPOHEADER-PO_NUMBER
*"     VALUE(ACCOUNT_ASSIGNMENT) TYPE  BAPIMMPARA-SELECTION DEFAULT
*"       SPACE
*"     VALUE(ITEM_TEXT) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"     VALUE(HEADER_TEXT) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"     VALUE(DELIVERY_ADDRESS) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"     VALUE(VERSION) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"     VALUE(SERVICES) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"     VALUE(SERIALNUMBERS) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"     VALUE(INVOICEPLAN) TYPE  BAPIMMPARA-SELECTION DEFAULT SPACE
*"  EXPORTING
*"     VALUE(POHEADER) LIKE  ZSMM066 STRUCTURE  ZSMM066
*"     VALUE(POEXPIMPHEADER) LIKE  BAPIEIKP STRUCTURE  BAPIEIKP
*"  TABLES
*"      RETURN STRUCTURE  BAPIRET2 OPTIONAL
*"      POITEM STRUCTURE  ZSMM067 OPTIONAL
*"      POADDRDELIVERY STRUCTURE  BAPIMEPOADDRDELIVERY OPTIONAL
*"      POSCHEDULE STRUCTURE  BAPIMEPOSCHEDULE OPTIONAL
*"      POACCOUNT STRUCTURE  BAPIMEPOACCOUNT OPTIONAL
*"      POCONDHEADER STRUCTURE  BAPIMEPOCONDHEADER OPTIONAL
*"      POCOND STRUCTURE  BAPIMEPOCOND OPTIONAL
*"      POLIMITS STRUCTURE  BAPIESUHC OPTIONAL
*"      POCONTRACTLIMITS STRUCTURE  BAPIESUCC OPTIONAL
*"      POSERVICES STRUCTURE  BAPIESLLC OPTIONAL
*"      POSRVACCESSVALUES STRUCTURE  BAPIESKLC OPTIONAL
*"      POTEXTHEADER STRUCTURE  BAPIMEPOTEXTHEADER OPTIONAL
*"      POTEXTITEM STRUCTURE  BAPIMEPOTEXT OPTIONAL
*"      POEXPIMPITEM STRUCTURE  BAPIEIPO OPTIONAL
*"      POCOMPONENTS STRUCTURE  BAPIMEPOCOMPONENT OPTIONAL
*"      POSHIPPINGEXP STRUCTURE  BAPIMEPOSHIPPEXP OPTIONAL
*"      POHISTORY STRUCTURE  BAPIEKBE OPTIONAL
*"      POHISTORY_TOTALS STRUCTURE  BAPIEKBES OPTIONAL
*"      POCONFIRMATION STRUCTURE  BAPIEKES OPTIONAL
*"      ALLVERSIONS STRUCTURE  BAPIMEDCM_ALLVERSIONS OPTIONAL
*"      POPARTNER STRUCTURE  BAPIEKKOP OPTIONAL
*"      EXTENSIONOUT STRUCTURE  BAPIPAREX OPTIONAL
*"      SERIALNUMBER STRUCTURE  BAPIMEPOSERIALNO OPTIONAL
*"      INVPLANHEADER STRUCTURE  BAPI_INVOICE_PLAN_HEADER OPTIONAL
*"      INVPLANITEM STRUCTURE  BAPI_INVOICE_PLAN_ITEM OPTIONAL
*"      POHISTORY_MA STRUCTURE  BAPIEKBE_MA OPTIONAL
*"----------------------------------------------------------------------
  DATA:poheader1   TYPE bapimepoheader,
       poitem1     TYPE TABLE OF bapimepoitem,
       ls_poitem   TYPE zsmm067,
       lv_menge    TYPE eket-menge,
       lv_wemng    TYPE eket-wemng,
       lv_lifnr    TYPE lfa1-lifnr,
       lv_lifnr_in TYPE lfa1-lifnr,
       lv_print(2),
       lv_ms(10),
       lv_prlab    TYPE labst,
       lv_key(70).

  DATA:lt_lines     TYPE TABLE OF tline,
       lv_id        TYPE thead-tdid VALUE 'F01',
       lv_object    TYPE thead-tdobject VALUE 'EKKO',
       lv_name      TYPE thead-tdname,
       lv_text(132).

  DATA:lt_lines1     TYPE TABLE OF tline,
       lv_id1        TYPE thead-tdid VALUE 'F06',
       lv_object1    TYPE thead-tdobject VALUE 'EKPO',
       lv_name1      TYPE thead-tdname,
       lv_text1(132).

  CALL FUNCTION 'BAPI_PO_GETDETAIL1'
    EXPORTING
      purchaseorder      = purchaseorder
      account_assignment = account_assignment
      item_text          = item_text
      header_text        = header_text
      delivery_address   = delivery_address
      version            = version
      services           = services
      serialnumbers      = serialnumbers
      invoiceplan        = invoiceplan
    IMPORTING
      poheader           = poheader1
      poexpimpheader     = poexpimpheader
    TABLES
      return             = return
      poitem             = poitem1
      poaddrdelivery     = poaddrdelivery
      poschedule         = poschedule
      poaccount          = poaccount
      pocondheader       = pocondheader
      pocond             = pocond
      polimits           = polimits
      pocontractlimits   = pocontractlimits
      poservices         = poservices
      posrvaccessvalues  = posrvaccessvalues
      potextheader       = potextheader
      potextitem         = potextitem
      poexpimpitem       = poexpimpitem
      pocomponents       = pocomponents
      poshippingexp      = poshippingexp
      pohistory          = pohistory
      pohistory_totals   = pohistory_totals
      poconfirmation     = poconfirmation
      allversions        = allversions
      popartner          = popartner
      extensionout       = extensionout
      serialnumber       = serialnumber
      invplanheader      = invplanheader
      invplanitem        = invplanitem
      pohistory_ma       = pohistory_ma.

  LOOP AT return TRANSPORTING NO FIELDS WHERE type CA 'AEX'.
  ENDLOOP.

  IF sy-subrc NE 0.

    MOVE-CORRESPONDING poheader1 TO poheader.
    "供應商助記碼
    SELECT SINGLE bu_sort1
      FROM but000
     WHERE partner = @poheader1-vendor
      INTO @poheader-bu_sort1.
    DATA:lv_comp_code TYPE but000-partner.
    lv_comp_code = poheader1-comp_code.
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = lv_comp_code
      IMPORTING
        output = lv_comp_code.
    "公司程式碼助記碼
    SELECT SINGLE bu_sort1
      FROM but000
     WHERE partner = @lv_comp_code
      INTO @poheader-company_sotr1.

    "傳送OA狀態,列印模板CODE
*    SELECT SINGLE markoa
*      FROM ekko
*     WHERE ebeln = @purchaseorder
*      INTO @poheader-markoa.
    SELECT SINGLE markoa,zprint,zzoarequest_id
      FROM ekko
     WHERE ebeln = @purchaseorder
      INTO ( @poheader-markoa,@poheader-zprint,@poheader-zzoarequest_id ).
    "取域描述
    SELECT SINGLE
           ddtext
      FROM dd07t
      INTO poheader-zprint_text
     WHERE domname = 'ZDM_PRINT'
       AND ddlanguage = sy-langu
       AND domvalue_l = poheader-zprint.

    "公司名稱
    SELECT SINGLE butxt
      FROM t001
     WHERE bukrs = @poheader1-comp_code
       AND spras = @sy-langu
      INTO @poheader-butxt.
    "採購組工號
    SELECT SINGLE tel_number
      FROM t024
     WHERE ekgrp = @poheader1-pur_group
      INTO @poheader-zcgzgh.
    "付款條件描述
    SELECT SINGLE zfktjms
      FROM ekko
     WHERE ebeln = @poheader1-po_number
      INTO @poheader-zfktjms.
    "供應商名稱
    SELECT SINGLE name1
      FROM lfa1
     WHERE lifnr = @poheader1-vendor
       AND spras = @sy-langu
      INTO @poheader-zbmmc.

    "抬頭文字
    lv_name = purchaseorder.
    CALL FUNCTION 'READ_TEXT'
      EXPORTING
        client                  = sy-mandt
        id                      = lv_id
        language                = sy-langu
        name                    = lv_name
        object                  = lv_object
      TABLES
        lines                   = lt_lines
      EXCEPTIONS
        id                      = 1
        language                = 2
        name                    = 3
        not_found               = 4
        object                  = 5
        reference_check         = 6
        wrong_access_to_archive = 7
        OTHERS                  = 8.
    IF sy-subrc EQ 0.
      CLEAR:lv_text.
      LOOP AT lt_lines INTO DATA(ls_lines).
        lv_text = lv_text && ls_lines-tdline.
        CLEAR:ls_lines.
      ENDLOOP.
    ENDIF.

    poheader-headertext = lv_text.

    "行專案計劃數量
    SELECT ebeln,ebelp,etenr,menge,wemng
      FROM eket
     WHERE ebeln = @purchaseorder
      INTO TABLE @DATA(lt_eket).
    SORT lt_eket BY ebeln ebelp etenr.

    "根據WBS元素取專案編碼
    SELECT ebeln,ebelp,ps_psp_pnr,b~posid
      FROM ekkn AS a
      LEFT JOIN prps AS b
        ON a~ps_psp_pnr = b~pspnr
     WHERE ebeln = @purchaseorder
      INTO TABLE @DATA(lt_ekkn).
    SORT lt_ekkn BY ebeln ebelp.

    "行專案增強欄位
    SELECT a~ebeln,a~ebelp,a~matnr,a~zdepart,a~zmatnr_w,a~zebeln,a~zebelp,b~groes,b~gdescribe,c~maktx,d~name1 AS zgcmc,b~f_wb_cgfzr,
           e~bstmi,e~bstrf,e~plifz
      FROM ekpo AS a
      LEFT JOIN mara AS b ON a~matnr = b~matnr
      LEFT JOIN marc AS e ON a~matnr = e~matnr AND a~werks = e~werks
      LEFT JOIN makt AS c ON a~matnr = c~matnr AND c~spras = @sy-langu
      LEFT JOIN t001w AS d ON a~werks = d~werks AND d~spras = @sy-langu
     WHERE a~ebeln = @purchaseorder
      INTO TABLE @DATA(lt_ekpo).
    SORT lt_ekpo BY ebeln ebelp.

    "行專案物料未清數量
    WITH +i AS ( SELECT DISTINCT matnr FROM @lt_ekpo AS k )
    SELECT i~matnr,SUM( b~menge - b~wemng ) AS zwqsl_sum
      FROM +i AS i
      JOIN ekpo AS a
        ON i~matnr = a~matnr
      JOIN ekko AS c
        ON a~ebeln = c~ebeln
      JOIN eket AS b
        ON a~ebeln = b~ebeln
       AND a~ebelp = b~ebelp
      JOIN ztmm0028 AS d
        ON c~bukrs = d~bukrs
       AND c~ekorg = d~ekorg
       AND a~werks = d~werks
       AND a~lgort = d~lgort
     WHERE a~loekz NE 'L'
       AND c~bsart IN ( 'NB','FNB','LXCG','GDZC','GXWX','ZNBS' )
       AND c~frgzu = 'XX'
     GROUP BY i~matnr
      INTO TABLE @DATA(lt_matnr).
    SORT lt_matnr BY matnr.

    "節點庫存:普通庫存
    WITH +i AS ( SELECT DISTINCT matnr FROM @lt_ekpo AS k )
     SELECT i~matnr,SUM( a~labst ) AS zlabst
       FROM +i AS i
       JOIN mard AS a
         ON i~matnr = a~matnr
       JOIN ztmm0030 AS c
         ON a~werks = c~werks
        AND a~lgort = c~lgort
      GROUP BY i~matnr
       INTO TABLE @DATA(lt_labst).
    SORT lt_labst BY matnr.

    "節點庫存:專案庫存
    WITH +i AS ( SELECT DISTINCT matnr FROM @lt_ekpo AS k )
     SELECT i~matnr,SUM( a~prlab ) AS prlab
       FROM +i AS i
       JOIN mspr AS a
         ON i~matnr = a~matnr
       JOIN ztmm0030 AS c
         ON a~werks = c~werks
        AND a~lgort = c~lgort
      GROUP BY i~matnr
       INTO TABLE @DATA(lt_mspr).
    SORT lt_mspr BY matnr.

    "取正常物料的日期段
    SELECT a~matnr,a~werks,b~datab,b~datbi
      FROM ekpo AS a
      JOIN a017 AS b
        ON a~matnr = b~matnr
       AND a~werks = b~werks
     WHERE a~ebeln = @poheader-po_number
       AND b~lifnr = @poheader-vendor
       AND b~ekorg = @poheader-purch_org
       AND b~kappl = 'M'
       AND b~kschl = 'PB00'
       AND b~esokz = '0'
*       AND b~datbi GE @poheader-doc_date
*       AND b~datab LE @poheader-doc_date
       AND a~matkl NE '600000'
      INTO TABLE @DATA(lt_a017).
    SORT lt_a017 BY werks matnr.

    "取工序外協的日期段
    SELECT a~txz01,a~werks,b~datab,b~datbi
      FROM ekpo AS a
      JOIN a025 AS b
        ON a~werks = b~werks
       AND a~infnr = b~infnr
     WHERE a~ebeln = @poheader-po_number
       AND b~lifnr = @poheader-vendor
       AND b~ekorg = @poheader-purch_org
       AND b~kappl = 'M'
       AND b~kschl = 'PB00'
       AND b~esokz = '0'
       AND a~matkl = '600000'
      INTO TABLE @DATA(lt_a025).
    SORT lt_a025 BY werks txz01.

    "取採購訂單行專案條件型別
    SELECT a~ebeln,b~ebelp,c~kschl
      FROM ekko AS a
      JOIN ekpo AS b
        ON a~ebeln = b~ebeln
      JOIN prcd_elements AS c
        ON a~knumv = c~knumv
       AND b~ebelp = substring( c~kposn,2,5 )
     WHERE c~kschl = 'PBXX'
       AND c~kinak = ''
       AND a~ebeln = @purchaseorder
      INTO TABLE @DATA(lt_prcd).
    SORT lt_prcd BY ebeln ebelp.

    "取採購訂單更改記錄
    SELECT a~objectclas,a~objectid,a~changenr,a~udate,b~tabkey,b~fname,b~chngind
      FROM cdhdr AS a
      JOIN cdpos AS b
        ON a~objectclas = b~objectclas
       AND a~objectid = b~objectid
       AND a~changenr = b~changenr
     WHERE a~objectid = @purchaseorder
       AND b~fname IN ('KEY','NETPR')
       AND b~tabname = 'EKPO'
      INTO TABLE @DATA(lt_cdhdr).
    SORT lt_cdhdr BY objectclas objectid tabkey udate DESCENDING.

    LOOP AT poitem1[] INTO DATA(ls_poitem1).
      MOVE-CORRESPONDING ls_poitem1 TO ls_poitem.

      "專案類別轉換
      IF ls_poitem1-item_cat IS NOT INITIAL.
        SELECT SINGLE epstp
          FROM t163y
         WHERE pstyp = @ls_poitem1-item_cat
           AND spras = @sy-langu
          INTO @ls_poitem-item_cat.
      ENDIF.

      "物料需求計劃文字
      lv_name1 = purchaseorder && ls_poitem-po_item.
      CALL FUNCTION 'READ_TEXT'
        EXPORTING
          client                  = sy-mandt
          id                      = lv_id1
          language                = sy-langu
          name                    = lv_name1
          object                  = lv_object1
        TABLES
          lines                   = lt_lines1
        EXCEPTIONS
          id                      = 1
          language                = 2
          name                    = 3
          not_found               = 4
          object                  = 5
          reference_check         = 6
          wrong_access_to_archive = 7
          OTHERS                  = 8.
      IF sy-subrc EQ 0.
        CLEAR:lv_text1.
        LOOP AT lt_lines1 INTO ls_lines.
          lv_text1 = lv_text1 && ls_lines-tdline.
          CLEAR:ls_lines.
        ENDLOOP.
      ENDIF.
      ls_poitem-itemtext = lv_text1.

      READ TABLE lt_ekpo INTO DATA(ls_ekpo) WITH KEY ebeln = purchaseorder
                                                     ebelp = ls_poitem1-po_item BINARY SEARCH.
      IF sy-subrc EQ 0.
        MOVE-CORRESPONDING ls_ekpo TO ls_poitem.
      ENDIF.

      READ TABLE lt_ekkn INTO DATA(ls_ekkn) WITH KEY ebeln = purchaseorder
                                                     ebelp = ls_poitem1-po_item BINARY SEARCH.
      IF sy-subrc EQ 0.
        SELECT SINGLE zzxmbm
          FROM ztps001
         WHERE posid = @ls_ekkn-posid(12)
          INTO @ls_poitem-zzxmbm.
      ENDIF.

      LOOP AT lt_eket INTO DATA(ls_eket) WHERE ebeln = purchaseorder AND ebelp = ls_poitem1-po_item.
        "計劃數量
        lv_menge = ls_eket-menge + lv_menge.
        "已收貨數量
        lv_wemng = ls_eket-wemng + lv_wemng.
        CLEAR:ls_eket.
      ENDLOOP.
      ls_poitem-zwemng = lv_wemng.
      ls_poitem-zcgwqsl = lv_menge - lv_wemng.

      "物料未清數量之和
      READ TABLE lt_matnr INTO DATA(ls_matnr) WITH KEY matnr = ls_poitem1-material BINARY SEARCH.
      IF sy-subrc EQ 0.
        ls_poitem-zwqsl_sum = ls_matnr-zwqsl_sum.
      ENDIF.

      "節點庫存普通
      READ TABLE lt_labst INTO DATA(ls_labst) WITH KEY matnr = ls_poitem1-material BINARY SEARCH.
      IF sy-subrc EQ 0.
        ls_poitem-zlabst = ls_labst-zlabst.
      ENDIF.

      "節點專案庫存
      READ TABLE lt_mspr INTO DATA(ls_mspr) WITH KEY matnr = ls_poitem1-material BINARY SEARCH.
      IF sy-subrc EQ 0.
        lv_prlab = ls_mspr-prlab.
      ENDIF.
      "節點庫存全量
      ls_poitem-zjdkc_full = lv_prlab + ls_poitem-zlabst.

      "有效開始日期
      lv_key = sy-mandt && poheader-po_number && ls_poitem1-po_item.
      READ TABLE lt_prcd INTO DATA(ls_prcd) WITH KEY ebelp = ls_poitem1-po_item BINARY SEARCH.
      IF sy-subrc EQ 0.
        "條件型別為PBXX,為手動輸入價格,首先看訂單有沒有修改NETPR淨價,有則取此修改日期
        READ TABLE lt_cdhdr INTO DATA(ls_cdhdr) WITH KEY tabkey = lv_key fname = 'NETPR' chngind = 'U'.
        IF sy-subrc EQ 0.
          ls_poitem-datab = ls_cdhdr-udate.
        ELSE.
          "沒有修改NETPR淨價,則看其是不是新增行專案
          READ TABLE lt_cdhdr INTO ls_cdhdr WITH KEY tabkey = lv_key fname = 'KEY' chngind = 'I'.
          IF sy-subrc EQ 0.
            ls_poitem-datab = ls_cdhdr-udate.
          ELSE.
            "如果不是新增行專案,則取憑證日期
            ls_poitem-datab = poheader-doc_date.
          ENDIF.
        ENDIF.
      ELSE.
        "條件型別為PB00,是取資訊記錄價格,首先看訂單有無修改淨價,有則取此修改日期對應的資訊記錄的有效開始日期
        READ TABLE lt_cdhdr INTO ls_cdhdr WITH KEY tabkey = lv_key fname = 'NETPR' chngind = 'U'.
        IF sy-subrc EQ 0.
          ls_poitem-datab = ls_cdhdr-udate.
        ELSE.
          "如果沒有修改淨價,則看其是不是新增行專案
          READ TABLE lt_cdhdr INTO ls_cdhdr WITH KEY tabkey = lv_key fname = 'KEY' chngind = 'I'.
          IF sy-subrc EQ 0.
            IF ls_poitem1-matl_group NE '600000'."正常物料
              LOOP AT lt_a017 INTO DATA(ls_a017) WHERE matnr = ls_poitem1-material
                                                   AND werks = ls_poitem1-plant
                                                   AND datab LE ls_cdhdr-udate
                                                   AND datbi GE ls_cdhdr-udate.
                ls_poitem-datab = ls_a017-datab.
              ENDLOOP.
            ELSE.
              "工序外協
              LOOP AT lt_a025 INTO DATA(ls_a025) WHERE txz01 = ls_poitem1-short_text
                                                   AND werks = ls_poitem1-plant
                                                   AND datab LE ls_cdhdr-udate
                                                   AND datbi GE ls_cdhdr-udate.
                ls_poitem-datab = ls_a025-datab.
              ENDLOOP.
            ENDIF.
          ELSE.
            "如果沒有修改價格,並且不是新增行專案,則取憑證日期對應的資訊記錄的有效開始日期
            IF ls_poitem1-matl_group NE '600000'."正常物料
              LOOP AT lt_a017 INTO ls_a017 WHERE matnr = ls_poitem1-material
                                              AND werks = ls_poitem1-plant
                                              AND datab LE poheader-doc_date
                                              AND datbi GE poheader-doc_date.
                ls_poitem-datab = ls_a017-datab.
              ENDLOOP.
            ELSE.
              "工序外協
              LOOP AT lt_a025 INTO ls_a025 WHERE txz01 = ls_poitem1-short_text
                                             AND werks = ls_poitem1-plant
                                             AND datab LE poheader-doc_date
                                             AND datbi GE poheader-doc_date.
                ls_poitem-datab = ls_a025-datab.
              ENDLOOP.
            ENDIF.
          ENDIF.
        ENDIF.
      ENDIF.
      APPEND ls_poitem TO poitem[].
      CLEAR:ls_poitem1,ls_poitem,lv_menge,lv_wemng,ls_matnr,ls_labst,ls_mspr,lv_prlab,
            ls_a017,ls_a025,ls_cdhdr,ls_prcd.
    ENDLOOP.
  ENDIF.
ENDFUNCTION.

相關文章