using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Aop.Api.Domain; using JNPF.Common.Contracts; using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.VisualDev; using JNPF.Common.Extension; using JNPF.Common.Security; using JNPF.FriendlyException; using JNPF.Systems.Entitys.Permission; using JNPF.Systems.Interfaces.System; using JNPF.VisualDev; using JNPF.VisualDev.Entitys; using JNPF.VisualDev.Interfaces; using Mapster; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json.Linq; using SqlSugar; using SqlSugar.DbConvert; using Tnb.BasicData.Entities; using Tnb.Common.Utils; using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities.Attributes; using Tnb.WarehouseMgr.Entities.Consts; using Tnb.WarehouseMgr.Entities.Dto; using Tnb.WarehouseMgr.Entities.Dto.Inputs; using Tnb.WarehouseMgr.Entities.Enums; using Tnb.WarehouseMgr.Interfaces; namespace Tnb.WarehouseMgr { /// /// 出库申请业务类 /// [OverideVisualDev(ModuleConsts.MODULE_WMSOUTSTOCK_ID)] [ServiceModule(BizTypeId)] public class WmsOutStockService : BaseWareHouseService, IWmsOutStockService { private const string BizTypeId = "26191522660645"; private readonly ISqlSugarClient _db; private readonly IDictionaryDataService _dictionaryDataService; private readonly IRunService _runService; private readonly IVisualDevService _visualDevService; private readonly IWareHouseService _wareHouseService; private readonly IUserManager _userManager; private readonly IBillRullService _billRullService; private readonly IWmsCarryMoveInStockService _wmsCarryMoveInStockService; private readonly IWmsCarryService _wareCarryService; public WmsOutStockService( ISqlSugarRepository repository, IDictionaryDataService dictionaryDataService, IRunService runService, IVisualDevService visualDevService, IWareHouseService wareHouseService, IUserManager userManager, IBillRullService billRullService, IWmsCarryMoveInStockService wmsCarryMoveInStockService, IWmsCarryService wareCarryService, ITaskMessageNotify taskMessageNotify) : base(taskMessageNotify.Writer) { _db = repository.AsSugarClient(); _dictionaryDataService = dictionaryDataService; _runService = runService; _visualDevService = visualDevService; _wareHouseService = wareHouseService; _userManager = userManager; _billRullService = billRullService; _wmsCarryMoveInStockService = wmsCarryMoveInStockService; _wareCarryService = wareCarryService; OverideFuncs.CreateAsync = OutStockApplyFor; } private async Task OutStockApplyFor(VisualDevModelDataCrInput input) { try { await _db.Ado.BeginTranAsync(); //判断目标库位是否自动签收 var loc = await _db.Queryable().SingleAsync(it => it.id == input.data[nameof(WmsPointH.location_id)].ToString()); var carryIds = new List(); //tablefield120 出库物料明细 if (input.data.ContainsKey("tablefield120") && input.data["tablefield120"].IsNotEmptyOrNull()) { var outStockDList = input.data["tablefield120"].ToObject>(); if (outStockDList?.Count > 0) { List carryMats = new(); List carryCodes = new(); foreach (var os in outStockDList) { var OutStockStrategyInput = new OutStockStrategyQuery { carry_id = input.data[nameof(OutStockStrategyQuery.carry_id)].ToString(), warehouse_id = input.data[nameof(WmsOutstockH.warehouse_id)].ToString(), material_id = os.material_id, code_batch = os.code_batch, }; var outStkCarrys = await _wareHouseService.OutStockStrategy(OutStockStrategyInput); Expression> whereExp = input.data.ContainsKey(nameof(WmsOutstockH.carry_id)) ? (a, b) => a.id == input.data[nameof(WmsOutstockH.carry_id)].ToString() : (a, b) => outStkCarrys.Select(x => x.id).Contains(b.carry_id); List? carryCodesPart = await _db.Queryable().InnerJoin((a, b) => a.id == b.carry_id).InnerJoin((a, b, c) => a.location_id == c.id) .Where(whereExp) .Select() .ToListAsync(); if (carryCodesPart?.Count > 0) { var codeQty = carryCodesPart.Sum(x => x.codeqty); if (codeQty < os.pr_qty) { throw new AppFriendlyException($"需要出库[{os.pr_qty}],实际库存{codeQty},数量不足", 500); } List curCarryCodes = new(); for (int i = 0; i < carryCodesPart.Count; i++) { if (os.pr_qty > carryCodesPart[i].codeqty) { os.pr_qty -= carryCodesPart[i].codeqty; curCarryCodes.Add(carryCodesPart[i]); } else if (os.pr_qty <= carryCodesPart[i].codeqty) { WmsCarryCode curCarryCode = DeepCopyHelper.DeepCopy(carryCodesPart[i]); curCarryCode.codeqty = os.pr_qty; curCarryCodes.Add(curCarryCode); break; } } carryCodes.AddRange(curCarryCodes); var partCarryMats = curCarryCodes.Adapt>(); for (int i = 0; i < partCarryMats.Count; i++) { partCarryMats[i].need_qty = curCarryCodes[i].codeqty; } carryMats.AddRange(partCarryMats); } } if (carryMats.Count > 0) { carryMats.ForEach(x => x.id = SnowflakeIdHelper.NextId()); carryMats = carryMats.OrderBy(o => o.create_time).GroupBy(g => new { g.carry_id, g.material_id, g.code_batch }) .Select(x => { var arr = x.ToArray(); WmsCarryMat carryMat = arr[^arr.Length]; carryMat.need_qty = x.Sum(d => d.need_qty); return carryMat; }) .ToList(); await _db.Insertable(carryMats).ExecuteCommandAsync(); var dic = carryMats.DistinctBy(x => x.carry_id).ToDictionary(x => x.carry_id, x => x.need_qty); var allOutIds = new List(); var sortingOutIds = new List(); foreach (var pair in dic) { var codes = carryCodes.FindAll(x => x.carry_id == pair.Key); if (codes?.Count > 0) { if (pair.Value == codes.Sum(d => d.codeqty)) { allOutIds.Add(pair.Key); } else { sortingOutIds.Add(pair.Key); } } } carryIds = allOutIds.Concat(sortingOutIds).ToList(); await _db.Updateable().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.全部出).ToString(), source_id = input.data[nameof(WmsOutstockH.source_id)].ToString(), source_code = input.data[nameof(WmsOutstockH.source_code)].ToString() }).Where(it => allOutIds.Contains(it.id)).ExecuteCommandAsync(); await _db.Updateable().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.分拣出).ToString(), source_id = input.data[nameof(WmsOutstockH.source_id)].ToString(), source_code = input.data[nameof(WmsOutstockH.source_code)].ToString() }).Where(it => sortingOutIds.Contains(it.id)).ExecuteCommandAsync(); } var carrys = await _db.Queryable().Where(it => carryIds.Contains(it.id)).ToListAsync(); if (carrys?.Count > 0) { var curCarry = carrys[^carrys.Count]; var isMatch = await IsCarryAndLocationMatchByCarryStd(curCarry, loc); if (!isMatch) throw new AppFriendlyException("该载具无法放置到目标库位", 500); VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSOUTSTOCK_ID, true); await _runService.Create(templateEntity, input); List preTasks = new(); List locIds = new(); foreach (var carry in carrys) { WmsPointH sPoint = null!; WmsPointH ePoint = null!; if (input.data.ContainsKey(nameof(WmsPointH.location_id))) { sPoint = await _db.Queryable().FirstAsync(it => it.location_id == carry.location_id); } if (input.data.ContainsKey(nameof(WmsPointH.location_id)) && input.data[nameof(WmsPointH.location_id)].IsNotEmptyOrNull()) { ePoint = await _db.Queryable().FirstAsync(it => it.location_id == input.data[nameof(WmsPointH.location_id)].ToString()); } else if (input.data.ContainsKey(nameof(WmsOutstockH.station_id))) { //多个投料库位 /* * 潍柴 * 1、那个库位状态是空的出那个 * 1.1、没有空位直接抛异常 * * 天益 * 2、不管库位是否为空, 获取到所有库位 A B * 2.1 根据这些库位去查任务执行 目的库位是这些库位的未完成任务数。 A 10 B 9 * 2.2 哪个最少给哪个 */ var org = await _db.Queryable().FirstAsync(it => it.Id == input.data[nameof(WmsOutstockH.station_id)].ToString()); if (!org?.FeedingLocationId.IsNullOrWhiteSpace() ?? false) { var fLocIds = JArray.Parse(org.FeedingLocationId).Values(); var minTaskNumLoc = await _db.Queryable().Where(it => it.status != WmsWareHouseConst.PRETASK_BILL_STATUS_COMPLE_ID && fLocIds.Contains(it.endlocation_id)) .GroupBy(it => it.endlocation_id) .Select(it => new { it.endlocation_id, count = SqlFunc.AggregateCount(it.endlocation_id) }) .MergeTable() .OrderBy(it => it.count) .FirstAsync(); ePoint = await _db.Queryable().FirstAsync(it => it.location_id == minTaskNumLoc.endlocation_id); } } if (sPoint != null && ePoint != null) { var points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id); locIds.AddRange(points.Select(x => x.location_id).ToList()!); //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) if (points?.Count > 0) { if (points.Count <= 2) throw new AppFriendlyException("该路径不存在", 500); var curPreTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it => { var sPoint = it.FirstOrDefault(); var ePoint = it.LastOrDefault(); WmsPretaskH preTask = new() { org_id = _userManager.User.OrganizeId, startlocation_id = sPoint?.location_id ?? string.Empty, startlocation_code = sPoint?.location_code ?? string.Empty, endlocation_id = ePoint?.location_id ?? string.Empty, endlocation_code = ePoint?.location_code!, start_floor = sPoint?.floor.ToString(), end_floor = ePoint?.floor.ToString(), startpoint_id = sPoint?.id!, startpoint_code = sPoint?.point_code!, endpoint_id = ePoint?.id!, endpoint_code = ePoint?.point_code!, bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(), status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, biz_type = WmsWareHouseConst.BIZTYPE_WMSOUTSTOCK_ID, task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID, carry_id = carry.id, carry_code = carry.carry_code, area_id = sPoint?.area_id ?? string.Empty, area_code = it.Key, require_id = input.data["ReturnIdentity"].ToString(), require_code = input.data[nameof(preTask.bill_code)]?.ToString()!, create_id = _userManager.UserId, create_time = DateTime.Now }; return preTask; }).ToList(); if (loc.is_sign == 0) { curPreTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值 } preTasks.AddRange(curPreTasks); } } } List pretaskCodes = new(); foreach (var pt in preTasks) { var partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList(); var curPreTaskCodes = partCodes.Adapt>(); curPreTaskCodes.ForEach(x => { x.id = SnowflakeIdHelper.NextId(); x.bill_id = pt.id; x.create_time = DateTime.Now; }); pretaskCodes.AddRange(curPreTaskCodes); } var isOk = await _wareHouseService.GenPreTask(preTasks, pretaskCodes); if (isOk) { outStockDList.ForEach(x => x.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID); await _db.Updateable(outStockDList).UpdateColumns(it => it.line_status).ExecuteCommandAsync(); await _db.Updateable().SetColumns(it => it.status == WmsWareHouseConst.BILLSTATUS_ON_ID).Where(it => it.id == input.data["ReturnIdentity"].ToString()).ExecuteCommandAsync(); GenPreTaskUpInput genPreTaskAfterUpInput = new(); genPreTaskAfterUpInput.CarryIds = preTasks.Select(x => x.carry_id).ToList(); genPreTaskAfterUpInput.LocationIds = new HashSet(locIds).ToList(); await _wareHouseService.GenInStockTaskHandleAfter(genPreTaskAfterUpInput, it => new WmsCarryH { is_lock = 1 }, it => new BasLocation { is_lock = 1 }); } } else throw new AppFriendlyException("库存不足", 500); } else throw new AppFriendlyException($"请输入物料明细", 500); } await _db.Ado.CommitTranAsync(); } catch (Exception) { await _db.Ado.RollbackTranAsync(); throw; } finally { await Publish(nameof(IWareHouseService.GenTaskExecute)); } return Task.FromResult(true); } /// /// 根据出库申请单ID获取申请单明细信息 /// /// /// [HttpGet] public async Task GetInStockDetailsListById([FromRoute] string billId) { var dic = await _dictionaryDataService.GetDictionaryByTypeId(WmsWareHouseConst.WMS_INSTOCK_D_BILL_STATUS_TYPEID); var items = await _db.Queryable().Where(it => it.bill_id == billId).ToListAsync(); _db.ThenMapper(items, it => it.line_status = dic.ContainsKey(it.line_status) ? dic[it.line_status]?.ToString()! : ""); return items; } /// /// 生产出库接口 /// /// /// [HttpPost] //[NonUnify] public async Task MESCreateOutstock(MESCreateOutstockInput input) { var isSuccessful = true; try { await _db.Ado.BeginTranAsync(); //出库申请主表 WmsOutstockH outstock = input.outstock.Adapt(); //出库申请明细表 List outstockDs = input.outstockDs.Adapt>(); var location = await _db.Queryable().SingleAsync(it => it.location_code == input.outstock.location_code && it.is_type != EnumLocationType.存储库位.ToString()); //如果数据不全或有误, if (location.IsNull() || outstockDs?.Count < 1) { //报错, 提示数据不全或有误。 throw new AppFriendlyException("数据不全或有误!", 500); } // 生成出库申请数据,添加其他数据 主表 outstock.id = SnowflakeIdHelper.NextId(); outstock.location_id = location.id; outstock.biz_type = WmsWareHouseConst.BIZTYPE_WMSOUTSTOCK_ID; outstock.bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_OUTSTOCK_ENCODE).GetAwaiter().GetResult(); outstock.generate_type = "1";// 自动 outstock.sync_status = WmsWareHouseConst.SYNC_STATUS__NOTSYNC;//未同步 outstock.status = WmsWareHouseConst.BILLSTATUS_ADD_ID;// 新增 outstock.create_id = _userManager.UserId; outstock.create_time = DateTime.Now; //明细表 foreach (var outstockD in outstockDs!) { outstockD.id = SnowflakeIdHelper.NextId(); outstockD.bill_id = outstock.id; outstockD.line_status = WmsWareHouseConst.BILLSTATUS_ADD_ID; outstockD.qty = 0; outstock.create_time = outstock.create_time; outstock.create_id = outstock.create_id; } //var loc = await _db.Queryable().SingleAsync(it => it.id == outstock.location_id.ToString()); var carryIds = new List(); //tablefield120 出库物料明细 var outStockDList = outstockDs.ToObject>(); if (outStockDList?.Count > 0) { List carryMats = new(); List carryCodes = new(); foreach (var os in outStockDList) { var whereExp = Expressionable.Create() .And((a, b, c) => a.is_lock == 0) .And((a, b, c) => !string.IsNullOrEmpty(a.location_id)) .And((a, b, c) => a.status == (int)EnumCarryStatus.占用) .And((a, b, c) => c.is_type == ((int)EnumLocationType.存储库位).ToString()) .And((a, b, c) => b.material_id == os.material_id) .AndIF(!string.IsNullOrEmpty(os.code_batch), (a, b, c) => b.code_batch == os.code_batch); var carryCodesPart = await _db.Queryable().InnerJoin((a, b) => a.id == b.carry_id).InnerJoin((a, b, c) => a.location_id == c.id) .Where(whereExp.ToExpression()) .Select() .ToListAsync(); if (carryCodesPart?.Count > 0) { var codeQty = carryCodes.Sum(x => x.codeqty); if (codeQty < os.pr_qty) { throw new AppFriendlyException($"需要出库[{os.pr_qty}],实际库存{codeQty},数量不足", 500); } List curCarryCodes = new(); for (int i = 0; i < carryCodesPart.Count; i++) { if (os.pr_qty > carryCodesPart[i].codeqty) { os.pr_qty -= carryCodesPart[i].codeqty; curCarryCodes.Add(carryCodesPart[i]); } else if (os.pr_qty <= carryCodesPart[i].codeqty) { var tmp = DeepCopyHelper.DeepCopy(carryCodesPart[i]); tmp.codeqty = os.pr_qty; curCarryCodes.Add(tmp); break; } } carryCodes.AddRange(curCarryCodes); var partCarryMats = curCarryCodes.Adapt>(); for (int i = 0; i < partCarryMats.Count; i++) { partCarryMats[i].need_qty = curCarryCodes[i].codeqty; } carryMats.AddRange(partCarryMats); } } if (carryMats.Count > 0) { carryMats.ForEach(x => x.id = SnowflakeIdHelper.NextId()); carryMats = carryMats.OrderBy(o => o.create_time).GroupBy(g => new { g.carry_id, g.material_id, g.code_batch }) .Select(x => { var arr = x.ToArray(); WmsCarryMat carryMat = arr[^arr.Length]; carryMat.need_qty = x.Sum(d => d.need_qty); return carryMat; }) .ToList(); await _db.Insertable(carryMats).ExecuteCommandAsync(); var dic = carryMats.DistinctBy(x => x.carry_id).ToDictionary(x => x.carry_id, x => x.need_qty); var allOutIds = new List(); var sortingOutIds = new List(); foreach (var pair in dic) { var codes = carryCodes.FindAll(x => x.carry_id == pair.Key); if (codes?.Count > 0) { if (pair.Value == codes.Sum(d => d.codeqty)) { allOutIds.Add(pair.Key); } else { sortingOutIds.Add(pair.Key); } } } carryIds = allOutIds.Concat(sortingOutIds).ToList(); if (carryIds?.Count > 0) { var carryId = carryIds[^carryIds.Count]; var curCurry = await _db.Queryable().SingleAsync(it => it.id == carryId); var isMatch = await IsCarryAndLocationMatchByCarryStd(curCurry, location); if (!isMatch) throw new AppFriendlyException("该载具无法放置到目标库位", 500); } await _db.Insertable(outstock).ExecuteCommandAsync(); await _db.Insertable(outstockDs).ExecuteCommandAsync(); await _db.Updateable().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.全部出).ToString(), source_id = outstock.source_id, source_code = outstock.source_code }).Where(it => allOutIds.Contains(it.id)).ExecuteCommandAsync(); await _db.Updateable().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.分拣出).ToString(), source_id = outstock.source_id, source_code = outstock.source_code }).Where(it => sortingOutIds.Contains(it.id)).ExecuteCommandAsync(); } var carrys = await _db.Queryable().Where(it => carryIds.Contains(it.id)).ToListAsync(); if (carrys?.Count > 0) { List preTasks = new(); List locIds = new(); foreach (var carry in carrys) { WmsPointH sPoint = await _db.Queryable().FirstAsync(it => it.location_id == carry.location_id); WmsPointH ePoint = await _db.Queryable().FirstAsync(it => it.location_id == outstock.location_id.ToString()); if (sPoint != null && ePoint != null) { var points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id); locIds.AddRange(points.Select(x => x.location_id).ToList()!); //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) if (points?.Count > 0) { if (points.Count <= 2) throw new AppFriendlyException("该路径不存在", 500); var curPreTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it => { var sPoint = it.FirstOrDefault(); var ePoint = it.LastOrDefault(); WmsPretaskH preTask = new() { org_id = _userManager.User.OrganizeId, startlocation_id = sPoint?.location_id ?? string.Empty, startlocation_code = sPoint?.location_code ?? string.Empty, endlocation_id = ePoint?.location_id ?? string.Empty, endlocation_code = ePoint?.location_code ?? string.Empty, start_floor = sPoint?.floor.ToString(), end_floor = ePoint?.floor.ToString(), bill_code = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_PRETASK_H_ENCODE).GetAwaiter().GetResult(), status = WmsWareHouseConst.PRETASK_BILL_STATUS_DXF_ID, biz_type = WmsWareHouseConst.BIZTYPE_WMSOUTSTOCK_ID, task_type = WmsWareHouseConst.WMS_PRETASK_OUTSTOCK_TYPE_ID, carry_id = carry.id, carry_code = carry.carry_code, area_id = sPoint?.area_id ?? string.Empty, area_code = it.Key, require_id = outstock.id.ToString(), require_code = outstock.bill_code?.ToString(), create_id = _userManager.UserId, create_time = DateTime.Now, source_id = outstock.source_id, source_code = outstock.source_code, }; return preTask; }).ToList(); if (location.is_sign == 0) { curPreTasks[^1].is_sign = 0; // 修改最后一个元素的是否签收值 } preTasks.AddRange(curPreTasks); } } } List pretaskCodes = new(); foreach (var pt in preTasks) { var partCodes = carryCodes.FindAll(x => x.carry_id == pt.carry_id).Distinct().ToList(); var curPreTaskCodes = partCodes.Adapt>(); curPreTaskCodes.ForEach(x => { x.id = SnowflakeIdHelper.NextId(); x.bill_id = pt.id; x.create_time = DateTime.Now; }); pretaskCodes.AddRange(curPreTaskCodes); } var isOk = await _wareHouseService.GenPreTask(preTasks, pretaskCodes); if (isOk) { outstockDs.ForEach(x => x.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID); await _db.Updateable(outstockDs).UpdateColumns(it => it.line_status).ExecuteCommandAsync(); await _db.Updateable().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == outstock.id).ExecuteCommandAsync(); GenPreTaskUpInput genPreTaskAfterUpInput = new(); genPreTaskAfterUpInput.CarryIds = preTasks.Select(x => x.carry_id).ToList(); genPreTaskAfterUpInput.LocationIds = new HashSet(locIds).ToList(); await _wareHouseService.GenInStockTaskHandleAfter(genPreTaskAfterUpInput, it => new WmsCarryH { is_lock = 1 }, it => new BasLocation { is_lock = 1 }); } } else throw new AppFriendlyException("库存不足", 500); } else throw new AppFriendlyException($"请输入物料明细", 500); await _db.Ado.CommitTranAsync(); } catch (Exception ex) { isSuccessful = false; JNPF.Logging.Log.Error(ex.Message); await _db.Ado.RollbackTranAsync(); throw; } finally { await Publish(nameof(IWareHouseService.GenTaskExecute)); } return isSuccessful; } public override async Task ModifyAsync(WareHouseUpInput input) { if (input == null) throw new ArgumentNullException(nameof(input)); try { await _db.Ado.BeginTranAsync(); var carryId = input.carryIds[^input.carryIds.Count]; var carry = await _db.Queryable().SingleAsync(it => it.id == carryId); if (carry != null) { var otds = await _db.Queryable().Where(it => it.bill_id == input.requireId).ToListAsync(); var outStatus = carry.out_status.ToEnum(); if (outStatus == EnumOutStatus.全部出) { //当前载具对应的所有条码插入 var carryCodes = await _db.Queryable().Where(it => it.carry_id == carryId).ToListAsync(); var outStockCodes = carryCodes.Adapt>(); outStockCodes.ForEach(x => { var billDId = otds?.Find(xx => xx.material_id == x.material_id && xx.code_batch == x.code_batch)?.id; if (billDId.IsNullOrEmpty()) { billDId = otds?.Find(xx => xx.material_id == x.material_id)?.id; } x.id = SnowflakeIdHelper.NextId(); x.bill_id = input.requireId; x.bill_d_id = billDId!; x.org_id = _userManager.User.OrganizeId; x.create_id = _userManager.UserId; x.create_time = DateTime.Now; }); await _db.Insertable(outStockCodes).ExecuteCommandAsync(); var detailIds = outStockCodes.Select(x => x.bill_d_id).ToList(); var curOutstockDetails = otds.FindAll(x => detailIds.Contains(x.id)); var dic = outStockCodes.GroupBy(g => g.bill_d_id).ToDictionary(x => x.Key, x => x.Select(x => x.codeqty).ToList()); foreach (var osd in curOutstockDetails) { if (dic.ContainsKey(osd.id)) { osd.qty += dic[osd.id].Sum(d => d); if (osd.qty >= osd.pr_qty) { osd.line_status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID; } else { osd.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID; } } } await _db.Updateable(curOutstockDetails).ExecuteCommandAsync(); if (otds.All(x => x.line_status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID)) { await _db.Updateable().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync(); //如果是自动单据,需要回更上层系统 } else { //如果没有完成,修改为工作中 await _db.Updateable().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync(); } await _wareCarryService.UpdateNullCarry(carry).Unwrap(); } else if (outStatus == EnumOutStatus.分拣出) { if (input.distaskCodes?.Count > 0) { var osCodes = input.distaskCodes.Adapt>(); osCodes.ForEach(x => { var billDId = otds?.Find(xx => xx.material_id == x.material_id && xx.code_batch == x.code_batch)?.id; if (billDId.IsNullOrEmpty()) { billDId = otds?.Find(xx => xx.material_id == x.material_id)?.id; } x.id = SnowflakeIdHelper.NextId(); x.bill_id = input.requireId; x.bill_d_id = billDId!; x.org_id = _userManager.User.OrganizeId; x.create_id = _userManager.UserId; x.create_time = DateTime.Now; }); await _db.Insertable(osCodes).ExecuteCommandAsync(); // 更新主表 var detailIds = osCodes.Select(x => x.bill_d_id).ToList(); var curOutstockDetails = otds.FindAll(x => detailIds.Contains(x.id)); var dic = osCodes.GroupBy(g => g.bill_d_id).ToDictionary(x => x.Key, x => x.Select(x => x.codeqty).ToList()); foreach (var osd in curOutstockDetails) { if (dic.ContainsKey(osd.id)) { osd.qty += dic[osd.id].Sum(d => d); if (osd.qty >= osd.pr_qty) { osd.qty = osd.pr_qty; osd.line_status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID; } else { osd.line_status = WmsWareHouseConst.BILLSTATUS_ON_ID; } } } await _db.Updateable(curOutstockDetails).ExecuteCommandAsync(); if (otds.All(x => x.line_status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID)) { //如果是自动单据,需要回更上层系统 await _db.Updateable().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_COMPLETE_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync(); } else { //如果没有完成,修改为工作中 await _db.Updateable().SetColumns(it => new WmsOutstockH { status = WmsWareHouseConst.BILLSTATUS_ON_ID }).Where(it => it.id == input.requireId).ExecuteCommandAsync(); } var carryCodes = await _db.Queryable().Where(it => input.carryIds.Contains(it.carry_id!)).ToListAsync(); var dicCodeQty = carryCodes.GroupBy(g => g.barcode).ToDictionary(x => x.Key, x => x.First().codeqty); var dicUpdate = new Dictionary(); var delBarcodes = new List(); foreach (var dtc in input.distaskCodes) { if (dicCodeQty.ContainsKey(dtc.barcode)) { if (dtc.codeqty < dicCodeQty[dtc.barcode]) { dicUpdate[dtc.barcode] = dicCodeQty[dtc.barcode] - dtc.codeqty; } else { delBarcodes.Add(dtc.barcode); } } } if (dicUpdate.Count > 0) { foreach (var pair in dicUpdate) { WmsCarryCode? carryCode = carryCodes.Find(x => x.barcode == pair.Key); if (carryCode != null) { carryCode.codeqty = pair.Value; await _db.Updateable(carryCode).UpdateColumns(it => it.codeqty).ExecuteCommandAsync(); } } var row = await _db.Updateable().SetColumns(it => new WmsCarryH { out_status = ((int)EnumOutStatus.正常).ToString() }).Where(it => input.carryIds.Contains(it.id)).ExecuteCommandAsync(); await _db.Deleteable().Where(it => input.carryIds.Contains(it.carry_id)).ExecuteCommandAsync(); } if (delBarcodes.Count > 0) { await _db.Deleteable().Where(it => delBarcodes.Contains(it.barcode)).ExecuteCommandAsync(); } //载具移入 var outStockH = await _db.Queryable().SingleAsync(it => it.id == input.requireId); var visulDevInput = new VisualDevModelDataCrInput(); visulDevInput.data = new Dictionary { [nameof(InStockStrategyQuery.warehouse_id)] = outStockH.warehouse_id, [nameof(WmsPointH.location_id)] = outStockH.location_id, [nameof(WmsCarryD.carry_id)] = input.carryIds.First(), [nameof(WmsCarryH.carry_code)] = carry.carry_code, [nameof(WmsHandleH.biz_type)] = input.bizTypeId, [nameof(WmsHandleH.create_id)] = _userManager.UserId, [nameof(WmsHandleH.create_time)] = DateTime.Now, [nameof(WmsMoveInstock.status)] = WmsWareHouseConst.BILLSTATUS_ADD_ID, [nameof(WmsHandleH.bill_code)] = _billRullService.GetBillNumber(WmsWareHouseConst.WMS_CARRYMOINSTK_ENCODE).GetAwaiter().GetResult(), }; await _wmsCarryMoveInStockService.CarryMoveIn(visulDevInput); } } await _db.Ado.CommitTranAsync(); } } catch (Exception) { await _db.Ado.RollbackTranAsync(); throw; } } } }