public void CreateReceipt(Receipt receipt, User user, bool isOddCreateHu) { log.Debug("Start create receipt"); #region 查找所有的发货项,收货单打印模板,收货差异处理选项 string orderType = null; Party partyFrom = null; Party partyTo = null; ShipAddress shipFrom = null; ShipAddress shipTo = null; string dockDescription = null; string receiptTemplate = null; string huTemplate = null; string grGapTo = null; IList <InProcessLocationDetail> inProcessLocationDetailList = new List <InProcessLocationDetail>(); if (receipt.InProcessLocations != null && receipt.InProcessLocations.Count > 0) { foreach (InProcessLocation inProcessLocation in receipt.InProcessLocations) { InProcessLocation currentIp = inProcessLocationMgr.LoadInProcessLocation(inProcessLocation.IpNo); if (currentIp.Status == BusinessConstants.CODE_MASTER_STATUS_VALUE_CLOSE) { throw new BusinessErrorException("InProcessLocation.Error.StatusErrorWhenReceive", currentIp.Status, currentIp.IpNo); } if (orderType == null) { orderType = inProcessLocation.OrderType; } //判断OrderHead的PartyFrom是否一致 if (partyFrom == null) { partyFrom = inProcessLocation.PartyFrom; } else if (inProcessLocation.PartyFrom.Code != partyFrom.Code) { throw new BusinessErrorException("Order.Error.ReceiveOrder.PartyFromNotEqual"); } //判断OrderHead的PartyFrom是否一致 if (partyTo == null) { partyTo = inProcessLocation.PartyTo; } else if (inProcessLocation.PartyTo.Code != partyTo.Code) { throw new BusinessErrorException("Order.Error.ReceiveOrder.PartyToNotEqual"); } //判断OrderHead的ShipFrom是否一致 if (shipFrom == null) { shipFrom = inProcessLocation.ShipFrom; } else if (!AddressHelper.IsAddressEqual(inProcessLocation.ShipFrom, shipFrom)) { throw new BusinessErrorException("Order.Error.ReceiveOrder.ShipFromNotEqual"); } //判断OrderHead的ShipTo是否一致 if (shipTo == null) { shipTo = inProcessLocation.ShipTo; } else if (!AddressHelper.IsAddressEqual(inProcessLocation.ShipTo, shipTo)) { throw new BusinessErrorException("Order.Error.ReceiveOrder.ShipToNotEqual"); } if (dockDescription == null) { dockDescription = inProcessLocation.DockDescription; } else if (inProcessLocation.DockDescription != dockDescription) { throw new BusinessErrorException("Order.Error.ReceiveOrder.DockDescriptionNotEqual"); } //判断收货单打印模板是否一致 if (receiptTemplate == null) { receiptTemplate = inProcessLocation.ReceiptTemplate; } else { if (inProcessLocation.ReceiptTemplate != null && inProcessLocation.ReceiptTemplate != receiptTemplate) { throw new BusinessErrorException("Order.Error.ReceiveOrder.ReceiptTemplateNotEqual"); } } //判断条码打印模板是否一致 if (huTemplate == null) { huTemplate = inProcessLocation.HuTemplate; } else { if (inProcessLocation.HuTemplate != null && inProcessLocation.HuTemplate != huTemplate) { throw new BusinessErrorException("Order.Error.ReceiveOrder.HuTemplateNotEqual"); } } #region 查找收货差异处理选项 if (grGapTo == null) { grGapTo = inProcessLocation.GoodsReceiptGapTo; } else { if (inProcessLocation.GoodsReceiptGapTo != null && inProcessLocation.GoodsReceiptGapTo != grGapTo) { throw new BusinessErrorException("Order.Error.ReceiveOrder.GoodsReceiptGapToNotEqual"); } } #endregion IListHelper.AddRange <InProcessLocationDetail>( inProcessLocationDetailList, this.inProcessLocationDetailMgr.GetInProcessLocationDetail(inProcessLocation)); } } #endregion IList <ReceiptDetail> targetReceiptDetailList = receipt.ReceiptDetails; receipt.ReceiptDetails = null; //清空Asn明细,稍后填充 #region 创建收货单Head receipt.ReceiptNo = numberControlMgr.GenerateNumber(BusinessConstants.CODE_PREFIX_RECEIPT); receipt.OrderType = orderType; receipt.CreateDate = DateTime.Now; receipt.CreateUser = user; receipt.PartyFrom = partyFrom; receipt.PartyTo = partyTo; receipt.ShipFrom = shipFrom; receipt.ShipTo = shipTo; receipt.DockDescription = dockDescription; receipt.ReceiptTemplate = receiptTemplate; receipt.IsPrinted = false; receipt.NeedPrint = false; if (receipt.InProcessLocations != null && receipt.InProcessLocations.Count > 0) { foreach (InProcessLocation inProcessLocation in receipt.InProcessLocations) { if (inProcessLocation.NeedPrintReceipt) { receipt.NeedPrint = true; break; } } } this.CreateReceipt(receipt); log.Debug("Create receipt " + receipt.ReceiptNo + " head successful"); #endregion #region HU处理/入库操作/创建收货明细 log.Debug("Start create receipt detail"); IList <LocationLotDetail> inspectLocationLotDetailList = new List <LocationLotDetail>(); foreach (ReceiptDetail receiptDetail in targetReceiptDetailList) { OrderLocationTransaction orderLocationTransaction = receiptDetail.OrderLocationTransaction; OrderDetail orderDetail = orderLocationTransaction.OrderDetail; OrderHead orderHead = orderDetail.OrderHead; if (orderHead.CreateHuOption == BusinessConstants.CODE_MASTER_CREATE_HU_OPTION_VALUE_GR && receiptDetail.HuId == null) //如果订单设置为收货时创建Hu,但是收货时已经扫描过Hu了,按已扫描处理 { #region 收货时创建Hu log.Debug("Create receipt detail with generate barcode."); #region 生产本次收货+剩余零头生成Hu decimal oddQty = 0; if (!isOddCreateHu && orderDetail.HuLotSize.HasValue && orderHead.Type == BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PRODUCTION) //只有生产支持零头 { #region 查找剩余零头 + 本次收货数是否能够生成Hu Hu oddHu = this.CreateHuFromOdd(receiptDetail, user); if (oddHu != null) { log.Debug("Generate barcode using odd qty."); //如果零头生成了Hu,本次收货数会扣减 #region 创建Hu IList <Hu> oddHuList = new List <Hu>(); oddHuList.Add(oddHu); IList <ReceiptDetail> oddReceiptDetailList = this.receiptDetailMgr.CreateReceiptDetail(receipt, orderLocationTransaction, oddHuList); log.Debug("Generate odd barcode successful."); #endregion #region 入库 IList <InventoryTransaction> inventoryTransactionList = this.locationMgr.InventoryIn(oddReceiptDetailList[0], user, receiptDetail.PutAwayBinCode); log.Debug("odd Inventory in successful."); #endregion #region 是否检验 if (orderDetail.NeedInspection && orderHead.NeedInspection && orderHead.SubType == BusinessConstants.CODE_MASTER_ORDER_SUB_TYPE_VALUE_NML) { foreach (InventoryTransaction inventoryTransaction in inventoryTransactionList) { LocationLotDetail locationLotDetail = this.locationLotDetailMgr.LoadLocationLotDetail(inventoryTransaction.LocationLotDetailId); locationLotDetail.CurrentInspectQty = locationLotDetail.Qty; inspectLocationLotDetailList.Add(locationLotDetail); } } #endregion } #endregion oddQty = receiptDetail.ReceivedQty.HasValue && orderDetail.HuLotSize.HasValue ? receiptDetail.ReceivedQty.Value % orderDetail.HuLotSize.Value : 0; //收货零头数 log.Debug("Receive odd qty is " + oddQty); receiptDetail.ReceivedQty = receiptDetail.ReceivedQty.Value - oddQty; //收货数量凑整 } #endregion #region 满包装/零头创建Hu处理 if (receiptDetail.ReceivedQty.HasValue || receiptDetail.RejectedQty.HasValue || receiptDetail.ScrapQty.HasValue) { //创建Hu IList <Hu> huList = this.huMgr.CreateHu(receiptDetail, user); log.Debug("Create barcode successful."); //创建收货项 IList <ReceiptDetail> receiptDetailList = this.receiptDetailMgr.CreateReceiptDetail(receipt, orderLocationTransaction, huList); log.Debug("Create receipt detail successful."); #region 如果还有次品或者废品收货,添加到收货列表 if ((receiptDetail.RejectedQty.HasValue && receiptDetail.RejectedQty > 0) || (receiptDetail.ScrapQty.HasValue && receiptDetail.ScrapQty > 0)) { ReceiptDetail rejAndScrapReceiptDetail = new ReceiptDetail(); CloneHelper.CopyProperty(receiptDetail, rejAndScrapReceiptDetail); rejAndScrapReceiptDetail.ReceivedQty = null; rejAndScrapReceiptDetail.PutAwayBinCode = null; rejAndScrapReceiptDetail.Receipt = receipt; this.receiptDetailMgr.CreateReceiptDetail(rejAndScrapReceiptDetail); receiptDetailList.Add(rejAndScrapReceiptDetail); receipt.AddReceiptDetail(rejAndScrapReceiptDetail); } #endregion foreach (ReceiptDetail huReceiptDetail in receiptDetailList) { #region 匹配ReceiptDetail和InProcessLocationDetail,Copy相关信息 if (orderHead.Type != BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PRODUCTION) { IList <InProcessLocationDetail> matchInProcessLocationDetailList = OrderHelper.FindMatchInProcessLocationDetail(receiptDetail, inProcessLocationDetailList); if (matchInProcessLocationDetailList != null && matchInProcessLocationDetailList.Count > 0) { if (matchInProcessLocationDetailList.Count > 1) { //只有当ASN中包含条码,按数量收货,并收货后创建条码才有可能发生这种情况。 //变态才这么干。 log.Error("只有当ASN中包含条码,按数量收货,并收货后创建条码才有可能发生这种情况。"); throw new BusinessErrorException("你是变态才这么设置。"); } //如果找到匹配项,只可能有一个 huReceiptDetail.PlannedBill = matchInProcessLocationDetailList[0].PlannedBill; huReceiptDetail.IsConsignment = matchInProcessLocationDetailList[0].IsConsignment; huReceiptDetail.ShippedQty = matchInProcessLocationDetailList[0].Qty; this.receiptDetailMgr.UpdateReceiptDetail(huReceiptDetail); } //收货创建HU,分配PlannedAmount,todo:考虑余数 huReceiptDetail.PlannedAmount = receiptDetail.PlannedAmount / receiptDetail.ReceivedQty.Value * huReceiptDetail.ReceivedQty.Value; } #endregion #region 入库 IList <InventoryTransaction> inventoryTransactionList = this.locationMgr.InventoryIn(huReceiptDetail, user, receiptDetail.PutAwayBinCode); log.Debug("Inventory in successful."); #endregion #region 是否检验 if (orderDetail.NeedInspection && orderHead.NeedInspection && orderHead.SubType == BusinessConstants.CODE_MASTER_ORDER_SUB_TYPE_VALUE_NML && huReceiptDetail.ReceivedQty.HasValue && huReceiptDetail.ReceivedQty > 0) { foreach (InventoryTransaction inventoryTransaction in inventoryTransactionList) { if (inventoryTransaction.Location.Code != BusinessConstants.SYSTEM_LOCATION_REJECT) { LocationLotDetail locationLotDetail = this.locationLotDetailMgr.LoadLocationLotDetail(inventoryTransaction.LocationLotDetailId); locationLotDetail.CurrentInspectQty = inventoryTransaction.Qty; inspectLocationLotDetailList.Add(locationLotDetail); } } } #endregion } } #endregion #region 生产剩余零头处理 if (oddQty > 0) { log.Debug("Start handle odd qty."); ReceiptDetail oddReceiptDetail = new ReceiptDetail(); CloneHelper.CopyProperty(receiptDetail, oddReceiptDetail); oddReceiptDetail.ReceivedQty = oddQty; oddReceiptDetail.RejectedQty = 0; oddReceiptDetail.ScrapQty = 0; #region 零头入库 oddReceiptDetail.Receipt = receipt; IList <InventoryTransaction> inventoryTransactionList = this.locationMgr.InventoryIn(oddReceiptDetail, user, receiptDetail.PutAwayBinCode); #endregion #region 零头创建收货明细 this.receiptDetailMgr.CreateReceiptDetail(oddReceiptDetail); receipt.AddReceiptDetail(oddReceiptDetail); #endregion #region 创建HuOdd LocationLotDetail locationLotDetail = locationLotDetailMgr.LoadLocationLotDetail(inventoryTransactionList[0].LocationLotDetailId); this.huOddMgr.CreateHuOdd(oddReceiptDetail, locationLotDetail, user); #endregion log.Debug("End handle odd qty."); } #endregion #endregion } else { #region 收货时不创建Hu log.Debug("Create receipt detail with no generate barcode."); #region 更新Hu上的OrderNo、ReceiptNo和AntiResloveHu if (receiptDetail.HuId != null && receiptDetail.HuId.Trim() != string.Empty) { Hu hu = this.huMgr.LoadHu(receiptDetail.HuId); bool isUpdated = false; if (hu.OrderNo == null || hu.ReceiptNo == null) { if (hu.OrderNo == null) { log.Debug("Update hu OrderNo " + orderHead.OrderNo + "."); hu.OrderNo = orderHead.OrderNo; } if (hu.ReceiptNo == null) { log.Debug("Update hu ReceiptNo " + receipt.ReceiptNo + "."); hu.ReceiptNo = receipt.ReceiptNo; } isUpdated = true; } if (hu.AntiResolveHu == null && orderHead.Type == BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PROCUREMENT) { hu.AntiResolveHu = orderHead.AntiResolveHu; isUpdated = true; } if (isUpdated) { this.huMgr.UpdateHu(hu); } } #endregion IList <ReceiptDetail> noCreateHuReceiptDetailList = new List <ReceiptDetail>(); #region 匹配ReceiptDetail和InProcessLocationDetail,Copy相关信息 log.Debug("Start match ReceiptDetail and InProcessLocationDetail."); if (orderHead.Type != BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PRODUCTION && orderHead.SubType != BusinessConstants.CODE_MASTER_ORDER_SUB_TYPE_VALUE_ADJ) //收货调整已经匹配过InProcessLocationDetail,不需要在匹配 { IList <InProcessLocationDetail> matchInProcessLocationDetailList = OrderHelper.FindMatchInProcessLocationDetail(receiptDetail, inProcessLocationDetailList); log.Debug("Find matched InProcessLocationDetailList, count = " + matchInProcessLocationDetailList != null ? matchInProcessLocationDetailList.Count : 0); if (matchInProcessLocationDetailList != null && matchInProcessLocationDetailList.Count == 1) { //一次收货对应一次发货。 log.Debug("one ipdet vs one receiptdet."); receiptDetail.PlannedBill = matchInProcessLocationDetailList[0].PlannedBill; receiptDetail.IsConsignment = matchInProcessLocationDetailList[0].IsConsignment; if (matchInProcessLocationDetailList[0].InProcessLocation.Type == BusinessConstants.CODE_MASTER_INPROCESS_LOCATION_TYPE_VALUE_GAP) { receiptDetail.ShippedQty = 0 - matchInProcessLocationDetailList[0].Qty; } else { receiptDetail.ShippedQty = matchInProcessLocationDetailList[0].Qty; } receiptDetail.ReceivedInProcessLocationDetail = matchInProcessLocationDetailList[0]; noCreateHuReceiptDetailList.Add(receiptDetail); } else if (matchInProcessLocationDetailList != null && matchInProcessLocationDetailList.Count > 1) { //一次收货对应多次发货。 //如:发货按条码,收货按数量。 log.Debug("multi ipdet vs one receiptdet."); decimal totalRecQty = receiptDetail.ReceivedQty.Value; InProcessLocationDetail lastInProcessLocationDetail = null; log.Debug("Start Fetch matched InProcessLocationDetailList."); foreach (InProcessLocationDetail inProcessLocationDetail in matchInProcessLocationDetailList) { lastInProcessLocationDetail = inProcessLocationDetail; //记录最后一次发货项,供没有对应发货的收货项使用 if (inProcessLocationDetail.ReceivedQty.HasValue && Math.Abs(inProcessLocationDetail.ReceivedQty.Value) >= Math.Abs(inProcessLocationDetail.Qty)) { continue; } if (Math.Abs(totalRecQty) > 0) { log.Debug("Start cloned ReceiptDetail."); ReceiptDetail clonedReceiptDetail = new ReceiptDetail(); CloneHelper.CopyProperty(receiptDetail, clonedReceiptDetail); log.Debug("End cloned ReceiptDetail."); clonedReceiptDetail.PlannedBill = inProcessLocationDetail.PlannedBill; clonedReceiptDetail.IsConsignment = inProcessLocationDetail.IsConsignment; #region if (matchInProcessLocationDetailList[0].InProcessLocation.Type == BusinessConstants.CODE_MASTER_INPROCESS_LOCATION_TYPE_VALUE_GAP) { inProcessLocationDetail.Qty = 0 - inProcessLocationDetail.Qty; } #endregion if (Math.Abs(totalRecQty) > Math.Abs(inProcessLocationDetail.Qty - (inProcessLocationDetail.ReceivedQty.HasValue ? inProcessLocationDetail.ReceivedQty.Value : decimal.Zero))) { clonedReceiptDetail.ReceivedQty = inProcessLocationDetail.Qty - (inProcessLocationDetail.ReceivedQty.HasValue ? inProcessLocationDetail.ReceivedQty.Value : decimal.Zero); clonedReceiptDetail.ShippedQty = inProcessLocationDetail.Qty - (inProcessLocationDetail.ReceivedQty.HasValue ? inProcessLocationDetail.ReceivedQty.Value : decimal.Zero); totalRecQty -= inProcessLocationDetail.Qty - (inProcessLocationDetail.ReceivedQty.HasValue ? inProcessLocationDetail.ReceivedQty.Value : decimal.Zero); } else { clonedReceiptDetail.ReceivedQty = totalRecQty; clonedReceiptDetail.ShippedQty = totalRecQty; totalRecQty = 0; } //因为去掉了数量,记录已经匹配的发货项,避免差异处理的时候匹配多条而产生差异。 clonedReceiptDetail.ReceivedInProcessLocationDetail = inProcessLocationDetail; noCreateHuReceiptDetailList.Add(clonedReceiptDetail); } else { break; } } log.Debug("End Fetch matched InProcessLocationDetailList."); //超收,没有找到对应的发货项,只记录收货数,发货数记0 if (Math.Abs(totalRecQty) > 0) { ReceiptDetail clonedReceiptDetail = new ReceiptDetail(); CloneHelper.CopyProperty(receiptDetail, clonedReceiptDetail); clonedReceiptDetail.ShippedQty = 0; clonedReceiptDetail.ReceivedQty = totalRecQty; clonedReceiptDetail.ReceivedInProcessLocationDetail = lastInProcessLocationDetail; noCreateHuReceiptDetailList.Add(clonedReceiptDetail); } } else { noCreateHuReceiptDetailList.Add(receiptDetail); } } else { noCreateHuReceiptDetailList.Add(receiptDetail); } log.Debug("End match ReceiptDetail and InProcessLocationDetail."); #endregion foreach (ReceiptDetail noCreateHuReceiptDetail in noCreateHuReceiptDetailList) { noCreateHuReceiptDetail.Receipt = receipt; if (noCreateHuReceiptDetail.ReceivedQty != 0) { #region 入库 log.Debug("Start Inventory In."); IList <InventoryTransaction> inventoryTransactionList = this.locationMgr.InventoryIn(noCreateHuReceiptDetail, user, noCreateHuReceiptDetail.PutAwayBinCode); log.Debug("End Inventory In."); #endregion #region 是否检验 if (orderDetail.NeedInspection && orderHead.NeedInspection && inventoryTransactionList != null && inventoryTransactionList.Count > 0 && orderHead.SubType == BusinessConstants.CODE_MASTER_ORDER_SUB_TYPE_VALUE_NML) { foreach (InventoryTransaction inventoryTransaction in inventoryTransactionList) { if (inventoryTransaction.Location.Code != BusinessConstants.SYSTEM_LOCATION_REJECT) { LocationLotDetail locationLotDetail = this.locationLotDetailMgr.LoadLocationLotDetail(inventoryTransaction.LocationLotDetailId); locationLotDetail.CurrentInspectQty = inventoryTransaction.Qty; inspectLocationLotDetailList.Add(locationLotDetail); } } } #endregion } #region 创建收货明细 log.Debug("Start Create Receipt Detail."); this.receiptDetailMgr.CreateReceiptDetail(noCreateHuReceiptDetail); receipt.AddReceiptDetail(noCreateHuReceiptDetail); log.Debug("End Create Receipt Detail."); #endregion } #endregion } } #endregion #region 检验 if (inspectLocationLotDetailList.Count > 0) { //对于没有Hu的,如果收货时已经回冲了负数库存,也就是库存数量和待检验数量不一致可能会有问题 //增加ipno,receiptno,isseperated字段 this.inspectOrderMgr.CreateInspectOrder(inspectLocationLotDetailList, user, receipt.InProcessLocations[0].IpNo, receipt.ReceiptNo, false); } #endregion //#region 匹配收货发货项,查找差异 //IList<InProcessLocationDetail> gapInProcessLocationDetailList = new List<InProcessLocationDetail>(); //#region 发货项不匹配 //foreach (InProcessLocationDetail inProcessLocationDetail in inProcessLocationDetailList) //{ // if (inProcessLocationDetail.OrderLocationTransaction.OrderDetail.OrderHead.Type // != BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PRODUCTION) //生产暂时不支持差异 // { // decimal receivedQty = 0; //发货项的累计收货数 // //一条发货项可能对应多条收货项 // foreach (ReceiptDetail receiptDetail in receipt.ReceiptDetails) // { // //匹配收货项和发货项 // if (receiptDetail.ReceivedInProcessLocationDetail != null) // { // //对于已经匹配的,直接按发货项匹配 // if (receiptDetail.ReceivedInProcessLocationDetail.Id == inProcessLocationDetail.Id) // { // if (receiptDetail.ReceivedQty.HasValue) // { // receivedQty += receiptDetail.ReceivedQty.Value; // } // } // } // else if (OrderHelper.IsInProcessLocationDetailMatchReceiptDetail( // inProcessLocationDetail, receiptDetail)) // { // if (receiptDetail.ReceivedQty.HasValue) // { // receivedQty += receiptDetail.ReceivedQty.Value; // } // } // } // if (receivedQty != inProcessLocationDetail.Qty) // { // #region 收货数量和发货数量不匹配,记录差异 // InProcessLocationDetail gapInProcessLocationDetail = new InProcessLocationDetail(); // gapInProcessLocationDetail.Qty = receivedQty - inProcessLocationDetail.Qty; // gapInProcessLocationDetail.OrderLocationTransaction = inProcessLocationDetail.OrderLocationTransaction; // //gapInProcessLocationDetail.HuId = inProcessLocationDetail.HuId; // gapInProcessLocationDetail.LotNo = inProcessLocationDetail.LotNo; // gapInProcessLocationDetail.IsConsignment = inProcessLocationDetail.IsConsignment; // gapInProcessLocationDetail.PlannedBill = inProcessLocationDetail.PlannedBill; // gapInProcessLocationDetailList.Add(gapInProcessLocationDetail); // #endregion // } // } //} //#endregion //#region 收货项不匹配 //foreach (ReceiptDetail receiptDetail in receipt.ReceiptDetails) //{ // if (receiptDetail.OrderLocationTransaction.OrderDetail.OrderHead.Type // != BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PRODUCTION) //生产暂时不支持差异 // { // IList<InProcessLocationDetail> matchInProcessLocationDetailList = OrderHelper.FindMatchInProcessLocationDetail(receiptDetail, inProcessLocationDetailList); // if (matchInProcessLocationDetailList == null || matchInProcessLocationDetailList.Count == 0) // { // OrderLocationTransaction outOrderLocationTransaction = // this.orderLocationTransactionMgr.GetOrderLocationTransaction(receiptDetail.OrderLocationTransaction.OrderDetail, BusinessConstants.IO_TYPE_OUT)[0]; // #region 没有找到和收货项对应的发货项 // InProcessLocationDetail gapInProcessLocationDetail = new InProcessLocationDetail(); // gapInProcessLocationDetail.Qty = receiptDetail.ReceivedQty.Value; // gapInProcessLocationDetail.OrderLocationTransaction = outOrderLocationTransaction; // //gapInProcessLocationDetail.HuId = receiptDetail.HuId; // gapInProcessLocationDetail.LotNo = receiptDetail.LotNo; // gapInProcessLocationDetail.IsConsignment = receiptDetail.IsConsignment; // gapInProcessLocationDetail.PlannedBill = receiptDetail.PlannedBill; // gapInProcessLocationDetailList.Add(gapInProcessLocationDetail); // #endregion // } // } //} //#endregion //#endregion #region 关闭InProcessLocation if (receipt.InProcessLocations != null && receipt.InProcessLocations.Count > 0) { foreach (InProcessLocation inProcessLocation in receipt.InProcessLocations) { if (inProcessLocation.IsAsnUniqueReceipt) { //不支持多次收货直接关闭 this.inProcessLocationMgr.CloseInProcessLocation(inProcessLocation, user); } else { this.inProcessLocationMgr.TryCloseInProcessLocation(inProcessLocation, user); } //transportationOrderMgr.TryCompleteTransportationOrder(inProcessLocation, user); } } #endregion }
public IList <Bill> CreateBill(IList <ActingBill> actingBillList, User user, string status, decimal discount) { if (status != BusinessConstants.CODE_MASTER_STATUS_VALUE_CREATE && status != BusinessConstants.CODE_MASTER_STATUS_VALUE_SUBMIT && status != BusinessConstants.CODE_MASTER_STATUS_VALUE_CLOSE) { throw new TechnicalException("status specified is not valided"); } if (actingBillList == null || actingBillList.Count == 0) { throw new BusinessErrorException("Bill.Error.EmptyBillDetails"); } DateTime dateTimeNow = DateTime.Now; IList <Bill> billList = new List <Bill>(); foreach (ActingBill actingBill in actingBillList) { ActingBill oldActingBill = this.actingBillMgr.LoadActingBill(actingBill.Id); oldActingBill.CurrentBillQty = actingBill.CurrentBillQty; oldActingBill.CurrentDiscount = actingBill.CurrentDiscount; ////检查ActingBill的剩余待开数量是否为0 //if (oldActingBill.Qty - oldActingBill.BilledQty == 0) //{ // throw new BusinessErrorException("Bill.Create.Error.ZeroActingBillRemainQty"); //} Bill bill = null; #region 查找和待开明细的transactionType、billAddress、currency一致的BillMstr foreach (Bill thisBill in billList) { if (thisBill.TransactionType == oldActingBill.TransactionType && thisBill.BillAddress.Code == oldActingBill.BillAddress.Code && thisBill.Currency.Code == oldActingBill.Currency.Code) { bill = thisBill; break; } } #endregion #region 没有找到匹配的Bill,新建 if (bill == null) { #region 检查权限 bool hasPermission = false; if (user.Code == BusinessConstants.SYSTEM_USER_MONITOR) { hasPermission = true; } else { foreach (Permission permission in user.OrganizationPermission) { if (permission.Code == oldActingBill.BillAddress.Party.Code) { hasPermission = true; break; } } } if (!hasPermission) { throw new BusinessErrorException("Bill.Create.Error.NoAuthrization", oldActingBill.BillAddress.Party.Code); } #endregion #region 创建Bill bill = new Bill(); bill.BillNo = numberControlMgr.GenerateNumber(BusinessConstants.CODE_PREFIX_BILL); bill.Status = status; bill.TransactionType = oldActingBill.TransactionType; bill.BillAddress = oldActingBill.BillAddress; bill.Currency = oldActingBill.Currency; bill.Discount = discount; //可能有问题 bill.BillType = BusinessConstants.CODE_MASTER_BILL_TYPE_VALUE_NORMAL; bill.CreateDate = dateTimeNow; bill.CreateUser = user; bill.LastModifyDate = dateTimeNow; bill.LastModifyUser = user; bill.HasProvEst = false; this.CreateBill(bill); billList.Add(bill); #endregion } #endregion BillDetail billDetail = this.billDetailMgr.TransferAtingBill2BillDetail(oldActingBill); billDetail.Bill = bill; bill.AddBillDetail(billDetail); #region 更新头上暂估表及 if (billDetail.IsProvEst && !bill.HasProvEst) { bill.HasProvEst = true; bill.LastModifyDate = dateTimeNow; bill.LastModifyUser = user; this.UpdateBill(bill); } #endregion this.billDetailMgr.CreateBillDetail(billDetail); //扣减ActingBill数量和金额 this.actingBillMgr.ReverseUpdateActingBill(null, billDetail, user); } return(billList); }
private Repack CreateRepack(IList <RepackDetail> repackDetailList, string type, User user) { IList <RepackDetail> inRepackDetailList = new List <RepackDetail>(); IList <RepackDetail> outRepackDetailList = new List <RepackDetail>(); bool hasHu = false; #region 判断RepackDetailList是否为空 if (repackDetailList != null && repackDetailList.Count > 0) { foreach (RepackDetail repackDetail in repackDetailList) { if (repackDetail.Qty != 0) { if (repackDetail.IOType == BusinessConstants.IO_TYPE_IN) { inRepackDetailList.Add(repackDetail); } else if (repackDetail.IOType == BusinessConstants.IO_TYPE_OUT) { outRepackDetailList.Add(repackDetail); if (!hasHu && repackDetail.Hu != null) { hasHu = true; } } else { throw new TechnicalException("Invalid IO Type:" + repackDetail.IOType); } } } #region 翻箱的如果没有输出,将输入代码合并,生成一张新条码 if (outRepackDetailList.Count == 0 && type == BusinessConstants.CODE_MASTER_REPACK_TYPE_VALUE_REPACK) { Hu inHu = inRepackDetailList[0].Hu; Hu outHu = new Hu(); CloneHelper.CopyProperty(inHu, outHu); outHu.OrderNo = null; outHu.ReceiptNo = null; outHu.Location = null; outHu.StorageBin = null; outHu.Status = BusinessConstants.CODE_MASTER_STATUS_VALUE_CREATE; string repackShift = entityPreferenceMgr.LoadEntityPreference(BusinessConstants.ENTITY_PREFERENCE_CODE_REPACK_SHIFT).Value; string prefix = inHu.HuId.Substring(0, inHu.HuId.Length - 4) + repackShift; outHu.HuId = numberControlMgr.GenerateNumber(prefix, 3); outHu.Qty = (from l in inRepackDetailList select l.Qty).Sum(); outHu.UnitCount = outHu.Qty; outHu.LotSize = outHu.UnitCount; outHu.PrintCount = 0; huMgr.CreateHu(outHu); RepackDetail outRepackDetail = new RepackDetail(); outRepackDetail.Hu = outHu; outRepackDetail.IOType = BusinessConstants.IO_TYPE_OUT; outRepackDetail.Qty = outHu.Qty; outRepackDetail.itemCode = outHu.Item.Code; outRepackDetailList.Add(outRepackDetail); } #endregion if (inRepackDetailList.Count == 0 || outRepackDetailList.Count == 0) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.RepackDetailEmpty"); } if (hasHu && type == BusinessConstants.CODE_MASTER_REPACK_TYPE_VALUE_DEVANNING && outRepackDetailList.Count < 2) { throw new BusinessErrorException("MasterData.Inventory.Devanning.Error.DevanningDetailLessThanTwo"); } } else { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.RepackDetailEmpty"); } #endregion #region 判断是否被拣货 foreach (RepackDetail inRepackDetail in inRepackDetailList) { if (inRepackDetail.LocationLotDetail.Hu != null && this.locationMgr.IsHuOcuppyByPickList(inRepackDetail.LocationLotDetail.Hu.HuId)) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.HuOccupied", inRepackDetail.Hu.HuId); } } #endregion #region 判断翻箱后条码是否为新条码 foreach (RepackDetail outRepackDetail in outRepackDetailList) { if (outRepackDetail.Hu != null && outRepackDetail.Hu.Status != BusinessConstants.CODE_MASTER_STATUS_VALUE_CREATE) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.HuStatusNotCreate", outRepackDetail.Hu.HuId); } } #endregion #region 检查In和Out明细数量是否匹配 IDictionary <string, decimal> inItemQtyDic = new Dictionary <string, decimal>(); Location location = null; #region 收集In数量 foreach (RepackDetail inRepackDetail in inRepackDetailList) { LocationLotDetail inLocationLotDetail = this.locationLotDetailMgr.LoadLocationLotDetail(inRepackDetail.LocationLotDetail.Id); if (location == null) { location = inLocationLotDetail.Location; if (!user.HasPermission(inLocationLotDetail.Location.Region.Code)) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.NoPermission", location.Code); } } else if (location.Code != inLocationLotDetail.Location.Code) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.InRepackDetailLocationNotEqual"); } if (inItemQtyDic.ContainsKey(inLocationLotDetail.Item.Code)) { inItemQtyDic[inLocationLotDetail.Item.Code] += inRepackDetail.Qty; } else { inItemQtyDic.Add(inLocationLotDetail.Item.Code, inRepackDetail.Qty); } } #endregion #region 收集Out数量 IDictionary <string, decimal> outItemQtyDic = new Dictionary <string, decimal>(); foreach (RepackDetail outRepackDetail in outRepackDetailList) { if (type == BusinessConstants.CODE_MASTER_REPACK_TYPE_VALUE_REPACK) { if (outRepackDetail.Hu == null) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.HuIdIsEmpty"); } else { if (outItemQtyDic.ContainsKey(outRepackDetail.Hu.Item.Code)) { outItemQtyDic[outRepackDetail.Hu.Item.Code] += outRepackDetail.Qty; } else { outItemQtyDic.Add(outRepackDetail.Hu.Item.Code, outRepackDetail.Qty); } } } else if (type == BusinessConstants.CODE_MASTER_REPACK_TYPE_VALUE_DEVANNING) { string itemCode = outRepackDetail.Hu != null ? outRepackDetail.Hu.Item.Code : outRepackDetail.itemCode; if (itemCode == null) { throw new TechnicalException("ItemCode not specified."); } if (outItemQtyDic.ContainsKey(itemCode)) { outItemQtyDic[itemCode] += outRepackDetail.Qty; } else { outItemQtyDic.Add(itemCode, outRepackDetail.Qty); } } else { throw new TechnicalException("Repack type: " + type + " is not valided."); } } #endregion #region 比较 if (inItemQtyDic.Count != outItemQtyDic.Count) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.InOutQtyNotMatch"); } foreach (string itemCode in inItemQtyDic.Keys) { if (outItemQtyDic.ContainsKey(itemCode)) { decimal inQty = inItemQtyDic[itemCode]; decimal outQty = outItemQtyDic[itemCode]; //是否自动创建剩余数量的记录 bool autoCreate = bool.Parse(entityPreferenceMgr.LoadEntityPreference(BusinessConstants.ENTITY_PREFERENCE_CODE_AUTO_CREATE_WHEN_DEAVING).Value); #region 拆箱根据剩余数量得到剩余数量的条码 if (autoCreate && type == BusinessConstants.CODE_MASTER_REPACK_TYPE_VALUE_DEVANNING && inQty > outQty) { RepackDetail remainRepackDetail = CloneHelper.DeepClone(inRepackDetailList[0]); remainRepackDetail.Qty = inQty - outQty; remainRepackDetail.IOType = BusinessConstants.IO_TYPE_OUT; outRepackDetailList.Add(remainRepackDetail); } #endregion else if (inQty != outQty) { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.InOutQtyNotMatch"); } } else { throw new BusinessErrorException("MasterData.Inventory.Repack.Error.InOutItemNotMatch", itemCode); } } #endregion #endregion #region 创建翻箱单头 Repack repack = new Repack(); repack.RepackNo = this.numberControlMgr.GenerateNumber(BusinessConstants.CODE_PREFIX_REPACK); repack.CreateDate = DateTime.Now; repack.CreateUser = user; repack.Type = type; this.CreateRepack(repack); #endregion #region 创建翻箱单明细 Int32?plannedBillId = null; //拆箱传递PlannedBill foreach (RepackDetail inRepackDetail in inRepackDetailList) { //出库 inRepackDetail.Repack = repack; this.locationMgr.InventoryRepackIn(inRepackDetail, user); this.repackDetailMgr.CreateRepackDetail(inRepackDetail); if (repack.Type == BusinessConstants.CODE_MASTER_REPACK_TYPE_VALUE_DEVANNING) { plannedBillId = inRepackDetail.LocationLotDetail.IsConsignment ? inRepackDetail.LocationLotDetail.PlannedBill : null; } } foreach (RepackDetail outRepackDetail in outRepackDetailList) { //入库 outRepackDetail.Repack = repack; InventoryTransaction inventoryTransaction = this.locationMgr.InventoryRepackOut(outRepackDetail, location, plannedBillId, user); outRepackDetail.LocationLotDetail = this.locationLotDetailMgr.LoadLocationLotDetail(inventoryTransaction.LocationLotDetailId); this.repackDetailMgr.CreateRepackDetail(outRepackDetail); } #endregion return(repack); }
public IList <TransportationBill> CreateTransportationBill(IList <TransportationActBill> transportationActBillList, User user, string status, decimal discount) { if (status != BusinessConstants.CODE_MASTER_STATUS_VALUE_CREATE && status != BusinessConstants.CODE_MASTER_STATUS_VALUE_SUBMIT && status != BusinessConstants.CODE_MASTER_STATUS_VALUE_CLOSE) { throw new TechnicalException("status specified is not valided"); } if (transportationActBillList == null || transportationActBillList.Count == 0) { throw new BusinessErrorException("TransportationBill.Error.EmptyBillDetails"); } DateTime dateTimeNow = DateTime.Now; IList <TransportationBill> transportationBillList = new List <TransportationBill>(); foreach (TransportationActBill transportationActBill in transportationActBillList) { TransportationActBill oldTransportationActBill = this.transportationActBillMgr.LoadTransportationActBill(transportationActBill.Id); oldTransportationActBill.CurrentBillQty = transportationActBill.CurrentBillQty; oldTransportationActBill.CurrentBillAmount = transportationActBill.CurrentBillAmount; oldTransportationActBill.CurrentDiscount = transportationActBill.CurrentDiscount; TransportationBill transportationBill = null; #region 查找和待开明细的billAddress、currency一致的TransportationBillMstr foreach (TransportationBill thisTransportationBill in transportationBillList) { if (thisTransportationBill.BillAddress.Code == oldTransportationActBill.BillAddress.Code && thisTransportationBill.Currency.Code == oldTransportationActBill.Currency.Code) { transportationBill = thisTransportationBill; break; } } #endregion #region 没有找到匹配的TransportationBill,新建 if (transportationBill == null) { #region 检查权限 bool hasPermission = false; foreach (Permission permission in user.OrganizationPermission) { if (permission.Code == oldTransportationActBill.BillAddress.Party.Code) { hasPermission = true; break; } } if (!hasPermission) { throw new BusinessErrorException("TransportationBill.Create.Error.NoAuthrization", oldTransportationActBill.BillAddress.Party.Code); } #endregion #region 创建TransportationBill transportationBill = new TransportationBill(); transportationBill.BillNo = numberControlMgr.GenerateNumber(BusinessConstants.CODE_PREFIX_TRANSPORTATIONBILL); transportationBill.Status = status; transportationBill.BillAddress = oldTransportationActBill.BillAddress; transportationBill.Currency = oldTransportationActBill.Currency; transportationBill.Discount = discount; //可能有问题 transportationBill.BillType = BusinessConstants.CODE_TRANSPORTATION_TRANSPORTATIONBILL_TYPE_VALUE_NORMAL; transportationBill.CreateDate = dateTimeNow; transportationBill.CreateUser = user; transportationBill.LastModifyDate = dateTimeNow; transportationBill.LastModifyUser = user; this.CreateTransportationBill(transportationBill); transportationBillList.Add(transportationBill); #endregion } #endregion TransportationBillDetail transportationBillDetail = this.transportationBillDetailMgr.TransferTransportationActBill2TransportationBillDetail(oldTransportationActBill); transportationBillDetail.Bill = transportationBill; transportationBill.AddTransportationBillDetail(transportationBillDetail); this.transportationBillDetailMgr.CreateTransportationBillDetail(transportationBillDetail); //扣减TransportationActBill数量和金额 this.transportationActBillMgr.ReverseUpdateTransportationActBill(null, transportationBillDetail, user); } return(transportationBillList); }
public PickList CreatePickList(IList <OrderLocationTransaction> orderLocationTransactionList, User user) { List <OrderLocationTransaction> targetOrderLocationTransactionList = new List <OrderLocationTransaction>(); OrderLocationTransactionComparer orderLocationTransactionComparer = new OrderLocationTransactionComparer(); if (orderLocationTransactionList != null && orderLocationTransactionList.Count > 0) { foreach (OrderLocationTransaction orderLocationTransaction in orderLocationTransactionList) { if (orderLocationTransaction.CurrentShipQty > 0) { targetOrderLocationTransactionList.Add(orderLocationTransaction); } } } if (targetOrderLocationTransactionList.Count == 0) { throw new BusinessErrorException("Order.Error.PickUp.DetailEmpty"); } else { //按FromLocation、零件号、单位、单包装排序 targetOrderLocationTransactionList.Sort(orderLocationTransactionComparer); } string orderType = null; Party partyFrom = null; Party partyTo = null; ShipAddress shipFrom = null; ShipAddress shipTo = null; string dockDescription = null; bool? isShipScanHu = null; bool? isReceiptScanHu = null; bool? isAutoReceive = null; decimal? completeLatency = null; string grGapTo = null; string asnTemplate = null; string receiptTemplate = null; string flow = null; DateTime? windowTime = null; bool? isAsnUniqueReceipt = null; #region 判断OrderHead的PartyFrom, PartyTo, ShipFrom, ShipTo, DockDescription是否一致 foreach (OrderLocationTransaction orderLocationTransaction in targetOrderLocationTransactionList) { OrderDetail orderDetail = orderLocationTransaction.OrderDetail; OrderHead orderHead = orderDetail.OrderHead; //判断OrderHead的Type是否一致 if (orderType == null) { orderType = orderHead.Type; } else if (orderHead.Type != orderType) { throw new BusinessErrorException("Order.Error.PickUp.OrderTypeNotEqual"); } //判断OrderHead的PartyFrom是否一致 if (partyFrom == null) { partyFrom = orderHead.PartyFrom; } else if (orderHead.PartyFrom.Code != partyFrom.Code) { throw new BusinessErrorException("Order.Error.PickUp.PartyFromNotEqual"); } //判断OrderHead的PartyFrom是否一致 if (partyTo == null) { partyTo = orderHead.PartyTo; } else if (orderHead.PartyTo.Code != partyTo.Code) { throw new BusinessErrorException("Order.Error.PickUp.PartyToNotEqual"); } //判断OrderHead的ShipFrom是否一致 if (shipFrom == null) { shipFrom = orderHead.ShipFrom; } else if (!AddressHelper.IsAddressEqual(orderHead.ShipFrom, shipFrom)) { throw new BusinessErrorException("Order.Error.PickUp.ShipFromNotEqual"); } //判断OrderHead的ShipTo是否一致 if (shipTo == null) { shipTo = orderHead.ShipTo; } else if (!AddressHelper.IsAddressEqual(orderHead.ShipTo, shipTo)) { throw new BusinessErrorException("Order.Error.PickUp.ShipToNotEqual"); } //判断OrderHead的DockDescription是否一致 if (dockDescription == null) { dockDescription = orderHead.DockDescription; } else if (orderHead.DockDescription != dockDescription) { throw new BusinessErrorException("Order.Error.PickUp.DockDescriptionNotEqual"); } //判断OrderHead的IsShipScanHu是否一致 if (isShipScanHu == null) { isShipScanHu = orderHead.IsShipScanHu; } else if (orderHead.IsShipScanHu != isShipScanHu) { throw new BusinessErrorException("Order.Error.PickUp.IsShipScanHuNotEqual"); } //判断OrderHead的IsReceiptScanHu是否一致 if (isReceiptScanHu == null) { isReceiptScanHu = orderHead.IsReceiptScanHu; } else if (orderHead.IsReceiptScanHu != isReceiptScanHu) { throw new BusinessErrorException("Order.Error.PickUp.IsReceiptScanHuNotEqual"); } //判断OrderHead的IsAutoReceipt是否一致 if (isAutoReceive == null) { isAutoReceive = orderHead.IsAutoReceive; } else if (orderHead.IsAutoReceive != isAutoReceive) { throw new BusinessErrorException("Order.Error.PickUp.IsAutoReceiveNotEqual"); } //判断OrderHead的CompleteLatency是否一致 if (completeLatency == null) { completeLatency = orderHead.CompleteLatency; } else { if (orderHead.CompleteLatency.HasValue && orderHead.CompleteLatency != completeLatency) { throw new BusinessErrorException("Order.Error.PickUp.CompleteLatencyNotEqual"); } } //判断OrderHead的GoodsReceiptGapTo是否一致 if (grGapTo == null) { grGapTo = orderHead.GoodsReceiptGapTo; } else { if (orderHead.GoodsReceiptGapTo != null && orderHead.GoodsReceiptGapTo != grGapTo) { throw new BusinessErrorException("Order.Error.PickUp.GoodsReceiptGapToNotEqual"); } } //判断OrderHead的AsnTemplate是否一致 if (asnTemplate == null) { asnTemplate = orderHead.AsnTemplate; } else { if (orderHead.AsnTemplate != null && orderHead.AsnTemplate != asnTemplate) { throw new BusinessErrorException("Order.Error.PickUp.AsnTemplateNotEqual"); } } //判断OrderHead的ReceiptTemplate是否一致 if (receiptTemplate == null) { receiptTemplate = orderHead.ReceiptTemplate; } else { if (orderHead.ReceiptTemplate != null && orderHead.ReceiptTemplate != receiptTemplate) { throw new BusinessErrorException("Order.Error.PickUp.ReceiptTemplateNotEqual"); } } //判断OrderHead的Flow是否一致 if (flow == null) { flow = orderHead.Flow; } else if (orderHead.Flow != flow) { //throw new BusinessErrorException("Order.Error.PickUp.FlowNotEqual"); } //寻找最小的WindowTime if (!windowTime.HasValue) { windowTime = orderHead.WindowTime; } else if (windowTime.Value > orderHead.WindowTime) { windowTime = orderHead.WindowTime; } //判断OrderHead的IsAsnUniqueReceipt是否一致 if (isAsnUniqueReceipt == null) { isAsnUniqueReceipt = orderHead.IsAsnUniqueReceipt; } else if (orderHead.IsAsnUniqueReceipt != isAsnUniqueReceipt) { throw new BusinessErrorException("Order.Error.PickUp.IsAsnUniqueReceiptNotEqual"); } } #endregion #region 创建捡货单头 DateTime dateTimeNow = DateTime.Now; PickList pickList = new PickList(); pickList.PickListNo = numberControlMgr.GenerateNumber(BusinessConstants.CODE_PREFIX_PICKLIST); pickList.Status = BusinessConstants.CODE_MASTER_STATUS_VALUE_SUBMIT; pickList.PickBy = this.entityPreferenceMgr.LoadEntityPreference(BusinessConstants.ENTITY_PREFERENCE_CODE_PICK_BY).Value; pickList.OrderType = orderType; pickList.PartyFrom = partyFrom; pickList.PartyTo = partyTo; pickList.ShipFrom = shipFrom; pickList.ShipTo = shipTo; pickList.DockDescription = dockDescription; pickList.CreateDate = dateTimeNow; pickList.CreateUser = user; pickList.LastModifyDate = dateTimeNow; pickList.LastModifyUser = user; pickList.IsShipScanHu = isShipScanHu.Value; pickList.IsReceiptScanHu = isReceiptScanHu.Value; pickList.IsAutoReceive = isAutoReceive.Value; pickList.CompleteLatency = completeLatency; pickList.GoodsReceiptGapTo = grGapTo; pickList.AsnTemplate = asnTemplate; pickList.ReceiptTemplate = receiptTemplate; pickList.Flow = flow; pickList.WindowTime = windowTime.Value; pickList.IsAsnUniqueReceipt = isAsnUniqueReceipt.Value; this.CreatePickList(pickList); #endregion #region 创建捡货单明细 int index = 0; IList <LocationLotDetail> locationLotDetailList = null; IList <LocationLotDetail> occupiedLocationLotDetailList = null; //捡货占用库存 for (int i = 0; i < targetOrderLocationTransactionList.Count; i++) { OrderLocationTransaction orderLocationTransaction = targetOrderLocationTransactionList[i]; //本次循环OrderLocationTransaction OrderLocationTransaction lastOrderLocationTransaction = i == 0 ? null : targetOrderLocationTransactionList[i - 1]; //上次OrderLocationTransaction List <PickListDetail> pickListDetailList = new List <PickListDetail>(); //本次生成的PickListDetail列表 OrderDetail orderDetail = orderLocationTransaction.OrderDetail; OrderHead orderHead = orderDetail.OrderHead; decimal shipQty = orderLocationTransaction.CurrentShipQty; //库存单位 #region 过量拣货判断 decimal pickedQty = 0; //其它拣货单的待拣货数量,只考虑Submit和InProcess状态 IList <PickListDetail> pickedPickListDetailList = this.pickListDetailMgr.GetPickedPickListDetail(orderLocationTransaction.Id); if (pickedPickListDetailList != null && pickedPickListDetailList.Count > 0) { foreach (PickListDetail pickListDetail in pickedPickListDetailList) { if (pickListDetail.PickList.Status == BusinessConstants.CODE_MASTER_STATUS_VALUE_SUBMIT || pickListDetail.PickList.Status == BusinessConstants.CODE_MASTER_STATUS_VALUE_INPROCESS) { pickedQty += pickListDetail.Qty; } } } //累计发货数量 + 待捡货数量 + 本次拣货数量 不能大于 订单数量 if ((orderLocationTransaction.AccumulateQty.HasValue ? orderLocationTransaction.AccumulateQty.Value : 0) + shipQty + pickedQty > orderLocationTransaction.OrderedQty) { throw new BusinessErrorException("MasterData.PickList.Error.PickExcceed", orderLocationTransaction.Item.Code); } #endregion //比较本次OrderLocationTransaction和上次OrderLocationTransaction,如果不相同需重新查找locationLotDetailList和重置index //为了处理订单合并捡货时,相同零件推荐的Hu/LotNo不重复问题 if (lastOrderLocationTransaction == null || orderLocationTransactionComparer.Compare(lastOrderLocationTransaction, orderLocationTransaction) == -1) { index = 0; #region 零头发货选项查询待拣货列表 string oddShipOption = orderDetail.OddShipOption; if (oddShipOption == null || oddShipOption.Trim() == string.Empty) { CodeMaster codeMaster = this.codeMasterMgr.GetDefaultCodeMaster(BusinessConstants.CODE_MASTER_ODD_SHIP_OPTION); oddShipOption = codeMaster.Value; } if (oddShipOption == BusinessConstants.CODE_MASTER_ODD_SHIP_OPTION_VALUE_SHIP_FIRST) { //零头优先发、LotnNo先进先出、货架、包装 if (orderHead.IsPickFromBin) { locationLotDetailList = this.locationLotDetailMgr.GetHuLocationLotDetail(orderLocationTransaction.Location.Code, null, null, null, orderDetail.Item.Code, null, false, null, orderDetail.Uom.Code, new string[] { "hu.ManufactureDate;Asc", "sb.Sequence;Asc", "Qty;Asc", "Id;Asc" }, orderHead.IsPickFromBin, true, null, null, true); } else { locationLotDetailList = this.locationLotDetailMgr.GetHuLocationLotDetail(orderLocationTransaction.Location.Code, null, null, null, orderDetail.Item.Code, null, false, null, orderDetail.Uom.Code, new string[] { "hu.ManufactureDate;Asc", "Qty;Asc", "Id;Asc" }, orderHead.IsPickFromBin, false, null, null, true); } #region 重新排序,把零头放在前面 if (locationLotDetailList != null && locationLotDetailList.Count > 0) { IList <LocationLotDetail> oddLocationLotDetailList = new List <LocationLotDetail>(); IList <LocationLotDetail> noOddLocationLotDetailList = new List <LocationLotDetail>(); foreach (LocationLotDetail locationLotDetail in locationLotDetailList) { if (!this.locationMgr.IsHuOcuppyByPickList(locationLotDetail.Hu.HuId)) { if (locationLotDetail.Hu.Qty < orderDetail.UnitCount) { oddLocationLotDetailList.Add(locationLotDetail); shipQty += locationLotDetail.Qty; //零头一定要先发走,不占用待拣货数量 } else { noOddLocationLotDetailList.Add(locationLotDetail); } } } locationLotDetailList = oddLocationLotDetailList; IListHelper.AddRange <LocationLotDetail>(locationLotDetailList, noOddLocationLotDetailList); } #endregion } else if (oddShipOption == BusinessConstants.CODE_MASTER_ODD_SHIP_OPTION_VALUE_NOT_SHIP) { //零头不发 if (orderHead.IsPickFromBin) { locationLotDetailList = this.locationLotDetailMgr.GetHuLocationLotDetail(orderLocationTransaction.Location.Code, null, null, null, orderDetail.Item.Code, null, false, orderDetail.UnitCount, orderDetail.Uom.Code, new string[] { "hu.ManufactureDate;Asc", "sb.Sequence;Asc", "Id;Asc" }, orderHead.IsPickFromBin, true); } else { locationLotDetailList = this.locationLotDetailMgr.GetHuLocationLotDetail(orderLocationTransaction.Location.Code, null, null, null, orderDetail.Item.Code, null, false, orderDetail.UnitCount, orderDetail.Uom.Code, new string[] { "hu.ManufactureDate;Asc", "Id;Asc" }, orderHead.IsPickFromBin, false); } } #endregion IList <PickListDetail> submitPickListDetailList = this.pickListDetailMgr.GetPickListDetail(orderLocationTransaction.Location.Code, orderDetail.Item.Code, orderDetail.UnitCount, orderDetail.Uom.Code, new string[] { BusinessConstants.CODE_MASTER_STATUS_VALUE_SUBMIT, BusinessConstants.CODE_MASTER_STATUS_VALUE_INPROCESS }); //IList<PickListResult> inprocessPickListResultList = this.pickListResultMgr.GetPickListResult(orderLocationTransaction.Location.Code, orderDetail.Item.Code, orderDetail.UnitCount, orderDetail.Uom.Code, new string[] { BusinessConstants.CODE_MASTER_STATUS_VALUE_INPROCESS }); occupiedLocationLotDetailList = this.Convert2OccupiedLocationLotDetail(submitPickListDetailList, pickList.PickBy); } if (locationLotDetailList != null && locationLotDetailList.Count > 0) { PickListDetail lastestPickListDetail = null; for (; index < locationLotDetailList.Count; index++) { LocationLotDetail locationLotDetail = locationLotDetailList[index]; decimal locQty = locationLotDetail.Qty; if (pickList.PickBy == BusinessConstants.CODE_MASTER_PICKBY_HU) { #region Hu捡货 #region 过滤掉已经被推荐的库存 if (occupiedLocationLotDetailList != null && occupiedLocationLotDetailList.Count > 0) { bool findMatch = false; foreach (LocationLotDetail occupiedLocationLotDetail in occupiedLocationLotDetailList) { if (occupiedLocationLotDetail.Hu.HuId == locationLotDetail.Hu.HuId) { findMatch = true; continue; } } if (findMatch) { continue; } } #endregion shipQty -= locQty; PickListDetail pickListDetail = new PickListDetail(); pickListDetail.PickList = pickList; pickListDetail.OrderLocationTransaction = orderLocationTransaction; pickListDetail.Item = orderLocationTransaction.Item; pickListDetail.UnitCount = orderDetail.UnitCount; pickListDetail.Uom = orderDetail.Uom; pickListDetail.HuId = locationLotDetail.Hu.HuId; pickListDetail.LotNo = locationLotDetail.LotNo; pickListDetail.Location = locationLotDetail.Location; if (locationLotDetail.StorageBin != null) { pickListDetail.StorageArea = locationLotDetail.StorageBin.Area; pickListDetail.StorageBin = locationLotDetail.StorageBin; } pickListDetail.Qty = locQty / orderLocationTransaction.UnitQty; //订单单位 this.pickListDetailMgr.CreatePickListDetail(pickListDetail); pickList.AddPickListDetail(pickListDetail); pickListDetailList.Add(pickListDetail); if (shipQty <= 0) { index++; break; } #endregion } else if (pickList.PickBy == BusinessConstants.CODE_MASTER_PICKBY_LOTNO) { #region LotNo捡货 #region 过滤掉已经被推荐的库存 if (occupiedLocationLotDetailList != null && occupiedLocationLotDetailList.Count > 0) { foreach (LocationLotDetail occupiedLocationLotDetail in occupiedLocationLotDetailList) { if (occupiedLocationLotDetail.Item.Code == locationLotDetail.Item.Code && occupiedLocationLotDetail.LotNo == locationLotDetail.LotNo && occupiedLocationLotDetail.Location.Code == locationLotDetail.Location.Code && StorageBinHelper.IsStorageBinEqual(occupiedLocationLotDetail.StorageBin, locationLotDetail.StorageBin)) { if (locationLotDetail.Hu.Qty < orderDetail.UnitCount) { shipQty -= locationLotDetail.Qty; //如果零头被占用,需要扣减发货数量 } if (occupiedLocationLotDetail.Qty == 0) { continue; } if (occupiedLocationLotDetail.Qty - locQty >= 0) { occupiedLocationLotDetail.Qty -= locQty; locQty = 0; continue; } else { occupiedLocationLotDetail.Qty = 0; locQty -= occupiedLocationLotDetail.Qty; break; } } } if (locQty == 0) { continue; } } #endregion shipQty -= locQty; if (shipQty < 0) { locQty += shipQty; shipQty = 0; } if (lastestPickListDetail != null && lastestPickListDetail.LotNo == locationLotDetail.LotNo && StorageBinHelper.IsStorageBinEqual(lastestPickListDetail.StorageBin, locationLotDetail.StorageBin)) { #region 合并捡货数量 lastestPickListDetail.Qty += locQty / orderLocationTransaction.UnitQty; //订单单位 this.pickListDetailMgr.UpdatePickListDetail(lastestPickListDetail); #endregion } else { #region 新增捡货明细 lastestPickListDetail = new PickListDetail(); lastestPickListDetail.PickList = pickList; lastestPickListDetail.OrderLocationTransaction = orderLocationTransaction; lastestPickListDetail.Item = orderLocationTransaction.Item; lastestPickListDetail.UnitCount = locationLotDetail.Hu.UnitCount; //可能拣货的包装和订单明细包装不一致,所以使用Hu上的单包装 lastestPickListDetail.Uom = orderDetail.Uom; lastestPickListDetail.LotNo = locationLotDetail.Hu.LotNo; lastestPickListDetail.Location = locationLotDetail.Location; if (locationLotDetail.StorageBin != null) { lastestPickListDetail.StorageArea = locationLotDetail.StorageBin.Area; lastestPickListDetail.StorageBin = locationLotDetail.StorageBin; } lastestPickListDetail.Qty = locQty / orderLocationTransaction.UnitQty; //订单单位 this.pickListDetailMgr.CreatePickListDetail(lastestPickListDetail); pickList.AddPickListDetail(lastestPickListDetail); pickListDetailList.Add(lastestPickListDetail); #endregion } if (shipQty <= 0) { index++; break; } #endregion } else { throw new TechnicalException("Invalied PickBy value:" + pickList.PickBy); } } } //if (pickListDetailList.Count == 0) //{ // throw new BusinessErrorException("MasterData.PickList.Error.NotEnoughInventory"); //} if (shipQty > 0) { PickListDetail pickListDetail = new PickListDetail(); pickListDetail.PickList = pickList; pickListDetail.OrderLocationTransaction = orderLocationTransaction; pickListDetail.Item = orderLocationTransaction.Item; pickListDetail.UnitCount = orderDetail.UnitCount; pickListDetail.Uom = orderDetail.Uom; pickListDetail.Location = orderLocationTransaction.Location; pickListDetail.Qty = shipQty / orderLocationTransaction.UnitQty; //订单单位 pickListDetail.Memo = this.languageMgr.TranslateMessage("MasterData.PickList.NotEnoughInventory", user); //设置Memo为库存不足 pickList.AddPickListDetail(pickListDetail); this.pickListDetailMgr.CreatePickListDetail(pickListDetail); } if (pickListDetailList.Count > 0 && pickList.PickBy == BusinessConstants.CODE_MASTER_PICKBY_LOTNO) { string lotNo = string.Empty; bool hasMultiLotNo = false; foreach (PickListDetail pickListDetail in pickListDetailList) { if (lotNo == string.Empty) { lotNo = pickListDetail.LotNo; } else if (lotNo != pickListDetail.LotNo) { hasMultiLotNo = true; break; } } //设置Memo为多批号 if (hasMultiLotNo) { foreach (PickListDetail pickListDetail in pickListDetailList) { if (pickListDetail.Memo == null || pickListDetail.Memo.Trim() == string.Empty) { pickListDetail.Memo = this.languageMgr.TranslateMessage("MasterData.PickList.MultiLotNo", user); } else { pickListDetail.Memo += "; " + this.languageMgr.TranslateMessage("MasterData.PickList.MultiLotNo", user); } this.pickListDetailMgr.UpdatePickListDetail(pickListDetail); } } } } #endregion //if (pickList.PickListDetails == null || pickList.PickListDetails.Count == 0) //{ // throw new BusinessErrorException("MasterData.PickList.Error.NotEnoughInventory"); //} return(pickList); }
public MiscOrder SaveMiscOrder(MiscOrder miscOrder, User user) { MiscOrder dbMiscOrder = null; if (miscOrder != null && miscOrder.OrderNo != null) { dbMiscOrder = miscOrderDao.LoadMiscOrder(miscOrder.OrderNo); } if (dbMiscOrder != null) { IList <MiscOrderDetail> dbMiscOrderDets = dbMiscOrder.MiscOrderDetails; foreach (MiscOrderDetail miscOrderDet in dbMiscOrderDets) { miscOrderDetailMgr.DeleteMiscOrderDetail(miscOrderDet); } MiscOrder pageMiscOrder = miscOrder; IList <MiscOrderDetail> pageMiscOrderDets = pageMiscOrder.MiscOrderDetails; foreach (MiscOrderDetail miscOrderDet in pageMiscOrderDets) { miscOrderDet.MiscOrder = pageMiscOrder; miscOrderDetailMgr.CreateMiscOrderDetail(miscOrderDet); } dbMiscOrder.Remark = pageMiscOrder.Remark; dbMiscOrder.Reason = pageMiscOrder.Reason; dbMiscOrder.EffectiveDate = pageMiscOrder.EffectiveDate; dbMiscOrder.Location = pageMiscOrder.Location; dbMiscOrder.CreateDate = DateTime.Now; miscOrderDao.UpdateMiscOrder(dbMiscOrder); } else { dbMiscOrder = miscOrder; dbMiscOrder.CreateUser = user; dbMiscOrder.CreateDate = DateTime.Now; dbMiscOrder.OrderNo = numberControlMgr.GenerateNumber(BusinessConstants.CODE_PREFIX_MISCO); miscOrderDao.CreateMiscOrder(dbMiscOrder); IList <MiscOrderDetail> pageMiscOrderDets = dbMiscOrder.MiscOrderDetails; foreach (MiscOrderDetail miscOrderDet in pageMiscOrderDets) { miscOrderDet.MiscOrder = dbMiscOrder; miscOrderDetailMgr.CreateMiscOrderDetail(miscOrderDet); //出入库 if (dbMiscOrder.Type == BusinessConstants.CODE_MASTER_MISC_ORDER_TYPE_VALUE_GI) { //出库 this.locationMgr.InventoryOut(miscOrderDet, user); } else if (dbMiscOrder.Type == BusinessConstants.CODE_MASTER_MISC_ORDER_TYPE_VALUE_GR) { //入库 this.locationMgr.InventoryIn(miscOrderDet, user); } else if (dbMiscOrder.Type == BusinessConstants.CODE_MASTER_MISC_ORDER_TYPE_VALUE_ADJ) { //用入库操作就可以做调整 this.locationMgr.InventoryIn(miscOrderDet, user); //if (miscOrderDet.Qty > 0) //{ // //入库 // this.locationMgr.InventoryIn(miscOrderDet, user); //} //else if (miscOrderDet.Qty < 0) //{ // //出库 // miscOrderDet.Qty = miscOrderDet.Qty * -1; //调整为正数 // this.locationMgr.InventoryOut(miscOrderDet, user); //} } else { throw new TechnicalException("MiscOrder Type:" + dbMiscOrder.Type + " is not valided"); } } } return(ReLoadMiscOrder(dbMiscOrder.OrderNo)); }