生产订单增强之修改工单数量弹窗填写原因及写入操作日志

73 阅读5分钟

生产工单增强之前有写过一篇文章是关于PPCO0007做研发工单的结算规则校验以及自动填充的。现在来讲一下另外一个增强WORKORDER_UPDATE以及PPCO0001。本文内容基于公司的具体业务,本人仅是菜鸟一名,如有错误请指出交流🤝。

有时候生产订单创建后可能会做修改,如果修改“工单数量”以及“报废数量”这些重要的信息,我们需要对每次修改都进行记录,这样好溯源。

CO02修改工单增强

修改工单数量弹窗填写原因

1. 需求:当修改工单数量的时候,点击保存需要弹窗填写扩单的原因。

2. 界面:当你进入CO02对应工单的界面后,修改了总数量,点击保存会弹出输入框需要填入扩单的原因;没有修改工单数量或者修改其他内容不会弹窗;需要填写扩单原因没有填写会报错并停留在当前页面,不允许保存。

image.png

image.png

3. 实现workorder_update增强点

*点击保存会触发该保存前增强
METHOD if_ex_workorder_update~at_save.  
    DATA: lt_fields   TYPE TABLE OF sval,  
          ls_field    TYPE sval,  "弹窗填写的字段
          lv_reason   TYPE c, "扩单原因  
          g_lv_reason TYPE zco02_log_table-gamngreason.  
    *首先判断是否有修改了工单数量,如果修改才做弹窗处理
    IF sy-tcode = 'CO02'.
    SELECT SINGLE gamng INTO @DATA(lv_gamng) FROM afko WHERE aufnr = @is_header_dialog-aufnr.  
    IF sy-subrc = 0 AND lv_gamng <> is_header_dialog-gamng.  
      ls_field-fieldname = 'GAMNGREASON'.  
      ls_field-tabname   = 'ZCO02_LOG_TABLE'.  
      ls_field-fieldtext  = '扩单原因'.  
      ls_field-value       = ''.  
      APPEND ls_field TO lt_fields.  
      "调用输入框弹窗函数
      CALL FUNCTION 'POPUP_GET_VALUES'  
        EXPORTING  
          popup_title     = '扩单原因'  
        IMPORTING  
          returncode      = lv_reason  
        TABLES  
          fields          = lt_fields  
        EXCEPTIONS  
          error_in_fields = 1  
          OTHERS          = 2.  
      IF lv_reason IS INITIAL.  
        LOOP AT lt_fields ASSIGNING FIELD-SYMBOL(<ls_fields>).  
          IF <ls_fields>-value IS NOT INITIAL.  
            g_lv_reason = <ls_fields>-value.  
          ELSE.  
            MESSAGE '请输入原因!' TYPE 'E' DISPLAY LIKE 'E'.  
          ENDIF.  
        ENDLOOP.  
      ELSE.  
        MESSAGE '请输入原因!' TYPE 'E' DISPLAY LIKE 'E'.  
      ENDIF. 
      "将获取到的扩单原因数据存入内存中,到后面-->插入数据库之前的增强中取出数据,插入到操作日志中。这个到下面章节2开始讲。
      "这使用的是同一**主会话**(同一窗口)内的程序
      EXPORT g_lv_reason FROM g_lv_reason TO MEMORY ID 'ZORDER_REASON'.  
     ENDIF.  
    ENDIF.  
  ENDMETHOD.

4. 碎碎念:本来是打算在PPCO0001这里做增强的,但是发现在此处做页面的交互行为并不会阻止她往下走做保存写入数据库处理,因为此处在做COMMITWORK。

修改工单数量写入操作日志

1. 需求:当修改工单数量以及报废数量的时候,点击保存同时记录修改的记录信息,方便溯源。

2. 实现PPCO0001增强,这个触发是在数据保存到数据库之前。

* 增强1:记录修改生产订单中关键字段的日志  
* 当为生产订单时才继续执行  
  CHECK header_table-autyp = '10'.  "订单类别:10-PP生产订单  
* 当不是创建时才继续执行   
  CHECK header_table-vbkz <> 'I'.   "抬头更新标识:I-新增   
  DATA: it_log LIKE zco02_log_table OCCURS 0 WITH HEADER LINE,   "日志内表  
        lv_log LIKE zco02_log_table.   "日志内表  
  
  DATA: ipx      LIKE msxxlist-hostadr,  "IP地址(16进制)  
        ip(15)   TYPE c,                 "IP地址(10进制字符串)  
        host(20) TYPE c.                 "主机名  
  
  DATA: vi_opnum(5) TYPE n,   "流水码变量  
        vs_str      TYPE string.   "字符串变量  
  
  DATA: g_lv_reason TYPE zco02_log_table-gamngreason.  
  
