public object ConsumeMaterial([FromBody] ConsumeMaterial materialManagement) { if (materialManagement.Bill == null) { return(Result.GenError <Result>(Error.ParamError)); } foreach (var bill in materialManagement.Bill) { bill.Type = MaterialOp.出库; bill.CorrectNumber(); } var mBills = materialManagement.Bill.Where(x => x.Number > 0); if (!mBills.Any()) { return(Result.GenError <Result>(Error.MaterialNotEmpty)); } //出库时物料必须存在 if (mBills.Any(x => x.Type == MaterialOp.出库 && x.BillId == 0)) { return(Result.GenError <Result>(Error.MaterialBillNotExist)); } var billIds = mBills.Select(x => x.BillId).Distinct(); if (!billIds.Any()) { return(Result.GenError <Result>(Error.MaterialNotEmpty)); } var allBills = MaterialHelper.GetDetails(billIds).ToDictionary(x => x.BillId); if (allBills.Count() != billIds.Count()) { return(Result.GenError <Result>(Error.MaterialBillNotExist)); } var createUserId = Request.GetIdentityInformation(); var markedDateTime = DateTime.Now; ProductPlan plan = null; if (materialManagement.PlanId != 0) { plan = ProductPlanHelper.Instance.Get <ProductPlan>(materialManagement.PlanId); if (plan == null) { return(Result.GenError <Result>(Error.ProductionPlanNotExist)); } } var result = new DataResult(); #region 检验库存 var consumeBills = billIds.Select(x => new OpMaterial { BillId = x, Number = mBills.Where(y => y.BillId == x).Sum(z => z.Number) }).ToList(); var less = consumeBills.Where(x => x.Number > allBills[x.BillId].Number).Select(x => allBills[x.BillId].Code); if (less.Any()) { result.errno = Error.MaterialLess; result.datas.AddRange(less); return(result); } var oldBatches = new Dictionary <int, MaterialBatch>(); var upIds = new Dictionary <int, int>(); //出库指定的批次 var batchBills = mBills.Where(x => x.HaveBatch); if (batchBills.Any()) { var bIds = batchBills.SelectMany(x => x.Batches.Select(y => y.Id)).Distinct(); oldBatches.AddRange(MaterialBatchHelper.GetDetails(bIds).ToDictionary(x => x.Id)); if (bIds.Count() != oldBatches.Count()) { return(Result.GenError <DataResult>(Error.MaterialBatchNotExist)); } var mergeBatch = bIds.Select(x => { var oldBatch = oldBatches[x]; var batches = batchBills.Where(y => y.BillId == oldBatch.BillId).SelectMany((Func <OpMaterial, IEnumerable <MaterialBatchSimple> >)(y => y.Batches.Where((Func <MaterialBatchSimple, bool>)(z => z.Id == oldBatch.Id)))); return(new MaterialBatch { Id = oldBatch.Id, BatchId = oldBatch.BatchId, Batch = oldBatch.Batch, BillId = oldBatch.BillId, SupplierId = oldBatch.SupplierId, Number = batches.Sum(y => y.Number), }); }); var much = mergeBatch.Where(x => oldBatches[x.Id].Left < x.Number); if (much.Any()) { result = new DataResult { errno = Error.MaterialBatchLeftLess }; result.datas.AddRange(much.Select(x => $"{x.Batch} {allBills[x.BillId].Code} {x.Supplier}")); return(result); } } var noBatchBills = mBills.Where(x => !x.HaveBatch); if (noBatchBills.Any()) { var noBillIds = noBatchBills.Select(x => x.BillId).Distinct(); var noZeroBatches = MaterialBatchHelper.GetDetailsNoZero(noBillIds) .GroupBy(x => x.BillId).ToDictionary(x => x.Key); //.GroupBy(x => x.BillId).ToDictionary(x => x.Key, x => x.Select(y => y)); var mergeBatch = noBillIds.Select(billId => { var batches = noBatchBills.Where(y => y.BillId == billId); var number = batches.Sum(y => y.Number); return(new MaterialBatch { BillId = billId, Number = number, }); }); var noZeroMergeBatch = noBillIds.Select(billId => { var left = noZeroBatches.ContainsKey(billId) ? noZeroBatches[billId].Sum(y => y.Left) : 0; return(new MaterialBatch { BillId = billId, Left = left, }); }).ToDictionary(x => x.BillId); var much = mergeBatch.Where(x => noZeroMergeBatch[x.BillId].Left < x.Number); if (much.Any()) { result = new DataResult { errno = Error.MaterialBatchLeftLess }; result.datas.AddRange(much.Select(x => $"{x.Batch} {allBills[x.BillId].Code} {x.Supplier}")); return(result); } foreach (var bill in noBatchBills) { var number = bill.Number; foreach (var batch in noZeroBatches[bill.BillId].OrderBy(x => x.Time)) { if (number <= 0) { break; } if (!upIds.ContainsKey(batch.Id)) { upIds.Add(batch.Id, 0); } var n = 0m; if (number > batch.Left) { number -= batch.Left; n = batch.Left; } else { n = number; number = 0; } var z = ClassExtension.CopyTo <MaterialBatch, MaterialBatchSimple>(batch); z.Number = n; bill.Batches.Add(z); } } oldBatches.AddRange(noZeroBatches.Values.SelectMany(x => x.Where(y => upIds.ContainsKey(y.Id))).ToDictionary(x => x.Id)); } #endregion #region 计划领料 var planChangeBill = new List <ProductPlanBill>(); var planAddBill = new List <ProductPlanBill>(); if (materialManagement.PlanId != 0) { var planBill = ProductPlanBillHelper.GetPlanBills(materialManagement.PlanId, billIds).ToDictionary(x => x.BillId); #region 更新 var existBill = consumeBills.Where(x => planBill.ContainsKey(x.BillId)); if (existBill.Any()) { foreach (var bill in existBill) { planBill[bill.BillId].MarkedDateTime = markedDateTime; planBill[bill.BillId].ActualConsumption += bill.Number; planChangeBill.Add(planBill[bill.BillId]); } } #endregion #region 添加额外领用的物料 var extraBill = consumeBills.Where(x => !planBill.ContainsKey(x.BillId)); if (extraBill.Any()) { planAddBill.AddRange(extraBill.Select(x => new ProductPlanBill { CreateUserId = createUserId, MarkedDateTime = markedDateTime, PlanId = materialManagement.PlanId, BillId = x.BillId, ActualConsumption = x.Number, Extra = true, })); } #endregion } #endregion var logs = mBills.Select(x => { var batches = new List <MaterialBatch>(); batches.AddRange(x.Batches.Select(y => { var batch = oldBatches[y.Id]; batch.MarkedDateTime = markedDateTime; batch.OutTime = markedDateTime; batch.Left -= y.Number; var z = ClassExtension.CopyTo <MaterialBatchSimple, MaterialBatch>(y); z.Batch = batch.Batch; z.Price = batch.Price; return(z); })); var log = new MaterialLog(createUserId, markedDateTime, x.Type, x.Purpose, x.Number, allBills[x.BillId].Number, x.RelatedPerson, createUserId, allBills[x.BillId], batches, plan); return(log); }).ToList(); if (oldBatches.Any()) { MaterialBatchHelper.UpdateConsumeLeft(oldBatches.Values); } Task.Run(() => { if (planChangeBill.Any()) { ProductPlanBillHelper.UpdateActualConsumptions(planChangeBill); } if (planAddBill.Any()) { ProductPlanBillHelper.Instance.Add(planAddBill); } if (logs.Any()) { MaterialLogHelper.Instance.Add(logs); } if (allBills.Keys.Any()) { HMaterialHelper.UpdateBillPrice(allBills.Keys); } }); try { #region 消耗 foreach (var bill in consumeBills) { allBills[bill.BillId].OutTime = markedDateTime; allBills[bill.BillId].Number -= bill.Number; } MaterialHelper.Consume(allBills.Values); #endregion } catch (Exception e) { Log.Error(allBills.Values.ToJSON()); Log.Error(e); } return(result); }
public DataResult GetMaterialBatch([FromQuery] bool log, int pId, string pIds, bool menu, int qId, string qIds, int batchId, string batchIds, int bId, string bIds, int sId, string sIds, bool zero, int itemId, int logId, bool con) { var result = new DataResult(); var pIdList = !pIds.IsNullOrEmpty() ? pIds.Split(",").Select(int.Parse) : null; var qIdList = !qIds.IsNullOrEmpty() ? qIds.Split(",").Select(int.Parse) : null; var batchList = !batchIds.IsNullOrEmpty() ? batchIds.Split(",").Select(int.Parse) : null; var bIdList = !bIds.IsNullOrEmpty() ? bIds.Split(",").Select(int.Parse) : null; var sIdList = !sIds.IsNullOrEmpty() ? sIds.Split(",").Select(int.Parse) : null; if (itemId != 0) { var data = ServerConfig.ApiDb.Query <MaterialBatch>( "SELECT b.* FROM `material_log` a JOIN `material_batch` b ON a.BIds = b.Id WHERE Type = @type AND ItemId = @itemId;", new { type = MaterialOp.入库, itemId }); var supplierIds = data.Select(x => x.SupplierId).Distinct(); if (supplierIds.Any()) { var suppliers = MaterialSupplierHelper.Instance.GetByIds <MaterialSupplier>(supplierIds).ToDictionary(x => x.Id); foreach (var d in data) { if (suppliers.ContainsKey(d.SupplierId)) { d.Supplier = suppliers[d.SupplierId].Supplier; } } } result.datas.AddRange(data); } else if (log) { IEnumerable <MaterialBatch> data; if (logId != 0) { var lg = MaterialLogHelper.Instance.Get <MaterialLog>(logId); if (!lg.BIdList.Any()) { result.errno = Error.MaterialBatchNotExist; return(result); } var batches = lg.BatchesList.ToDictionary(x => x.Id); data = MaterialBatchHelper.GetDetails(lg.BIdList); foreach (var d in data) { d.Number = batches.ContainsKey(d.Id) ? batches[d.Id].Number : 0; } } else if (pId != 0) { data = ServerConfig.ApiDb.Query <MaterialBatch>( "SELECT b.*, a.Number `Left` FROM `material_log` a JOIN `material_batch` b ON a.BIds = b.Id WHERE Type = @type AND PlanId = @pId AND a.BillId = @bId;", new { type = MaterialOp.出库, pId, bId }); } else { data = ServerConfig.ApiDb.Query <MaterialBatch>( "SELECT b.*, a.Number `Left` FROM `material_log` a JOIN `material_batch` b ON a.BIds = b.Id WHERE Type = @type AND PlanId = 0 AND a.BillId = @bId;", new { type = MaterialOp.出库, bId }); } var supplierIds = data.Select(x => x.SupplierId).Distinct(); if (supplierIds.Any()) { var suppliers = MaterialSupplierHelper.Instance.GetByIds <MaterialSupplier>(supplierIds).ToDictionary(x => x.Id); foreach (var d in data) { if (suppliers.ContainsKey(d.SupplierId)) { d.Supplier = suppliers[d.SupplierId].Supplier; } } } result.datas.AddRange(data); } else if (zero) { result.datas.AddRange(MaterialBatchHelper.GetDetailsNoZero(new List <int> { bId })); } //物料扫码 批次 else if (con) { var batch = MaterialBatchHelper.GetDetail(qId); if (batch == null) { result.errno = Error.MaterialBatchNotExist; return(result); } var bill = MaterialHelper.GetDetail(batch.BillId); if (bill == null) { result.errno = Error.MaterialBillNotExist; return(result); } var res = ClassExtension.CopyTo <Material, MaterialManagementBatch>(bill); res.Supplier = batch.Supplier; res.Left = batch.Left; res.Batch = batch.Batch; result.datas.Add(res); } else { result.datas.AddRange(menu ? MaterialBatchHelper.GetMenus(qId, qIdList, batchId, batchList, bId, bIdList, sId, sIdList, zero) : MaterialBatchHelper.GetDetails(qId, qIdList, batchId, batchList, bId, bIdList, sId, sIdList, zero)); if (qId != 0 && !result.datas.Any()) { result.errno = Error.MaterialBatchNotExist; return(result); } } return(result); }