/// ///LOGIC CLASS FOR TABLE t_wmsOutPickPort ///By wm with codesmith. ///on 06/17/2020 /// using System; using System.Collections.Generic; using System.Linq; using System.Text; using DeiNiu.wms.Data.Model; using System.Data; using System.Transactions; using DeiNiu.Utils; namespace DeiNiu.wms.Logical { [Serializable] public class lWmsOutPickPort :lbase { WmsOutPickPort _obj; public lWmsOutPickPort() { initialize(); } WmsInRequestDetail _inRequestDetail; public WmsInRequestDetail getWmsInRequestDetail { get { if (_inRequestDetail == null) { _inRequestDetail = new WmsInRequestDetail(); } _inRequestDetail.operater = operId; return _inRequestDetail; } } WmsInUpPort _inUpPort; public WmsInUpPort getWmsInUpPort { get { if (_inUpPort == null) { _inUpPort = new WmsInUpPort(); } _inUpPort.operater = operId; return _inUpPort; } } public WmsOutPickPort getWmsOutPickPort { get { if (_obj == null) { _obj = new WmsOutPickPort(); } _obj.operater = operId; return _obj; } } public lWmsOutPickPort(int operId) : base(operId) { initialize(); } WmsWave _wmsWave ; WmsWave wmsWave { get { if (_wmsWave == null) { _wmsWave = new WmsWave(); } _wmsWave.operater = operId; return _wmsWave; } } /// /// get all data /// public DataSet getAllData() { return _obj.Query(); } /// /// get all data /// public DataSet getAllActiveData() { return _obj.QueryActived(); } /// /// get a record by id /// public void initialize(int id) { _obj = id != 0 ? new WmsOutPickPort(id) : new WmsOutPickPort(); } /// /// get a record by id 0 /// public void initialize() { initialize(0); } /// /// get a record by id /// public void initialize(DataRow dr) { _obj = new WmsOutPickPort(dr); } protected override DeiNiu.Data.BaseObject.BaseModel getModel() { return _obj; } //begin cust db operation, query, excute sql etc. internal int add(WmsOutPickPort obj) { return obj.Add(); } internal DataSet getWaveDetails(string waveNo, int rowStart, int rowEnd) { return _obj.getWaveDetails(waveNo, rowStart, rowEnd); } internal DataTable getWaveDetails(string waveNo) { return _obj.getWaveDetails(waveNo ); } internal DataSet getWavePages(int state, int rowStart, int rowEnd) { return wmsWave.queryPages(state, rowStart, rowEnd); } internal DataTable getPickInfo(string waveNo, int volType) { return _obj.getPickInfo(waveNo, volType); } internal DataTable getPickInfo(string waveNo) { return _obj.getPickInfo(waveNo ); } internal DataTable getPickSummary(string waveNo, int volType) { return _obj.getPickSummary(waveNo, volType); } // to move to lStockOutPort /// /// 出库分拣任务 /// 按相同的集货区域的拣货单合并拣货 /// 同一个波次按拣货区域划分为不同的任务 /// 每个任务有一个或多个拣货明细 /// 每个任务考虑作为播种亮灯的播种单号 /// /// public bool createPickWaves() { DataTable dt = getWmsOutPickPort.getNewPickTasks(new WaveRule().getCurrentActiveRule(enumWaveRuleType.普通波次)); if (dt.Rows.Count == 0) { return false; } logTest.Debug("start to process new waves...count:" + dt.Rows.Count); int lastTranArea = -100, lastPartion = -100, lastVolType = -100, lastOrderType = -100;//,lastChannel=-100; string lastPickRequest = "", waveNo = "", jobNo = "",lastWaveNo=""; bool isNewWave = false, isNewJob = false; Dictionary waveJobs = new Dictionary(); int waveSize = 0; int maxSize = WmsConstants.WAVE_ORDERS_CNT; int jobMax = WmsConstants.MAX_JOBS_IN_A_WAVE; int jobcnt = 0; int taskcnt = 0; bool isCreateFlowTask = WmsConstants.OUT_LIGHT_ENABLE ? WmsConstants.DPS_TASK_GENERATION :true ; WmsOutPickPort _obj; WmsFlow wmsflow; decimal boxMax = 0; decimal boxPercent = 0; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { //IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted, IsolationLevel = System.Transactions.IsolationLevel.Serializable, Timeout = new TimeSpan(0, 10, 0) } )) { // logSpec.Debug("start work...to create wave and jobs "); foreach (DataRow dr in dt.Rows) { // int channel = Convert.ToInt32(dr["channel"].ToString()); _obj = new WmsOutPickPort(dr); boxMax = Convert.ToDecimal(dr["full_max"].ToString()); if (boxMax > 0) { boxPercent += (_obj.count / boxMax) * 100; } if (lastTranArea == -100) { lastTranArea = _obj.tranArea; } if (lastPartion == -100) { lastPartion = _obj.partion; } if (lastVolType == -100) { lastVolType = _obj.volType; } // if (lastChannel == -100) { // lastChannel = channel; } /* if (lastOrderType == -100) { lastOrderType = _obj.or; } */ if (lastPickRequest != _obj.pickOrderNo) { waveSize++; //TODO:更新拣货状态 1. 整库拣货状态 2. 零库拣货状态 if (String.IsNullOrEmpty(lastPickRequest)) { lastPickRequest = _obj.pickOrderNo; } WmsOutPickRequest pr = new WmsOutPickRequest(lastPickRequest); if (pr.state != (int)enumOutStockRequestStatus.等待补货) { pr.state = (int)enumOutStockRequestStatus.正在分拣; pr.Update(); } jobcnt = jobMax; //每个job只属于一个分拣单 } isNewWave = String.IsNullOrEmpty(waveNo) || lastTranArea != _obj.tranArea //集货目的地不同,开新波次 || waveSize == maxSize; //达到波次最大订单数,开新波次 if (isNewWave) { /*if (!string.IsNullOrEmpty(waveNo) && waveJobs.ContainsKey(lastPartion)) { WmsFlow wmsflow = new WmsFlow(jobNo, waveNo); if(wmsflow.ID>0){ wmsflow.taskCnt = jobcnt; wmsflow.Update(); } }*/ lastWaveNo = waveNo; waveNo = Util.getOrderNo(enumCreateOrderType.waveOrder, _obj.getNextSeq(enumCreateOrderType.waveOrder)); waveJobs = new Dictionary(); waveSize = 0; WmsWave wave = new WmsWave(); wave.waveNo = waveNo; wave.type = _obj.recType; wave.operater = operId; wave.Add(); } isNewJob = isNewWave || lastPartion != _obj.partion || jobcnt >= jobMax || !waveJobs.ContainsKey(_obj.partion) //|| lastChannel != channel || boxPercent>=100; if (jobcnt >= maxSize) { } if (isNewJob) { boxPercent= 0; isCreateFlowTask = WmsConstants.OUT_LIGHT_ENABLE ? WmsConstants.DPS_TASK_GENERATION : true ; isCreateFlowTask = isCreateFlowTask || lastVolType > 0; // LogHelper.WriteLog(typeof(lWmsOutPickPort), string.Format("1 isCreateFlowTask: {0},lastVolType {1}", isCreateFlowTask, lastVolType)); if (isCreateFlowTask && !string.IsNullOrEmpty(jobNo) ) { wmsflow = new WmsFlow(jobNo); if (wmsflow.ID > 0) { wmsflow.taskCnt = taskcnt;// waveJobs[lastPartion].Length; wmsflow.Update(); } } jobcnt = 0; taskcnt = 0; jobNo = Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo)); waveJobs[_obj.partion] = jobNo; isCreateFlowTask = WmsConstants.OUT_LIGHT_ENABLE ? WmsConstants.DPS_TASK_GENERATION :true ; isCreateFlowTask = isCreateFlowTask || _obj.volType > 0; // LogHelper.WriteLog(typeof(lWmsOutPickPort), string.Format("2 isCreateFlowTask: {0},_obj.volType {1}", isCreateFlowTask, _obj.volType)); if (isCreateFlowTask) { wmsflow = new WmsFlow(); wmsflow.operater = operId; wmsflow.orderNo = _obj.pickOrderNo;// waveNo; wmsflow.type = (int)Util.getTaskType(_obj.recType); wmsflow.typeName = Util.getTaskType(_obj.recType).ToString(); wmsflow.task = jobNo; wmsflow.fromPartion = _obj.partion; wmsflow.toPartion = _obj.tranArea; wmsflow.taskPartion = _obj.partion; // wmsflow.fromLocationId=_obj.locationId; wmsflow.Add(); } } else { jobNo = waveJobs[_obj.partion]; } jobcnt++; taskcnt++; _obj.waveOrder = waveNo; _obj.jobNo = jobNo; _obj.operater = operId; _obj.Update(); //lastChannel = channel; lastTranArea = _obj.tranArea; lastPickRequest = _obj.pickOrderNo; lastPartion = _obj.partion; lastVolType = _obj.volType; } if (!string.IsNullOrEmpty(waveNo) ) { wmsflow = new WmsFlow(jobNo ); if (wmsflow.ID > 0) { wmsflow.taskCnt = taskcnt; wmsflow.Update(); } } scope.Complete(); } logTest.Debug("end process new waves.. in last wave, created job count " +jobcnt); return true; } WmsOutDesk _desk; WmsOutDesk desk { get { if (_desk == null) { _desk = new WmsOutDesk(); _desk.operater = operId; } return _desk; } } WmsOutDesk _seedsDesk; WmsOutDesk seedsDesk { get { if (_seedsDesk == null) { _seedsDesk = new WmsOutDesk(); } return _seedsDesk; } } static List lblist = new List(); static Dictionary comLables = new Dictionary(); void initialDebugSetting() { DataTable dt = new Node().QueryByFlag(10001); foreach (DataRow dr in dt.Rows) { Node node = new Node(dr); if (!node.isOn) { continue; } try { string labels = node.description; string[] lbs = labels.Split(','); foreach (string s in lbs) { comLables[Convert.ToInt32(s.Trim())] = Convert.ToInt32(node.name.Trim()); lblist.Add(Convert.ToInt32(s.Trim())); } } catch { continue; } } } private string waveOrder = ""; public void newBulkDPSPickWave() { if (!WmsConstants.OUT_LIGHT_ENABLE) { return; } //播种筛选, //适合播种的客户订单合并成一个、多个大订单,统一捡出后进行播种操作 //1. 单个订单的品种少 、数量少 //2. 订单数量多 //只处理订单零货部分 //加入播种选项,所有订单零货部分使用摘取+播种方式 //1.播种点数量可配置, 分别用不同颜色区分 //2.每个播种点可分播客户的数量配置, 即每个播种点处理零货订单数量( 例如配置成6个,一次捡6个客户的订单零货部分,送由一个播种点播种) //3.波次和播种点的对应关系,一个波次只摘取一个播种点的零货,还是多个播种点的数据? //4. //一个波次可以摘取订单数 = 空闲分播台数量*每个分播台可分播客户数, 分播台的订单用颜色区分 // LogHelper.debug(typeof(lWmsOutPickPort), "开始新波次。。。。。。。。。。。。。。。。。。"); DataTable dtPorts = getWmsOutPickPort.getNewPickTasks(new WaveRule().getCurrentActiveRule(enumWaveRuleType.DPS灯光波次)); LogHelper.debug(typeof(lWmsOutPickPort), string.Format("待处理任务数量:{0}", dtPorts.Rows.Count)); if (dtPorts.Rows.Count == 0) { LogHelper.debug(typeof(lWmsOutPickPort), string.Format("无订单需要处理,波次结束")); new lWmsOutPickRequest(this.operId).checkRepAndNoStockOrders(); return; } desk.restDeskStatus(enumDeskState.空闲); desk.restDeskStatus(enumDeskState.空闲, enumDeskType.播种); //播种台状态复位到空闲,是不是可以由播种员实际播种任务进度控制? _seedsDesk = desk.getRandomDesk(enumDeskState.空闲, enumDeskType.播种); ; _desk = desk.getRandomDesk(enumDeskState.空闲, enumDeskType.复核); int labelMaxInWave = WmsConstants.MAX_LABEL_DATA_IN_A_WAVE; //一个标签一个波次只能存储40条数据 #if DEBUG // if (lblist.Count == 0) { lblist.Clear(); initialDebugSetting(); } lblist.Sort(); #endif // List strecs = null; waveOrder = Util.getOrderNo(enumCreateOrderType.dpsOrder, _obj.getNextSeq(enumCreateOrderType.dpsOrder)); //waveOrder = "WV" + System.DateTime.Now.ToString("yyyyMMddHHmmss"); Dictionary labelCnt = new Dictionary(); Dictionary comCnt = new Dictionary(); Dictionary tmplabelCnt = new Dictionary(); Dictionary tmpcomCnt = new Dictionary(); bool isReachLimit = false; int waveSize = 0; //List lstPort; List lstLabel; List lstBulk; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("waveNo {0}", waveOrder)); //播种常量,达不到最小订单摘取需求的合并成大订单先统一摘取再分播 bool isSeedsEnabled = WmsConstants.OUT_BULK_SEEDS_PICK_ON; int pickGoodsTypeMin = WmsConstants.OUT_MAX_SEEDS_GOODSTYPE_CNT; //单独摘取订单 最少货物类型 int pickGoodsCountMin = WmsConstants.OUT_MAX_SEEDS_BULK_CNT_SUM; // 单独摘取订单 最少货物数量 int seedsCount = seedsDesk.seedsCount; //播种台一次播种订单数量 decimal sumBulkCnt = 0; bool isSeedPickInSameWave = true; // bool canSeedPickLessThanseedsCount = false; //单个播种拣选单数量不可少于播种能力 List seedsRequests = new List(); Dictionary seedsBulks = new Dictionary(); if (desk.ID == 0) // no free pick desk { if (isSeedsEnabled) { _seedsDesk = desk.getRandomDesk(enumDeskState.空闲, enumDeskType.播种); if (seedsDesk.ID == 0) { return; } } else { return; } } int bulkCnt = 0; int requestCnt = 0; //开始处理有零货的订单 DateTime d0 = DateTime.Now; double totoalTime = 0d; string lastAddress = ""; // foreach (WmsOutPickRequest request in requests) WmsOutPickPort wopp; string lastPickOrder = ""; List lstPort = new List(); lstBulk = new List(); int elebleId = 0, port = 0; WmsOutPickRequest request; List taskRequests = new List(); Dictionary> tasks = new Dictionary>(); Dictionary> portTasks = new Dictionary>(); foreach (DataRow dr in dtPorts.Rows) { DateTime d00 = DateTime.Now; wopp = new WmsOutPickPort(dr); if (lastPickOrder != wopp.pickOrderNo) { lastPickOrder = wopp.pickOrderNo; _desk = desk.getRandomDesk(enumDeskState.空闲, enumDeskType.复核); if (_desk.ID > 0) { request = new WmsOutPickRequest(lastPickOrder); request.desk = _desk.color; desk.state = (int)enumDeskState.任务中; desk.Update(); taskRequests.Add(request); } else { break; } } if (!tasks.Keys.Contains(lastPickOrder)) { tasks[lastPickOrder] = new List(); } if (!portTasks.Keys.Contains(lastPickOrder)) { portTasks[lastPickOrder] = new List(); } tasks[lastPickOrder].Add(new WmsStockRecord(dr)); portTasks[lastPickOrder].Add(wopp); } #region savedata foreach (WmsOutPickRequest pickRequest in taskRequests) { int lastId = 0; LogHelper.debug(typeof(lWmsOutPickRequest), " 摘果式 保存整货和零货出库分拣数据"); lstLabel = new List(); WmsOutPickLable_tmp wpl; foreach (WmsStockRecord rec in tasks[pickRequest.pickOrderNo]) { // if (rec.count == 0) if (rec.count + rec.countOuting < 1) //不支持小数 { continue; } if (lblist.Count > 0) { int id = new Random().Next(lblist.Count); //#if DEBUG rec.location.elabId = lblist[id]; //new Random().Next(minId, maxId + 1); //测试。。。随机分配标签id 为 1-3 while (lblist.Count > 1 && lastId == rec.location.elabId) { id = new Random().Next(lblist.Count); rec.location.elabId = lblist[id]; } lastId = rec.location.elabId; //#endif } wpl = new WmsOutPickLable_tmp(); wpl.pickOrderNo = pickRequest.pickOrderNo; wpl.recordId = rec.ID; wpl.color = pickRequest.desk; wpl.count = rec.count + rec.countOuting; wpl.locationId = rec.locationId; wpl.elabAddress = rec.location.elabAddress; wpl.elabId = rec.location.elabId; wpl.port = rec.location.port; wpl.orderDetailId = rec.orderDetailId; //#if DEBUG try { if (comLables.Count > 0) { wpl.port = comLables[wpl.elabId]; //rec.location.elabId < 4 ?5 :3; //测试。。。 分配标签端口为3 } } catch { } //#endif wpl.dpsOrder = waveOrder; wpl.operater = this.operId; lstLabel.Add(wpl); } //保存整货和零货出库分拣数据 try { using (TransactionScope scope1 = new TransactionScope()) { foreach (WmsOutPickLable_tmp wp in lstLabel) //建立电子拣选临时数据 { wp.Add(); } foreach (WmsOutPickPort pt in portTasks[pickRequest.pickOrderNo]) { pt.dpsOrder = waveOrder; pt.Update(); } if (lstLabel.Count > 0) { pickRequest.waveOrder = waveOrder; pickRequest.state = (int)enumOutStockRequestStatus.正在分拣; pickRequest.waveStart = pickRequest.getDateTime(); pickRequest.operater = this.operId; pickRequest.updateBulkPickStatus(pickRequest.pickOrderNo, enumOutStockPickStatus.正在分拣, operId); // pickRequest.state = pickRequest.Update(); } waveSize++; scope1.Complete(); } } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); desk.restDeskStatus(enumDeskState.空闲); throw e; } } #endregion // totoalTime += ts00.TotalSeconds; //建立零库电子拣选临时数据 new WmsOutPickRequest().saveTempData4Validation(waveOrder); WmsConstants.WAVE_CURRENT_PICK_STATUS.Clear(); WmsConstants.WAVE_CURRENT_ORDER = waveOrder; WmsConstants.WAVE_LAST_TIME = DateTime.Now; //检查待补货出货单状态 new lWmsOutPickRequest(this.operId).checkRepAndNoStockOrders(); } /// /// 返回亮灯数据 /// /// /// /// /// /// /// internal DataTable prePareLightSeeds(int deskId, string flowno, string barcode, int userId, bool isValid) { return getWmsOutPickPort.getLightSeeds(deskId, flowno, barcode); } internal DataTable getLightTasks(string query, int wareHouse, int partion, int lineId, int state,string date, bool isLight) { return getWmsOutPickPort.getLightTasks( pareseCondition(query), wareHouse, partion, lineId, state,date, isLight); } internal int clearJobLightTask(string jobNo) { return new WmsOutPickLable_tmp().clearByDpsOrder(jobNo); } internal DataTable prePareLightByJob(int userId,string jobNo,bool isValid) { operId = userId; WmsOutPickLable_tmp wpl = new WmsOutPickLable_tmp(); log.Debug(" to get pick port task for light :" +jobNo +" isValid :" +isValid); if (!isValid) { DataTable dt = getWmsOutPickPort.geTasksByJobNo(jobNo); if (dt.Rows.Count > 0) { wpl = new WmsOutPickLable_tmp(dt.Rows[0]); } else { return dt; } WmsFlow wmsflow = new WmsFlow(jobNo); wmsflow.owner = operId; using (TransactionScope scope = new TransactionScope()) { int i = 0; wpl.clearByDpsOrder(jobNo); wmsflow.Update(); wpl.clearByPartion(wpl.partion); foreach (DataRow dr in dt.Rows) { WmsOutPickPort wpp = new WmsOutPickPort(dr); log.Debug(" get pick port task :" + wpp); decimal pcs = Convert.ToDecimal(dr["pcs"].ToString()); wpl = new WmsOutPickLable_tmp(dr); wpl.count = pcs > 0 ? pcs : 1; wpl.color = wpp.virtialCnt>0? 1:3; wpl.dpsOrder = jobNo; if (dt.Columns.Contains("goodsid")) { string goodsid = dr["goodsid"].ToString().Trim().Substring(1); goodsid = goodsid.Substring(goodsid.Length - 2); try { wpl.elabAddress = Convert.ToUInt16(goodsid); } catch { } } #if DEBUG wpl.elabId = ++i; log.Debug("use fake id....." + wpl.elabId); #endif wpl.Add(); log.Debug("2 get pick port task for light :" + wpl); } scope.Complete(); } } return wpl.getByDpsOrder(jobNo); } internal DataTable getPickLightTasks(int takeBy, int partion, int orderType) { return getWmsOutPickPort.getPickLightTasks( takeBy, partion, orderType); } /* * 分配拣货任务 */ public void taskAssign(int taskBy,int partion,int lineId,int maxLocCnt=0,int maxBoxs=0, bool batchOnly=true,enumOrderType orderType = enumOrderType.销售出库) { // logTest.Debug(string.Format("1 maxLocCnt {0},maxBoxs {1}",maxLocCnt,maxBoxs)); maxLocCnt = maxLocCnt<=0?WmsConstants.MAX_PICK_LOT_CNT:maxLocCnt; maxBoxs = maxBoxs <= 0 ? WmsConstants.MAX_PICK_BOX_CNT : maxBoxs; // logTest.Debug(string.Format("2 maxLocCnt {0},maxBoxs {1}", maxLocCnt, maxBoxs)); // int lotcnt = 0,boxcnt=0; if (isJobMax(taskBy, partion, lineId, maxLocCnt, maxBoxs, batchOnly, orderType)) { return; } int lotcnt = 0, boxcnt = 0; WmsOutPickPort wop; DataTable dt = getWmsOutPickPort.getFreeTasks(partion, lineId, batchOnly,orderType,taskBy); // logTest.Debug(string.Format(" exists tasks to do , loc cnt :{0}, box cnt: {1}, free tasks cnt :{2}", lotcnt, boxcnt,dt.Rows.Count)); using (TransactionScope scope = new TransactionScope()) { foreach (DataRow dr in dt.Rows) { wop = new WmsOutPickPort(dr); lotcnt++; boxcnt += Convert.ToInt32(dr["boxcnt"].ToString()); if (lotcnt > maxLocCnt || boxcnt > maxBoxs) { // logTest.Debug(string.Format(" All tasks to do , loc cnt :{0}, box cnt: {1}",lotcnt,boxcnt)); break; } wop.takeBy = taskBy; // wop.operater = operId; wop.Update(); // log.Debug( " user " + taskBy + " task Assign :" + wop.ID); /* WmsFlow wf = new WmsFlow(wop.jobNo); wf.owner = operId; wf.state = (int)enumFlowTaskStatus.进行中; wf.Update(); */ /** * 改为下架时生成补零上架任务 * if (wop.recType != (int)enumStockRecordType.补零出库) { continue; } //to create inport data int skuId = Convert.ToInt32(dr["skuId"].ToString()); string goodsId =dr["goodsId"].ToString(); string batch =dr["batch"].ToString(); string skucode = dr["skucode"].ToString(); string prdtime = dr["productDate"].ToString(); string vltime = dr["validDate"].ToString(); DataTable dtBulkLocs = lstk.getBulkLocations(skuId, "",goodsId , batch, wop.count); foreach (DataRow dr1 in dtBulkLocs.Rows) { //todo: to add stock record WmsInUpPort wip = new WmsInUpPort(); wip.locationId = dr1[0].ToString(); wip.count =Convert.ToDecimal( dr1[1].ToString()); wip.orderNo = wop.pickOrderNo; wip.skuId = skuId; wip.skuCode = skucode; wip.batch = batch; wip.goodsId = goodsId; wip.detailId = wop.pickDetailId; wip.recType = (int)enumStockRecordType.补零入库; wip.recordId = wop.recordId; wip.productDate = prdtime; wip.validDate = vltime; wip.flowNo = "0"; WmsLocation loc = new WmsLocation(wip.locationId); Node nd = new Node( loc.part); if (nd.ID > 0) { wip.partion = nd.flag; } wip.Add(); //create stock,lock the location WmsStock newStk = new WmsStock(wip.locationId, skuId,wip.goodsId); if (newStk.ID == 0) //new one { newStk.countIn = wip.count; newStk.skuCode = skucode; newStk.goodsId = goodsId; newStk.skuId = skuId; newStk.locationId = wip.locationId ; newStk.batch = batch; newStk.productDate = wip.productDate; newStk.validDate = wip.validDate; newStk.maintainDate = newStk.getDateTime(); newStk.Add(); } } */ } scope.Complete(); } // // logTest.Debug(string.Format(" All tasks to do , loc cnt :{0}, box cnt: {1},max lot limit {2},max box limit {3},orderType:{4}", lotcnt, boxcnt,maxLocCnt,maxBoxs,orderType)); } bool isJobMax(int takeBy, int partion, int lineId, int maxLocCnt = 0, int maxBoxs = 0, bool batchOnly = true, enumOrderType orderType = enumOrderType.销售出库) { maxLocCnt = maxLocCnt <= 0 ? WmsConstants.MAX_PICK_LOT_CNT : maxLocCnt; maxBoxs = maxBoxs <= 0 ? WmsConstants.MAX_PICK_BOX_CNT : maxBoxs; // logTest.Debug(string.Format("2 maxLocCnt {0},maxBoxs {1}", maxLocCnt, maxBoxs)); int lotcnt = 0, boxcnt = 0; WmsOutPickPort wop; DataTable dt = getWmsOutPickPort.getAssignedTasks(takeBy, partion, -1, batchOnly, orderType); lotcnt = dt.Rows.Count; if (lotcnt >= maxLocCnt) { logOut.Debug(" user " + takeBy + " 无法分配更多的任务了,未完成 task lotcnt :" + lotcnt); return true; } foreach (DataRow dr in dt.Rows) { wop = new WmsOutPickPort(dr); try { boxcnt += Convert.ToInt32(dr["boxcnt"].ToString()); } catch { } if (boxcnt >= maxBoxs) { logOut.Debug(" user " + takeBy + " 无法分配更多的任务了,未完成 box cnt :" + boxcnt); return true; } // wop.operater = operId; } return false; } /// /// 以Job 为单位分配工作 /// /// /// /// /// /// /// /// public void taskAssignByJob(int taskBy, int partion, int lineId, int maxLocCnt = 0, int maxBoxs = 0, bool batchOnly = true, enumOrderType orderType = enumOrderType.销售出库) { // logTest.Debug(string.Format("1 maxLocCnt {0},maxBoxs {1}",maxLocCnt,maxBoxs)); maxLocCnt = maxLocCnt <= 0 ? WmsConstants.MAX_PICK_LOT_CNT : maxLocCnt; maxBoxs = maxBoxs <= 0 ? WmsConstants.MAX_PICK_BOX_CNT : maxBoxs; // logTest.Debug(string.Format("2 maxLocCnt {0},maxBoxs {1}", maxLocCnt, maxBoxs)); if(isJobMax( taskBy, partion, lineId, maxLocCnt, maxBoxs , batchOnly , orderType)) { return; } int lotcnt = 0, boxcnt = 0; WmsOutPickPort wop; DataTable dt = getWmsOutPickPort.getFreeTasksByJob(partion, lineId, batchOnly, orderType, taskBy); // logTest.Debug(string.Format(" exists tasks to do , loc cnt :{0}, box cnt: {1}, free tasks cnt :{2}", lotcnt, boxcnt,dt.Rows.Count)); DataView dv = dt.DefaultView; dv.Sort = "jobNo"; string lastJob = ""; using (TransactionScope scope = new TransactionScope()) { foreach (DataRowView dr in dv) { /* lotcnt++; boxcnt += Convert.ToInt32(dr["boxcnt"].ToString()); if (lotcnt > maxLocCnt || boxcnt > maxBoxs) { // logTest.Debug(string.Format(" All tasks to do , loc cnt :{0}, box cnt: {1}",lotcnt,boxcnt)); break; } */ wop = new WmsOutPickPort(dr.Row); wop.takeBy = taskBy; // wop.operater = operId; wop.Update(); // log.Debug( " user " + taskBy + " task Assign :" + wop.ID); if (string.IsNullOrEmpty(lastJob)) { lastJob = wop.jobNo; } else if (lastJob != wop.jobNo) { WmsFlow wf = new WmsFlow(wop.jobNo); wf.owner = operId; wf.state = (int)enumFlowTaskStatus.进行中; wf.Update(); } lastJob= wop.jobNo; } scope.Complete(); } // // logTest.Debug(string.Format(" All tasks to do , loc cnt :{0}, box cnt: {1},max lot limit {2},max box limit {3},orderType:{4}", lotcnt, boxcnt,maxLocCnt,maxBoxs,orderType)); } internal DataTable taskAssignByJob( string lastJobNo, string locationId, int warehouse=0,int taskBelongTo=0) { logOut.Debug(string.Format("last job :{0}, location {1},warehouse {2},takebelongto {3}", lastJobNo, locationId, warehouse, taskBelongTo)); DataTable jobs = new DataTable("jobs"); int partion = 0; int lineId = 0; bool batchOnly = false; string orderNo=""; bool isWeightSeeds = false; bool isWeightSeedsLitmited= false; //接受最大量约束 if (!string.IsNullOrEmpty(lastJobNo)) { WmsFlow flow = new WmsFlow(lastJobNo); orderNo = flow.orderNo; } DataTable dtFreeTasks = new DataTable(); bool isWholePickOrder = (locationId.StartsWith("PK") || locationId.StartsWith("RP"))&& new WmsOutPickRequest(locationId).ID>0; if (isWholePickOrder) { dtFreeTasks = getWmsOutPickPort.getFreeTasksByPickOrder(locationId); }else if (locationId.StartsWith("JOB") && new WmsFlow(locationId).ID > 0) { dtFreeTasks = getWmsOutPickPort.getFreeTasksByJob(locationId); } else { WmsLocation loc = new WmsLocation(locationId); if (loc.ID == 0 && warehouse == 0) { return jobs; } partion = loc.partion; enumOrderType orderType = enumOrderType.销售出库; //默认取全部订单类型 isWeightSeeds = loc.isWeightSeeds || loc.part == 16759 //蔬菜类,边拣边分,获取单品所有任务,不跨区分配 // || loc.part == 16761 //冷冻 // || loc.part == 16762 ; //冷冻 isWeightSeedsLitmited = loc.part == 16761 || loc.part == 16762; //冷冻 // logOut.Debug("蔬菜类 is weight seeds ? " + isWeightSeeds); if (!isWeightSeeds && isJobMax(operId, partion, lineId, 0, 0, batchOnly, orderType)) { logOut.Debug(" job max exeed"); return jobs; } warehouse = warehouse == 0 ? loc.warehouse : warehouse; logOut.Debug(string.Format("partion {0}, lineId {1}, batchOnly {2}, orderType {3}, taskBelongTo {4},warehouse {5}, orderNo {6},lastJobNo {7},isWeightSeeds {8},isWeightSeedsLitmited {9} ", partion, lineId, batchOnly, orderType, taskBelongTo, warehouse, orderNo, lastJobNo, isWeightSeeds, isWeightSeedsLitmited)); // DataTable dtFreeTasks = new DataTable(); getWmsOutPickPort.getFreeTasksByJob(partion, lineId, batchOnly, orderType, taskBelongTo,warehouse, orderNo,lastJobNo,isWeightSeeds); //取同一个job下的任务,可能碰到缺货的任务穿插交错的情况 // partion = 0;// set partion to zero, 目的是减少 扫描取任务的频率 bool isTimeForFetchTasks = (DateTime.Now.Hour >= WmsConstants.SEEDS_TASK_FETCH_START_HOUR && DateTime.Now.Hour <= WmsConstants.SEEDS_TASK_FETCH_END_HOUR ) && ( DateTime.Now.Minute >= WmsConstants.SEEDS_TASK_FETCH_START_MINUTES && DateTime.Now.Minute <= WmsConstants.SEEDS_TASK_FETCH_END_MINUTES); // logOut.Debug(string.Format("当前小时 {0}, 分{1}" ,DateTime.Now.Hour, DateTime.Now.Minute)); // logOut.Debug(string.Format("任务分配开始时间{0}:{1},结束时间{2}:{3}, 可以抢拣货任务? {4}", WmsConstants.SEEDS_TASK_FETCH_START_HOUR, WmsConstants.SEEDS_TASK_FETCH_START_MINUTES, WmsConstants.SEEDS_TASK_FETCH_END_HOUR, WmsConstants.SEEDS_TASK_FETCH_END_MINUTES, isTimeForFetchTasks)); if (!isTimeForFetchTasks) { throw new Exception(string.Format("不在任务分配时间{0}:{1:D2}---{2}:{3:D2} ", WmsConstants.SEEDS_TASK_FETCH_START_HOUR, WmsConstants.SEEDS_TASK_FETCH_START_MINUTES, WmsConstants.SEEDS_TASK_FETCH_END_HOUR, WmsConstants.SEEDS_TASK_FETCH_END_MINUTES)); //return jobs; } if (isWeightSeeds || isWeightSeedsLitmited) { dtFreeTasks = getWmsOutPickPort.getFreeTasksByJob(partion, lineId, batchOnly, orderType, taskBelongTo, warehouse, "", "", true); } else { if (dtFreeTasks.Rows.Count == 0) // 指定区域 上一个job没有可用的下架任务, 取orderNo 订单下新 的jobNo { logTest.Debug(" 1 指定区域 上一个job没有可用的下架任务, 取orderNo 订单下新 的jobNo "); dtFreeTasks = getWmsOutPickPort.getFreeTasksByJob(partion, lineId, batchOnly, orderType, taskBelongTo, warehouse, orderNo, "", isWeightSeeds); } if (dtFreeTasks.Rows.Count == 0) // 不指定区域, orderNo 订单下新 的jobNo { logTest.Debug("2 不指定区域, orderNo 订单下新 的jobNo "); dtFreeTasks = getWmsOutPickPort.getFreeTasksByJob(0, lineId, batchOnly, orderType, taskBelongTo, warehouse, orderNo, "", isWeightSeeds); } if (dtFreeTasks.Rows.Count == 0)// 不指定区域 orderNo 订单下没有可用的下架任务, 取所在区域 新的任务 { logTest.Debug("3 不指定区域 orderNo 订单下没有可用的下架任务, 取所在区域 新的任务 "); dtFreeTasks = getWmsOutPickPort.getFreeTasksByJob(partion, lineId, batchOnly, orderType, taskBelongTo, warehouse, "", "", isWeightSeeds); } if (dtFreeTasks.Rows.Count == 0)//所在区域没有下架任务,不指定区域,取新任务 { logTest.Debug("4 所在区域没有下架任务,不指定区域,取新任务 "); dtFreeTasks = getWmsOutPickPort.getFreeTasksByJob(0, lineId, batchOnly, orderType, taskBelongTo, warehouse, "", "", isWeightSeeds); } } } if (dtFreeTasks.Rows.Count == 0) { logOut.Debug(" no free tasks"); return jobs; } DataView dv = dtFreeTasks.DefaultView; int lotcnt = 0, boxcnt = 0; string lastJob = ""; WmsOutPickPort wop; if (isWeightSeeds || isWeightSeedsLitmited) { dv.RowFilter = "recType=" + (int)enumStockRecordType.集货拣货; dv.Sort = "locationId,goodsId"; int taskCnt = 0; foreach (DataRowView drv in dv) { wop = new WmsOutPickPort(drv.Row); wop.takeBy = operId; wop.Update(); logOut.Debug(" user " + operId + " task Assign :" + wop.ID); if (lastJob != wop.jobNo) { lastJob = wop.jobNo; WmsFlow wf = new WmsFlow(wop.jobNo); wf.owner = operId; wf.state = (int)enumFlowTaskStatus.进行中; wf.Update(); // logOut.Debug(" user " + operId + " flow Assign :" + wf.task); } taskCnt++; if (isWeightSeedsLitmited) { lotcnt++; boxcnt += Convert.ToInt32(drv["boxcnt"].ToString()); if (lotcnt >= dv.Count * WmsConstants.MAX_PICK_PERCENT / 100 || lotcnt > WmsConstants.MAX_PICK_LOT_CNT || boxcnt > WmsConstants.MAX_PICK_BOX_CNT) { logOut.Debug(string.Format("1 can't assign more tasks , loc cnt :{0}, box cnt: {1}, dv.Count * WmsConstants.MAX_PICK_PERCENT / 100: {2}", lotcnt, boxcnt, dv.Count * WmsConstants.MAX_PICK_PERCENT / 100)); break; } } else if (taskCnt > 20) { break; } /* */ } if (taskCnt > 0) { return jobs; } dv.RowFilter = "recType <>" + (int)enumStockRecordType.集货拣货; // dv.Sort = "priority desc,goodsId"; dv.Sort = "goodsId"; string lastGoods = ""; logOut.Debug(string.Format(" tasks count for assisgn {0}", dv.Count)); foreach (DataRowView drv in dv) { //非集货订单 则按商品分配,一次获取一个单品所有任务分配给一个人 { if (string.IsNullOrEmpty(lastGoods)) { lastGoods = drv["goodsId"].ToString(); logOut.Debug(string.Format(" current goods {0} {1} " , lastGoods, drv["goodsname"].ToString())); } else if (lastGoods != drv["goodsId"].ToString()) { logOut.Debug(string.Format(" next goods {0}.....break... ", drv["goodsname"].ToString())); break; } } wop = new WmsOutPickPort(drv.Row); wop.takeBy = operId; wop.Update(); taskCnt++; logOut.Debug(string.Format("user id {0} , task assign ID {1}, toatal task cnt {2}", operId,wop.ID,taskCnt)); if (lastJob != wop.jobNo) { lastJob = wop.jobNo; WmsFlow wf = new WmsFlow(wop.jobNo); wf.owner = operId; wf.state = (int)enumFlowTaskStatus.进行中; wf.Update(); // logOut.Debug(" user " + operId + " flow Assign :" + wf.task); } } return jobs; } dv.Sort = " warehouse,partion,channel,shelf,col,layer,goodsid"; string lastOrder = ""; foreach (DataRowView drv in dv) { wop = new WmsOutPickPort(drv.Row); if (string.IsNullOrEmpty(lastOrder)) { lastOrder = wop.pickOrderNo; }else if (lastOrder != wop.pickOrderNo) { break; } wop.takeBy = operId; wop.Update(); logOut.Debug( " user " + operId + " task Assign :" + wop.ID); if (lastJob != wop.jobNo) { lastJob = wop.jobNo; WmsFlow wf = new WmsFlow(wop.jobNo); wf.owner = operId; wf.state = (int)enumFlowTaskStatus.进行中; wf.Update(); } if (!isWholePickOrder) //非整单获取 { lotcnt++; boxcnt += Convert.ToInt32(drv["boxcnt"].ToString()); if (/*lotcnt >= dv.Count * WmsConstants.MAX_PICK_PERCENT / 100 ||*/ lotcnt > WmsConstants.MAX_PICK_LOT_CNT || boxcnt > WmsConstants.MAX_PICK_BOX_CNT) { logOut.Debug(string.Format("2 can't assign more tasks , loc cnt :{0}, box cnt: {1}, dv.Count * WmsConstants.MAX_PICK_PERCENT / 100: {2}", lotcnt, boxcnt, dv.Count * WmsConstants.MAX_PICK_PERCENT / 100)); break; } } } return jobs; } internal decimal seedsPickOut2(string flowNo, int skuId, string productDate, string batch, int outDetailId, decimal seedCnt, string toFlowNo, int inDetailId, bool isForceClose) { decimal seeded = new WmsOutPickDetail(outDetailId).seeded; enumRepResult rs = seedsPickOut(flowNo,skuId,productDate,batch,outDetailId,seedCnt,toFlowNo,inDetailId,isForceClose); if (rs == enumRepResult.成功) { return new WmsOutPickDetail(outDetailId).seeded - seeded; } return 0; } /// /// 取总播种操作 /// /// 取总板号 /// 销售明细id /// 分播数量 /// 周转箱号 /// internal enumRepResult seedsPickOut(string flowNo,int skuId,string productDate, string batch, int outDetailId, decimal seedCnt, string toFlowNo,int inDetailId, bool isForceClose, int lightOperid=0) { logTest.Debug(string.Format(" flowNo:{0} ,batch :{1} , outDetailId:{2} , seedsCnt:{3}, toFlowNo {4} , lightOperid {5}", flowNo, batch ,outDetailId, seedCnt,toFlowNo, lightOperid)); // WmsOutDetail wod = new WmsOutDetail(outDetailId); // WmsOutRequest wor = new WmsOutRequest(wod.orderNo); this.operId = lightOperid; bool isZhitongSeed = inDetailId > 0; if (isZhitongSeed) { return zhitongSeedOut(inDetailId, outDetailId, seedCnt, flowNo, toFlowNo); } WmsOutPickDetail wod = new WmsOutPickDetail(outDetailId); logTest.Debug(string.Format("seeds pickdetail {0}", wod.ToString())); if (wod.ID==0 || !isZhitongSeed && string.IsNullOrEmpty(wod.seedsPickNo) ) { logTest.Debug(string.Format(" detialId {0}, seedsNo is null, {1}", outDetailId, enumRepResult.不适合播种)); return enumRepResult.不适合播种; } if ( wod.state == (int)enumOutStockDetailStatus.播种完成) { return enumRepResult.播种已完成; } if (wod.count != seedCnt) { logTest.Debug(string.Format(" detialId {0}, order Cnt {1}, seeds cnt {2}", outDetailId, wod.count, seedCnt)); } // WmsFlow wmsflow = new WmsFlow(wod.seedsPickNo+wod.goodsId+batch, flowNo); WmsFlow wmsflow = new WmsFlow(wod.seedsPickNo, flowNo); // logTest.Debug(string.Format("orderNo {0}, flowNo {1}, wmsflow {2}", wod.seedsPickNo + wod.goodsId + batch, flowNo, wmsflow.ToString())); /* enumRepResult rs= wmsflow.checkFlow(operId, wmsflow.type); if (rs!=enumRepResult.成功) { logTest.Debug(string.Format(" {0} checkflow result {1}, WmsConstants.MAX_TASKS_OWN {2}", operId, rs, WmsConstants.MAX_TASKS_OWN)); // return rs;// enumRepResult.任务已被他人抢占; } */ //to check the toFlowNo plate WmsPlate toP = new WmsPlate(toFlowNo); string custId = toP.customerId; // logTest.Debug("1 " + toP); if (String.IsNullOrEmpty(custId)) { if (toP.ID > 0) { if (toP.partion == 0 && String.IsNullOrEmpty(toP.customerId)) { toP.partion = wod.goods.part; toP.customerId = wod.customerId; toP.Update(); logTest.Debug("2 updated plate customerId " + wod.customerId); } custId = toP.customerId; } else { custId = new WmsPlateStock_tmp().getRelatedCustId(toFlowNo); } } //------》》》》 //TODO: to remove this block /* logTest.Debug("3 " + toP); toP = new WmsPlate(toFlowNo); //TODO: to remove this line logTest.Debug("31 new saved plate: " + toP); //TODO: to remove this line logTest.Debug(" to flow "+ toFlowNo +" , exist customer id " + custId + ", wod customerId is " + wod.customerId); if (toP.ID > 0) { custId = new WmsPlateStock_tmp().getRelatedCustId(toFlowNo); } */ //------<《《《《《 if (!string.IsNullOrEmpty(custId) && custId != wod.customerId) { return enumRepResult.容器已被其他客户占用; } if (!WmsConstants.OUT_SEEDS_CAN_OVER_REQ) //不许超发 { seedCnt = seedCnt > wod.count - wod.seeded ? wod.count - wod.seeded : seedCnt; } // 更新总拣记录 pickport with flowno can be multi records, update the finished seeds count in loop DataTable dt = getWmsOutPickPort.getFlowNoDetails(wod.seedsPickNo, flowNo, wod.goodsId, batch); List lstSeeds = new List(); List lstUpdate = new List(); ; decimal tmpCnt = seedCnt; DataView dv = dt.DefaultView; dv.RowFilter = "state="+ (int)enumPickState.已分播; int seedsDoneCnt = dv.Count; dv.RowFilter = ""; logTest.Debug(string.Format("1 seeds done cnt {0}, totalcnt of task {1}", seedsDoneCnt, dt.Rows.Count)); foreach (DataRow dr in dt.Rows) { WmsOutPickPort wop = new WmsOutPickPort(dr); decimal tmpCnt2 = 0; if (wop.state == (int)enumPickState.已分播) { seedsDoneCnt++; } if (wop.state == 1) //已经拣货完毕 { if (wop.seedsOutCount + tmpCnt <= wop.pickCount) { tmpCnt2 = tmpCnt; wop.seedsOutCount += tmpCnt; lstSeeds.Add(wop); tmpCnt = 0; } else { tmpCnt -= wop.pickCount - wop.seedsOutCount; wop.seedsOutCount = wop.pickCount; lstSeeds.Add(wop); tmpCnt2 = wop.pickCount; } /* * 更新临时库数据 * */ WmsPlateStock_tmp tmpStk = new WmsPlateStock_tmp(); DataTable dt1 = tmpStk.getByOutPort(wop.ID); foreach (DataRow dr1 in dt1.Rows) { if (tmpCnt2 <= 0) { break; } tmpStk = new WmsPlateStock_tmp(dr1); // log.Debug("1 tmpStk.count " + tmpStk.count + ", tmpCnt2: " + tmpCnt2); if (tmpStk.count >= tmpCnt2) { tmpStk.count -= tmpCnt2; tmpCnt2 = 0; } else { tmpCnt2 -= tmpStk.count; tmpStk.count = 0; } // log.Debug("2 tmpStk.count " + tmpStk.count + ", tmpCnt2: " + tmpCnt2); // log.Debug(tmpStk); lstUpdate.Add(tmpStk); } if (tmpCnt == 0) { break; } } } if (tmpCnt > 0) { logTest.Debug(string.Format(" 播种请求数量{0}, 可用播种数量{1},flowNo:{2} ,batch :{3} , outDetailId:{4} ", seedCnt, seedCnt - tmpCnt, flowNo, batch, outDetailId)); // return enumRepResult.分播数量大于剩余数量; } seedCnt -= tmpCnt; if (seedCnt < 0) { logTest.Debug(string.Format("分播数量大于剩余数量 seedCnt {0} ", seedCnt)); return enumRepResult.分播数量大于剩余数量; } if (!WmsConstants.OUT_SEEDS_CAN_OVER_REQ) //不许超发 { seedCnt = seedCnt > wod.count - wod.seeded ? wod.count - wod.seeded : seedCnt; } logTest.Debug(string.Format("wod {0}, new seeded cnt {1} ",wod.ID,seedCnt)); wod.seeded += seedCnt; if (wod.count <= wod.seeded || isForceClose) { wod.state = (int)enumOutStockDetailStatus.播种完成; } logTest.Debug(" 1 WmsPlateStock_tmp lstUpdate count " + lstUpdate.Count); using (TransactionScope scope = new TransactionScope()) { logTest.Debug(string.Format("seeds out start update 分播 tasks ,operid {0}, wmsflow : {1}",operId, wmsflow.ToString() )); wod.Update(); if (wod.isAllPicked(wod.pickOrderNo)) { new lWmsOutPickRequest(operId).updateOrderStatus(wod.pickOrderNo, enumOutStockPickStatus.分拣完成); } WmsStockRecord wsr = new WmsStockRecord(); wsr.orderNo = wod.pickOrderNo; wsr.orderDetailId = wod.ID; wsr.goodsId = wod.goodsId; wsr.count = seedCnt; wsr.locationId = lstSeeds[0].locationId;//flowNo; wsr.operater = operId; wsr.batch = batch;// wod.batch; wsr.productDate = productDate; wsr.skuId = skuId; wsr.rectype = (int)enumStockRecordType.集货分播; wsr.Add(); WmsOutPickPort wop = new WmsOutPickPort(); wop.recordId = wsr.ID; wop.pickBy = operId; wop.pickTime = wop.getDateTime(); wop.pickCount = seedCnt; wop.pickOrderNo = wod.pickOrderNo; wop.state = (int)enumPickState.已分播; wop.recType = (int)enumStockRecordType.集货分播; wop.seedsFromFlowNo = flowNo; wop.flowNo = toFlowNo; wop.pickDetailId = wod.ID; wop.operater = operId; wop.jobNo = wmsflow.task; wop.takeBy = operId; wop.locationId = wsr.locationId; wop.count = wod.count; int id = wop.Add(); /* /// 发车时从已分播到客户的容器里减去容器占用 WmsStock stk1 = new WmsStock(wsr.locationId, wsr.skuId, wsr.goodsId); stk1.plateCount -= seedCnt; stk1.updateCountOut(); */ /* if(toPlate.customerId!=wod.customerId) { toPlate.customerId = wod.customerId; toPlate.Update(); } */ foreach (WmsOutPickPort port in lstSeeds) { if (port.pickCount <= port.seedsOutCount) { port.state = (int)enumPickState.已分播; seedsDoneCnt++; } port.Update(); // WmsPlateStock_tmp t = new WmsPlateStock_tmp(); // t.getByOutPort(wop.ID); // t.Delete(); } log.Debug(string.Format("2 seeds done cnt {0}, totalcnt of task {1}, lstUpdate.Count {2}", seedsDoneCnt, dt.Rows.Count, lstUpdate.Count)); wmsflow.finishedTasksPlus(operId, seedCnt / wod.goods.minOperateCount, true, false); //下架任务更新分播数据 WmsFlow wmsflowCust = new WmsFlow(wmsflow.orderNo, wod.customerId + "-" + operId); //按分播单 和客户ID 分播ID 创建分播任务 if (wmsflowCust.ID == 0) { wmsflowCust.operater = operId; wmsflowCust.orderNo = wmsflow.orderNo;// + sr.goodsId + sr.batch; wmsflowCust.flowNo = wod.customerId + "-" + operId; wmsflowCust.type = wmsflow.type; wmsflowCust.typeName = wmsflow.typeName; wmsflowCust.task = Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo)); wmsflowCust.taskCnt = 1; wmsflowCust.Add(); } wmsflowCust.finishedTasksPlus(operId, seedCnt / wod.goods.minOperateCount, true); //更新分播任务 // log.Debug(" 2 WmsPlateStock_tmp lstUpdate count " + lstUpdate.Count); foreach (WmsPlateStock_tmp tmp in lstUpdate) { // log.Debug("3 tmp.count " + tmp.count); // log.Debug(tmpStk); if (tmp.count == 0) { // log.Debug("deleted tmp stock, outPortId " + tmp.outPortId); tmp.Delete(); } else { tmp.Update(); } } log.Debug(" 2 WmsPlateStock_tmp lstUpdate count " + lstUpdate.Count); if (lstUpdate.Count > 0) { WmsPlateStock_tmp stk = lstUpdate[0]; //copy source tmp stk info stk.outPortId = id; stk.plateId = toFlowNo; stk.count = seedCnt; stk.orderNo = wod.pickOrderNo; stk.recordId = wsr.ID; stk.skuId = skuId; stk.productDate = productDate; stk.jobNo = stk.orderNo + toFlowNo; ; stk.operater = operId; stk.customerId = wod.customerId; WmsOutPickRequest wopr = new WmsOutPickRequest(wod.pickOrderNo); wopr.createLoadTruckJob(operId); if ( !WmsConstants.AUTO_LOAD_TRUCK && toP.type != (int)enumPlateLevel.客户集货 && toP.plateLevel != (int)enumPlateLevel.客户集货) { stk.state = (int)enumPlateStatus.出库待集货; WmsFlow jiFlow = new WmsFlow(stk.orderNo, toFlowNo, enumFlowTaskStatus.未开始, EnumFlowTaskType.客户集货); if (jiFlow.ID == 0) { jiFlow.operater = operId; jiFlow.orderNo = stk.orderNo; jiFlow.flowNo = toFlowNo; jiFlow.type = (int)EnumFlowTaskType.客户集货; jiFlow.typeName = EnumFlowTaskType.客户集货.ToString(); jiFlow.task = stk.orderNo + toFlowNo;// stk.jobNo; jiFlow.fromPartion = wmsflow.toPartion; jiFlow.toLocationId = new WmsOutPickRequest(wod.pickOrderNo).tranLocationId; jiFlow.taskCnt = 1; jiFlow.Add(); } } else //客户类型的容器,新增装车任务 { stk.state = (int)enumPlateStatus.已集货; if (!WmsConstants.IS_PLATE_IN_LINE && string.IsNullOrEmpty(toP.customerId)) { int lineId = 0; DataTable dt1 = stk.getOutPort(stk.outPortId); foreach (DataRow dr1 in dt1.Rows) { custId = dr1["customerId"].ToString(); lineId = Convert.ToInt32(dr1["lineId"].ToString()); toP.volume += Convert.ToDecimal(dr1["volCm"].ToString()); toP.load += Convert.ToDecimal(dr1["weight"].ToString()); break; } if (wod != null) { toP.partion = wod.goods.part; } toP.lineId = lineId; toP.jobNo = wopr.loadTruckJob; toP.customerId = custId; toP.Update(); } } stk.Add(); } if (WmsConstants.AUTO_LOAD_TRUCK) { try { string truck = "000";// + wsr.locationId.Substring(0, 1); new lWmsPlate(operId).loadTruck(toFlowNo, truck); } catch (Exception er) { log.Error(er); } } scope.Complete(); } return enumRepResult.成功; } private enumRepResult zhitongSeedOut(int inDetailId, int outDetailId, decimal seedCnt, string flowNo, string toFlowNo) { logOut.Debug("直通分货开始。。。。。。。。"); WmsPlateStock_tmp tmpStk = new WmsPlateStock_tmp(); WmsOutPickDetail wod = new WmsOutPickDetail(outDetailId); WmsInRequestDetail wid = new WmsInRequestDetail(inDetailId); WmsFlow flow = new WmsFlow(wid.taskNo); enumRepResult rs = flow.checkFlow(operId, flow.type); if (rs != enumRepResult.成功) { return rs; } DataTable dt = getWmsInUpPort.getJobsByFlowSku(flowNo, wid.goodsId, wid.productDate); List lstExists = new List(); List lstUpdate = new List(); decimal tmpCnt = seedCnt; foreach (DataRow dr in dt.Rows) { WmsInUpPort wip = new WmsInUpPort(dr); decimal tmpCnt2 = 0; if (wip.state == (int)enumInStockDetailStatus.已分配货位) //已经收货完毕 { if (wip.upCount + tmpCnt <= wip.count) { tmpCnt2 = tmpCnt; wip.upCount += tmpCnt; lstExists.Add(wip); tmpCnt = 0; } else { tmpCnt -= wip.count - wip.upCount; wip.upCount = wip.count; lstExists.Add(wip); tmpCnt2 = wip.count; } /* * 更新临时库数据 * */ DataTable dt1 = tmpStk.getByInPort(wip.ID); foreach (DataRow dr1 in dt1.Rows) { if (tmpCnt2 <= 0) { break; } tmpStk = new WmsPlateStock_tmp(dr1); // log.Debug("1 tmpStk.count " + tmpStk.count + ", tmpCnt2: " + tmpCnt2); if (tmpStk.count >= tmpCnt2) { tmpStk.count -= tmpCnt2; tmpCnt2 = 0; } else { tmpCnt2 -= tmpStk.count; tmpStk.count = 0; } // log.Debug("2 tmpStk.count " + tmpStk.count + ", tmpCnt2: " + tmpCnt2); // log.Debug(tmpStk); lstUpdate.Add(tmpStk); } if (tmpCnt == 0) { break; } } } if (seedCnt > wid.validCount-wid.seedOutCnt) { seedCnt = wid.validCount - wid.seedOutCnt; // return enumRepResult.分播数量大于剩余数量; } seedCnt = seedCnt > wod.count - wod.seeded ? wod.count - wod.seeded : seedCnt; wod.seeded += seedCnt; if (wod.count <= wod.seeded) { wod.state = (int)enumOutStockDetailStatus.播种完成; } WmsOutPickRequest wopr = new WmsOutPickRequest(wod.pickOrderNo); // log.Debug(" 1 WmsPlateStock_tmp lstUpdate count " + lstUpdate.Count); using (TransactionScope scope = new TransactionScope()) { wopr.createLoadTruckJob(operId); string custId = ""; WmsPlate toP = new WmsPlate(toFlowNo); if (toP.ID > 0) { if (toP.partion == 0 && String.IsNullOrEmpty(toP.customerId)) { toP.partion = wod.goods.part; toP.customerId = wod.customerId; toP.Update(); } custId = toP.customerId; } if (String.IsNullOrEmpty(custId)) { custId = new WmsPlateStock_tmp().getRelatedCustId(toFlowNo); } // logTest.Debug(" to flow " + toFlowNo + " , exist customer id " + custId + ", wod customerId is " + wod.customerId); if (!string.IsNullOrEmpty(custId) && custId != wod.customerId) { return enumRepResult.容器已被其他客户占用; } wid.seedOutCnt+=seedCnt; wid.Update(); flow.finishedTasksPlus(operId,seedCnt/wod.goods.minOperateCount,true,wid.seedOutCnt>=wid.validCount); wod.Update(); if (wod.isAllPicked(wod.pickOrderNo)) { new lWmsOutPickRequest(operId).updateOrderStatus(wod.pickOrderNo, enumOutStockPickStatus.分拣完成); } logOut.Debug(string.Format("zhitong seeds out goodsId :{0}, seedCnt :{1}, wid seedOutCnt {2}, wod id {3}, seeded count {4}", wid.goodsId, seedCnt, wid.seedOutCnt, wod.ID, wod.seeded)); WmsStockRecord wsr = new WmsStockRecord(); wsr.orderNo = wod.pickOrderNo; wsr.orderDetailId = wod.ID; wsr.goodsId = wod.goodsId; wsr.count = seedCnt; wsr.locationId = flowNo; wsr.operater = operId; wsr.batch = wid.productDate;// wod.batch; wsr.productDate = wid.productDate; wsr.skuId = wid.skuId; wsr.rectype = (int)enumStockRecordType.集货分播; wsr.Add(); WmsOutPickPort wop = new WmsOutPickPort(); wop.recordId = wsr.ID; wop.pickBy = operId; wop.pickTime = wop.getDateTime(); wop.count= wop.pickCount = seedCnt; wop.pickOrderNo = wod.pickOrderNo; wop.state = (int)enumPickState.已分播; wop.recType = (int)enumStockRecordType.集货分播; wop.seedsFromFlowNo = flowNo; wop.flowNo = toFlowNo; wop.pickDetailId = wod.ID; wop.operater = operId; wop.jobNo = flow.task; int id = wop.Add(); foreach (WmsInUpPort port in lstExists) { if (port.count <= port.upCount) { port.state = (int)enumInStockDetailStatus.直通分货完成; port.Update(); } } /* if(toPlate.customerId!=wod.customerId) { toPlate.customerId = wod.customerId; toPlate.Update(); } */ // log.Debug(" 2 WmsPlateStock_tmp lstUpdate count " + lstUpdate.Count); foreach (WmsPlateStock_tmp tmp in lstUpdate) { // log.Debug("3 tmp.count " + tmp.count); // log.Debug(tmpStk); if (tmp.count == 0) { // log.Debug("deleted tmp stock, outPortId " + tmp.outPortId); tmp.Delete(); } else { tmp.Update(); } } if (lstUpdate.Count > 0) { WmsPlateStock_tmp stk = lstUpdate[0]; //copy source tmp stk info stk.outPortId = id; stk.plateId = toFlowNo; stk.count = seedCnt; stk.orderNo = wod.pickOrderNo; stk.recordId = wsr.ID; // stk.skuId = skuId; // stk.productDate = productDate; stk.state = (int)enumPlateStatus.出库待集货; stk.customerId = wod.customerId; stk.Add(); WmsFlow jiFlow = new WmsFlow(); // WmsFlow jiFlow = new WmsFlow(stk.orderNo + toFlowNo, toFlowNo, enumFlowTaskStatus.未开始); // if (jiFlow.ID == 0) if (!WmsConstants.AUTO_LOAD_TRUCK) { jiFlow.operater = operId; jiFlow.orderNo = stk.orderNo; jiFlow.flowNo = toFlowNo; jiFlow.type = (int)EnumFlowTaskType.客户集货; jiFlow.typeName = EnumFlowTaskType.客户集货.ToString(); jiFlow.task = jiFlow.orderNo + toFlowNo; ; jiFlow.taskCnt = 1; jiFlow.Add(); } } if (WmsConstants.AUTO_LOAD_TRUCK) { new lWmsPlate(operId).loadTruck(toFlowNo, "000"); } scope.Complete(); } logOut.Debug("直通分货结束"); return enumRepResult.成功; } internal enumRepResult stackDone(string preInNo, string flowNo) { throw new NotImplementedException(); } internal DataTable getSeedsPickDetail(string flowNo, bool isOrderByCust) { // return getWmsOutPickPort.getSeedsOutDetail(flowNo, isOrderByCust); return getWmsOutPickPort.getSeedsOutPickDetail(flowNo, isOrderByCust); } /* * 取消拣货任务 * */ public int taskRessign(int taskBy, int partion, int lineId, bool batchOnly = true, enumOrderType orderType = enumOrderType.销售出库) { DataTable dt = getWmsOutPickPort.getAssignedTasks(taskBy, partion, lineId, batchOnly,orderType); int i=0; WmsOutPickPort wop; using (TransactionScope scope = new TransactionScope()) { foreach (DataRow dr in dt.Rows) { wop = new WmsOutPickPort(dr); wop.takeBy = 0; // wop.operater = operId; if (wop.state == (int)enumPickState.未拣) { wop.Update(); i++; LogHelper.debug("lWmsOutPickPort", " user " + taskBy + " task resign:" + wop.ID); } } scope.Complete(); } return i; } public DataTable getAssignedTasks4Wince(int taskBy, int partion = 0, int lineId = -1, bool batchOnly = true,enumOrderType orderType = enumOrderType.销售出库) { return getWmsOutPickPort.getAssignedTasks4Wince(taskBy, partion, lineId, batchOnly, orderType); } public DataTable getAssignedOutTasks(int taskBy,string locationid ="",int partion = 0, int lineId = -1, bool batchOnly = false, enumOrderType orderType = enumOrderType.销售出库,int taskId=0, int state = -1) { // logTest.Debug(string.Format(" taskBy {0}, locationId {1}, partion {2},lineId {3},batchOnly {4},orderType {5},taskId {6}, state {7}", taskBy, locationid , partion , lineId , batchOnly , orderType.ToString(), taskId , state)); if (taskId > 0 && havePermission(WmsConstants.SPECIAL_VALID_REASSIN_TASK_BY_ID)) { WmsOutPickPort wop = new WmsOutPickPort(taskId); if (!string.IsNullOrEmpty(wop.jobNo)) { // if (wop.state == 0) { if (wop.takeBy > 0) { wop.description += " 原任务所有者 为 " + wop.takeBy +",reassign to " + operId +", " + DateTime.Now; } wop.takeBy = operId; wop.Update(); } } } bool isWholePickOrder = !string.IsNullOrEmpty(locationid) && locationid.StartsWith("PK"); if ( partion == 0 && !string.IsNullOrEmpty(locationid) && !isWholePickOrder) { WmsLocation loc = new WmsLocation(locationid); partion = loc.partion; } // partion = 0; // logTest.Debug(string.Format(" getAssignedOutTasks ,taskBy {0}, locationId {1}, partion {2},lineId {3},batchOnly {4},orderType {5},taskId {6}, state {7}", taskBy, locationid, /partion, lineId, batchOnly, orderType.ToString(), taskId, state)); DataTable dt = getWmsOutPickPort.getAssignedTasks(taskBy, partion, lineId, batchOnly, orderType, state); if (dt.Rows.Count == 0 && partion>0) //指定区域没有分配的任务,不指定区域获取任务 { dt = getWmsOutPickPort.getAssignedTasks(taskBy, 0, lineId, batchOnly, orderType, state); } if (state == 1 || isWholePickOrder ) //分拣的历史记录 或 整单分拣 { return dt; } bool isWeightOut=false; foreach(DataRow dr in dt.Rows) { try { if (WmsConstants.GOODS_WEIGHT_UNITS.Contains(dr["pickUnit"].ToString())) { // isWeightOut = true; isWeightOut = Convert.ToInt32(dr["recType"].ToString()) == (int)enumStockRecordType.销售出库; if (isWeightOut) { break; } } } catch { } } if (isWeightOut ) { DataView dv = dt.DefaultView; // dv.Sort = "goodsId,lineId,lineorder,[count] desc"; //称重的,路远的,重量高的先出 dv.Sort = "goodsId,linePriority desc, [count] desc"; //路远的,重量大的先出 return dv.ToTable("sorted"); } return dt; } // internal DataTable getAssignedOutTasks(int taskBy) // { // return getWmsOutPickPort.getAssignedTasks(taskBy); // } public DataTable getPartions(int userID) { return getWmsOutPickPort.getPartions(userID); } internal DataTable getRepTasks(int takeBy, int taskPartion ) { return getWmsOutPickPort.getRepTasks(takeBy, taskPartion ); } internal DataTable getFlows4SeedsOut() { return getWmsOutPickPort.getFlows4SeedsOut() ; } internal DataTable getFlows4ZhitongSeedsOut() { return getWmsInRequestDetail.getFlows4ZhitongSeedsOut(); } } }