SAP-SD交货运输单

  1. 程序说明
    1. 程序说明

对条码系统发货装车产生的运输单, 执行运费维护, 发货过账和审批转费用采购订单功能, 以及打印功能.  发货过账前需要对交货单做批次确认, 对与启用条码管理的仓库或物料, 以条码的批次为准, 否则以销售订单库存里的批次为准.

(1)	取得运输单数据:
ZTYSK: 运输单抬头数据
ZTYSP: 运输单项目数据
ZTYSD: 运输单项目的批次数据
编辑运输单后, 执行锁定该运输单
  SELECT SINGLE *
  FROM ZTYSK
  WHERE ZEYSO = P_ZEYSO.
  IF SY-SUBRC NE 0.
    MESSAGE S001(00) WITH '运输单不存在' DISPLAY LIKE 'E'.
    STOP.
  ENDIF.
  IF ZTYSK-EBELN NE '' OR ZTYSK-KZERM = ''.
    G_MOD2 = 'A'.
  ELSE.
    G_MOD2 = 'U'.
  ENDIF.
  IF G_MOD1 = 'U'.
    PERFORM FRM_LOCK_DATA USING P_ZEYSO CHANGING G_LOCK G_UNAM.
    IF G_LOCK = 'X'.
      MESSAGE S001(00) WITH P_ZEYSO '的处理被用户' G_UNAM '锁定' DISPLAY LIKE 'E'.
      STOP.
    ENDIF.
  ENDIF.
  SELECT SINGLE WAERS INTO L_ZZWAE FROM TVKO WHERE VKORG = ZTYSK-VKORG.
  SELECT *
  INTO TABLE ITAB
  FROM ZTYSP
  WHERE ZEYSO = P_ZEYSO.
(2)	输出屏幕2000
根据事务码和权限以及运输单状态确定哪些功能生效
运输单有如下状态:
确定状态: ZTYSK-KZERM, ‘X’/’’, X为已最终确认, 只有确认的运输单才能维护运费及后续操作;
过账状态: ZTYSK-LFGSK, ‘’/’B’/’C’, B为运输单中部分交货单已过账, C为完全过账, 在运输单过账前后均能维护运费;
审批状态: ZTYSK-ZEYST, ‘A’/’B’/’C/, 维护完运费后修改审批状态值为A 提交待审批, 流转到审批人员后, 审批不通过则直接修改为B审批拒绝, 审批通过则直接直接转采购订单, 成功后该审批状态自动修改为C审批完成. 
审批完成后, 不允许再对运输单维护运费.
  REFRESH FCOD.
  IF ZTYSK-KZERM = '' OR G_MOD1 = 'A' OR ZTYSK-EBELN NE '' OR ZTYSK-EBEL1 NE '' OR
    ZTYSK-EBEL2 NE '' OR ZTYSK-EBEL3 NE ''.
    FCOD-FCODE = 'POST'.
    APPEND FCOD.
    FCOD-FCODE = 'TOPO'.
    APPEND FCOD.
    FCOD-FCODE = 'SAVE'.
    APPEND FCOD.
    FCOD-FCODE = 'CANC'.
    APPEND FCOD.
  ELSE.
    IF ZTYSK-LFGSK NE ''.
      FCOD-FCODE = 'CANC'.
      APPEND FCOD.
      IF ZTYSK-LFGSK = 'C'.
        FCOD-FCODE = 'POST'.
        APPEND FCOD.
        IF ZTYSK-ZEYST NE 'A'.
          FCOD-FCODE = 'TOPO'.
          APPEND FCOD.
        ENDIF.
      ELSE.
        FCOD-FCODE = 'TOPO'.
        APPEND FCOD.
      ENDIF.
    ELSE.
      FCOD-FCODE = 'TOPO'.
      APPEND FCOD.
    ENDIF.
  ENDIF.
  IF ZTYSK-KZERM = 'X' AND G_MOD1 NE 'A' AND ZTYSK-LFGSK = 'C' AND ZTYSK-ZEYST = 'A'.
    IF ( ZTYSK-EBELN = '' AND ZTYSK-TOTA1 > 0 ) OR
       ( ZTYSK-EBEL1 = '' AND ZTYSK-TOTA2 > 0 ) OR
       ( ZTYSK-EBEL2 = '' AND ZTYSK-TOTA3 > 0 ) OR
       ( ZTYSK-EBEL3 = '' AND ZTYSK-TOTA5 > 0 ).
      DELETE FCOD WHERE FCODE = 'TOPO'.
    ENDIF.
  ENDIF.

  FCOD-FCODE = 'UPDE'.
  APPEND FCOD.
  IF G_MOD1 = 'U'.
    IF ( ZTYSK-EBELN = '' AND ZTYSK-TOTA1 > 0 ) OR
       ( ZTYSK-EBEL1 = '' AND ZTYSK-TOTA2 > 0 ) OR
       ( ZTYSK-EBEL2 = '' AND ZTYSK-TOTA3 > 0 ) OR
       ( ZTYSK-EBEL3 = '' AND ZTYSK-TOTA5 > 0 ).
    ELSE.
      LOOP AT ZTAB WHERE UPDAT = '' AND YSRAT > 0.
        EXIT.
      ENDLOOP.
      IF SY-SUBRC = 0.
        DELETE FCOD WHERE FCODE = 'UPDE'.
      ENDIF.
    ENDIF.
  ENDIF.

  IF G_MOD1 = 'U'.
    AUTHORITY-CHECK OBJECT 'ZSD_TRANSP'
             ID 'ACTVT' FIELD '02'.
    IF SY-SUBRC NE 0.
      READ TABLE FCOD WITH KEY FCODE = 'UPDE'.
      IF SY-SUBRC NE 0.
        FCOD-FCODE = 'UPDE'.
        APPEND FCOD.
      ENDIF.
      READ TABLE FCOD WITH KEY FCODE = 'TOPO'.
      IF SY-SUBRC NE 0.
        FCOD-FCODE = 'TOPO'.
        APPEND FCOD.
      ENDIF.
    ENDIF.
  ENDIF.

