From c02f9216d5372b77bcda2219586e0e8a2ef7b882 Mon Sep 17 00:00:00 2001 From: majian <780924089@qq.com> Date: Fri, 11 Oct 2024 15:42:40 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=80=E5=94=AE=E5=8F=91=E8=B4=A7=E5=90=88?= =?UTF-8?q?=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Consts/WmsWareHouseConst.cs | 4 + .../Dto/Inputs/SaleReleaseMergeInput.cs | 14 + .../Tnb.WarehouseMgr/WmsCarryService.cs | 14 +- .../Tnb.WarehouseMgr/WmsSaleReleaseService.cs | 380 +++++------------- 4 files changed, 123 insertions(+), 289 deletions(-) create mode 100644 WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseMergeInput.cs diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs index aeb2e922..6cca55cc 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs @@ -267,6 +267,10 @@ namespace Tnb.WarehouseMgr.Entities.Consts /// 单据状态-待配送 /// public const string BILLSTATUS_TOBESHIPPED_ID = "26169434213669"; + /// + /// 单据状态-合并 + /// + public const string BILLSTATUS_MERGE_ID = "37495007710998"; /// /// 任务类型-入库TypeId diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseMergeInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseMergeInput.cs new file mode 100644 index 00000000..c4c066e7 --- /dev/null +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/Inputs/SaleReleaseMergeInput.cs @@ -0,0 +1,14 @@ +namespace Tnb.WarehouseMgr.Entities.Dto +{ + public class SaleReleaseMergeInput + { + /// + /// 组织ID + /// + public string org_id { get; set; } + /// + /// 来源单据id + /// + public List source_ids { get; set; } + } +} diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs index 90cbcea4..e63adae1 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsCarryService.cs @@ -81,7 +81,7 @@ namespace Tnb.WarehouseMgr public async Task GetCarryInfoByCode([FromRoute] string carrycode) { var carryOutPut = await _db.Queryable().Where(it => it.carry_code == carrycode).FirstAsync(); - + return carryOutPut; } /// @@ -303,7 +303,7 @@ namespace Tnb.WarehouseMgr { if (input.barCodes == null || input.barCodes.Count < 1) throw new ArgumentNullException(nameof(input.barCodes)); input.barCodes = input.barCodes.OrderBy(o => o).ToList(); - base.BarCodePrint(input.barCodes, input.copies,""); + base.BarCodePrint(input.barCodes, input.copies, ""); } @@ -350,7 +350,7 @@ namespace Tnb.WarehouseMgr wmsCarrybindH.location_code = wmsCarryH.location_code; List wmsCarrybindCodes = new List(); - + var wmsCarrybindCode = input.Adapt(); wmsCarrybindCode.carrybind_id = wmsCarrybindH.id; @@ -381,7 +381,7 @@ namespace Tnb.WarehouseMgr /// [HttpPost, NonUnify, AllowAnonymous] - public async Task MaterialByCarry(MaterialByCarryInput input) + public async Task MaterialByCarry(MaterialByCarryInput input) { try { @@ -436,7 +436,7 @@ namespace Tnb.WarehouseMgr } } } - + break; } case WmsWareHouseConst.BIZTYPE_WmsRawmatOutstock_ID: @@ -500,12 +500,12 @@ namespace Tnb.WarehouseMgr } - return "成功"; + return await ToApiResult(HttpStatusCode.OK, "成功", wmsCarryCodes); } catch (Exception ex) { await _db.Ado.RollbackTranAsync(); - throw new AppFriendlyException(ex.Message, 500); + return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); } } } diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs index 6236ec43..841a48db 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsSaleReleaseService.cs @@ -1,4 +1,5 @@ -using System.Security.Cryptography.X509Certificates; +using System.Linq; +using System.Security.Cryptography.X509Certificates; using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.VisualDev; using JNPF.Common.Enums; @@ -10,6 +11,7 @@ using JNPF.Systems.Interfaces.System; using JNPF.VisualDev; using JNPF.VisualDev.Entitys; using JNPF.VisualDev.Interfaces; +using Mapster; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.CodeAnalysis; @@ -163,6 +165,19 @@ namespace Tnb.WarehouseMgr } WmsSaleD wmsOutstockD = await _db.Queryable().FirstAsync(it => it.id == input.source_id); + WmsSaleH wmsSaleH = await _db.Queryable().Where(r => r.id == wmsOutstockD.bill_id).FirstAsync(); + if (wmsSaleH.status == WmsWareHouseConst.BILLSTATUS_CANCEL_ID) + { + throw new AppFriendlyException($"发货单{wmsSaleH.bill_code}已取消,无法下发", 500); + } + if (wmsSaleH.status == WmsWareHouseConst.BILLSTATUS_COMPLETE_ID) + { + throw new AppFriendlyException($"发货单{wmsSaleH.bill_code}已完成,无法下发", 500); + } + if (wmsSaleH.status == WmsWareHouseConst.BILLSTATUS_MERGE_ID) + { + throw new AppFriendlyException($"发货单{wmsSaleH.bill_code}已合并,无法下发", 500); + } await _db.Ado.BeginTranAsync(); //入库取终点 //出库起点 OutStockStrategyQuery outStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_CP_ID, material_id = wmsOutstockD.material_id, qty = input.qty, code_batch = wmsOutstockD.code_batch, Region_id = WmsWareHouseConst.REGION_CPOutstock_ID, dbConn = _db }; @@ -437,287 +452,6 @@ namespace Tnb.WarehouseMgr return await ToApiResult(HttpStatusCode.OK, "成功"); } - - /// - /// 下发 - /// - /// - /// - /// - //[HttpPost, NonUnify, AllowAnonymous] - //public async Task Distribute(SaleReleaseDistributeInput input) - //{ - // Logger.LogInformation($"【Distribute】 销售出库下发"); - // SemaphoreSlim semaphoreSlim = null; - // try - // { - // semaphoreSlim = _wareHouseService.GetSemaphore("outstock", WmsWareHouseConst.WAREHOUSE_CP_ID); - // await semaphoreSlim.WaitAsync(); - // if (input.qty <= 0) - // { - // throw new AppFriendlyException("数量必须大于0", 500); - // } - // if (string.IsNullOrEmpty(input.source_id)) - // { - // throw new AppFriendlyException("来源单据id不可为空", 500); - // } - - // WmsSaleD wmsOutstockD = await _db.Queryable().FirstAsync(it => it.id == input.source_id); - // await _db.Ado.BeginTranAsync(); - // //入库取终点 //出库起点 - // OutStockStrategyQuery outStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_CP_ID, material_id = wmsOutstockD.material_id, qty = input.qty, code_batch = wmsOutstockD.code_batch, Region_id = WmsWareHouseConst.REGION_CPOutstock_ID }; - // List> items = await _wareHouseService.OutStockStrategy_saleRelease(outStockStrategyInput); - - // decimal canOutstockQty = items.Sum(r => r.Item3.codeqty).ParseToDecimal(); - // if (canOutstockQty < input.qty) - // { - // throw new AppFriendlyException($@"当前可出库数量只有 {canOutstockQty.ToString("G")}", 500); - // } - - // List> items_sorttask = items.Where(r => r.Item1 == "分拣任务").ToList(); - // List> items_pretask = items.Where(r => r.Item1 == "预任务").ToList(); - - // Logger.LogInformation($"【Distribute】 预计生成{items_pretask.Count}条预任务"); - - - // List endLocations = null; - // // 自动发货 - // if (!input.isManual) - // { - // endLocations = await _db.Queryable().Where(r => _wareHouseService.GetFloor1OutstockLocation().Contains(r.id) && r.is_lock == 0 && r.is_use == "0").ToListAsync(); - - // if (endLocations.Count < items_pretask.Count) - // { - // throw new AppFriendlyException("一楼没有足够的未锁定且空闲的出库工位", 500); - // } - - // List endLocations_temp = await _db.Queryable().Where(r => r.region_id == WmsWareHouseConst.REGION_CPOutstockCache_ID && r.is_lock == 0 && r.is_use == "0").ToListAsync(); - - // if (endLocations_temp.Count < items_pretask.Count) - // { - // throw new AppFriendlyException($"三楼发货时,没有可用的暂存库位可以使用,需要下发任务{items_pretask.Count}条,可用的暂存库位只有{endLocations_temp.Count}条", 500); - // } - // } - // //人工发货 - // else - // { - // InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_CP_ID, Size = items_pretask.Count, Region_id = WmsWareHouseConst.REGION_CPManualOutstock_ID }; - // endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput); - - // if (endLocations.Count < items_pretask.Count) - // { - // throw new AppFriendlyException("三楼人工出库区没有足够的未锁定且空闲的出库工位", 500); - // } - // } - - - // // 预任务逻辑 - // foreach (Tuple item in items_pretask) - // { - // WmsCarryH carry = item.Item2; - // WmsCarryCode carryCode = item.Item3; - // BasLocation startLocation = item.Item4; - // // 根据一楼工位任务数平均分配任务 确定一楼工位 - - // BasLocation endLocation = null; - // // 自动发货 - // if (!input.isManual) - // { - // endLocation = await _db.Queryable().Where(r => _wareHouseService.GetFloor1OutstockLocation().Contains(r.id) && r.is_lock == 0 && r.is_use == "0").OrderBy("is_lock, task_nums, location_code").FirstAsync(); - - // if (endLocation == null) - // { - // throw new AppFriendlyException("一楼没有足够的未锁定且空闲的出库工位", 500); - // } - // } - // //人工发货 - // else - // { - // InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_CP_ID, Size = 1, Region_id = WmsWareHouseConst.REGION_CPManualOutstock_ID }; - // endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput); - - // if (endLocations.Count < 1) - // { - // throw new AppFriendlyException("三楼人工出库区没有足够的未锁定且空闲的出库工位", 500); - // } - // endLocation = endLocations[0]; - // } - // if (endLocation == null) - // { - // throw new AppFriendlyException("一楼没有足够的未锁定且空闲的出库工位", 500); - // } - // WmsPointH sPoint = null!; - // WmsPointH ePoint = null!; - - // sPoint = await _db.Queryable().FirstAsync(it => it.location_id == startLocation.id); - - // bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, endLocation); - // if (!isMatch) - // { - // throw new AppFriendlyException("库位与载具规格不匹配", 500); - // } - - // ePoint = await _db.Queryable().FirstAsync(it => it.location_id == endLocation.id); - - // if (ePoint != null) - // { - // } - // else - // { - // throw new AppFriendlyException($"库位{endLocation.location_code}未在点位表中维护对应点位", 500); - // } - - // string endLocationId = endLocation.id; - - // // 在线开发 - // //VisualDevEntity? templateEntity = await _visualDevService?.GetInfoById(ModuleConsts.MODULE_WMSDELIVERYPDA_ID, true)!; - // //await _runService.Create(templateEntity, input); - - // // 计算路径,插入预任务申请 - - // if (sPoint != null && ePoint != null) - // { - // List points = new List(); - // if (sPoint.area_code != ePoint.area_code) - // { - // points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id); - // //if (points.Count <= 2) - // //{ - // // throw new AppFriendlyException($"sPoint {sPoint.point_code} ePoint{ePoint.point_code}该路径不存在", 500); - // //} - // } - // else - // { - // points.Add(sPoint); - // points.Add(ePoint); - // } - - // //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) - // if (points?.Count > 0) - // { - // List preTasks = points.Where(it => !it.location_id.IsNullOrEmpty()).GroupBy(g => g.area_code).Select(it => - // { - // WmsPointH? sPoint = it.FirstOrDefault(); - // WmsPointH? ePoint = it.LastOrDefault(); - - // WmsPretaskH preTask = new() - // { - // org_id = _userManager!.User.OrganizeId, - // startlocation_id = sPoint?.location_id!, - // startlocation_code = sPoint?.location_code!, - // endlocation_id = ePoint?.location_id!, - // 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_WMSSALERELEASE_ID, - // task_type = WmsWareHouseConst.WMS_PRETASK_TRANSFER_TYPE_ID - // }; - // preTask.carry_id = carry.id; - // preTask.carry_code = carry.carry_code; - // preTask.area_id = sPoint?.area_id!; - // preTask.area_code = it.Key; - // preTask.require_id = input.source_id; - // preTask.require_code = ""; - // preTask.create_id = _userManager.UserId; - // preTask.create_time = DateTime.Now; - // return preTask; - // }).ToList(); - // bool isOk = await _wareHouseService.GenPreTask(preTasks, null!, _db); - // if (isOk) - // { - // if (endLocationId != null) - // { - // //查询库位表 - // BasLocation location = await _db.Queryable().SingleAsync(it => it.id == startLocation.id); - // { - // //载具加锁,增加库位信息 - // _ = await _db.Updateable().SetColumns(it => new WmsCarryH - // { - // carry_status = ((int)EnumCarryStatus.占用).ToString(), - // is_lock = 1, - // location_id = startLocation.id, - // location_code = location.location_code, - // require_id = input.source_id, - // biz_type = WmsWareHouseConst.BIZTYPE_WMSSALERELEASE_ID - // }).Where(it => it.id == carry.id).ExecuteCommandAsync(); - // } - - // //所有库位加锁 - // string?[] ids = new[] { startLocation.id, preTasks[0].endlocation_id, endLocationId }; - // _ = await _db.Updateable().SetColumns(it => new BasLocation { is_lock = 1 }).Where(it => ids.Contains(it.id)).ExecuteCommandAsync(); - - // } - // } - // } - - // } - // } - - // Logger.LogInformation($"【Distribute】 预计生成{items_sorttask.Count}条分拣任务"); - // // 分拣任务逻辑 - // foreach (Tuple item in items_sorttask) - // { - // WmsCarryH carry = item.Item2; - // WmsCarryCode carryCode = item.Item3; - // BasLocation startLocation = item.Item4; - - // // 锁定分拣载具 - // await _db.Updateable().SetColumns(r => r.is_lock == 1).Where(r => r.id == carry.id).ExecuteCommandAsync(); - - // Dictionary dic = new() - // { - // [nameof(WmsSortingtask.id)] = SnowflakeIdHelper.NextId(), - // [nameof(WmsSortingtask.bill_code)] = await _billRullService.GetBillNumber(WmsWareHouseConst.WMS_SORTINGTASK_ENCODE), - // [nameof(WmsSortingtask.org_id)] = input.org_id ?? _userManager.User.OrganizeId, - // [nameof(WmsSortingtask.qty)] = carryCode.codeqty, - // [nameof(WmsSortingtask.carry_id)] = carry.id, - // [nameof(WmsSortingtask.carry_code)] = carry.carry_code, - // [nameof(WmsSortingtask.status)] = WmsWareHouseConst.TASK_BILL_STATUS_DZX_ID, - // [nameof(WmsSortingtask.location_id)] = startLocation.id, - // [nameof(WmsSortingtask.location_code)] = startLocation.location_code, - // [nameof(WmsSortingtask.create_id)] = input.create_id ?? _userManager.UserId, - // [nameof(WmsSortingtask.create_time)] = DateTime.Now, - // [nameof(WmsSortingtask.source_id)] = input.source_id - // }; - - // VisualDevModelDataCrInput visualDevModelDataCrInput = new() - // { - // data = dic - // }; - - // //在线开发 - // VisualDevEntity? templateEntity = await _visualDevService.GetInfoById(ModuleConsts.MODULE_WMSSORTINGTASK_ID, false); - // await _runService.Create(templateEntity, visualDevModelDataCrInput); - // } - - // // 更新销售出库单子表已下发数量 - // await _db.Updateable().SetColumns(r => r.purchase_arriveqty == r.purchase_arriveqty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync(); - - // await _db.Ado.CommitTranAsync(); - // Logger.LogInformation($"【Distribute】 销售出库下发完成"); - // } - // catch (Exception ex) - // { - // await _db.Ado.RollbackTranAsync(); - // Logger.LogError($"【Distribute】 销售出库 {ex.Message}"); - // Logger.LogError($"【Distribute】 销售出库 {ex.StackTrace}"); - // return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); - // } - // finally - // { - // semaphoreSlim.Release(); - // await InvokeGenPretaskExcute(); - // } - - // return await ToApiResult(HttpStatusCode.OK, "成功"); - //} - /// /// 分拣 /// @@ -769,6 +503,88 @@ namespace Tnb.WarehouseMgr + /// + /// 下发 电梯第三次改动 + /// + /// + /// + /// + [HttpPost, NonUnify, AllowAnonymous] + public async Task Merge(SaleReleaseMergeInput input) + { + Logger.LogInformation($"【Merge】 销售发货合并"); + SemaphoreSlim semaphoreSlim = null; + try + { + semaphoreSlim = _wareHouseService.GetSemaphore("outstock", WmsWareHouseConst.WAREHOUSE_CP_ID); + await semaphoreSlim.WaitAsync(); + if (input.source_ids == null || input.source_ids.Count == 0) + { + throw new AppFriendlyException("至少选择一张发货单", 500); + } + + List wmsSaleHs = await _db.Queryable().Where(r => input.source_ids.Contains(r.id)).ToListAsync(); + + List wmsSaleDs = await _db.Queryable().Where(r => input.source_ids.Contains(r.bill_id)).ToListAsync(); + + List status_wmsSaleHs = wmsSaleHs.Where(r => r.status != WmsWareHouseConst.BILLSTATUS_ADD_ID).ToList(); + if (status_wmsSaleHs.Count() > 0) + { + throw new AppFriendlyException($"发货单{string.Join(",", status_wmsSaleHs.Select(x => x.bill_code))}状态不为新增,不能合并!", 500); + } + + List used_wmsSaleDs = wmsSaleDs.Where(r => r.purchase_arriveqty > 0).ToList(); + if (used_wmsSaleDs.Count() > 0) + { + List used_wmsSaleHs = wmsSaleHs.Where(r => used_wmsSaleDs.Select(x => x.bill_id).Contains(r.id)).ToList(); + throw new AppFriendlyException($"发货单{string.Join(",", used_wmsSaleHs.Select(x => x.bill_code))}已下发,不能进行合并!", 500); + } + string Code = await _billRullService.GetBillNumber("WmsSale"); + WmsSaleH newWmsSaleH = wmsSaleHs[0].Adapt(); + newWmsSaleH.id = SnowflakeIdHelper.NextId(); + newWmsSaleH.bill_code = Code; + newWmsSaleH.erp_bill_code = string.Join(",", wmsSaleHs.Select(x => x.erp_bill_code)); + newWmsSaleH.customer_id = string.Join(",", wmsSaleHs.Select(x => x.customer_id)); + newWmsSaleH.customer_code = string.Join(",", wmsSaleHs.Select(x => x.customer_code)); + newWmsSaleH.customer_name = string.Join(",", wmsSaleHs.Select(x => x.customer_name)); + newWmsSaleH.create_time = DateTime.Now; + newWmsSaleH.create_id = _userManager.UserId; + + List newWmsSaleDs = new List(); + var group = wmsSaleDs.GroupBy(g => new { g.material_id, g.unit_id, g.code_batch }); + foreach (var item in group) + { + WmsSaleD newWmsSaleD = item.ToList()[0].Adapt(); + newWmsSaleD.id = SnowflakeIdHelper.NextId(); + newWmsSaleD.bill_id = newWmsSaleH.id; + decimal newqty = wmsSaleDs.Where(r => r.material_id == item.Key.material_id && r.unit_id == item.Key.unit_id && r.code_batch == item.Key.code_batch).Sum(r => r.purchase_qty); + newWmsSaleD.purchase_qty = newqty; + newWmsSaleDs.Add(newWmsSaleD); + } + foreach (var item in wmsSaleHs) + item.status = WmsWareHouseConst.BILLSTATUS_MERGE_ID; + await _db.Ado.BeginTranAsync(); + await _db.Insertable(newWmsSaleH).ExecuteCommandAsync(); + await _db.Insertable(newWmsSaleDs).ExecuteCommandAsync(); + await _db.Updateable(wmsSaleHs).UpdateColumns(r => r.status).ExecuteCommandAsync(); + await _db.Ado.CommitTranAsync(); + Logger.LogInformation($"【Merge】 销售发货合并完成: {string.Join(",", wmsSaleHs.Select(x => x.bill_code))} => {Code}"); + } + catch (Exception ex) + { + await _db.Ado.RollbackTranAsync(); + Logger.LogError($"【Merge】 销售发货 {ex.Message}"); + Logger.LogError($"【Merge】 销售发货 {ex.StackTrace}"); + return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); + } + finally + { + semaphoreSlim.Release(); + await InvokeGenPretaskExcute(); + } + + return await ToApiResult(HttpStatusCode.OK, "成功"); + } } }