using Rhea.Common; using Tiger.IBusiness; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading; using System.Threading.Tasks; using Tiger.Model; using Tiger.Model.Sharetronic.Shelf; using System.ComponentModel; using Tiger.Model.Entitys.MES.U9C; using ProdInBatch = Tiger.Model.ProdInBatch; using Org.BouncyCastle.Ocsp; using Tiger.Model.Entitys.MES.BizPrintInstoreDoc; using System.Drawing.Printing; using Tiger.Model.Entitys.MES.Position; using System.Drawing.Drawing2D; using static Microsoft.CodeAnalysis.CSharp.SyntaxTokenParser; using Tiger.Model.Minsun; namespace Tiger.Business.MES.Transaction { /// /// 入库单事务 /// public class InStoreOrderNo : MESTransactionBase, IInStoreOrderNo { private readonly IMES_U9C _IMES_U9C = DI.Resolve(); private readonly IBIZ_MES_WO _IBIZ_MES_WO = DI.Resolve(); public IInStoreOrderNo Init(string id, string apiHost, InstoreDocInput input) { TransID = id; UserCode = input.UserCode; ApiHost = apiHost; OrgCode = input.OrgCode; pageSize = input.pageSize; _GetScannedList(); CurBatchNo = !inStoreInfos.IsNullOrEmpty() && inStoreInfos.InStoreScanInfos.Count > 0 ? InStoreScanInfos[0].BATCH_NO : DateTime.Now.ToString("yyyyMMddHHmmss"); Logger.Console.Info($"Start {this.GetType().Name} Transaction[ID: {TransID}]"); return this; } #region Propertys & Variables public string UserCode { get; set; } public long UserId { get; set; } public string OrgCode { get; set; } public string CurSN { get; set; } public string CurBatchNo { get; set; } public int pageSize { get; set; } public RcvRptDocCreateInput RcvRptInput { get; set; } = new RcvRptDocCreateInput(); public List ProdInBatchs { get; set; } = new List(); public List ErpProdInBths { get; set; } = new List(); public List ErpProdIns { get; set; } = new List(); /// /// 扫描列表 /// public List InStoreScanInfos { get; set; } = new List(); public List ErpProdInSns { get; set; } = new List(); public InStoreInfos inStoreInfos { get; set; } #endregion Propertys & Variables #region Functions public ApiAction GetInStoreInfos() { return new() { Data = inStoreInfos }; } /// /// 扫描条码 /// /// /// public async Task> Submit(string code) { var action = new ApiAction(); try { if (code.IsNullOrEmpty()) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"条码不能为空"); return action; } var apiAction = await _IBIZ_MES_WO.GetErpProdInBth(code); if (!apiAction.IsSuccessed) { return action; } CurSN = code.Split('|')[0]; InStoreInfo Info = apiAction.Data; //要存入的批次入库单数据 int n = InStoreScanInfos.Where(q => q.WORK_ORDER == Info.ErpProdInBth.WORK_ORDER).Count(); if (!ErpProdInBths.Any(q => q.WORK_ORDER == Info.ErpProdInBth.WORK_ORDER)) { Info.ErpProdInBth.AUTH_ORG = OrgCode; Info.ErpProdInBth.BATCH_NO = CurBatchNo; Info.ErpProdInBth.CREATE_USER = UserCode; Info.ErpProdInBth.CREATE_TIME = DateTime.Now; Info.ErpProdInBth.SCANED_DATE = DateTime.Now; Info.ErpProdInBth.HANDLED_DATE = DateTime.Now; Info.ErpProdInBth.IS_SCANED = "Y"; Info.ErpProdInBth.ORDER_NO = UserCode; Info.ErpProdInBth.IS_HANDLED = "N"; Info.ErpProdInBth.CartonQty = n == 0 ? 1 : n; BIZ_ERP_PROD_IN prodIn = new() { AUTH_ORG = OrgCode, BILLCODE = UserCode, BILLDATE = DateTime.Now, STATUS = 0, HANDLED = -1, WAREHOUSECODE = "", SOURCECODE = Info.ErpProdInBth.WORK_ORDER, HANDLED_DATE = DateTime.Now, }; ErpProdInBths.Add(Info.ErpProdInBth); ErpProdIns.Add(prodIn); } else { if (!InStoreScanInfos.Any(q => q.WORK_ORDER == Info?.ErpProdInBth.WORK_ORDER && q.SN == CurSN)) { var erpbth = ErpProdInBths.Where(q => q.WORK_ORDER == Info.ErpProdInBth.WORK_ORDER).FirstOrDefault(); if (!erpbth.IsNullOrEmpty()) { erpbth.SCAN_QTY += Info.InStoreScanInfo.SCAN_QTY.ToDouble(); erpbth.CartonQty = n + 1; } } } //生成打印实体 if (RcvRptInput.PrintJsons.Count == 0) { RcvRptInput.PrintJsons.Add(new() { ID = Guid.NewGuid().ToString("N"), Items = new() { Info.ErpProdInBth } }); } else { //拼分页 bool isAdded = false; foreach (var item in RcvRptInput.PrintJsons) { if (!item.Items.Any(q => q.WORK_ORDER == Info.ErpProdInBth.WORK_ORDER)) { if (item.Items.Count < pageSize) { item.Items.Add(Info.ErpProdInBth); isAdded = true; } } else { isAdded = true; } } if (!isAdded) { RcvRptInput.PrintJsons.Add(new() { ID = Guid.NewGuid().ToString("N"), Items = new() { Info.ErpProdInBth } }); } } //暂存扫码数据 if (!InStoreScanInfos.Any(q => q.WORK_ORDER == Info?.ErpProdInBth.WORK_ORDER && q.SN == CurSN)) { Info.InStoreScanInfo.BATCH_NO = CurBatchNo; InStoreScanInfos.Add(Info.InStoreScanInfo); } var wipPkgs = Biz.Db.Ado.UseStoredProcedure().SqlQuery("SP_MES_GET_ITEM_PKG", new SugarParameter("root", CurSN)); int maxLevel = wipPkgs.Max(p => p.LEVEL); foreach (var item in wipPkgs.Where(q => q.LEVEL == maxLevel)) { var scanResult = new BIZ_ERP_PROD_IN_SN { AUTH_ORG = OrgCode, ID = Guid.NewGuid().ToString(), CARTONNO = CurSN, SN = item.SN, BUSINESSCODE = UserCode, ITEM_CODE = item.ITEM_CODE, Qty = item.QTY.ToDecimal(), SOURCECODE = Info?.ErpProdInBth.WORK_ORDER, STATUS = WMS_ITEM.STATUSs.Counted.GetValue(), CREATE_USER = UserCode, CREATE_TIME = DateTime.Now, UPDATE_USER = UserCode, UPDATE_TIME = DateTime.Now, }; ErpProdInSns.Add(scanResult); } //保存数据库 var db = Business.Biz.Db; var dbTran = db.UseTran(() => { var x = db.Storageable(ErpProdInBths, $"InStoreOrderNo_{UserCode}") .WhereColumns(t => new { t.ORDER_NO, t.WORK_ORDER, t.GHOST_ROW }) .ToStorage(); x.AsInsertable.ExecuteCommand(); x.AsUpdateable.IgnoreColumns(x => x.ID).ExecuteCommand(); var s = db.Storageable(ErpProdInSns, $"InStoreOrderNo_{UserCode}") .WhereColumns(t => new { t.CARTONNO, t.SN, t.GHOST_ROW }) .ToStorage(); s.AsInsertable.ExecuteCommand(); s.AsUpdateable.IgnoreColumns(x => x.ID).ExecuteCommand(); }); if (!dbTran.IsSuccess) { Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception"); this.Close(!dbTran.IsSuccess); throw dbTran.ErrorException; } RcvRptInput.RcvRptDocBases = new(); RcvRptInput.labels = new(); RcvRptInput.ErpProdInBths = ErpProdInBths; RcvRptInput.userId = UserCode; inStoreInfos = new() { ErpProdInBths = ErpProdInBths, InStoreScanInfos = InStoreScanInfos, }; action.Data = inStoreInfos; } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"扫描条码[{code}]复核异常"); } return action; } /// /// 调用U9C接口生成入库单 /// /// /// public async Task> GenerateInStoreOrder() { var action = new ApiAction(); try { //如果扫描记录为0 if (!RcvRptInput.ErpProdInBths.Any(q => q.IS_HANDLED == "N")) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"没有要入库的产品数据,请扫描包装完成的箱二维码重新生成入库单据!"); return action; } if (RcvRptInput.RcvRptDocBases.IsNullOrEmpty() || RcvRptInput.RcvRptDocBases.Count == 0) { foreach (var item in RcvRptInput.ErpProdInBths) { var DocBase = new RcvRptDocBase() { WorkOrder = item.WORK_ORDER, ItemCode = item.ITEM_CODE, WhCode = "10105", PkgQty = item.SCAN_QTY, CompleteQty = item.SCAN_QTY, OutputType = 0, StorageType = 4, DocState = 1, Status = "N" }; if (!RcvRptInput.RcvRptDocBases.Any(q => q.WorkOrder == item.WORK_ORDER)) { RcvRptInput.RcvRptDocBases.Add(DocBase); } } } else { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"有存在未提交的入库单,不能生成入库单"); return action; } action = await _IMES_U9C.RcvRptDocCreate(RcvRptInput); if (action.IsSuccessed) { foreach (var sn in ErpProdInSns) { var d = action.Data.ErpProdInBths.Where(q => q.WORK_ORDER == sn.SOURCECODE).FirstOrDefault(); if (!d.IsNullOrEmpty()) { sn.BUSINESSCODE = d.ORDER_NO; sn.UPDATE_USER = UserCode; sn.UPDATE_TIME = DateTime.Now; } } foreach (var p in ErpProdIns) { var d = action.Data.ErpProdInBths.Where(q => q.WORK_ORDER == p.SOURCECODE).FirstOrDefault(); if (!d.IsNullOrEmpty()) { p.BILLCODE = d.ORDER_NO; p.UPDATE_USER = UserCode; p.UPDATE_TIME = DateTime.Now; p.HANDLED = 0; } } //保存数据库 var db = Business.Biz.Db; var dbTran = db.UseTran(() => { db.Updateable(ErpProdInSns, $"InStoreOrderNo_{UserCode}").UpdateColumns(q => new { q.UPDATE_TIME, q.UPDATE_USER, q.BUSINESSCODE }).ExecuteCommand(); var x = db.Storageable(ErpProdIns, $"InStoreOrderNo_{UserCode}") .WhereColumns(t => new { t.BILLCODE, t.SOURCECODE, t.GHOST_ROW }) .ToStorage(); x.AsInsertable.ExecuteCommand(); x.AsUpdateable.IgnoreColumns(x => x.ID).ExecuteCommand(); }); if (!dbTran.IsSuccess) { Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception"); this.Close(!dbTran.IsSuccess); throw dbTran.ErrorException; } } } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"调用U9C接口生成入库单异常"); } return action; } /// /// 查询已扫描列表 /// /// public async Task> GetScannedList() { var action = new ApiAction(); try { _GetScannedList(); action.Data = inStoreInfos; } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"查询已扫描列表异常"); } return action; } /// /// 从数据库读回操作者原本操作的记录 /// /// private RcvRptDocCreateInput _GetScannedList() { RcvRptInput.RcvRptDocBases = new(); RcvRptInput.ErpProdInBths = new(); RcvRptInput.PrintJsons = new(); RcvRptInput.labels = new(); RcvRptInput.userId = UserCode; ErpProdInSns.Clear(); ErpProdIns.Clear(); ErpProdInBths.Clear(); InStoreScanInfos.Clear(); RcvRptInput.ErpProdInBths = Biz.Db.Queryable() .Where(q => q.BATCH_NO == SqlFunc.Subqueryable().Where(s => s.ORDER_NO == UserCode && s.GHOST_ROW == false).Select(s => s.BATCH_NO)) .IncludesAllFirstLayer().ToList(); foreach (var item in RcvRptInput.ErpProdInBths) { var values = item.ProdInSns.GroupBy(x => x.CARTONNO) .Select(g => new InStoreScanInfo() { SN = g.Key, SALES_ORDER = item.SALES_ORDER, BATCH_NO = item.BATCH_NO, WORK_ORDER = item.WORK_ORDER, SCAN_QTY = g.Sum(x => x.Qty).ToDouble() }); foreach (var t in values) { InStoreScanInfos.Add(t); } item.CartonQty = values.Count(); ErpProdIns.Add(new() { AUTH_ORG = OrgCode, BILLCODE = UserCode, BILLDATE = DateTime.Now, STATUS = 0, HANDLED = -1, WAREHOUSECODE = "", SOURCECODE = item.WORK_ORDER, HANDLED_DATE = DateTime.Now, }); ErpProdInSns.AddRange(item.ProdInSns); //生成打印实体 if (RcvRptInput.PrintJsons.Count == 0) { RcvRptInput.PrintJsons.Add(new() { ID = Guid.NewGuid().ToString("N"), Items = new() { item } }); } else { //拼分页 bool isAdded = false; foreach (var p in RcvRptInput.PrintJsons) { if (!p.Items.Any(q => q.WORK_ORDER == item.WORK_ORDER)) { if (p.Items.Count < pageSize) { p.Items.Add(item); isAdded = true; } } else { isAdded = true; } } if (!isAdded) { RcvRptInput.PrintJsons.Add(new() { ID = Guid.NewGuid().ToString("N"), Items = new() { item } }); } } } ErpProdInBths = RcvRptInput.ErpProdInBths; inStoreInfos = new() { ErpProdInBths = ErpProdInBths, InStoreScanInfos = InStoreScanInfos, }; return RcvRptInput; } /// /// 删除箱 /// /// /// public async Task Delete(string CartonNo) { var action = new ApiAction(); try { var ErpProdInSn = ErpProdInSns.Where(s => s.CARTONNO == CartonNo).ToList(); BIZ_ERP_PROD_IN_BTH erpbth = new(); if (!ErpProdInSn.IsNullOrEmpty()) { erpbth = ErpProdInBths.Where(q => q.WORK_ORDER == ErpProdInSn[0].SOURCECODE).FirstOrDefault(); if (!erpbth.IsNullOrEmpty()) { erpbth.SCAN_QTY -= ErpProdInSn.Count(q => q.CARTONNO == CartonNo); erpbth.CartonQty--; } } //保存数据库 var db = Business.Biz.Db; var dbTran = db.UseTran(() => { db.Deleteable().Where(x => x.BUSINESSCODE == UserCode && x.CARTONNO == CartonNo).ExecuteCommand(); db.Updateable(erpbth, $"InStoreOrderNo_{UserCode}").ExecuteCommand(); if (erpbth.CartonQty == 0) { db.Deleteable(erpbth).ExecuteCommand(); } }); if (!dbTran.IsSuccess) { Logger.Default.Fatal(dbTran.ErrorException, "Database transaction delete exception"); this.Close(!dbTran.IsSuccess); throw dbTran.ErrorException; } } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"查询已扫描列表异常"); } return action; } /// /// 清除 /// /// public async Task Clear() { var action = new ApiAction(); try { RcvRptInput = new(); ProdInBatchs = new() { }; ErpProdInBths = new() { }; ErpProdIns = new(); /// /// 扫描列表 /// InStoreScanInfos = new() { }; ErpProdInSns = new(); inStoreInfos = new() { }; //保存数据库 var db = Business.Biz.Db; var dbTran = db.UseTran(() => { db.Deleteable().Where(x => x.ORDER_NO == UserCode && x.IS_HANDLED == "N").ExecuteCommand(); db.Deleteable().Where(x => x.BUSINESSCODE == UserCode).ExecuteCommand(); }); if (!dbTran.IsSuccess) { Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception"); this.Close(!dbTran.IsSuccess); throw dbTran.ErrorException; } } catch (Exception ex) { action.CatchExceptionWithLog(ex, $"查询已扫描列表异常"); } return action; } #endregion Functions public override bool Close(bool needSaveHistoryLog = false) { //needSaveHistoryLog = true; //保存操作日志 this.IsFinished = true; return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished; } }//endClass }