(3)	运输单保存功能
TMP1,TMP2为临时内表, 仅用来比较数据以判断数据是否有修改.
  MODIFY ZTYSK FROM ZTYSK.
  IF SY-SUBRC = 0.
    MODIFY ZTYSP FROM TABLE LTP.
    IF SY-SUBRC = 0.
      COMMIT WORK AND WAIT.
      IF PR_TYPE = 'X'.
        MESSAGE S001(00) WITH '运输单' ZTYSK-ZEYSO '已保存'.
      ENDIF.
      TMP1 = ZTYSK.
      REFRESH TMP2.
      TMP2[] = ZTAB[].

(4)	执行过账功能
过账前要求联系人或电话必须输入.
ZTYSP-WABUC为项目级别的过账标识, 为空则表示为过账.
取到这些未过账的交货单到内表DEL.
读取交货单的过账状态WBSTK, 如果已用标准事务过账, 则这里提示先前已记账处理, 不需要再次记账, 只需要更新项目级别的过账标识.
  LOOP AT ZTAB WHERE WABUC = ''.
    DEL-VBELN = ZTAB-VBELN.
    COLLECT DEL.
  ENDLOOP.

  DATA L_WBSTK LIKE VBUK-WBSTK.
  LOOP AT DEL.
    CLEAR L_WBSTK.
    SELECT SINGLE WBSTK
    INTO L_WBSTK
    FROM VBUK WHERE VBELN = DEL-VBELN.
    IF L_WBSTK = 'C'.
      IT_ESP-LINENO = DEL-VBELN.
      IT_ESP-MSGTY = 'W'.
      IT_ESP-MSGID = '00'.
      IT_ESP-MSGNO = '001'.
      IT_ESP-MSGV1 = '交货单'.
      IT_ESP-MSGV2 = DEL-VBELN.
      IT_ESP-MSGV3 = '先前已做记账处理'.
      IT_ESP-MSGV4 = ''.
      APPEND IT_ESP.
      PERFORM FRM_UPDATE_DATA ON COMMIT.
      COMMIT WORK AND WAIT.
      CONTINUE.
    ENDIF.

