--[[ 版本: Version 1.0 创建日期: 2023-6-16 创建人: HAN 功能: 和盘点相关的一些标准函数 -- Create_CountOrder_ByCountPlan 根据盘点计划创建盘点单 -- Count_PostProcess 盘点后处理 更改说明: --]] wms_base = require ("wms_base") local wms_count = {_version = "0.1.1"} local COUNT_PLAN_TYPE_GOODS = 1 -- 货品盘点 local COUNT_PLAN_TYPE_LOCATION = 2 -- 货位盘点 --[[ 根据盘点计划 count_plan 创建一个盘点单数据对象,触发 num 个【】计划盘点容器进行"生成盘点货品明细", -- method 盘点方法 1 -- 人工到货位盘点 2 -- 自动设备搬运到站台 -- station 如果method = 2 必须有值 ]] function wms_count.Create_CountOrder_ByCountPlan( strLuaDEID, count_plan, method, station, num ) local nRet, strRetInfo, n -- step1:输入参数合法性检查 if ( count_plan == nil or count_plan == '') then return 1, "count_plan 必须有值!" end if ( method == nil or type(method) ~= "number" ) then method = 2 end if ( method == 2 ) then if ( station == nil or station == '') then return 1, "station 必须有值!" end end if ( num == nil ) then num = 0 end -- 获取常量 盘点差异需要审核 = Y local diff_need_review = wms_base.Get_sConst( strLuaDEID, "盘点差异需要审核", 1 ) local diff_hand_method = 0 -- 1 表示有差异需要审核后才能变 if ( diff_need_review == "Y" ) then diff_hand_method = 1 end -- step2:创建盘点单 local count_order = m3.AllocObject(strLuaDEID,"Count_Order") count_order.cp_no = count_plan.cp_no count_order.wh_code = count_plan.wh_code count_order.area_code = count_plan.area_code count_order.method = method -- 1 表示是人工盘点,这是新兴项目的要求 count_order.num = num count_order.station = station count_order.count_type = count_plan.type count_order.diff_hand_method = diff_hand_method nRet, count_order = m3.CreateDataObj( strLuaDEID, count_order ) if (nRet ~= 0) then return 1, "创建【盘点单】失败!"..count_order end -- step3:查询盘点计划中没有盘点单的【计划盘点容器】 -- 特别注意需要 多页查询 local strCondition = "S_CP_NO = '"..count_plan.cp_no.."' AND N_B_STATE = 0" nRet, strRetInfo = mobox.queryDataObjAttr2( strLuaDEID, "CP_Count_Container", strCondition, strOrder, 100 ) if ( nRet ~= 0 ) then return 1, "queryDataObjAttr2: "..strRetInfo end if ( strRetInfo == '' ) then return 1, "盘点计划'".. count_plan.cp_no.."'中没有待盘点的容器!" end local success local queryInfo success, queryInfo = pcall( json.decode, strRetInfo ) if ( success == false ) then return 1, "queryDataObjAttr2 返回结果啊非法的JSON格式!" end local queryID = queryInfo.queryID local nPageCount = queryInfo.pageCount local nPage = 1 local dataSet = queryInfo.dataSet -- 查询出来的数据集 local datajson = { count_type = count_plan.type, -- 盘点类型,这个在WFP的脚本里有用 count_order_no = count_order.count_no, -- 盘点单号 count_method = method, -- 盘点方法 diff_hand_method = diff_hand_method, -- 盘点有差异处理方法 station = station -- 盘点站台 } local count = 1 while (nPage <= nPageCount) do for n = 1, #dataSet do -- step3.1: 后台触发【计划盘点容器】的 Create_Count_CG_Detail -- 考虑到生成盘点货品明细的时间会较长用 WFP 来进行处理 local add_wfp = { wfp_type = 1, -- 触发数据对象事件(指定数据对象标识) datajson = datajson, cls = "CP_Count_Container", obj_id = dataSet[n].id, trigger_event = "Create_Count_CG_Detail" } nRet, strRetInfo = m3.AddSysWFP( strLuaDEID, add_wfp ) if ( nRet ~= 0 ) then return 1, strRetInfo end if ( num > 0 ) then -- 如果num=0 就触发所有容器 if ( count == num ) then goto finish_step end end count = count + 1 end nPage = nPage + 1 if ( nPage <= nPageCount ) then -- 取下一页 nRet, strRetInfo = mobox.queryDataObjAttr2( queryID, nPage) if ( nRet ~= 0 ) then return 1, "queryDataObjAttr2失败! nPage="..nPage.." "..strRetInfo end queryInfo = json.decode(strRetInfo) dataSet = queryInfo.dataSet end end -- step4:更新盘点单中盘点容器数量, if ( count < num or num == 0 ) then -- 更新盘点单盘点容器数量 strCondition = "S_COUNT_NO = '"..count_order.count_no.."'" local strSetSQL = "N_COUNT_NUM = "..count nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "Count_Order", strCondition, strSetSQL) if (nRet ~= 0) then return 1, "设置【盘点单】信息失败!"..strRetInfo end end ::finish_step:: -- step5:更新盘点计划中的 进行盘点容器数量 strCondition = "S_CP_NO = '"..count_plan.cp_no.."'" nRet, strRetInfo = mobox.incDataObjAccQty( strLuaDEID, "Count_Plan", strCondition, "N_PLAN_TOTAL", "N_ACC_COUNT", count ) if ( nRet ~= 0 ) then return 1, "incDataObjAccQty(Count_Plan)失败! "..strRetInfo end if ( strRetInfo ~= '') then return 1, "盘点计划号'"..count_order.count_no.."'的累计盘点容器数量异常,无法增加!" end return 0 end --[[ 根据[CP_Count_Container]cp_cntr 查询【Count_CG_Detail】如果有差异就生成【Count_Diff】 ]] function wms_count.Count_PostProcess( strLuaDEID, cp_cntr ) local nRet, strRetInfo local strCondition = "S_CC_NO = '"..cp_cntr.cc_no.."'" -- 判断盘点计划类型是否是货物盘点,如果是,需要更新货品盘点的结果 【CP_Good_List】 local cp_no = lua.Get_StrAttrValue( cp_cntr.cp_no ) local first_cc_no = lua.Get_StrAttrValue( cp_cntr.first_cc_no ) -- 复盘会有这个属性,表示对什么进行复盘 local is_good_count = false -- 是货品盘点 if ( '' ~= cp_no ) then local count_plan nRet, count_plan = m3.GetDataObjectByKey( strLuaDEID, "Count_Plan", "S_CP_NO", cp_cntr.cp_no ) if ( nRet ~= 0 ) then return 1, "GetDataObjectByKey失败"..count_plan end if ( count_plan.type == COUNT_PLAN_TYPE_GOODS ) then is_good_count = true end end nRet, data_objs = m3.QueryDataObject(strLuaDEID, "Count_CG_Detail", strCondition ) if (nRet ~= 0) then return 1, "QueryDataObject失败!"..data_objs end if ( data_objs == '' ) then return 0 end local n local have_diff = false local obj_attrs local count_diff local strCondition, strUpdateSql -- 遍历【Count_CG_Detail】 for n = 1, #data_objs do obj_attrs = m3.KeyValueAttrsToObjAttr(data_objs[n].attrs) qty = lua.StrToNumber( obj_attrs.F_QTY ) act_qty = lua.StrToNumber( obj_attrs.F_ACT_QTY ) -- 盘点数量 if ( is_good_count ) then strCondition = "S_ITEM_CODE = '"..obj_attrs.S_ITEM_CODE.."' AND S_CP_NO = '"..cp_no.."'" strUpdateSql = "F_ACT_QTY = F_ACT_QTY + "..act_qty nRet, strRetInfo = mobox.updateDataAttrByCondition(strLuaDEID, "CP_Good_List", strCondition, strUpdateSql) if (nRet ~= 0) then return 1, "更新【计划盘点货品】 实际数量失败!"..strRetInfo end end if ( qty ~= act_qty ) then if ( first_cc_no == '' ) then count_diff = m3.AllocObject(strLuaDEID,"Count_Diff") count_diff.cc_no = cp_cntr.cc_no count_diff.cp_no = cp_no count_diff.cntr_code = cp_cntr.cntr_code count_diff.count_no = cp_cntr.count_no count_diff.cg_detail_id = obj_attrs.S_CG_DETAIL_ID count_diff.wh_code = cp_cntr.wh_code count_diff.area_code = cp_cntr.area_code count_diff.qty = qty count_diff.act_qty = act_qty count_diff.cell_no = obj_attrs.S_CELL_NO count_diff.item_code = obj_attrs.S_ITEM_CODE count_diff.item_name = obj_attrs.S_ITEM_NAME count_diff.item_state = lua.StrToNumber( obj_attrs.N_ITEM_STATE ) count_diff.batch_no = obj_attrs.S_BATCH_NO count_diff.serial_no = obj_attrs.S_SERIAL_NO count_diff.erp_wh_code = obj_attrs.S_ERP_WH_CODE count_diff.end_user = obj_attrs.S_END_USER count_diff.owner = obj_attrs.S_OWNER count_diff.supplier = obj_attrs.S_SUPPLIER_NO count_diff.uom = obj_attrs.S_UOM count_diff.ext_attr1 = obj_attrs.S_EXT_ATTR1 count_diff.ext_attr2 = obj_attrs.S_EXT_ATTR2 count_diff.ext_attr3 = obj_attrs.S_EXT_ATTR3 count_diff.ext_attr4 = obj_attrs.S_EXT_ATTR4 count_diff.ext_attr5 = obj_attrs.S_EXT_ATTR5 nRet, count_diff = m3.CreateDataObj( strLuaDEID, count_diff ) if ( nRet ~= 0 ) then return 1, 'mobox 创建【盘点差异表】对象失败!'..count_diff end have_diff = true else -- 复盘处理差异,首先获取原先最早盘点容器流水号中的差异 strCondition = "S_CC_NO = '"..first_cc_no.."' AND S_CG_DETAIL_ID = '"..obj_attrs.S_CG_DETAIL_ID.."'" nRet, count_diff = m3.GetDataObjByCondition( strLuaDEID, "Count_Diff", strCondition ) if ( nRet ~= 0 ) then return 1, "获取【盘点差异表】信息失败!"..count_diff end -- 判断盘点次数, 如果已经是二盘 strUpdateSql = "N_B_STATE = 1, F_ACTUAL_QTY = "..act_qty if ( count_diff.count_time == 2 ) then -- 不允许再复盘 strUpdateSql = strUpdateSql..", N_COUNT_TIME = 3, C_RECOUNT = 'Y'" else strUpdateSql = strUpdateSql..", N_COUNT_TIME = 2 " end nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Count_Diff", strCondition, strUpdateSql ) if ( nRet ~= 0 ) then return 1, "更新【Count_Diff】信息失败!"..strRetInfo end have_diff = true end end end -- 盘点单{累计盘点数量}+1 strCondition = "S_COUNT_NO = '"..cp_cntr.count_no.."'" nRet, strRetInfo = mobox.incDataObjAccQty ( strLuaDEID, "Count_Order", strCondition, "N_COUNT_NUM", "N_ACC_FINISH", 1 ) if ( nRet ~= 0 or strRetInfo ~= '') then return 1, '在增加【盘点单】中的累计盘点数量时失败!'..strRetInfo end -- 更新计划盘点容器中的 C_HAVE_DIFF = 'Y' 表示这个容器盘点有差异 if ( have_diff ) then strCondition = "S_ID = '"..cp_cntr.id.."'" local strSetAttr = "C_HAVE_DIFF = 'Y'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "CP_Count_Container", strCondition, strSetAttr ) if ( nRet ~= 0 ) then return 1, "更新【CP_Count_Container】信息失败!"..strRetInfo end end return 0 end return wms_count