/// ///LOGIC CLASS FOR TABLE t_wmsOutPickRequest ///By wm with codesmith. ///on 05/22/2017 /// 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; using System.Threading; using DeiNiu.Data.BaseObject; using System.Net; using Newtonsoft.Json.Linq; using Newtonsoft.Json; namespace DeiNiu.wms.Logical { [Serializable] public class lWmsOutPickRequest : lbase { WmsOutPickRequest _obj; private WmsOutDesk _desk; private WmsOutDesk _seedsDesk; private WmsOutPickDetail_tmp _outPickTmp; private WmsPlate _plate; WmsPlate plate { get { if ( _plate == null) { _plate = new WmsPlate(); _plate.operater = operId; } return _plate; } } WmsOutPickRequest outRequest { get { if (_outRequest == null) { _outRequest = new WmsOutPickRequest(); _outRequest.operater = operId; } return _outRequest; } } public WmsOutPickDetail_tmp outPickTmp { get { if (_outPickTmp == null) { _outPickTmp = new WmsOutPickDetail_tmp(); _outPickTmp.operater = operId; } return _outPickTmp; } } WmsStockRecord stkRecord { get { if(_stkRecord == null){ _stkRecord = new WmsStockRecord(); _stkRecord.operater = operId; } return _stkRecord; } } WmsOutPickLable pickLabelDetail { get { if (_pickLabelDetail == null) { _pickLabelDetail = new WmsOutPickLable(); _pickLabelDetail.operater = operId; } return _pickLabelDetail; } } WmsOutPickPort outPickPort { get { if (_outPickPort == null) { _outPickPort = new WmsOutPickPort(); _outPickPort.operater = operId; } return _outPickPort; } } WmsOutPickPort _outPickPort; WmsOutPickRequest _outRequest ; WmsStockRecord _stkRecord ; WmsOutPickLable _pickLabelDetail ; WmsOutDesk desk { get { if (_desk == null) { _desk = new WmsOutDesk(); _desk.operater = operId; } return _desk; } } WmsOutDesk seedsDesk { get { if (_seedsDesk == null) { _seedsDesk = new WmsOutDesk(); } return _seedsDesk; } } public lWmsOutPickRequest() { initialize(); } public lWmsOutPickRequest(int p) :base(p) { initialize(); } public WmsOutPickRequest getWmsOutPickRequest { get { if (_obj == null) { _obj = new WmsOutPickRequest(); } return _obj; } } /// /// get all data /// public DataSet getAllData() { return _obj.Query(); } /// ///get pick details ///if no pick data,return order details /// public DataSet getPickDetails(string orderNo,bool isPickdetail) { DataSet ds = ds = _obj.getPickDetailByOrder(orderNo, isPickdetail); /*if (orderType == enumOutOrderType.销售订单) { DataTable dt = ds.Tables[0]; if (dt.Rows.Count > 0) { if (string.IsNullOrEmpty(dt.Rows[0]["pickOrderNo"].ToString())) { WmsOutRequest ord = new WmsOutRequest(); ord.orderNo = orderNo; return ord.getOutDetail(); } } }*/ return ds ; } /// /// get all data /// public DataSet getAllActiveData() { return _obj.QueryActived(); } /// /// get a record by id /// public void initialize(int id) { _obj = id != 0 ? new WmsOutPickRequest(id) : new WmsOutPickRequest(); } /// /// get a record by id 0 /// public void initialize() { initialize(0); } /// /// get a record by id /// public void initialize(DataRow dr) { _obj = new WmsOutPickRequest(dr); } protected override DeiNiu.Data.BaseObject.BaseModel getModel() { return _obj; } //begin cust db operation, query, excute sql etc. //private static bool _canNewWave = false; ////Int64 lastWave =0; //DateTime lastWave; // public bool canNewWave // { // get // { // _canNewWave = _canNewWave || outRequest.canNewWave(); // if (_canNewWave) // { // lastWave = DateTime.Now ; // } // else // { // TimeSpan ts = DateTime.Now - lastWave; // if (ts.TotalMilliseconds > WmsConstants.MAX_SECONDS_BETWEEN_WAVES) //强制开始新波次,有可能会有再次发送亮灯数据时 // { // _canNewWave = true; // lastWave = DateTime.Now; // } // } // return _canNewWave ;//|| outRequest.canNewWave() ;//|| true; // // return _canNewWave; // pickLabelDetail.getCurrentPickList(enumLabelPickState.notPicked).Tables[0].Rows.Count > 0; // } // } //static Dictionary> comLables = new Dictionary>(); 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 =""; private List bulkRequests; private static Dictionary seedsWaiting = new Dictionary(); private static List noSeeds = new List(); // public static bool isProcessWaveing = false; private static int waveCnt= 0 ; /// /// 开始新波次 /// public void newBulkDPSandSeedsPickWave() { waveCnt++; //播种筛选, //适合播种的客户订单合并成一个、多个大订单,统一捡出后进行播种操作 //1. 单个订单的品种少 、数量少 //2. 订单数量多 //只处理订单零货部分 //加入播种选项,所有订单零货部分使用摘取+播种方式 //1.播种点数量可配置, 分别用不同颜色区分 //2.每个播种点可分播客户的数量配置, 即每个播种点处理零货订单数量( 例如配置成6个,一次捡6个客户的订单零货部分,送由一个播种点播种) //3.波次和播种点的对应关系,一个波次只摘取一个播种点的零货,还是多个播种点的数据? //4. //一个波次可以摘取订单数 = 空闲分播台数量*每个分播台可分播客户数, 分播台的订单用颜色区分 bool isSeedsEnabled = WmsConstants.OUT_BULK_SEEDS_PICK_ON; if (!WmsConstants.OUT_BULK_DESK_CONTROLL) {//播种复核台完成复核任务前,复核台不可用,拆零波次不分配给复核台任务 //播种复核台复位 desk.restDeskStatus(enumDeskState.空闲); desk.restDeskStatus(enumDeskState.空闲, enumDeskType.播种); //播种台状态复位到空闲, } _desk = getRandomFreeDesk(); _seedsDesk = getRandomFreeSeedsDesk(); if (desk.ID == 0) // no free pick desk { if (isSeedsEnabled) { if (seedsDesk.ID == 0) { return; } } else { return; } } LogHelper.debug(typeof(lWmsOutPickRequest), "开始新波次。。。。。。。。。。。。。。。。。。"); // System.Diagnostics.Debug.WriteLine("begin make new wave .....{0}" ,DateTime.Now); // List requests = outRequest.getRequests4Wave(); //.getRequestObjects(enumOutOrderType.拣货单, enumOutStockRequestStatus.波次处理); // System.Diagnostics.Debug.WriteLine("begin make new wave .....{0}" ,DateTime.Now); WaveRule wr = new WaveRule().getCurrentActiveRule(enumWaveRuleType.DPS灯光波次); DataSet ds = outRequest.getRequests4DpsWave(enumOrderType.销售出库, wr); DataTable dtSeeds = ds.Tables[1]; DataTable dtOne = ds.Tables[0]; List requests = new List(); foreach (DataRow dr in dtSeeds.Rows)//播种订单 { WmsOutPickRequest wo = new WmsOutPickRequest(dr); if (!noSeeds.Contains(wo.pickOrderNo)) { requests.Add(wo); } } LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理 SEEDS 订单数量:{0}",dtSeeds.Rows.Count)); foreach (string order in noSeeds) // 等待播种订单转入摘果 { WmsOutPickRequest wo = new WmsOutPickRequest(order); wo.seedsLabelId = 0; requests.Add(wo); } foreach (DataRow dr in dtOne.Rows) //摘果订单 { requests.Add(new WmsOutPickRequest(dr)); } LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理 摘果 订单数量:{0}", dtOne.Rows.Count)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理 等待Seeds 订单数量:{0}", noSeeds.Count)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理订单数量:{0}", requests.Count)); if (requests.Count == 0) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("无订单需要处理,波次结束")); checkRepAndNoStockOrders(); return; } int labelMaxInWave = WmsConstants.MAX_LABEL_DATA_IN_A_WAVE; //一个标签一个波次只能存储40条数据 #if DEBUG // if (lblist.Count == 0) { lblist.Clear(); initialDebugSetting(); } lblist.Sort(); // int minId = lblist[0]; // int maxId = lblist[lblist.Count - 1]; // labelMaxInWave = 2; #endif // List strecs = null; waveOrder = Util.getOrderNo(enumCreateOrderType.dpsOrder, _obj.getNextSeq(enumCreateOrderType.dpsOrder)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("new waveNo {0}", waveOrder)); //waveOrder = "WV" + System.DateTime.Now.ToString("yyyyMMddHHmmss"); int pickDetailMaxInWave = WmsConstants.MAX_CONTROL_DATA_IN_A_WAVE; //一个控制器最大存储1200条 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; //播种常量,达不到最小订单摘取需求的合并成大订单先统一摘取再分播 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(); List lstSeedsBulk = new List(); ; //订单充足的情况下,每个波次的拣货负载均衡化,每个波次每个复核台都要最大负载,不空转 //先满足播种数据,再进行摘果 int bulkCnt = 0; bulkRequests = new List(); //for batch process in a new thread //开始处理有零货的订单 DateTime d0 = DateTime.Now; double totoalTime = 0d; string lastAddress = ""; foreach (WmsOutPickRequest request in requests) { LogHelper.debug(this.GetType(), string.Format("开始处理零库出库 {0} ------------", request.pickOrderNo)); _desk = getRandomFreeDesk(); if (desk.ID == 0) // no free pick desk { LogHelper.debug(this.GetType(), " no pick desk available....."); if (isSeedsEnabled) { if (seedsDesk.ID == 0) { LogHelper.debug(this.GetType(), "no pick no seeds desk ,break 1"); break; } else { if (request.seedsLabelId != WmsConstants.SEEDS_LABLEID_MARK_VALUE)//仅剩下摘果的订单 { LogHelper.debug(this.GetType(), "no pick no seeds order ,break 2"); break; } } } else { break; } } else { if (request.seedsLabelId == WmsConstants.SEEDS_LABLEID_MARK_VALUE)//播种的订单 { if (isSeedsEnabled) { if (seedsDesk.ID == 0) { LogHelper.debug(this.GetType(), " no seed desk available.....,continue"); continue; } } } } //确保每个pick order 都进入波次 ,不空耗资源 DateTime d00 = DateTime.Now; if (request.bulkCnt == 0) { continue; } DataTable dt = stkRecord.getPickStockRecods(request.pickOrderNo, true).Tables[0];//取出库明细, // lstPort = new List(); lstLabel = new List(); //开始处理零货出库 DataView dvBulk = new DataView(dt); dvBulk.RowFilter = string.Format(" volType in ({0},{1})", (int)enumWhLocVol.零库1, (int)enumWhLocVol.零库); if (bulkCnt + dvBulk.Count >= pickDetailMaxInWave) { continue; } DateTime d1 = DateTime.Now; List lstBulk = new List(); bulkCnt += dvBulk.Count; lstBulk = new List(); sumBulkCnt = 0; int lastId = 0; foreach (DataRowView drv in dvBulk) { WmsStockRecord sr = new WmsStockRecord(); sr.ID = Convert.ToInt32(drv["id"].ToString()); sr.locationId = drv["locationID"].ToString(); sr.orderDetailId = Convert.ToInt32(drv["orderDetailId"].ToString()); if (WmsConstants.OUT_STOCK_DEDUCT) { sr.count = Convert.ToDecimal(drv["countOuting"].ToString()); } else { sr.count = Convert.ToDecimal(drv["count"].ToString()); } #if DEBUG if (lblist.Count > 0) { int id = new Random().Next(lblist.Count); //#if DEBUG sr.location.elabId = lblist[id]; //new Random().Next(minId, maxId + 1); //测试。。。随机分配标签id 为 1-3 while (lblist.Count > 1 && lastId == sr.location.elabId) { id = new Random().Next(lblist.Count); sr.location.elabId = lblist[id]; } lastId = sr.location.elabId; //#endif } #endif sumBulkCnt += sr.count; lstBulk.Add(sr); } #region checklabellimit foreach (WmsStockRecord rec in lstBulk)//检查电子标签数量是否超过范围 { if (tmplabelCnt.ContainsKey(rec.location.elabId)) { tmplabelCnt[rec.location.elabId]++; } else { tmplabelCnt[rec.location.elabId] = 1; } if (tmpcomCnt.ContainsKey(rec.location.port)) { tmpcomCnt[rec.location.port] = tmpcomCnt[rec.location.port] + 1; } else { tmpcomCnt[rec.location.port] = 1; } if (labelCnt.ContainsKey(rec.location.elabId)) { labelCnt[rec.location.elabId] = labelCnt[rec.location.elabId] + 1; if (labelCnt[rec.location.elabId] >= labelMaxInWave) { isReachLimit = true; foreach (int k in tmplabelCnt.Keys) { if (labelCnt.ContainsKey(k)) { labelCnt[k] -= tmplabelCnt[k]; } } break; } } else { labelCnt[rec.location.elabId] = 1; } if (comCnt.ContainsKey(rec.location.port)) { comCnt[rec.location.port] = comCnt[rec.location.port] + 1; if (comCnt[rec.location.port] >= pickDetailMaxInWave) { isReachLimit = true; foreach (int k in tmpcomCnt.Keys) { if (comCnt.ContainsKey(k)) { comCnt[k] -= tmpcomCnt[k]; } } break; } } else { comCnt[rec.location.port] = 1; } } //TimeSpan ts11 = DateTime.Now - d11; //System.Diagnostics.Debug.WriteLine(string.Format(" 检查是否超限完毕 --- cost {0}", ts11.TotalSeconds + " : " + ts11.TotalMilliseconds)); if (isReachLimit) { isReachLimit = false; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("超过限制,继续下条数据.... ")); continue; } #endregion //tsss = DateTime.Now - d2; tmplabelCnt.Clear(); tmpcomCnt.Clear(); //DateTime d11 = DateTime.Now; //System.Diagnostics.Debug.WriteLine(string.Format(" 开始检查是否超限 --- {0}", d11)); if (isSeedsEnabled && request.seedsLabelId==WmsConstants.SEEDS_LABLEID_MARK_VALUE ) //订单货品零货数量小 /*if (isSeedsEnabled && lstBulk.Count < pickGoodsTypeMin //订单货品种类小 && sumBulkCnt < pickGoodsCountMin && !noSeeds.Contains(request.pickOrderNo) ) */ { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("进入播种拣选 seedsRequests.Count:{0} ,_seedsDesk.ID :{1}" + ",seedsRequests contains {2}: {3}", seedsRequests.Count, _seedsDesk.ID, request.pickOrderNo, seedsRequests.Contains(request))); foreach (WmsOutPickRequest wor in seedsRequests) { if (wor.pickOrderNo == request.pickOrderNo) { LogHelper.debug(typeof(lWmsOutPickRequest), "seedsRequests.Contains(request): " + seedsRequests.Contains(request)); LogHelper.debug(typeof(lWmsOutPickRequest), "seedsRequests contains " + request.pickOrderNo); continue; } } //播种筛选 // if (isSeedsEnabled && seedsRequests.Count < seedsCount )//播种能力之内 // && lstBulk.Count < pickGoodsTypeMin //订单货品种类小 // && sumBulkCnt < pickGoodsCountMin) //订单货品零货数量小 if (_seedsDesk.ID > 0) //exist free seeds desk { if (seedsRequests.Count < seedsCount)//播种能力之内 { //符合播种条件,整合订单 seedsRequests.Add(request); //出库明细合并 foreach (WmsStockRecord wsr in lstBulk) { if (seedsBulks.ContainsKey(wsr.locationId)) { seedsBulks[wsr.locationId].count += wsr.count; seedsBulks[wsr.locationId].countOuting += wsr.countOuting; } else { seedsBulks[wsr.locationId] = wsr; } lstSeedsBulk.Add(wsr); } if (seedsRequests.Count == seedsCount) //生成播种拣选单 { //create seeds pick request //create pick detail WmsOutPickLable_tmp createSeedsRequest(seedsRequests, seedsBulks, lstSeedsBulk); lstSeedsBulk.Clear(); seedsRequests.Clear(); seedsBulks.Clear(); _seedsDesk = getRandomFreeSeedsDesk(); //重新取可用播种台 seedsCount = _seedsDesk.seedsCount; // continue; } continue; } } else //no free seeds desk { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("播种拣选,no free seeds desk")); if (!isSeedPickInSameWave) //播、摘同波次 { break; } LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("订单{0} 将进入下一播种波次,开始处理下个订单", request.pickOrderNo)); continue; } } else // 非播种拣选 { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" lstBulk.Count:{1},sumBulkCnt:{2}" , seedsRequests.Count, lstBulk.Count, sumBulkCnt)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("进入摘果式拣选")); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("last address: {0},current address: {1}", lastAddress, request.customerName + request.custAddress)); //} //建立零库电子拣选临时数据 ---摘果 if (desk.color == 0) { break; } LogHelper.debug(typeof(lWmsOutPickRequest), " 摘果式 保存整货和零货出库分拣数据"); WmsOutPickLable_tmp wpl; foreach (WmsStockRecord rec in lstBulk) { // if (rec.count == 0) if (rec.count + rec.countOuting < 1) //不支持小数 { continue; } wpl = new WmsOutPickLable_tmp(); wpl.pickOrderNo = request.pickOrderNo; wpl.recordId = rec.ID; wpl.color = desk.color; wpl.count = rec.count + rec.countOuting; wpl.locationId = rec.locationId; wpl.elabAddress = rec.location.elabAddress; wpl.elabId = rec.location.elabId; // wpl.elabId = new Random().Next(1,4); //测试。。。随机分配标签id 为 1-3 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(); WmsOutPickPort wop = new WmsOutPickPort();// wp.recordId wop.getPickPortByRecordId(wp.recordId); wop.dpsOrder = waveOrder; wop.Update(); // WmsOutPickDetail pd = new WmsOutPickDetail(wp.orderDetailId); // pd.updateErpSaleDetail_deng(true); } // foreach (WmsOutPickPort wop in lstPort) //建立电子拣选临时数据 // { // wop.Add(); // } if (lstLabel.Count > 0) { request.waveOrder = waveOrder; // request.state = (int)enumOutStockRequestStatus.正在分拣; request.waveStart = request.getDateTime(); request.operater = this.operId; request.updateBulkPickStatus(request.pickOrderNo, enumOutStockPickStatus.正在分拣, operId); request.desk = desk.color; desk.state = (int)enumDeskState.任务中; desk.Update(); request.Update(); bulkRequests.Add(request); int count = outRequest.saveTempData4Validation(waveOrder, request.pickOrderNo); LogHelper.debug(typeof(lWmsOutPickRequest), "---------- insert into detail temp data count " + count); } //if (lstPort.Count > 0) // { // request.updateBatchPickStatus(request.pickOrderNo, enumOutStockPickStatus.待处理); // } waveSize++; scope1.Complete(); //TimeSpan ts2 = DateTime.Now - d12; //System.Diagnostics.Debug.WriteLine(string.Format(" {1} 保存完毕 {0} cost {2} .....", request.pickOrderNo, DateTime.Now, ts2.TotalSeconds + " : " + ts2.TotalMilliseconds)); } //System.Diagnostics.Debug.WriteLine(string.Format("{1} 处理完毕 {0} cost {2} .....", request.pickOrderNo,DateTime.Now, ts.TotalSeconds +" : "+ ts.TotalMilliseconds)); } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); // System.Diagnostics.Debug.WriteLine(e.Message); } TimeSpan ts00 = DateTime.Now - d00; totoalTime += ts00.TotalSeconds; } } /*少于播种台播种订单个数时 ,等待新订单加入后再拣选 或改播种台或改摘果 */ if (isSeedsEnabled && seedsRequests.Count > 0) { LogHelper.debug(typeof(lWmsOutPickRequest), String.Format("not full seeds pool detetcted, size {0}", seedsRequests.Count)); if (seedsRequests.Count == seedsCount || seedsRequests.Count >= seedsDesk.seedsMinCount) // || seedsRequests.Count < seedsCount && canSeedPickLessThanseedsCount { LogHelper.debug(typeof(lWmsOutPickRequest), String.Format(" mini seeds cnt meet for seeds desk {0} , size {1}",_seedsDesk.ID, seedsRequests.Count)); createSeedsRequest(seedsRequests, seedsBulks, lstSeedsBulk);//生成播种拣选单 } else { LogHelper.debug(typeof(lWmsOutPickRequest), String.Format(" seedsWaiting size {0} ", seedsWaiting.Count)); foreach (WmsOutPickRequest pr in seedsRequests) { if (!seedsWaiting.Keys.Contains(pr.pickOrderNo)) { seedsWaiting[pr.pickOrderNo] = System.DateTime.Now; } else { DateTime dte = seedsWaiting[pr.pickOrderNo].AddMinutes(WmsConstants.OUT_MAX_SEEDS_WAIT_MINUES); if (dte > System.DateTime.Now) { seedsWaiting.Remove(pr.pickOrderNo); noSeeds.Add(pr.pickOrderNo); LogHelper.debug(typeof(lWmsOutPickRequest), String.Format("pr {0} waited {1},noseeds marked", pr.pickOrderNo, dte.CompareTo(DateTime.Now))); } } } } seedsRequests.Clear(); seedsBulks.Clear(); } //int count1 = 0; try { // count = outRequest.saveTempData4Validation(waveOrder); } catch (Exception er) { LogHelper.debug(typeof(lWmsOutPickRequest), er.Message); } // LogHelper.debug(typeof(lWmsOutPickRequest), "---------- insert into detail temp data count " + count); TimeSpan ts1 = DateTime.Now - d0; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 零库处理完毕----- cost {1} .....{2}", DateTime.Now, ts1.TotalSeconds + ":" + ts1.TotalMilliseconds, totoalTime)); // insert tmp data for validation //outRequest.saveTempData4Validation(waveOrder); WmsConstants.WAVE_CURRENT_PICK_STATUS.Clear(); WmsConstants.WAVE_CURRENT_ORDER = waveOrder; WmsConstants.WAVE_LAST_TIME = DateTime.Now; //检查待补货出货单状态 Thread stockCheckThread = new Thread(checkRepAndNoStockOrders); stockCheckThread.IsBackground = true; stockCheckThread.Start(); TimeSpan ts0 = DateTime.Now - d0; //System.Diagnostics.Debug.WriteLine(string.Format("{0} 全部处理完毕{1} ..", DateTime.Now, ts0.TotalSeconds + " : " + ts0.TotalMilliseconds)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 全部处理完毕,耗时{1} ..", DateTime.Now, ts0.TotalSeconds + ":" + ts0.TotalMilliseconds)); // TaskCallBack(); try { outRequest.fixMore(); } catch (Exception er) { LogHelper.debug(typeof(lWmsOutPickRequest), er.StackTrace.ToString()); } LogHelper.debug(typeof(lWmsOutPickRequest), "wave cnt is " + waveCnt); foreach(int key in comCnt.Keys) { LogHelper.debug(typeof(lWmsOutPickRequest), String.Format("com {0}, rec cnt {1} ", key, comCnt[key])); } foreach (int key in labelCnt.Keys) { if(labelCnt[key]>2) LogHelper.debug(typeof(lWmsOutPickRequest), String.Format("labelid {0}, rec cnt {1}" , key, labelCnt[key])); } } internal string assignTasks(int[] ids, int empId) { if (!havePermission(WmsConstants.SPECIAL_VALID_REASSIN_TASK_BY_ID)) { return "权限不足"; } Employee employee = new Employee(empId); if (string.IsNullOrEmpty(employee.create_time)) { return "员工信息错误"; } int i = 0; foreach (int id in ids) { WmsOutPickPort wop = new WmsOutPickPort(id); if (!string.IsNullOrEmpty(wop.jobNo)) { if (wop.state == 0) { if (wop.takeBy > 0) { wop.description += " 原任务所有者 为 " + wop.takeBy + ",reassign to " + empId + ", " + DateTime.Now; } wop.takeBy = empId; wop.Update(); i++; } } } if (i > 0) return "分配成功,共分配了 " + i + " 条任务"; else return "分配失败"; } internal List getRequestsByTransNo(string transNo) { return getWmsOutPickRequest.getRequestsByTransNo(transNo); } internal DataTable getRequestDtByTransNo(string transNo) { return getWmsOutPickRequest.getReqDtByTransNo(transNo); } public void newBulkDPSandSeedsPickWave2() { //播种筛选, //适合播种的客户订单合并成一个、多个大订单,统一捡出后进行播种操作 //1. 单个订单的品种少 、数量少 //2. 订单数量多 //只处理订单零货部分 //加入播种选项,所有订单零货部分使用摘取+播种方式 //1.播种点数量可配置, 分别用不同颜色区分 //2.每个播种点可分播客户的数量配置, 即每个播种点处理零货订单数量( 例如配置成6个,一次捡6个客户的订单零货部分,送由一个播种点播种) //3.波次和播种点的对应关系,一个波次只摘取一个播种点的零货,还是多个播种点的数据? //4. //一个波次可以摘取订单数 = 空闲分播台数量*每个分播台可分播客户数, 分播台的订单用颜色区分 // LogHelper.debug(typeof(lWmsOutPickRequest), "开始新波次。。。。。。。。。。。。。。。。。。"); // System.Diagnostics.Debug.WriteLine("begin make new wave .....{0}" ,DateTime.Now); List requests = outRequest.getRequests4Wave(); //.getRequestObjects(enumOutOrderType.拣货单, enumOutStockRequestStatus.波次处理); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理订单数量:{0}", requests.Count)); if (requests.Count == 0) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("无订单需要处理,波次结束")); checkRepAndNoStockOrders(); return; } desk.restDeskStatus(enumDeskState.空闲); if (!WmsConstants.OUT_BULK_DESK_CONTROLL) {//播种复核台完成复核任务前,复核台不可用,拆零波次不分配给复核台任务 //播种复核台复位 desk.restDeskStatus(enumDeskState.空闲, enumDeskType.播种); //播种台状态复位到空闲, } _seedsDesk = getRandomFreeSeedsDesk(); _desk = getRandomFreeDesk(); int labelMaxInWave = WmsConstants.MAX_LABEL_DATA_IN_A_WAVE; //一个标签一个波次只能存储40条数据 #if DEBUG // if (lblist.Count == 0) { lblist.Clear(); initialDebugSetting(); } lblist.Sort(); // int minId = lblist[0]; // int maxId = lblist[lblist.Count - 1]; // labelMaxInWave = 2; #endif // List strecs = null; waveOrder = Util.getOrderNo(enumCreateOrderType.dpsOrder, _obj.getNextSeq(enumCreateOrderType.dpsOrder)); //waveOrder = "WV" + System.DateTime.Now.ToString("yyyyMMddHHmmss"); int pickDetailMaxInWave = WmsConstants.MAX_CONTROL_DATA_IN_A_WAVE; //一个控制器最大存储1200条 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; 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(); List lstSeedsBulk = new List(); //订单充足的情况下,每个波次的拣货负载均衡化,每个波次每个复核台都要最大负载,不空转 //先满足播种数据,再进行摘果 if (desk.ID == 0) // no free pick desk { if (isSeedsEnabled) { _seedsDesk = getRandomFreeSeedsDesk(); if (seedsDesk.ID == 0) { return; } } else { return; } } int bulkCnt = 0; int requestCnt = 0; bulkRequests = new List(); //for batch process in a new thread //开始处理有零货的订单 DateTime d0 = DateTime.Now; double totoalTime = 0d; string lastAddress = ""; foreach (WmsOutPickRequest request in requests) { DateTime d00 = DateTime.Now; if(request.pickOrderNo== "PK23031557945") { bool HIT = true; } if (request.bulkCnt > 0) { requestCnt++; } if (requestCnt >= pickDetailMaxInWave) { break; } if (request.bulkCnt == 0) { continue; } // LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("开始处理零库出库 {0} ------------", request.pickOrderNo )); LogHelper.debug(this.GetType(), string.Format("开始处理零库出库 {0} ------------", request.pickOrderNo)); DataTable dt = stkRecord.getPickStockRecods(request.pickOrderNo, true).Tables[0];//取出库明细 // lstPort = new List(); lstLabel = new List(); //开始处理零货出库 DataView dvBulk = new DataView(dt); dvBulk.RowFilter = string.Format(" volType in ({0},{1})", (int)enumWhLocVol.零库1, (int)enumWhLocVol.零库); if (bulkCnt + dvBulk.Count >= pickDetailMaxInWave) { break; } //TimeSpan tssss = DateTime.Now - d00; //System.Diagnostics.Debug.WriteLine(string.Format(" {0} {1},befor prepare bulklist, cost {2}", DateTime.Now, request.pickOrderNo, tssss.TotalSeconds)); DateTime d1 = DateTime.Now; List lstBulk = new List(); bulkCnt = dvBulk.Count; /*foreach (DataRowView drv in dvBulk) { bulkCnt++; lstBulk.Add(new WmsStockRecord(drv.Row)); }*/ // TimeSpan tsss = DateTime.Now - d1; // LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" {0} prepare bulklist count :{1}, cost {2}", request.pickOrderNo, lstBulk.Count, tsss.TotalSeconds)); // DateTime d2 = DateTime.Now; lstBulk = new List(); sumBulkCnt = 0; int lastId = 0; foreach (DataRowView drv in dvBulk) { WmsStockRecord sr = new WmsStockRecord(); sr.ID = Convert.ToInt32(drv["id"].ToString()); sr.locationId = drv["locationID"].ToString(); sr.orderDetailId = Convert.ToInt32(drv["orderDetailId"].ToString()); if (WmsConstants.OUT_STOCK_DEDUCT) { sr.count = Convert.ToDecimal(drv["countOuting"].ToString()); } else { sr.count = Convert.ToDecimal(drv["count"].ToString()); } #if DEBUG if (lblist.Count > 0) { int id = new Random().Next(lblist.Count); //#if DEBUG sr.location.elabId = lblist[id]; //new Random().Next(minId, maxId + 1); //测试。。。随机分配标签id 为 1-3 while (lblist.Count > 1 && lastId == sr.location.elabId) { id = new Random().Next(lblist.Count); sr.location.elabId = lblist[id]; } lastId = sr.location.elabId; //#endif } #endif sumBulkCnt += sr.count; lstBulk.Add(sr); } //tsss = DateTime.Now - d2; // LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" {0} {1},prepare bulklist2 count :{2}, cost {3}", DateTime.Now, request.pickOrderNo, lstBulk.Count, tsss.TotalSeconds)); /* pickDetailMaxInWave -= strecs.Count; if (pickDetailMaxInWave < 0) { //超出一个波次最大分拣数量 isReachLimit = true; break; } */ tmplabelCnt.Clear(); tmpcomCnt.Clear(); //DateTime d11 = DateTime.Now; //System.Diagnostics.Debug.WriteLine(string.Format(" 开始检查是否超限 --- {0}", d11)); if (isSeedsEnabled && lstBulk.Count < pickGoodsTypeMin //订单货品种类小 && sumBulkCnt < pickGoodsCountMin && !noSeeds.Contains(request.pickOrderNo) ) //订单货品零货数量小 { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("进入播种拣选 seedsRequests.Count:{0} ,_seedsDesk.ID :{1}" + ",seedsRequests contains {2}: {3}", seedsRequests.Count, _seedsDesk.ID, request.pickOrderNo, seedsRequests.Contains(request))); foreach (WmsOutPickRequest wor in seedsRequests) { if (wor.pickOrderNo == request.pickOrderNo) { LogHelper.debug(typeof(lWmsOutPickRequest), "seedsRequests.Contains(request): " + seedsRequests.Contains(request)); LogHelper.debug(typeof(lWmsOutPickRequest), "seedsRequests contains " + request.pickOrderNo); continue; } } //播种筛选 // if (isSeedsEnabled && seedsRequests.Count < seedsCount )//播种能力之内 // && lstBulk.Count < pickGoodsTypeMin //订单货品种类小 // && sumBulkCnt < pickGoodsCountMin) //订单货品零货数量小 if (_seedsDesk.ID > 0) //exist free seeds desk { if (seedsRequests.Count < seedsCount)//播种能力之内 { //符合播种条件,整合订单 seedsRequests.Add(request); //出库明细合并 foreach (WmsStockRecord wsr in lstBulk) { if (seedsBulks.ContainsKey(wsr.locationId)) { seedsBulks[wsr.locationId].count += wsr.count; seedsBulks[wsr.locationId].countOuting += wsr.countOuting; } else { seedsBulks[wsr.locationId] = wsr; } lstSeedsBulk.Add(wsr); } if (seedsRequests.Count == seedsCount) //生成播种拣选单 { //create seeds pick request //create pick detail WmsOutPickLable_tmp createSeedsRequest(seedsRequests, seedsBulks, lstSeedsBulk); lstSeedsBulk.Clear(); seedsRequests.Clear(); seedsBulks.Clear(); _seedsDesk = getRandomFreeSeedsDesk(); //重新取可用播种台 seedsCount = _seedsDesk.seedsCount; // continue; } continue; } } else //no free seeds desk { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("播种拣选,no free seeds desk")); if (!isSeedPickInSameWave) //播、摘同波次 { break; } LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("订单{0} 将进入下一播种波次,开始处理下个订单", request.pickOrderNo)); continue; } } else // 非播种拣选 { _desk = getRandomFreeDesk(); /* *一个客户在同一个波次不能有多个pickOrder,不然比较麻烦 if (!lastAddress.Equals(request.customerName + request.custAddress)) { _desk = getRandomFreeDesk(); lastAddress = request.customerName + request.custAddress; } */ if (desk.color == 0) // no exist free desk, then process bulk { // LogHelper.debug(typeof(lWmsOutPickRequest), "摘果式拣选,无可用复核台"); if (isSeedsEnabled && _seedsDesk.ID > 0) // 启用播种后,由播种台是否空闲来判断是否结束循环 { LogHelper.debug(typeof(lWmsOutPickRequest), " 播种台有空,继续处理剩余订单"); continue; } else { LogHelper.debug(typeof(lWmsOutPickRequest), " 无可用复核台、播种台,波次生成结束"); break; } } else { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("pickorderno: {0},desk id :{1}", request.pickOrderNo, desk.ID)); } if (WmsConstants.OUT_LIGHT_ENABLE) { #region checklabellimit foreach (WmsStockRecord rec in lstBulk)//检查电子标签数量是否超过范围 { /* 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 } */ if (tmplabelCnt.ContainsKey(rec.location.elabId)) { tmplabelCnt[rec.location.elabId]++; } else { tmplabelCnt[rec.location.elabId] = 1; } if (tmpcomCnt.ContainsKey(rec.location.port)) { tmpcomCnt[rec.location.port] = tmpcomCnt[rec.location.port] + 1; } else { tmpcomCnt[rec.location.port] = 1; } if (labelCnt.ContainsKey(rec.location.elabId)) { labelCnt[rec.location.elabId] = labelCnt[rec.location.elabId] + 1; if (labelCnt[rec.location.elabId] >= labelMaxInWave) { isReachLimit = true; foreach (int k in tmplabelCnt.Keys) { if (labelCnt.ContainsKey(k)) { labelCnt[k] -= tmplabelCnt[k]; } } break; } } else { labelCnt[rec.location.elabId] = 1; } if (comCnt.ContainsKey(rec.location.port)) { comCnt[rec.location.port] = comCnt[rec.location.port] + 1; if (comCnt[rec.location.port] >= pickDetailMaxInWave) { isReachLimit = true; foreach (int k in tmpcomCnt.Keys) { if (comCnt.ContainsKey(k)) { comCnt[k] -= tmpcomCnt[k]; } } break; } } else { comCnt[rec.location.port] = 1; } } #endregion //TimeSpan ts11 = DateTime.Now - d11; //System.Diagnostics.Debug.WriteLine(string.Format(" 检查是否超限完毕 --- cost {0}", ts11.TotalSeconds + " : " + ts11.TotalMilliseconds)); if (isReachLimit) { isReachLimit = false; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("超过限制,继续下条数据.... ")); continue; } } LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" lstBulk.Count:{1},sumBulkCnt:{2}" , seedsRequests.Count, lstBulk.Count, sumBulkCnt)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("进入摘果式拣选")); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("last address: {0},current address: {1}", lastAddress, request.customerName + request.custAddress)); //} //建立零库电子拣选临时数据 ---摘果 if (desk.color == 0) { break; } LogHelper.debug(typeof(lWmsOutPickRequest), " 摘果式 保存整货和零货出库分拣数据"); WmsOutPickLable_tmp wpl; foreach (WmsStockRecord rec in lstBulk) { // if (rec.count == 0) if (rec.count + rec.countOuting < 1) //不支持小数 { continue; } wpl = new WmsOutPickLable_tmp(); wpl.pickOrderNo = request.pickOrderNo; wpl.recordId = rec.ID; wpl.color = desk.color; wpl.count = rec.count + rec.countOuting; wpl.locationId = rec.locationId; wpl.elabAddress = rec.location.elabAddress; wpl.elabId = rec.location.elabId; // wpl.elabId = new Random().Next(1,4); //测试。。。随机分配标签id 为 1-3 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(); WmsOutPickPort wop = new WmsOutPickPort();// wp.recordId wop.getPickPortByRecordId(wp.recordId); wop.dpsOrder = waveOrder; wop.Update(); // WmsOutPickDetail pd = new WmsOutPickDetail(wp.orderDetailId); // pd.updateErpSaleDetail_deng(true); } // foreach (WmsOutPickPort wop in lstPort) //建立电子拣选临时数据 // { // wop.Add(); // } if (lstLabel.Count > 0) { request.waveOrder = waveOrder; // request.state = (int)enumOutStockRequestStatus.正在分拣; request.waveStart = request.getDateTime(); request.operater = this.operId; request.updateBulkPickStatus(request.pickOrderNo, enumOutStockPickStatus.正在分拣, operId); request.desk = desk.color; desk.state = (int)enumDeskState.任务中; desk.Update(); request.Update(); bulkRequests.Add(request); int count= outRequest.saveTempData4Validation(waveOrder,request.pickOrderNo); LogHelper.debug(typeof(lWmsOutPickRequest), "---------- insert into detail temp data count " + count); } //if (lstPort.Count > 0) // { // request.updateBatchPickStatus(request.pickOrderNo, enumOutStockPickStatus.待处理); // } waveSize++; scope1.Complete(); //TimeSpan ts2 = DateTime.Now - d12; //System.Diagnostics.Debug.WriteLine(string.Format(" {1} 保存完毕 {0} cost {2} .....", request.pickOrderNo, DateTime.Now, ts2.TotalSeconds + " : " + ts2.TotalMilliseconds)); } //System.Diagnostics.Debug.WriteLine(string.Format("{1} 处理完毕 {0} cost {2} .....", request.pickOrderNo,DateTime.Now, ts.TotalSeconds +" : "+ ts.TotalMilliseconds)); } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); // System.Diagnostics.Debug.WriteLine(e.Message); } TimeSpan ts00 = DateTime.Now - d00; totoalTime += ts00.TotalSeconds; } } /*少于播种台播种订单个数时 ,等待新订单加入后再拣选 或改播种台或改摘果 */ if (isSeedsEnabled && seedsRequests.Count > 0) { if (seedsRequests.Count == seedsCount || seedsRequests.Count >= seedsDesk.seedsMinCount) // || seedsRequests.Count < seedsCount && canSeedPickLessThanseedsCount { createSeedsRequest(seedsRequests, seedsBulks, lstSeedsBulk);//生成播种拣选单 } else { // _seedsDesk = getRandomFreeSeedsDesk(); // if (seedsDesk.ID == 0) //无可用播种台 { foreach (WmsOutPickRequest pr in seedsRequests) { if (!seedsWaiting.Keys.Contains(pr.pickOrderNo)) { seedsWaiting[pr.pickOrderNo] = System.DateTime.Now; } else { DateTime dte = seedsWaiting[pr.pickOrderNo].AddMinutes(WmsConstants.OUT_MAX_SEEDS_WAIT_MINUES); if (dte > System.DateTime.Now) { seedsWaiting.Remove(pr.pickOrderNo); noSeeds.Add(pr.pickOrderNo); LogHelper.debug(typeof(lWmsOutPickRequest), String.Format("pr {0} waited {1},noseeds marked",pr.pickOrderNo,dte.CompareTo(DateTime.Now))); } } } } } seedsRequests.Clear(); seedsBulks.Clear(); } //int count1 = 0; try { // count = outRequest.saveTempData4Validation(waveOrder); } catch (Exception er) { LogHelper.debug(typeof(lWmsOutPickRequest), er.Message); } // LogHelper.debug(typeof(lWmsOutPickRequest), "---------- insert into detail temp data count " + count); TimeSpan ts1 = DateTime.Now - d0; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 零库处理完毕----- cost {1} .....{2}", DateTime.Now, ts1.TotalSeconds + ":" + ts1.TotalMilliseconds, totoalTime)); // insert tmp data for validation //outRequest.saveTempData4Validation(waveOrder); WmsConstants.WAVE_CURRENT_PICK_STATUS.Clear(); WmsConstants.WAVE_CURRENT_ORDER = waveOrder; WmsConstants.WAVE_LAST_TIME = DateTime.Now; //点亮标签开始捡货 // elelab.pick.send_data_pick(pickLabelDetail.getData4Pick(waveOrder).Tables[0], enumLabelPickType.pick); //检查待补货出货单状态 checkRepAndNoStockOrders(); // isProcessWaveing = false; //TODO: check if all batch is not finished, what happend? /* * Thread.CurrentThread.Join(1); Thread batchPick4Bulk = new Thread(new ParameterizedThreadStart(processBatchOrdersWithBulk)); batchPick4Bulk.IsBackground = true; batchPick4Bulk.Start(bulkRequests); */ // Thread.CurrentThread.Join(1); // process all batch pick request // Thread batchPick = new Thread(new ParameterizedThreadStart(processBatchWithBulkOrders)); // batchPick.IsBackground = true; // batchPick.Start(requests); // batchPick.Start(bulkRequests); //只处理有零货的订单,全为整的订单暂时在 GoodsBatchOutForm newBatchOnlyPDATasks // processAllBatchOrders(requests, waveOrder); TimeSpan ts0 = DateTime.Now - d0; //System.Diagnostics.Debug.WriteLine(string.Format("{0} 全部处理完毕{1} ..", DateTime.Now, ts0.TotalSeconds + " : " + ts0.TotalMilliseconds)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 全部处理完毕,耗时{1} ..", DateTime.Now, ts0.TotalSeconds + ":" + ts0.TotalMilliseconds)); // TaskCallBack(); try { outRequest.fixMore(); } catch (Exception er) { LogHelper.debug(typeof(lWmsOutPickRequest),er.StackTrace.ToString()); } } /// /// 取指定分区的,指定状态的亮灯数据 /// 按复核台、波次号 asc 排序 /// /// /// /// internal DataTable getSeedDesksPickList(int partId, enumPickState status) { DataTable dt= pickLabelDetail.getSeedDesksPickList(partId, status); if (!WmsConstants.SEEDS_PARTION_DESK_COLOR_MAP) { return dt; } Dictionary currentWavePart = new Dictionary (); Dictionary mapColorPairs = new Dictionary (); foreach (DataRow dr in dt.Rows) { string waveNo = dr["dpsOrder"].ToString(); int color = getMapColor(mapColorPairs, Convert.ToInt32(dr["color"].ToString())); dr["color"] = color; currentWavePart[color]=waveNo; } WmsWave ww = new WmsWave(); ww.clearSeedsPart(partId); foreach (int color in currentWavePart.Keys) { ww.partion = partId; ww.mapColor = color; ww.waveNo= currentWavePart[color]; ww.terminal = getOrigColor(mapColorPairs, color); ww.Add(); } return dt; } private int getMapColor(Dictionary mapColorPairs, int color) { if (mapColorPairs.ContainsKey(color)) { return mapColorPairs[color]; } int maxColor = 0; foreach (int value in mapColorPairs.Values) { if (maxColor < value) { maxColor = value; } } maxColor++; mapColorPairs[color] = maxColor; return maxColor; } private int getOrigColor(Dictionary mapColorPairs, int color) { foreach (int key in mapColorPairs.Keys) { if (color == mapColorPairs[key]) { return key; } } return color; } void createSeedsRequest(List seedsRequests, Dictionary seedsBulks,List lstBulk ) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("开始生成播种拣选单,seedsRequests.count :{0},seedsBulks.count:{1}", seedsRequests.Count, seedsBulks.Count)); List lstLabel = new List(); if (_seedsDesk.ID == 0) { return; } WmsOutPickRequest seedPickRequest = new WmsOutPickRequest(); seedPickRequest.pickOrderNo = Util.getOrderNo(enumCreateOrderType.seedsPickOrder, seedPickRequest.getNextSeq(enumCreateOrderType.seedsPickOrder)); seedPickRequest.orderType = (int)enumOrderType.销售出库; seedPickRequest.outStoreType = (int)enumOutStoreType.播种拣货出库; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("播种拣选单 :{0} ", seedPickRequest.pickOrderNo)); WmsWave ww = new WmsWave(); ww.waveNo = waveOrder; ww.seedsNo = seedPickRequest.pickOrderNo; ww.deskColor = _seedsDesk.color; ww.state =(int) enumOutStockRequestStatus.正在分拣; WmsOutPickLable_tmp wpl; foreach (WmsStockRecord rec in seedsBulks.Values) { if (rec.count +rec.countOuting <1) { // continue; } wpl = new WmsOutPickLable_tmp(); wpl.pickOrderNo = seedPickRequest.pickOrderNo; wpl.recordId = rec.ID; wpl.color = seedsDesk.color; wpl.orderDetailId = rec.orderDetailId;//部分,不精确到一一对应 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; //#if DEBUG if (comLables.Count > 0) { wpl.port = comLables[wpl.elabId]; //rec.location.elabId < 4 ?5 :3; //测试。。。 分配标签端口为3 } //#endif wpl.dpsOrder = waveOrder; wpl.operater = this.operId; lstLabel.Add(wpl); } int i =0; int startId = seedsDesk.startLabelId; //保存整货和零货出库分拣数据 try { using (TransactionScope scope1 = new TransactionScope()) { ww.Add(); foreach (WmsOutPickLable_tmp wp in lstLabel) //建立电子拣选临时数据 { wp.Add(); } seedsDesk.state = (int)enumDeskState.任务中; seedsDesk.Update(); foreach (WmsOutPickRequest request in seedsRequests) { if (lstLabel.Count > 0) { request.waveOrder = waveOrder; // request.state = (int)enumOutStockRequestStatus.正在分拣; request.waveStart = request.getDateTime(); request.operater = this.operId; // request.updateBulkPickStatus(request.pickOrderNo, enumOutStockPickStatus.正在分拣, operId); request.bulkPickState = (int)enumOutStockPickStatus.正在分拣; request.desk = seedsDesk.color; request.seedsLabelId = startId > 0 ? startId++ : seedsDesk.color * 10 + ++i; //每个播种复合台的标签ID编号不重复,应对多个播种台共用一个标签控制器的情况。 request.seedsPickNo = seedPickRequest.pickOrderNo; //赋值播种拣选订单单号 request.seedsPort = seedsDesk.port; request.Update(); bulkRequests.Add(request); int count = outRequest.saveTempData4Validation(waveOrder, request.pickOrderNo); request.updateBulkPickStatus(request.pickOrderNo, enumOutStockPickStatus.正在分拣,operId); LogHelper.debug(typeof(lWmsOutPickRequest), "---------- insert into detail temp data count " + count); } //waveSize++; /* Erp_sale es = new Erp_sale(); es.getByPickOrder(request.pickOrderNo); es.liangdeng = true; es.Update(); */ } WmsOutPickPort wop; foreach (WmsStockRecord wsr in lstBulk) { wop = new WmsOutPickPort(); wop.getPickPortByRecordId(wsr.ID); wop.dpsOrder = waveOrder; wop.pickDetailId = wsr.orderDetailId; wop.Update(); } scope1.Complete(); //TimeSpan ts2 = DateTime.Now - d12; //System.Diagnostics.Debug.WriteLine(string.Format(" {1} 保存完毕 {0} cost {2} .....", request.pickOrderNo, DateTime.Now, ts2.TotalSeconds + " : " + ts2.TotalMilliseconds)); } //System.Diagnostics.Debug.WriteLine(string.Format("{1} 处理完毕 {0} cost {2} .....", request.pickOrderNo,DateTime.Now, ts.TotalSeconds +" : "+ ts.TotalMilliseconds)); } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); } } /// /// 点亮待拣选标签 /// //public void lightLables() //{ // lastWave = DateTime.Now; // WmsConstants.WAVE_CURRENT_LIGHTS_STATUS.Clear(); // elelab.pick.send_data_pick( pickLabelDetail.getPickedData(enumLabelPickState.notPicked).Tables[0], enumLabelPickType.pick); //} /// /// 检查补货出货单状态 /// 若不再缺货则进下个波次 /// public void checkRepAndNoStockOrders() { LogHelper.debug(typeof(lWmsOutPickRequest), String.Format(" start check stock for ...... " + enumOutStockRequestStatus.等待补货)); bool isOk; List prs = outRequest.getRequestObjects( enumOutStockRequestStatus.等待补货); foreach (WmsOutPickRequest pr in prs) { // LogHelper.debug(typeof(lWmsOutPickRequest), String.Format(" start check stock for pr {0} ...... ", pr.pickOrderNo)); isOk = true; foreach (WmsOutPickDetail pd in pr.outDetails) { if (pd.state == (int)enumOutStockDetailStatus.等待补货) { // decimal d = pd.goods.stockBulkCount /* pd.getGoodsStockCnt(enumWhLocVol.零库)*/; decimal d = pd.goods.stockBulkAvCount /* pd.getGoodsStockCnt(enumWhLocVol.零库)*/; if (pd.bulkCount >= d) { isOk = false; break; } } } if (isOk) { LogHelper.debug(typeof(lWmsOutPickRequest), String.Format( "pr {0} stock bulk available, start stock process... ",pr.pickOrderNo ) ); pr.state = (int)enumOutStockRequestStatus.待定位; // pr.operater = LoginInfo.UserId; // pr.lastmodified = pr.getDateTime(); pr.operater = this.operId; pr.Update(); new lWmsOutRequest(operId).requestOutStock(pr); //在库存扣除后,将分拣单状态置为等待波次 LogHelper.debug(typeof(lWmsOutPickRequest), String.Format("pr {0} stock process done...,new status {1} ", pr.pickOrderNo, pr.state)); } } LogHelper.debug(typeof(lWmsOutPickRequest), String.Format(" end check stock for ...... " + enumOutStockRequestStatus.等待补货)); } /* void processBatchOrdersWithBulk(Object obs) { //开始处理整库出货部分 DateTime t0 = DateTime.Now; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" 整库部分出库 处理开始...................." ) ); List requests = (List)obs; foreach (WmsOutPickRequest request in requests) { processPickRequest(request); } TimeSpan ts = DateTime.Now - t0; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" 整库部分出库 处理完毕 cost {0}....................", ts.TotalSeconds + " : " + ts.TotalMilliseconds)); } void processBatchWithBulkOrders(Object obs) { //开始处理全整库出货部分 DateTime t0 = DateTime.Now; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format (" 整库出库 处理开始...................." )); List requests = (List)obs; foreach (WmsOutPickRequest request in requests) { if (request.bulkCnt ==0){ //亮灯波次只处理有零货也有整货的分拣单 continue; } processPickRequest(request); } TimeSpan ts = DateTime.Now - t0; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format (" 整库部分出库 处理完毕 cost {0}....................", ts.TotalSeconds + " : " + ts.TotalMilliseconds)); } */ /// /// 生成手持拣货数据 //GoodsBatchOutForm.cs newBatchOnlyPDATasks /// public void createPDAPickTasks( ) { createPDAPickTasks_do(enumOutStockRequestStatus.定位完成); if ( WmsConstants.OUT_STOCK_BULK_LACK_OUT) // 所有类型的分拣单,缺零 状态下是否进行分拣 { createPDAPickTasks_do(enumOutStockRequestStatus.等待补货); }else if (WmsConstants.OUT_STOCK_BULK_LACK_OUT_SEEDS) //取总分拣单在缺零状态下是否可以分拣 { createPDAPickTasks_do_type(enumOutStockRequestStatus.等待补货, enumOutStoreType.配货汇总拣货出库); } } public void createPDAPickTasks_do_type(enumOutStockRequestStatus status, enumOutStoreType outType) { List lst = outRequest.getRequestObjects(outType,status); // logOut.Debug(string.Format("begin createPDAPickTasks filter status {0}...count {1}................", status, lst.Count)); foreach (WmsOutPickRequest pr in lst) { processPickRequest(pr); } } public void createPDAPickTasks_do(enumOutStockRequestStatus status) { List lst = outRequest.getRequestObjects(status); // logOut.Debug(string.Format("begin createPDAPickTasks filter status {0}...count {1}................", status, lst.Count)); foreach (WmsOutPickRequest pr in lst) { processPickRequest(pr); } } /* public void processBatchPickOrders() { DataTable tb = outRequest.getBatchOnlyRequests(enumOutStockPickStatus.待处理); foreach (DataRow dr in tb.Rows) { processPickRequest(new WmsOutPickRequest(dr)); } }*/ void processPickRequest(WmsOutPickRequest request) { // DateTime t0 = DateTime.Now; // logOut.Debug(string.Format("{0} {1} 处理开始..................", DateTime.Now, request.pickOrderNo)); // DataTable dt = stkRecord.getPickStockRecods(request.pickOrderNo, true).Tables[0];//取出库明细 DataTable dt = stkRecord.getPickStockRecodsForPDAProcess(request.pickOrderNo ).Tables[0]; List lstPort = new List(); DataView dv = new DataView(dt); if (!WmsConstants.OUT_STOCK_BULK_PDA_SCAN) { //零库数据也入PDA手持捡货表 //dv.RowFilter = string.Format(" volType in ({0},{1},{2})", (int)enumWhLocVol.小整, (int)enumWhLocVol.中整, (int)enumWhLocVol.大整); dv.RowFilter = string.Format(" volType >0 " ); } // logSpec.Debug(dv.RowFilter); // logSpec.Debug(string.Format(" {2} outStoreType {4} ,status {3} ,stock out records count:{0}, include bulk out :{1} " // ,dv.Count, WmsConstants.OUT_STOCK_BULK_PDA_SCAN,request.pickOrderNo // ,(enumOutStockRequestStatus)request.state,(enumOutStoreType)request.outStoreType // )); string tranLocationId = request.tranLocationId; WmsLocation tranLoc=null; // logSpec.Debug( string.Format("begin processPickRequest...prNo {0}....,records cnt {1}............",request.pickOrderNo, dv.Count)); if (dv.Count == 0) { decimal cnt = 0, lackcnt = 0,seedcnt=0; foreach (WmsOutPickDetail wd in request.outDetails) { // logSpec.Debug("wd.seedsPickNo " + wd.seedsPickNo); if (!string.IsNullOrEmpty(wd.seedsPickNo)) { seedcnt += wd.count; continue; } cnt += wd.count; lackcnt += wd.lackCount; } // logSpec.Debug(string.Format("cnt {0}, seedscnt:{1}, lackcnt{2}" ,cnt,seedcnt,lackcnt)); if (cnt == 0) { request.description += "/.. 没有要出库的任务,结束拣选。"; if (lackcnt > 0) { request.description += ";/n 参考缺货记录"; } request.state =seedcnt>0? (int)enumOutStockRequestStatus.正在分拣: (int)enumOutStockRequestStatus.订单完成; // logSpec.Debug("order state " + request.state); request.Update(); } return; } if (dv.Count == 0 && request.batchPickState > 0) { if (String.IsNullOrEmpty(tranLocationId)) { tranLocationId = new TmsStock().getTranLocation(request.customerId); } // logSpec.Debug(string.Format("!!!!!! request stock out count :{0}, request.batchPickState :{1}, no out pick port created, return for next loop ", dv.Count, request.batchPickState)); request.operater = this.operId; request.tranLocationId = tranLocationId; request.batchPickState = (int)enumOutStockPickStatus.已定位; request.Update(); return; } if (String.IsNullOrEmpty(tranLocationId) &&!String.IsNullOrEmpty(request.customerId)) { tranLocationId = new TmsStock().getTranLocation(request.customerId); } //get tranLocationId,集货区,一条线路 共用一个整货位 if (!String.IsNullOrEmpty(tranLocationId)) { tranLoc = new WmsLocation(tranLocationId); } // logSpec.Debug(string.Format(" request tranLocationId :{0} ", tranLocationId)); foreach (DataRowView drv in dv) { // logSpec.Debug( " detail state is :" + drv["state"].ToString()); WmsStockRecord stRec = new WmsStockRecord(drv.Row); WmsOutPickPort wpp = new WmsOutPickPort(); if (stRec.ID == 0) { continue; } if (WmsConstants.OUT_STOCK_DEDUCT) { wpp.count = stRec.countOuting; } else { wpp.count = stRec.count; } wpp.virtialCnt = stRec.virCount; wpp.volType = Convert.ToInt32(drv["volType"].ToString()); wpp.locationId = stRec.locationId; wpp.pickOrderNo = stRec.orderNo; wpp.recType = stRec.rectype; wpp.recordId = stRec.ID; // wpp.waveOrder = request.waveOrder;// WmsConstants.WAVE_CURRENT_ORDER; //TODO: wave order can be null wpp.pickOrderNo = request.pickOrderNo; wpp.operater = operId; wpp.tranLocationId = tranLocationId; wpp.pickDetailId = stRec.orderDetailId; if (tranLoc != null) { wpp.tranArea = tranLoc.part; } wpp.partion = stRec.partion;//part 分区flag 1,2,3,4,5 分区拣货定义 lstPort.Add(wpp); } // logSpec.Debug("out pick port count to create :" + lstPort.Count); // System.Diagnostics.Debug.WriteLine(string.Format("{2} {0}, 记录 count:{1}", request.pickOrderNo, dvBatch.Count,DateTime.Now)); try { using (TransactionScope scope = new TransactionScope()) { foreach (WmsOutPickPort wop in lstPort) //建立手持分拣数据 { wop.Add(); } if (request.state != (int)enumOutStockRequestStatus.等待补货) { request.state = (int)enumOutStockRequestStatus.等待波次; if (request.batchPickState == (int)enumOutStockPickStatus.待处理) { request.batchPickState = (int)enumOutStockPickStatus.已定位; } if (WmsConstants.OUT_STOCK_BULK_PDA_SCAN && request.bulkPickState == (int)enumOutStockPickStatus.待处理) { request.bulkPickState = (int)enumOutStockPickStatus.已定位; } } // request.waveStart = request.getDateTime(); request.operater = this.operId; request.tranLocationId = tranLocationId; if (lstPort.Count > 0) { // request.updateBatchPickStatus(request.pickOrderNo, enumOutStockPickStatus.正在分拣,operId); } request.Update(); scope.Complete(); } } catch (Exception e) { logSpec.Error( e); throw e; } // logSpec.Debug(string.Format("end processPickRequest...prNo {0}....,records cnt {1}............", request.pickOrderNo, dv.Count)); // TimeSpan ts = DateTime.Now - t0; // System.Diagnostics.Debug.WriteLine(string.Format("{0} {2}处理完毕 cost {1}....................", DateTime.Now, ts.TotalSeconds + " : " + ts.TotalMilliseconds, request.pickOrderNo)); } /// /// 随机获取摘取单订单复合台 /// /// private WmsOutDesk getRandomFreeDesk() { // #if DEBUG // initialDesk();//TODO: remove // #endif return desk.getRandomDesk(enumDeskState.空闲); } /// /// 随机获取多订单播种复合台 /// /// private WmsOutDesk getRandomFreeSeedsDesk() { return desk.getRandomDesk(enumDeskState.空闲,enumDeskType.播种); } /// /// seeds pick, by plate, 按灭捡货灯,更新数据 /// /// /// /// /// /// public bool updateSeedsPickingStatus(int color, int elabId, decimal pickCount, int elabAddress,int partion=-1) { if(partion>-1 && WmsConstants.SEEDS_PARTION_DESK_COLOR_MAP) { WmsWave ww = new WmsWave(); DataTable dt= ww.getSeedsPart(partion, color); foreach(DataRow dr in dt.Rows) { ww = new WmsWave(dr); color = ww.terminal; } } using (TransactionScope scope = new TransactionScope()) { WmsOutPickLable_tmp wpt = new WmsOutPickLable_tmp(color, elabId, elabAddress); ; if (!WmsConstants.OUT_STOCK_DEDUCT) { pickLabelDetail.updatePickingStatus(color, elabId, elabAddress, pickCount); } else { /* * seeds pick //update wmsOutPickPort WmsOutPickPort wop = new WmsOutPickPort(); wop.updatePickDetailByStkrecId(wpt.recordId, enumPickState.已拣, operId); //new stockRecord //to update current rec WmsStockRecord wsr = new WmsStockRecord(wpt.recordId); wsr.count = pickCount; wsr.countOuting = 0; wsr.operater = operId; // wsr.Add(); wsr.Update(); */ //update stock,update label tmp pickLabelDetail.updatePickingStatus(color, elabId, elabAddress, pickCount, true); //pickLabelDetail.finishCurrentPickingData(false); } //更新待复核数据状态 /* WmsOutPickDetail_tmp pd = new WmsOutPickDetail_tmp(wpt.orderDetailId); pd.bulkPicked += pickCount; if (pd.bulkPicked == pd.bulkCount) { pd.bulkPickState = (int)enumOutStockPickStatus.分拣完成; } pd.Update(); WmsOutPickDetail pd1 = new WmsOutPickDetail (wpt.orderDetailId); pd1.bulkPicked += pickCount; if (pd1.bulkPicked == pd.bulkCount) { pd1.bulkPickState = (int)enumOutStockPickStatus.分拣完成; } pd1.Update(); * */ // pickLabelDetail.updateValidPickingStatus(color, elabId, elabAddress); scope.Complete(); } // UpdateUIDelegate(); //update ui //updateStockByElePick( color, elabId, pickCount, elabAddress); return true; } /// /// 按灭拣货灯,更新数据 /// /// /// /// /// /// public bool updatePickingStatus(int color, int elabId, decimal pickCount, int elabAddress) { using (TransactionScope scope = new TransactionScope()) { // WmsOutPickLable_tmp wpt = new WmsOutPickLable_tmp(color, elabId, elabAddress,(int) pickCount); ; WmsOutPickLable_tmp wpt = new WmsOutPickLable_tmp(color, elabId, elabAddress); ; if (!WmsConstants.OUT_STOCK_DEDUCT) { pickLabelDetail.updatePickingStatus(color, elabId, elabAddress, pickCount); } else { //update wmsOutPickPort WmsOutPickPort wop = new WmsOutPickPort(); wop.updatePickDetailByStkrecId(wpt.recordId, enumPickState.已拣, operId); //new stockRecord //to update current rec WmsStockRecord wsr = new WmsStockRecord(wpt.recordId); wsr.count = pickCount; wsr.countOuting = 0; wsr.operater = operId; // wsr.Add(); wsr.Update(); pickLabelDetail.updatePickingStatus(color, elabId, elabAddress, pickCount, true); } //更新待复核数据状态 WmsOutPickDetail_tmp pd = new WmsOutPickDetail_tmp(wpt.orderDetailId); pd.bulkPicked += pickCount; if (pd.bulkPicked == pd.bulkCount) { pd.bulkPickState = (int)enumOutStockPickStatus.分拣完成; } pd.Update(); WmsOutPickDetail pd1 = new WmsOutPickDetail(wpt.orderDetailId); pd1.bulkPicked += pickCount; if (pd1.bulkPicked == pd1.bulkCount) { pd1.bulkPickState = (int)enumOutStockPickStatus.分拣完成; } pd1.Update(); // pickLabelDetail.updateValidPickingStatus(color, elabId, elabAddress); //to update erp detail // wpt.pickOrderNo // pd1.updateErpSaleDetail_deng(false); scope.Complete(); } return true; } /// /// 扫任务码亮灯,按键事件 /// /// /// /// /// /// public bool updatePortPickingStatus(int color, int elabId, decimal pickCount, int elabAddress,int userId=0) { WmsOutPickLable_tmp wpt = new WmsOutPickLable_tmp(color, elabId, elabAddress); logSpec.Debug(wpt.ToString()); logSpec.Debug(string.Format("light is off, color {0}, elabId {1},elabAddress {2}",color,elabId,elabAddress)); WmsFlow wmsflow = new WmsFlow( wpt.dpsOrder); operId = userId > 0 ? userId : operId; using (TransactionScope scope = new TransactionScope()) { wmsflow.finishedTasksPlus(operId, pickCount); int i= pickLabelDetail.updatePickingStatus(color, elabId, elabAddress, pickCount); //update tmep label data enumPickResult re= finishPickItem(wpt.dpsOrder, "", wpt.pickOrderNo, wpt.portId, wpt.count*wpt.minOperateCount); log.Debug(string.Format("update pick status cnt {0}, finish pick item result {1}",i,re.ToString())); scope.Complete(); } return true; } /* public void updateStockByElePick(int color, int elabId, decimal pickCount, int elabAddress) { if (!WmsConstants.OUT_STOCK_PDA_SCAN) { return; } } */ public delegate void UpdateUI();//声明一个更新主线程的委托 public UpdateUI UpdateUIDelegate; public delegate void AccomplishTask();//声明一个在完成任务时通知主线程的委托 public AccomplishTask TaskCallBack; private int p; /// /// 结束当前波次 /// pick.cs 在不同线程访问该方法。 /// /// /// public bool finishCurrentWave(string waveNo,bool isForce) { { //string waveOrder = pickLabelDetail.finishCurrentPickingData();//结束当前拣选的数据 // if (!string.IsNullOrEmpty(waveOrder)) // { try { // if (isForce) // { //TODO: to turn off the lights // } LogHelper.debug("lwmsoutpickrequest", String.Format(" WmsConstants.WAVE_CURRENT_ORDER {0}, WmsConstants.WAVE_LAST_ORDER {1}, waveNo {2}", WmsConstants.WAVE_CURRENT_ORDER, WmsConstants.WAVE_LAST_ORDER, waveNo)); WmsConstants.WAVE_CURRENT_ORDER = waveNo.Equals(WmsConstants.WAVE_LAST_ORDER) ? WmsConstants.WAVE_CURRENT_ORDER:waveNo ; using (TransactionScope scope = new TransactionScope()) { outRequest.completeWaveBulkPickStatus(WmsConstants.WAVE_CURRENT_ORDER,operId); pickLabelDetail.finishCurrentPickingData(isForce);//结束当前拣选的数据 LogHelper.debug("lwmsoutpickrequest","end finish current picking data " +waveNo); WmsConstants.WAVE_CURRENT_ORDER = ""; if (!WmsConstants.WAVE_CURRENT_ORDER.Equals(WmsConstants.WAVE_LAST_ORDER)) { WmsConstants.WAVE_LAST_ORDER = WmsConstants.WAVE_CURRENT_ORDER; TimeSpan ts = DateTime.Now - WmsConstants.WAVE_LAST_TIME; WmsConstants.WAVE_TOTAL_SECONDS += ts.Seconds; WmsConstants.WAVE_CNT++; //WmsConstants.WAVE_CURRENT_ORDER = ""; WmsConstants.WAVE_SECONDS = WmsConstants.WAVE_TOTAL_SECONDS / WmsConstants.WAVE_CNT; } //if (!string.IsNullOrEmpty(WmsConstants.WAVE_CURRENT_ORDER)) { } scope.Complete(); } // _canNewWave = true; // TaskCallBack(); //send info to the main ui to start new wave.,for its in another thread, will neve success. } catch (Exception er ) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), er); Thread.CurrentThread.Join(10); // finishCurrentWave(isForce); throw er; } } // } return true; } /// /// 清理已捡完数据 /// 当前分区若全部已拣完,则选取新数据开始新拣选 /// /// /// /// public bool finishPartWave(int part, bool isForce) { try { using (TransactionScope scope = new TransactionScope()) { //TODO: 分区分拣结束,判断分区的订单不存在未拣的部分,则更新pickdetail 和pickrequest bulkPikckStatus //1. 更新每个[orderDetailId] detail picked Count and bulk pick status ---已经在每个灯灭时做 ,见 lWmsOutPickRequest.updatePickingStatus //3. 更新每个[pickOrderNo] pick status DataTable dt = pickLabelDetail.getPartPickList(part).Tables[0]; if (dt.Rows.Count >0 ) //本区未拣完 { foreach (DataRow dr in dt.Rows) { if (new WmsOutPickLable(dr).state == 0) { if( !isForce) return false; } } } //本区已拣完,查看订单明细可能在其他区或未开始拣选的情况 DataTable dt1= pickLabelDetail.getPartUnPickList(part) ; if (dt1.Rows.Count == 0) //本区订单不存在未捡完的情况 { //更新pickorder,pickorder detail validation bulkstate,清理亮灯数据 string lastRequest = ""; foreach (DataRow dr in dt.Rows) { if (String.IsNullOrEmpty(lastRequest)|| lastRequest != new WmsOutPickLable(dr).pickOrderNo) { lastRequest = new WmsOutPickLable(dr).pickOrderNo; lastRequest = new WmsOutPickLable(dr).pickOrderNo; WmsOutPickRequest pr = new WmsOutPickRequest(lastRequest); pr.bulkPickState =(int) enumOutStockPickStatus.分拣完成; if (pr.batchPickState == -1 || pr.batchPickState >= (int)enumOutStockPickStatus.分拣完成) { pr.state = (int)enumOutStockRequestStatus.分拣完成; //TODO: outrequest order status // WmsOutRequest or = new WmsOutRequest(); } pr.operater = operId; pr.Update(); } } } pickLabelDetail.finishPartPickingData(part,isForce);//结束当前拣选的数据 scope.Complete(); } // _canNewWave = true; // TaskCallBack(); //send info to the main ui to start new wave.,for its in another thread, will neve success. } catch (Exception er) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), er); Thread.CurrentThread.Join(10); // finishCurrentWave(isForce); // throw er; } return true; } public DataSet getPickRequest4BulkValidate(object desk) { DataSet ds = outRequest.getPickRequest4BulkVailidate(desk); //test for barcode // #if DEBUG DataTable tmp; Int64 i = 6900000000000; for (int j = 0; j < 2; j++) { tmp = ds.Tables[j]; foreach (DataRow dr in tmp.Rows) { i++; if (string.IsNullOrEmpty(dr["barCode"].ToString())) { dr["barCode"] = dr["goodsId"].ToString(); } } } // #endif DataView dv = ds.Tables[0].DefaultView; dv.Sort = "dpsOrder ASC"; //fifo // DataTable dt = dv.ToTable(true, "pickOrderNo","orderState","customerName"); // TODO: check why custid to multi custname, custid: C1ZTLQIA97N DataTable dt = dv.ToTable(true,"orderBulkPickstate","dpsOrder", "pickOrderNo", "orderState", "customerName", "custAddress", "desk", "seedsLabelId","xuhao"); // 打印封箱 dt.TableName = "tablePickOrderList"; int kk=0; foreach (DataRow dr in dt.Rows) { kk++; dr["xuhao"] = kk + ""; } ds.Tables.Add(dt); // dv.RowFilter = string.Format("orderState <'{0}'",(int)enumOutStockPickStatus.复核完成); //DataTable dt2 = dv.ToTable(true, "dpsOrder", "seedsPickNo", "desk", "orderState"); // distinct pickOrderNo DataTable dt2 = dv.ToTable(true, "dpsOrder", "seedsPickNo", "desk"); // distinct seedsPickNo dt2.TableName = "tableSeedsPickOrders"; ds.Tables.Add(dt2); //DataView dv2 = outRequest.getValidationExceptionSolutions(desk).Tables[0].DefaultView; //dv2.RowFilter = "state =" + (int)enumOutStockDetailStatus.validatedExceptionSulution ; //DataTable dtExceptionSolution = dv.ToTable(); //dtExceptionSolution.TableName = "exsolutions"; //ds.Tables.Add(dtExceptionSolution); //DataTable dtExceptionSolution = outRequest.getValidationExceptionSolutions(desk).Tables[0].Clone(); //dtExceptionSolution.TableName = "exsolutions"; //ds.Tables.Add(dtExceptionSolution); return ds; } public DataSet getPickRequest4SeedsOperation(int desk, enumOutStockRequestStatus seedsStatus, string seedsNo = "") { DataSet ds = outRequest.getPickRequest4BulkSeedsVailidate(desk,seedsStatus,seedsNo); //test for barcode #if DEBUG DataTable tmp; for (int j = 0; j < 2; j++) { tmp = ds.Tables[j]; foreach (DataRow dr in tmp.Rows) { if (string.IsNullOrEmpty(dr["barCode"].ToString())) { dr["barCode"] = dr["goodsId"].ToString(); } } } #endif DataView dv = ds.Tables[0].DefaultView; dv.Sort = "seedsPickNo ASC"; //fifo // DataTable dt = dv.ToTable(true, "pickOrderNo","orderState","customerName"); // TODO: check why custid to multi custname, custid: C1ZTLQIA97N DataTable dt = dv.ToTable(true, "orderBulkPickstate", "dpsOrder", "pickOrderNo", "orderState", "customerName", "custAddress", "desk", "seedsLabelId", "xuhao"); // 打印封箱 dt.TableName = "tablePickOrderList"; ds.Tables.Add(dt); dv = ds.Tables[1].DefaultView; DataTable dt2 = dv.ToTable(true, "dpsOrder", "seedsPickNo", "desk","seedsstatus"); // distinct seedsPickNo dt2.TableName = "tableSeedsPickOrders"; ds.Tables.Add(dt2); //DataView dv2 = outRequest.getValidationExceptionSolutions(desk).Tables[0].DefaultView; //dv2.RowFilter = "state =" + (int)enumOutStockDetailStatus.validatedExceptionSulution ; //DataTable dtExceptionSolution = dv.ToTable(); //dtExceptionSolution.TableName = "exsolutions"; //ds.Tables.Add(dtExceptionSolution); //DataTable dtExceptionSolution = outRequest.getValidationExceptionSolutions(desk).Tables[0].Clone(); //dtExceptionSolution.TableName = "exsolutions"; //ds.Tables.Add(dtExceptionSolution); return ds; } public DataTable getSeedsGoods(string seedsNo) { return outRequest.getSeedsGoods(seedsNo); } /// /// 零货分拣复核完成 /// /// /// public bool completeBulkValidation(string pickOrderNo, int bulkBox, int bulkBag, DataTable validationDetails = null) { try { using (TransactionScope scope = new TransactionScope()) { if (!string.IsNullOrEmpty(pickOrderNo)) { if (validationDetails == null) { validationDetails = outRequest.getValidationDetail(pickOrderNo); } bool isException = false; DataView dv = validationDetails.DefaultView; dv.RowFilter = "bulkPickState =" + (int)enumOutStockPickStatus.复核异常; isException = dv.Count > 0; WmsOutPickRequest po = new WmsOutPickRequest(pickOrderNo); po.bulkBox = bulkBox; po.bulkBag = bulkBag; lTmsStock lts = new lTmsStock(operId); lts.newBulkTransStore(pickOrderNo, po.customerId, bulkBox, bulkBag);// 拼箱拼袋进集货区 /* try { lTmsStock lts = new lTmsStock(operId); lts.newBulkTransStore(pickOrderNo, po.customerId, bulkBox, bulkBag);// 拼箱拼袋进集货区 } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); } */ po.bulkPickState = isException ? (int)enumOutStockPickStatus.复核异常 : (int)enumOutStockPickStatus.复核完成; po.operater = this.operId; if (po.bulkPickState == (int)enumOutStockPickStatus.复核完成) //both bulk and batch completed validation { if (po.batchPickState == (int)enumOutStockPickStatus.无需分拣 || po.batchPickState == (int)enumOutStockPickStatus.复核完成) { po.state = (int)enumOutStockRequestStatus.集货完成; updateErpSaleStatus(po.pickOrderNo, enumOutStockRequestStatus.集货完成); /* Erp_sale es = new Erp_sale(); if (!WmsConstants.OUT_REQUEST_MERGE) { es.getByPickOrder(po.pickOrderNo); Employee em = new Employee(operId); es.fuheren = em.em_name; es.fuhesj = es.getDateTime(); es.fuhezt = true; es.Update(); } else { es.updatePickStatus(po.pickOrderNo, enumOutStockRequestStatus.集货完成); } */ } } po.Update(); foreach (DataRow dr in validationDetails.Rows) { WmsOutPickDetail pd = new WmsOutPickDetail(dr); WmsOutPickDetail_tmp pdt = new WmsOutPickDetail_tmp(dr); // isException = isException || pdt.bulkPickState == (int)enumOutStockPickStatus.复核异常; pd.operater = this.operId; pdt.operater = this.operId; //check batch pick status if ( (int)pd.batchPickState ==(int)enumOutStockPickStatus.无需分拣 || (int)pd.batchPickState > (int)enumOutStockPickStatus.分拣完成 ) //batch pick completed { if (pdt.bulkPickState != (int)enumOutStockPickStatus.复核异常) { pd.state = (int)enumOutStockDetailStatus.集货完成; logOut.Debug(" Y O U A R E H E R E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111"); } } pdt.state = pd.state; pdt.orderState = po.bulkPickState; pd.UpdateNoCompare(); //所有字段,除ID外,覆盖原值 pdt.Update(); } outRequest.deleteTempValidationData(pickOrderNo); } scope.Complete(); return true; } // TaskCallBack(); //send info to the main ui to start new wave.,for its in another thread, will neve success. } catch (Exception er) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), er); Thread.CurrentThread.Join(200); // completeBulkValidation(pickOrderNo, bulkBox, bulkBag, validationDetails); throw er; return false; } } /// /// 零货分拣复核完成 /// /// /// public bool completeSeedsPack(string pickOrderNo, int bulkBox=0,int bulkBag=0, DataTable validationDetails = null) { try { WmsOutPickRequest po = new WmsOutPickRequest(pickOrderNo); if (po.bulkPickState == (int)enumOutStockPickStatus.打包完成) { return false; } using (TransactionScope scope = new TransactionScope()) { if (!string.IsNullOrEmpty(pickOrderNo)) { if (validationDetails == null) { validationDetails = outRequest.getValidationDetail(pickOrderNo); } bool isException = false; DataView dv = validationDetails.DefaultView; dv.RowFilter = "bulkPickState =" + (int)enumOutStockPickStatus.复核异常; isException = dv.Count > 0; po.bulkBox = bulkBox; po.bulkBag = bulkBag; if (bulkBox + bulkBag == 0) //播种复核台前置打印,数量为一个包装 { po.bulkBag = 1; } lTmsStock lts = new lTmsStock(operId); lts.newBulkTransStore(pickOrderNo, po.customerId, bulkBox, bulkBag);// 拼箱拼袋进集货区 /* try { lTmsStock lts = new lTmsStock(operId); lts.newBulkTransStore(pickOrderNo, po.customerId, bulkBox, bulkBag);// 拼箱拼袋进集货区 } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); } */ po.bulkPickState = isException ? (int)enumOutStockPickStatus.复核异常 : (int)enumOutStockPickStatus.打包完成; po.operater = this.operId; if (po.bulkPickState == (int)enumOutStockPickStatus.打包完成) //both bulk and batch completed validation { if (po.batchPickState == (int)enumOutStockPickStatus.无需分拣 || po.batchPickState == (int)enumOutStockPickStatus.复核完成) { po.state = (int)enumOutStockRequestStatus.集货完成; Erp_sale es = new Erp_sale(); es.updatePickStatus(po.pickOrderNo, enumOutStockRequestStatus.集货完成); } } po.Update(); foreach (DataRow dr in validationDetails.Rows) { WmsOutPickDetail pd = new WmsOutPickDetail(dr); WmsOutPickDetail_tmp pdt = new WmsOutPickDetail_tmp(dr); // isException = isException || pdt.bulkPickState == (int)enumOutStockPickStatus.复核异常; pd.operater = this.operId; pdt.operater = this.operId; //check batch pick status if ((int)pd.batchPickState == (int)enumOutStockPickStatus.无需分拣 || (int)pd.batchPickState > (int)enumOutStockPickStatus.分拣完成) //batch pick completed { if (pdt.bulkPickState != (int)enumOutStockPickStatus.复核异常) { pd.state = (int)enumOutStockDetailStatus.集货完成; logOut.Debug(" Y O U A R E H E R E!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!111"); } } pdt.state = pd.state; pdt.orderState = po.bulkPickState; pd.UpdateNoCompare(); //所有字段,除ID外,覆盖原值 pdt.Update(); } outRequest.deleteTempValidationData(pickOrderNo); } scope.Complete(); return true; } // TaskCallBack(); //send info to the main ui to start new wave.,for its in another thread, will neve success. } catch (Exception er) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), er); Thread.CurrentThread.Join(200); // completeBulkValidation(pickOrderNo, bulkBox, bulkBag, validationDetails); throw er; return false; } } /// /// batch pick orders waiting for out /// /// public DataSet getBatchOutPickOrders4Pick() { DataSet ds = outRequest.getBatchOutPickOrders(enumOutStockRequestStatus.正在分拣, enumOutStockPickStatus.待处理, enumOutStockPickStatus.正在分拣); //DataTable dt = outRequest.getRepRequestDetailsLessThan(enumOutStockPickStatus.复核完成); // DataTable repTable = outRequest.getRequests(enumOutOrderType.repOrderOut, enumOutStockRequestStatus.等待分拣).Tables[0]; DataView dv = ds.Tables[0].DefaultView; dv.RowFilter = "orderType =" + (int) enumOrderType.补货出库; DataTable dt = dv.ToTable(); dt.TableName = "repOrder"; ds.Tables.Add(dt); return ds; } /// /// pick order detail /// /// /// public DataSet getBatchOutPickOrderDetails(string pickOrderNo) { return outRequest.getBatchOutPickOrderDetails(pickOrderNo, enumOutStockDetailStatus.等待分拣, enumOutStockPickStatus.待处理); } /// /// get port pick detail by id /// /// /// public DataTable getPortOutPickOrderDetail(int id,bool isAssignToMe =false) { if (isAssignToMe && havePermission( WmsConstants.SPECIAL_VALID_REASSIN_TASK_BY_ID)) { WmsOutPickPort wop = new WmsOutPickPort(id); 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(); } } } return outPickPort.getPickDetail(id); } /// batch pick order pick detail /// /// /// public DataSet getBatchOutPickOrderPickDetails(string pickOrderNo) { // return outRequest.getBatchOutPickOrderPickDetails(pickOrderNo,enumOutStockRequestStatus.正在分拣, enumOutStockPickStatus.待处理); return outRequest.getBatchOutPickOrderPickDetails(pickOrderNo); } /// /// batch pick order pick detail /// /// /// public DataTable getPickOrderTmsInfo(string pickOrderNo) { // return outRequest.getBatchOutPickOrderPickDetails(pickOrderNo,enumOutStockRequestStatus.正在分拣, enumOutStockPickStatus.待处理); return outRequest.getPickOrderTmsInfo(pickOrderNo); } /// ///整库开始拣货 /// /// public bool startPickBatchPickOrder(string pickOrderNo) { bool success = false; try { WmsOutPickRequest po = new WmsOutPickRequest(pickOrderNo); TmsLineDetail tld = new TmsLineDetail().getLineDetailByCustId(po.customerId); List locs =new TmsStock().getFreeLocation(tld.ID, Utils.enumWhLocVol.分拣集货, Utils.enumWhType.集货库 ); using (TransactionScope scope = new TransactionScope()) { foreach (WmsLocation loc in locs) { po.tranLocationId = loc.locationId; po.operater = operId; po.Update(); //添加集货货位,整货出库目的地 break; } success= outRequest.updateBatchPickStatus(pickOrderNo, enumOutStockPickStatus.正在分拣,operId) > 0; scope.Complete(); return true; } } catch (Exception e) { LogHelper.WriteLog(this.GetType(), e); return false; } } public bool updateOrderStatus(string pickOrderNo, enumOutStockPickStatus pickStatus) { WmsOutPickRequest pickRequest = new WmsOutPickRequest(pickOrderNo); using (TransactionScope scope = new TransactionScope()) { //更新订单明细状态 enumOutStockDetailStatus detailState = pickStatus == enumOutStockPickStatus.分拣完成 ? enumOutStockDetailStatus.完成分拣 : enumOutStockDetailStatus.复核完成; //更新订单状态 enumOutStockRequestStatus orderState = pickStatus == enumOutStockPickStatus.分拣完成 ? enumOutStockRequestStatus.分拣完成 : enumOutStockRequestStatus.复核完成; pickRequest.updateOrderStatus (pickOrderNo, orderState, detailState, operId); Erp_sale es = new Erp_sale(); es.updatePickStatus(pickRequest.pickOrderNo, orderState); scope.Complete(); } return true; } /// /// 整库出库\复核完成 /// /// /// public bool updateBatchPickStatus(string pickOrderNo, enumOutStockPickStatus pickStatus) { WmsOutPickRequest pickRequest = new WmsOutPickRequest(pickOrderNo); try { using (TransactionScope scope = new TransactionScope()) { //更新batchPickstatus pickRequest.updateBatchPickStatus(pickOrderNo, pickStatus,operId); if (pickRequest.bulkPickState == (int)enumOutStockPickStatus.无需分拣 || pickRequest.bulkPickState >= (int)pickStatus) //no bulk or bulk finished { //更新订单明细状态 enumOutStockDetailStatus detailState = pickStatus == enumOutStockPickStatus.分拣完成 ? enumOutStockDetailStatus.完成分拣 : enumOutStockDetailStatus.复核完成; //更新订单状态 enumOutStockRequestStatus orderState = pickStatus == enumOutStockPickStatus.分拣完成 ? enumOutStockRequestStatus.分拣完成 : enumOutStockRequestStatus.复核完成; pickRequest.updateBatchOrderStatus(pickOrderNo,orderState, detailState, operId); Erp_sale es = new Erp_sale(); es.updatePickStatus(pickRequest.pickOrderNo, orderState); } scope.Complete(); } }catch(Exception e){ LogHelper.WriteLog(this.GetType(), e); return false; } return true; } /// /// finish one pick detail /// /// public enumPickResult finishPickItem(string flowNo,string waveOrder, string pickOrderNo , int id, decimal pickCount) { return updatePortPickStateStk(id, flowNo, enumPickState.已拣, pickCount); #region /* _outPickPort = new WmsOutPickPort(id); string jobNo = _outPickPort.jobNo; if (WmsConstants.OUT_STOCK_BULK_PDA_SCAN) { return updatePortPickStateStk(id, flowNo, enumPickState.已拣, pickCount); } using (TransactionScope scope = new TransactionScope()) { // wf.Update(); int volType = updatePortPickStateStk(id, flowNo,enumPickState.已拣,pickCount); if (outPickPort.getPickDetailsCnt(pickOrderNo, enumPickState.未拣, volType > 0) == 0) { if (volType > 0) //订单整货手持分拣完成 { if (!(updateBatchPickStatus(pickOrderNo, enumOutStockPickStatus.分拣完成))) { if (!(updateBatchPickStatus(pickOrderNo, enumOutStockPickStatus.分拣完成))) { outPickPort.updatePickState(id, enumPickState.未拣, operId); //twice failure then roll back status return false; }; }; } else //订单零货手持捡货完成 { if (!(outRequest.completeBulkPickStatus(pickOrderNo, operId))) { if (!(outRequest.completeBulkPickStatus(pickOrderNo, operId))) { outPickPort.updatePickState(id, enumPickState.未拣, operId); //twice failure then roll back status return false; }; }; //当前wave的零货全部拣选完毕,则结束当前wave if (!String.IsNullOrEmpty(waveOrder) && outPickPort.getPickDetailsCnt(null, enumPickState.未拣, false, waveOrder) == 0) { finishCurrentWave(waveOrder,true); } } } scope.Complete(); } return true; */ #endregion } /// /// finish check one pick detail by location /// /// /// /// public bool finishBatchValidateItem(string pickOrderNo, int id,int checkBy2=0) { using (TransactionScope scope = new TransactionScope()) { outPickPort.updatePickState(id, enumPickState.复核完成,operId); _outPickPort = new WmsOutPickPort(id); _outPickPort.checkBy2 = checkBy2; _outPickPort.checkBy = operId; _outPickPort.checkTime = outPickPort.getDateTime(); _outPickPort.checkByTime2 = outPickPort.getDateTime(); _outPickPort.Update(); //updatePickState(id, enumPickState.复核完成); if (outPickPort.getPickDetailsCnt(pickOrderNo, enumPickState.未拣) + outPickPort.getPickDetailsCnt(pickOrderNo, enumPickState.已拣) == 0) { if (!(updateBatchPickStatus(pickOrderNo, enumOutStockPickStatus.复核完成))) { if (!(updateBatchPickStatus(pickOrderNo, enumOutStockPickStatus.复核完成))) { outPickPort.updatePickState(id, enumPickState.已拣, operId); return false; }; }; } scope.Complete(); } return true; } enumPickResult updatePortPickStateStk(int id, string flowNo, enumPickState state, decimal pickCount = 0) { logOut.Debug(string.Format("{0},flowNO:{1},{2},{3}", id, flowNo, state, pickCount)); WmsPlateStock_tmp ptmp = new WmsPlateStock_tmp(); string custId = ptmp.getRelatedCustId(flowNo); _outPickPort = new WmsOutPickPort(id); // logOut.Debug("outpickport: " + _outPickPort); if (string.IsNullOrEmpty(_outPickPort.jobNo)) { return enumPickResult.任务不存在; } _outRequest = new WmsOutPickRequest(outPickPort.pickOrderNo); if (!string.IsNullOrEmpty(custId) && custId != _outRequest.customerId) { return enumPickResult.容器已被其他客户占用; } if (outPickPort.state == (int)enumPickState.已拣) { return enumPickResult.任务已经分拣完成; } WmsStockRecord sr = new WmsStockRecord(outPickPort.recordId); WmsGoods goods = new WmsGoods(sr.goodsId); if (pickCount > 0) { outPickPort.pickCount += pickCount; //pickCount 仅用于校验补货入库用,不用于记录实际拣货数量 decimal overRate = Math.Abs((pickCount - outPickPort.count)) * 100 / outPickPort.count; // logSpec.Debug(string.Format("goodsid {3}, is weightout? {4}, over rate {5} , pick count {0}, count of task {1}, operId {2}, need special permission {6}" // , pickCount, outPickPort.count, operId, goods.goodsId, goods.isWeightOut(), overRate // , overRate > WmsConstants.OVER_WEIGHT_PERCENT_ALLOW)); if (pickCount != outPickPort.count) { logSpec.Debug(" count not match "); if (!goods.isWeightOut() && overRate > WmsConstants.OVER_WEIGHT_PERCENT_ALLOW) { logSpec.Debug("needs special authority...."); logSpec.Debug(string.Format("goodsNme {0}, goods.minoperatunit {1} ,goods.isWeightOut() {2}", goods.goodsName, goods.minOperateUnit, goods.isWeightOut())); if (!havePermission(WmsConstants.SPECIAL_AUTHS_PICK_COUNT_MODIFY)) { logSpec.Debug(" have no special authority....,return false"); return enumPickResult.修改下架数量需要授权; } } } } outPickPort.operater = this.operId; outPickPort.state = (int)state; outPickPort.flowNo = flowNo; outPickPort.pickBy = operId; outPickPort.takeBy = operId; outPickPort.pickTime = outPickPort.getDateTime(); WmsFlow flow = new WmsFlow(outPickPort.jobNo); if (WmsConstants.OUT_STOCK_DEDUCT) { //更新库存 WmsStock stk = new WmsStock(outPickPort.locationId,sr.skuId, sr.goodsId); if (stk.ID == 0) { stk = new WmsStock(outPickPort.locationId, 0, sr.goodsId,sr.batch); } if (stk.ID == 0) { log.Error(string.Format("库存异常, goodsId {0}, skuId {1},batch {2},location {3}, stk id {4}, stockrecord id {5}",sr.goodsId,sr.skuId,sr.batch,sr.location,stk.ID,sr.ID )); return enumPickResult.库存不存在; } if (pickCount == 0) //允许打零 { using (TransactionScope scope = new TransactionScope()) { outPickPort.Update(); stk.countOuting -= outPickPort.count; flow.finishedTasksPlus(operId, pickCount / goods.bigCount); stk.updateCountOut(); scope.Complete(); return enumPickResult.成功; //TODO: 当订单所有明细都打零时,如何装车出库? } } WmsPlate toP = new WmsPlate(flowNo); WmsStock stkVir = new WmsStock(new WmsLocation().getVirLocations(goods.part).locationId,new WmsOutPickDetail(outPickPort.pickDetailId).skuId, sr.goodsId); //.Debug("拣货更新库存前: " + stk); enumStockRecordType type = (enumStockRecordType)outPickPort.recType; string description = string.Format("\n 业务类型:{0}, 下架数量{1}, 备注:{2}", type.ToString(), pickCount, ""); // stk.countOuting -= pickCount; _outPickPort.count stk.countOuting -= _outPickPort.count > pickCount ? _outPickPort.count : pickCount; // 计划分拣数量可能不同于实际数量,只分拣一次 stk.countOuting = stk.countOuting > 0 ? stk.countOuting : 0; //????can countouting <0? stk.countOut += pickCount; stk.plateCount += pickCount; //TODO: 处理虚拟库存 if ( WmsConstants.OUT_STOCK_LACK_VIR_OUT_AUTO && stk.virtialCount > 0 && outPickPort.virtialCnt>0 ) { // logOut.Debug(string.Format("扣虚拟库存, 原库存 {0}, 虚拟库存 {1} ", stk.ToString(), stkVir.ToString())); stk.virtialCount -= outPickPort.virtialCnt; stk.virtialCount = stk.virtialCount<0?0: stk.virtialCount; stk.count += outPickPort.virtialCnt; stkVir.countOuting -= outPickPort.virtialCnt; stkVir.countOut += outPickPort.virtialCnt; } sr.count = pickCount; sr.countOuting = sr.countOuting - pickCount; sr.description = description; sr.operater = operId; sr.goodsId = sr.goodsId; /* * 库存转移到流水临时库 * */ WmsPlateStock_tmp plateStock = new WmsPlateStock_tmp(); plateStock.plateId = flowNo; plateStock.goodsId = stk.goodsId; plateStock.productDate = stk.productDate; plateStock.validDate = stk.validDate; plateStock.batch = stk.batch; plateStock.count = pickCount; plateStock.locationid = stk.locationId; plateStock.outPortId = id; plateStock.skuCode = stk.skuCode; plateStock.skuId = stk.skuId; plateStock.orderNo = _outPickPort.pickOrderNo; plateStock.jobNo = _outPickPort.jobNo; plateStock.recType = _outPickPort.recType; plateStock.recordId = _outPickPort.recordId; plateStock.customerId=_outRequest.customerId; if(string.IsNullOrEmpty(plateStock.goodsId)) { logOut.Error("new plateStock value " + plateStock); } WmsOutPickDetail wod = null; WmsOrderDetail wodd=null; WmsOrderRequest wor = null; WmsOutPickRequest wopr = new WmsOutPickRequest(outPickPort.pickOrderNo); WmsFlow wmsflow=null ; // WmsLocation loc = new WmsLocation(outPickPort.locationId); if (_outRequest.ID==0 ) { wor = new WmsOrderRequest(outPickPort.pickOrderNo); wodd = new WmsOrderDetail(outPickPort.pickDetailId); } else { wod = new WmsOutPickDetail(outPickPort.pickDetailId); } if (outPickPort.recType == (int)enumStockRecordType.集货拣货) { plateStock.state =(int) enumPlateStatus.取总待分播; // add tasks for 分播 /// 按照货品 + 容器号 分任务 EnumFlowTaskType taskType= Util.getTaskType((int)enumStockRecordType.集货分播); wmsflow = new WmsFlow(outPickPort.pickOrderNo, flowNo, enumFlowTaskStatus.未开始, taskType); if (wmsflow.ID == 0 ) { wmsflow.operater = operId; wmsflow.orderNo = outPickPort.pickOrderNo;// + sr.goodsId + sr.batch; wmsflow.flowNo = flowNo; wmsflow.type = (int)taskType; wmsflow.typeName = taskType.ToString(); wmsflow.task = Util.getOrderNo(enumCreateOrderType.pickJobNo, _obj.getNextSeq(enumCreateOrderType.pickJobNo)); ; // wmsflow.taskPartion = r.partion; // wmsflow.toPartion = r.partion; // wmsflow.toLocationId = r.locationId; wmsflow.taskCnt = 1; // wod.seedTaskNo = wmsflow.task; } else { wmsflow.taskCnt++; } } else //创建集货任务 { if (!WmsConstants.AUTO_LOAD_TRUCK) { string taskNo = outPickPort.pickOrderNo + flowNo; wmsflow = new WmsFlow(taskNo); if (wmsflow.ID == 0) { wmsflow.operater = operId; wmsflow.orderNo = outPickPort.pickOrderNo; wmsflow.flowNo = flowNo; wmsflow.type = (int)EnumFlowTaskType.客户集货; wmsflow.typeName = EnumFlowTaskType.客户集货.ToString(); wmsflow.task = taskNo; wmsflow.taskCnt = 1; } } if (toP.plateLevel != (int)enumPlateLevel.客户集货) { plateStock.state = (int)enumPlateStatus.出库待集货; } else { plateStock.state = (int)enumPlateStatus.已集货; if (!WmsConstants.IS_PLATE_IN_LINE && string.IsNullOrEmpty(toP.customerId)) { int lineId = 0; DataTable dt1 = ptmp.getOutPort(ptmp.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; } } } using (TransactionScope scope = new TransactionScope()) { if (outPickPort.recType != (int)enumStockRecordType.集货拣货) { wopr.createLoadTruckJob(operId); //创建装车任务 } if (wmsflow != null) { if (wmsflow.ID > 0) { wmsflow.Update(); } else if(!string.IsNullOrEmpty(wmsflow.task)) { wmsflow.Add(); } } toP.Update(); sr.Update(); stk.skuId = sr.skuId; //托盘,多sku情况 // logOut.Debug("拣货更新库存: " + stk); stk.updateCountOut(); stkVir.updateCountOut(); //stk.Update(); plateStock.skuId = stk.skuId; plateStock.Add(); // logOut.Debug(string.Format(" auto load truck? {0}, recType {1}, wopr.seedsPickNo {2}, wopr.pickorderNo {3}", WmsConstants.AUTO_LOAD_TRUCK, outPickPort.recType, wopr.seedsPickNo,wopr.pickOrderNo)); if (WmsConstants.AUTO_LOAD_TRUCK) { if (outPickPort.recType != (int)enumStockRecordType.集货拣货) { string truck = "000"; //+ stk.locationId.Substring(0,1); new lWmsPlate(operId).loadTruck(plateStock.plateId, string.IsNullOrEmpty( wopr.seedsPickNo) ? wopr.pickOrderNo: truck);//有总拣任务的分拣单集中装车 } } outPickPort.Update(); if (wodd != null) { /* if( loc.state != (int)enumStockLocationStatus.正常) { loc.state = (int)enumStockLocationStatus.正常; loc.Update(); } */ if (wor.toWhType > -1) { addOrderUpTasks(sr, flowNo, pickCount,(enumWhType)wor.toWhType); // 上架新增任务 } wodd.finishedCount +=pickCount; if (outPickPort.getCntByDetailId(outPickPort.pickDetailId, enumPickState.未拣) == 0) { wodd.state = (int)enumOutStockDetailStatus.完成分拣; // logTest.Debug(string.Format(" pickdetail {0},new state:{1} ", wod.ID, (enumOutStockDetailStatus)wod.state)); wodd.Update(); if (wodd.isAllPicked(wodd.orderNo)) { wor.state = (int)enumOrderStatus.已完成; wor.Update(); //to call erp noticeErpOrder(wor); } } else { wodd.Update(); } }else if (wod != null) { addRepUpTasks(sr, flowNo, pickCount,enumWhType.合格库); //补零上架新增任务 if (outPickPort.volType == 0) { wod.bulkPicked += outPickPort.pickCount; } else { wod.batchPicked += outPickPort.pickCount; } if (outPickPort.getCntByDetailId(outPickPort.pickDetailId, enumPickState.未拣) == 0) { wod.state = (int)enumOutStockDetailStatus.完成分拣; // logTest.Debug(string.Format(" pickdetail {0},new state:{1} ", wod.ID, (enumOutStockDetailStatus)wod.state)); wod.Update(); if (wod.isAllPicked(wod.pickOrderNo)) { updateOrderStatus(wod.pickOrderNo, enumOutStockPickStatus.分拣完成); } } else { wod.Update(); } } flow.finishedTasksPlus(operId, pickCount / goods.bigCount); scope.Complete(); } } else { outPickPort.Update(); } return enumPickResult.成功; } private void addRepUpTasks(WmsStockRecord rec,string flowNo,decimal count, enumWhType whType) { if (rec.rectype != (int)enumStockRecordType.补零出库) { return; } //to create inport data int skuId =rec.skuId; string goodsId =rec.goodsId; string batch = rec.batch; string skucode =rec.skuCode; string prdtime =rec.productDate; string vltime =rec.validDate; DataTable dtBulkLocs = new lWmsStock(operId).getBulkLocations(skuId, "", goodsId, batch, count); decimal cnt = 0; DataView dv = dtBulkLocs.DefaultView; dv.Sort = "数量 desc"; foreach (DataRowView dr1 in dv) { //todo: to add stock record WmsInUpPort wip = new WmsInUpPort(); wip.locationId = dr1[0].ToString(); wip.count = Convert.ToDecimal(dr1[1].ToString()); wip.orderNo = rec.orderNo; wip.skuId = skuId; wip.skuCode = skucode; wip.batch = batch; wip.goodsId = goodsId; wip.detailId = rec.orderDetailId; wip.recType = (int)enumStockRecordType.补零入库; wip.recordId = rec.ID; wip.productDate = prdtime; wip.validDate = vltime; wip.flowNo = flowNo; wip.state =(int) enumInStockDetailStatus.已分配货位; WmsLocation loc = new WmsLocation(wip.locationId); Node nd = new Node(loc.part); if (nd.ID > 0) { wip.partion = nd.flag; } logTest.Debug(string.Format(" rep count {0}, done cnt {1}, loc task count is {2}, rec id: {3} ", count, cnt, wip.count,rec.ID)); if ( wip.count == 0) { wip.count = count - cnt; } if (wip.count == 0) { logTest.Debug(string.Format("!!! catch zero......count....")); continue; } wip.Add(); logTest.Debug(string.Format( "2 create rep up tasks, rep count {0}, done cnt {1}, loc task count is {2} ", count, cnt, wip.count)); //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(); } else { newStk.countIn+= wip.count; newStk.Update(); } cnt += Convert.ToDecimal(dr1[1].ToString()); if (Convert.ToDecimal(dr1[1].ToString()) == 0) { break; } } } private void addOrderUpTasks(WmsStockRecord rec, string flowNo, decimal count, enumWhType whType) { //to create inport data int skuId = rec.skuId; string goodsId = rec.goodsId; string batch = rec.batch; string skucode = rec.skuCode; string prdtime = rec.productDate; string vltime = rec.validDate; WmsLocation nearLoc = new WmsLocation(); if (whType == enumWhType.不合格库) { nearLoc.volType = (int)enumWhLocVol.不合格区; logIn.Debug(string.Format("需 {0} 型新库位 {1}", enumWhLocVol.不合格区, 1)); } else if (whType == enumWhType.合格库) { if (rec.location!=null && rec.location.whType == (int)enumWhType.合格库) { nearLoc = rec.location; } } List locs = new List(); try { locs = nearLoc.getFreeLocation(nearLoc, whType, 1); } catch (Exception er) { } try { logIn.Debug(string.Format(" 找到 {0} 型新库位 {1}", whType, locs.Count)); if (locs.Count == 0) { nearLoc.locationId = "临时货位"; locs.Add(nearLoc); } foreach (WmsLocation loc in locs) { WmsInUpPort wip = new WmsInUpPort(); wip.locationId = loc.locationId; wip.count = count; wip.orderNo = rec.orderNo; wip.skuId = skuId; wip.skuCode = skucode; wip.batch = batch; wip.goodsId = goodsId; wip.detailId = rec.orderDetailId; wip.recType = rec.rectype; wip.recordId = rec.ID; wip.productDate = prdtime; wip.validDate = vltime; wip.flowNo = flowNo; wip.operater = operId; wip.state = (int)enumInStockDetailStatus.已分配货位; Node nd = new Node(loc.part); if (nd.ID > 0) { wip.partion = nd.flag; } wip.Add(); log.Debug("new inUpPort: " + wip); 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(); } else { newStk.countIn += wip.count; newStk.Update(); } return; } } catch (Exception er) //小整货位不足 { log.Error(er); } } public DataTable getBatchPickOrders4Validate() { DataTable dt = getWmsOutPickRequest.getBatchPickOrders4Validation(); return dt; } public int getPickCount4valid(string pickOrderNo) { return outPickPort.getPickDetailsCnt(pickOrderNo, enumPickState.已拣); } public DataTable repTodayDetails4Pick(int userId = 0) { DataTable dt = getWmsOutPickRequest.getBatchPickOrderRepDetail("", enumOrderType.补货出库, enumPickState.未拣); if (userId > 0) { DataView dv = dt.DefaultView; dv.RowFilter = "takeBy="+userId; return dv.ToTable("meOnly"); } /* dt.Columns.Remove("状态"); //dt.Columns.Remove("pickOrderNo"); dt.Columns.Remove("state"); dt.Columns.Remove("orderType"); dt.Columns.Remove("orderDate"); dt.Columns.Remove("pickCount"); dt.Columns.Remove("goodsid"); */ return dt; } public DataTable repTodayDetails4In(string flowNo="") { DataTable dt = getWmsOutPickRequest.getBatchPickOrderRepDetail(flowNo, enumOrderType.补货出库, enumPickState.已拣); /* dt.Columns.Remove("货位"); dt.Columns.Remove("状态"); dt.Columns.Remove("state"); dt.Columns.Remove("orderType"); dt.Columns.Remove("orderDate"); dt.Columns.Remove("pickCount"); */ return dt; } //-------------------------out logs----------------------begin--- private WmsOutLog _outLog; WmsOutLog outLog { get { if (_outLog == null) { _outLog = new WmsOutLog(); } return _outLog; } } public DataTable getOrderLogs(string orderNo, string pickOrderNo) { return outLog.getOrderLogs(orderNo,pickOrderNo); } public DataTable getOrderLogs(string orderNo, bool isSaleOrder) { if (isSaleOrder) { return outLog.getOrderLogs(orderNo, ""); } else { return outLog.getOrderLogs("",orderNo); } } internal bool updatePriority(string[] orders, int priority,int operId) { try { // using (TransactionScope scope = new TransactionScope()) { string whOrders = ""; foreach (string order in orders) { whOrders += "'"+ order + "',"; } whOrders = whOrders.Substring(0, whOrders.Length - 1); whOrders = "(" + whOrders + ")"; return _obj.updatePriority(whOrders, priority,operId); // scope.Complete(); } } catch (Exception e) { LogHelper.WriteLog(this.GetType(), e); return false; } // return true; } //------------------light labels public void lightLables() { elelab.pick.init_port(enumLabelPickType.pick); DataTable dt = new WmsOutPickLable().getPickedData(enumPickState.未拣).Tables[0]; elelab.pick.send_data_pick(dt, enumLabelPickType.pick); } //seeds public enumOutSeedsStatus updateSeedingStatus(string seedsPickNo, string goodsId, string batch, int labId, int address, decimal count, int checkedBy2) { LogHelper.debug(this.GetType(), "updateSeedingStatus... operId is " + operId); LogHelper.debug(this.GetType(), "begin to update seeding pick.....>"); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("seedsPickNo:{0},goodsId:{1},batch:{2},labId:{3},address:{4},count:{5},checkBy2:{6}" ,seedsPickNo, goodsId, batch, labId, address, count, checkedBy2)); enumOutSeedsStatus rt = enumOutSeedsStatus.状态更新成功; int cnt = outPickTmp.updateSeedingPickStatus(seedsPickNo, goodsId, batch, labId, address, count,operId,checkedBy2); if (cnt == 0) { LogHelper.debug(this.GetType(), " 更新失败,。。。。。。。return failure"); return enumOutSeedsStatus.处理失败; } int color = 0; using (TransactionScope scope = new TransactionScope()) { if (outRequest.getUnSeedsCnt(seedsPickNo, goodsId, batch) == 0) { //该商品播种完毕 outPickTmp.completeSeeding(seedsPickNo, goodsId, batch); rt = enumOutSeedsStatus.商品完成分播; } LogHelper.debug(this.GetType(), " " + rt); if (outRequest.getUnSeedsCnt(seedsPickNo, labId) == 0) // LabId对应的分拣单播种完毕 { DataTable dtSeeds = outRequest.getSeedsData(seedsPickNo, labId); DataView dv = dtSeeds.DefaultView; DataTable dtPickOrders = dv.ToTable(true, "pickOrderNo"); try { foreach (DataRow dr in dtPickOrders.Rows) { string pickOrderNo = dr[0].ToString(); WmsOutPickRequest pr = new WmsOutPickRequest(pickOrderNo); //分拣明细状态 更新为 零货复核完成(enumOutStockPickStatus.复核完成) 和 全部完成分拣(enumOutStockDetailStatus.完成分拣) foreach (WmsOutPickDetail pd in pr.outDetails) { if (pd.bulkCount > 0) { pd.bulkPickState = (int)enumOutStockPickStatus.复核完成; if (pd.batchPickState == (int)enumOutStockPickStatus.无需分拣 || pd.batchPickState > (int)enumOutStockPickStatus.分拣完成) { pd.state = (int)enumOutStockDetailStatus.复核完成; ; } pd.operater = this.operId; pd.Update(); } } pr.bulkPickState = (int)enumOutStockPickStatus.复核完成; if (pr.batchPickState == (int)enumOutStockPickStatus.无需分拣 || pr.batchPickState >= (int)enumOutStockPickStatus.分拣完成) { enumOutStockRequestStatus state = enumOutStockRequestStatus.分拣完成; if (pr.batchPickState == (int)enumOutStockPickStatus.无需分拣 || pr.batchPickState == (int)enumOutStockPickStatus.复核完成) { state = enumOutStockRequestStatus.复核完成; } pr.state = (int)state; updateErpSaleStatus( pr.pickOrderNo,state); } pr.operater = this.operId; pr.Update(); outPickPort.updateBulkPickStateByPickOrder(pr.pickOrderNo, operId, checkedBy2); //update pickport // outRequest.completeValidation(pr.pickOrderNo);//打包后,再从临时表删除 color = pr.desk; } rt = enumOutSeedsStatus.分拣单完成分播; LogHelper.debug(this.GetType(), " " + rt); } catch (Exception e) { LogHelper.WriteLog(this.GetType(), e); return enumOutSeedsStatus.处理失败; } // pk order is finished, to print code, can be packed. } if (outRequest.getUnSeedsCnt(seedsPickNo) == 0)//是否播种单订单全部分播完毕 { outPickTmp.completeSeeding(seedsPickNo); if (WmsConstants.OUT_BULK_DESK_CONTROLL) { setDeskFree(color); LogHelper.debug(typeof(lWmsOutRequest), color +"播种台播种完毕,设置状态为空闲,参与下个波次"); } WmsWave ww = new WmsWave(); ww.QueryBySeedsNo(seedsPickNo); ww.state = (int)enumOutStockRequestStatus.复核完成; ww.Update(); rt = enumOutSeedsStatus.播种单完成分播; LogHelper.debug(this.GetType(), " " + rt); LogHelper.debug(typeof(lWmsOutPickRequest), " 测试日志输出"); } scope.Complete(); } LogHelper.debug(typeof(lWmsOutPickRequest), " return value is " + rt.ToString()); LogHelper.debug(typeof(lWmsOutPickRequest), "end update seeding pick.....>"); return rt; //elabid pk order is not finished. } private void updateErpSaleStatus(string pickOrderNo, enumOutStockRequestStatus state) { Erp_sale es = new Erp_sale(); if (1==2 &&!WmsConstants.OUT_REQUEST_MERGE) { es.getByPickOrder( pickOrderNo); Employee em = new Employee(operId); es.fuheren = em.em_name; es.fuhesj = es.getDateTime(); es.fuhezt = true; es.Update(); es.updatePickStatus(pickOrderNo, enumOutStockRequestStatus.复核完成); } else { es.updatePickStatus( pickOrderNo, state); try { new WmsOutRequest().updatePickState(pickOrderNo, state); } catch (Exception er) { log.Error(er); } } } public void createBoxes(int color,int volume,int lengh=0,int width=0,int height=0,int number =1){ WmsPlate wob = new WmsPlate(); for (int i = 1; i <= number; i++) { wob.volume = volume; wob.color = color; wob.length = lengh; wob.width = width; wob.height = height; wob.Add(); } } /// /// 注册箱子 /// /// /// /// /// /// public bool regBox(string boxId,string waveNo,int color) { plate.deleteByPlateId(boxId); plate.plateId = boxId; plate.waveNo = waveNo; plate.color = color; return plate.Add() > 0; } /// /// 可注册箱子的波次号 /// /// public DataSet getBoxWaves() { return plate.getPlateWaves() ; } public DataTable getBoxsByWave(string waveOrder, int color =0) { return plate.getPlatesByWave(waveOrder, color); } public string getWaveNoByBoxId(string boxId) { DataTable dt = plate.getPlateById(boxId); if (dt.Rows.Count > 0) { return dt.Rows[0]["waveNo"].ToString(); } return ""; } internal DataTable getWaveDeskByBoxId(string boxId) { return plate.getPlateById(boxId); } internal DataTable getPartionPickDetailByBoxId(string boxId) { return plate.getPartionPickDetailByPlateId(boxId); } internal enumRegPlateResult regPartBox(int partion, string boxId) { int id = Util.getBoxId(boxId); DataTable dt = new WmsOutPickLable().getPartPickList(partion).Tables[0]; DataView dv = dt.DefaultView; if (WmsConstants.PART_ORDER_SIZE > 1) //多单拣选 { //周转箱颜色要和亮灯颜色一致 int color = Util.getBoxColor(boxId); dv.RowFilter = "color =" + color; if (dv.Count > 0) { String pickNo = dv[0]["pickOrderNo"].ToString(); WmsPlate wb = new WmsPlate(id); wb.pickOrderNo = pickNo; wb.partion = partion; wb.Update(); return enumRegPlateResult.成功; } else { return enumRegPlateResult.箱子颜色和订单灯色不符; } } else { if (dv.Count > 0) { String pickNo = dv[0]["pickOrderNo"].ToString(); WmsPlate wb = new WmsPlate(id); wb.pickOrderNo = pickNo; wb.Update(); return enumRegPlateResult.成功; } else { return enumRegPlateResult.当前无拣货订单; } } } internal DataTable getBoxsByPickOrder(string pickOrderNo) { return plate.getPlatesByPickOrder(pickOrderNo); } internal List getPartsFinishIds() { DataTable dt = getWmsOutPickRequest.getPartsFinishIds(); List lst = new List(); Node nd; foreach (DataRow dr in dt.Rows) { nd = new Node(dr); lst.Add(nd.flag); } return lst; } internal DataTable getPartionRequests(int partion) { return pickLabelDetail.getPartionRequests(partion); } internal DataTable getLightPartions() { return getWmsOutPickRequest.getLightPartions(); } Dictionary partColors = new Dictionary(); public List newPartPickWave() { LogHelper.debug(typeof(lWmsOutPickRequest), "开始新波次。。。。。。。。。。。。。。。。。。"); List lst = outRequest.getRecords4PartWave(enumOrderType.销售出库); //.getRequestObjects(enumOutOrderType.拣货单, enumOutStockRequestStatus.波次处理); return createPartPickWave(lst); } /// /// 按拣货单生成亮灯数据 /// /// /// public void newPartionPick(string pickOrderNo, int partion) { List lst = new List(); lst.Add( outRequest.getRecords4PickOrder(pickOrderNo, partion)); createPartPickWave(lst); } public List createPartPickWave(List lst) { List lstParts = new List(); LogHelper.debug(typeof(lWmsOutPickRequest), "开始新波次。。。。。。。。。。。。。。。。。。"); // List lst = outRequest.getRecords4PartWave(); //.getRequestObjects(enumOutOrderType.拣货单, enumOutStockRequestStatus.波次处理); List batchRequests = new List(); int recCnt = 0; foreach (DataTable dt in lst) { recCnt += dt.Rows.Count; } if (recCnt == 0) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("无订单需要处理,波次结束")); checkRepAndNoStockOrders(); return lstParts; } int labelMaxInWave = WmsConstants.MAX_LABEL_DATA_IN_A_WAVE; //一个标签一个波次只能存储40条数据 #if DEBUG // if (lblist.Count == 0) { lblist.Clear(); initialDebugSetting(); } lblist.Sort(); // int minId = lblist[0]; // int maxId = lblist[lblist.Count - 1]; // labelMaxInWave = 2; #endif // List strecs = null; waveOrder ="WAVE_PART_PICK"; int pickDetailMaxInWave = WmsConstants.MAX_CONTROL_DATA_IN_A_WAVE; //控制器每个端口最大存储1200条 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 = new List(); List lstBulk = new List(); 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 = false; // bool canSeedPickLessThanseedsCount = false; //单个播种拣选单数量不可少于播种能力 List seedsRequests = new List(); Dictionary seedsBulks = new Dictionary(); // int bulkCnt = 0; // int requestCnt = 0; //bulkRequests = new List(); //for batch process in a new thread //开始处理有零货的订单 DateTime d0 = DateTime.Now; // double totoalTime = 0d; // string lastAddress = ""; // int lastPart = -1; int color = 1; string lastRequest = ""; int requestCntInPart = 0; foreach (DataTable dt1 in lst) { lastRequest = ""; requestCntInPart = 0; foreach (DataRow dr in dt1.Rows) { WmsStockRecord sr = new WmsStockRecord(dr); if (String.IsNullOrEmpty(lastRequest) || !sr.orderNo.Equals(lastRequest)) { lastRequest = sr.orderNo; requestCntInPart++; if (requestCntInPart > WmsConstants.PART_ORDER_SIZE) //限制同区同时分拣订单的数量 { break; } } if(pickDetailMaxInWave <= lstBulk.Count){ break; } lstBulk.Add(new WmsStockRecord(dr)); } } LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理拣货笔数:{0}", lstBulk.Count)); #region 建立零库电子拣选临时数据 int lastId = 0; WmsOutPickLable_tmp wpl; foreach( WmsStockRecord rec in lstBulk) { 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 } //建立零库电子拣选临时数据 if (rec.count + rec.countOuting < 1) //不支持小数 { continue; } wpl = new WmsOutPickLable_tmp(); wpl.pickOrderNo = rec.orderNo; wpl.recordId = rec.ID; // wpl.color = desk.color; wpl.count = rec.countOuting; wpl.locationId = rec.locationId; wpl.elabAddress = rec.location.elabAddress; wpl.elabId = rec.location.elabId; // wpl.elabId = new Random().Next(1,4); //测试。。。随机分配标签id 为 1-3 wpl.port = rec.location.port; wpl.partion = rec.partion; 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); } #endregion LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" lstBulk.Count:{1},sumBulkCnt:{2}" , seedsRequests.Count, lstBulk.Count, sumBulkCnt)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("进入摘果式拣选")); #region 保存整货和零货出库分拣数据 WmsOutPickRequest request ; lastRequest = ""; int lastPartion=-1; try { using (TransactionScope scope1 = new TransactionScope()) { foreach (WmsOutPickLable_tmp wp in lstLabel) //建立电子拣选临时数据 { if (lastPartion == -1 || lastPartion != wp.partion) { lstParts.Add(wp.partion); color = 0; //每个区从红色开始分配灯色 lastPartion = wp.partion; lastRequest = ""; if (partColors.ContainsKey(wp.partion)) //在分区一波次只有一个订单情况下,每波次颜色红绿轮替 { if (partColors[wp.partion] == 1) { partColors[wp.partion] = 2; } else { partColors[wp.partion] = 1; } } else { partColors[wp.partion] = 1; } } if (String.IsNullOrEmpty(lastRequest) || !wp.pickOrderNo.Equals(lastRequest)) { lastRequest = wp.pickOrderNo; request = new WmsOutPickRequest(wp.pickOrderNo); request.waveOrder = waveOrder; // request.state = (int)enumOutStockRequestStatus.正在分拣; if(String.IsNullOrEmpty(request.waveStart)){ request.waveStart = request.getDateTime(); } request.operater = this.operId; request.bulkPickState =(int)enumOutStockPickStatus.正在分拣; WmsOutPickDetail wd = new WmsOutPickDetail(wp.orderDetailId); if(wd.bulkPickState !=(int)enumOutStockPickStatus.正在分拣){ wd.bulkPickState =(int)enumOutStockPickStatus.正在分拣; wd.operater =operId; wd.Update(); } // add or update WmsOutPickDetail_tmp for validation if(request.desk ==0){ request.desk = getRandomFreeDesk().color; } //color = request.desk; color++; if (String.IsNullOrEmpty(request.tranLocationId)) { request.tranLocationId = new TmsStock().getTranLocation(request.customerId); } request.waveOrder = waveOrder; request.Update(); request.savePartionTempData4Validation(request.pickOrderNo); if (request.batchPickState > -1) { batchRequests.Add(request); } } if (WmsConstants.PART_ORDER_SIZE == 1) { wp.color = partColors[wp.partion]; } else { wp.color = color; } wp.Add(); } waveSize++; scope1.Complete(); //TimeSpan ts2 = DateTime.Now - d12; //System.Diagnostics.Debug.WriteLine(string.Format(" {1} 保存完毕 {0} cost {2} .....", request.pickOrderNo, DateTime.Now, ts2.TotalSeconds + " : " + ts2.TotalMilliseconds)); } //System.Diagnostics.Debug.WriteLine(string.Format("{1} 处理完毕 {0} cost {2} .....", request.pickOrderNo,DateTime.Now, ts.TotalSeconds +" : "+ ts.TotalMilliseconds)); } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); // System.Diagnostics.Debug.WriteLine(e.Message); } // TimeSpan ts00 = DateTime.Now - d00; // totoalTime += ts00.TotalSeconds; #endregion //检查待补货出货单状态 // checkRepAndNoStockOrders(); Thread stockCheckThread = new Thread(checkRepAndNoStockOrders); stockCheckThread.IsBackground = true; stockCheckThread.Start(); /* Thread.CurrentThread.Join(1); // process all batch pick request Thread batchPick = new Thread(new ParameterizedThreadStart(processBatchWithBulkOrders)); batchPick.IsBackground = true; batchPick.Start(batchRequests); */ // processAllBatchOrders(requests, waveOrder); TimeSpan ts0 = DateTime.Now - d0; //System.Diagnostics.Debug.WriteLine(string.Format("{0} 全部处理完毕{1} ..", DateTime.Now, ts0.TotalSeconds + " : " + ts0.TotalMilliseconds)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 全部处理完毕{1} ..", DateTime.Now, ts0.TotalSeconds + " : " + ts0.TotalMilliseconds)); // TaskCallBack(); return lstParts; } /// /// 根据销售订单或拣货单生成亮灯数据 /// /// /// /// /// internal DataTable getOrderPickList(string orderNo, bool isPickOrder, int partion) { string pickOrderNo = orderNo; if (!isPickOrder) { pickOrderNo = new lWmsOutRequest(operId).genPickOrder(orderNo); } newPartionPick(pickOrderNo, partion); return outRequest.getOrderPickList(pickOrderNo, partion); } /// /// 播种式拣选 /// 只有播种台一种复核台 /// 每个播种台发起一组波次,当有播种台空闲时,该播种台发起新拣货任务,拣货任务分布在各个拣货区,拣货区通过几种方式实现亮灯拣货 /// 1. 先注册周转箱领取任务并亮灯,每个周转箱只对应一个复核台,只亮一种颜色的灯 /// 2. 先拣货后注册周转箱。 通过完成键呼叫后续任务,任务按 /// 波次任务安分区注册周转箱 /// 摘果拣选分区按周转箱亮灯 /// 周转箱在同一个波次内可以流转到多个分拣区拣货 /// public void newBulkSeedsDPSPickWave() { //播种筛选, //适合播种的客户订单合并成一个、多个大订单,统一捡出后进行播种操作 //1. 单个订单的品种少 、数量少 //2. 订单数量多 //只处理订单零货部分 //加入播种选项,所有订单零货部分使用摘取+播种方式 //1.播种点数量可配置, 分别用不同颜色区分 //2.每个播种点可分播客户的数量配置, 即每个播种点处理零货订单数量( 例如配置成6个,一次捡6个客户的订单零货部分,送由一个播种点播种) //3.波次和播种点的对应关系,一个波次只摘取一个播种点的零货,还是多个播种点的数据? //4. //一个波次可以摘取订单数 = 空闲分播台数量*每个分播台可分播客户数, 分播台的订单用颜色区分 // LogHelper.debug(typeof(lWmsOutPickRequest), "开始新波次。。。。。。。。。。。。。。。。。。"); // System.Diagnostics.Debug.WriteLine("begin make new wave .....{0}" ,DateTime.Now); List requests = outRequest.getRequests4Wave(); //.getRequestObjects(enumOutOrderType.拣货单, enumOutStockRequestStatus.波次处理); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("待处理订单数量:{0}", requests.Count)); if (requests.Count == 0) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("无订单需要处理,波次结束")); checkRepAndNoStockOrders(); return; } // desk.restDeskStatus(enumDeskState.free); // desk.restDeskStatus(enumDeskState.free, enumDeskType.播种); //播种台状态复位到空闲,是不是可以由播种员实际播种任务进度控制? //_seedsDesk = getRandomFreeSeedsDesk(); // _desk = getRandomFreeDesk(); int labelMaxInWave = WmsConstants.MAX_LABEL_DATA_IN_A_WAVE; //一个标签一个波次只能存储40条数据 //#if DEBUG // if (lblist.Count == 0) { lblist.Clear(); initialDebugSetting(); } lblist.Sort(); // int minId = lblist[0]; // int maxId = lblist[lblist.Count - 1]; // labelMaxInWave = 2; //#endif // List strecs = null; // waveOrder = Util.getOrderNo(enumCreateOrderType.waveOrder, _obj.getNextSeq()); //waveOrder = "WV" + System.DateTime.Now.ToString("yyyyMMddHHmmss"); int pickDetailMaxInWave = WmsConstants.MAX_CONTROL_DATA_IN_A_WAVE; //一个控制器最大存储1200条 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(); _seedsDesk = getRandomFreeSeedsDesk(); seedsCount = seedsDesk.seedsCount; int bulkCnt = 0; int requestCnt = 0; bulkRequests = new List(); //for batch process in a new thread //开始处理有零货的订单 DateTime d0 = DateTime.Now; double totoalTime = 0d; string lastAddress = ""; foreach (WmsOutPickRequest request in requests) { if (seedsDesk.ID == 0) { return; } DateTime d00 = DateTime.Now; if (request.bulkCnt > 0) { requestCnt++; } if (requestCnt >= pickDetailMaxInWave) { break; } if (request.bulkCnt == 0) { continue; } // LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("开始处理零库出库 {0} ------------", request.pickOrderNo )); LogHelper.debug(this.GetType(), string.Format("开始处理零库出库 {0} ------------", request.pickOrderNo)); DataTable dt = stkRecord.getPickStockRecods(request.pickOrderNo, true).Tables[0];//取出库明细 // lstPort = new List(); lstLabel = new List(); //开始处理零货出库 DataView dvBulk = new DataView(dt); dvBulk.RowFilter = string.Format(" volType in ({0},{1})", (int)enumWhLocVol.零库1, (int)enumWhLocVol.零库); //TimeSpan tssss = DateTime.Now - d00; //System.Diagnostics.Debug.WriteLine(string.Format(" {0} {1},befor prepare bulklist, cost {2}", DateTime.Now, request.pickOrderNo, tssss.TotalSeconds)); DateTime d1 = DateTime.Now; // lstBulk = new List(); // TimeSpan tsss = DateTime.Now - d1; // LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" {0} prepare bulklist count :{1}, cost {2}", request.pickOrderNo, lstBulk.Count, tsss.TotalSeconds)); // DateTime d2 = DateTime.Now; lstBulk = new List(); sumBulkCnt = 0; foreach (DataRowView drv in dvBulk) { WmsStockRecord sr = new WmsStockRecord(drv.Row); // sr.ID = Convert.ToInt32(drv["id"].ToString()); // sr.locationId = drv["locationID"].ToString(); // sr.orderDetailId = Convert.ToInt32(drv["orderDetailId"].ToString()); if (WmsConstants.OUT_STOCK_DEDUCT) { sr.count = Convert.ToDecimal(drv["countOuting"].ToString()); } else { sr.count = Convert.ToDecimal(drv["count"].ToString()); } sumBulkCnt += sr.count; lstBulk.Add(sr); } //tsss = DateTime.Now - d2; // LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" {0} {1},prepare bulklist2 count :{2}, cost {3}", DateTime.Now, request.pickOrderNo, lstBulk.Count, tsss.TotalSeconds)); /* pickDetailMaxInWave -= strecs.Count; if (pickDetailMaxInWave < 0) { //超出一个波次最大分拣数量 isReachLimit = true; break; } */ tmplabelCnt.Clear(); tmpcomCnt.Clear(); int lastId = 0; //DateTime d11 = DateTime.Now; //System.Diagnostics.Debug.WriteLine(string.Format(" 开始检查是否超限 --- {0}", d11)); #region checkmax /* * if (WmsConstants.OUT_LIGHT_ENABLE) { foreach (WmsStockRecord rec in lstBulk)//检查电子标签数量是否超过范围 { 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 } if (tmplabelCnt.ContainsKey(rec.location.elabId)) { tmplabelCnt[rec.location.elabId]++; } else { tmplabelCnt[rec.location.elabId] = 1; } if (tmpcomCnt.ContainsKey(rec.location.port)) { tmpcomCnt[rec.location.port] = tmpcomCnt[rec.location.port] + 1; } else { tmpcomCnt[rec.location.port] = 1; } if (labelCnt.ContainsKey(rec.location.elabId)) { labelCnt[rec.location.elabId] = labelCnt[rec.location.elabId] + 1; if (labelCnt[rec.location.elabId] >= labelMaxInWave) { isReachLimit = true; foreach (int k in tmplabelCnt.Keys) { if (labelCnt.ContainsKey(k)) { labelCnt[k] -= tmplabelCnt[k]; } } break; } } else { labelCnt[rec.location.elabId] = 1; } if (comCnt.ContainsKey(rec.location.port)) { comCnt[rec.location.port] = comCnt[rec.location.port] + 1; if (comCnt[rec.location.port] >= pickDetailMaxInWave) { isReachLimit = true; foreach (int k in tmpcomCnt.Keys) { if (comCnt.ContainsKey(k)) { comCnt[k] -= tmpcomCnt[k]; } } break; } } else { comCnt[rec.location.port] = 1; } } //TimeSpan ts11 = DateTime.Now - d11; //System.Diagnostics.Debug.WriteLine(string.Format(" 检查是否超限完毕 --- cost {0}", ts11.TotalSeconds + " : " + ts11.TotalMilliseconds)); if (isReachLimit) { isReachLimit = false; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("超过限制,继续下条数据.... ")); continue; } } * */ #endregion endcheck LogHelper.debug(typeof(lWmsOutPickRequest), string.Format(" lstBulk.Count:{1},sumBulkCnt:{2}" , seedsRequests.Count, lstBulk.Count, sumBulkCnt)); if (isSeedsEnabled // && lstBulk.Count < pickGoodsTypeMin //订单货品种类小 // && sumBulkCnt < pickGoodsCountMin && !noSeeds.Contains(request.pickOrderNo) ) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("进入播种拣选 seedsRequests.Count:{0} ", seedsRequests.Count)); //播种筛选 if (_seedsDesk.ID > 0) //exist free seeds desk { if (seedsRequests.Count < seedsCount)//播种能力之内 { //符合播种条件,整合订单 seedsRequests.Add(request); //出库明细合并 foreach (WmsStockRecord wsr in lstBulk) { if (seedsBulks.ContainsKey(wsr.locationId)) { seedsBulks[wsr.locationId].count += wsr.count; seedsBulks[wsr.locationId].countOuting += wsr.countOuting; } else { seedsBulks[wsr.locationId] = wsr; } } if (seedsRequests.Count == seedsCount) //生成播种拣选单 { //create seeds pick request //create pick detail WmsOutPickLable_tmp createSeedsLabelDetail(seedsRequests, seedsBulks); seedsRequests.Clear(); seedsBulks.Clear(); _seedsDesk = getRandomFreeSeedsDesk(); //重新取可用播种台 seedsCount = seedsDesk.seedsCount; // continue; } continue; } } else //no free seeds desk { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("播种拣选,no free seeds desk")); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("订单{0} 将进入下一播种波次,开始处理下个订单", request.pickOrderNo)); continue; } } TimeSpan ts00 = DateTime.Now - d00; totoalTime += ts00.TotalSeconds; } if (seedsRequests.Count>0) //生成播种拣选单 { //create seeds pick request //create pick detail WmsOutPickLable_tmp createSeedsLabelDetail(seedsRequests, seedsBulks); } /*少于播种台播种订单个数时 ,等待新订单加入后再拣选 或改播种台或改摘果 if (isSeedsEnabled && seedsRequests.Count > 0) { if (seedsRequests.Count == seedsCount || seedsRequests.Count >= seedsDesk.seedsMinCount) // || seedsRequests.Count < seedsCount && canSeedPickLessThanseedsCount { createSeedsLabelDetail(seedsRequests, seedsBulks);//生成播种拣选单 } else { _seedsDesk = getRandomFreeSeedsDesk(); if (seedsDesk.ID == 0) //无可用播种台 { foreach (WmsOutPickRequest pr in seedsRequests) { if (!seedsWaiting.Keys.Contains(pr.pickOrderNo)) { seedsWaiting[pr.pickOrderNo] = System.DateTime.Now; } else { if (seedsWaiting[pr.pickOrderNo].AddMinutes(WmsConstants.OUT_MAX_SEEDS_WAIT_MINUES) < System.DateTime.Now) { seedsWaiting.Remove(pr.pickOrderNo); noSeeds.Add(pr.pickOrderNo); } } } } } seedsRequests.Clear(); seedsBulks.Clear(); }*/ TimeSpan ts1 = DateTime.Now - d0; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 零库处理完毕----- cost {1} .....{2}", DateTime.Now, ts1.TotalSeconds + " : " + ts1.TotalMilliseconds, totoalTime)); // insert tmp data for validation /// outRequest.saveTempData4Validation(waveOrder); WmsConstants.WAVE_CURRENT_PICK_STATUS.Clear(); WmsConstants.WAVE_CURRENT_ORDER = waveOrder; WmsConstants.WAVE_LAST_TIME = DateTime.Now; //检查待补货出货单状态 Thread stockCheckThread = new Thread(checkRepAndNoStockOrders); stockCheckThread.IsBackground = true; stockCheckThread.Start(); TimeSpan ts0 = DateTime.Now - d0; //System.Diagnostics.Debug.WriteLine(string.Format("{0} 全部处理完毕{1} ..", DateTime.Now, ts0.TotalSeconds + " : " + ts0.TotalMilliseconds)); LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("{0} 全部处理完毕{1} ..", DateTime.Now, ts0.TotalSeconds + " : " + ts0.TotalMilliseconds)); // TaskCallBack(); } private void createSeedsLabelDetail(List seedsRequests, Dictionary seedsBulks) { LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("开始生成播种拣选单,seedsRequests.count :{0},seedsBulks.count:{1}", seedsRequests.Count, seedsBulks.Count)); List lstLabel = new List(); if (_seedsDesk.ID == 0) { return; } waveOrder = Util.getOrderNo(enumCreateOrderType.dpsOrder, _obj.getNextSeq(enumCreateOrderType.dpsOrder)); WmsOutPickRequest seedPickRequest = new WmsOutPickRequest(); seedPickRequest.pickOrderNo = Util.getOrderNo(enumCreateOrderType.seedsPickOrder, seedPickRequest.getNextSeq(enumCreateOrderType.seedsPickOrder)); seedPickRequest.orderType = (int)enumOrderType.销售出库; seedPickRequest.outStoreType = (int)enumOutStoreType.播种拣货出库; LogHelper.debug(typeof(lWmsOutPickRequest), string.Format("播种拣选单 :{0} ", seedPickRequest.pickOrderNo)); WmsOutPickLable_tmp wpl; foreach (WmsStockRecord rec in seedsBulks.Values) { if (rec.count + rec.countOuting <= 1) { continue; } wpl = new WmsOutPickLable_tmp(); wpl.pickOrderNo = seedPickRequest.pickOrderNo; wpl.recordId = rec.ID; //link goods info wpl.color = seedsDesk.color; wpl.partion = rec.partion; 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; //#if DEBUG if (comLables.Count > 0) { int id = new Random().Next(lblist.Count); wpl.elabId = lblist[id]; wpl.port = comLables[wpl.elabId]; } //#endif wpl.dpsOrder = waveOrder; wpl.operater = this.operId; lstLabel.Add(wpl); } int i = 0; int startId = seedsDesk.startLabelId; //保存分拣数据 try { using (TransactionScope scope1 = new TransactionScope()) { foreach (WmsOutPickLable_tmp wp in lstLabel) //建立电子拣选临时数据 { wp.Add(); } seedsDesk.state = (int)enumDeskState.任务中; seedsDesk.Update(); foreach (WmsOutPickRequest request in seedsRequests) { request.waveOrder = waveOrder; // request.state = (int)enumOutStockRequestStatus.正在分拣; request.waveStart = request.getDateTime(); request.operater = this.operId; if (lstLabel.Count > 0) { // request.updateBulkPickStatus(request.pickOrderNo, enumOutStockPickStatus.正在分拣, operId); request.bulkPickState = (int)enumOutStockPickStatus.正在分拣; request.desk = seedsDesk.color; } request.seedsLabelId = startId > 0 ? startId++ : seedsDesk.color * 10 + ++i; //每个播种复合台的标签ID编号不重复,应对多个播种台共用一个标签控制器的情况。 request.seedsPickNo = seedPickRequest.pickOrderNo; //赋值播种拣选订单单号 request.seedsPort = seedsDesk.port; if (comLables.Count > 0) { request.seedsPort = comLables[1]; } request.Update(); // bulkRequests.Add(request); //waveSize++; } outRequest.saveTempData4Validation(waveOrder); scope1.Complete(); //TimeSpan ts2 = DateTime.Now - d12; //System.Diagnostics.Debug.WriteLine(string.Format(" {1} 保存完毕 {0} cost {2} .....", request.pickOrderNo, DateTime.Now, ts2.TotalSeconds + " : " + ts2.TotalMilliseconds)); } //System.Diagnostics.Debug.WriteLine(string.Format("{1} 处理完毕 {0} cost {2} .....", request.pickOrderNo,DateTime.Now, ts.TotalSeconds +" : "+ ts.TotalMilliseconds)); } catch (Exception e) { LogHelper.WriteLog(typeof(lWmsOutPickRequest), e); } } /// /// 播种区域周转箱任务领取注册并亮灯 /// 当拣货分区有拣货任务,且空闲时,空周转箱流入 /// 扫描周转箱条码,根据周转箱容积,分配拣货任务并亮灯 /// 分配任务按分播台顺序依次分配 /// 同一个物品尽量分配在同一个周转箱或相邻周转箱 /// 周转箱专属一个分拣区,同个周转箱不跨区分配 /// /// /// /// public enumRegPlateResult regSeedsPlate(string plateId,int partion) { decimal usedVol = 0; int lastColor = 0; DataTable dt = getWmsOutPickRequest.getPartionBulkDetailInCurrentWave(); DataView dv = dt.DefaultView; WmsPlate box = new WmsPlate(plateId); if (box.ID == 0) { return enumRegPlateResult.容器不存在; } if (box.state == (int)enumPlateStatus.空闲)//复核台扫描周转箱,设置状态为free. { box.waveNo = ""; box.terminal = 0; box.partion = 0; } else// not free box { if (!String.IsNullOrEmpty(box.waveNo) || box.terminal > 0) { dv.RowFilter = "dpsOrder='" + box.waveNo + "' and color =" + box.terminal; if (dv.Count == 0) //周转箱历史绑定未被释放 { box.waveNo = ""; box.terminal = 0; } } dv.RowFilter = "plate='" + plateId + "' and partion <>" + partion; if (dv.Count > 0) { return enumRegPlateResult.容器已被其他货区占用; } } dv.RowFilter = "plate='" + plateId + "' and partion =" + partion +" and dpsOrder ='" + box.waveNo +"'"; foreach (DataRowView drv in dv) { WmsOutPickLable_tmp wpl = new WmsOutPickLable_tmp(drv.Row); usedVol += wpl.calVol; } if (usedVol >= box.volume) { return enumRegPlateResult.容器空间不足; } dv.RowFilter = "isnull(plate,'-1')='-1' and state=0 and partion =" + partion; if (box.terminal > 0) { dv.RowFilter += " and color = " + box.terminal; } dv.Sort = "color,plate,calVol desc"; if (dv.Count == 0) { return enumRegPlateResult.当前无拣货订单; } bool isReged = false; using (TransactionScope scope1 = new TransactionScope()) { foreach (DataRowView drv in dv) { if (box.volume - usedVol <= 0) { break; } WmsOutPickLable_tmp wpl = new WmsOutPickLable_tmp(drv.Row); lastColor= box.terminal; if (lastColor > 0 && lastColor != wpl.color) //周转箱分配唯一的分播台 { continue; } if (!String.IsNullOrEmpty(box.waveNo) && box.waveNo != wpl.dpsOrder)//周转箱分配唯一的分播台 { continue; } decimal sv = wpl.calVol / wpl.count; decimal osv = wpl.minOperateCount * sv; decimal newCnt = 0; bool isSplitTask = false; if (wpl.calVol > box.volume - usedVol) { newCnt = Math.Floor((box.volume - usedVol) / osv) * wpl.minOperateCount; usedVol = box.volume; } else if (wpl.calVol == box.volume - usedVol) { newCnt = wpl.count; usedVol += wpl.calVol; /* wpl.plate = box.plateId; wpl.Update(); box.Update(); break; */ } else if (wpl.calVol < box.volume - usedVol) { newCnt = wpl.count; usedVol += wpl.calVol; isSplitTask = wpl.plate == "-1"; /* wpl.plate = box.plateId; wpl.Update(); box.Update(); if (isSplitTask) //同一个品多个周转箱,剩余尾数独占一个周转箱,方便分播 { break; } */ } newCnt = newCnt > WmsConstants.MAX_PICK_CNT_BULK ? WmsConstants.MAX_PICK_CNT_BULK : newCnt; if (newCnt > 0) { if (lastColor == 0) { lastColor = wpl.color; box.waveNo = wpl.dpsOrder; box.terminal = wpl.color;//seeds desk box.state = (int)enumPlateStatus.取总待分播; } wpl.count = newCnt; wpl.plate = box.plateId; wpl.Update(); // usedVol += newCnt * sv; wpl = new WmsOutPickLable_tmp(drv.Row); if (wpl.count - newCnt > 0) { wpl.count = wpl.count - newCnt; wpl.plate = "-1"; wpl.calVol = 0; wpl.Add();//新增待注册周转箱任务 } box.Update(); isReged = true; } if (isSplitTask) //同一个品多个周转箱,剩余尾数独占一个周转箱,方便分播 { break; } } scope1.Complete(); } return enumRegPlateResult.成功 ; } internal DataTable getPlatePickList(string plateId, int part) { return pickLabelDetail.getPlateTaskPickList(plateId, part); } internal DataTable getPlatePickTaskList4wince(string plateId, int part) { return pickLabelDetail.getPlatePickTaskList4wince(plateId, part); } internal DataTable getDeskList(enumDeskType deskType) { return desk.getDeskList(deskType); } internal int setDeskFree(int deskId) { WmsOutDesk desk = new WmsOutDesk().getDeskObjByColor(deskId); if (desk.state != (int)enumDeskState.空闲) { desk.state =(int)enumDeskState.空闲; return desk.Update(); } return 0; } internal int setPlateFree(string plateId) { WmsPlate plate = new WmsPlate(plateId); plate.state = (int)enumPlateStatus.空闲; return plate.Update(); } internal bool finishBulkValidateItem(int id, int status, string remark, int reason, decimal count, int checkedBy1) { WmsOutPickDetail_tmp tmp = new WmsOutPickDetail_tmp(id); tmp.bulkPickState = status; tmp.validRemark = remark; tmp.validReason = reason; tmp.confirmedCount = count; tmp.operater = operId; tmp.checkedBy1 = checkedBy1; tmp.checkedBy = tmp.operater; tmp.checkedTime = tmp.getDateTime(); //updatePickState(id, enumPickState.复核完成); using (TransactionScope scope = new TransactionScope()) { outPickPort.updatePickStateByOrderDetailId(id, enumPickState.复核完成, operId, checkedBy1); tmp.Update(); scope.Complete(); } return true; } /// /// 对于分拣完成的,且其所有的拣货任务已复核(装车)的分拣单 更新分拣状态、复核拣货明细,通知ERP 订单出库 /// public void unloadPickrequests() { // List requests = getWmsOutPickRequest.getRequestsReady4Validation(); List requests = getWmsOutPickRequest.getRequestObjects(enumOutStockRequestStatus.已装车); //TODO: get 自提类型的订单,状态为已复核 logPlate.Debug("装车后续处理。。。。开始"); WmsPlateStock_tmp wpt = new WmsPlateStock_tmp(); foreach (WmsOutPickRequest req in requests) { using (TransactionScope scope = new TransactionScope()) { req.state = (int)enumOutStockRequestStatus.已出库; req.Update(); DataTable dt = wpt.getByOrder(req.pickOrderNo); foreach(DataRow dr in dt.Rows) { wpt = new WmsPlateStock_tmp(dr); WmsStock stk = new WmsStock(wpt.locationid, wpt.skuId, wpt.goodsId); stk.plateCount -= wpt.count; stk.updateCountOut(); } //to realse plate tmp stock. int cnt= wpt.releasePlateByOrder(req.pickOrderNo); logPlate.Debug(req.pickOrderNo + " released tmp stock item cnt " + cnt); scope.Complete(); } } log.Debug("装车后续处理。。。。结束"); } public void Test() { log.Debug("JUST T E S T"); } /// /// 线路码头装车集货时触发 /// /// public void finishRequest(WmsOutPickRequest req) { log.Debug(string.Format(" validation request {0}, status {1}", req.pickOrderNo, (enumOutStockRequestStatus)req.state)); if (req.state >= (int)enumOutStockRequestStatus.已出库) { return; } List lstDetail = req.outDetails; List lstSaled = new List(); DataTable dt = new Erp_sale().getDetailByPickOrder(req.pickOrderNo); using (TransactionScope scope = new TransactionScope()) { foreach (DataRow dr in dt.Rows) { lstSaled.Add(new Erp_sale_d(dr)); } // log.Debug(string.Format(" to update sale detail pickcount, request {0} ,pick detail count {1}, sale details {2}", req.pickOrderNo, lstDetail.Count, lstSaled.Count)); decimal pickCnt = 0; foreach (WmsOutPickDetail detail in lstDetail) { pickCnt = detail.bulkPicked + detail.batchPicked + detail.seeded; // log.Debug(string.Format("detail id {2}, goodsId {0} ,pick count {1} ", detail.goodsId, pickCnt,detail.ID)); foreach (Erp_sale_d esd in lstSaled) { // log.Debug(esd.goods_id); if (esd.goods_id == detail.goodsId) { esd.pickCount = pickCnt >= esd.count ? esd.count : pickCnt; // log.Debug(string.Format(" to update saled {0}, pickcount to {1} ", esd.ID,esd.pickCount)); esd.Update(); pickCnt -= esd.pickCount; } if (pickCnt <= 0) { break; } } // log.Debug(string.Format(" 1 left pick count {0} ", pickCnt)); if (pickCnt > 0) { foreach (Erp_sale_d esd in lstSaled) { if (esd.goods_id == detail.goodsId) { esd.pickCount += pickCnt; esd.Update(); break; } } } // log.Debug(string.Format(" 2 left pick count {0} ", pickCnt)); } req.state = (int)enumOutStockRequestStatus.已出库; req.Update(); updateErpSaleStatus(req.pickOrderNo, enumOutStockRequestStatus.已出库); scope.Complete(); } log.Debug(string.Format(" request {0} 已出库 ,{1}", req.pickOrderNo, enumOutStockRequestStatus.已出库)); /* Erp_sale erp_Sale = new Erp_sale(); List lstSales = erp_Sale.getObjs(erp_Sale.getSaleOrdersByPickOrder(req.pickOrderNo)); foreach (Erp_sale s in lstSales) { // if (s.erp_state != (int)enumErpOrderStatus.通知成功) 一个单可能多次拣货、集货 noticeErpSaleOut(s); // Thread.Sleep(300); } */ } public string retryNoticeErp() { // enumErpOrderStatus status = enumErpOrderStatus.通知失败; DataTable dt = new Erp_sale().getByErpState(); if (dt.Rows.Count == 0) { return "没有数据"; } logERP.Debug( " erp sale order 待通知总共数量 " +dt.Rows.Count); WmsConstants.ERP_NOTICE_STOCK_OUT_DOING = true; int i = 0; foreach (DataRow dr in dt.Rows) { //noticeErpSaleOut(new Erp_sale(dr)); logERP.Debug(++i+" try to notice erp sale order " + new Erp_sale(dr).sale_order); try { noticeOutErp(new Erp_sale(dr)); }catch(Exception e) { } Thread.Sleep(100); // break; } logERP.Debug(" erp sale order 通知 结束------《"); WmsConstants.ERP_NOTICE_STOCK_OUT_DOING = false; return ""; } public void noticeErpSaleOut(Erp_sale order) { Thread threadPreProcess = new Thread(new ParameterizedThreadStart(noticeOutErp)); threadPreProcess.IsBackground = true; threadPreProcess.Start(order); } private void noticeOutErp(Object order) { if (!WmsConstants.ERP_NOTICE_STOCK_OUT) { return; } // string orderNo = "ZCCGR230106-0027"; string url = string.Format(WmsConstants.ERP_API_ORDER_NOTICE, ((Erp_sale)order).sale_order, (int)enumErpOrderType.出库); // logIn.Error("WmsConstants.ERP_API_ORDER_NOTICE " + WmsConstants.ERP_API_ORDER_NOTICE); // logIn.Error("WmsConstants.ERP_API_KEY " + WmsConstants.ERP_API_KEY); // logIn.Error(url); try { HttpWebRequest webReq = getErpRequest(url); System.Net.HttpWebResponse response; response = (System.Net.HttpWebResponse)webReq.GetResponse(); System.IO.StreamReader myreader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8); string responseText = myreader.ReadToEnd(); myreader.Close(); // logOut.Debug(((Erp_sale)order).sale_order + " enumErpOrderType.出库, notice erp response code " + response.StatusCode); logERP.Debug(string.Format(" notice ERP sale order {0},response {1}", ((Erp_sale)order).sale_order, responseText)); ((Erp_sale)order).erp_state = (int)enumErpOrderStatus.通知失败; if (response.StatusCode == HttpStatusCode.OK) { Newtonsoft.Json.Linq.JObject jo = (JObject)JsonConvert.DeserializeObject(responseText); // logOut.Debug(" jo obj : " + jo.GetValue("status")); // Res res = (Res)JsonConvert.DeserializeObject(responseText,typeof(Res)); // logIn.Debug(" res obj : " + Util.getJson(res)); if (jo.GetValue("status").ToString() == "SUCCESS")// || res.Status== "SUCCESS") { ((Erp_sale)order).erp_state = (int)enumErpOrderStatus.通知成功; } } ((Erp_sale)order).Update(); logOut.Debug(" success notice ERP sale order status to: " + (enumErpOrderStatus)((Erp_sale)order).erp_state); } catch (Exception e) { log.Error(e); } } public string retryNoticeErpOrder() { // enumErpOrderStatus status = enumErpOrderStatus.通知失败; DataTable dt = new WmsOrderRequest().getNoticeFailures(); if (dt.Rows.Count > 0) { logERP.Debug(" ERP order request 待通知总共数量 " + dt.Rows.Count); foreach (DataRow dr in dt.Rows) { noticeErpOrder(new WmsOrderRequest(dr)); Thread.Sleep(1000); } } return ""; } public void noticeErpOrder(WmsOrderRequest order) { Thread threadPreProcess = new Thread(new ParameterizedThreadStart(noticeErpOrder)); threadPreProcess.IsBackground = true; threadPreProcess.Start(order); } private void noticeErpOrder(Object order) { if (!WmsConstants.ERP_NOTICE_STOCK_OUT) { return; } // string orderNo = "ZCCGR230106-0027"; enumOrderType type = (enumOrderType)((WmsOrderRequest)order).orderType; enumErpOrderType erpType;//= type == enumOrderType.报废申请 ? enumErpOrderType.报废 : enumErpOrderType.盘点; switch (type) { case enumOrderType.报废申请: erpType = enumErpOrderType.报废; break; case enumOrderType.内部领用: erpType = enumErpOrderType.内部领用; break; case enumOrderType.盘点通知: erpType = enumErpOrderType.盘点; break; default: erpType = enumErpOrderType.盘点; break; } string url = string.Format(WmsConstants.ERP_API_ORDER_NOTICE, ((WmsOrderRequest)order).orderNo,(int)erpType); // logIn.Error("WmsConstants.ERP_API_ORDER_NOTICE " + WmsConstants.ERP_API_ORDER_NOTICE); // logIn.Error("WmsConstants.ERP_API_KEY " + WmsConstants.ERP_API_KEY); // logIn.Error(url); try { HttpWebRequest webReq = getErpRequest(url); System.Net.HttpWebResponse response; response = (System.Net.HttpWebResponse)webReq.GetResponse(); System.IO.StreamReader myreader = new System.IO.StreamReader(response.GetResponseStream(), Encoding.UTF8); string responseText = myreader.ReadToEnd(); myreader.Close(); // logOut.Debug(((Erp_sale)order).sale_order + " enumErpOrderType.出库, notice erp response code " + response.StatusCode); logERP.Debug(string.Format(" notice ERP obs order {0},response {1}", ((WmsOrderRequest)order).orderNo, responseText)); ((WmsOrderRequest)order).state = (int)enumOrderStatus.通知ERP失败; if (response.StatusCode == HttpStatusCode.OK) { Newtonsoft.Json.Linq.JObject jo = (JObject)JsonConvert.DeserializeObject(responseText); // logOut.Debug(" jo obj : " + jo.GetValue("status")); // Res res = (Res)JsonConvert.DeserializeObject(responseText,typeof(Res)); // logIn.Debug(" res obj : " + Util.getJson(res)); if (jo.GetValue("status").ToString() == "SUCCESS")// || res.Status== "SUCCESS") { ((WmsOrderRequest)order).state = (int)enumOrderStatus.通知ERP成功; } } ((WmsOrderRequest)order).Update(); logOut.Debug(" success notice ERP order status to: " + (enumOrderStatus)((WmsOrderRequest)order).state); } catch (Exception e) { log.Error(e); } } } }