对于需要记账的交货单, 先要做批次拆分和库位确认过程.
ZTYSK-BATCH用来标记交货行项目是否有成功做过批次拆分和库位确认.
从运输单项目ZTAB中取得当前交货单且BATCH为空的项目, 从ZTYSD中取得该项目的批次, 新增9000*项目编号的批次项目, 项目中其他字段值从主项目LIPS带出.
交货单的确认库位从运输单项目ZTAB复制过去.
如果ZTYSD没有对应项目的批次数据, 则直接从订单批次库存MSKA取到批次数据,
按批次库存的数量来满足交货单数据, 以此确定批次号.
批次拆分后交货项目还有剩余的数量, 则剩余的数量保留在主项目中.
      SELECT SINGLE * INTO LS_LIPS FROM LIPS WHERE VBELN = ZTAB-VBELN AND POSNR = ZTAB-POSNR.
      L_LFIMG = LS_LIPS-LFIMG.
      LOOP AT YSD WHERE ZITEM = ZTAB-ZITEM AND CHARG NE ''.
        LS_LIPS-LFIMG = LS_LIPS-LFIMG - YSD-LFIMG.
        POSNR = POSNR + 1.
        ITEM-DELIV_NUMB = ZTAB-VBELN.
        ITEM-DELIV_ITEM = POSNR.
        ITEM-DLV_QTY = YSD-LFIMG.
        ITEM-HIERARITEM = ZTAB-POSNR.
        ITEM-BATCH = YSD-CHARG.
        ITEM-MATERIAL = ZTAB-MATNR.
        ITEM-USEHIERITM = '1'.
        ITEM-SALES_UNIT = LS_LIPS-VRKME.
        ITEM-BASE_UOM = LS_LIPS-MEINS.
        ITEM-DLV_QTY_IMUNIT = YSD-LFIMG.
        ITEM-FACT_UNIT_NOM = 1.
        ITEM-FACT_UNIT_DENOM = 1.
        APPEND ITEM.
        CLEAR ITEM.
        ITEMC-DELIV_NUMB = ZTAB-VBELN.
        ITEMC-DELIV_ITEM = POSNR.
        ITEMC-CHG_DELQTY = 'X'.
        APPEND ITEMC.
        CLEAR ITEMC.
        SPL-DELIV_NUMB = ZTAB-VBELN.
        SPL-DELIV_ITEM = ZTAB-POSNR.
        SPL-STGE_LOC = ZTAB-LGORT.
        APPEND SPL.
        CLEAR SPL.
      ENDLOOP.
      IF SY-SUBRC NE 0.
        CLEAR L_XCHPF.
        REFRESH LT_MSKA.
        SELECT SINGLE XCHPF INTO L_XCHPF FROM MARC WHERE WERKS = LS_LIPS-WERKS AND MATNR = LS_LIPS-MATNR.
        IF L_XCHPF = 'X'.
          SELECT *
          INTO TABLE LT_MSKA
          FROM MSKA
          WHERE MATNR = LS_LIPS-MATNR
            AND WERKS = LS_LIPS-WERKS
            AND LGORT = ZTAB-LGORT
            AND VBELN = LS_LIPS-VGBEL
            AND POSNR = LS_LIPS-VGPOS
            AND KALAB > 0.
          L_MENGE = LS_LIPS-LFIMG.
          LOOP AT LT_MSKA.
            L_MENGE = L_MENGE - LT_MSKA-KALAB.
            IF L_MENGE > 0.
              LS_LIPS-LFIMG = LS_LIPS-LFIMG - LT_MSKA-KALAB.
              POSNR = POSNR + 1.
              ITEM-DELIV_NUMB = ZTAB-VBELN.
              ITEM-DELIV_ITEM = POSNR.
              ITEM-DLV_QTY = LT_MSKA-KALAB.
              ITEM-HIERARITEM = ZTAB-POSNR.
              ITEM-BATCH = LT_MSKA-CHARG.
              ITEM-MATERIAL = ZTAB-MATNR.
              ITEM-USEHIERITM = '1'.
              ITEM-SALES_UNIT = LS_LIPS-VRKME.
              ITEM-BASE_UOM = LS_LIPS-MEINS.
              ITEM-DLV_QTY_IMUNIT = LT_MSKA-KALAB.
              ITEM-FACT_UNIT_NOM = 1.
              ITEM-FACT_UNIT_DENOM = 1.
              APPEND ITEM.
              CLEAR ITEM.
              ITEMC-DELIV_NUMB = ZTAB-VBELN.
              ITEMC-DELIV_ITEM = POSNR.
              ITEMC-CHG_DELQTY = 'X'.
              APPEND ITEMC.
              CLEAR ITEMC.
              SPL-DELIV_NUMB = ZTAB-VBELN.
              SPL-DELIV_ITEM = ZTAB-POSNR.
              SPL-STGE_LOC = ZTAB-LGORT.
              APPEND SPL.
              CLEAR SPL.
            ELSE.
              L_MENGE = L_MENGE + LT_MSKA-KALAB.
              LS_LIPS-LFIMG = LS_LIPS-LFIMG - L_MENGE.
              POSNR = POSNR + 1.
              ITEM-DELIV_NUMB = ZTAB-VBELN.
              ITEM-DELIV_ITEM = POSNR.
              ITEM-DLV_QTY = L_MENGE.
              ITEM-HIERARITEM = ZTAB-POSNR.
              ITEM-BATCH = LT_MSKA-CHARG.
              ITEM-MATERIAL = ZTAB-MATNR.
              ITEM-USEHIERITM = '1'.
              ITEM-SALES_UNIT = LS_LIPS-VRKME.
              ITEM-BASE_UOM = LS_LIPS-MEINS.
              ITEM-DLV_QTY_IMUNIT = L_MENGE.
              ITEM-FACT_UNIT_NOM = 1.
              ITEM-FACT_UNIT_DENOM = 1.
              APPEND ITEM.
              CLEAR ITEM.
              ITEMC-DELIV_NUMB = ZTAB-VBELN.
              ITEMC-DELIV_ITEM = POSNR.
              ITEMC-CHG_DELQTY = 'X'.
              APPEND ITEMC.
              CLEAR ITEMC.
              SPL-DELIV_NUMB = ZTAB-VBELN.
              SPL-DELIV_ITEM = ZTAB-POSNR.
              SPL-STGE_LOC = ZTAB-LGORT.
              APPEND SPL.
              CLEAR SPL.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.
      ENDIF.
