diff --git a/BasicData/Tnb.BasicData.Entities/Consts/CodeTemplateConst.cs b/BasicData/Tnb.BasicData.Entities/Consts/CodeTemplateConst.cs index d64fbec0..1c2ed6e1 100644 --- a/BasicData/Tnb.BasicData.Entities/Consts/CodeTemplateConst.cs +++ b/BasicData/Tnb.BasicData.Entities/Consts/CodeTemplateConst.cs @@ -94,6 +94,10 @@ namespace Tnb.BasicData /// /模具保养 /// public const string MOLDMAINTENANCE_CODE = "MoldMaintenance"; + /// + /// 质量暂控处理单 + /// + public const string QCCONTROLTEMP_CODE = "QcControlTempH"; } } \ No newline at end of file diff --git a/BasicData/Tnb.BasicData/BasLocationService.cs b/BasicData/Tnb.BasicData/BasLocationService.cs index af13f6d3..e5115062 100644 --- a/BasicData/Tnb.BasicData/BasLocationService.cs +++ b/BasicData/Tnb.BasicData/BasLocationService.cs @@ -1,5 +1,6 @@ using JNPF.DependencyInjection; using JNPF.DynamicApiController; +using JNPF.FriendlyException; using Microsoft.AspNetCore.Mvc; using SqlSugar; using Tnb.BasicData.Entities; @@ -48,5 +49,37 @@ namespace Tnb.BasicData List items = await _db.Queryable().Where(it => locIds.Contains(it.id)).ToListAsync(); return items; } + + + + /// + /// 根据库位编码,清空库位 + /// + /// + /// + [HttpPost] + public async Task ModifyClearLocation(Dictionary dic) + { + try + { + var location_code = dic["code"].ToString(); + if (string.IsNullOrEmpty(location_code)) + throw Oops.Bah("库位编码不能为空"); + + var location = await _db.Queryable().Where(r => r.location_code == location_code).FirstAsync(); + if (location == null) + throw Oops.Bah($"库位编号{location_code}不存在"); + await _db.Ado.BeginTranAsync(); + //把状态改为空闲 + await _db.Updateable().SetColumns(r => r.is_use == "0").Where(r=>r.id==location.id).ExecuteCommandAsync(); + await _db.Ado.CommitTranAsync(); + } + catch(Exception e) + { + await _db.Ado.RollbackTranAsync(); + throw Oops.Bah(e.Message); + } + return "成功"; + } } } diff --git a/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdMoTaskDefectRecordD.cs b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdMoTaskDefectRecordD.cs new file mode 100644 index 00000000..26bca0db --- /dev/null +++ b/ProductionMgr/Tnb.ProductionMgr.Entities/Entity/PrdMoTaskDefectRecordD.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JNPF.Common.Contracts; +using JNPF.Common.Security; +using SqlSugar; + +namespace Tnb.ProductionMgr.Entities.Entity +{ + /// + /// 生产报废记录子表 + /// + [SugarTable("prd_mo_task_defect_record_d")] + public partial class PrdMoTaskDefectRecordD:BaseEntity + { + public PrdMoTaskDefectRecordD() + { + id=SnowflakeIdHelper.NextId(); + } + /// + /// 主表id + /// + public string bill_id { get; set; } + + /// + /// 来源单据id + /// + public string source_id { get; set; } + /// + /// 料箱id + /// + public string carry_id { get; set; } + /// + /// 料箱code + /// + public string carry_code { get; set; } + /// + /// 报废数量 + /// + public string scrap_qty { get; set; } + /// + /// 提报人 + /// + public string submiter_id { get;set; } + /// + /// 处理人 + /// + public string maker_id { get; set; } + /// + /// 处理时间 + /// + public DateTime? make_time { get;set; } + } +} diff --git a/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs b/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs index 89b1b690..a8b22004 100644 --- a/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs +++ b/ProductionMgr/Tnb.ProductionMgr/PrdMoTaskService.cs @@ -2758,6 +2758,7 @@ namespace Tnb.ProductionMgr } catch (Exception e) { + await db.Ado.RollbackTranAsync(); Log.Error("提报入库任务下发失败:"+e.Message, e); throw new Exception("提报入库任务下发失败:"+e.Message); } diff --git a/QcMgr/Tnb.QcMgr.Entities/Dto/CheckTask.cs b/QcMgr/Tnb.QcMgr.Entities/Dto/CheckTask.cs index 899f8751..8e3dd535 100644 --- a/QcMgr/Tnb.QcMgr.Entities/Dto/CheckTask.cs +++ b/QcMgr/Tnb.QcMgr.Entities/Dto/CheckTask.cs @@ -220,7 +220,7 @@ public List>? checktypes { get; set; } - public CheckCarry carryInfo { get; set; } + public List carryInfo { get; set; } } public class Checktype { diff --git a/QcMgr/Tnb.QcMgr.Entities/Dto/QcTempControlHOutput.cs b/QcMgr/Tnb.QcMgr.Entities/Dto/QcTempControlHOutput.cs index 1e995ac5..f3d4fa4c 100644 --- a/QcMgr/Tnb.QcMgr.Entities/Dto/QcTempControlHOutput.cs +++ b/QcMgr/Tnb.QcMgr.Entities/Dto/QcTempControlHOutput.cs @@ -281,10 +281,23 @@ namespace Tnb.QcMgr.Entities.Dto /// 单位 /// public string unit_code { get; set; } + + } + + public class QcTempControlPickQualifiedQtyOutput + { /// /// 暂控数量 /// - public decimal? control_qty { get; set; } + public string temp_control_qty { get; set; } + /// + /// 合格数量 + /// + public string qualified_qty { get; set; } + /// + /// 不合格数量 + /// + public string unQualified_qty { get; set; } } } diff --git a/QcMgr/Tnb.QcMgr.Entities/Entity/QcTempControlD.cs b/QcMgr/Tnb.QcMgr.Entities/Entity/QcTempControlD.cs new file mode 100644 index 00000000..a0507bd0 --- /dev/null +++ b/QcMgr/Tnb.QcMgr.Entities/Entity/QcTempControlD.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JNPF.Common.Contracts; +using JNPF.Common.Security; +using SqlSugar; + +namespace Tnb.QcMgr.Entities.Entity +{ + /// + /// 质量暂控处理子表 + /// + [SugarTable("qc_temp_control_d")] + public partial class QcTempControlD:BaseEntity + { + public QcTempControlD() { + id=SnowflakeIdHelper.NextId(); + } + + /// + /// 暂控表单id + /// + public string bill_id { get;set; } + /// + /// 载具id + /// + public string carry_id { get; set; } + /// + /// 载具编号 + /// + public string carry_code { get;set; } + /// + /// 仓库id + /// + public string warehouse_id { get; set; } + /// + /// 仓库编号 + /// + public string warehouse_code { get; set; } + /// + /// 库位id + /// + public string location_id { get; set; } + /// + /// 库位编号 + /// + public string location_code { get;set; } + /// + /// 数量 + /// + public string qty { get; set; } + /// + /// 提报人 + /// + public string submiter { get; set; } + /// + /// 处理人id + /// + public string maker_id { get; set; } + /// + /// 创建人id + /// + public string create_id { get; set; } + /// + /// 创建时间 + /// + public DateTime? create_time { get; set;} + /// + /// 修改人id + /// + public string modify_id { get; set; } + /// + /// 修改时间 + /// + public DateTime? modify_time { get; set; } + /// + /// 检验状态(暂控,让步接收) + /// + public string check_status { get;set; } + /// + /// 呼叫状态 + /// + public string call_status { get; set; } + /// + /// 不合格数量 + /// + public string unqualified_qty { get; set; } + /// + /// 合格数量 + /// + public string qualified_qty { get; set; } + /// + /// 挑选状态(未挑选,已挑选) + /// + public string pick_status { get; set; } + /// + /// 暂控料入库预任务id + /// + public string pre_task_id { get;set; } + } +} diff --git a/QcMgr/Tnb.QcMgr.Entities/Entity/QcTempControlH.cs b/QcMgr/Tnb.QcMgr.Entities/Entity/QcTempControlH.cs new file mode 100644 index 00000000..1502dd4d --- /dev/null +++ b/QcMgr/Tnb.QcMgr.Entities/Entity/QcTempControlH.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using JNPF.Common.Contracts; +using JNPF.Common.Security; +using SqlSugar; + +namespace Tnb.QcMgr.Entities.Entity +{ + /// + /// 质量暂控处理单主表 + /// + [SugarTable("qc_temp_control_h")] + public partial class QcTempControlH:BaseEntity + { + public QcTempControlH() { + id = SnowflakeIdHelper.NextId(); + } + /// + /// 单据编号 + /// + public string bill_code { get; set; } + /// + /// 来源单据编号 + /// + public string source_code { get; set; } + /// + /// 生产任务单号 + /// + public string pro_task_code { get; set; } + /// + /// 出库仓库id + /// + public string out_warehouse_id { get; set;} + /// + /// 入库仓库id + /// + public string in_warehouse_id { get; set;} + /// + /// 物料id + /// + public string material_id { get; set; } + /// + /// 物料名称 + /// + public string material_code { get; set; } + /// + /// 暂控料箱数 + /// + public string control_lx_qty { get; set; } + /// + /// 暂控数量 + /// + public string control_qty { get;set; } + /// + /// 结论(暂控,让步接收) + /// + public string result { get; set; } + /// + /// 记录人id + /// + public string loger_id { get; set; } + /// + /// 确认人id + /// + public string confirmer_id { get; set; } + /// + /// 状态 + /// + public string status { get; set; } + /// + /// 已呼叫箱数 + /// + public string called_box_qty { get;set; } + /// + /// 已呼叫数量 + /// + public string called_qty { get; set; } + /// + /// 剩余呼叫箱数 + /// + public string leave_call_box_qty { get; set; } + /// + /// 剩余呼叫数量 + /// + public string leave_call_qty { get; set; } + + public string create_id { get; set; } + public DateTime? create_time { get; set; } + + public string modify_id { get; set; } + + public DateTime? modify_time { get; set; } + } +} diff --git a/QcMgr/Tnb.QcMgr.Entities/Enums/EnumTempControlStatus.cs b/QcMgr/Tnb.QcMgr.Entities/Enums/EnumTempControlStatus.cs new file mode 100644 index 00000000..81b10e0c --- /dev/null +++ b/QcMgr/Tnb.QcMgr.Entities/Enums/EnumTempControlStatus.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tnb.QcMgr.Entities.Enums +{ + /// + /// 暂控处理单状态 + /// + public enum EnumTempControlStatus + { + 待确认=1, + 待下发=2, + 已下发=3, + 执行中=4, + 已同步=5 + } +} diff --git a/QcMgr/Tnb.QcMgr/QcCheckTaskService.cs b/QcMgr/Tnb.QcMgr/QcCheckTaskService.cs index f26f2e7a..52d0f5e5 100644 --- a/QcMgr/Tnb.QcMgr/QcCheckTaskService.cs +++ b/QcMgr/Tnb.QcMgr/QcCheckTaskService.cs @@ -29,6 +29,11 @@ using Tnb.WarehouseMgr.Entities.Enums; using Tnb.ProductionMgr.Entities.Dto.PrdManage; using Tnb.WarehouseMgr.Entities; using JNPF.Common.Extension; +using Tnb.QcMgr.Entities.Entity; +using Tnb.BasicData; +using JNPF.Systems.Interfaces.System; +using NPOI.SS.Formula.Functions; +using Tnb.QcMgr.Entities.Enums; namespace Tnb.QcMgr { @@ -46,13 +51,15 @@ namespace Tnb.QcMgr private readonly IWmsSaleService _wmsSaleService; private readonly IWmsPurchaseService _wmsPurchaseService; private readonly IPrdMoTaskService _prdMoTaskService; + private readonly IBillRullService _billRullService; private static SemaphoreSlim prdreportSemaphore = new(1); public OverideVisualDevFunc OverideFuncs { get; } = new OverideVisualDevFunc(); public QcCheckTaskService(ISqlSugarRepository repository, IUserManager userManager, IWmsSaleService wmsSaleService, IPrdMoTaskService prdMoTaskService, - IWmsPurchaseService wmsPurchaseService) + IWmsPurchaseService wmsPurchaseService, + IBillRullService billRullService) { _repository = repository; _userManager = userManager; @@ -60,6 +67,7 @@ namespace Tnb.QcMgr _wmsSaleService= wmsSaleService; _prdMoTaskService = prdMoTaskService; _wmsPurchaseService= wmsPurchaseService; + _billRullService = billRullService; } private async Task GetListAsync(VisualDevModelListQueryInput input) @@ -259,6 +267,7 @@ namespace Tnb.QcMgr [HttpPost] public async Task SaveData(CheckTaskInput CheckTaskInput) { + //CheckTaskInput.startEndTime = new long[] { 1730084456000, 1730170856000 }; await prdreportSemaphore.WaitAsync(); ISqlSugarClient db = _repository.AsSugarClient(); try @@ -289,7 +298,7 @@ namespace Tnb.QcMgr #region 质检结论不合格, 需要记录暂控时间区间,并且记录载具信息 if (CheckTaskInput.result == "no")//质检结论不合格,记录暂控时间 { - if(CheckTaskInput.startEndTime==null || CheckTaskInput.startEndTime.Length <= 1) + if (CheckTaskInput.startEndTime == null || CheckTaskInput.startEndTime.Length <= 1) { throw Oops.Bah("不合格时,请选择时间区间"); } @@ -315,10 +324,10 @@ namespace Tnb.QcMgr { foreach (ExecItemInput item in exextype.items) { - if (item.postItemForm == null) - { - throw Oops.Oh("执行失败"); - } + //if (item.postItemForm == null) + //{ + // throw Oops.Oh("执行失败"); + //} QcCheckExecD? QcCheckExecD = QcCheckExecDs.Where(p => p.id == item.itemdid).FirstOrDefault(); if (QcCheckExecD == null) @@ -376,6 +385,8 @@ namespace Tnb.QcMgr .SetColumns(x => x.attachment == QcCheckExecH.attachment) .SetColumns(x => x.qty == QcCheckExecH.qty) .SetColumns(x => x.rqty == QcCheckExecH.rqty) + .SetColumns(x => x.control_start_time == QcCheckExecH.control_start_time) + .SetColumns(x => x.control_end_time == QcCheckExecH.control_end_time) .Where(x => x.id == CheckTaskInput.mainid) .ExecuteCommandAsync(); _ = await db.Deleteable(QcCheckExecDdel).ExecuteCommandAsync(); @@ -395,9 +406,10 @@ namespace Tnb.QcMgr mesCheckdCallbackUpinput.maintableid = QcCheckExecH.extras; mesCheckdCallbackUpinput.check_conclusion = dic.Where(p => p.Key == CheckTaskInput.result).Any() ? dic.Where(p => p.Key == CheckTaskInput.result).First().Value : 0; await _wmsPurchaseService.MesCheckdPurchaseCallback(mesCheckdCallbackUpinput); - }else if (QcCheckExecH.checktype == WmsWareHouseConst.LINGBUJIANZUIZHONGJIANYAN_ID) + } + else if (QcCheckExecH.checktype == WmsWareHouseConst.LINGBUJIANZUIZHONGJIANYAN_ID) { - PrdReport prdReport = await db.Queryable().SingleAsync(x=>x.id==QcCheckExecH.report_id); + PrdReport prdReport = await db.Queryable().SingleAsync(x => x.id == QcCheckExecH.report_id); decimal pqty = prdReport.reported_qty.Value - rqty; if (rqty > Decimal.Parse(QcCheckExecH.checknum)) { @@ -411,18 +423,19 @@ namespace Tnb.QcMgr .SetColumns(x => x.is_check == isCheck) .Where(x => x.carry_code == prdReport.material_box_code) .ExecuteCommandAsync(); - + await _prdMoTaskService.ReportInstock(new CheckCompleteInput() { report_id = QcCheckExecH.report_id, pqty = pqty, rqty = rqty, check_result = ((EnumCheckConclusion)dic[CheckTaskInput.result]).ToString(), - },prdReport,db); + }, prdReport, db); } - }else if (QcCheckExecH.checktype == WmsWareHouseConst.XUNJIAN_ID || QcCheckExecH.checktype == WmsWareHouseConst.SHOUJIAN_ID || QcCheckExecH.checktype == WmsWareHouseConst.MOJIAN_ID ) + } + else if (QcCheckExecH.checktype == WmsWareHouseConst.XUNJIAN_ID || QcCheckExecH.checktype == WmsWareHouseConst.SHOUJIAN_ID || QcCheckExecH.checktype == WmsWareHouseConst.MOJIAN_ID) { - PrdMoTask prdMoTask = await db.Queryable().Where(x=>x.mo_task_code==QcCheckExecH.mo_task_code && x.id!=null).FirstAsync(); + PrdMoTask prdMoTask = await db.Queryable().Where(x => x.mo_task_code == QcCheckExecH.mo_task_code && x.id != null).FirstAsync(); if (CheckTaskInput.result == "no") { string pauseReason = QcCheckExecH.checktype == WmsWareHouseConst.XUNJIAN_ID ? "巡检不合格" : QcCheckExecH.checktype == WmsWareHouseConst.SHOUJIAN_ID ? "首检不合格" : "末检不合格"; @@ -431,57 +444,186 @@ namespace Tnb.QcMgr TaskIds = NPOI.Util.Arrays.AsList(prdMoTask.id), Behavior = "Pause", PauseReeson = pauseReason - },db); - await _prdMoTaskService.SelfTestScrapped2(new SelfTestScrappedInput() + }, db); + + #region 没看懂逻辑,暂时注释 + //await _prdMoTaskService.SelfTestScrapped2(new SelfTestScrappedInput() + //{ + // mo_task_id = prdMoTask.id, + // scrap_qty = rqty, + // remark = "抽样不合格报废", + // categoryItems = new List() + // { + // new SelfTestScrappedInputItem() + // { + // category_id = "25574005966629", + // items = new List() + // { + // new defectItem() + // { + // defective_item = "抽样不合格报废", + // defective_item_qty = rqty + // } + // } + // } + // } + //}, db); + #endregion + + //载具需要在中储仓和暂存仓才需要暂控 + List prdReports = await db.Queryable().LeftJoin((a, b) => a.material_box_code == b.carry_code).LeftJoin((a, b, c) => b.location_id == c.id).LeftJoin((a, b, c, d) => c.wh_id == d.id).Where((a, b, c, d) => a.mo_task_id == prdMoTask.id && a.create_time >= CheckTaskInput.startEndTime[0].TimeStampToDateTime() && a.create_time <= CheckTaskInput.startEndTime[1].TimeStampToDateTime() && (c.wh_id == WmsWareHouseConst.WAREHOUSE_ZC_ID || c.wh_id == WmsWareHouseConst.WAREHOUSE_ZCC_ID)).ToListAsync(); + if (prdReports != null) { - mo_task_id = prdMoTask.id, - scrap_qty = rqty, - remark = "抽样不合格报废", - categoryItems = new List() + var carryCodes = prdReports.Select(r => r.material_box_code).Distinct().ToList(); + if (carryCodes != null && carryCodes.Count > 0) { - new SelfTestScrappedInputItem() + await db.Updateable() + .SetColumns(x => x.is_check == ((int)EnumCheckConclusion.暂控).ToString()) + .SetColumns(x => x.carry_status == "6")//把料架状态改为退料状态,会自动触发把料架上的子载具从二楼暂存仓退回一楼中储仓任务 + .Where(x => carryCodes.Contains(x.carry_code)) + .ExecuteCommandAsync(); + + #region 记录被暂控的载具信息 + //var qcCheckExecCarrys = new List(); + //foreach(var carryCode in carryCodes) + //{ + // var wmsCarryH = await db.Queryable().Where(r => r.carry_code == carryCode).FirstAsync(); + // if (wmsCarryH == null) + // continue; + + // WmsCarryCode wmsCarryCode = await db.Queryable().FirstAsync(x => x.carry_id == wmsCarryH.id); + // BasLocation basLocation = await db.Queryable().Where(r => r.location_code == wmsCarryH.location_code).FirstAsync(); + // WmsCarryMat wmsCarryMat = await db.Queryable().Where(r => r.carry_id == wmsCarryH.id).FirstAsync(); + + // var qcCheckExecCarry = new QcCheckExecCarry() + // { + // qc_check_exec_id = QcCheckExecH.id, + // carry_id = wmsCarryH.id, + // carry_code = wmsCarryH.carry_code, + // warehouse_id = basLocation != null ? basLocation.wh_id : "", + // qty = wmsCarryCode != null ? wmsCarryCode.codeqty.ToString() : "", + // status = wmsCarryH.is_check, + // location_id = basLocation != null ? basLocation.id : "", + // location_code = basLocation != null ? basLocation.location_code : "", + // material_id= wmsCarryMat?.material_id, + // create_id = _userManager.UserId, + // create_time = DateTime.Now + // }; + // qcCheckExecCarrys.Add(qcCheckExecCarry); + //} + //_ = await db.Insertable(qcCheckExecCarrys).ExecuteCommandAsync(); + #endregion + + #region 记录暂控处理单主/子表信息 + + if (carryCodes != null && carryCodes.Count > 0) { - category_id = "25574005966629", - items = new List() + + var basMaterial = await db.Queryable().Where(r => r.id == prdMoTask.material_id).FirstAsync(); + string outWHid = ""; string inWHid = ""; + if (basMaterial.category_id.Contains("DGJCJ") || basMaterial.category_id.Contains("ZSJ")) { - new defectItem() - { - defective_item = "抽样不合格报废", - defective_item_qty = rqty - } + outWHid = WmsWareHouseConst.WAREHOUSE_ZC_ID; + inWHid = "中储不合格品仓id"; } + else if (basMaterial.category_id.Contains("CGJCJ")) + { + outWHid = WmsWareHouseConst.WAREHOUSE_HCC_ID; + inWHid = "长管不合格品仓id"; + } + + var carryIds = await db.Queryable().Where(r => carryCodes.Contains(r.carry_code)).Select(r => r.id).ToListAsync(); + var wmsCarryCodes = await db.Queryable().Where(r => carryIds.Contains(r.carry_id) && r.material_id == QcCheckExecH.materialid).ToListAsync(); + var codeQty = wmsCarryCodes == null ? 0 : wmsCarryCodes.Sum(r => r.codeqty); + var qcTempControlH = new QcTempControlH() + { + id = SnowflakeIdHelper.NextId(), + bill_code = await _billRullService.GetBillNumber(CodeTemplateConst.QCCONTROLTEMP_CODE), + source_code = QcCheckExecH.bill_code, + pro_task_code = QcCheckExecH.mo_task_code, + out_warehouse_id = outWHid, + in_warehouse_id = inWHid, + material_id = QcCheckExecH.materialid, + material_code = basMaterial.code, + control_lx_qty = carryCodes.Count.ToString(), + control_qty = codeQty.ToString(), + result = "暂控", + loger_id = _userManager.UserId, + confirmer_id = "", + status = ((int)EnumTempControlStatus.待确认).ToString(), + called_box_qty = "0", + called_qty = "0", + leave_call_box_qty = carryCodes.Count.ToString(), + leave_call_qty = codeQty.ToString(), + create_id = _userManager.UserId, + create_time = DateTime.Now, + }; + + await db.Insertable(qcTempControlH).ExecuteCommandAsync(); + + var qcTempControlDs = new List(); + foreach (var carryCode in carryCodes) + { + var wmsCarryH = await db.Queryable().Where(r => r.carry_code == carryCode).FirstAsync(); + if (wmsCarryH == null) + continue; + + WmsCarryCode wmsCarryCode = await db.Queryable().FirstAsync(x => x.carry_id == wmsCarryH.id); + BasLocation basLocation = await db.Queryable().Where(r => r.location_code == wmsCarryH.location_code).FirstAsync(); + if (basLocation == null) + throw Oops.Bah($"未找到编号为{wmsCarryH.location_code}的库位"); + WmsCarryMat wmsCarryMat = await db.Queryable().Where(r => r.carry_id == wmsCarryH.id).FirstAsync(); + BasWarehouse basWarehouse = await db.Queryable().Where(r => r.id == basLocation.wh_id).FirstAsync(); + var _prdReports = prdReports.Where(r => r.material_box_code == carryCode).First(); + var qcTempConD = new QcTempControlD() + { + bill_id = qcTempControlH.id, + carry_id = wmsCarryH.id, + carry_code = carryCode, + warehouse_id = basLocation?.wh_id, + warehouse_code = basWarehouse.whcode, + location_code = basLocation?.location_code, + location_id = basLocation?.id, + qty = wmsCarryCode?.codeqty.ToString(), + submiter = _prdReports == null ? null : _prdReports.create_id, + maker_id = "", + create_id = _userManager.UserId, + create_time = DateTime.Now, + check_status = "暂控", + call_status = "未呼叫" + }; + qcTempControlDs.Add(qcTempConD); + } + await db.Insertable(qcTempControlDs).ExecuteCommandAsync(); } + #endregion } - },db); - List carryCodes = await db.Queryable().Where(x=>x.mo_task_id==prdMoTask.id).Select(x=>x.material_box_code).Distinct().ToListAsync(); - await db.Updateable() - .SetColumns(x => x.is_check == ((int)EnumCheckConclusion.暂控).ToString()) - .Where(x => carryCodes.Contains(x.carry_code)) - .ExecuteCommandAsync(); - } - else - { - //末检自动完工 - if (QcCheckExecH.checktype == WmsWareHouseConst.MOJIAN_ID) + } + else { - await _prdMoTaskService.PrdTaskRelease2(new PrdTaskReleaseUpInput() + //末检自动完工 + if (QcCheckExecH.checktype == WmsWareHouseConst.MOJIAN_ID) { - TaskIds = NPOI.Util.Arrays.AsList(prdMoTask.id), - Behavior = "Compled", - },db); + await _prdMoTaskService.PrdTaskRelease2(new PrdTaskReleaseUpInput() + { + TaskIds = NPOI.Util.Arrays.AsList(prdMoTask.id), + Behavior = "Compled", + }, db); + } } } - } - await db.Ado.CommitTranAsync(); + await db.Ado.CommitTranAsync(); + } } catch (Exception e) { await db.Ado.RollbackTranAsync(); - Log.Error(e.Message,e); - throw Oops.Oh("执行失败:"+e.Message); + JNPF.Logging.Log.Error(e.Message, e); + throw Oops.Oh("执行失败:" + e.Message); } - finally{ + finally + { prdreportSemaphore.Release(); } } @@ -531,21 +673,43 @@ namespace Tnb.QcMgr attachment = a.attachment, }).FirstAsync(); Result.checktypes = new List>(); - if (!string.IsNullOrEmpty(QcCheckExecH.carry_code)) - { - WmsCarryH carryH = await db.Queryable().FirstAsync(x => x.carry_code == QcCheckExecH.carry_code); - WmsCarryCode carryCode = await db.Queryable().FirstAsync(x => x.carry_id == carryH.id); - string materialId = carryCode?.id ?? ""; - BasMaterial basMaterial = await db.Queryable().SingleAsync(x=>x.id==materialId); - Result.carryInfo = new CheckCarry() - { - carry_name = carryH.carry_name, - location_id = carryH.location_id, - location_code = carryH.location_code, - material_name = basMaterial?.name, - qty = carryCode?.codeqty ?? 0, - }; - } + + //var qcCheckExecCarrys = await db.Queryable().Where(r => r.qc_check_exec_id == QcCheckExecH.id).ToListAsync(); + //if(qcCheckExecCarrys!=null && qcCheckExecCarrys.Count > 0) + //{ + // var checkCarrys = new List(); + // foreach(var acec in qcCheckExecCarrys) + // { + // WmsCarryH carryH = await db.Queryable().FirstAsync(x => x.id == acec.carry_id); + // BasMaterial basMaterial = await db.Queryable().SingleAsync(x => x.id == acec.material_id); + // var carry = new CheckCarry() + // { + // carry_name = carryH.carry_name, + // location_id = acec.location_id, + // location_code = acec.location_code, + // material_name = basMaterial?.name, + // qty = string.IsNullOrEmpty(acec.qty) ? 0 : Convert.ToDecimal(acec.qty), + // is_check=acec.status + // }; + // checkCarrys.Add(carry); + // } + // Result.carryInfo= checkCarrys; + //} + //if (!string.IsNullOrEmpty(QcCheckExecH.carry_code)) + //{ + // WmsCarryH carryH = await db.Queryable().FirstAsync(x => x.carry_code == QcCheckExecH.carry_code); + // WmsCarryCode carryCode = await db.Queryable().FirstAsync(x => x.carry_id == carryH.id); + // string materialId = carryCode?.id ?? ""; + // BasMaterial basMaterial = await db.Queryable().SingleAsync(x=>x.id==materialId); + // Result.carryInfo = new CheckCarry() + // { + // carry_name = carryH.carry_name, + // location_id = carryH.location_id, + // location_code = carryH.location_code, + // material_name = basMaterial?.name, + // qty = carryCode?.codeqty ?? 0, + // }; + //} List groupkeys = QcCheckExecDs.Select(p => p.checkindex).Distinct().ToList(); foreach (string? key in groupkeys) { diff --git a/QcMgr/Tnb.QcMgr/QcTempControlHService.cs b/QcMgr/Tnb.QcMgr/QcTempControlHService.cs new file mode 100644 index 00000000..0825c587 --- /dev/null +++ b/QcMgr/Tnb.QcMgr/QcTempControlHService.cs @@ -0,0 +1,721 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Aop.Api.Domain; +using DingTalk.Api.Request; +using JNPF.Common.Core.Manager; +using JNPF.Common.Extension; +using JNPF.Common.Filter; +using JNPF.Common.Security; +using JNPF.DependencyInjection; +using JNPF.DynamicApiController; +using JNPF.FriendlyException; +using JNPF.Logging; +using JNPF.Systems.Entitys.System; +using JNPF.Systems.Interfaces.System; +using JNPF.VisualDev; +using JNPF.VisualDev.Entitys.Dto.VisualDevModelData; +using Microsoft.AspNetCore.Mvc; +using Microsoft.ClearScript.JavaScript; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using SqlSugar; +using Tnb.BasicData.Entities; +using Tnb.EquipMgr.Entities; +using Tnb.ProductionMgr.Entities; +using Tnb.ProductionMgr.Entities.Entity; +using Tnb.QcMgr.Entities; +using Tnb.QcMgr.Entities.Dto; +using Tnb.QcMgr.Entities.Entity; +using Tnb.QcMgr.Entities.Enums; +using Tnb.WarehouseMgr; +using Tnb.WarehouseMgr.Entities; +using Tnb.WarehouseMgr.Entities.Consts; +using Tnb.WarehouseMgr.Entities.Dto; +using Tnb.WarehouseMgr.Entities.Enums; +using Tnb.WarehouseMgr.Interfaces; + +namespace Tnb.QcMgr +{ + [ApiDescriptionSettings(Tag = ModuleConsts.Tag, Area = ModuleConsts.Area, Order = 800)] + [Route("api/[area]/[controller]/[action]")] + public class QcTempControlHService : BaseWareHouseService, IDynamicApiController, ITransient + { + private readonly ISqlSugarRepository _repository; + private readonly IUserManager _userManager; + private readonly IWareHouseService _wareHouseService; + private readonly IBillRullService _billRullService; + private readonly ISqlSugarClient _db; + public QcTempControlHService(ISqlSugarRepository repository, IUserManager userManager, IWareHouseService wareHouseService,IBillRullService billRullService) + { + _db = repository.AsSugarClient(); + _userManager = userManager; + _wareHouseService = wareHouseService; + _billRullService = billRullService; + } + + + /// + /// 获取质检暂控处理单 + /// + /// + + [HttpPost] + public async Task AllList(VisualDevModelListQueryInput input) + { + var bill_code = ""; //单据号 + var pro_task_code = ""; //生产任务单号 + var status = "";//状态 + if (!input.queryJson.IsNullOrWhiteSpace()) + { + bill_code = JObject.Parse(input.queryJson).Value("bill_code"); + pro_task_code = JObject.Parse(input.queryJson).Value("pro_task_code"); + status = JObject.Parse(input.queryJson).Value("status"); + } + + var result = await _db.Queryable().LeftJoin((a, b) => a.in_warehouse_id == b.id) + .LeftJoin((a, b, c) => a.out_warehouse_id == c.id) + .WhereIF(!string.IsNullOrEmpty(bill_code), (a, b, c) => a.bill_code.Contains(bill_code)) + .WhereIF(!string.IsNullOrEmpty(pro_task_code), (a, b, c) => a.pro_task_code.Contains(pro_task_code)) + .WhereIF(!string.IsNullOrEmpty(status), (a, b, c) => a.status == status) + .OrderByDescending((a, b, c) => a.create_time) + .Select((a, b, c) => new QcTempControlHOutput() + { + id = a.id, + bill_code = a.bill_code, + source_code = a.source_code, + pro_task_code = a.pro_task_code, + out_warehouse_id = a.out_warehouse_id, + out_warehouse_name = c.whname, + in_warehouse_id = a.in_warehouse_id, + in_warehouse_name = b.whname, + material_id = a.material_id, + material_code = a.material_code, + control_lx_qty = a.control_lx_qty, + control_qty = a.control_qty, + result = a.result, + loger_id = a.loger_id, + confirmer_id = a.confirmer_id, + status = a.status, + called_box_qty = a.called_box_qty, + called_qty = a.called_qty, + leave_call_box_qty = a.leave_call_box_qty, + leave_call_qty = a.leave_call_qty, + + details = SqlFunc.Subqueryable().Where(r => r.bill_id == a.id).OrderByDesc(r => r.create_time).ToList((x) => new QcTempControlDsOutput + { + id = x.id, + bill_id = x.bill_id, + carry_id = x.carry_id, + carry_code = x.carry_code, + warehouse_code = x.warehouse_code, + warehouse_id = x.warehouse_id, + location_code = x.location_code, + location_id = x.location_id, + qty = x.qty, + submiter = x.submiter, + maker_id = x.maker_id, + }) + + }).ToPagedListAsync(input.currentPage, input.pageSize); + + return PageResult.SqlSugarPageResult(result); + } + + + /// + /// 确认暂控料处理单结论 + /// + /// + /// + [HttpPost] + public async Task ModifyResult(Dictionary dic) + { + string id = dic["id"]; + string qcRes = dic["result"]; + + try + { + var qcTempControlH = await _db.Queryable().Where(r => r.id == id).FirstAsync(); + if(qcTempControlH==null) + { + throw Oops.Bah("暂控处理单数据不存在"); + } + await _db.Ado.BeginTranAsync(); + + await _db.Updateable().SetColumns(x => x.result == qcRes).SetColumns(x=>x.status==((int)EnumTempControlStatus.待下发).ToString()).Where(x => x.id == id).ExecuteCommandAsync(); + await _db.Updateable().SetColumns(x => x.check_status == qcRes).Where(x => x.bill_id == qcTempControlH.bill_code).ExecuteCommandAsync(); + + await _db.Ado.CommitTranAsync(); + } + catch(Exception e) + { + await _db.Ado.RollbackTranAsync(); + Log.Error(e.Message, e); + throw Oops.Bah(e.Message); + } + + return "修改成功"; + } + + /// + /// 下发暂控料处理单 + /// + /// + /// + [HttpPost] + public async Task QcTempControlIssued(Dictionary dic) + { + string id = dic["id"]; + + try + { + var qcTempControlH = await _db.Queryable().Where(r => r.id == id).FirstAsync(); + if (qcTempControlH == null) + { + throw Oops.Bah("暂控处理单数据不存在"); + } + //所有暂控的料箱必须都进入中储仓才能进行下发 + var qcTempControlDs = await _db.Queryable().Where(r => r.bill_id == qcTempControlH.id).ToListAsync(); + if (qcTempControlDs!=null && qcTempControlDs.Count > 0) + { + var carrys = await _db.Queryable().Where(r => qcTempControlDs.Select(r => r.carry_id).Contains(r.carry_id)).ToListAsync(); + var noInStockCarrys = carrys.Where(r => r.warehouse_id != WmsWareHouseConst.WAREHOUSE_ZC_ID); + if (noInStockCarrys.Any()) + { + var carryCodes=string.Join(",", noInStockCarrys.Distinct().Select(r=>r.carry_code)); + throw Oops.Bah($"{carryCodes}等料箱还没入中储仓,不能下发"); + } + } + + await _db.Ado.BeginTranAsync(); + + await _db.Updateable().SetColumns(x => x.status == ((int)EnumTempControlStatus.已下发).ToString()).Where(x => x.id == id).ExecuteCommandAsync(); + + await _db.Ado.CommitTranAsync(); + } + catch (Exception e) + { + await _db.Ado.RollbackTranAsync(); + Log.Error(e.Message, e); + throw Oops.Bah(e.Message); + } + + return "修改成功"; + } + + /// + /// 获取质检单 for APP + /// + /// + [HttpPost] + public async Task GetQcTempControlList(PageInputBase input) + { + Dictionary queryJson = string.IsNullOrEmpty(input.queryJson) ? new Dictionary() : input.queryJson.ToObject>(); + string? bill_code = queryJson.ContainsKey("bill_code") ? queryJson["bill_code"].ToString() : ""; + string? status = queryJson.ContainsKey("status") ? queryJson["status"].ToString() : ""; + + if (string.IsNullOrEmpty(input.sidx)) + { + input.sidx = "create_time"; + input.sort = "desc"; + } + + var result = await _db.Queryable().LeftJoin((a, b) => a.in_warehouse_id == b.id) + .LeftJoin((a, b, c) => a.out_warehouse_id == c.id) + .WhereIF(!string.IsNullOrEmpty(bill_code), (a, b, c) => a.bill_code.Contains(bill_code)) + .WhereIF(!string.IsNullOrEmpty(status), (a, b, c) => a.status == status) + .OrderByDescending((a, b, c) => a.create_time) + .Select((a, b, c) => new QcTempControlHAppOutput() + { + id = a.id, + bill_code = a.bill_code, + source_code = a.source_code, + pro_task_code = a.pro_task_code, + out_warehouse_id = a.out_warehouse_id, + out_warehouse_name = c.whname, + in_warehouse_id = a.in_warehouse_id, + in_warehouse_name = b.whname, + material_id = a.material_id, + material_code = a.material_code, + control_lx_qty = a.control_lx_qty, + control_qty = a.control_qty, + result = a.result, + loger_id = a.loger_id, + confirmer_id = a.confirmer_id, + status = a.status, + called_box_qty = a.called_box_qty, + called_qty = a.called_qty, + leave_call_box_qty = a.leave_call_box_qty, + leave_call_qty = a.leave_call_qty, + + }).ToPagedListAsync(input.currentPage, input.pageSize); + + return PageResult.SqlSugarPageResult(result); + } + + /// + /// PDA暂控料呼叫 + /// + /// + [HttpPost] + public async Task TempControlCall(QcTempControlCallInput input) + { + try + { + if (string.IsNullOrEmpty(input.id)) + throw Oops.Bah("主键id不能为空"); + if (string.IsNullOrEmpty(input.destination_location_code)) + throw Oops.Bah("目标库位不能为空"); + if (input.box_qty <= 0) + throw Oops.Bah("呼叫箱数不能小于1"); + + var qcTempControlH = await _db.Queryable().Where(r => r.id == input.id).FirstAsync(); + if (qcTempControlH == null) + throw Oops.Bah("暂控处理单数据不存在"); + + var basLocation=await _db.Queryable().Where(r=>r.location_code==input.destination_location_code).FirstAsync(); + if (basLocation == null) + throw Oops.Bah($"目标库位{input.destination_location_code}不存在"); + + var qcTempControlDs = await _db.Queryable().Where(r => r.bill_id == input.id && r.call_status == "未呼叫").Take(input.box_qty).ToListAsync(); + if (qcTempControlDs == null || qcTempControlDs.Count <= 0) + throw Oops.Bah("不存在未下发的料箱"); + + await _db.Ado.BeginTranAsync(); + + decimal callqty = 0;//当前呼叫物料总数量 + foreach(var item in qcTempControlDs) + { + callqty += (string.IsNullOrEmpty(item.qty) ? 0 : Convert.ToDecimal(item.qty)); + + // 计算路径,插入预任务申请 + WmsPointH sPoint = await _db.Queryable().FirstAsync(it => it.location_id ==item.location_id); + WmsPointH ePoint = await _db.Queryable().FirstAsync(it => it.location_id == basLocation.id); + + if (sPoint == null) + throw Oops.Bah($"载具编号{item.carry_code}未找到起始点位"); + if (ePoint == null) + throw Oops.Bah($"载具编号{item.carry_code}未找到终点点位"); + + 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) + throw Oops.Bah("点位不存在"); + + 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_WMSTRANSFERINSTOCK_ID, + task_type = WmsWareHouseConst.WMS_PRETASK_TRANSFER_TYPE_ID + }; + preTask.area_id = sPoint?.area_id!; + preTask.area_code = it.Key; + preTask.require_id = qcTempControlH.id; + preTask.require_code = qcTempControlH.bill_code; + preTask.create_id = _userManager.UserId; + preTask.create_time = DateTime.Now; + return preTask; + }).ToList(); + bool isOk = await _wareHouseService.GenPreTask(preTasks, null!); + if (!isOk) + throw Oops.Bah($"载具编号{item.carry_code}生成预任务失败"); + + } + + await _db.Updateable(qcTempControlDs).SetColumns(x=>x.call_status=="已呼叫").ExecuteCommandAsync(); + + //已呼叫料箱数量 + var called_box_qty = qcTempControlDs.Count + (string.IsNullOrEmpty(qcTempControlH.called_box_qty) ? 0 : Convert.ToDecimal(qcTempControlH.called_box_qty)); + //已呼叫物料数量 + var called_qty = callqty + (string.IsNullOrEmpty(qcTempControlH.called_qty) ? 0 : Convert.ToDecimal(qcTempControlH.called_qty)); + //剩余呼叫料箱数量 + var leave_call_box_qty = (string.IsNullOrEmpty(qcTempControlH.control_lx_qty) ? 0 : Convert.ToDecimal(qcTempControlH.control_lx_qty)) - called_box_qty; + //剩余呼叫数量 + var leave_call_qty = (string.IsNullOrEmpty(qcTempControlH.control_qty) ? 0 : Convert.ToDecimal(qcTempControlH.control_qty)) - called_qty; + + await _db.Updateable(qcTempControlH).SetColumns(x => x.called_box_qty == called_box_qty.ToString()) + .SetColumns(x => x.called_qty == called_qty.ToString()) + .SetColumns(x => x.leave_call_box_qty == leave_call_box_qty.ToString()) + .SetColumns(x => x.leave_call_qty == leave_call_qty.ToString()) + .SetColumns(x=>x.status==((int)EnumTempControlStatus.执行中).ToString()) + .ExecuteCommandAsync(); + + await _db.Ado.CommitTranAsync(); + } + catch (Exception e) + { + await _db.Ado.RollbackTranAsync(); + Log.Error(e.Message, e); + throw Oops.Bah(e.Message); + } + return "呼叫成功"; + } + + + /// + /// PDA扫描料箱获取暂控处理单详情 + /// + /// + /// + [HttpPost] + + public async Task GetQcTempControlDetail(Dictionary dic) + { + var id = dic["id"].ToString(); + var carryCode = dic["carryCode"].ToString(); + + if (string.IsNullOrEmpty(carryCode)) + throw Oops.Bah("料箱号不能为空"); + + var qcTempControlH = await _db.Queryable().Where(r => r.id == id).FirstAsync(); + if (qcTempControlH == null) + throw Oops.Bah("未找到暂控料处理单数据"); + + var carry = await _db.Queryable().Where(r => r.carry_code == carryCode).FirstAsync(); + if (carry == null) + throw Oops.Bah($"料箱号:{carryCode}不存在"); + + var qcTempControlD = await _db.Queryable().Where(r => r.bill_id == qcTempControlH.id && r.carry_id == carry.id).FirstAsync(); + if (qcTempControlD == null) + throw Oops.Bah($"料箱号:{carryCode}不在此暂控料处理单的暂控料箱列表中"); + + var material= await _db.Queryable().Where(r => r.id == qcTempControlH.material_id).FirstAsync(); + var result = new QcTempControlScanCodeOutput(); + result.id = qcTempControlD.id; + result.material_code = material?.code; + result.material_name = material?.name; + result.container_no=material?.container_no; + result.material_standard = material?.material_standard; + result.material_specification = material?.material_specification; + result.unit_code = material?.unit_id; + result.code_qty = qcTempControlD.qty; + return result; + } + + /// + /// 保存挑选合格数量 + /// + /// + /// + [HttpPost] + + public async Task SaveQualifiedQty(Dictionary dic) + { + try + { + var id = dic["id"].ToString(); + var qualifiedQty = dic["qualifiedQty"].ToString(); + if (string.IsNullOrEmpty(qualifiedQty)) + throw Oops.Bah("合格数量不能为空"); + + //先保存不合格数量,修改状态为让步接收,改变对应载具台账的检验状态为合格,并生成对应料箱的8号线入库任务 + var qcTempControlD = await _db.Queryable().Where(r => r.id == id).FirstAsync(); + if (qcTempControlD == null) + throw Oops.Bah($"数据不存在"); + + if (qcTempControlD.pick_status == "已挑选") + throw Oops.Bah("已挑选,不能重复挑选"); + + var qctempControlH=await _db.Queryable().Where(r=>r.id==qcTempControlD.bill_id).FirstAsync(); + //计算不合格数量 + var unQualifiedQty = (string.IsNullOrEmpty(qcTempControlD.qty) ? 0 : Convert.ToDecimal(qcTempControlD.qty)) - (Convert.ToDecimal(qualifiedQty)); + await _db.Ado.BeginTranAsync(); + //修改对应暂控子表的不合格数量和挑选状态 + await _db.Updateable() + .SetColumns(r => r.qualified_qty == qualifiedQty) + .SetColumns(r=>r.unqualified_qty== unQualifiedQty.ToString()) + .SetColumns(r => r.pick_status == "已挑选") + .SetColumns(r=>r.check_status=="让步接收") + .Where(r => r.id == qcTempControlD.id).ExecuteCommandAsync(); + //更新对应载具台账的检验状态为合格 + await _db.Updateable().SetColumns(r => r.is_check == ((int)EnumCheckConclusion.合格).ToString()).Where(r => r.id == qcTempControlD.carry_id).ExecuteCommandAsync(); + //更新对应载具条码表的条码数量为挑选好的合格数量 + await _db.Updateable().SetColumns(r => r.codeqty == Convert.ToDecimal(qualifiedQty)).Where(r => r.carry_id == qcTempControlD.carry_id && r.material_id == qctempControlH.material_id).ExecuteCommandAsync(); + + #region 生成8号线入库任务 + + //入库取终点 + InStockStrategyQuery inStockStrategyInput = new() { warehouse_id = qcTempControlD.warehouse_id, Size = 1 }; + List endLocations = await _wareHouseService.InStockStrategy(inStockStrategyInput); + WmsPointH? sPoint = null; + WmsPointH? ePoint = null; + sPoint = await _db.Queryable().FirstAsync(it => it.location_id == qcTempControlD.warehouse_id); + if (sPoint == null) + throw Oops.Bah($"起始库位不可用"); + if (endLocations?.Count > 0) + { + WmsCarryH carry = await _db.Queryable().SingleAsync(it => it.id == qcTempControlD.carry_id); + 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); + } + if (ePoint == null) + throw Oops.Bah("无可用的目标库位"); + + 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); + } + + //根据获取的路径点生成预任务,生成顺序必须预路径算法返回的起终点的顺序一致(预任务顺序) + + 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_TEMPCONTROLINSTOCK_ID, + task_type = WmsWareHouseConst.WMS_PRETASK_INSTOCK_TYPE_ID, + carry_id = qcTempControlD.carry_id, + carry_code = qcTempControlD.carry_code, + area_id = sPoint?.area_id!, + area_code = it.Key, + require_id = qctempControlH?.id, + require_code = qctempControlH?.bill_code, + create_id = _userManager.UserId, + create_time = DateTime.Now, + }; + + return preTask; + }).ToList(); + bool isOk = await _wareHouseService.GenPreTask(preTasks, null!); + if (!isOk) + throw Oops.Bah($"生成暂控料入库预任务失败"); + + await _db.Updateable().SetColumns(r => r.pre_task_id == preTasks.FirstOrDefault().id).Where(r => r.id == id).ExecuteCommandAsync(); + #endregion + + await _db.Ado.CommitTranAsync(); + } + catch(Exception e) + { + await _db.Ado.RollbackTranAsync(); + Log.Error(e.Message, e); + throw Oops.Bah(e.Message); + } + return "保存成功"; + } + + /// + /// 显示已挑选合格数量 + /// + /// + /// + [HttpPost] + + public async Task ShowPickQualifiedQty(Dictionary dic) + { + try + { + var id = dic["id"].ToString(); + var qcTempControlH = await _db.Queryable().Where(r => r.id == id).FirstAsync(); + if (qcTempControlH == null) + throw Oops.Bah($"数据不存在"); + + var qcTempControlDs = await _db.Queryable().Where(r => r.bill_id == id).ToListAsync(); + + QcTempControlPickQualifiedQtyOutput result = new QcTempControlPickQualifiedQtyOutput(); + if (qcTempControlDs != null) + { + result.temp_control_qty = qcTempControlH.control_qty; + result.qualified_qty = qcTempControlDs.Sum(r => (string.IsNullOrEmpty(r.qualified_qty) ? 0 : Convert.ToDecimal(r.qualified_qty))).ToString(); + result.unQualified_qty = ((string.IsNullOrEmpty(qcTempControlH.control_qty) ? 0 : Convert.ToDecimal(qcTempControlH.control_qty)) - Convert.ToDecimal(result.qualified_qty)).ToString(); + } + else + { + result.temp_control_qty = qcTempControlH.control_qty; + result.qualified_qty = "0"; + result.unQualified_qty = "0"; + } + return result; + } + catch (Exception e) + { + Log.Error(e.Message, e); + throw Oops.Bah(e.Message); + } + } + + + + /// + /// 挑选不合格数量完成 + /// + /// + /// + [HttpPost] + + public async Task SavePickComplete(Dictionary dic) + { + try + { + var id = dic["id"].ToString(); + + //保存暂控处理单状态为挑选完成之前,需要确保所有的8号线入库任务全部完成,挑选完成之后,对接bip(暂时不对接),把不合格总数量传给BIP; + //并且生成一个其它出库(从中储仓出到次品仓),其他入库(从中储仓入到次品仓)任务 + var qcTempControlH = await _db.Queryable().Where(r => r.id == id).FirstAsync(); + if (qcTempControlH == null) + throw Oops.Bah($"数据不存在"); + //质检任务主表 + var qcCheckExecH = await _db.Queryable().Where(r => r.bill_code == qcTempControlH.source_code).FirstAsync(); + + var qcTempControlDs = await _db.Queryable().Where(r => r.bill_id == qcTempControlH.id).ToListAsync(); + //找到所有的预任务id + var pre_task_ids = qcTempControlDs.Where(r => !string.IsNullOrEmpty(r.pre_task_id)).Select(r => r.pre_task_id).Distinct(); + + //查找到未完成的任务 + var wmsDistasks = await _db.Queryable().Where(r => pre_task_ids.Contains(r.pretask_id) && r.status != WmsWareHouseConst.TASK_BILL_STATUS_COMPLE_ID).ToListAsync(); + if (wmsDistasks != null && wmsDistasks.Count > 0) + throw Oops.Bah($"还存在未完成的入库任务,挑选完成失败"); + + //计算所有合格数量 + var qualifiedQty = qcTempControlDs.Sum(r => (string.IsNullOrEmpty(r.qualified_qty) ? 0 : Convert.ToDecimal(r.qualified_qty))); + + #region 生产报废记录 + + //新增生产报废记录 + var prdTaskDefect = new PrdMoTaskDefectRecord(); + //生产工单 + var prdMo = await _db.Queryable().LeftJoin((a, b) => a.id == b.mo_id).Where((a, b) => b.mo_task_code == qcTempControlH.pro_task_code).FirstAsync(); + var prdMoTask = await _db.Queryable().Where(r => r.mo_task_code == qcTempControlH.pro_task_code).FirstAsync(); + prdTaskDefect.mo_code=prdMo?.mo_code; + prdTaskDefect.mo_task_id = prdMoTask?.id; + prdTaskDefect.mo_task_code=qcTempControlH.pro_task_code; + prdTaskDefect.mo_task_type = prdMo?.mo_type; + + var basMaterial = await _db.Queryable().Where(r => r.id == qcTempControlH.material_id).FirstAsync(); + prdTaskDefect.material_code = basMaterial?.code; + prdTaskDefect.material_name=basMaterial?.name; + prdTaskDefect.estimated_start_date = prdMoTask?.estimated_start_date; + prdTaskDefect.estimated_end_date=prdMoTask?.estimated_end_date; + prdTaskDefect.plan_qty = prdMoTask?.plan_qty; + prdTaskDefect.scrap_qty = (string.IsNullOrEmpty(qcTempControlH.control_qty) ? 0 : Convert.ToDecimal(qcTempControlH.control_qty)) - qualifiedQty;//暂控数量-合格数量 + prdTaskDefect.status = prdMoTask?.mo_task_status; + prdTaskDefect.eqp_code = prdMoTask == null ? "" : (await _db.Queryable().FirstAsync(it => it.id == prdMoTask.eqp_id))?.code!; + prdTaskDefect.mold_name = prdMoTask == null ? "" : (await _db.Queryable().FirstAsync(it => it.id == prdMoTask.mold_id))?.mold_name!; + prdTaskDefect.create_time = DateTime.Now; + prdTaskDefect.create_id = _userManager.UserId; + + await _db.Insertable(prdTaskDefect).ExecuteCommandAsync(); + //新增生产报废记录子表 + var prdMoTaskDefectRecordDs = new List(); + foreach(var item in qcTempControlDs) + { + var prdMoTaskDefectRecordD = new PrdMoTaskDefectRecordD + { + bill_id = prdTaskDefect.id, + source_id = item.id, + carry_id = item.carry_id, + carry_code = item.carry_code, + scrap_qty = ((string.IsNullOrEmpty(item.qty) ? 0 : Convert.ToDecimal(item.qty)) - (string.IsNullOrEmpty(item.qualified_qty) ? 0 : Convert.ToDecimal(item.qualified_qty))).ToString(), + submiter_id= item.submiter, + maker_id =item.maker_id, + make_time= prdTaskDefect.create_time + }; + prdMoTaskDefectRecordDs.Add(prdMoTaskDefectRecordD); + } + + await _db.Insertable(prdMoTaskDefectRecordDs).ExecuteCommandAsync(); + #endregion + + //载具台账变为空载具(载具状态:空闲、库位ID清空、检验状态:待检、子表数据清空) + + foreach(var item in qcTempControlDs) + { + var wmsCarryH = await _db.Queryable().Where(r => r.id == item.carry_id).FirstAsync(); + wmsCarryH.carry_status = ((int)EnumCarryStatus.空闲).ToString(); + wmsCarryH.is_check = ((int)EnumCheckConclusion.待检).ToString(); + wmsCarryH.location_code = ""; + wmsCarryH.location_id = ""; + wmsCarryH.is_lock = 0; + await _db.Updateable(wmsCarryH).ExecuteCommandAsync(); + + await _db.Updateable() + .SetColumns(r => r.carry_status == ((int)EnumCarryStatus.空闲).ToString()) + .SetColumns(r => r.is_check == ((int)EnumCheckConclusion.待检).ToString()) + .SetColumns(r => r.location_code == "") + .SetColumns(r => r.location_id == "") + .SetColumns(r => r.is_lock == 0) + .Where(r=>r.id==item.carry_id) + .ExecuteCommandAsync(); + + await _db.Deleteable().Where(r => r.carry_id == item.carry_id).ExecuteCommandAsync(); + } + + await _db.Ado.CommitTranAsync(); + } + catch (Exception e) + { + await _db.Ado.RollbackTranAsync(); + Log.Error(e.Message, e); + throw Oops.Bah(e.Message); + } + return "保存成功"; + } + + + } +} diff --git a/QcMgr/Tnb.QcMgr/Tnb.QcMgr.csproj b/QcMgr/Tnb.QcMgr/Tnb.QcMgr.csproj index 2aca6871..eaf6d3b6 100644 --- a/QcMgr/Tnb.QcMgr/Tnb.QcMgr.csproj +++ b/QcMgr/Tnb.QcMgr/Tnb.QcMgr.csproj @@ -12,6 +12,7 @@ + diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs index 4d83555c..bbc09d96 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Consts/WmsWareHouseConst.cs @@ -426,6 +426,11 @@ namespace Tnb.WarehouseMgr.Entities.Consts /// public const string BIZTYPE_TEMPCONTROLOUTSTOCK_ID = "38027183728661"; + /// + /// 预任务生成业务类型-暂控料入库 + /// + public const string BIZTYPE_TEMPCONTROLINSTOCK_ID = "38065450570261"; + /// /// 成品调拨入库 /// diff --git a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/ErpInputs/MaterialTransferInput.cs b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/ErpInputs/MaterialTransferInput.cs index 433b7465..03dc9e4d 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/ErpInputs/MaterialTransferInput.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr.Entities/Dto/ErpInputs/MaterialTransferInput.cs @@ -62,6 +62,10 @@ namespace Tnb.WarehouseMgr.Entities.Dto.ErpInputs /// 应到货日期 /// public DateTime arrival_date { get; set; } + /// + /// 转库单类型(人工线,自动线) + /// + public string transfer_type { get; set; } /// /// 主表主键 diff --git a/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs b/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs index a5d9ec76..be37cc48 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/ErpToWmsService.cs @@ -1019,7 +1019,7 @@ namespace Tnb.WarehouseMgr WmsMaterialTransfer wmsMaterialTransfer = new WmsMaterialTransfer(); string Code = await _billRuleService.GetBillNumber("MaterialTransfer"); wmsMaterialTransfer.bill_code = Code; - wmsMaterialTransfer.status = WmsWareHouseConst.BILLSTATUS_ADD_ID; + wmsMaterialTransfer.status = input.transfer_type == "0001H11000000000D32H" ? WmsWareHouseConst.BILLSTATUS_COMPLETE_ID : WmsWareHouseConst.BILLSTATUS_ADD_ID;//转库单类型是人工线的,直接是完成状态 wmsMaterialTransfer.bill_date = DateTime.Now; wmsMaterialTransfer.warehouse_outstock = warehouse_outstock.id; wmsMaterialTransfer.warehouse_instock = warehouse_instock.id; @@ -1088,7 +1088,7 @@ namespace Tnb.WarehouseMgr WmsPrdReturnH wmsPrdReturnH = new WmsPrdReturnH(); string Code = await _billRuleService.GetBillNumber("WMSPRDRETURN"); wmsPrdReturnH.bill_code = Code; - wmsPrdReturnH.status = WmsWareHouseConst.BILLSTATUS_ADD_ID; + wmsPrdReturnH.status = input.transfer_type == "0001H11000000000D32H" ? WmsWareHouseConst.BILLSTATUS_COMPLETE_ID : WmsWareHouseConst.BILLSTATUS_ADD_ID;//转库单类型是人工线的,直接是完成状态 wmsPrdReturnH.warehouse_id = warehouse_instock.id; wmsPrdReturnH.create_id = WmsWareHouseConst.ErpUserId; wmsPrdReturnH.create_time = DateTime.Now; diff --git a/WarehouseMgr/Tnb.WarehouseMgr/WmsPurchaseDService.cs b/WarehouseMgr/Tnb.WarehouseMgr/WmsPurchaseDService.cs index c11bd71e..22f135a2 100644 --- a/WarehouseMgr/Tnb.WarehouseMgr/WmsPurchaseDService.cs +++ b/WarehouseMgr/Tnb.WarehouseMgr/WmsPurchaseDService.cs @@ -142,8 +142,8 @@ namespace Tnb.WarehouseMgr List allInstockDetails = await _db.Queryable().Where(it => instock_mains.Select(r => r.id).Contains(it.bill_id) - && it.material_id == wmsPurchaseD.material_id && it.code_batch == wmsPurchaseD.code_batch - && (!string.IsNullOrEmpty(it.source_detail_id) && it.source_detail_id == wmsPurchaseD.id)).OrderBy(x=>x.id).ToListAsync(); + && it.material_id == wmsPurchaseD.material_id && it.code_batch == wmsPurchaseD.code_batch + && (string.IsNullOrEmpty(it.source_detail_id) || (!string.IsNullOrEmpty(it.source_detail_id) && it.source_detail_id == wmsPurchaseD.id))).OrderBy(x => x.id).ToListAsync(); List> requestData = new List>(); List carryIds = instock_mains.Select(x => x.carry_id).ToList(); diff --git a/apihost/Tnb.API.Entry/Configurations/Cache.json b/apihost/Tnb.API.Entry/Configurations/Cache.json index 7a6d1350..52e8c235 100644 --- a/apihost/Tnb.API.Entry/Configurations/Cache.json +++ b/apihost/Tnb.API.Entry/Configurations/Cache.json @@ -2,19 +2,19 @@ "Cache": { "CacheType": "RedisCache", //MemoryCache "ip": "127.0.0.1", - "port": 6379, + "port": 6378, "password": "05jWEoJa8v", "RedisConnectionString": "{0}:{1},password={2}, poolsize=500,ssl=false,defaultDatabase=0" }, "Redis": { "ip": "127.0.0.1", - "port": 6379, + "port": 6378, "password": "05jWEoJa8v", "RedisConnectionString": "{0}:{1},password={2}, poolsize=500,ssl=false,defaultDatabase=0" }, "Redis2": { "ip": "127.0.0.1", - "port": 6379, + "port": 6378, "password": "05jWEoJa8v", "RedisConnectionString": "{0}:{1},password={2}, poolsize=500,ssl=false,defaultDatabase=1" } diff --git a/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json b/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json index 01aa1fd4..2e6e4525 100644 --- a/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json +++ b/apihost/Tnb.API.Entry/Configurations/ConnectionStrings.json @@ -4,13 +4,13 @@ "DBType": "PostgreSQL", //MySql;SqlServer;Oracle;PostgreSQL;Dm;Kdbndp;Sqlite; //"Host": "192.168.11.109", "Host": "127.0.0.1", - "Port": "5432", + "Port": "5431", //"DBName": "tianyi_db", //"UserName": "postgres", //"Password": "pass@word123", - "DBName": "tianyi", - "UserName": "postgres", - "Password": "pass@word123", + "DBName": "tianyi_cwk2", + "UserName": "totong", + "Password": "IPANyxGSKxIXg0dBM", //SqlServer //"DefaultConnection": "server={0},{1};database={2};uid={3};pwd={4};MultipleActiveResultSets=true" //Kdbndp