private ReceiptMaster ReceiveOrder(IList<OrderDetail> orderDetailList, bool isCheckKitTraceItem, ProductLineMap productLineMap, DateTime effectiveDate, string ipNo) { #region 判断是否全0收货 if (orderDetailList == null || orderDetailList.Count == 0) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveDetailIsEmpty); } IList<OrderDetail> nonZeroOrderDetailList = orderDetailList.Where(o => o.ReceiveQtyInput != 0 || o.ScrapQtyInput != 0).ToList(); if (nonZeroOrderDetailList.Count == 0) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveDetailIsEmpty); } #endregion #region 查询订单头对象 IList<OrderMaster> orderMasterList = LoadOrderMasters(nonZeroOrderDetailList.Select(p => p.OrderNo).Distinct(), true); #endregion #region 获取收货订单类型 IList<com.Sconit.CodeMaster.OrderType> orderTypeList = (from orderMaster in orderMasterList group orderMaster by orderMaster.Type into result select result.Key).ToList(); if (orderTypeList.Count > 1) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_CannotMixOrderTypeReceive); } com.Sconit.CodeMaster.OrderType orderType = orderTypeList.First(); #endregion #region 计划协议不能按收货校验 if (orderType == CodeMaster.OrderType.ScheduleLine) { throw new BusinessException("计划协议不能按订单收货。"); } #endregion #region 排序单不能按订单收货校验 if (orderMasterList.Where(o => o.OrderStrategy == CodeMaster.FlowStrategy.SEQ).Count() > 0) { throw new BusinessException("排序单不能按订单收货。"); } #endregion #region 循环订单头检查 foreach (OrderMaster orderMaster in orderMasterList) { //if (!Utility.SecurityHelper.HasPermission(orderMaster)) //{ // throw new BusinessException("没有此订单{0}的操作权限。", orderMaster.OrderNo); //} orderMaster.OrderDetails = nonZeroOrderDetailList.Where(det => det.OrderNo == orderMaster.OrderNo).ToList(); //如果非生产,把Submit状态改为InProcess if (orderMaster.Status == com.Sconit.CodeMaster.OrderStatus.Submit && orderMaster.Type != com.Sconit.CodeMaster.OrderType.Production && orderMaster.Type != com.Sconit.CodeMaster.OrderType.SubContract) { UpdateOrderMasterStatus2InProcess(orderMaster); } //判断OrderHead状态 if (orderMaster.Status != com.Sconit.CodeMaster.OrderStatus.InProcess) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_StatusErrorWhenReceive, orderMaster.OrderNo, systemMgr.GetCodeDetailDescription(com.Sconit.CodeMaster.CodeMaster.OrderStatus, ((int)orderMaster.Status).ToString())); } #region 订单、生产线暂停检查 if (orderMaster.IsPause) { if (orderMaster.Type == CodeMaster.OrderType.Production) { throw new BusinessException("生产单{0}已经暂停,不能收货。", orderMaster.OrderNo); } else if (orderMaster.OrderStrategy == CodeMaster.FlowStrategy.KIT) { throw new BusinessException("KIT单{0}已经暂停,不能收货。", orderMaster.OrderNo); } else if (orderMaster.OrderStrategy == CodeMaster.FlowStrategy.SEQ) { throw new BusinessException("排序单{0}已经暂停,不能收货。", orderMaster.OrderNo); } else { throw new BusinessException("订单{0}已经暂停,不能收货。", orderMaster.OrderNo); } } //if ((orderMaster.Type == CodeMaster.OrderType.Production // || orderMaster.Type == CodeMaster.OrderType.SubContract // //生产线暂停可以收货 // //|| orderMaster.OrderStrategy == CodeMaster.FlowStrategy.KIT // //|| orderMaster.OrderStrategy == CodeMaster.FlowStrategy.SEQ // ) // && !string.IsNullOrWhiteSpace(orderMaster.Flow)) //{ // FlowMaster flowMaster = this.genericMgr.FindById<FlowMaster>(orderMaster.Flow); // if (flowMaster.IsPause) // { // throw new BusinessException("生产线{0}已经暂停,不能收货。", orderMaster.Flow); // } //} #endregion #region 整包装收货判断,快速的不要判断 if (orderMaster.IsReceiveFulfillUC && orderMaster.SubType == com.Sconit.CodeMaster.OrderSubType.Normal && !(orderMaster.IsAutoRelease && orderMaster.IsAutoStart)) { foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { //不合格品不作为收货数 //if (orderDetail.ReceiveQualifiedQtyInput % orderDetail.UnitCount != 0) if (orderDetail.ReceiveQtyInput % orderDetail.UnitCount != 0) { //不是整包装 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyNotFulfillUnitCount, orderDetail.Item); } } } #endregion #region 是否过量发货判断,未发货即收货也要判断是否过量发货 foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { if (!orderMaster.IsOpenOrder && orderMaster.Type != com.Sconit.CodeMaster.OrderType.Production //生产和委外不需要判断 && orderMaster.Type != com.Sconit.CodeMaster.OrderType.SubContract) { if (Math.Abs(orderDetail.ShippedQty) > Math.Abs(orderDetail.OrderedQty)) { //订单的发货数已经大于等于订单数 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ShipQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } else if (!orderMaster.IsShipExceed && Math.Abs(orderDetail.ShippedQty + orderDetail.ReceiveQtyInput) > Math.Abs(orderDetail.OrderedQty)) //不允许过量收货 { //订单的发货数 + 本次发货数大于订单数 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ShipQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } } } #endregion #region 是否过量收货判断 foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { if (!orderMaster.IsOpenOrder) { var orderDeviationQty = decimal.MaxValue; if (!orderMaster.IsReceiveExceed) { orderDeviationQty = Math.Abs(orderDetail.OrderedQty); } else { if (orderMaster.CurrentFlowMaster.OrderDeviation > 0) { orderDeviationQty = Math.Abs(orderDetail.OrderedQty * (((decimal)orderMaster.CurrentFlowMaster.OrderDeviation / 100) + 1)); } } //订单的收货数已经大于等于订单数 if (Math.Abs(orderDetail.ReceivedQty) >= Math.Abs(orderDetail.OrderedQty)) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } else if (Math.Abs(orderDetail.ReceivedQty + orderDetail.RejectedQty + orderDetail.ScrapQty + orderDetail.ReceiveQtyInput + orderDetail.ScrapQtyInput) > orderDeviationQty) //不允许过量收货 { //订单的收货数 + 本次收货数大于订单数 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } } } #endregion #region KIT单收货判断 if (orderMaster.OrderStrategy == CodeMaster.FlowStrategy.KIT) { CheckKitOrderDetail(orderMaster, isCheckKitTraceItem, false); } #endregion } #endregion #region 校验发货先进先出 CheckShipFiFo(orderMasterList); #endregion #region 循环更新订单明细 foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { //未发货直接收货需要累加已发货数量 if (orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.Production && orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.SubContract) { orderDetail.ShippedQty += orderDetail.ReceiveQtyInput; } if (orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.Production && orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.SubContract) { //orderDetail.ReceivedQty += orderDetail.ReceiveQualifiedQtyInput; orderDetail.ReceivedQty += orderDetail.ReceiveQtyInput; } else { //生产收货更新合格数和不合格数量 //orderDetail.ReceivedQty += orderDetail.ReceiveQualifiedQtyInput; orderDetail.ReceivedQty += orderDetail.ReceiveQtyInput; orderDetail.ScrapQty += orderDetail.ScrapQtyInput; } genericMgr.Update(orderDetail); } #endregion #region 发货 #region OrderDetailInput赋发货数量 foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { foreach (OrderDetailInput orderDetailInput in orderDetail.OrderDetailInputs) { orderDetailInput.ShipQty = orderDetailInput.ReceiveQty; } } #endregion IpMaster ipMaster = null; var subType = orderMasterList.First().SubType; if ((orderType == com.Sconit.CodeMaster.OrderType.Production || orderType == com.Sconit.CodeMaster.OrderType.SubContract) && subType != CodeMaster.OrderSubType.Return) { //生产和委外的非退货单 } else { //物流单 生产和委外的退货单也要创建Ip ipMaster = this.ipMgr.TransferOrder2Ip(orderMasterList); #region 循环发货 foreach (IpDetail ipDetail in ipMaster.IpDetails) { ipDetail.CurrentPartyFrom = ipMaster.PartyFrom; //为了记录库存事务 ipDetail.CurrentPartyFromName = ipMaster.PartyFromName; //为了记录库存事务 ipDetail.CurrentPartyTo = ipMaster.PartyTo; //为了记录库存事务 ipDetail.CurrentPartyToName = ipMaster.PartyToName; //为了记录库存事务 //ipDetail.CurrentOccupyType = com.Sconit.CodeMaster.OccupyType.None; //todo-默认出库未占用库存,除非捡货或检验的出库 IList<InventoryTransaction> inventoryTransactionList = this.locationDetailMgr.InventoryOut(ipDetail, effectiveDate); #region 建立发货库明细和IpDetailInput的关系 if (inventoryTransactionList != null && inventoryTransactionList.Count > 0) { ipDetail.IpLocationDetails = (from trans in inventoryTransactionList group trans by new { HuId = trans.HuId, LotNo = trans.LotNo, IsCreatePlanBill = trans.IsCreatePlanBill, IsConsignment = trans.IsConsignment, PlanBill = trans.PlanBill, ActingBill = trans.ActingBill, QualityType = trans.QualityType, IsFreeze = trans.IsFreeze, IsATP = trans.IsATP, OccupyType = trans.OccupyType, OccupyReferenceNo = trans.OccupyReferenceNo } into g select new IpLocationDetail { HuId = g.Key.HuId, LotNo = g.Key.LotNo, IsCreatePlanBill = g.Key.IsCreatePlanBill, IsConsignment = g.Key.IsConsignment, PlanBill = g.Key.PlanBill, ActingBill = g.Key.ActingBill, QualityType = g.Key.QualityType, IsFreeze = g.Key.IsFreeze, IsATP = g.Key.IsATP, OccupyType = g.Key.OccupyType, OccupyReferenceNo = g.Key.OccupyReferenceNo, Qty = g.Sum(t => -t.Qty), //发货的库存事务为负数,转为收货数应该取负数 //PlanBillQty = g.Sum(t=>-t.PlanBillQty), //ActingBillQty = g.Sum(t=>-t.ActingBillQty) }).ToList(); } #endregion } #endregion #region 生成收货的IpInput foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { OrderMaster orderMaster = orderMasterList.Where(o => o.OrderNo == orderDetail.OrderNo).Single(); //订单收货一定是一条订单明细对应一条发货单明细 IpDetail ipDetail = ipMaster.IpDetails.Where(det => det.OrderDetailId == orderDetail.Id).Single(); ipDetail.IpDetailInputs = null; //清空Ip的发货数据,准备添加收货数据 foreach (OrderDetailInput orderDetailInput in orderDetail.OrderDetailInputs) { IpDetailInput ipDetailInput = new IpDetailInput(); ipDetailInput.ReceiveQty = orderDetailInput.ShipQty; if (orderMaster.IsReceiveScanHu || orderMaster.OrderStrategy == CodeMaster.FlowStrategy.KIT) { ipDetailInput.HuId = orderDetailInput.HuId; ipDetailInput.LotNo = orderDetailInput.LotNo; } ipDetail.AddIpDetailInput(ipDetailInput); } } if (orderMasterList.Where(o => o.OrderStrategy == CodeMaster.FlowStrategy.KIT).Count() > 0) { #region Kit单生成收货Input foreach (IpDetail ipDetail in ipMaster.IpDetails) { foreach (IpDetailInput ipDetailInput in ipDetail.IpDetailInputs) { if (!string.IsNullOrEmpty(ipDetailInput.HuId)) { #region 按条码匹配 IpLocationDetail matchedIpLocationDetail = ipDetail.IpLocationDetails.Where(locDet => locDet.HuId == ipDetailInput.HuId).SingleOrDefault(); matchedIpLocationDetail.ReceivedQty = matchedIpLocationDetail.Qty; if (matchedIpLocationDetail != null) { ipDetailInput.AddReceivedIpLocationDetail(matchedIpLocationDetail); } #endregion } else { #region 按数量匹配 IpDetail gapIpDetail = new IpDetail(); MatchIpDetailInput(ipDetail, ipDetailInput, ipDetail.IpLocationDetails, ref gapIpDetail); #endregion } } } #endregion } else { #region 其它订单生成收货Input if (ipMaster.IsShipScanHu && ipMaster.IsReceiveScanHu) { #region 按条码匹配 foreach (IpDetail ipDetail in ipMaster.IpDetails) { foreach (IpDetailInput ipDetailInput in ipDetail.IpDetailInputs) { IpLocationDetail matchedIpLocationDetail = ipDetail.IpLocationDetails.Where(locDet => locDet.HuId == ipDetailInput.HuId).SingleOrDefault(); matchedIpLocationDetail.ReceivedQty = matchedIpLocationDetail.Qty; if (matchedIpLocationDetail != null) { ipDetailInput.AddReceivedIpLocationDetail(matchedIpLocationDetail); } } } #endregion } else { #region 按数量匹配 foreach (IpDetail ipDetail in ipMaster.IpDetails) { CycleMatchIpDetailInput(ipDetail, ipDetail.IpDetailInputs, ipDetail.IpLocationDetails); } #endregion } #endregion } #endregion } #endregion #region 收货 生产和委外退货的逻辑在CreateReceipt中实现 ReceiptMaster receiptMaster = null; if (subType != CodeMaster.OrderSubType.Return && (orderType == com.Sconit.CodeMaster.OrderType.Production || orderType == com.Sconit.CodeMaster.OrderType.SubContract)) { #region 生产和委外正常收货 消耗原材料,收成品 if (orderMasterList.Count > 1 && orderType == com.Sconit.CodeMaster.OrderType.Production) { throw new TechnicalException("生产单不能合并收货。"); } foreach (OrderMaster orderMaster in orderMasterList) { orderMaster.IpNo = ipNo; receiptMaster = this.receiptMgr.TransferOrder2Receipt(orderMaster); this.receiptMgr.CreateReceipt(receiptMaster); #region 回冲物料 if (productLineMap != null) { #region 整车 BackflushVan(productLineMap, nonZeroOrderDetailList, receiptMaster, orderMaster); #endregion } else { #region 非整车 foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { //OrderDetailInput orderDetailInput = orderDetail.OrderDetailInputs[0]; foreach (var orderDetailInput in orderDetail.OrderDetailInputs) { orderDetailInput.ReceiptDetails = receiptMaster.ReceiptDetails.Where(r => r.OrderDetailId == orderDetail.Id).ToList(); } } this.productionLineMgr.BackflushProductOrder(nonZeroOrderDetailList, orderMaster, DateTime.Now); #endregion } #endregion } #endregion } else { #region 物流收货 receiptMaster = this.receiptMgr.TransferIp2Receipt(ipMaster); if (orderMasterList.Where(o => o.OrderStrategy == CodeMaster.FlowStrategy.KIT).Count() > 0) { //kit收货特殊处理 this.receiptMgr.CreateReceipt(receiptMaster, true, effectiveDate); } else { this.receiptMgr.CreateReceipt(receiptMaster, false, effectiveDate); } #endregion } #endregion #region 尝试关闭订单 foreach (OrderMaster orderMaster in orderMasterList) { if (orderMaster.Type == CodeMaster.OrderType.Production) { #region 生产 if (productLineMap != null && productLineMap.ProductLine == orderMaster.Flow) { #region 总装生产单 CloseVanOrder(orderMaster, productLineMap); #endregion } else if (productLineMap != null && (productLineMap.CabFlow == orderMaster.Flow || productLineMap.ChassisFlow == orderMaster.Flow)) { #region 驾驶室和底盘 //驾驶室和底盘下线完工订单,总装下线后一起关闭 CompleteVanSubOrder(orderMaster); #endregion } else { #region 非整车 TryCloseOrder(orderMaster); #endregion } #endregion } else { #region 物流 TryCloseOrder(orderMaster); #endregion } } #endregion return receiptMaster; }
private void MatchIpDetailInput(IpDetail ipDetail, IpDetailInput ipDetailInput, IList<IpLocationDetail> ipLocationDetailList, ref IpDetail gapIpDetail) { decimal remainQty = ipDetailInput.ReceiveQty * ipDetail.UnitQty; //转为库存单位 foreach (IpLocationDetail ipLocationDetail in ipLocationDetailList) { if (ipLocationDetail.IsClose) { continue; } //iplocationdet只可能为正数 if (ipLocationDetail.RemainReceiveQty >= remainQty) { //收货明细匹配完 #region 添加收货记录和IpLocationDetail的映射关系 IpLocationDetail receivedIpLocationDetail = Mapper.Map<IpLocationDetail, IpLocationDetail>(ipLocationDetail); receivedIpLocationDetail.ReceivedQty = remainQty; ipDetailInput.AddReceivedIpLocationDetail(receivedIpLocationDetail); #endregion ipLocationDetail.ReceivedQty += remainQty; remainQty = 0; if (ipLocationDetail.Qty == ipLocationDetail.ReceivedQty) { ipLocationDetail.IsClose = true; } } else { //收货明细未匹配完 #region 添加收货记录和IpLocationDetail的映射关系 IpLocationDetail receivedIpLocationDetail = Mapper.Map<IpLocationDetail, IpLocationDetail>(ipLocationDetail); receivedIpLocationDetail.ReceivedQty = ipLocationDetail.RemainReceiveQty; ipDetailInput.AddReceivedIpLocationDetail(receivedIpLocationDetail); #endregion remainQty -= ipLocationDetail.RemainReceiveQty; ipLocationDetail.ReceivedQty = ipLocationDetail.Qty; ipLocationDetail.IsClose = true; } //更新 if (ipLocationDetail.Id > 0) { genericMgr.Update(ipLocationDetail); } if (remainQty == 0) { //匹配完,跳出循环 break; } } //超收,还有未匹配完的数量 if (remainQty > 0) { #region 记录差异 if (gapIpDetail == null || !gapIpDetail.GapIpDetailId.HasValue) { gapIpDetail = Mapper.Map<IpDetail, IpDetail>(ipDetail); gapIpDetail.Type = com.Sconit.CodeMaster.IpDetailType.Gap; gapIpDetail.GapReceiptNo = string.Empty; gapIpDetail.ReceivedQty = 0; gapIpDetail.IsClose = false; gapIpDetail.GapIpDetailId = ipDetail.Id; } gapIpDetail.Qty += -(remainQty / ipDetail.UnitQty); //多收,数量为负,转为订单单位 IpLocationDetail gapIpLocationDetail = new IpLocationDetail(); gapIpLocationDetail.IpNo = ipDetail.IpNo; gapIpLocationDetail.OrderType = ipDetail.OrderType; gapIpLocationDetail.OrderDetailId = ipDetail.OrderDetailId; gapIpLocationDetail.Item = ipDetail.Item; gapIpLocationDetail.HuId = null; //收货未匹配产生的差异全部为数量(除了条码匹配条码) gapIpLocationDetail.LotNo = null; gapIpLocationDetail.IsCreatePlanBill = false; gapIpLocationDetail.PlanBill = null; gapIpLocationDetail.ActingBill = null; gapIpLocationDetail.IsFreeze = false; gapIpLocationDetail.IsATP = false; //差异不能进行MRP运算 gapIpLocationDetail.QualityType = ipDetail.QualityType; gapIpLocationDetail.OccupyType = com.Sconit.CodeMaster.OccupyType.None; gapIpLocationDetail.OccupyReferenceNo = null; gapIpLocationDetail.Qty = -remainQty; //多收,产生负数的差异 gapIpLocationDetail.ReceivedQty = 0; gapIpLocationDetail.IsClose = false; gapIpDetail.AddIpLocationDetail(gapIpLocationDetail); #endregion } }
public ReceiptMaster ReceiveOrder(IList<OrderDetail> orderDetailList, DateTime effectiveDate) { #region 判断是否全0收货 if (orderDetailList == null || orderDetailList.Count == 0) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveDetailIsEmpty); } IList<OrderDetail> nonZeroOrderDetailList = orderDetailList.Where(o => o.ReceiveQtyInput != 0 || o.ScrapQtyInput != 0).ToList(); if (nonZeroOrderDetailList.Count == 0) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveDetailIsEmpty); } #endregion #region 查询订单头对象 IList<OrderMaster> orderMasterList = LoadOrderMasters((from det in nonZeroOrderDetailList //where !string.IsNullOrWhiteSpace(det.OrderNo) todo支持无订单收货 select det.OrderNo).Distinct().ToArray()); #endregion foreach (var oMaster in orderMasterList) { if (oMaster.Type == com.Sconit.CodeMaster.OrderType.Transfer) { CheckInventory(orderDetailList.Where(ol => ol.OrderNo == oMaster.OrderNo).ToList(), oMaster); } } //#region 按订单明细汇总发货数,按条码发货一条订单明细会对应多条发货记录 //var summaryOrderDet = from det in orderDetailList // group det by new { Id = det.Id, OrderNo = det.OrderNo } into g // select new // { // Id = g.Key.Id, // OrderNo = g.Key.OrderNo, // ReceiveQty = g.Sum(det => det.CurrentReceiveQty), // RejectQty = g.Sum(det => det.CurrentRejectQty) // }; //#endregion #region 获取收货订单类型 IList<com.Sconit.CodeMaster.OrderType> orderTypeList = (from orderMaster in orderMasterList group orderMaster by orderMaster.Type into result select result.Key).ToList(); if (orderTypeList.Count > 1) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_CannotMixOrderTypeReceive); } com.Sconit.CodeMaster.OrderType orderType = orderTypeList.First(); #endregion #region 计划协议不能按收货校验 if (orderType == CodeMaster.OrderType.ScheduleLine) { throw new BusinessException("计划协议不能按订单收货。"); } #endregion #region 循环订单头检查 foreach (OrderMaster orderMaster in orderMasterList) { orderMaster.OrderDetails = nonZeroOrderDetailList.Where(det => det.OrderNo == orderMaster.OrderNo).ToList(); //如果非生产,把Submit状态改为InProcess if (orderMaster.Status == com.Sconit.CodeMaster.OrderStatus.Submit && orderMaster.Type != com.Sconit.CodeMaster.OrderType.Production && orderMaster.Type != com.Sconit.CodeMaster.OrderType.SubContract) { UpdateOrderMasterStatus2InProcess(orderMaster); } //判断OrderHead状态 if (orderMaster.Status != com.Sconit.CodeMaster.OrderStatus.InProcess) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_StatusErrorWhenReceive, orderMaster.OrderNo, systemMgr.GetCodeDetailDescription(com.Sconit.CodeMaster.CodeMaster.OrderStatus, ((int)orderMaster.Status).ToString())); } #region 订单、生产线暂停检查 if (orderMaster.PauseStatus == CodeMaster.PauseStatus.Paused) { if (orderMaster.Type == CodeMaster.OrderType.Production) { throw new BusinessException("生产单{0}已经暂停,不能收货。", orderMaster.OrderNo); } else { throw new BusinessException("订单{0}已经暂停,不能收货。", orderMaster.OrderNo); } } if ((orderMaster.Type == CodeMaster.OrderType.Production || orderMaster.Type == CodeMaster.OrderType.SubContract ) && !string.IsNullOrWhiteSpace(orderMaster.Flow)) { FlowMaster flowMaster = this.genericMgr.FindById<FlowMaster>(orderMaster.Flow); if (flowMaster.IsPause) { throw new BusinessException("生产线{0}已经暂停,不能收货。", orderMaster.Flow); } } #endregion #region 整包装收货判断,快速的不要判断 if (orderMaster.IsReceiveFulfillUC && orderMaster.SubType == com.Sconit.CodeMaster.OrderSubType.Normal && !(orderMaster.IsAutoRelease && orderMaster.IsAutoStart)) { foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { //不合格品不作为收货数 //if (orderDetail.ReceiveQualifiedQtyInput % orderDetail.UnitCount != 0) if (orderDetail.ReceiveQtyInput % orderDetail.UnitCount != 0) { //不是整包装 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyNotFulfillUnitCount, orderDetail.Item); } } } #endregion #region 是否过量发货判断,未发货即收货也要判断是否过量发货 foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { if (!orderMaster.IsOpenOrder) { if (Math.Abs(orderDetail.ShippedQty) > Math.Abs(orderDetail.OrderedQty)) { //订单的发货数已经大于等于订单数 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ShipQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } else if (orderMaster.Type != com.Sconit.CodeMaster.OrderType.Production //生产和委外不需要判断 && orderMaster.Type != com.Sconit.CodeMaster.OrderType.SubContract && !orderMaster.IsShipExceed && Math.Abs(orderDetail.ShippedQty + orderDetail.ReceiveQtyInput) > Math.Abs(orderDetail.OrderedQty)) //不允许过量收货 { //订单的发货数 + 本次发货数大于订单数 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ShipQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } } } #endregion #region 是否过量收货判断 foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { if (!orderMaster.IsOpenOrder) { //订单的收货数已经大于等于订单数 if (Math.Abs(orderDetail.ReceivedQty) >= Math.Abs(orderDetail.OrderedQty)) { throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } //sih要求,废品数和不合格品数不占用入库数量 else if (!orderMaster.IsReceiveExceed && Math.Abs(orderDetail.ReceivedQty + orderDetail.ReceiveQtyInput) > Math.Abs(orderDetail.OrderedQty)) //不允许过量收货 { //订单的收货数 + 本次收货数大于订单数 throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); } //else if (!orderMaster.IsReceiveExceed && Math.Abs(orderDetail.ReceivedQty + orderDetail.RejectedQty + orderDetail.ScrapQty + orderDetail.ReceiveQtyInput + orderDetail.ScrapQtyInput) > Math.Abs(orderDetail.OrderedQty)) //不允许过量收货 //{ // //订单的收货数 + 本次收货数大于订单数 // throw new BusinessException(Resources.ORD.OrderMaster.Errors_ReceiveQtyExcceedOrderQty, orderDetail.OrderNo, orderDetail.Item); //} } } #endregion #region 采购收货是否有价格单判断 //if (orderHead.Type == BusinessConstants.CODE_MASTER_ORDER_TYPE_VALUE_PROCUREMENT // && !bool.Parse(entityPreference.Value)) //{ // if (orderDetail.UnitPrice == Decimal.Zero) // { // //重新查找一次价格 // PriceListDetail priceListDetail = priceListDetailMgrE.GetLastestPriceListDetail( // orderDetail.DefaultPriceList, // orderDetail.Item, // orderHead.StartTime, // orderHead.Currency, // orderDetail.Uom); // if (priceListDetail != null) // { // orderDetail.UnitPrice = priceListDetail.UnitPrice; // orderDetail.IsProvisionalEstimate = priceListDetail.IsProvisionalEstimate; // orderDetail.IsIncludeTax = priceListDetail.IsIncludeTax; // orderDetail.TaxCode = priceListDetail.TaxCode; // } // else // { // throw new BusinessErrorException("Order.Error.NoPriceListReceipt", orderDetail.Item.Code); // } // } //} #endregion #region 采购收货是否有计划协议行或PO号 if (orderMaster.Type == com.Sconit.CodeMaster.OrderType.Procurement) { foreach (OrderDetail orderDetail in orderMaster.OrderDetails) { if (string.IsNullOrWhiteSpace(orderDetail.ExternalOrderNo) || string.IsNullOrWhiteSpace(orderDetail.ExternalSequence)) { throw new BusinessException("供应商直供要货单{0}物料号{1}的计划协议号或PO号不能为空。", orderDetail.OrderNo, orderDetail.Item); } } } #endregion } #endregion #region 循环更新订单明细 foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { //未发货直接收货需要累加已发货数量 if (orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.Production && orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.SubContract) { orderDetail.ShippedQty += orderDetail.ReceiveQtyInput; } if (orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.Production && orderDetail.OrderType != com.Sconit.CodeMaster.OrderType.SubContract) { //orderDetail.ReceivedQty += orderDetail.ReceiveQualifiedQtyInput; orderDetail.ReceivedQty += orderDetail.ReceiveQtyInput; } else { //生产收货更新合格数和不合格数量 //orderDetail.ReceivedQty += orderDetail.ReceiveQualifiedQtyInput; orderDetail.ReceivedQty += orderDetail.ReceiveQtyInput; orderDetail.ScrapQty += orderDetail.ScrapQtyInput; } genericMgr.Update(orderDetail); } #endregion #region 发货 #region OrderDetailInput赋发货数量 foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { foreach (OrderDetailInput orderDetailInput in orderDetail.OrderDetailInputs) { orderDetailInput.ShipQty = orderDetailInput.ReceiveQty; } } #endregion IpMaster ipMaster = null; if (orderType != com.Sconit.CodeMaster.OrderType.Production && orderType != com.Sconit.CodeMaster.OrderType.SubContract) { ipMaster = this.ipMgr.TransferOrder2Ip(orderMasterList); #region 循环发货 foreach (IpDetail ipDetail in ipMaster.IpDetails) { ipDetail.CurrentPartyFrom = ipMaster.PartyFrom; //为了记录库存事务 ipDetail.CurrentPartyFromName = ipMaster.PartyFromName; //为了记录库存事务 ipDetail.CurrentPartyTo = ipMaster.PartyTo; //为了记录库存事务 ipDetail.CurrentPartyToName = ipMaster.PartyToName; //为了记录库存事务 //ipDetail.CurrentOccupyType = com.Sconit.CodeMaster.OccupyType.None; //todo-默认出库未占用库存,除非捡货或检验的出库 IList<InventoryTransaction> inventoryTransactionList = this.locationDetailMgr.InventoryOut(ipDetail, effectiveDate); #region 建立发货库明细和IpDetailInput的关系 if (inventoryTransactionList != null && inventoryTransactionList.Count > 0) { ipDetail.IpLocationDetails = (from trans in inventoryTransactionList group trans by new { HuId = trans.HuId, LotNo = trans.LotNo, IsCreatePlanBill = trans.IsCreatePlanBill, IsConsignment = trans.IsConsignment, PlanBill = trans.PlanBill, ActingBill = trans.ActingBill, QualityType = trans.QualityType, IsFreeze = trans.IsFreeze, IsATP = trans.IsATP, OccupyType = trans.OccupyType, OccupyReferenceNo = trans.OccupyReferenceNo } into g select new IpLocationDetail { HuId = g.Key.HuId, LotNo = g.Key.LotNo, IsCreatePlanBill = g.Key.IsCreatePlanBill, IsConsignment = g.Key.IsConsignment, PlanBill = g.Key.PlanBill, ActingBill = g.Key.ActingBill, QualityType = g.Key.QualityType, IsFreeze = g.Key.IsFreeze, IsATP = g.Key.IsATP, OccupyType = g.Key.OccupyType, OccupyReferenceNo = g.Key.OccupyReferenceNo, Qty = g.Sum(t => -t.Qty), //发货的库存事务为负数,转为收货数应该取负数 //PlanBillQty = g.Sum(t=>-t.PlanBillQty), //ActingBillQty = g.Sum(t=>-t.ActingBillQty) }).ToList(); } #endregion } #endregion #region 生成收货的IpInput foreach (OrderDetail orderDetail in nonZeroOrderDetailList) { OrderMaster orderMaster = orderMasterList.Where(o => o.OrderNo == orderDetail.OrderNo).Single(); //订单收货一定是一条订单明细对应一条发货单明细 IpDetail ipDetail = ipMaster.IpDetails.Where(det => det.OrderDetailId == orderDetail.Id).Single(); ipDetail.IpDetailInputs = null; //清空Ip的发货数据,准备添加收货数据 foreach (OrderDetailInput orderDetailInput in orderDetail.OrderDetailInputs) { IpDetailInput ipDetailInput = new IpDetailInput(); ipDetailInput.ReceiveQty = orderDetailInput.ShipQty; if (orderMaster.IsReceiveScanHu) { ipDetailInput.HuId = orderDetailInput.HuId; ipDetailInput.LotNo = orderDetailInput.LotNo; } ipDetail.AddIpDetailInput(ipDetailInput); } } #region 订单生成收货Input if (ipMaster.IsShipScanHu && ipMaster.IsReceiveScanHu) { #region 按条码匹配 foreach (IpDetail ipDetail in ipMaster.IpDetails) { foreach (IpDetailInput ipDetailInput in ipDetail.IpDetailInputs) { IpLocationDetail matchedIpLocationDetail = ipDetail.IpLocationDetails.Where(locDet => locDet.HuId == ipDetailInput.HuId).SingleOrDefault(); matchedIpLocationDetail.ReceivedQty = matchedIpLocationDetail.Qty; if (matchedIpLocationDetail != null) { ipDetailInput.AddReceivedIpLocationDetail(matchedIpLocationDetail); } } } #endregion } else { #region 按数量匹配 foreach (IpDetail ipDetail in ipMaster.IpDetails) { CycleMatchIpDetailInput(ipDetail, ipDetail.IpDetailInputs, ipDetail.IpLocationDetails); } #endregion } #endregion #endregion } #endregion #region 收货 ReceiptMaster receiptMaster = null; if (orderType == com.Sconit.CodeMaster.OrderType.Production || orderType == com.Sconit.CodeMaster.OrderType.SubContract) { #region 生产收货 if (orderMasterList.Count > 1) { throw new TechnicalException("生产单不能合并收货。"); } foreach (OrderMaster orderMaster in orderMasterList) { receiptMaster = this.receiptMgr.TransferOrder2Receipt(orderMaster); this.receiptMgr.CreateReceipt(receiptMaster); //在报工的时候反冲物料,收货时不反冲 //foreach (OrderDetail orderDetail in nonZeroOrderDetailList) //{ // OrderDetailInput orderDetailInput = orderDetail.OrderDetailInputs[0]; // orderDetailInput.ReceiptDetail = receiptMaster.ReceiptDetails.Where(r => r.OrderDetailId == orderDetail.Id).Single(); //} //this.productionLineMgr.BackflushProductOrder(nonZeroOrderDetailList); } #endregion } else if (orderType != com.Sconit.CodeMaster.OrderType.Production && orderType != com.Sconit.CodeMaster.OrderType.SubContract) { #region 物流收货 receiptMaster = this.receiptMgr.TransferIp2Receipt(ipMaster); this.receiptMgr.CreateReceipt(receiptMaster, false, effectiveDate); #endregion } #endregion #region 尝试关闭订单 foreach (OrderMaster orderMaster in orderMasterList) { if (orderMaster.Type == CodeMaster.OrderType.Production) { #region 生产 TryCloseOrder(orderMaster); #endregion } else { #region 物流 TryCloseOrder(orderMaster); #endregion } } #endregion return receiptMaster; }