ZR_FI_016

*===============================基本信息===============================*
* 标题:产品成本估算明细表
* 创建日期:2005-08-01       
*===============================定    义===============================*

************************************************************************
* 基本代码
************************************************************************
REPORT ZR_FI_016
NO STANDARD PAGE HEADING
LINE-COUNT 58
LINE-SIZE  150
MESSAGE-ID ZFI1.

************************************************************************
* INCLUDE:包含文件
************************************************************************
INCLUDE OLE2INCL.

************************************************************************
* TABLE: 定义TABLE
************************************************************************
TABLES: MBEW,  "物料评估
        MARA,  "常规物料数据
        MARC,  "
        KEKO,  "产品成本核算 - 表头数据
        CKIS,  "项目单位成本核算/产品成本核算分项列举
        MAST,  "BOM链接物料
        STPO,  "BOM项目
        STKO,  "BOM表头
        T001,  "公司代码
        MAKT,  "物料描述
        CRHD.  "工作中心表头
************************************************************************
*INTERNAL TABLES
************************************************************************
*定义内表ITABS
DATA: BEGIN OF IT_PRINT_001 OCCURS 0.
        DATA FLAG.
        DATA WERKS LIKE KEKO-WERKS.          "公司代码
        DATA KALNR LIKE KEKO-KALNR.          "成本估算号(产品成本核算)
        DATA KADKY LIKE KEKO-KADKY.          "成本核算日期
        DATA MATNR LIKE MBEW-MATNR.          "成品料号

        DATA NO TYPE I.                      "序号
        DATA FEHLKZ LIKE CKIS-FEHLKZ.        "错误状态
        DATA TIERNO TYPE I.                  "BOM层次
        DATA TYPPS LIKE CKIS-TYPPS.          "记录类别
        DATA RECO_CODE LIKE MBEW-MATNR.      "记录代码(用于存放物料号、信息记录)
        DATA RECO_NAME LIKE MAKT-MAKTX.      "记录名称
        DATA TOTAL TYPE P DECIMALS 4.        "总计值
        DATA TOTAL1 TYPE P DECIMALS 4.       "标准值
        DATA TOTAL2 TYPE P DECIMALS 4.       "损耗值
        DATA FWAER_KPF LIKE CKIS-FWAER_KPF.  "货币
        DATA MENGE LIKE CKIS-MENGE.          "总计数量
        DATA MENGE1 LIKE CKIS-MENGE.         "标准数量= 数量-损耗数量
        DATA AUSMG LIKE CKIS-AUSMG.          "废品数量
        DATA PMEHT LIKE CKIS-PMEHT.          "计量单位
        DATA MEEHT LIKE CKIS-MEEHT.          "计量单位

        DATA WERTN TYPE P DECIMALS 4.        "价格
        DATA PEINH TYPE P DECIMALS 4.        "单位价格
        DATA LSTAR LIKE CKIS-LSTAR.          "活动类型
        DATA INFNR LIKE CKIS-INFNR.          "信息记录
        DATA KSTAR LIKE CKIS-KSTAR.          "成本要素
        DATA KOSTL LIKE CKIS-KOSTL.          "成本中心
        DATA ARBID LIKE CKIS-ARBID.          "对象 ID
        DATA FLAG_MID TYPE I.                "是否是组件(1是,0否)
*打印增加字段 07-07-23
        DATA LOSGR LIKE KEKO-LOSGR.          "批量数量
        DATA AVOAU LIKE STPO-AVOAU.          "工序损耗率
        DATA AUSCH LIKE STPO-AUSCH.          "废品率
        DATA KSRAT TYPE P DECIMALS 2.        "成本占比
        DATA KSTXT(9) TYPE C.               "成本占比文本
        DATA TYTXT(50) TYPE C.               "类别文本
DATA: END OF IT_PRINT_001.


DATA: BEGIN OF ITAB_01 OCCURS 0.
        DATA FLAG.
        DATA MATNR LIKE MBEW-MATNR.          "成品料号
        DATA KALNR LIKE KEKO-KALNR.          "成本估算号 - 产品成本核算
        DATA LOSGR LIKE KEKO-LOSGR.          "批量数量
        DATA MEINS LIKE KEKO-MEINS.          "基本计量单位
        DATA FWAER_KPF LIKE KEKO-FWAER_KPF.  "币别
        DATA STNUM LIKE KEKO-STNUM.          "物料清单
        DATA STLAN LIKE KEKO-STLAN.          "BOM用途
        DATA STALT LIKE KEKO-STALT.          "替代
DATA: END OF ITAB_01.


*往数据库增加运行日志
  DATA: BEGIN OF IT_ZREPORTLOG OCCURS  0.
    INCLUDE TYPE ZREPORTLOG.
  DATA: END OF IT_ZREPORTLOG.
************************************************************************
* CONSTANTS : 定义常量
************************************************************************

************************************************************************
* TYPE : 定义数据类型
************************************************************************
TYPE-POOLS: SLIS.

************************************************************************
* DATA : 定义变量
************************************************************************
*单据表格上相关坐标值定义
DATA: A1 TYPE I VALUE 0,
      A2 TYPE I VALUE 0,
      A3 TYPE I VALUE 0,
      A4 TYPE I VALUE 0,
      A5 TYPE I VALUE 0,
      A6 TYPE I VALUE 0,
      A7 TYPE I VALUE 0,
      A8 TYPE I VALUE 0,
      A9 TYPE I VALUE 0,
      A10 TYPE I VALUE 0,
      A11 TYPE I VALUE 0,
      A12 TYPE I VALUE 0.