*      IF SY-SUBRC = 0.
      ITEM-DELIV_NUMB = ZTAB-VBELN.
      ITEM-DELIV_ITEM = ZTAB-POSNR.
      ITEM-MATERIAL = ZTAB-MATNR.
      ITEM-DLV_QTY = LS_LIPS-LFIMG.
      ITEM-DLV_QTY_IMUNIT = LS_LIPS-LFIMG.
      ITEM-SALES_UNIT = LS_LIPS-VRKME.
      ITEM-BASE_UOM = LS_LIPS-MEINS.
      ITEM-FACT_UNIT_NOM = 1.
      ITEM-FACT_UNIT_DENOM = 1.
*        ITEM-USEHIERITM = '1'.
      APPEND ITEM.
      CLEAR ITEM.
      ITEMC-DELIV_NUMB = ZTAB-VBELN.
      ITEMC-DELIV_ITEM = ZTAB-POSNR.
      ITEMC-CHG_DELQTY = 'X'.
      APPEND ITEMC.
      CLEAR ITEMC.
      SPL-DELIV_NUMB = ZTAB-VBELN.
      SPL-DELIV_ITEM = ZTAB-POSNR.
      SPL-STGE_LOC = ZTAB-LGORT.
      APPEND SPL.
      CLEAR SPL.
调用BAPI: BAPI_OUTB_DELIVERY_CHANGE修改交货单
修改成功后, 更新ZTYSP-BATCH = ‘X’.
      "需要更改交货,增加批次
      HEAD-DELIV_NUMB  = DEL-VBELN.
      TECHC-UPD_IND    = 'U'.
      HEADC-DELIV_NUMB = DEL-VBELN.
      CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'
        EXPORTING
          HEADER_DATA    = HEAD
          HEADER_CONTROL = HEADC
          TECHN_CONTROL  = TECHC
          DELIVERY       = DEL-VBELN
        TABLES
          ITEM_DATA      = ITEM
          ITEM_CONTROL   = ITEMC
          ITEM_DATA_SPL  = SPL
          RETURN         = RETURN.
      LOOP AT RETURN WHERE TYPE = 'E'.
        IT_ESP-LINENO = DEL-VBELN.
        IT_ESP-MSGID = RETURN-ID.
        IT_ESP-MSGTY = RETURN-TYPE.
        IT_ESP-MSGNO = RETURN-NUMBER.
        IT_ESP-MSGV1 = RETURN-MESSAGE_V1.
        IT_ESP-MSGV2 = RETURN-MESSAGE_V2.
        IT_ESP-MSGV3 = RETURN-MESSAGE_V3.
        IT_ESP-MSGV4 = RETURN-MESSAGE_V4.
        APPEND IT_ESP.
      ENDLOOP.
      IF SY-SUBRC NE 0.
        PERFORM FRM_UPDATE_DATA_A ON COMMIT.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            WAIT = 'X'.
        LOOP AT ZTAB WHERE VBELN = DEL-VBELN.
          ZTAB-BATCH = 'X'.
          MODIFY ZTAB TRANSPORTING BATCH.
        ENDLOOP.