* 定义去除字符串中小数点后无用的0  
*(只适用于带小数点的数字字符串)  
  DEFINE del_zero_r.  
  
    SHIFT &1 RIGHT DELETING TRAILING  '0 '.    "去掉末尾0  
    SHIFT &1 RIGHT DELETING TRAILING  '. '.    "若小数位全是0,则去掉小数点,只保存整数位  
    CONDENSE &1 NO-GAPS.  
  
  END-OF-DEFINITION.  
  
*========================================  
* 定义记录修改的宏(对单行表)  
*========================================  
  DEFINE ulog_line.  
*  ---------------------------------------------------  
*  &1:记录新值的表名称  
*  &2:记录旧值的表名称与新表的差异部分(通常为OLD)  
*  &3:比较的字段名称  
*  &4:操作对象类型  
*  &5:操作对象描述  
*  &6: 扩单原因  
*  ---------------------------------------------------  
    IF &1-&3 <> &1_&2-&3.  
      vi_opnum     = vi_opnum + 1"记录本次操作的流水编码(自增1)  
      it_log-opnum = vi_opnum.     "记录本次操作的流水编码  
  
      it_log-optyp = 'U'.          "操作类型:U-更新  
      it_log-objtp = '&4'.         "操作对象类型(抬头、组件、工艺等)  
      it_log-objnm = '&5'.         "操作对象描述  
      it_log-vlold = &1_&2-&3.     "操作对象的旧值  
      it_log-vlnew = &1-&3.        "操作对象的新值  
      it_log-gamngreason = &6.          "扩单原因  
  
      APPEND it_log.               "追加记录  
      CLEAR it_log.  
    ENDIF.  
  
  END-OF-DEFINITION.  
  
*==================================  
* 订单抬头修改 --目前只需要记录“订单总数量”和“废品数量”的修改记录  
*==================================  
  IF header_table-vbkz = 'U'.  "如果改变了数据
**/ 在此处取出内存中扩单原因字段的值
    IMPORT g_lv_reason TO g_lv_reason from memory id 'ZORDER_REASON'.    
  
    ulog_line: header_table old gamng 订单抬头 订单总数量 g_lv_reason,  
               header_table old gasmg 订单抬头 订单废品数量 ''.
  ENDIF.  
  
* 如有修改日志产生时才进行记录  
  IF NOT it_log[] IS INITIAL.  
*  获取客户端IP地址(16进制)、主机名  
    CALL FUNCTION 'TH_USER_INFO'  
      IMPORTING  
        hostaddr = ipx    "IP地址(16进制)  
        terminal = host.  "主机名  
*  转换IP地址(16进制转换为10进制字符串)  
    CALL FUNCTION 'GWY_IPADR2STRING'  
      EXPORTING  
        ipadr  = ipx  
      IMPORTING  
        string = ip.   "IP地址(10进制字符串)  
*  补充日志内表的公共部分  
    GET TIME.   "获取最新的时间  
    it_log-aufnr  = header_table-aufnr.  "订单编码  
    it_log-kdauf  = header_table-kdauf_aufk.  "销售订单号  
    it_log-kdpos  = header_table-kdpos_aufk.  "销售订单行号  
    it_log-opdat  = sy-datum.            "操作日期(服务器)  
    it_log-optim  = sy-uzeit.            "操作时间(服务器)  
    it_log-tcode  = sy-tcode.            "事务代码  
    it_log-opusr  = sy-uname.            "操作客户端用户名  
    it_log-opipa  = ip.                  "操作客户端IP地址  
    it_log-ophos  = host.                "操作客户端主机名  
  
    MODIFY it_log TRANSPORTING aufnr opdat optim tcode opusr opipa ophos kdauf kdpos  
                               WHERE aufnr IS INITIAL.   "全部更新
  
*  ---------------------------  
*  将日志保存至数据库  
*  ---------------------------  
    INSERT zco02_log_table FROM TABLE it_log ACCEPTING DUPLICATE KEYS.  "忽略索引相同的记录.  
    CLEAR lv_log.      
 ENDIF.

2. 表结构:新建一个表来保存操作记录,具体字段如下:

image.png