DATA: B1 TYPE I VALUE 0,
      B2 TYPE I VALUE 0,
      B3 TYPE I VALUE 0,
      B4 TYPE I VALUE 0,
      B5 TYPE I VALUE 0,
      B6 TYPE I VALUE 0,
      B7 TYPE I VALUE 0,
      B8 TYPE I VALUE 0,
      B9 TYPE I VALUE 0,
      B10 TYPE I VALUE 0,
      B11 TYPE I VALUE 0.
DATA: NAME_LAST LIKE USER_ADDR-NAME_LAST,
      NAME_FIRST LIKE USER_ADDR-NAME_FIRST,
      NAME(16).

DATA: L_TEMP LIKE CKIS-WERTN VALUE 0.
DATA: G_KALNR LIKE KEKO-KALNR,
      G_UKALN LIKE CKIS-UKALN,
      G_KALNR1 LIKE KEKO-KALNR,
      G_UKALN1 LIKE CKIS-UKALN,
      G_MENGE LIKE CKIS-MENGE,        "物料批量
      G_PEINH TYPE P DECIMALS 6,      "价格单位
*      G_PEINH TYPE P DECIMALS 2,     "价格单位
      G_CLF TYPE P DECIMALS 4,        "材料费
      G_JGF TYPE P DECIMALS 4,        "加工费
      G_WYJGF TYPE P DECIMALS 4,      "委外加工费
      G_TIERNO TYPE I.                "BOM层次
DATA: V_MATNR2 LIKE STPO-IDNRK,
      V_MATKL2 LIKE MARA-MATKL,
      G_MATNR LIKE MBEW-MATNR.

DATA: G_DAY(2),
      G_LEN TYPE I,
      G_MOD TYPE I,
      G_DATE1 LIKE LIKP-ERDAT,
      G_STNUM LIKE KEKO-STNUM,
      G_STLAN LIKE KEKO-STLAN,
      G_STALT LIKE KEKO-STALT,
      G_AVOAU LIKE STPO-AVOAU,
      G_AUSCH LIKE STPO-AUSCH,
      G_DATE2 LIKE LIKP-ERDAT.

*用于ALV控件双击事件
DATA: G_SELECTED_FIELD_VALUE(80).

*ALV控件构造时需要的参数
DATA: G_ALV_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV,
      G_ALV_FIELDCAT_LINE LIKE LINE OF G_ALV_FIELDCAT,
      G_ALV_EVENT         TYPE SLIS_T_EVENT.

*ALV控件输出的表头
DATA: G_ALV_LISTHEADER TYPE SLIS_T_LISTHEADER.

*指定ALV控件触发TOP_OF_PAGE事件时调用的子程序
DATA: G_ALV_FORMNAME_TOP_OF_PAGE TYPE SLIS_FORMNAME
             VALUE 'F_ALV_EVENT_TOP_OF_PAGE'.
DATA: G_ALV_FORMNAME_END_OF_LIST TYPE SLIS_FORMNAME
             VALUE 'F_ALV_EVENT_END_OF_LIST'.

*指定ALV控件的显示特征
DATA : G_ALV_LAYOUT TYPE SLIS_LAYOUT_ALV.
************************************************************************
* DEFINE: 定义宏
************************************************************************
*普通报表格式的输出宏
DEFINE GRID1.               "画表格
  WRITE: AT /A1   SY-VLINE.
  WRITE: AT  B1   &1.
  WRITE: AT  A2   SY-VLINE.
  WRITE: AT  B2   &2 LEFT-JUSTIFIED.
  WRITE: AT  A3   SY-VLINE.
  WRITE: AT  B3   &3.
  WRITE: AT  A4   SY-VLINE.
  WRITE: AT  B4   &4.
  WRITE: AT  A5   SY-VLINE.
  WRITE: AT  B5   &5 LEFT-JUSTIFIED.
  WRITE: AT  A6   SY-VLINE.
  WRITE: AT  B6   &6 LEFT-JUSTIFIED.
  WRITE: AT  A7   SY-VLINE.
  WRITE: AT  B7   &7 LEFT-JUSTIFIED.
  WRITE: AT  A8   SY-VLINE.
  WRITE: AT  B8   &8 LEFT-JUSTIFIED.
  WRITE: AT  A9   SY-VLINE.
  WRITE: AT  B9   &9 LEFT-JUSTIFIED.
END-OF-DEFINITION.

DEFINE GRID2.               "画表格
  WRITE: AT  A10  SY-VLINE.
  WRITE: AT  B10  &1 RIGHT-JUSTIFIED.
  WRITE: AT  A11  SY-VLINE.
  WRITE: AT  B11  &2 LEFT-JUSTIFIED.
  WRITE: AT  A12  SY-VLINE.
END-OF-DEFINITION.
************************************************************************
*  SELECTION SCREEN : 定义报表筛选条件
************************************************************************
*确定过滤参数
SELECTION-SCREEN BEGIN OF BLOCK BLK_001 WITH FRAME. TITLE BLK_001.
    SELECT-OPTIONS P_MATNR FOR KEKO-MATNR MEMORY ID 205.            "物料号
    PARAMETERS : P_BUKRS LIKE GLT0-BUKRS OBLIGATORY MEMORY ID 206.  "公司代码
    PARAMETERS : P_RYEAR(4) TYPE C OBLIGATORY DEFAULT SY-DATUM+0(4)."报表年度
    PARAMETERS : P_PERID(2) TYPE C OBLIGATORY DEFAULT SY-DATUM+4(2)."报表期间
    PARAMETERS:  P_BY AS CHECKBOX.   "显示中间组件层估算值及各本层损耗值
SELECTION-SCREEN END OF BLOCK BLK_001.