修改交货成功后, 执行交货单过账
调用函数WS_DELIVERY_UPDATE
过账成功,或以用标准事务过账,则更新ZTYSP-WABUC = ‘X’
同时还要更新电池条码和托条码为07出货状态
        CALL FUNCTION 'WS_DELIVERY_UPDATE'
          EXPORTING
            VBKOK_WA                  = VBKOK_WA
            DELIVERY                  = DEL-VBELN
            UPDATE_PICKING            = 'X'
            COMMIT                    = ''
          IMPORTING
            EF_ERROR_ANY_0            = EF_ERROR_ANY_0
            EF_ERROR_IN_GOODS_ISSUE_0 = EF_ERROR_GI
          TABLES
            VBPOK_TAB                 = VBPOK
            PROT                      = I_PROT.
        IF EF_ERROR_GI = 'X'.
          "过账失败
          READ TABLE I_PROT WITH KEY MSGID = 'VL' MSGNO = '602'.
          IF SY-SUBRC = 0.
            "发货单已被记账, 更新过账状态
            IT_ESP-LINENO = DEL-VBELN.
            IT_ESP-MSGTY = 'W'.
            IT_ESP-MSGID = '00'.
            IT_ESP-MSGNO = '001'.
            IT_ESP-MSGV1 = '交货单'.
            IT_ESP-MSGV2 = DEL-VBELN.
            IT_ESP-MSGV3 = '先前已做记账处理'.
            IT_ESP-MSGV4 = ''.
            APPEND IT_ESP.
            PERFORM FRM_UPDATE_DATA ON COMMIT.
            CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
              EXPORTING
                WAIT = 'X'.
            L_F1 = 'X'.
          ELSE.
            CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
            LOOP AT I_PROT WHERE MSGTY = 'E'.
              IT_ESP-LINENO = DEL-VBELN.
              IT_ESP-MSGTY = I_PROT-MSGTY.
              IT_ESP-MSGID = I_PROT-MSGID.
              IT_ESP-MSGNO = I_PROT-MSGNO.
              IT_ESP-MSGV1 = I_PROT-MSGV1.
              IT_ESP-MSGV2 = I_PROT-MSGV2.
              IT_ESP-MSGV3 = I_PROT-MSGV3.
              IT_ESP-MSGV4 = I_PROT-MSGV4.
              APPEND IT_ESP.
            ENDLOOP.
            L_F2 = 'X'.
          ENDIF.
        ELSE.
          "过账成功
          PERFORM FRM_UPDATE_DATA ON COMMIT.
          CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
            EXPORTING
              WAIT = 'X'.
          L_F1 = 'X'.
        ENDIF.
FORM FRM_UPDATE_DATA .
  UPDATE ZTYSP SET WABUC = 'X' WHERE VBELN = DEL-VBELN.
  UPDATE ZTTBC SET ZERFS = '07' WHERE VBELF = DEL-VBELN.
  UPDATE ZTMBC SET ZERFS = '07' WHERE VBELF = DEL-VBELN.
  ZTAB-WABUC = 'X'.
  MODIFY ZTAB TRANSPORTING WABUC WHERE VBELN = DEL-VBELN.
ENDFORM.
对于没有批次更新的交货单, 则直接做记账处理, 过程同上处理
通过所有交货单记账的结果来标记抬头过账状态ZTYSK-LFGSK的值
并保存运输单
  IF L_F1 = '' AND L_F2 = ''.
    ZTYSK-LFGSK = 'C'.
    MESSAGE S001(00) WITH '交货单已全部记账'.
    PERFORM FRM_SAVE_DATA USING ''.
  ELSEIF L_F1 = 'X' AND L_F2 = ''.
    ZTYSK-LFGSK = 'C'.
    MESSAGE S001(00) WITH '交货单已全部记账'.
    PERFORM FRM_SAVE_DATA USING ''.
  ELSEIF L_F1 = '' AND L_F2 = 'X'.
    IF L_F3 = 'X'.
      PERFORM FRM_SAVE_DATA USING ''.
    ENDIF.
    MESSAGE E001(00) WITH '交货单记账失败'.
  ELSE.
    ZTYSK-LFGSK = 'B'.
    MESSAGE S001(00) WITH '交货单已部分记账'.
    PERFORM FRM_SAVE_DATA USING ''.
  ENDIF.

