单据列表获取即时库存更新到实体字段实现方案原创
金蝶云社区-邱育华
邱育华
32人赞赏了该文章 1661次浏览 未经作者许可,禁止转载编辑于2022年06月15日 15:07:02

一、【业务需求】

列表中查询物料的即时库存能否直接更新到实体字段,能保存到指定字段用于业务人员查看和导出Excel作为业务评估一个参数。


二、【功能分析】

当前列表中获取即时库存调用的方式是操作方法,配置"获取即时库存操作",只能在列表中自动生成一个非实体字段用于展示即时库存,有几个问题

1、该字段不支持引出

2、无法持久化,每次触发查询刷新列表等操作需要重新获取


列表配置获取即时库存参考文章:列表如何显示即时库存


三、【实现】

1、单据扩展数量类型,实体字段,如:"当前库存"

image.png


2、启用系统标准功能,配置"获取即时库存操作",启用对应的列表插件

image.png


3、二开插件,重写AfterDoOperation事件,触发获取即时库存操作后,插件会返回获取到的即时库存的数据包,根据即时库存数据包进行对应更新处理


以其他出库单为例:

import clr
clr.AddReference('System')
clr.AddReference('System.Data')
clr.AddReference('Kingdee.BOS')
clr.AddReference('Kingdee.BOS.Core')
clr.AddReference('Kingdee.BOS.App.Core')
clr.AddReference('Kingdee.BOS.App')
clr.AddReference('Kingdee.BOS.DataEntity')
clr.AddReference('Kingdee.BOS.ServiceHelper')
clr.AddReference('Kingdee.BOS.Contracts')
clr.AddReference('Kingdee.K3.Core')

from System import *
from Kingdee.BOS.Log import Logger
from Kingdee.BOS import *
from Kingdee.BOS.Core import *
from Kingdee.BOS.Contracts import *
from System.Data import *
from System.Collections import *
from Kingdee.BOS.App.Data import *
from System.Collections.Generic import List
from System.Collections.Generic import Dictionary
from System import StringComparison
from Kingdee.BOS.ServiceHelper import *
from Kingdee.BOS.Core.DynamicForm.PlugIn.Args import *
from Kingdee.K3.Core.SCM.Args import *
from Kingdee.BOS.Core.List.PlugIn import *
     
def AfterDoOperation(e):
    if e.Operation.OperationId != 149:
        return
    
    invStockResult = e.OperationResult.FuncResult    
    if invStockResult == None:
        return
        
    havaUpdateInvs = Dictionary[object,object]()
    for stockResult in invStockResult:
        entryId = stockResult.EntryId
        stockQty = stockResult.StockQty
        havaUpdateInvs[entryId] = stockQty
        
    if havaUpdateInvs.Count > 0:
        lstSqlObj = List[SqlObject]()    
        invTmpTable = DBServiceHelper.CreateTemporaryTableName(this.Context)
        BuildUpdateInvQtyTmpTable(this.Context, invTmpTable)
        
        InvQtyDt = DataTable(invTmpTable)
        otColumn1 = DataColumn()
        otColumn1.ColumnName = "FENTRYID"
        InvQtyDt.Columns.Add(otColumn1)
        
        otColumn2 = DataColumn()
        otColumn2.ColumnName = "FSTOCKQTY"
        InvQtyDt.Columns.Add(otColumn2)
        
        pdict = dict(havaUpdateInvs)
        for key,value in pdict.items():
            dr = InvQtyDt.NewRow()
            dr["FENTRYID"] = Convert.ToInt64(key)
            dr["FSTOCKQTY"] = Convert.ToDecimal(value)
            InvQtyDt.Rows.Add(dr)
            
        DBUtils.BulkInserts(this.Context, InvQtyDt)
        
        sql = '''MERGE INTO T_STK_MISDELIVERYENTRY IT USING   
                        (
                            SELECT T1.FENTRYID, T1.FSTOCKQTY FROM {0} T1 JOIN T_STK_MISDELIVERYENTRY T2 ON T1.FENTRYID = T2.FENTRYID
                        ) UT ON (IT.FENTRYID = UT.FENTRYID)
                        WHEN MATCHED THEN UPDATE 
                        SET IT.FINVENTORYQTY = UT.FSTOCKQTY;'''.format(invTmpTable)
        paras = List[SqlParam]()
        sqlObject = SqlObject(sql, paras)
        lstSqlObj.Add(sqlObject)
        
        sql = "DROP TABLE {0}".format(invTmpTable)
        lstSqlObj.Add(sqlObject)
        
        if lstSqlObj.Count > 0:
            DBUtils.ExecuteBatch(this.Context, lstSqlObj)    
            
def BuildUpdateInvQtyTmpTable(ctx, tempTableName):
    sqlTM = " ( FENTRYID INT NOT NULL DEFAULT(0), FSTOCKQTY DECIMAL(23,10) NOT NULL DEFAULT (0))"
    sql = " CREATE TABLE {0} {1} ".format(str(tempTableName), str(sqlTM)) 
    sqls = List[str]()
    sqls.Add(sql)
    DBUtils.ExecuteBatchWithTime(ctx, sqls, sqls.Count, 120)


实现效果:

image.png


image.png



注意:

1、e.Operation.OperationId == 149 表示是"获取即时库存操作"按钮触发

2、针对不同单据需修改更新sql语句中的单据明细表名

3、更新取决于列表页选中的数据,涉及到列表分页的数据将无法处理到


赞 32