*选择报表类型
SELECTION-SCREEN BEGIN OF BLOCK BLK_002 WITH FRAME. TITLE BLK_002 .
  PARAMETERS : P_KUNNR LIKE KNMT-KUNNR.  "客户代码
SELECTION-SCREEN END OF BLOCK BLK_002.

*选择报表类型
SELECTION-SCREEN BEGIN OF BLOCK BLK_003 WITH FRAME. TITLE BLK_003 .
PARAMETERS: P_REPORT RADIOBUTTON GROUP R1,
            P_ALV RADIOBUTTON GROUP R1 DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK BLK_003.

*===============================事    件===============================*
************************************************************************
* INITIALIZATION.启动程序开始执行
************************************************************************
INITIALIZATION.
  BLK_001 = '检索参数'.
  BLK_002 = '报价参数'.
  BLK_003 = '报表类型'.
  PERFORM. SUB_INI.
************************************************************************
* AT SELECTION SCREEN:
************************************************************************
AT SELECTION-SCREEN.
  PERFORM. F_CHECK_INPUT.          "检查用户输入
************************************************************************
* START OF SELECTION:
************************************************************************
START-OF-SELECTION.
*往数据库增加运行日志
  IT_ZREPORTLOG-MANDT = SY-MANDT.
  IT_ZREPORTLOG-TCODE = SY-TCODE.
  IT_ZREPORTLOG-DATUM = SY-DATUM.
  IT_ZREPORTLOG-UZEIT = SY-UZEIT.
  IT_ZREPORTLOG-UNAME = SY-UNAME.
  IT_ZREPORTLOG-TITLE = SY-TITLE.
  APPEND IT_ZREPORTLOG.
  INSERT INTO ZREPORTLOG VALUES IT_ZREPORTLOG .

  PERFORM. CAL_DAY.                "每月天数判断

  PERFORM. F_READ_DATA.

  IF P_REPORT = 'X'.
    PERFORM. F_PRINT_REPORT.
  ELSEIF P_ALV = 'X'.
    PERFORM. F_PRINT_ALV.
  ENDIF.
************************************************************************
* END OF SELECTION
************************************************************************
END-OF-SELECTION.

************************************************************************
* TOP OF PAGE
************************************************************************
TOP-OF-PAGE.
  PERFORM. SUB_HEAD.
************************************************************************
* END OF PAGE
************************************************************************
END-OF-PAGE.
*  PERFORM. SUB_BOTTOM.
*===============================子 例 程===============================*
*&---------------------------------------------------------------------*
*过滤条件有效性检查
*&---------------------------------------------------------------------*
FORM. F_CHECK_INPUT.
DATA L_TEMP(20).
  "日期处理
  IF P_PERID+1(1) = ''.
    CONCATENATE '0' P_PERID INTO P_PERID.
  ENDIF.
  IF ( P_PERID < '01' ) OR ( P_PERID > '16' ).
    MESSAGE E000.    "该会计期间不存在!
  ENDIF.

  "物料判断
  SELECT MATNR
    INTO L_TEMP
    FROM MARA
    WHERE ( MTART = 'FERT' OR MTART = 'HALB' )
      AND MATNR IN P_MATNR.
  ENDSELECT.

  IF SY-SUBRC <> 0.
    MESSAGE E071. "不存在该物料或该物料不是产成品!
  ENDIF.

  SELECT MATNR
    INTO MARC-MATNR
    FROM MARC
    WHERE MATNR IN P_MATNR
      AND WERKS = P_BUKRS.
  ENDSELECT.
  IF SY-SUBRC <> 0.
    MESSAGE E072. "该物料不存在该工厂中!
  ENDIF.

ENDFORM.                    " F_CHECK_INPUT
*&---------------------------------------------------------------------*
*从数据库中读取数据,填充报表输出时所用的内表
*&---------------------------------------------------------------------*
FORM. F_READ_DATA .
DATA: L_MAKTX LIKE MAKT-MAKTX,
      L_TOTAL TYPE P DECIMALS 4,
      L_TOTAL1 TYPE P DECIMALS 4,
      L_TOTAL2 TYPE P DECIMALS 4,
      L_NO TYPE I VALUE 0,
      L_ERROR TYPE I VALUE 0.

  REFRESH ITAB_01.
  CLEAR ITAB_01.

*--物料的成本核算号及物料批量
  SELECT MATNR KALNR LOSGR MEINS FWAER_KPF STNUM STLAN STALT
  FROM KEKO
  INTO CORRESPONDING FIELDS OF TABLE ITAB_01
  WHERE MATNR IN P_MATNR
  AND WERKS = P_BUKRS
  AND KADKY = G_DATE1              "成本核算日期(每月只有一条记录)
  AND KALKA = '01'                 "成本核算类型=PPC1
  AND TVERS = '01'                 "成本核算版本
  AND LOEKZ = ''                   "产品成本核算的删除标志
  AND BZOBJ = '0'                  "参考对象
  AND BWVAR = '001'                "成本核算中的估算变式
  AND KKZMA = ''.                  "在附加或自动成本估算中手工输入的成本

  LOOP AT ITAB_01.
    "将第0层数据加入内表中
    G_MATNR = ITAB_01-MATNR.
    PERFORM. F_INSERT_TABLE USING G_MATNR P_BUKRS 0 'M'
                                 P_MATNR '' ''
                                 '' '' ''
                                 0 1 ITAB_01-FWAER_KPF
                                 ITAB_01-LOSGR ITAB_01-LOSGR ''
                                 ITAB_01-MEINS '' '' '' '' 1.

    "调用下层数据
    G_MENGE = ITAB_01-LOSGR.           "物料批量
    G_PEINH = 1.
    G_TIERNO = 1.
    G_STNUM = ITAB_01-STNUM.
    G_STLAN = ITAB_01-STLAN.
    G_STALT = ITAB_01-STALT.
    PERFORM. F_SUB USING ITAB_01-KALNR 1.