(5)	执行转采购订单功能
转采购订单之前, 检查相关运费和供应商必须输入.
检查配置表ZTVKP中维护了运输单销售组织对应的采购订单必须的组织数据.
将运输单维护了的所有运费信息, 按供应商归集到内表LT_LFA, 装卸费和特殊运费作为单独的采购订单行项目, 相同供应商的运费产生在同一张采购订单上.
海运段运费以输入的货币计入采购订单中, 其余以rmb记录
  IF ZTYSK-EBELN = ''.
    LT_LFA-LIFNR = ZTYSK-LIFNR.
    LT_LFA-EBELP = '00010'.
    LT_LFA-TOTAL = ZTYSK-TOTA1 - ZTYSK-ZXIEF - ZTYSK-TSYSF.
    LT_LFA-WAERK = 'RMB'.
    IF LT_LFA-TOTAL > 0.
      COLLECT LT_LFA.
    ENDIF.
    IF ZTYSK-ZXIEF > 0.
      LT_LFA-LIFNR = ZTYSK-LIFNR.
      LT_LFA-EBELP = '00020'.
      LT_LFA-TOTAL = ZTYSK-ZXIEF.
      LT_LFA-WAERK = 'RMB'.
      COLLECT LT_LFA.
    ENDIF.
    IF ZTYSK-TSYSF > 0.
      LT_LFA-LIFNR = ZTYSK-LIFNR.
      LT_LFA-EBELP = '00030'.
      LT_LFA-TOTAL = ZTYSK-TSYSF.
      LT_LFA-WAERK = 'RMB'.
      COLLECT LT_LFA.
    ENDIF.
  ENDIF.
  IF ZTYSK-TOTA2 > 0 AND ZTYSK-EBEL1 = ''.
    LT_LFA-LIFNR = ZTYSK-LIFN1.
    LT_LFA-EBELP = '00010'.
    LT_LFA-TOTAL = ZTYSK-TOTA2.
    LT_LFA-WAERK = 'RMB'.
    COLLECT LT_LFA.
  ENDIF.
  IF ZTYSK-TOTA3 > 0 AND ZTYSK-EBEL2 = ''.
    LT_LFA-LIFNR = ZTYSK-LIFN2.
    LT_LFA-EBELP = '00010'.
    LT_LFA-TOTAL = ZTYSK-TOTA3.
    LT_LFA-WAERK = ZTYSK-ZZWAE.
    COLLECT LT_LFA.
  ENDIF.
  IF ZTYSK-TOTA5 > 0 AND ZTYSK-EBEL3 = ''.
    LT_LFA-LIFNR = ZTYSK-LIFN3.
    LT_LFA-EBELP = '00010'.
    LT_LFA-TOTAL = ZTYSK-TOTA5.
    LT_LFA-WAERK = 'RMB'.
    COLLECT LT_LFA.
  ENDIF.
针对每个供应商和货币调用BAPI_PO_CREATE1生成采购订单
    AT END OF KEY.
      READ TABLE LT_LFA INDEX L_TABIX.
      CALL FUNCTION 'BAPI_PO_CREATE1'
        EXPORTING
          POHEADER         = POHEADER
          POHEADERX        = POHEADERX
        IMPORTING
          EXPPURCHASEORDER = L_EBELN
        TABLES
          POITEM           = POITEM
          POITEMX          = POITEMX
          POSCHEDULE       = POSCHEDULE
          POSCHEDULEX      = POSCHEDULEX
          POACCOUNT        = POACC
          POACCOUNTX       = POACCX
*         POCOND           = POCOND
*         POCONDX          = POCONDX
          RETURN           = RETURN.
