using System.Security.Cryptography.X509Certificates; using JNPF.Common.Core.Manager; using JNPF.Common.Dtos.VisualDev; using JNPF.Common.Enums; using JNPF.Common.Filter; using JNPF.Common.Security; using JNPF.FriendlyException; using JNPF.VisualDev; using JNPF.VisualDev.Entitys; using JNPF.VisualDev.Entitys.Dto.VisualDevModelData; using JNPF.VisualDev.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using NPOI.POIFS.Storage; using SqlSugar; using Tnb.BasicData.Entities; using Tnb.ProductionMgr.Entities; 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.Dto.Outputs; using Tnb.WarehouseMgr.Entities.Entity; using Tnb.WarehouseMgr.Entities.Enums; using Tnb.WarehouseMgr.Interfaces; using JNPF.Common.Extension; using JNPF.Systems.Interfaces.System; namespace Tnb.WarehouseMgr { [OverideVisualDev(ModuleConsts.MODULE_WMSPACKINSTOCK_ID)] [ServiceModule(BizTypeId)] public class WmsPackInstockService : BaseWareHouseService, IWmsPackInstockService { private const string BizTypeId = WmsWareHouseConst.BIZTYPE_WMSPACKINSTOCK_ID; private readonly ISqlSugarClient _db; private readonly IRunService _runService; private readonly IVisualDevService _visualDevService; private readonly IUserManager _userManager; private readonly IWareHouseService _wareHouseService; private readonly IWmsCarryBindService _wmsCarryBindService; private readonly IBillRullService _billRullService; public static SemaphoreSlim s_packInstockSemaphore = new(1); private readonly IWmsCarryService _wmsCarryService; public WmsPackInstockService( ISqlSugarRepository repository, IRunService runService, IVisualDevService visualDevService, IWareHouseService wareHouseService, IUserManager userManager, IWmsCarryBindService wmsCarryBindService, IBillRullService billRullService, IWmsCarryService wmsCarryService) { _db = repository.AsSugarClient(); _runService = runService; _visualDevService = visualDevService; _userManager = userManager; _wareHouseService = wareHouseService; _wmsCarryBindService = wmsCarryBindService; _billRullService = billRullService; _wmsCarryService = wmsCarryService; } public override async Task ModifyAsync(WareHouseUpInput input) { if (input == null) { throw new ArgumentNullException(nameof(input)); } try { //if (input.wmsDistaskH.start_floor == 4 && input.wmsDistaskH.end_floor == 4) { WmsCarryCode wmsCarryCode = await _db.Queryable().Where(r => r.carry_id == input.wmsDistaskH.carry_id).FirstAsync(); await _db.Updateable().SetColumns(r => r.qty == r.qty + wmsCarryCode.codeqty).Where(r => r.id == input.wmsDistaskH.require_id).ExecuteCommandAsync(); WmsPackInstockD wmsPackInstockD = await _db.Queryable().Where(r => r.id == input.wmsDistaskH.require_id).FirstAsync(); if (wmsPackInstockD != null) { int row = await _db.Updateable().SetColumns(r => new WmsCarryCode { auxprop_gys = wmsPackInstockD.auxprop_gys, auxprop_xph = wmsPackInstockD.auxprop_xph }).Where(r => r.carry_id == input.wmsDistaskH.carry_id).ExecuteCommandAsync(); } else { throw new Exception($"【WmsPackInstockService ModifyAsync】id为{input.wmsDistaskH.require_id}的包材入库明细在系统中不存在"); } } } catch (Exception ex) { Logger.LogWarning("【WmsPackInstockService ModifyAsync】" + ex.Message); Logger.LogWarning("【WmsPackInstockService ModifyAsync】" + ex.StackTrace); } } [HttpPost, NonUnify, AllowAnonymous] public async Task List(TransferInstockHListInput input) { try { JObject jobject = new JObject(); jobject["code"] = "200"; List wmsPackInstockD = _db.Queryable().Where(r => r.bill_id == input.id && r.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).ToList(); jobject["data"] = JArray.Parse(JsonConvert.SerializeObject(wmsPackInstockD)); return await Task.FromResult(jobject); } catch (Exception ex) { return Task.FromResult(ex); } } /// /// 1楼到4楼 包材入库 /// /// /// /// [HttpPost, NonUnify, AllowAnonymous] public async Task PackInstock(OutsourcedPartsInstockInput input) { try { if (string.IsNullOrEmpty(input.carry_code)) { throw new AppFriendlyException("载具编号不可为空", 500); } if (string.IsNullOrEmpty(input.material_id)) { throw new AppFriendlyException("物料id不可为空", 500); } if (input.qty <= 0) { throw new AppFriendlyException("数量必须大于0", 500); } if (string.IsNullOrEmpty(input.source_id)) { throw new AppFriendlyException("包材入库明细id不可为空", 500); } if (string.IsNullOrEmpty(input.startlocation_id)) { throw new AppFriendlyException("起点不可为空", 500); } WmsPackInstockD wmsPackInstockD = await _db.Queryable().Where(r => r.id == input.source_id).FirstAsync(); if (wmsPackInstockD.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID) { throw new AppFriendlyException("此包材入库任务已完成,不允许重复提交", 500); } await s_packInstockSemaphore.WaitAsync(); await _db.Ado.BeginTranAsync(); //入库取终点 //出库起点 InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = WmsWareHouseConst.WAREHOUSE_BCK_ID, Size = 1 }; List endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput); if (endLocations.Count == 0) { throw new AppFriendlyException("没有可用的入库库位", 500); } WmsPointH sPoint = null!; WmsPointH ePoint = null!; sPoint = await _db.Queryable().FirstAsync(it => it.location_id == input.startlocation_id); if (endLocations?.Count > 0) { WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.carry_code == input.carry_code); //if (carry.carry_status == "1") //{ // throw new AppFriendlyException("载具已占用!", 500); //} if (carry.is_lock == 1) { throw new AppFriendlyException("载具已锁定!", 500); } BasLocation loc = await _db.Queryable().SingleAsync(it => it.id == endLocations[0].id); bool isMatch = await IsCarryAndLocationMatchByCarryStd(carry, loc); if (!isMatch) { throw new AppFriendlyException("库位与载具规格不匹配", 500); } ePoint = await _db.Queryable().FirstAsync(it => it.location_id == endLocations[0].id); } else { throw new AppFriendlyException($"库位{endLocations[0].location_code}未在点位表中维护对应点位", 500); } string endLocationId = endLocations[0].id; // 计算路径,插入预任务申请 if (sPoint != null && ePoint != null) { List points = new List(); if (sPoint.area_code != ePoint.area_code) { points = await _wareHouseService.PathAlgorithms(sPoint.id, ePoint.id); Logger.LogError($"【PackInstock】 选择了 {sPoint.point_code} {ePoint.point_code}"); if (points.Count <= 2) { throw new AppFriendlyException($"sPoint {sPoint.point_code} ePoint{ePoint.point_code}该路径不存在", 500); } } else { points.Add(sPoint); points.Add(ePoint); } WmsCarryH wmsCarryH = await _db.Queryable().FirstAsync(it => it.carry_code == input.carry_code); //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) 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_WMSPACKINSTOCK_ID, task_type = WmsWareHouseConst.WMS_PRETASK_TRANSFER_TYPE_ID }; preTask.carry_id = wmsCarryH.id; preTask.carry_code = wmsCarryH.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 == input.startlocation_id); { //载具加锁,增加库位信息 _ = await _db.Updateable().SetColumns(it => new WmsCarryH { carry_status = ((int)EnumCarryStatus.占用).ToString(), is_lock = 1, location_id = input.startlocation_id, location_code = location.location_code }).Where(it => it.id == wmsCarryH.id).ExecuteCommandAsync(); } //所有库位加锁 string?[] ids = new[] { input.startlocation_id, endLocationId }; _ = await _db.Updateable().SetColumns(it => new BasLocation { is_lock = 1 }).Where(it => ids.Contains(it.id)).ExecuteCommandAsync(); BasMaterial basMaterial = await _db.Queryable().FirstAsync(it => it.id == input.material_id); BindCarryCodeInput bindCarryCodeInput = new BindCarryCodeInput(); bindCarryCodeInput.carry_id = wmsCarryH.id; bindCarryCodeInput.barcode = wmsCarryH.carry_code; bindCarryCodeInput.codeqty = input.qty; bindCarryCodeInput.material_id = input.material_id; bindCarryCodeInput.material_code = basMaterial.code; bindCarryCodeInput.material_name = basMaterial.name; bindCarryCodeInput.location_id = endLocations[0].id; bindCarryCodeInput.location_code = endLocations[0].location_code; bindCarryCodeInput.code_batch = wmsPackInstockD.pi_code; bindCarryCodeInput.unit_id = basMaterial.unit_id; await _wmsCarryService.BindCarryMaterial(bindCarryCodeInput); } } } } // 更新包材入库单子表已下发数量 await _db.Updateable().SetColumns(r => r.xf_qty == r.xf_qty + input.qty).Where(r => r.id == input.source_id).ExecuteCommandAsync(); // 已下发数量达到需求数量回写已完成 wmsPackInstockD = await _db.Queryable().Where(r => r.id == input.source_id).FirstAsync(); if (wmsPackInstockD.xf_qty == wmsPackInstockD.pr_qty) { await _db.Updateable().SetColumns(r => r.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).Where(r => r.id == input.source_id).ExecuteCommandAsync(); } // 入库明细都完成 回写主表完成状态 List wmsPackInstockDs = _db.Queryable().InnerJoin((a, b) => a.bill_id == b.bill_id).Where((a, b) => a.id == input.source_id) .Where((a, b) => b.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).ToList(); if (wmsPackInstockDs.Count == 0) { await _db.Updateable().SetColumns(r => r.status == WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).Where(r => r.id == wmsPackInstockD.bill_id).ExecuteCommandAsync(); } await _db.Ado.CommitTranAsync(); } catch (Exception ex) { Logger.LogError($"【PackInstock】 {ex.Message}"); Logger.LogError($"【PackInstock】 {ex.StackTrace}"); await _db.Ado.RollbackTranAsync(); return await ToApiResult(HttpStatusCode.InternalServerError, ex.Message); } finally { _ = s_packInstockSemaphore.Release(); await InvokeGenPretaskExcute(); } return await ToApiResult(HttpStatusCode.OK, "成功"); } } }