*--处理记录序号
    L_NO = 0.
    LOOP AT IT_PRINT_001.
*      IT_PRINT_001-LOSGR = G_MENGE.
      IF IT_PRINT_001-MATNR = ITAB_01-MATNR.
        L_NO = L_NO + 1.
        IT_PRINT_001-NO = L_NO.
      ENDIF.
      MODIFY IT_PRINT_001.
    ENDLOOP.
  ENDLOOP.

*-处理错误状态信息
  LOOP AT IT_PRINT_001.
    IF IT_PRINT_001-FEHLKZ = 'X'.
      L_ERROR = 1.
      EXIT.
    ENDIF.
  ENDLOOP.
  LOOP AT IT_PRINT_001.
    IF L_ERROR = 1 AND IT_PRINT_001-NO = 1.
      IT_PRINT_001-FEHLKZ = 'X'.
      MODIFY IT_PRINT_001.
      EXIT.
    ENDIF.
  ENDLOOP.

  IF P_ALV = 'X' AND P_BY = ''.
**-将中间层虚拟件的金额改为0
    DATA: IT_TEMP LIKE IT_PRINT_001 OCCURS 10 WITH HEADER LINE.
    DATA: L_SUB_NO TYPE I.
    CLEAR IT_TEMP.REFRESH IT_TEMP.
    L_SUB_NO = 0.
    MOVE IT_PRINT_001[] TO IT_TEMP[].
    LOOP AT IT_PRINT_001.
      L_SUB_NO = IT_PRINT_001-NO + 1.
      LOOP AT IT_TEMP.
        IF IT_TEMP-NO = L_SUB_NO AND IT_TEMP-TIERNO > IT_PRINT_001-TIERNO
         AND IT_TEMP-MATNR = IT_PRINT_001-MATNR.
          IT_PRINT_001-FLAG_MID = 1.
          EXIT.
        ENDIF.
      ENDLOOP.
      MODIFY IT_PRINT_001.
    ENDLOOP.
    LOOP AT IT_PRINT_001.
      IF IT_PRINT_001-FLAG_MID = 1 AND IT_PRINT_001-TIERNO <> 0.
        IT_PRINT_001-TOTAL = 0.
        IT_PRINT_001-TOTAL1 = 0.
        IT_PRINT_001-TOTAL2 = 0.
        MODIFY IT_PRINT_001.
      ENDIF.
    ENDLOOP.
*--总计值(由最底层汇总至0层)
    L_TOTAL = 0.
    L_TOTAL1 = 0.
    L_TOTAL2 = 0.
    LOOP AT IT_PRINT_001.
      IF IT_PRINT_001-MATNR = ITAB_01-MATNR.
          L_TOTAL = L_TOTAL + IT_PRINT_001-TOTAL.
          L_TOTAL1 = L_TOTAL1 + IT_PRINT_001-TOTAL1.
          L_TOTAL2 = L_TOTAL2 + IT_PRINT_001-TOTAL2.
      ENDIF.
    ENDLOOP.
    LOOP AT IT_PRINT_001.
      IF IT_PRINT_001-MATNR = ITAB_01-MATNR.
        IF IT_PRINT_001-TIERNO = 0.
          IT_PRINT_001-TOTAL = L_TOTAL.
          IT_PRINT_001-TOTAL1 = L_TOTAL1.
          IT_PRINT_001-TOTAL2 = L_TOTAL2.
          MODIFY IT_PRINT_001.
        ENDIF.
      ENDIF.
    ENDLOOP.
  ELSE.
