服务端的TigerApi 框架,基于.NET6 2024 版本
Ben Lin
20 小时以前 a960900364d19bbf0ad7923a57989609e7fce798
Tiger.Business.WMS/WMS_ITEM_Biz.cs
@@ -3,7 +3,6 @@
using SqlSugar;
using System;
using System.Collections.Generic;
using System.DirectoryServices.ActiveDirectory;
using System.Linq;
using System.Threading.Tasks;
using Tiger.IBusiness;
@@ -32,16 +31,21 @@
            /// <param name="option">授权查询选项</param>
            /// <param name="doUnPack">是否同时执行拆包操作,解除与父条码之间的包装关系</param>
            /// <returns></returns>
            public Result<Inventory> Get(string sn, AuthOption option, bool doUnPack)
            public Result<IInventory> Get(string sn, AuthOption option, bool doUnPack)
            {
                var result = new Result<Inventory>(Result.Flags.Success, new Inventory());
                var result = new Result<IInventory>(Result.Flags.Success);
                try
                {
                    var inv = new Inventory();
                    Barcode barcode = new Barcode(sn);
                    if (sn.IsNullOrEmpty())
                    {
                        result.Flag = Result.Flags.Failed;
                        result.LocaleMsg = new("WMS.WmsItem.Barcode.EmptyFailure");
                    }
                    else if (barcode.IsException)
                    {
                        throw barcode.AnalyseException;
                    }
                    //非法条码
                    else if (!barcode.IsRegular)
@@ -49,40 +53,39 @@
                        result.Flag = Result.Flags.Failed;
                        result.LocaleMsg = new("WMS.WmsItem.Barcode.IllegalFailure");
                    }
                    else if (barcode.Qty <= 0)
                    {
                        result.Flag = Result.Flags.Failed;
                        result.LocaleMsg = new("数量不能小于等于零,请检查二维码!");
                    }
                    //else if (barcode.Qty <= 0)
                    //{
                    //    result.Flag = Result.Flags.Failed;
                    //    result.LocaleMsg = new("数量不能小于等于零,请检查二维码!");
                    //}
                    else
                    {
                        var query = Biz.Db.Queryable<WMS_ITEM_PKG>().ByAuth(option).Where(q => q.SN == barcode.SN).IncludesAllFirstLayer().First();
                        //var query = Biz.Db.Queryable<WMS_ITEM_PKG>().Where(q => q.SN == barcode.SN).IncludesAllFirstLayer().First();//.ByAuth(option)
                        //包装表中找到条码
                        if (!query.IsNullOrEmpty() && query.QTY > 0)
                        if (!query.IsNullOrEmpty())// && query.QTY > 0)
                        {
                            result.Data.SN = barcode.SN;
                            result.Data.Barcode = barcode;
                            result.Data.ExtInfo = query.ExtInfo;
                            result.Data.ItemInfo = query.ItemInfo;
                            result.Data.Warehouse = query.Warehouse;
                            result.Data.Region = query.Region;
                            result.Data.Shelf = query.Shelf;
                            result.Data.Location = query.Location;
                            result.Data.Packages = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM_PKG>("pkg_wms_get_item_pkg", new SugarParameter("root", barcode.SN));
                            result.Data.Items = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM>("pkg_wms_get_items", new SugarParameter("root", barcode.SN));
                            result.Data.ItemsExt = Biz.Db.Queryable<WMS_ITEM_EXT>().Where(q => result.Data.Items.Any(s => s.SN == q.SN)).ToList();
                            //var data = result.Data.Items.Select(i => i.SN).ToList().Except(result.Data.ItemsExt.Select(i => i.SN).ToList());
                            var data = result.Data.Items.Where(q => !result.Data.ItemsExt.Any(s => s.SN == q.SN)).ToList();
                            inv.SN = barcode.SN;
                            inv.Barcode = barcode;
                            inv.ExtInfo = query.ExtInfo;
                            inv.ItemInfo = query.ItemInfo;
                            inv.Warehouse = query.Warehouse;
                            inv.Region = query.Region;
                            inv.Shelf = query.Shelf;
                            inv.Location = query.Location;
                            inv.Packages = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM_PKG>("sp_wms_get_item_pkg", new SugarParameter("root", barcode.SN));
                            inv.Items = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM>("sp_wms_get_items", new SugarParameter("root", barcode.SN));
                            inv.ItemsExt = Biz.Db.Queryable<WMS_ITEM_EXT>().Where(q => inv.Items.Any(s => s.SN == q.SN)).ToList();
                            //var data = inv.Items.Select(i => i.SN).ToList().Except(inv.ItemsExt.Select(i => i.SN).ToList());
                            var data = inv.Items.Where(q => !inv.ItemsExt.Any(s => s.SN == q.SN)).ToList();
                            if (data.Count > 0)
                            {
                                foreach (var item in data)
                                {
                                    result.Data.ItemsExt.Add(new()
                                    inv.ItemsExt.Add(new()
                                    {
                                        SN = item.SN,
                                        SUPP_ITEM_CODE = barcode.OEMItemCode,
                                        META_SN = barcode.MetaSn,
                                        QR_CODE = barcode.MetaSn
                                    });
@@ -91,12 +94,12 @@
                            result.LocaleMsg = new($"WMS.WmsItem.Barcode.Get{(doUnPack ? "UnPack" : "")}Success", barcode.SN, query.Parent?.SN);
                            if (!query.Parent.IsNullOrEmpty() && doUnPack && query.Parent.SN != query.SN)
                            {
                                result.Data.ParentPkg = null;
                                inv.ParentPkg = null;
                                //保存数据到数据库
                                var db = Biz.Db;
                                var dbTran = db.UseTran(() =>
                                {
                                    var unPackQty = result.Data.Items.Sum(q => q.QTY);
                                    var unPackQty = inv.Items.Sum(q => q.QTY);
                                    db.Updateable<WMS_ITEM_PKG>().SetColumns(q => q.PARENT_SN == null).Where(q => q.ID == query.ID).ExecuteCommand();
                                    db.Updateable<WMS_ITEM_PKG>().SetColumns(q => q.QTY == q.QTY - unPackQty).Where(q => q.ID == query.Parent.ID).ExecuteCommand();
                                    if (!Biz.Db.Queryable<WMS_ITEM_PKG>().Any(q => q.PARENT_SN == query.PARENT_SN && q.SN != query.SN))
@@ -111,17 +114,18 @@
                            }
                            else
                            {
                                result.Data.ParentPkg = query.Parent;
                                inv.ParentPkg = query.Parent;
                            }
                        }
                        else
                        {
                            result.Data.SN = barcode.SN;
                            result.Data.Barcode = barcode;
                            result.Data.ItemInfo = Biz.Db.Queryable<BAS_ITEM>().Where(q => q.ITEM_CODE == barcode.ItemCode).First();
                            inv.SN = barcode.SN;
                            inv.Barcode = barcode;
                            inv.ItemInfo = Biz.Db.Queryable<BAS_ITEM>().Where(q => q.ITEM_CODE == barcode.ItemCode).First();
                            result.LocaleMsg = new($"WMS.WmsItem.Barcode.NotFound", barcode.SN);
                        }
                    }
                    result.Data = inv;
                }
                catch (Exception ex)
                {
@@ -138,17 +142,22 @@
            /// <param name="option">授权查询选项</param>
            /// <param name="doUnPack">是否同时执行拆包操作,解除与父条码之间的包装关系</param>
            /// <returns></returns>
            public Result<Inventory> GetK(string sn, AuthOption option, bool doUnPack)
            public Result<IInventory> GetK(string sn, AuthOption option, bool doUnPack)
            {
                var result = new Result<Inventory>(Result.Flags.Success, new Inventory());
                var result = new Result<IInventory>(Result.Flags.Success, new Inventory());
                try
                {
                    var inv = new Inventory();
                    Barcode barcode = new Barcode(sn);
                    barcode.ItemCode = (barcode.ItemCode.IsNullOrEmpty("K").StartsWith("K") ? "" : "K") + barcode.ItemCode;
                    if (sn.IsNullOrEmpty())
                    {
                        result.Flag = Result.Flags.Failed;
                        result.LocaleMsg = new("WMS.WmsItem.Barcode.EmptyFailure");
                    }
                    else if (barcode.IsException)
                    {
                        throw barcode.AnalyseException;
                    }
                    //非法条码
                    else if (!barcode.IsRegular)
@@ -168,28 +177,27 @@
                        //包装表中找到条码
                        if (!query.IsNullOrEmpty() && query.QTY > 0)
                        {
                            result.Data.SN = barcode.SN;
                            result.Data.Barcode = barcode;
                            result.Data.ExtInfo = query.ExtInfo;
                            result.Data.ItemInfo = query.ItemInfo;
                            result.Data.Warehouse = query.Warehouse;
                            result.Data.Region = query.Region;
                            result.Data.Shelf = query.Shelf;
                            result.Data.Location = query.Location;
                            result.Data.Packages = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM_PKG>("pkg_wms_get_item_pkg", new SugarParameter("root", barcode.SN));
                            result.Data.Items = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM>("pkg_wms_get_items", new SugarParameter("root", barcode.SN));
                            result.Data.ItemsExt = Biz.Db.Queryable<WMS_ITEM_EXT>().Where(q => result.Data.Items.Any(s => s.SN == q.SN)).ToList();//扩展表
                            //var data = result.Data.Items.Select(i => i.SN).ToList().Except(result.Data.ItemsExt.Select(i => i.SN).ToList());
                            var data = result.Data.Items.Where(q => !result.Data.ItemsExt.Any(s => s.SN == q.SN)).ToList();
                            inv.SN = barcode.SN;
                            inv.Barcode = barcode;
                            inv.ExtInfo = query.ExtInfo;
                            inv.ItemInfo = query.ItemInfo;
                            inv.Warehouse = query.Warehouse;
                            inv.Region = query.Region;
                            inv.Shelf = query.Shelf;
                            inv.Location = query.Location;
                            inv.Packages = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM_PKG>("sp_wms_get_item_pkg", new SugarParameter("root", barcode.SN));
                            inv.Items = Biz.Db.Ado.UseStoredProcedure().SqlQuery<WMS_ITEM>("sp_wms_get_items", new SugarParameter("root", barcode.SN));
                            inv.ItemsExt = Biz.Db.Queryable<WMS_ITEM_EXT>().Where(q => inv.Items.Any(s => s.SN == q.SN)).ToList();//扩展表
                            //var data = inv.Items.Select(i => i.SN).ToList().Except(inv.ItemsExt.Select(i => i.SN).ToList());
                            var data = inv.Items.Where(q => !inv.ItemsExt.Any(s => s.SN == q.SN)).ToList();
                            //扩展表不存在时新建
                            if (data.Count > 0)
                            {
                                foreach (var item in data)
                                {
                                    result.Data.ItemsExt.Add(new()
                                    inv.ItemsExt.Add(new()
                                    {
                                        SN = item.SN,
                                        SUPP_ITEM_CODE = barcode.OEMItemCode,
                                        META_SN = barcode.MetaSn,
                                        QR_CODE = barcode.MetaSn
                                    });
@@ -199,12 +207,12 @@
                            if (!query.Parent.IsNullOrEmpty() && doUnPack && query.Parent.SN != query.SN)
                            {
                                result.Data.ParentPkg = null;
                                inv.ParentPkg = null;
                                //保存数据到数据库
                                var db = Biz.Db;
                                var dbTran = db.UseTran(() =>
                                {
                                    var unPackQty = result.Data.Items.Sum(q => q.QTY);
                                    var unPackQty = inv.Items.Sum(q => q.QTY);
                                    db.Updateable<WMS_ITEM_PKG>().SetColumns(q => q.PARENT_SN == null).Where(q => q.ID == query.ID).ExecuteCommand();
                                    db.Updateable<WMS_ITEM_PKG>().SetColumns(q => q.QTY == q.QTY - unPackQty).Where(q => q.ID == query.Parent.ID).ExecuteCommand();
                                    if (!Biz.Db.Queryable<WMS_ITEM_PKG>().Any(q => q.PARENT_SN == query.PARENT_SN && q.SN != query.SN))
@@ -219,17 +227,18 @@
                            }
                            else
                            {
                                result.Data.ParentPkg = query.Parent;
                                inv.ParentPkg = query.Parent;
                            }
                        }
                        else
                        {
                            result.Data.SN = barcode.SN;
                            result.Data.Barcode = barcode;
                            result.Data.ItemInfo = Biz.Db.Queryable<BAS_ITEM>().Where(q => q.ITEM_CODE == barcode.ItemCode).First();
                            inv.SN = barcode.SN;
                            inv.Barcode = barcode;
                            inv.ItemInfo = Biz.Db.Queryable<BAS_ITEM>().Where(q => q.ITEM_CODE == barcode.ItemCode).First();
                            result.LocaleMsg = new($"WMS.WmsItem.Barcode.NotFound", barcode.SN);
                        }
                    }
                    result.Data = inv;
                }
                catch (Exception ex)
                {
@@ -246,11 +255,12 @@
            /// <param name="targetLocation">要上架的储位代码</param>
            /// <param name="isTransfer">是否移库操作</param>
            /// <returns></returns>
            public Result<PutOnInfo> PutOn(Inventory inventory, AuthOption option, string targetLocation, bool isTransfer = false)
            public Result<PutOnInfo> PutOn(IInventory inventory, AuthOption option, string targetLocation, bool isTransfer = false)
            {
                var result = new Result<PutOnInfo>(Result.Flags.Success, new PutOnInfo());
                try
                {
                    var inv = inventory as Inventory;
                    var location = Biz.Db.Queryable<V_WH_UNIT>().Where(q => q.LOCATION_CODE == targetLocation && q.AUTH_ORG == option.CurOrg).IncludesAllFirstLayer().First();
                    if (!location.IsNullOrEmpty())
                    {
@@ -261,7 +271,7 @@
                        foreach (var item in inventory.Items)
                        {
                            item.STATUS = WMS_ITEM.STATUSs.InStore.GetValue();
                            item.SUPP_LOTNO = inventory.Barcode.LotNo;
                            item.SUPP_LOTNO = inv.Barcode.LotNo;
                            item.FIRST_IN_DATE = item.FIRST_IN_DATE <= DateTime.MinValue ? DateTime.Now : item.FIRST_IN_DATE;
                            item.PROD_DATE = item.PROD_DATE <= DateTime.MinValue ? item.FIRST_IN_DATE : item.PROD_DATE;
                            item.WH_ID = location.WH_ID;
@@ -280,8 +290,7 @@
                        foreach (var item in inventory.ItemsExt)
                        {
                            item.AUTH_ORG = option.OrgCode;
                            item.SN = inventory.Barcode.SN;
                            item.SUPP_ITEM_CODE = inventory.Barcode.OEMItemCode;
                            item.SN = inv.Barcode.SN;
                        }
                        result.Data.Items = inventory.Items;
@@ -308,9 +317,11 @@
            /// <param name="inventory">要下架的库存对象</param>
            /// <param name="option">授权查询选项</param>
            /// <param name="status">下架后状态</param>
            /// <param name="clearLocation">是否清理储区货架储位信息</param>
            /// <returns></returns>
            public Result<TakeDownInfo> TakeDown(Inventory inventory, AuthOption option, WMS_ITEM.STATUSs status, bool clearLocation = true)
            public Result<TakeDownInfo> TakeDown(IInventory inventory, AuthOption option, WMS_ITEM.STATUSs status, bool clearLocation = true)
            {
                return TakeDown(inventory, inventory.Items.ToDictionary(k => k.SN, v => v.QTY), option, status, clearLocation);
                var result = new Result<TakeDownInfo>(Result.Flags.Success, new TakeDownInfo());
                try
                {
@@ -336,6 +347,68 @@
                            item.LOCATION_ID = null;
                        }
                    }
                    result.Data.Items = inventory.Items;
                    result.Data.History = inventory.History;
                    result.Data.Packages = inventory.Packages;
                }
                catch (Exception ex)
                {
                    result.CatchExceptionWithLog(ex, Biz.L("WMS.WmsItem.TakeDown.Exception", inventory.SN, inventory?.Location?.LOCATION_CODE));
                }
                return result;
            }
            /// <summary>
            /// 下架
            /// </summary>
            /// <param name="inventory">要下架的库存对象</param>
            /// <param name="qtyList">要下架的最小包装数量字典,key:sn,value:qty</param>
            /// <param name="option">授权查询选项</param>
            /// <param name="status">下架后状态</param>
            /// <param name="clearLocation">是否清理储区货架储位信息</param>
            /// <returns></returns>
            public Result<TakeDownInfo> TakeDown(IInventory inventory, Dictionary<string, double> qtyList, AuthOption option, WMS_ITEM.STATUSs status, bool clearLocation = true)
            {
                var result = new Result<TakeDownInfo>(Result.Flags.Success, new TakeDownInfo());
                try
                {
                    //如果要下架的数量字典为空则认为是全部下架
                    qtyList = qtyList.IsNullOrEmpty(inventory.Items.ToDictionary(k => k.SN, v => v.QTY));
                    foreach (var item in inventory.Items)
                    {
                        if (qtyList.ContainsKey(item.SN) && qtyList[item.SN] > 0)
                        {
                            var downQty = qtyList[item.SN];
                            if (item.QTY > downQty)
                            {
                                item.QTY -= downQty;
                                var pkg = inventory.Packages.First(q => q.SN == item.SN);
                                pkg.QTY = item.QTY;
                            }
                            else
                            {
                                item.STATUS = status.GetValue();
                                var pkg = inventory.Packages.First(q => q.SN == item.SN);
                                pkg.PARENT_SN = null;
                                pkg.Parent = null;
                                if (clearLocation)
                                {
                                    //item.WH_ID = null;
                                    item.REGION_ID = null;
                                    item.SHELF_ID = null;
                                    item.LOCATION_ID = null;
                                    //pkg.WH_ID = null;
                                    pkg.REGION_ID = null;
                                    pkg.SHELF_ID = null;
                                    pkg.LOCATION_ID = null;
                                }
                            }
                            inventory.History.Add(new WMS_ITEM_HIS(item, $"条码[{inventory.SN}]从储位[{inventory?.Location?.LOCATION_CODE}]下架数量[{downQty}]成功,状态[{item.STATUS.GetEnumDesc<WMS_ITEM.STATUSs>()}],操作单据[{item.TRANS_NO}]"));
                        }
                    }
                    inventory.Packages = WMS_ITEM_PKG.UpdateQty(inventory.Packages);
                    result.Data.Items = inventory.Items;
                    result.Data.History = inventory.History;
                    result.Data.Packages = inventory.Packages;
@@ -446,13 +519,13 @@
            /// <param name="option">授权查询选项</param>
            /// <param name="reqQty">需求数量,会返回满足需求的物料个数</param>
            /// <returns></returns>
            public Result<List<SuggestItem>> Suggest(string order, string itemCode, string erpWH, string whID, string regionID, string shelfID, AuthOption option, decimal reqQty)
            public Result<List<SuggestItem>> Suggest(string order, string itemCode, string erpWH, string whID, string regionID, string shelfID, AuthOption option, double reqQty)
            {
                var result = new Result<List<SuggestItem>>(Result.Flags.Success, new List<SuggestItem>()) { LocaleMsg = new("WMS.WmsItem.Suggest.Success") };
                try
                {
                    var takeCount = 0;
                    var checkSum = (decimal)0;
                    var checkSum = 0.0;
                    var checkCount = 0;
                    do
                    {
@@ -553,7 +626,7 @@
                                                    Location = l,
                                                })
                                                .Take(takeCount).ToList();
                    var curQty = (decimal)0;
                    var curQty = 0.0;
                    foreach (var item in items)
                    {
                        result.Data.Add(item);
@@ -664,7 +737,7 @@
        /// <param name="transLine"></param>
        /// <param name="actQty"></param>
        /// <param name="isFirst"></param>
        public static WMS_ITEM_POOL GetPoolItem(this WMS_ITEM item, string orgCode, string transCode, string transNo, string transLine, decimal actQty, bool isFirst)
        public static WMS_ITEM_POOL GetPoolItem(this WMS_ITEM item, string orgCode, string transCode, string transNo, string transLine, double actQty, bool isFirst)
        {
            var poolItem = new WMS_ITEM_POOL()
            {