同时将采购订单号更新到运输单ZTYSK上
同时采购订单上也记录当前运输单号
        IF LT_LFA-WAERK NE 'RMB'.
          ZTYSK-EBEL2 = L_EBELN.
        ELSE.
          IF ZTYSK-LIFNR = LT_LFA-LIFNR.
            ZTYSK-EBELN = L_EBELN.
          ENDIF.
          IF ZTYSK-LIFN1 = LT_LFA-LIFNR.
            ZTYSK-EBEL1 = L_EBELN.
          ENDIF.
          IF ZTYSK-LIFN2 = LT_LFA-LIFNR AND ZTYSK-ZZWAE = 'RMB'.
            ZTYSK-EBEL2 = L_EBELN.
          ENDIF.
          IF ZTYSK-LIFN3 = LT_LFA-LIFNR.
            ZTYSK-EBEL3 = L_EBELN.
          ENDIF.
        ENDIF.
        UPDATE EKKO SET ZZYSO = ZTYSK-ZEYSO WHERE EBELN = L_EBELN.
只要有采购订单生成成功, 则需要保存运输单数据.
如果全部采购订单均生成成功, 则还需要将运输单项目中分摊的运费更新累加到交货单对应的销售订单行项目上.
  IF IT_ESP[] IS NOT INITIAL.
    CALL FUNCTION 'C14Z_MESSAGES_SHOW_AS_POPUP'
      TABLES
        I_MESSAGE_TAB = IT_ESP.
    IF L_FLAG_S = 'X'.
      G_MOD2 = 'A'.
      PERFORM FRM_SAVE_DATA USING ''.
    ENDIF.
  ELSE.
    MESSAGE I001(00) WITH '无需转成运费采购订单'.
  ENDIF.
  IF L_FLAG = ''.
    PERFORM FRM_UPDATE_SO USING G_FLAG.
    IF G_FLAG = 'X'.
      PERFORM FRM_SAVE_DATA USING ''.
    ENDIF.
  ENDIF.

(6)	执行更新销售订单运费价格功能
采购订单完全生成后, 会自动执行该功能, 如果执行失败, 则后续可以在菜单上手工点击按钮执行该功能.
ZTYSP-UPDAT标记了没有运输单行项目是否已更新销售订单价格.
首先从运输单项目ZTAB中取得UPDAT为空的销售订单项目和运费.
  LOOP AT ZTAB WHERE UPDAT = ''.
    MOVE-CORRESPONDING ZTAB TO SOP.
    SOP-VGPOS = ZTAB-UEPOS.
    COLLECT SOP.
    CLEAR SOP.
  ENDLOOP.
  IF SY-SUBRC NE 0.
    MESSAGE I001(00) WITH '订单价格已全部更新'.
    RETURN.
  ENDIF.
取得销售当前的价格, 再累加上当前的运费, 作为新的运费, 调用BAPI_SALESORDER_CHANGE更新销售订单
      READ TABLE LT_KONV WITH KEY KNUMV = L_KNUMV KPOSN = SOP-VGPOS KSCHL = 'ZKF1'.
      COND-ITM_NUMBER = SOP-VGPOS.
      COND-COND_ST_NO = LT_KONV-STUNR.
      COND-COND_COUNT = LT_KONV-ZAEHK.
      COND-COND_TYPE = 'ZKF1'.
      COND-COND_VALUE = ( LT_KONV-KWERT + SOP-YSRAT ) / 10.
      APPEND COND.
      CLEAR COND.
      CONDX-ITM_NUMBER = SOP-VGPOS.
      CONDX-COND_ST_NO = LT_KONV-STUNR.
      CONDX-COND_COUNT = LT_KONV-ZAEHK.
      CONDX-COND_TYPE = 'ZKF1'.
      CONDX-COND_VALUE = 'X'.
      CONDX-UPDATEFLAG = 'U'.
      APPEND CONDX.
      CLEAR CONDX.
销售订单更新成功后, 更新运输单项目ZTYSK-UPDAT = ‘X’.
并保存运输单.
        LOOP AT ZTAB WHERE VGBEL = SOP-VGBEL AND UPDAT = ''.
          ZTAB-UPDAT = 'X'.
          MODIFY ZTAB TRANSPORTING UPDAT.
        ENDLOOP.

(7)	运费维护相关处理
模块UPDATE_DATA:
相关运费输入后, 计算合计运费, 并分摊到项目中
该过程中, 海运段运费需要将外币转换为RMB后再汇总.
注意, 调整费用允许输入负值, 所以需要判断各项合计值不能小于0
  ZTYSK-TOTA1 = ZTYSK-ZZYSP * ZTYSK-BRGEW / 1000 + ZTYSK-TSYSF + ZTYSK-ZXIEF.
  ZTYSK-TOTA2 = ZTYSK-ZZNRP * ZTYSK-ZZYGC + ZTYSK-TJRAT * ZTYSK-ZZYGC + ZTYSK-BCRAT * ZTYSK-ZZYGC + ZTYSK-TZFY1.

  IF ZTYSK-TOTA3 > 0.
    IF ZTYSK-ZZWAE NE 'RMB'.
      CALL FUNCTION 'READ_EXCHANGE_RATE'
        EXPORTING