*--总计值(由第一层汇总至0层)
    L_TOTAL = 0.
    L_TOTAL1 = 0.
    L_TOTAL2 = 0.
    LOOP AT IT_PRINT_001.
      IF IT_PRINT_001-MATNR = ITAB_01-MATNR.
        IF IT_PRINT_001-TIERNO = 1.
          L_TOTAL = L_TOTAL + IT_PRINT_001-TOTAL.
          L_TOTAL1 = L_TOTAL1 + IT_PRINT_001-TOTAL1.
          L_TOTAL2 = L_TOTAL2 + IT_PRINT_001-TOTAL2.
        ENDIF.
      ENDIF.
    ENDLOOP.
    LOOP AT IT_PRINT_001.
      IF IT_PRINT_001-MATNR = ITAB_01-MATNR.
        IF IT_PRINT_001-TIERNO = 0.
          IT_PRINT_001-TOTAL = L_TOTAL.
          IT_PRINT_001-TOTAL1 = L_TOTAL1.
          IT_PRINT_001-TOTAL2 = L_TOTAL2.
          MODIFY IT_PRINT_001.
        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDIF.
  IF P_REPORT = 'X'.
    SORT IT_PRINT_001 BY NO ASCENDING.
    LOOP AT IT_PRINT_001 WHERE NO <> ''.
      IF IT_PRINT_001-NO = 1.
        IT_PRINT_001-TOTAL = IT_PRINT_001-TOTAL / G_MENGE.
        L_TOTAL = IT_PRINT_001-TOTAL.
        CLEAR IT_PRINT_001.
        IT_PRINT_001-TYTXT = '成本合计'.
        IT_PRINT_001-TOTAL = L_TOTAL.
        IT_PRINT_001-KSTXT = '100%'.
        APPEND IT_PRINT_001.
        CLEAR IT_PRINT_001.
        IT_PRINT_001-TYTXT = '其中:材料费'.
        IT_PRINT_001-TOTAL = G_CLF.
        IT_PRINT_001-KSRAT = IT_PRINT_001-TOTAL / L_TOTAL.
        IT_PRINT_001-KSTXT = IT_PRINT_001-KSRAT * 100.
        CONCATENATE IT_PRINT_001-KSTXT '%' INTO IT_PRINT_001-KSTXT.
        APPEND IT_PRINT_001.
        CLEAR IT_PRINT_001.
        IT_PRINT_001-TYTXT = '加工费'.
        IT_PRINT_001-TOTAL = G_JGF.
        IT_PRINT_001-KSRAT = IT_PRINT_001-TOTAL / L_TOTAL.
        IT_PRINT_001-KSTXT = IT_PRINT_001-KSRAT * 100.
        CONCATENATE IT_PRINT_001-KSTXT '%' INTO IT_PRINT_001-KSTXT.
        APPEND IT_PRINT_001.
        CLEAR IT_PRINT_001.
        IT_PRINT_001-TYTXT = '委外加工费'.
        IT_PRINT_001-TOTAL = G_WYJGF.
        IT_PRINT_001-KSRAT = IT_PRINT_001-TOTAL / L_TOTAL.
        IT_PRINT_001-KSTXT = IT_PRINT_001-KSRAT * 100.
        CONCATENATE IT_PRINT_001-KSTXT '%' INTO IT_PRINT_001-KSTXT.
        APPEND IT_PRINT_001.
        CLEAR IT_PRINT_001.
        IT_PRINT_001-TYTXT = '报价系数'.
        IT_PRINT_001-MENGE = '0.8350'.
        APPEND IT_PRINT_001.
        CLEAR IT_PRINT_001.
        IT_PRINT_001-TYTXT = '报价(不含税)'.
        IT_PRINT_001-TOTAL = L_TOTAL * 1000 / 835.
        APPEND IT_PRINT_001.
        CLEAR IT_PRINT_001.
      ELSE.
        IF IT_PRINT_001-PMEHT = 'MIN'.
          IT_PRINT_001-PMEHT = 'S'.
          IT_PRINT_001-MENGE = IT_PRINT_001-MENGE * 60.
        ENDIF.
        IT_PRINT_001-TOTAL = IT_PRINT_001-TOTAL / G_MENGE.
        IT_PRINT_001-MENGE = IT_PRINT_001-MENGE / G_MENGE.
        IT_PRINT_001-KSRAT = IT_PRINT_001-TOTAL / L_TOTAL.
        IT_PRINT_001-KSTXT = IT_PRINT_001-KSRAT * 100.
        CONCATENATE IT_PRINT_001-KSTXT '%' INTO IT_PRINT_001-KSTXT.
        IF IT_PRINT_001-MENGE <> 0 AND IT_PRINT_001-MENGE <> ''.
          IT_PRINT_001-PEINH = IT_PRINT_001-TOTAL / IT_PRINT_001-MENGE.
        ENDIF.
        MODIFY IT_PRINT_001.
        CLEAR IT_PRINT_001.
      ENDIF.
    ENDLOOP.
  ENDIF.
ENDFORM.                    " F_READ_DATA
*&---------------------------------------------------------------------*
*递归调用程序
*&---------------------------------------------------------------------*
FORM. F_SUB USING P_KALNR P_LOSGR.
DATA : L_UKALN LIKE CKIS-UKALN,
       L_UKALN1 LIKE CKIS-UKALN,
       L_PEINH TYPE P DECIMALS 6,      "价格单位
*       L_PEINH TYPE P DECIMALS 2,      "价格单位
       L_TIERNO TYPE I,                "BOM层次
       L_MAKTX LIKE MAKT-MAKTX,
       L_LOSGR LIKE KEKO-LOSGR,
       L_TOTAL TYPE P DECIMALS 6.
DATA: N TYPE I.
DATA: ITAB_02 LIKE IT_PRINT_001 OCCURS 10 WITH HEADER LINE.

  L_PEINH = G_PEINH.
  L_TIERNO = G_TIERNO.

  SELECT UKALN AS KALNR         "输入的成本估算的成本估算编号
         WERTN                  "控制区域货币的值
         TYPPS                  "项目类别
         MENGE                  "数量
         PMEHT                  "价格数量单位
         MEEHT                  "基本单位
         PEINH                  "以控制范围货币记价的单位价格
         MATNR                  "物料
         WERKS                  "工厂
         FWAER_KPF              "货币
         LSTAR                  "活动类型
         INFNR                  "信息记录
         KSTAR                  "成本要素
         KOSTL                  "成本中心
         ARBID                  "对象ID
         FEHLKZ                 "错误状态
         AUSMG                  "废品数量
    FROM CKIS
    INTO CORRESPONDING FIELDS OF TABLE ITAB_02
    WHERE KALNR = P_KALNR        "成本估算号
      AND KADKY = G_DATE1        "成本核算日期
      AND KALKA = '01'           "成本核算类型=PPC1
      AND TVERS = '1'            "成本核算版本
      AND ( TYPPS = 'L' OR       "项目类别=托工
            TYPPS = 'E' OR       "项目类别=装配费用、自制费用
            TYPPS = 'G' OR       "项目类别=附加费
            TYPPS = 'I' OR       "项目类别=本层的直采物料
            TYPPS = 'M' )        "项目类别=含有下层的半成品
      AND LEDNR = '00'           "控制对象的分类帐
      AND BZOBJ = 0              "参考对象
      AND BWVAR = '001'          "成本核算中的估算变式
      AND KKZMA = ''             "在附加或自动成本估算中手工输入的成本
      AND POSNR <> ''.           "单位成本核算行项号
  LOOP AT ITAB_02.
    IF ITAB_02-TYPPS = 'M'.
      "将本层数据加入内表中
      IF ITAB_02-AUSMG <> ''.
         ITAB_02-MENGE1 = ITAB_02-MENGE - ITAB_02-AUSMG.
      ELSE.
         ITAB_02-MENGE1 = ITAB_02-MENGE.
      ENDIF.
      IF P_REPORT = 'X'.
        "工序损耗率和废品率
        SELECT AVOAU
               AUSCH
        FROM STPO
             JOIN STAS
             ON STAS~STLNR = STPO~STLNR
             AND STAS~STLKN = STPO~STLKN
             AND STAS~STLTY = STPO~STLTY
        INTO (G_AVOAU,G_AUSCH)
        WHERE STPO~STLTY = 'M'
        AND STAS~STLAL = G_STALT
        AND STPO~STLNR = G_STNUM
        AND STPO~IDNRK = ITAB_02-MATNR.
        ENDSELECT.
