using Rhea.Common; using Tiger.Business.WMS.Seastone; using Microsoft.AspNetCore.Http; 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 System.DirectoryServices.ActiveDirectory; using System.Reflection.Emit; using Tiger.Model; using Tiger.IBusiness; namespace Tiger.Business.WMS.Transaction { /// /// 其他入库清点事务 /// public class OtherInLocationChecking : WMSTransactionBase, IOtherInLocationChecking { public IOtherInLocationChecking Init(string id, string userCode, string apiHost, string orgCode) { TransID = id; UserCode = userCode; ApiHost = apiHost; OrgCode = orgCode; Logger.Console.Info($"Start {this.GetType().Name} Transaction[ID: {TransID}]"); return this; } #region Propertys & Variables public string UserCode { get; set; } public static long UserId { get; set; } public string VenderCode { get; set; } public string LotNo { get; set; } public string SecondVenderCode { get; set; } public string WarehouseCode { get; set; } public string WarehouseName { get; set; } public string OrgCode { get; set; } public string CustomsNo { get; set; } public List suppliers { get; set; } #endregion Propertys & Variables #region Functions /// /// 扫描物料并复核,如果物料已经完成移库则货架上亮灯提醒储位 /// public async Task ScanItem(CustSupplyCheckingInput input) { var action = new ApiAction(); try { if (string.IsNullOrEmpty(input.SN)) { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.SnEmptyFailure", input.SN); return action; } #region 报关单号判断 if (input.AuthOption.CurOrg == "YTXC" && string.IsNullOrWhiteSpace(CustomsNo)) { if (string.IsNullOrWhiteSpace(input.SN)) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"盐田据点请扫描报关单号二维码!"); return action; } var customsNo = input.SN.Replace(",", ",").Trim(); if (customsNo.Split(",").Length != 2) { action.IsSuccessed = false; action.LocaleMsg = Biz.L($"报关单号格式错误,请确认格式是否为【报关单号,核算清单号】!"); return action; } CustomsNo = input.SN; action.Data = new IncomingMatStorage { sn = CustomsNo, IsCustomsNo = true }; action.IsSuccessed = true; action.LocaleMsg = Biz.L($"报关单号二维码扫描成功"); return action; } #endregion 报关单号判断 //判断是否扫描的仓库,并查询是否存在 var query = Biz.Db.Queryable().Where(t => t.WH_CODE == input.SN.Trim()).First(); if (query != null) { WarehouseCode = query.WH_CODE; WarehouseName = query.WH_NAME; action.Data = query; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.GetWhSuccess", WarehouseCode); return action; } if (string.IsNullOrEmpty(WarehouseCode)) { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.NotExist", input.SN); return action; } input.AuthOption.OrgCode = input.AuthOption.OrgCode.IsNullOrEmpty() ? input.AuthOption.CurOrg : input.AuthOption.OrgCode; Result result = WarehouseName.Contains("客供") ? WMS_ITEM_Biz.WmsItem.GetK(input.SN, input.AuthOption, false) : WMS_ITEM_Biz.WmsItem.Get(input.SN, input.AuthOption, false); if (result.Flag != Result.Flags.Success) { action.IsSuccessed = false; action.LocaleMsg = result.LocaleMsg; return action; } var curBarcode = result.Data; if (!curBarcode.IsQRCode) { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.NotQrCode", curBarcode.Barcode.MetaSn); return action; } //判断条码是否为最少包装 if (!new[] { Barcode.Types.Small, Barcode.Types.Other }.Contains(curBarcode.Barcode.Type)) { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.TypeError", curBarcode.SN); return action; } //判断条码状态为不存在或已下架可以清点(!nDisassembleBarcode.isNormalStatus ||) //物料验证 if (curBarcode.ItemInfo.IsNullOrEmpty() || curBarcode.ItemInfo.IS_ACTIVE == "N") { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.ProdMReq.ScanItem.ItemCodeNotExistsOrNotActive", curBarcode.ItemInfo.ITEM_CODE.IsNullOrEmpty(curBarcode.Barcode.ItemCode)); return action; } if (!new[] { WMS_ITEM.STATUSs.NotExists, WMS_ITEM.STATUSs.OffShelf }.Contains(curBarcode.Status)) { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.ExistItem", curBarcode.ItemInfo.ITEM_CODE); return action; } BIZ_ERP_OTH_IN_SNExt snExt = new(); // BIZ_ERP_OTH_IN_SN scanResult = Business.Biz.Db.Queryable().Where(q=>q.SN==curBarcode.Barcode.SN).First(); //验证条码是否已做过清点 var scanResult = Biz.Db.Queryable().Where(t => t.SN.ToUpper() == curBarcode.SN.ToUpper()).First(); if (!scanResult.IsNullOrEmpty() && scanResult.STATUS > WMS_ITEM.STATUSs.Counted.GetValue()) { action.IsSuccessed = false; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.BarcodeCounted", curBarcode.SN); return action; } var isNo = true; //判断物料是否存在 if (scanResult.IsNullOrEmpty()) { isNo = false; scanResult = new(); scanResult.ID = Guid.NewGuid().ToString(); scanResult.CREATE_USER = UserCode; scanResult.BUSINESSCODE = "OTH_" + UserCode; scanResult.WAREHOUSECODE = WarehouseCode; scanResult.SN = curBarcode.Barcode.SN; scanResult.ITEM_CODE = curBarcode.Barcode.ItemCode; scanResult.QTY = curBarcode.Barcode.Qty ?? 0; scanResult.DATECODE = curBarcode.Barcode.ProdDate ?? DateTime.MinValue; scanResult.LOTNO = LotNo; //item.Barcode.LotNo; scanResult.STATUS = WMS_ITEM.STATUSs.Counted.GetValue(); scanResult.META_SN = input.SN; scanResult.AUTH_ORG = input.AuthOption.CurOrg; } else { isNo = true; //scanResult.ID = Guid.NewGuid().ToString(); scanResult.BUSINESSCODE = "OTH_" + UserCode; scanResult.WAREHOUSECODE = WarehouseCode; scanResult.SN = curBarcode.SN; scanResult.ITEM_CODE = curBarcode.ItemInfo.ITEM_CODE; scanResult.QTY = curBarcode.Barcode.Qty ?? 0; scanResult.DATECODE = curBarcode.Barcode.ProdDate ?? DateTime.MinValue; scanResult.LOTNO = LotNo; //item.Barcode.LotNo; scanResult.STATUS = WMS_ITEM.STATUSs.Counted.GetValue(); scanResult.META_SN = input.SN; scanResult.AUTH_ORG = input.AuthOption.CurOrg; } OrgCode = input.AuthOption.CurOrg; snExt.BUSINESSCODE = scanResult.BUSINESSCODE; snExt.WAREHOUSECODE = scanResult.WAREHOUSECODE; snExt.SN = scanResult.SN; snExt.ITEM_CODE = scanResult.ITEM_CODE; snExt.QTY = scanResult.QTY; snExt.DATECODE = scanResult.DATECODE; snExt.DATECODESTR = scanResult.DATECODESTR; snExt.LOTNO = scanResult.LOTNO; snExt.STATUS = scanResult.STATUS; snExt.WH_CODE = scanResult.WAREHOUSECODE; snExt.WH_NAME = WarehouseName; snExt.MName = curBarcode.ItemInfo?.ITEM_NAME; snExt.MDesc = curBarcode.ItemInfo?.SPEC; snExt.MUom = curBarcode.ItemInfo?.UNIT; //保存到数据库 var db = Business.Biz.Db; var model = new BIZ_ERP_CUSTOMS() { AUTH_ORG = input.AuthOption.CurOrg, CREATE_USER = UserCode, OrderNo = UserCode, Barcodes = curBarcode.SN, CustomsNo = CustomsNo.Replace(",", ",").Trim().Split(',')[0], AccountingNo = CustomsNo.Replace(",", ",").Trim().Split(',')[1], CountsType = BIZ_ERP_CUSTOMS.CountsEnum.OtherInput }; if (model != null) { db.Insertable(model).ExecuteCommand(); } var dbTran = db.UseTran(() => { db.Storageable(scanResult).ExecuteCommand(); }); if (!dbTran.IsSuccess) { Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception"); this.Close(!dbTran.IsSuccess); throw dbTran.ErrorException; } action.Data = snExt; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.CountSuccess", input.SN); } catch (Exception ex) { //取消当前操作 action.CatchExceptionWithLog(ex, $"扫描物料[{input.SN}]复核异常"); action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.ScanException", input.SN); } return action; } // /// 生成其他物料入库单据 /// /// /// public async Task SubmitInvBill() { var action = new ApiAction(); bool isIQCOk = true; try { //获取当前用户所有已清点、未制单的条码数据 var nScannedBarcodes = await Biz.Db.Queryable((t, m) => new JoinQueryInfos( JoinType.Left, t.ITEM_CODE == m.ITEM_CODE )) .Where((t, m) => t.CREATE_USER == UserCode && t.WAREHOUSECODE.ToUpper() == WarehouseCode.ToUpper() && t.STATUS == WMS_ITEM.STATUSs.Counted.GetValue() && t.BUSINESSCODE == "OTH_" + UserCode && t.AUTH_ORG == OrgCode) .Select((t, m) => new BIZ_ERP_OTH_IN_SNExt { ID = t.ID, SN = t.SN, ITEM_CODE = t.ITEM_CODE, QTY = t.QTY, META_SN = t.META_SN, BUSINESSCODE = t.BUSINESSCODE, BUSINESSLINE = t.BUSINESSLINE, UPDATE_TIME = t.UPDATE_TIME, UPDATE_USER = t.UPDATE_USER, CREATE_TIME = t.CREATE_TIME, CREATE_USER = t.CREATE_USER, DATECODE = t.DATECODE, DATECODESTR = t.DATECODESTR, LOTNO = t.LOTNO, STATUS = t.STATUS, WAREHOUSECODE = t.WAREHOUSECODE, MUom = m.UNIT, MName = m.ITEM_NAME, MDesc = m.SPEC, }) .ToListAsync(); if (!nScannedBarcodes.Any()) { action.IsSuccessed = false; action.Message = $"没有可以提交的清点数据"; action.LocaleMsg = Biz.L("WMS.CustSupChk.ScanItem.NotDataToSubmit"); return action; } // 查询条码清点表所有仓库代码 //var nWarehouseCodes = nScannedBarcodes.Select(x => x.WarehouseCode).Distinct().ToList(); //新建其他入库单据头 OtherInstockHeader Result ruleResult = Biz.CodeRule["OI001"].Generate("OI"); //iWMS.GetBillNoByType("CI"); if (!ruleResult.IsSuccessed) { throw new Exception(ruleResult.ExceptionMsg.Message); } var billcode = ruleResult.Data.ToString(); var nBillHeader = new BIZ_ERP_OTH_IN { BILLCODE = billcode, BILLDATE = DateTime.Now.Date, WAREHOUSECODE = WarehouseCode, STATUS = BIZ_ERP_OTH_IN.STATUSs.WORKING.GetValue(), REMARK = LotNo, AUTH_ORG = OrgCode }; // 查找待处理记录料号列表 var nMaterials = nScannedBarcodes.Select(x => x.ITEM_CODE).Distinct().ToList(); // 单据行号变量,初始值1 var nLineSeq = 1; List scanList = new List(); List detailList = new List(); //List iqcHeaders = new List(); //List details = new List(); // 按照料号列表处理单据明细 foreach (var matCode in nMaterials) { // 按照料号、计量单位汇总scanBarcode var lineMaterials = (from codes in nScannedBarcodes.Where(x => x.ITEM_CODE.ToUpper() == matCode.ToUpper()) group codes by new { codes.ITEM_CODE, codes.MUom } into g select new { g.Key.ITEM_CODE, g.Key.MUom, sumQty = g.Sum(x => x.QTY) } ).ToList(); // 循环处理每一行 foreach (var matLine in lineMaterials) { //插入单据明细行 var billDetail = new BIZ_ERP_OTH_IN_DTL { WAREHOUSECODE = WarehouseCode, BILLCODE = billcode, BILLLINE = nLineSeq.ToString(), LINESTATUS = BIZ_ERP_OTH_IN.STATUSs.WORKING.GetValue(), ITEM_CODE = matLine.ITEM_CODE, UNITCODE = matLine.MUom, PRQTY = matLine.sumQty, AUTH_ORG = OrgCode, QTY = 0 }; detailList.Add(billDetail); // 更新清点表,单据号 foreach (BIZ_ERP_OTH_IN_SN barcode in nScannedBarcodes.Where(x => x.ITEM_CODE == matLine.ITEM_CODE)) { barcode.BUSINESSCODE = billcode; barcode.BUSINESSLINE = nLineSeq.ToString(); barcode.STATUS = WMS_ITEM.STATUSs.WaitIn.GetValue(); barcode.AUTH_ORG = OrgCode; scanList.Add(barcode); } // 单据明细行号 ++ nLineSeq++; } } ////调用T100接口生成到货单 List Items = new List(); List ItemPkgs = new List(); List ItemHistorys = new List(); #region 生成库存数据 foreach (var wi in nScannedBarcodes) { Barcode barcode = new Barcode(wi.META_SN); WMS_ITEM wmsItem = new WMS_ITEM { SN = wi.SN, ITEM_CODE = wi.ITEM_CODE, QTY = wi.QTY, PROD_DATE = barcode.ProdDate ?? DateTime.MinValue, SUPP_CODE = VenderCode, LOTNO = LotNo, ERP_WH = WarehouseCode, STATUS = WMS_ITEM.STATUSs.WaitIn.GetValue(), TRANS_CODE = nameof(BIZ_ERP_OTH_IN), TRANS_NO = billcode, TRANS_LINE = wi.BUSINESSLINE, //SOURCE_CODE = nameof(BIZ_ERP_IQC), //SOURCE_ORDER = item.BILLCODE, AUTH_ORG = OrgCode, }; Items.Add(wmsItem); WMS_ITEM_HIS his = new WMS_ITEM_HIS(wmsItem, $"其他入库单清点,到货单[{billcode}]"); ItemHistorys.Add(his); WMS_ITEM_PKG pKG = new WMS_ITEM_PKG { SN = wi.SN, ITEM_CODE = wi.ITEM_CODE, PARENT_SN = "", PKG_TYPE = WMS_ITEM_PKG.PKG_TYPEs.OnePiece.GetValue(), QTY = wi.QTY, SUPP_CODE = VenderCode, LOTNO = LotNo, ERP_WH = WarehouseCode, TRANS_CODE = nameof(BIZ_ERP_OTH_IN), TRANS_NO = billcode, TRANS_LINE = wi.BUSINESSLINE, //SOURCE_CODE = nameof(BIZ_ERP_IQC), //SOURCE_ORDER = item.BILLCODE, AUTH_ORG = OrgCode, }; ItemPkgs.Add(pKG); } #endregion 生成库存数据 //保存到数据库 var db = Business.Biz.Db; var dbTran = db.UseTran(() => { // 插入单据表头 var headerId = Biz.Db.Insertable(nBillHeader, UserCode).ExecuteReturnBigIdentity(); var x = db.Storageable(detailList, UserCode).ToStorage(); x.AsInsertable.ExecuteCommand();//不存在插入 x.AsUpdateable.IgnoreColumns(z => new { z.CREATE_TIME, z.CREATE_USER }).ExecuteCommand();//存在更新,更新时忽略字段CreationTime、CreatorUserId db.Updateable(scanList, UserCode).ExecuteCommand(); //if (action.IsSuccessed && isIQCOk) //{ // db.Insertable(iqcHeaders, UserCode).ExecuteCommand(); // action.Message += $"{action.Message.IsNullOrEmpty("", ";")}生成其他物料入库单据和送检单成功"; //} //db.Insertable(Items, UserCode).ExecuteCommand(); var y = db.Storageable(Items, UserCode).WhereColumns(t => t.SN).ToStorage(); y.AsInsertable.ExecuteCommand();//不存在插入 y.AsUpdateable.ExecuteCommand(); db.Insertable(ItemPkgs, UserCode).ExecuteCommand(); db.Insertable(ItemHistorys, UserCode).ExecuteCommand(); }); if (!dbTran.IsSuccess) { Logger.Default.Fatal(dbTran.ErrorException, "Database transaction save exception"); this.Close(!dbTran.IsSuccess); throw dbTran.ErrorException; } } catch (System.Exception ex) { return action.CatchExceptionWithLog(ex, Biz.L("")); } return action; } /// /// 删除当前用户的已扫记录(缓存表) /// /// public async Task DeleteAllScannedBarcode() { var action = new ApiAction(); try { if (WarehouseCode.IsNullOrEmpty()) { action.IsSuccessed = false; action.Message = $"空,无法删除已清点条码"; return action; } else { await Biz.Db.Deleteable(x => x.CREATE_USER == UserCode && x.WAREHOUSECODE == WarehouseCode && x.STATUS == WMS_ITEM.STATUSs.Counted.GetValue() && x.BUSINESSCODE == "OTH_" + UserCode).ExecuteCommandAsync(); } } catch (System.Exception ex) { } return action; } /// /// 删除单个条码(缓存表) /// /// public async Task DeleteScannedBarcode(CustSupplyInInput input) { var action = new ApiAction(); try { if (WarehouseCode.IsNullOrEmpty()) { action.IsSuccessed = false; action.Message = $"空,无法删除已清点条码"; return action; } else { await Biz.Db.Deleteable(x => x.SN == input.SN).ExecuteCommandAsync(); } } catch (System.Exception ex) { } return action; } /// /// 获取已清点的物料汇总 /// /// public async Task> GetScannedMaterialSummarys() { var query = Biz.Db.Queryable((t, m) => new JoinQueryInfos( JoinType.Left, t.ITEM_CODE == m.ITEM_CODE )) .Where((t, m) => t.CREATE_USER == UserCode && t.WAREHOUSECODE.ToUpper() == WarehouseCode.ToUpper() && t.STATUS == WMS_ITEM.STATUSs.Counted.GetValue() && t.BUSINESSCODE == "OTH_" + UserCode) .GroupBy((t, m) => new { t.WAREHOUSECODE, t.ITEM_CODE }) .Select((t, m) => new Model.Minsun.CustSupplyCheckList { WarehouseCode = t.WAREHOUSECODE, MaterialCode = t.ITEM_CODE, MaterialName = SqlFunc.AggregateMax(m.ITEM_NAME), MaterialStandard = SqlFunc.AggregateMax(m.SPEC), InventoryQty = SqlFunc.AggregateSum(t.QTY), Unit = SqlFunc.AggregateMax(m.UNIT) }) .ToList(); return await Task.FromResult(new PageAble() { data = query, totals = query.Count(), }); } /// /// 查询物料对应的条码 /// /// /// public async Task> GetScannedMaterialDetailBarcodes(string MaterialCode) { var query = await Biz.Db.Queryable((t, m) => new JoinQueryInfos( JoinType.Left, t.ITEM_CODE == m.ITEM_CODE )) .Where((t, m) => t.CREATE_USER == UserCode && t.WAREHOUSECODE.ToUpper() == WarehouseCode.ToUpper() && t.STATUS == WMS_ITEM.STATUSs.Counted.GetValue() && t.ITEM_CODE.ToUpper() == MaterialCode.ToUpper() && t.BUSINESSCODE == "OTH_" + UserCode) .Select((t, m) => new Model.Minsun.CustSupplyCheckDetail { Barcode = t.SN, BarcodeQty = t.QTY, Unit = m.UNIT }) .ToListAsync(); return new PageAble() { data = query, totals = query.Count(), }; } #endregion Functions public override bool Close(bool needSaveHistoryLog = false) { //保存操作日志 this.IsFinished = true; return IsFinished ? base.Close(needSaveHistoryLog) : IsFinished; } }//endClass }