*         CLIENT           = SY-MANDT
          DATE             = ZTYSK-PRSDT
          FOREIGN_CURRENCY = ZTYSK-ZZWAE
          LOCAL_CURRENCY   = 'RMB'
*         TYPE_OF_RATE     = 'M'
*         EXACT_DATE       = ' '
        IMPORTING
          EXCHANGE_RATE    = L_UKURS
        EXCEPTIONS
          NO_RATE_FOUND    = 1
          NO_FACTORS_FOUND = 2
          NO_SPREAD_FOUND  = 3
          DERIVED_2_TIMES  = 4
          OVERFLOW         = 5
          ZERO_RATE        = 6
          OTHERS           = 7.
      IF SY-SUBRC NE 0.
        MESSAGE E001(00) WITH '没有取得货币' ZTYSK-ZZWAE '的汇率'.
      ENDIF.
    ELSE.
      L_UKURS = 1.
    ENDIF.
    L_TOTAL = ZTYSK-TOTA3 / L_UKURS.
  ELSE.
    L_TOTAL = 0.
  ENDIF.

  ZTYSK-TOTA4 = ZTYSK-TOTA2 + L_TOTAL.
  ZTYSK-TOTA5 = ZTYSK-DCRAT * ZTYSK-ZZYGC + ZTYSK-THRAT * ZTYSK-ZZYGC + ZTYSK-XDRAT * ZTYSK-ZZYGC + ZTYSK-DZRAT * ZTYSK-ZZYGC +
                ZTYSK-YPRAT * ZTYSK-ZZYGC + ZTYSK-WJRAT + ZTYSK-TZFY3 +
                ZTYSK-ENRAT + ZTYSK-CZRAT + ZTYSK-DFRAT + ZTYSK-TFRAT +
                ZTYSK-BGRAT + ZTYSK-QTRAT.
  IF ZTYSK-TOTA1 < 0 OR ZTYSK-TOTA2 < 0 OR ZTYSK-TOTA4 < 0 OR ZTYSK-TOTA5 < 0.
    MESSAGE E001(00) WITH '合计金额不能小于0'.
  ENDIF.
按所有项目的毛重的权重来分摊运费, 并将RMB的费用转换为销售订单货币金额.
尾差全部放到最后一个项目上.
  LOOP AT ZTAB.
    IF SY-TABIX < L_LINES.
      ZTAB-YSRAT = ZTAB-BRGEW / ZTYSK-BRGEW * L_TOTAL.
      L_SYTAL = L_SYTAL - ZTAB-YSRAT.
    ELSE.
      ZTAB-YSRAT = L_SYTAL.
    ENDIF.

    CLEAR L_UKURS.
    IF ZTAB-WAERK NE 'RMB'.
      CALL FUNCTION 'READ_EXCHANGE_RATE'
        EXPORTING
*         CLIENT           = SY-MANDT
          DATE             = ZTYSK-PRSDT
          FOREIGN_CURRENCY = ZTAB-WAERK
          LOCAL_CURRENCY   = 'RMB'
*         TYPE_OF_RATE     = 'M'
*         EXACT_DATE       = ' '
        IMPORTING
          EXCHANGE_RATE    = L_UKURS
        EXCEPTIONS
          NO_RATE_FOUND    = 1
          NO_FACTORS_FOUND = 2
          NO_SPREAD_FOUND  = 3
          DERIVED_2_TIMES  = 4
          OVERFLOW         = 5
          ZERO_RATE        = 6
          OTHERS           = 7.
      IF SY-SUBRC NE 0.
        MESSAGE E001(00) WITH '没有取得货币' ZTAB-WAERK '的汇率'.
      ENDIF.
    ELSE.
      L_UKURS = 1.
    ENDIF.
    ZTAB-YSRAT = ZTAB-YSRAT / L_UKURS.
    MODIFY ZTAB TRANSPORTING YSRAT.
  ENDLOOP.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小啊曼

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值