* 获取虚拟件BOM该层工序损耗率和废品率
        IF SY-SUBRC <> 0.
          SELECT AVOAU
                 AUSCH
          FROM STPO
               JOIN STAS
               ON STAS~STLNR = STPO~STLNR
               AND STAS~STLKN = STPO~STLKN
               AND STAS~STLTY = STPO~STLTY
          INTO (G_AVOAU,G_AUSCH)
          WHERE STPO~STLTY = 'M'
          AND STAS~STLAL = G_STALT
          AND STPO~STLNR = G_STNUM.
          ENDSELECT.
        ENDIF.
        IF ITAB_02-KALNR <> 0.
          CLEAR:G_STNUM,G_STLAN,G_STALT.
          "获取新的BOM
          SELECT STNUM STLAN STALT
          FROM KEKO
          INTO (G_STNUM,G_STLAN,G_STALT)
          WHERE MATNR = ITAB_02-MATNR
          AND WERKS = P_BUKRS
          AND KADKY = G_DATE1              "成本核算日期(每月只有一条记录)
          AND KALKA = '01'                 "成本核算类型=PPC1
          AND TVERS = '01'                 "成本核算版本
          AND LOEKZ = ''                   "产品成本核算的删除标志
          AND BZOBJ = '0'                  "参考对象
          AND BWVAR = '001'                "成本核算中的估算变式
          AND KKZMA = ''.                  "在附加或自动成本估算中手工输入的成本
          ENDSELECT.
        ENDIF.
      ENDIF.
      PERFORM. F_INSERT_TABLE USING G_MATNR ITAB_02-WERKS L_TIERNO ITAB_02-TYPPS
                                   ITAB_02-MATNR ITAB_02-INFNR ITAB_02-LSTAR
                                   ITAB_02-KSTAR ITAB_02-KOSTL ITAB_02-ARBID
                                   ITAB_02-WERTN L_PEINH ITAB_02-FWAER_KPF
                                   ITAB_02-MENGE ITAB_02-MENGE1 ITAB_02-AUSMG
                                   ITAB_02-MEEHT ITAB_02-FEHLKZ G_AVOAU G_AUSCH
                                   ITAB_02-KALNR 1.
      IF ITAB_02-KALNR <> 0.
*-------递归处理开始
        SELECT KALNR
        FROM CKIS
        INTO CKIS-KALNR
        WHERE KALNR = ITAB_02-KALNR
        AND KADKY = G_DATE1
        AND KALKA = '01'
        AND TVERS = '1'
        AND TYPPS = 'I'           "项目类别
        AND LEDNR = '00'
        AND BZOBJ = 0
        AND BWVAR = '001'
        AND KKZMA = ''
        AND POSNR <> ''.
        ENDSELECT.
        IF SY-SUBRC = 0.
          "如果找到相关记录,本层数据加入内表中
          PERFORM. F_INSERT_TABLE USING G_MATNR ITAB_02-WERKS L_TIERNO ITAB_02-TYPPS
                                       ITAB_02-MATNR ITAB_02-INFNR ITAB_02-LSTAR
                                       ITAB_02-KSTAR ITAB_02-KOSTL ITAB_02-ARBID
                                       0 L_PEINH ITAB_02-FWAER_KPF ITAB_02-MENGE
                                       ITAB_02-MENGE1 ITAB_02-AUSMG ITAB_02-MEEHT
                                       ITAB_02-FEHLKZ G_AVOAU G_AUSCH '' 1.
        ELSE.
*COMEMENT BY ZWM AT 2007-12-17 更改算法,价格直接由本层总价除以本层的数量
          SELECT SINGLE LOSGR
          FROM KEKO
          INTO L_LOSGR
          WHERE MATNR = ITAB_02-MATNR
          AND WERKS = P_BUKRS
          AND KADKY = G_DATE1              "成本核算日期(每月只有一条记录)
          AND KALKA = '01'                 "成本核算类型=PPC1
          AND TVERS = '01'                 "成本核算版本
          AND LOEKZ = ''                   "产品成本核算的删除标志
          AND BZOBJ = '0'                  "参考对象
          AND BWVAR = '001'                "成本核算中的估算变式
          AND KKZMA = ''.                  "在附加或自动成本估算中手工输入的成本
* 批量需累乘
*          IF P_LOSGR <> '' AND P_LOSGR > 0.
*            L_LOSGR = L_LOSGR * P_LOSGR.
*          ENDIF.
*         G_PEINH = L_PEINH * ITAB_02-MENGE / ITAB_02-PEINH.
          "修改上一层的汇总金额(取最后一条记录)
          PERFORM. F_GET_TOTAL USING ITAB_02-KALNR CHANGING L_TOTAL.
**          IF L_TOTAL <> 0.
*          IF ITAB_02-PEINH > 0.
** ITAB_02-PEINH 有可能是1,也有可能是100在除以批量后,这个数值在这里就没有意义.
**            G_PEINH = L_PEINH * ITAB_02-MENGE / ITAB_02-PEINH.
*            G_PEINH = L_PEINH * ITAB_02-MENGE.
**            G_PEINH = L_PEINH * ( ITAB_02-WERTN / L_TOTAL ). "倍数处理
*          ELSE.
*            G_PEINH = 1.
*          ENDIF.
          IF L_LOSGR = 0.
            L_LOSGR = 1.
          ENDIF.
          G_PEINH = L_PEINH * ITAB_02-MENGE / L_LOSGR.
          N = 0.
          DESCRIBE TABLE IT_PRINT_001 LINES N.
          LOOP AT IT_PRINT_001.
            IF SY-TABIX = N.
*              IF L_LOSGR <> 0 AND L_LOSGR <> ''.
              IT_PRINT_001-TOTAL = L_TOTAL * G_PEINH.
*              ELSE.
*                IT_PRINT_001-TOTAL = L_TOTAL * G_PEINH.
*              ENDIF.
              MODIFY IT_PRINT_001.
            ENDIF.
          ENDLOOP.

          L_TIERNO = L_TIERNO + 1.
          G_TIERNO = L_TIERNO.
*          PERFORM. F_SUB USING ITAB_02-KALNR L_LOSGR.
          PERFORM. F_SUB USING ITAB_02-KALNR 1.
          L_TIERNO = L_TIERNO - 1.
          G_TIERNO = L_TIERNO.
*-------递归处理结束
        ENDIF.
      ENDIF.
    ELSE.
      "无子层的记录直接更新到内表中
      "将本层数据加入内表中
      ITAB_02-MENGE1 = ITAB_02-MENGE.
      PERFORM. F_INSERT_TABLE USING G_MATNR ITAB_02-WERKS L_TIERNO ITAB_02-TYPPS
                                   ITAB_02-MATNR ITAB_02-INFNR ITAB_02-LSTAR
                                   ITAB_02-KSTAR ITAB_02-KOSTL ITAB_02-ARBID
                                   ITAB_02-WERTN L_PEINH ITAB_02-FWAER_KPF
                                   ITAB_02-MENGE ITAB_02-MENGE1 ITAB_02-AUSMG
                                   ITAB_02-MEEHT ITAB_02-FEHLKZ '' '' '' 1.
    ENDIF.
    CLEAR: G_AVOAU,G_AUSCH.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*调用增加内表数据
*&---------------------------------------------------------------------*
FORM. F_INSERT_TABLE USING V_PRODNO V_BUKRS V_TIERNO V_TYPPS
                          V_MATNR V_INFNR V_LSTAR
                          V_KSTAR V_KOSTL V_ARBID
                          V_WERTN V_PEINH V_FWAER_KPF
                          V_MENGE V_MENGE1 V_AUSMG V_PMEHT V_FEHLKZ
                          V_AVOAU V_AUSCH V_KALNR V_LOSGR.
DATA: L_MAKTX LIKE MAKT-MAKTX,
      L_KSTEXT LIKE CSKT-KTEXT,
      L_MTART LIKE MARA-MTART,
      L_TEMP LIKE MAKT-MAKTX.

  IT_PRINT_001-MATNR = V_PRODNO.
  IT_PRINT_001-WERKS = V_BUKRS.
  IT_PRINT_001-TIERNO = V_TIERNO.        "BOM层次
  IT_PRINT_001-TYPPS = V_TYPPS.          "记录类别
  IF V_TYPPS = 'I' OR V_TYPPS = 'M'.
    IT_PRINT_001-RECO_CODE = V_MATNR.    "记录代码(用于存放物料号、信息记录)
    PERFORM. F_GET_PRODNAME USING V_MATNR CHANGING L_MAKTX.
  ELSEIF V_TYPPS = 'L'.
    IT_PRINT_001-RECO_CODE = V_INFNR.                       "取供应商编号
    PERFORM. F_GET_LIFNR USING V_INFNR CHANGING L_MAKTX.
  ELSEIF V_TYPPS = 'E'.
    IT_PRINT_001-RECO_CODE = V_LSTAR.
    L_MAKTX = V_KOSTL+5(5).                                 "取成本中心
    PERFORM. F_GET_ARBID USING V_ARBID CHANGING L_TEMP.      "取工作中心
    CONCATENATE L_MAKTX '   &  ' L_TEMP INTO L_MAKTX.
  ELSEIF V_TYPPS = 'G'.
    IT_PRINT_001-RECO_CODE = V_KSTAR.
    PERFORM. F_GET_CBYSNAME USING V_KSTAR CHANGING L_MAKTX.  "取附加费名称
  ENDIF.
"类别
  IF P_REPORT = 'X'.
    IF V_TYPPS = 'M'.
      PERFORM. F_GET_MTART USING V_MATNR CHANGING L_MTART.
      IF L_MTART = 'ROH' AND V_KALNR = ''.
        IT_PRINT_001-TYTXT = '材料费'.
        G_CLF = G_CLF + V_WERTN * V_PEINH / G_MENGE / V_LOSGR.
      ELSEIF L_MTART = 'ROH' AND V_KALNR <> ''.
        IT_PRINT_001-TYTXT = '托工件'.
      ELSE.
        IT_PRINT_001-TYTXT = '自制件'.
      ENDIF.
    ELSEIF V_TYPPS = 'L'.
      IT_PRINT_001-TYTXT = '委外加工费'.
      G_WYJGF = G_WYJGF + V_WERTN * V_PEINH / G_MENGE / V_LOSGR.
    ELSEIF V_TYPPS = 'E'.
      G_JGF = G_JGF + V_WERTN * V_PEINH / G_MENGE / V_LOSGR.
      SELECT SINGLE KTEXT
      FROM CSKT
      INTO L_KSTEXT
      WHERE SPRAS = '1'
      AND KOKRS = '1000'
      AND KOSTL = V_KOSTL.
      CONCATENATE L_KSTEXT '加工费' INTO IT_PRINT_001-TYTXT.
    ENDIF.
  ENDIF.

  IT_PRINT_001-RECO_NAME = L_MAKTX.         "记录名称
  IT_PRINT_001-TOTAL = V_WERTN * V_PEINH / V_LOSGR.   "总计值
  IT_PRINT_001-TOTAL1 = V_WERTN / V_MENGE * V_MENGE1 * V_PEINH / V_LOSGR."标准值
  IT_PRINT_001-TOTAL2 = IT_PRINT_001-TOTAL - IT_PRINT_001-TOTAL1.
*  V_WERTN / V_MENGE * V_AUSMG * V_PEINH . "损耗值
  IT_PRINT_001-FWAER_KPF = V_FWAER_KPF.     "货币
  IT_PRINT_001-MENGE = V_MENGE * V_PEINH / V_LOSGR.   "总计数量
  IT_PRINT_001-MENGE1 = V_MENGE1 * V_PEINH / V_LOSGR. "标准用量
  IT_PRINT_001-AUSMG = V_AUSMG * V_PEINH / V_LOSGR.   "损耗用量
  IT_PRINT_001-PMEHT = V_PMEHT.             "计量单位
  IT_PRINT_001-FEHLKZ = V_FEHLKZ.           "错误状态
  IT_PRINT_001-AVOAU = V_AVOAU.             "工序损耗率
  IT_PRINT_001-AUSCH = V_AUSCH.             "废品率
  IT_PRINT_001-KALNR = V_KALNR.             "废品率
  APPEND IT_PRINT_001.
ENDFORM.
*&---------------------------------------------------------------------*
* 下层成本之和
*&---------------------------------------------------------------------*
FORM. F_GET_TOTAL USING P_KALNR CHANGING P_TOTAL.
  SELECT SUM( WERTN )
  FROM CKIS
  INTO P_TOTAL
  WHERE KALNR = P_KALNR
  AND KALKA = '01'           "成本核算类型=PPC1
  AND TVERS = '1'            "成本核算版本DEVK901121
  AND KADKY = G_DATE1
  AND TYPPS <> ''            "项目类别
  AND LEDNR = '00'
  AND BZOBJ = 0
  AND BWVAR = '001'
  AND KKZMA = ''
  AND POSNR <> ''.
ENDFORM.
*&---------------------------------------------------------------------*
*调用物料名称
*&---------------------------------------------------------------------*
FORM. F_GET_PRODNAME USING P_PRODNO CHANGING P_MAKTX.
  SELECT MAKTX
    FROM MAKT
    INTO P_MAKTX
    WHERE SPRAS = '1'
      AND MATNR = P_PRODNO.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用物料类型
*&---------------------------------------------------------------------*
FORM. F_GET_MTART USING P_PRODNO CHANGING P_MTART.
  SELECT MTART
  FROM MARA
  INTO P_MTART
  WHERE MATNR = P_PRODNO.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用成本要素名称
*&---------------------------------------------------------------------*
FORM. F_GET_CBYSNAME USING P_KSTAR CHANGING P_KTEXT.
  SELECT KTEXT
    FROM CSKU
    INTO P_KTEXT
    WHERE SPRAS = '1'
      AND KTOPL = '1000'
      AND KSTAR = P_KSTAR.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用供应商账号
*&---------------------------------------------------------------------*
FORM. F_GET_LIFNR USING P_INFNR CHANGING P_LIFNR.
  SELECT LIFNR
    FROM EINA
    INTO P_LIFNR
    WHERE INFNR = P_INFNR.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用OH/LABOR的工作中心
*&---------------------------------------------------------------------*
FORM. F_GET_ARBID USING P_ARBID CHANGING P_ARBPL.
  SELECT ARBPL
    FROM CRHD
    INTO P_ARBPL
    WHERE BJTY = 'A'
      AND BJID = P_ARBID.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*     普通报表格式的打印
*&---------------------------------------------------------------------*
FORM. F_PRINT_REPORT.
  DATA L_LINE(2) TYPE I VALUE 0.
  LOOP AT IT_PRINT_001.
    L_LINE = L_LINE + 1.
    IF L_LINE = 23.
      NEW-PAGE.
    ENDIF.
    IF IT_PRINT_001-NO <> '1' AND IT_PRINT_001-NO <> ''.
      GRID1 IT_PRINT_001-TYTXT(18) IT_PRINT_001-TIERNO
            IT_PRINT_001-RECO_CODE(18) IT_PRINT_001-RECO_NAME
            IT_PRINT_001-PMEHT IT_PRINT_001-MENGE
            IT_PRINT_001-TOTAL IT_PRINT_001-AVOAU
            IT_PRINT_001-AUSCH.
      GRID2 IT_PRINT_001-KSTXT IT_PRINT_001-PEINH.
      ULINE.
    ELSEIF IT_PRINT_001-NO = '' AND IT_PRINT_001-TYTXT <> '报价系数' .
      GRID1 IT_PRINT_001-TYTXT(18) '' '' '' '' ''
            IT_PRINT_001-TOTAL '' ''.
      GRID2 IT_PRINT_001-KSTXT ''.
      ULINE.
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/765243/viewspace-253299/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/765243/viewspace-253299/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值