chengsc
2024-10-20 f8957ba7f0ade842553bd37254cf31da639a1925
Wms/WMS.BLL/BllPdaServer/PdaSoServer.cs
@@ -18,6 +18,8 @@
using WMS.BLL.LogServer;
using WMS.DAL;
using WMS.Entity.LogEntity;
using Model.ModelDto.SysDto;
using Model.ModelDto.BllSoDto;
namespace WMS.BLL.BllPdaServer
{
@@ -66,6 +68,11 @@
                if (string.IsNullOrWhiteSpace(palletNo))//判断托盘是否为空
                {
                    throw new Exception("托盘码为空,请输入托盘码");
                }
                var palletInfo = Db.Queryable<DataStockDetail>().First(w => w.IsDel == "0" && w.PalletNo == palletNo);
                if (!string.IsNullOrEmpty(palletInfo.WareHouseNo) && type != "1")
                {
                    throw new Exception("该托盘还未出库");
                }
                if (type == "1")//平库出库获取单据
                {
@@ -242,8 +249,20 @@
                        {
                            foreach (var demo in list)
                            {
                                var com = comInfo.FirstOrDefault(m => m.IsDel == "0" && m.BoxNo3 == demo.BoxNo);
                                if (com!=null)
                                //if (!string.IsNullOrWhiteSpace(boxNo3))
                                //{
                                //    var com = comInfo.FirstOrDefault(m => m.IsDel == "0" && m.BoxNo3 == demo.BoxNo);
                                //}
                                //else if (!string.IsNullOrWhiteSpace(boxNo))
                                //{
                                //    if (expr)
                                //    {
                                //    }
                                //}
                                var com = comInfo.FirstOrDefault(m => m.IsDel == "0" && m.BoxNo3 != null && m.BoxNo3 == demo.BoxNo);
                                if (com != null)
                                {
                                    demo.PickedQty = com.CompleteQty;
                                }
@@ -279,21 +298,78 @@
        }
        //获取库内无箱码的托盘分配信息
        public List<OutPdaInfo> GetAllotPlnInfo(string soDetailId, string palletNo)
        public List<BoxInfo> GetAllotPlnInfo(string soDetailId, string palletNo)
        {
            try
            {
                #region 判断
                //根据id及托盘获取出库单和托盘拣货信息
                if (string.IsNullOrWhiteSpace(palletNo))
                {
                    throw new Exception("托盘号不能为空");
                }
                //获取对应托盘下是否存在箱码信息
                var boxInfo = Db.Queryable<DataBoxInfo>().First(b => b.IsDel == "0" && b.PalletNo == palletNo);
                if (boxInfo != null)
                {
                    throw new Exception($"{palletNo}托盘上存在箱码信息,无法在数量拣货进行操作!");
                }
                BllExportAllot allot = null;
                if (!string.IsNullOrWhiteSpace(soDetailId))
                {
                    //出库单明细
                    var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(a => a.Id == int.Parse(soDetailId) && a.IsDel == "0");
                    if (noticeDetail == null)
                    {
                        throw new Exception($"未查询到对应出库单明细信息,请核实!");
                    }
                    //出库单总单
                    var notice = Db.Queryable<BllExportNotice>().First(a => a.IsDel == "0" && a.SONo == noticeDetail.SONo);
                    if (notice == null)
                    {
                        throw new Exception($"未查询到对应出库单总单信息,请核实!");
                    }
                    //分配信息
                    allot = Db.Queryable<BllExportAllot>().First(a => a.IsDel == "0" && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.PalletNo == palletNo && (a.Status == "2" || a.Status == "3"));
                    if (allot == null)
                    {
                        throw new Exception($"未查询到对应分配信息,请核实!");
                    }
                }
                //库存明细
                var detail = Db.Queryable<DataStockDetail>().First(a => a.IsDel == "0" && a.PalletNo == palletNo);
                if (detail == null)
                {
                    throw new Exception($"未查询到库存明细信息,请核实!");
                }
                #endregion
                List<BoxInfo> pdaInfo = new List<BoxInfo>();
                BoxInfo info = new BoxInfo()
                {
                    SkuNo = detail.SkuNo,
                    BoxNo = detail.SkuNo,
                    Qty = allot == null ? (int)(detail.Qty - detail.LockQty) : (int)allot.Qty,
                    PickedQty = allot == null ? 0 : (int)allot.CompleteQty,
                };
                pdaInfo.Add(info);
                return pdaInfo;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            throw new NotImplementedException();
        }
        //出库pda拣货
        public void SoSetPick(string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, int userId)
        public void SoSetPick(string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, string pickQty1, int userId)
        {
            Db.BeginTran();
            try
@@ -312,7 +388,11 @@
                {
                    throw new Exception("托盘码不能为空");
                }
                if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)
                {
                    throw new Exception("追溯条码和拣货数量不能同时输入");
                }
                //出库单
                var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == soNo);
                if (notice == null)
@@ -354,6 +434,7 @@
                    throw new Exception("未查询到该托盘分配的库存信息!");
                }
                #endregion
                if (string.IsNullOrWhiteSpace(boxNo))//整托拣货
                {
                    List<DataBoxInfo> boxInfos;
@@ -368,12 +449,12 @@
                    {
                        throw new Exception("拣货数量不能大于箱内剩余待拣数量");
                    }
                    var pickQty = 0;//拣货的数量
                    decimal pickQty = 0;//拣货的数量
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList();
                    var comList = new List<BllCompleteDetail>();
                    foreach (var item in boxInfos)
                    {
                        if (comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                        if (comDetailList.Any(m => m.BoxNo3 == item.BoxNo3) && item.BoxNo3 != null)
                        {
                            throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                        }
@@ -413,7 +494,8 @@
                    Db.Insertable(comList).ExecuteCommand();
                    //修改出库分配信息
                    allot.CompleteQty += pickQty;
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.UpdateTime = DateTime.Now;
                    Db.Updateable(allot).ExecuteCommand();
                    //删除库存明细
                    Db.Deleteable(stockDetail).ExecuteCommand();
@@ -438,6 +520,7 @@
                    Db.Updateable(pallet).ExecuteCommand();
                    //修改出库单明细拣货数量
                    noticeDetail.CompleteQty += pickQty;
                    noticeDetail.Status = "2";
                    Db.Updateable(noticeDetail).ExecuteCommand();
                    var num = Db.Queryable<BllExportNoticeDetail>()
@@ -445,20 +528,25 @@
                    if (num <= 0)
                    {
                        notice.Status = "4"; //更改为执行完成
                        noticeDetail.Status = "3";
                        Db.Updateable(noticeDetail).ExecuteCommand();
                    }
                    //修改出库单信息
                    Db.Updateable(notice).ExecuteCommand();
                }
                else
                {
                    var biaoShi = "0";//0:整箱拣货、1:散支拣货
                    var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货
                    List<DataBoxInfo> boxInfos;
                    var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo);
                    var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo && m.StockDetailId == stockDetail.Id);
                    if (boxInfo.Count() == 0)
                    {
                        throw new Exception("未查询到该箱码及追溯码的信息");
                    }
                    boxInfos = boxInfo.ToList();
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList();
                    if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货
                    {
                        boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList();
@@ -482,7 +570,33 @@
                            throw new Exception("拣货数量不能大于剩余待拣数量");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                            {
                                throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                            }
                        }
                        biaoShi = "1";
                    }
                    else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货
                    {
                        if (boxInfo.Count() > 1)
                        {
                            throw new Exception("该箱码内存在支码不能进行数量拣货");
                        }
                        decimal boxQty = boxInfo.First().Qty;
                        if (Convert.ToDecimal(pickQty1) > boxQty)
                        {
                            throw new Exception("拣货数量不能大于箱内数量");
                        }
                        if (Convert.ToDecimal(pickQty1) > needQty)
                        {
                            throw new Exception("拣货数量不能大于剩余待拣数量");
                        }
                        biaoShi = "2";
                    }
                    else //整箱拣货
                    {
@@ -499,16 +613,20 @@
                        {
                            throw new Exception("拣货数量不能大于箱内剩余待拣数量");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo))
                            {
                                throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货");
                            }
                        }
                    }
                    var pickQty = 0;//拣货的数量
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList();
                    decimal pickQty = 0;//拣货的数量
                    var comList = new List<BllCompleteDetail>();
                    foreach (var item in boxInfos)
                    {
                        if (comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                        {
                            throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                        }
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
@@ -527,15 +645,36 @@
                            SkuName = allot.SkuName,
                            Standard = allot.Standard,
                            PalletNo = palletNo,
                            CompleteQty = item.Qty,
                            CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty,
                            CreateUser = userId
                        };
                        comList.Add(completeDetail);
                        //删除库存箱码明细
                        Db.Deleteable(item).ExecuteCommand();
                        pickQty += item.Qty;
                        if (biaoShi != "2")
                        {
                            pickQty += item.Qty;
                            //删除库存箱码明细
                            Db.Deleteable(item).ExecuteCommand();
                        }
                        else//数量拣货
                        {
                            if (decimal.Parse(pickQty1) == item.Qty)
                            {
                                pickQty += item.Qty;
                                //删除库存箱码明细
                                Db.Deleteable(item).ExecuteCommand();
                            }
                            else
                            {
                                pickQty += decimal.Parse(pickQty1);
                                item.Qty -= decimal.Parse(pickQty1);
                                item.BitBoxMark = "1";//零箱标识
                                Db.Updateable(item).ExecuteCommand();
                            }
                        }
                    }
                    //改变库内箱码是否零箱信息
                    if (biaoShi == "1")
@@ -552,6 +691,2596 @@
                    //修改出库分配信息
                    allot.CompleteQty += pickQty;
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.UpdateTime = DateTime.Now;
                    if (allot.Status == "5")
                    {
                        //判断该托盘是否还存在物料 存在改为待回库 待回库完成后改为已完成
                    }
                    Db.Updateable(allot).ExecuteCommand();
                    //删除或修改库存明细
                    stockDetail.BitPalletMark = "1";//修改为零托标识
                    stockDetail.Qty -= pickQty;
                    stockDetail.LockQty -= pickQty;
                    if (stockDetail.Qty == stockDetail.LockQty)
                    {
                        stockDetail.Status = "2";
                    }
                    else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0)
                    {
                        stockDetail.Status = "1";
                    }
                    else
                    {
                        stockDetail.Status = "0";
                    }
                    if (stockDetail.Qty <= 0)
                    {
                        Db.Deleteable(stockDetail).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                    stock.Qty -= pickQty;
                    stock.LockQty -= pickQty;
                    if (stock.Qty <= 0)
                    {
                        Db.Deleteable(stock).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stock).ExecuteCommand();
                    }
                    var num2 = Db.Queryable<DataStockDetail>().Count(m => m.IsDel == "0" && m.PalletNo == palletNo);
                    if (num2 <= 0)
                    {
                        //改变托盘状态
                        var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                        if (pallet == null)
                        {
                            throw new Exception("未在托盘表中查询到托盘信息");
                        }
                        pallet.Status = "0";
                        Db.Updateable(pallet).ExecuteCommand();
                    }
                    //修改出库单明细拣货数量
                    noticeDetail.CompleteQty += pickQty;
                    noticeDetail.Status = "2";
                    Db.Updateable(noticeDetail).ExecuteCommand();
                    var num = Db.Queryable<BllExportNoticeDetail>()
                        .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty);
                    if (num <= 0)
                    {
                        notice.Status = "4"; //更改为执行完成
                        noticeDetail.Status = "3";
                        Db.Updateable(noticeDetail).ExecuteCommand();
                    }
                    //修改出库单信息
                    Db.Updateable(notice).ExecuteCommand();
                }
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId);
                Db.CommitTran();
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        //出库pda拣货
        public void SoSetQtyPick(string soNo, string soDetailId, string palletNo, string PickQty, int userId)
        {
            Db.BeginTran();
            try
            {
                #region 判断
                if (string.IsNullOrWhiteSpace(soNo))
                {
                    throw new Exception("出库单据不能为空");
                }
                //if (string.IsNullOrWhiteSpace(soDetailId))
                //{
                //    throw new Exception("出库物料-批次不能为空");
                //}
                if (string.IsNullOrWhiteSpace(palletNo))
                {
                    throw new Exception("托盘码不能为空");
                }
                //出库单
                var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == soNo);
                if (notice == null)
                {
                    throw new Exception("未查询到该出库单的信息");
                }
                if (notice.Status != "3")
                {
                    throw new Exception("出库单的状态不是正在执行,不能拣货");
                }
                //出库单明细
                var noticeDetail = Db.Queryable<BllExportNoticeDetail>()
                    .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId));
                if (noticeDetail == null)
                {
                    throw new Exception("未查询到该出库单明细的信息");
                }
                //出库分配信息
                var allot = Db.Queryable<BllExportAllot>().First(m =>
                    m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo &&
                    m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo);
                if (allot == null)
                {
                    throw new Exception("未查询到该托盘的分配信息");
                }
                //剩余拣货数量(待拣减去已拣)
                var needQty = allot.Qty - allot.CompleteQty;
                if (decimal.Parse(PickQty) > needQty)
                {
                    throw new Exception("拣货数量不能大于托内剩余待拣数量");
                }
                //库存明细
                var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.Id == allot.StockId);
                if (stockDetail == null)
                {
                    throw new Exception("未查询到该托盘分配的库存明细信息!");
                }
                //库存总表
                var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                if (stock == null)
                {
                    throw new Exception("未查询到该托盘分配的库存信息!");
                }
                #endregion
                //获取当前托盘拣货明细
                var complete = Db.Queryable<BllCompleteDetail>().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.ExportAllotId == allot.Id && a.StockId == stockDetail.Id);
                //判读是否存在拣货明细
                int isComplete = 0;
                if (complete != null)
                {
                    isComplete = 1;
                }
                var comList = new List<BllCompleteDetail>();
                //判断是否存在拣货明细
                isComplete = 0;// 所有无箱码或一级箱码拣货时,拣货明细应重新插入数据(体现多次拣货流程记录)
                if (isComplete == 0)
                {
                    //添加拣货明细
                    var completeDetail = new BllCompleteDetail()
                    {
                        SONo = soNo,
                        SODetailNo = int.Parse(soDetailId),
                        ExportAllotId = allot.Id,
                        StockId = allot.StockId,
                        BoxNo = "",
                        BoxNo2 = "",
                        BoxNo3 = "",
                        LotNo = allot.LotNo,
                        LotText = allot.LotText,
                        SupplierLot = allot.SupplierLot,
                        SkuNo = allot.SkuNo,
                        SkuName = allot.SkuName,
                        Standard = allot.Standard,
                        PalletNo = palletNo,
                        CompleteQty = int.Parse(PickQty),
                        CreateUser = userId,
                        CreateTime = Db.GetDate(),
                    };
                    comList.Add(completeDetail);
                    //添加拣货明细
                    Db.Insertable(comList).ExecuteCommand();
                }
                else if (isComplete == 1)
                {
                    complete.CompleteQty += decimal.Parse(PickQty);
                    complete.UpdateUser = userId;
                    complete.UpdateTime = Db.GetDate();
                    Db.Updateable(complete).ExecuteCommand();
                }
                //修改出库分配信息
                allot.CompleteQty += decimal.Parse(PickQty);
                allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                allot.UpdateTime = DateTime.Now;
                Db.Updateable(allot).ExecuteCommand();
                int isDel = 0;
                //删除或修改库存明细
                stockDetail.BitPalletMark = "1";//修改为零托标识
                stockDetail.Qty -= decimal.Parse(PickQty);
                stockDetail.LockQty -= decimal.Parse(PickQty);
                if (stockDetail.Qty == stockDetail.LockQty)
                {
                    stockDetail.Status = "2";
                }
                else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0)
                {
                    stockDetail.Status = "1";
                }
                else
                {
                    stockDetail.Status = "0";
                }
                if (stockDetail.Qty <= 0)
                {
                    Db.Deleteable(stockDetail).ExecuteCommand();
                }
                else
                {
                    isDel = 1;
                    Db.Updateable(stockDetail).ExecuteCommand();
                }
                //删除或修改库存
                stock.Qty -= decimal.Parse(PickQty);
                stock.LockQty -= decimal.Parse(PickQty);
                if (stock.Qty <= 0)
                {
                    Db.Deleteable(stock).ExecuteCommand();
                }
                else
                {
                    Db.Updateable(stock).ExecuteCommand();
                }
                //改变托盘状态为:未使用
                var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                if (pallet == null)
                {
                    throw new Exception("未在托盘表中查询到托盘信息");
                }
                //判断托盘上物料是否拣货完毕
                if (isDel == 0)
                {
                    pallet.Status = "0";
                    Db.Updateable(pallet).ExecuteCommand();
                }
                //修改出库单明细拣货数量
                noticeDetail.CompleteQty += int.Parse(PickQty);
                noticeDetail.Status = "2";
                Db.Updateable(noticeDetail).ExecuteCommand();
                var num = Db.Queryable<BllExportNoticeDetail>()
                    .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty);
                if (num <= 0)
                {
                    notice.Status = "4"; //更改为执行完成
                    noticeDetail.Status = "3";
                    Db.Updateable(noticeDetail).ExecuteCommand();
                }
                //修改出库单信息
                Db.Updateable(notice).ExecuteCommand();
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId);
                Db.CommitTran();
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 下发空托出库
        /// </summary>
        /// <param name="model"> </param>
        /// <param name="userId"> </param>
        /// <param name="url"> </param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public string IssuePlnOutHouse(OutModePalletVm model, int userId, string url)
        {
            try
            {
                string strMsg = "";
                var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位)
                var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位)
                var moveDto = new List<OutCommandDto>(); //要移库数据的集合
                //获取当前时间
                DateTime serverTime = Db.GetDate();
                //获取库存明细是否小于等于该垛数
                string str = "select * from DataStockDetail where IsDel = '0' and SkuNo = '100099' and Status = '0' ";
                var stockDetail = Db.Ado.SqlQuery<DataStockDetail>(str);
                if (stockDetail.Count > 0)
                {
                    //判断是否大于需要垛数
                    if (stockDetail.Count < int.Parse(model.Num))
                    {
                        strMsg = "需要垛数大于库存垛数,请重新输入!";
                        return strMsg;
                    }
                }
                //获取库存总表信息
                var stock = Db.Queryable<DataStock>().First(s => s.IsDel == "0" && s.SkuNo == "100099");
                //验证库存总表是否为空
                if (stock == null)
                {
                    strMsg = "库存信息不存在,请核查!";
                    return strMsg;
                }
                var com = new Common();
                Db.BeginTran();
                //遍历库存信息
                foreach (var s in stockDetail)
                {
                    //if (outDto1.Contains(m=>m.PalletNo == s.PalletNo) >0)
                    //{
                    //    continue;
                    //}
                    //获取储位信息
                    var locat = Db.Queryable<SysStorageLocat>().First(l => l.LocatNo == s.LocatNo && l.IsDel == "0" && l.WareHouseNo == "W01");
                    if(locat == null)
                    {
                        continue;
                    }
                    ////更改储位状态为出库中
                    //locat.Status = "3"; //3 出库中
                    //locat.UpdateTime = serverTime; //修改时间
                    //locat.UpdateUser = userId; //修改人
                    ////修改储位信息
                    //Db.Updateable(locat).ExecuteCommand();
                    if (locat.Status == "1")
                    {
                        if (locat.Depth == "01") //深度为1
                        {
                            #region 改变库存
                            //增加库存锁定数量
                            stock.LockQty += (int)s.Qty; //锁定数量
                            stock.UpdateTime = serverTime; //修改时间
                            stock.UpdateUser = userId; //修改人
                            Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                            //增加库存明细锁定数量
                            s.LockQty += (int)s.Qty; //锁定数量
                            s.UpdateTime = serverTime; //修改时间
                            s.UpdateUser = userId; //修改人
                            s.Status = "2"; //2 已分配
                            Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                            #endregion
                            #region 分配
                            //添加分配表信息
                            var allot = new BllExportAllot
                            {
                                SONo = "",
                                WaveNo = "",
                                SODetailNo = 0,
                                StockId = s.Id,
                                LotNo = "",
                                LotText = "",
                                SupplierLot = "",
                                SkuNo = s.SkuNo,
                                SkuName = s.SkuName,
                                Standard = s.Standard,
                                PalletNo = s.PalletNo,
                                IsBale = "0", //是否裹包
                                IsBelt = "0", //是否打带
                                //BoxexQty = s.Qty,
                                Qty = (int)s.Qty,
                                CompleteQty = 0,
                                Status = "1",
                                LogisticsId = 0,
                                IsAdvance = "0",
                                OutMode = model.OutMode,//出库口
                                CreateUser = userId,
                                CreateTime = DateTime.Now
                            };
                            Db.Insertable(allot).ExecuteCommand();
                            #endregion
                            #region 添加出库任务信息
                            var taskNo = new Common().GetMaxNo("TK");
                            var exTask = new LogTask    //出库任务
                            {
                                TaskNo = taskNo,
                                Sender = "WMS",
                                Receiver = "PDA",
                                IsSuccess = 1, //是否下发成功 0失败 1成功
                                StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                EndLocat = model.OutMode,//目标位置
                                PalletNo = s.PalletNo,//托盘码
                                IsSend = 1,//是否可再次下发
                                IsCancel = 1,//是否可取消
                                IsFinish = 1,//是否可完成
                                Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                CreateTime = serverTime, //创建时间
                                CreateUser = userId, //创建人
                                Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                 //FinishDate = serverTime, //完成时间
                            };
                            outDto1.Add(new OutCommandDto()
                            {
                                PalletNo = exTask.PalletNo,//托盘号
                                StartLocate = exTask.StartLocat, // 起始位置
                                StartRoadway = locat.RoadwayNo, //所属巷道
                                EndLocate = model.OutMode, // 目标位置
                                TaskNo = exTask.TaskNo, // 任务号
                                TaskType = "1",// 任务类型 (出库)
                                OutMode = model.OutMode,  //目标地址
                                Order = 1
                            });
                            Db.Insertable(exTask).ExecuteCommand();
                            #endregion
                            #region 储位状态变更
                            //更改储位状态为出库中
                            locat.Status = "3"; //3 出库中
                            Db.Updateable(locat).ExecuteCommand();//修改储位信息
                            #endregion
                        }
                        else if (locat.Depth == "02") //深度为2
                        {
                            //获取出库深度为2储位前面的储位信息
                            var sql2 = $@"select * from SysStorageLocat where  WareHouseNo = '{locat.WareHouseNo}' and row = {locat.Row} and [Column] = {locat.Column} and Layer = {locat.Layer} and Depth = '01'; ";
                            var slotBefore = Db.Ado.SqlQuery<SysStorageLocat>(sql2).First();
                            if (slotBefore == null)
                            {
                                #region 改变库存
                                //增加库存锁定数量
                                stock.LockQty += (int)s.Qty; //锁定数量
                                stock.UpdateTime = serverTime; //修改时间
                                stock.UpdateUser = userId; //修改人
                                Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                //增加库存明细锁定数量
                                s.LockQty += (int)s.Qty; //锁定数量
                                s.UpdateTime = serverTime; //修改时间
                                s.UpdateUser = userId; //修改人
                                s.Status = "2"; //2 已分配
                                Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                #endregion
                                #region 分配
                                //添加分配表信息
                                var allot = new BllExportAllot
                                {
                                    SONo = "",
                                    WaveNo = "",
                                    SODetailNo = 0,
                                    StockId = s.Id,
                                    LotNo = "",
                                    LotText = "",
                                    SupplierLot = "",
                                    SkuNo = s.SkuNo,
                                    SkuName = s.SkuName,
                                    Standard = s.Standard,
                                    PalletNo = s.PalletNo,
                                    IsBale = "0", //是否裹包
                                    IsBelt = "0", //是否打带
                                    //BoxexQty = s.Qty,
                                    Qty = (int)s.Qty,
                                    CompleteQty = 0,
                                    Status = "1",
                                    LogisticsId = 0,
                                    IsAdvance = "0",
                                    OutMode = model.OutMode,//出库口
                                    CreateUser = userId,
                                    CreateTime = DateTime.Now
                                };
                                Db.Insertable(allot).ExecuteCommand();
                                #endregion
                                #region 添加出库任务信息
                                var taskNo = new Common().GetMaxNo("TK");
                                var exTask = new LogTask    //出库任务
                                {
                                    TaskNo = taskNo,
                                    Sender = "WMS",
                                    Receiver = "PDA",
                                    IsSuccess = 1, //是否下发成功 0失败 1成功
                                    StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                    EndLocat = model.OutMode,//目标位置
                                    PalletNo = s.PalletNo,//托盘码
                                    IsSend = 1,//是否可再次下发
                                    IsCancel = 1,//是否可取消
                                    IsFinish = 1,//是否可完成
                                    Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                    Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                    OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                    CreateTime = serverTime, //创建时间
                                    CreateUser = userId, //创建人
                                    Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                     //FinishDate = serverTime, //完成时间
                                };
                                outDto1.Add(new OutCommandDto()
                                {
                                    PalletNo = exTask.PalletNo,//托盘号
                                    StartLocate = exTask.StartLocat, // 起始位置
                                    StartRoadway = locat.RoadwayNo, //所属巷道
                                    EndLocate = model.OutMode, // 目标位置
                                    TaskNo = exTask.TaskNo, // 任务号
                                    TaskType = "1",// 任务类型 (出库)
                                    OutMode = model.OutMode,  //目标地址
                                    Order = 1
                                });
                                Db.Insertable(exTask).ExecuteCommand();
                                #endregion
                                #region 储位状态变更
                                //更改储位状态为出库中
                                locat.Status = "3"; //3 出库中
                                Db.Updateable(locat).ExecuteCommand();//修改储位信息
                                #endregion
                            }
                            else
                            {
                                //判断储位状态
                                if (slotBefore.Status == "0")
                                {
                                    #region 改变库存
                                    //增加库存锁定数量
                                    stock.LockQty += (int)s.Qty; //锁定数量
                                    stock.UpdateTime = serverTime; //修改时间
                                    stock.UpdateUser = userId; //修改人
                                    Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                    //增加库存明细锁定数量
                                    s.LockQty += (int)s.Qty; //锁定数量
                                    s.UpdateTime = serverTime; //修改时间
                                    s.UpdateUser = userId; //修改人
                                    s.Status = "2"; //2 已分配
                                    Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                    #endregion
                                    #region 分配
                                    //添加分配表信息
                                    var allot = new BllExportAllot
                                    {
                                        SONo = "",
                                        WaveNo = "",
                                        SODetailNo = 0,
                                        StockId = s.Id,
                                        LotNo = "",
                                        LotText = "",
                                        SupplierLot = "",
                                        SkuNo = s.SkuNo,
                                        SkuName = s.SkuName,
                                        Standard = s.Standard,
                                        PalletNo = s.PalletNo,
                                        IsBale = "0", //是否裹包
                                        IsBelt = "0", //是否打带
                                        //BoxexQty = s.Qty,
                                        Qty = (int)s.Qty,
                                        CompleteQty = 0,
                                        Status = "1",
                                        LogisticsId = 0,
                                        IsAdvance = "0",
                                        OutMode = model.OutMode,//出库口
                                        CreateUser = userId,
                                        CreateTime = DateTime.Now
                                    };
                                    Db.Insertable(allot).ExecuteCommand();
                                    #endregion
                                    #region 添加出库任务信息
                                    var taskNo = new Common().GetMaxNo("TK");
                                    var exTask = new LogTask    //出库任务
                                    {
                                        TaskNo = taskNo,
                                        Sender = "WMS",
                                        Receiver = "PDA",
                                        IsSuccess = 1, //是否下发成功 0失败 1成功
                                        StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                        EndLocat = model.OutMode,//目标位置
                                        PalletNo = s.PalletNo,//托盘码
                                        IsSend = 1,//是否可再次下发
                                        IsCancel = 1,//是否可取消
                                        IsFinish = 1,//是否可完成
                                        Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                        Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                        OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                        CreateTime = serverTime, //创建时间
                                        CreateUser = userId, //创建人
                                        Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                         //FinishDate = serverTime, //完成时间
                                    };
                                    outDto1.Add(new OutCommandDto()
                                    {
                                        PalletNo = exTask.PalletNo,//托盘号
                                        StartLocate = exTask.StartLocat, // 起始位置
                                        StartRoadway = locat.RoadwayNo, //所属巷道
                                        EndLocate = model.OutMode, // 目标位置
                                        TaskNo = exTask.TaskNo, // 任务号
                                        TaskType = "1",// 任务类型 (出库)
                                        OutMode = model.OutMode,  //目标地址
                                        Order = 1
                                    });
                                    Db.Insertable(exTask).ExecuteCommand();
                                    #endregion
                                    #region 储位状态变更
                                    //更改储位状态为出库中
                                    locat.Status = "3"; //3 出库中
                                    Db.Updateable(locat).ExecuteCommand();//修改储位信息
                                    #endregion
                                }
                                else if(slotBefore.Status == "1")
                                {
                                    //判断托盘上物料
                                    var pallSku = Db.Queryable<DataStockDetail>().First(m=>m.SkuNo == "100099" && m.LocatNo == slotBefore.LocatNo);
                                    if (pallSku == null) //移库
                                    {
                                        #region 分配
                                        ////添加分配表信息
                                        //var allot = new BllExportAllot
                                        //{
                                        //    SONo = "",
                                        //    WaveNo = "",
                                        //    SODetailNo = 0,
                                        //    StockId = s.Id,
                                        //    LotNo = "",
                                        //    LotText = "",
                                        //    SupplierLot = "",
                                        //    SkuNo = s.SkuNo,
                                        //    SkuName = s.SkuName,
                                        //    Standard = s.Standard,
                                        //    PalletNo = s.PalletNo,
                                        //    IsBale = "0", //是否裹包
                                        //    IsBelt = "0", //是否打带
                                        //    //BoxexQty = s.Qty,
                                        //    Qty = (int)s.Qty,
                                        //    CompleteQty = 0,
                                        //    Status = "1",
                                        //    LogisticsId = 0,
                                        //    IsAdvance = "0",
                                        //    OutMode = model.OutMode,//出库口
                                        //    CreateUser = userId,
                                        //    CreateTime = DateTime.Now
                                        //};
                                        //Db.Insertable(allot).ExecuteCommand();
                                        #endregion
                                        #region 添加移库任务信息
                                        var stkModel = Db.Queryable<DataStockDetail>().First(m => m.LocatNo == slotBefore.LocatNo);
                                        string PalletNo = "LN000000";   // 默认演示托盘
                                        string SkuNo = "";
                                        if (stkModel != null)
                                        {
                                            PalletNo = stkModel.PalletNo;
                                            SkuNo = stkModel.SkuNo;
                                        }
                                        //获取移库的库位
                                        var newSlot = MoveAddress(slotBefore.LocatNo, slotBefore.RoadwayNo, SkuNo, slotBefore.AreaNo);
                                        if (string.IsNullOrWhiteSpace(newSlot))
                                        {
                                            continue;
                                        }
                                        var taskNo = new Common().GetMaxNo("TK");
                                        var exTask = new LogTask    //出库任务
                                        {
                                            TaskNo = taskNo,
                                            Sender = "WMS",
                                            Receiver = "PDA",
                                            IsSuccess = 1, //是否下发成功 0失败 1成功
                                            StartLocat = slotBefore.LocatNo,//起始位置
                                            EndLocat = newSlot,//目标位置
                                            PalletNo = PalletNo,//托盘码
                                            IsSend = 1,//是否可再次下发
                                            IsCancel = 1,//是否可取消
                                            IsFinish = 1,//是否可完成
                                            Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                            Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                            OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                            CreateTime = serverTime, //创建时间
                                            CreateUser = userId, //创建人
                                            Msg = "Pda空托从" + locat == null ? "" : slotBefore.LocatNo + "到" + newSlot + "的移库任务", //关键信息
                                                                                                                             //FinishDate = serverTime, //完成时间
                                        };
                                        moveDto.Add(new OutCommandDto()
                                        {
                                            PalletNo = exTask.PalletNo,//托盘号
                                            StartLocate = exTask.StartLocat, // 起始位置
                                            StartRoadway = locat.RoadwayNo, //所属巷道
                                            EndLocate = exTask.EndLocat, // 目标位置
                                            TaskNo = exTask.TaskNo, // 任务号
                                            TaskType = "2",// 任务类型 (移库)
                                            OutMode = "",  //目标地址
                                            Order = 1
                                        });
                                        Db.Insertable(exTask).ExecuteCommand();
                                        #endregion
                                        #region 储位状态变更
                                        //更改储位状态为移出中
                                        slotBefore.Status = "5"; //5 移出中
                                        Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息
                                        var newSlot2 = Db.Queryable<SysStorageLocat>().First(m => m.LocatNo == newSlot && m.IsDel == "0");
                                        if (newSlot2!= null)
                                        {
                                            newSlot2.Status = "4";//移入中
                                            Db.Updateable(newSlot2).ExecuteCommand();//修改储位信息
                                        }
                                        #endregion
                                    }
                                    else  //出库
                                    {
                                        #region 改变库存
                                        //增加库存锁定数量
                                        stock.LockQty += (int)pallSku.Qty; //锁定数量
                                        stock.UpdateTime = serverTime; //修改时间
                                        stock.UpdateUser = userId; //修改人
                                        Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                        //增加库存明细锁定数量
                                        pallSku.LockQty += (int)pallSku.Qty; //锁定数量
                                        pallSku.UpdateTime = serverTime; //修改时间
                                        pallSku.UpdateUser = userId; //修改人
                                        pallSku.Status = "2"; //2 已分配
                                        Db.Updateable(pallSku).ExecuteCommand();//修改库存明细信息
                                        #endregion
                                        #region 分配
                                        //添加分配表信息
                                        var allot = new BllExportAllot
                                        {
                                            SONo = "",
                                            WaveNo = "",
                                            SODetailNo = 0,
                                            StockId = pallSku.Id,
                                            LotNo = "",
                                            LotText = "",
                                            SupplierLot = "",
                                            SkuNo = pallSku.SkuNo,
                                            SkuName = pallSku.SkuName,
                                            Standard = pallSku.Standard,
                                            PalletNo = pallSku.PalletNo,
                                            IsBale = "0", //是否裹包
                                            IsBelt = "0", //是否打带
                                            //BoxexQty = s.Qty,
                                            Qty = (int)pallSku.Qty,
                                            CompleteQty = 0,
                                            Status = "1",
                                            LogisticsId = 0,
                                            IsAdvance = "0",
                                            OutMode = model.OutMode,//出库口
                                            CreateUser = userId,
                                            CreateTime = DateTime.Now
                                        };
                                        Db.Insertable(allot).ExecuteCommand();
                                        #endregion
                                        #region 添加出库任务信息
                                        var taskNo = new Common().GetMaxNo("TK");
                                        var exTask = new LogTask    //出库任务
                                        {
                                            TaskNo = taskNo,
                                            Sender = "WMS",
                                            Receiver = "PDA",
                                            IsSuccess = 1, //是否下发成功 0失败 1成功
                                            StartLocat = locat == null ? "" : pallSku.LocatNo,//起始位置
                                            EndLocat = model.OutMode,//目标位置
                                            PalletNo = pallSku.PalletNo,//托盘码
                                            IsSend = 1,//是否可再次下发
                                            IsCancel = 1,//是否可取消
                                            IsFinish = 1,//是否可完成
                                            Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                            Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                            OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                            CreateTime = serverTime, //创建时间
                                            CreateUser = userId, //创建人
                                            Msg = "Pda空托从" + locat == null ? "" : pallSku.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                             //FinishDate = serverTime, //完成时间
                                        };
                                        outDto2.Add(new OutCommandDto()
                                        {
                                            PalletNo = exTask.PalletNo,//托盘号
                                            StartLocate = exTask.StartLocat, // 起始位置
                                            StartRoadway = locat.RoadwayNo, //所属巷道
                                            EndLocate = model.OutMode, // 目标位置
                                            TaskNo = exTask.TaskNo, // 任务号
                                            TaskType = "1",// 任务类型 (出库)
                                            OutMode = model.OutMode,  //目标地址
                                            Order = 1
                                        });
                                        Db.Insertable(exTask).ExecuteCommand();
                                        #endregion
                                        #region 储位状态变更
                                        //更改储位状态为出库中
                                        slotBefore.Status = "3"; //3 出库中
                                        Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息
                                        #endregion
                                    }
                                    if (int.Parse(model.Num) == outDto1.Count + outDto2.Count)
                                    {
                                        break;//需求垛数已达到 可以出库了
                                    }
                                    else
                                    {
                                        #region 改变库存
                                        //增加库存锁定数量
                                        stock.LockQty += (int)s.Qty; //锁定数量
                                        stock.UpdateTime = serverTime; //修改时间
                                        stock.UpdateUser = userId; //修改人
                                        Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                        //增加库存明细锁定数量
                                        s.LockQty += (int)s.Qty; //锁定数量
                                        s.UpdateTime = serverTime; //修改时间
                                        s.UpdateUser = userId; //修改人
                                        s.Status = "2"; //2 已分配
                                        Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                        #endregion
                                        #region 分配
                                        //添加分配表信息
                                        var allot = new BllExportAllot
                                        {
                                            SONo = "",
                                            WaveNo = "",
                                            SODetailNo = 0,
                                            StockId = s.Id,
                                            LotNo = "",
                                            LotText = "",
                                            SupplierLot = "",
                                            SkuNo = s.SkuNo,
                                            SkuName = s.SkuName,
                                            Standard = s.Standard,
                                            PalletNo = s.PalletNo,
                                            IsBale = "0", //是否裹包
                                            IsBelt = "0", //是否打带
                                            //BoxexQty = s.Qty,
                                            Qty = (int)s.Qty,
                                            CompleteQty = 0,
                                            Status = "1",
                                            LogisticsId = 0,
                                            IsAdvance = "0",
                                            OutMode = model.OutMode,//出库口
                                            CreateUser = userId,
                                            CreateTime = DateTime.Now
                                        };
                                        Db.Insertable(allot).ExecuteCommand();
                                        #endregion
                                        #region 添加出库任务信息
                                        var taskNo = new Common().GetMaxNo("TK");
                                        var exTask = new LogTask    //出库任务
                                        {
                                            TaskNo = taskNo,
                                            Sender = "WMS",
                                            Receiver = "PDA",
                                            IsSuccess = 1, //是否下发成功 0失败 1成功
                                            StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                            EndLocat = model.OutMode,//目标位置
                                            PalletNo = s.PalletNo,//托盘码
                                            IsSend = 1,//是否可再次下发
                                            IsCancel = 1,//是否可取消
                                            IsFinish = 1,//是否可完成
                                            Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                            Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                            OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                            CreateTime = serverTime, //创建时间
                                            CreateUser = userId, //创建人
                                            Msg = "Pda空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                             //FinishDate = serverTime, //完成时间
                                        };
                                        outDto2.Add(new OutCommandDto()
                                        {
                                            PalletNo = exTask.PalletNo,//托盘号
                                            StartLocate = exTask.StartLocat, // 起始位置
                                            StartRoadway = locat.RoadwayNo, //所属巷道
                                            EndLocate = model.OutMode, // 目标位置
                                            TaskNo = exTask.TaskNo, // 任务号
                                            TaskType = "1",// 任务类型 (出库)
                                            OutMode = model.OutMode,  //目标地址
                                            Order = 1
                                        });
                                        Db.Insertable(exTask).ExecuteCommand();
                                        #endregion
                                        #region 储位状态变更
                                        //更改储位状态为出库中
                                        locat.Status = "3"; //3 出库中
                                        Db.Updateable(locat).ExecuteCommand();//修改储位信息
                                        #endregion
                                    }
                                }
                            }
                        }
                    }
                    if (int.Parse(model.Num) == outDto1.Count+ outDto2.Count)
                    {
                        break;//需求垛数已达到 可以出库了
                    }
                }
                outDto1.AddRange(moveDto);
                outDto1.AddRange(outDto2);
                if (outDto1.Count > 0)
                {
                    // 正式运行程序放开
                    var list2 = outDto1.Select(m => m.TaskNo).ToList();
                    var jsonData = JsonConvert.SerializeObject(outDto1);
                    string response = "";
                    try
                    {
                        var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                        response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
                        var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                        ////解析返回数据
                        var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
                        if (wcsModel.StatusCode == 0)
                        {
                            //更改任务的发送返回时间//
                            new TaskServer().EditTaskIssueOk(list2, time1, time2);
                            str += "下发成功";
                        }
                        if (wcsModel.StatusCode == -1)
                        {
                            new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
                            throw new Exception(wcsModel.Msg);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message);
                    }
                }
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "空托出库", int.Parse(model.Num) + "", "下发", $"用PDA下发了 {int.Parse(model.Num)} 个空托垛", userId);
                Db.CommitTran();
                return "";
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// WCS申请空托出库
        /// </summary>
        /// <param name="model"> </param>
        /// <param name="userId"> </param>
        /// <param name="url"> </param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public List<OutCommandDto> IssuePlnOutHouseWcs(OutModePalletVm model, int userId)
        {
            try
            {
                string strMsg = "";
                var outDto1 = new List<OutCommandDto>(); //先出库数据的集合(深度为1的储位)
                var outDto2 = new List<OutCommandDto>(); //后出库数据的集合(深度为2的储位)
                var moveDto = new List<OutCommandDto>(); //要移库数据的集合
                //获取当前时间
                DateTime serverTime = Db.GetDate();
                //获取库存明细是否小于等于该垛数
                string str = "select * from DataStockDetail where IsDel = '0' and SkuNo = '100099' and Status = '0' ";
                var stockDetail = Db.Ado.SqlQuery<DataStockDetail>(str);
                if (stockDetail.Count > 0)
                {
                    //判断是否大于需要垛数
                    if (stockDetail.Count < int.Parse(model.Num))
                    {
                        throw new Exception("需要垛数大于库存垛数,请重新输入!");
                    }
                }
                //获取库存总表信息
                var stock = Db.Queryable<DataStock>().First(s => s.IsDel == "0" && s.SkuNo == "100099");
                //验证库存总表是否为空
                if (stock == null)
                {
                    throw new Exception("库存信息不存在,请核查!");
                }
                var com = new Common();
                Db.BeginTran();
                //遍历库存信息
                foreach (var s in stockDetail)
                {
                    //if (outDto1.Contains(m=>m.PalletNo == s.PalletNo) >0)
                    //{
                    //    continue;
                    //}
                    //获取储位信息
                    var locat = Db.Queryable<SysStorageLocat>().First(l => l.LocatNo == s.LocatNo && l.IsDel == "0" && l.WareHouseNo == "W01");
                    if (locat == null)
                    {
                        continue;
                    }
                    ////更改储位状态为出库中
                    //locat.Status = "3"; //   1 有物品
                    //locat.UpdateTime = serverTime; //修改时间
                    //locat.UpdateUser = userId; //修改人
                    ////修改储位信息
                    //Db.Updateable(locat).ExecuteCommand();
                    if (locat.Status == "1")
                    {
                        if (locat.Depth == "01") //深度为1
                        {
                            #region 改变库存
                            //增加库存锁定数量
                            stock.LockQty += (int)s.Qty; //锁定数量
                            stock.UpdateTime = serverTime; //修改时间
                            stock.UpdateUser = 0; //修改人
                            Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                            //增加库存明细锁定数量
                            s.LockQty += (int)s.Qty; //锁定数量
                            s.UpdateTime = serverTime; //修改时间
                            s.UpdateUser = userId; //修改人
                            s.Status = "2"; //2 已分配
                            Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                            #endregion
                            #region 分配
                            //添加分配表信息
                            var allot = new BllExportAllot
                            {
                                SONo = "",
                                WaveNo = "",
                                SODetailNo = 0,
                                StockId = s.Id,
                                LotNo = "",
                                LotText = "",
                                SupplierLot = "",
                                SkuNo = s.SkuNo,
                                SkuName = s.SkuName,
                                Standard = s.Standard,
                                PalletNo = s.PalletNo,
                                IsBale = "0", //是否裹包
                                IsBelt = "0", //是否打带
                                //BoxexQty = s.Qty,
                                Qty = (int)s.Qty,
                                CompleteQty = 0,
                                Status = "1",
                                LogisticsId = 0,
                                IsAdvance = "0",
                                OutMode = model.OutMode,//出库口
                                CreateUser = userId,
                                CreateTime = DateTime.Now
                            };
                            Db.Insertable(allot).ExecuteCommand();
                            #endregion
                            #region 添加出库任务信息
                            var taskNo = new Common().GetMaxNo("TK");
                            var exTask = new LogTask    //出库任务
                            {
                                TaskNo = taskNo,
                                Sender = "WMS",
                                Receiver = "WCS",
                                IsSuccess = 1, //是否下发成功 0失败 1成功
                                StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                EndLocat = model.OutMode,//目标位置
                                PalletNo = s.PalletNo,//托盘码
                                IsSend = 1,//是否可再次下发
                                IsCancel = 1,//是否可取消
                                IsFinish = 1,//是否可完成
                                Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                CreateTime = serverTime, //创建时间
                                CreateUser = userId, //创建人
                                Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                 //FinishDate = serverTime, //完成时间
                            };
                            outDto1.Add(new OutCommandDto()
                            {
                                PalletNo = exTask.PalletNo,//托盘号
                                StartLocate = exTask.StartLocat, // 起始位置
                                StartRoadway = locat.RoadwayNo, //所属巷道
                                EndLocate = model.OutMode, // 目标位置
                                TaskNo = exTask.TaskNo, // 任务号
                                TaskType = "1",// 任务类型 (出库)
                                OutMode = model.OutMode,  //目标地址
                                Order = 1
                            });
                            Db.Insertable(exTask).ExecuteCommand();
                            #endregion
                            #region 储位状态变更
                            //更改储位状态为出库中
                            locat.Status = "3"; //3 出库中
                            Db.Updateable(locat).ExecuteCommand();//修改储位信息
                            #endregion
                        }
                        else if (locat.Depth == "02") //深度为2
                        {
                            //获取出库深度为2储位前面的储位信息
                            var sql2 = $@"select * from SysStorageLocat where  WareHouseNo = '{locat.WareHouseNo}' and row = {locat.Row} and [Column] = {locat.Column} and Layer = {locat.Layer} and Depth = '01'; ";
                            var slotBefore = Db.Ado.SqlQuery<SysStorageLocat>(sql2).First();
                            if (slotBefore == null)
                            {
                                #region 改变库存
                                //增加库存锁定数量
                                stock.LockQty += (int)s.Qty; //锁定数量
                                stock.UpdateTime = serverTime; //修改时间
                                //stock.UpdateUser = userId; //修改人
                                Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                //增加库存明细锁定数量
                                s.LockQty += (int)s.Qty; //锁定数量
                                s.UpdateTime = serverTime; //修改时间
                                s.UpdateUser = userId; //修改人
                                s.Status = "2"; //2 已分配
                                Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                #endregion
                                #region 分配
                                //添加分配表信息
                                var allot = new BllExportAllot
                                {
                                    SONo = "",
                                    WaveNo = "",
                                    SODetailNo = 0,
                                    StockId = s.Id,
                                    LotNo = "",
                                    LotText = "",
                                    SupplierLot = "",
                                    SkuNo = s.SkuNo,
                                    SkuName = s.SkuName,
                                    Standard = s.Standard,
                                    PalletNo = s.PalletNo,
                                    IsBale = "0", //是否裹包
                                    IsBelt = "0", //是否打带
                                    //BoxexQty = s.Qty,
                                    Qty = (int)s.Qty,
                                    CompleteQty = 0,
                                    Status = "1",
                                    LogisticsId = 0,
                                    IsAdvance = "0",
                                    OutMode = model.OutMode,//出库口
                                    CreateUser = userId,
                                    CreateTime = DateTime.Now
                                };
                                Db.Insertable(allot).ExecuteCommand();
                                #endregion
                                #region 添加出库任务信息
                                var taskNo = new Common().GetMaxNo("TK");
                                var exTask = new LogTask    //出库任务
                                {
                                    TaskNo = taskNo,
                                    Sender = "WMS",
                                    Receiver = "WCS",
                                    IsSuccess = 1, //是否下发成功 0失败 1成功
                                    StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                    EndLocat = model.OutMode,//目标位置
                                    PalletNo = s.PalletNo,//托盘码
                                    IsSend = 1,//是否可再次下发
                                    IsCancel = 1,//是否可取消
                                    IsFinish = 1,//是否可完成
                                    Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                    Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                    OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                    CreateTime = serverTime, //创建时间
                                    CreateUser = userId, //创建人
                                    Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                     //FinishDate = serverTime, //完成时间
                                };
                                outDto1.Add(new OutCommandDto()
                                {
                                    PalletNo = exTask.PalletNo,//托盘号
                                    StartLocate = exTask.StartLocat, // 起始位置
                                    StartRoadway = locat.RoadwayNo, //所属巷道
                                    EndLocate = model.OutMode, // 目标位置
                                    TaskNo = exTask.TaskNo, // 任务号
                                    TaskType = "1",// 任务类型 (出库)
                                    OutMode = model.OutMode,  //目标地址
                                    Order = 1
                                });
                                Db.Insertable(exTask).ExecuteCommand();
                                #endregion
                                #region 储位状态变更
                                //更改储位状态为出库中
                                locat.Status = "3"; //3 出库中
                                Db.Updateable(locat).ExecuteCommand();//修改储位信息
                                #endregion
                            }
                            else
                            {
                                //判断储位状态
                                if (slotBefore.Status == "0")
                                {
                                    #region 改变库存
                                    //增加库存锁定数量
                                    stock.LockQty += (int)s.Qty; //锁定数量
                                    stock.UpdateTime = serverTime; //修改时间
                                    //stock.UpdateUser = userId; //修改人
                                    Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                    //增加库存明细锁定数量
                                    s.LockQty += (int)s.Qty; //锁定数量
                                    s.UpdateTime = serverTime; //修改时间
                                    s.UpdateUser = userId; //修改人
                                    s.Status = "2"; //2 已分配
                                    Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                    #endregion
                                    #region 分配
                                    //添加分配表信息
                                    var allot = new BllExportAllot
                                    {
                                        SONo = "",
                                        WaveNo = "",
                                        SODetailNo = 0,
                                        StockId = s.Id,
                                        LotNo = "",
                                        LotText = "",
                                        SupplierLot = "",
                                        SkuNo = s.SkuNo,
                                        SkuName = s.SkuName,
                                        Standard = s.Standard,
                                        PalletNo = s.PalletNo,
                                        IsBale = "0", //是否裹包
                                        IsBelt = "0", //是否打带
                                        //BoxexQty = s.Qty,
                                        Qty = (int)s.Qty,
                                        CompleteQty = 0,
                                        Status = "1",
                                        LogisticsId = 0,
                                        IsAdvance = "0",
                                        OutMode = model.OutMode,//出库口
                                        CreateUser = userId,
                                        CreateTime = DateTime.Now
                                    };
                                    Db.Insertable(allot).ExecuteCommand();
                                    #endregion
                                    #region 添加出库任务信息
                                    var taskNo = new Common().GetMaxNo("TK");
                                    var exTask = new LogTask    //出库任务
                                    {
                                        TaskNo = taskNo,
                                        Sender = "WMS",
                                        Receiver = "WCS",
                                        IsSuccess = 1, //是否下发成功 0失败 1成功
                                        StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                        EndLocat = model.OutMode,//目标位置
                                        PalletNo = s.PalletNo,//托盘码
                                        IsSend = 1,//是否可再次下发
                                        IsCancel = 1,//是否可取消
                                        IsFinish = 1,//是否可完成
                                        Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                        Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                        OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                        CreateTime = serverTime, //创建时间
                                        CreateUser = userId, //创建人
                                        Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                         //FinishDate = serverTime, //完成时间
                                    };
                                    outDto1.Add(new OutCommandDto()
                                    {
                                        PalletNo = exTask.PalletNo,//托盘号
                                        StartLocate = exTask.StartLocat, // 起始位置
                                        StartRoadway = locat.RoadwayNo, //所属巷道
                                        EndLocate = model.OutMode, // 目标位置
                                        TaskNo = exTask.TaskNo, // 任务号
                                        TaskType = "1",// 任务类型 (出库)
                                        OutMode = model.OutMode,  //目标地址
                                        Order = 1
                                    });
                                    Db.Insertable(exTask).ExecuteCommand();
                                    #endregion
                                    #region 储位状态变更
                                    //更改储位状态为出库中
                                    locat.Status = "3"; //3 出库中
                                    Db.Updateable(locat).ExecuteCommand();//修改储位信息
                                    #endregion
                                }
                                else if (slotBefore.Status == "1")
                                {
                                    //判断托盘上物料
                                    var pallSku = Db.Queryable<DataStockDetail>().First(m => m.SkuNo == "100099" && m.LocatNo == slotBefore.LocatNo);
                                    if (pallSku == null) //移库
                                    {
                                        #region 分配
                                        //添加分配表信息
                                        var allot = new BllExportAllot
                                        {
                                            SONo = "",
                                            WaveNo = "",
                                            SODetailNo = 0,
                                            StockId = s.Id,
                                            LotNo = "",
                                            LotText = "",
                                            SupplierLot = "",
                                            SkuNo = s.SkuNo,
                                            SkuName = s.SkuName,
                                            Standard = s.Standard,
                                            PalletNo = s.PalletNo,
                                            IsBale = "0", //是否裹包
                                            IsBelt = "0", //是否打带
                                            //BoxexQty = s.Qty,
                                            Qty = (int)s.Qty,
                                            CompleteQty = 0,
                                            Status = "1",
                                            LogisticsId = 0,
                                            IsAdvance = "0",
                                            OutMode = model.OutMode,//出库口
                                            CreateUser = userId,
                                            CreateTime = DateTime.Now
                                        };
                                        Db.Insertable(allot).ExecuteCommand();
                                        #endregion
                                        #region 添加移库任务信息
                                        var stkModel = Db.Queryable<DataStockDetail>().First(m=>m.LocatNo == slotBefore.LocatNo);
                                        string PalletNo = "LN000000";   // 默认演示托盘
                                        string SkuNo = "";
                                        if (stkModel != null)
                                        {
                                            PalletNo = stkModel.PalletNo;
                                            SkuNo= stkModel.SkuNo;
                                        }
                                        //获取移库的库位
                                        var newSlot = MoveAddress(slotBefore.LocatNo, slotBefore.RoadwayNo, SkuNo, slotBefore.AreaNo);
                                        var taskNo = new Common().GetMaxNo("TK");
                                        var exTask = new LogTask    // 移库任务
                                        {
                                            TaskNo = taskNo,
                                            Sender = "WMS",
                                            Receiver = "WCS",
                                            IsSuccess = 1, //是否下发成功 0失败 1成功
                                            StartLocat = slotBefore.LocatNo,//起始位置
                                            EndLocat = newSlot,//目标位置
                                            PalletNo = PalletNo,//托盘码
                                            IsSend = 1,//是否可再次下发
                                            IsCancel = 1,//是否可取消
                                            IsFinish = 1,//是否可完成
                                            Type = "2",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                            Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                            OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                            CreateTime = serverTime, //创建时间
                                            CreateUser = userId, //创建人
                                            Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + newSlot + "的移库任务", //关键信息
                                                                                                                             //FinishDate = serverTime, //完成时间
                                        };
                                        moveDto.Add(new OutCommandDto()
                                        {
                                            PalletNo = exTask.PalletNo,//托盘号
                                            StartLocate = exTask.StartLocat, // 起始位置
                                            StartRoadway = locat.RoadwayNo, //所属巷道
                                            EndLocate = exTask.EndLocat, // 目标位置
                                            TaskNo = exTask.TaskNo, // 任务号
                                            TaskType = "2",// 任务类型 (出库)
                                            OutMode = "",  //目标地址
                                            Order = 1
                                        });
                                        Db.Insertable(exTask).ExecuteCommand();
                                        #endregion
                                        #region 储位状态变更
                                        //更改储位状态为移出中
                                        slotBefore.Status = "5"; //5 移出中
                                        Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息
                                        #endregion
                                    }
                                    else  //出库
                                    {
                                        #region 改变库存
                                        //增加库存锁定数量
                                        stock.LockQty += (int)s.Qty; //锁定数量
                                        stock.UpdateTime = serverTime; //修改时间
                                        //stock.UpdateUser = userId; //修改人
                                        Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                        //增加库存明细锁定数量
                                        s.LockQty += (int)s.Qty; //锁定数量
                                        s.UpdateTime = serverTime; //修改时间
                                        s.UpdateUser = userId; //修改人
                                        s.Status = "2"; //2 已分配
                                        Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                        #endregion
                                        #region 分配
                                        //添加分配表信息
                                        var allot = new BllExportAllot
                                        {
                                            SONo = "",
                                            WaveNo = "",
                                            SODetailNo = 0,
                                            StockId = s.Id,
                                            LotNo = "",
                                            LotText = "",
                                            SupplierLot = "",
                                            SkuNo = s.SkuNo,
                                            SkuName = s.SkuName,
                                            Standard = s.Standard,
                                            PalletNo = s.PalletNo,
                                            IsBale = "0", //是否裹包
                                            IsBelt = "0", //是否打带
                                            //BoxexQty = s.Qty,
                                            Qty = (int)s.Qty,
                                            CompleteQty = 0,
                                            Status = "1",
                                            LogisticsId = 0,
                                            IsAdvance = "0",
                                            OutMode = model.OutMode,//出库口
                                            CreateUser = userId,
                                            CreateTime = DateTime.Now
                                        };
                                        Db.Insertable(allot).ExecuteCommand();
                                        #endregion
                                        #region 添加出库任务信息
                                        var taskNo = new Common().GetMaxNo("TK");
                                        var exTask = new LogTask    //出库任务
                                        {
                                            TaskNo = taskNo,
                                            Sender = "WMS",
                                            Receiver = "WCS",
                                            IsSuccess = 1, //是否下发成功 0失败 1成功
                                            StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                            EndLocat = model.OutMode,//目标位置
                                            PalletNo = s.PalletNo,//托盘码
                                            IsSend = 1,//是否可再次下发
                                            IsCancel = 1,//是否可取消
                                            IsFinish = 1,//是否可完成
                                            Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                            Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                            OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                            CreateTime = serverTime, //创建时间
                                            CreateUser = userId, //创建人
                                            Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                             //FinishDate = serverTime, //完成时间
                                        };
                                        outDto2.Add(new OutCommandDto()
                                        {
                                            PalletNo = exTask.PalletNo,//托盘号
                                            StartLocate = exTask.StartLocat, // 起始位置
                                            StartRoadway = locat.RoadwayNo, //所属巷道
                                            EndLocate = model.OutMode, // 目标位置
                                            TaskNo = exTask.TaskNo, // 任务号
                                            TaskType = "1",// 任务类型 (出库)
                                            OutMode = model.OutMode,  //目标地址
                                            Order = 1
                                        });
                                        Db.Insertable(exTask).ExecuteCommand();
                                        #endregion
                                        #region 储位状态变更
                                        //更改储位状态为出库中
                                        slotBefore.Status = "3"; //3 出库中
                                        Db.Updateable(slotBefore).ExecuteCommand();//修改储位信息
                                        #endregion
                                    }
                                    if (int.Parse(model.Num) == outDto1.Count + outDto2.Count)
                                    {
                                        break;//需求垛数已达到 可以出库了
                                    }
                                    else
                                    {
                                        #region 改变库存
                                        //增加库存锁定数量
                                        stock.LockQty += (int)s.Qty; //锁定数量
                                        stock.UpdateTime = serverTime; //修改时间
                                        //stock.UpdateUser = userId; //修改人
                                        Db.Updateable(stock).ExecuteCommand();//修改库存总表信息
                                        //增加库存明细锁定数量
                                        s.LockQty += (int)s.Qty; //锁定数量
                                        s.UpdateTime = serverTime; //修改时间
                                        s.UpdateUser = userId; //修改人
                                        s.Status = "2"; //2 已分配
                                        Db.Updateable(s).ExecuteCommand();//修改库存明细信息
                                        #endregion
                                        #region 分配
                                        //添加分配表信息
                                        var allot = new BllExportAllot
                                        {
                                            SONo = "",
                                            WaveNo = "",
                                            SODetailNo = 0,
                                            StockId = s.Id,
                                            LotNo = "",
                                            LotText = "",
                                            SupplierLot = "",
                                            SkuNo = s.SkuNo,
                                            SkuName = s.SkuName,
                                            Standard = s.Standard,
                                            PalletNo = s.PalletNo,
                                            IsBale = "0", //是否裹包
                                            IsBelt = "0", //是否打带
                                            //BoxexQty = s.Qty,
                                            Qty = (int)s.Qty,
                                            CompleteQty = 0,
                                            Status = "1",
                                            LogisticsId = 0,
                                            IsAdvance = "0",
                                            OutMode = model.OutMode,//出库口
                                            CreateUser = userId,
                                            CreateTime = DateTime.Now
                                        };
                                        Db.Insertable(allot).ExecuteCommand();
                                        #endregion
                                        #region 添加出库任务信息
                                        var taskNo = new Common().GetMaxNo("TK");
                                        var exTask = new LogTask    //出库任务
                                        {
                                            TaskNo = taskNo,
                                            Sender = "WMS",
                                            Receiver = "WCS",
                                            IsSuccess = 1, //是否下发成功 0失败 1成功
                                            StartLocat = locat == null ? "" : s.LocatNo,//起始位置
                                            EndLocat = model.OutMode,//目标位置
                                            PalletNo = s.PalletNo,//托盘码
                                            IsSend = 1,//是否可再次下发
                                            IsCancel = 1,//是否可取消
                                            IsFinish = 1,//是否可完成
                                            Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                                            Status = "1",//任务状态0:等待执行1正在执行2执行完成
                                            OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                                            CreateTime = serverTime, //创建时间
                                            CreateUser = userId, //创建人
                                            Msg = "WCS空托从" + locat == null ? "" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                                                                                                                             //FinishDate = serverTime, //完成时间
                                        };
                                        outDto2.Add(new OutCommandDto()
                                        {
                                            PalletNo = exTask.PalletNo,//托盘号
                                            StartLocate = exTask.StartLocat, // 起始位置
                                            StartRoadway = locat.RoadwayNo, //所属巷道
                                            EndLocate = model.OutMode, // 目标位置
                                            TaskNo = exTask.TaskNo, // 任务号
                                            TaskType = "1",// 任务类型 (出库)
                                            OutMode = model.OutMode,  //目标地址
                                            Order = 1
                                        });
                                        Db.Insertable(exTask).ExecuteCommand();
                                        #endregion
                                        #region 储位状态变更
                                        //更改储位状态为出库中
                                        locat.Status = "3"; //3 出库中
                                        Db.Updateable(locat).ExecuteCommand();//修改储位信息
                                        #endregion
                                    }
                                }
                            }
                        }
                    }
                    if (int.Parse(model.Num) == outDto1.Count + outDto2.Count)
                    {
                        break;//需求垛数已达到 可以出库了
                    }
                }
                outDto1.AddRange(moveDto);
                outDto1.AddRange(outDto2);
                if (outDto1.Count <= 0)
                {
                    throw new Exception("暂无出库任务,请核查!");
                }
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "空托出库", int.Parse(model.Num) + "", "下发", $"WCS下发了 {int.Parse(model.Num)} 个空托垛", userId);
                Db.CommitTran();
                return outDto1;
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        public string MoveAddress(string oldAddress, string roadWay, string skuNo,string areaNo="")//01020201  排-列-层-深度
        {
            string nowAddress = "";
            var category = new SysMaterialCategory();
            if (!string.IsNullOrEmpty(skuNo))
            {
                //根据物料编码获取对应区域
                var skuCategoryNo = Db.Queryable<SysMaterials>().Where(a => a.IsDel == "0" && a.SkuNo == skuNo).Select(a => a.CategoryNo).First();
                category = Db.Queryable<SysMaterialCategory>().First(a => a.IsDel == "0" && a.CategoryNo == skuCategoryNo);
                areaNo = category.AreaNo;
            }
            else
            {
                //todo 待验证
                category = Db.Queryable<SysMaterialCategory>().First(a => a.IsDel == "0" && a.AreaNo == areaNo);
            }
            // 获取移库目标储位
            var row = int.Parse(oldAddress.Substring(0, 2));
            var lie = int.Parse(oldAddress.Substring(2, 2));
            var ceng = int.Parse(oldAddress.Substring(4, 2));
            var sqlString = $@"select LocatNo,[Row],[Column],Layer, (ABS(Row-{row}) + ABS([Column]-{lie}) + ABS(Layer-{ceng}))  as distNum from SysStorageLocat where Flag = '0' and Status = '0' and Depth = '02' and RoadwayNo = '{roadWay}' and AreaNo in ('{areaNo}') order by distNum;";
            var addressModels = Db.Ado.SqlQuery<AddressCls>(sqlString).ToList();
            if (addressModels.Count > 0)   // 判断同巷道内排空库位
            {
                var listLocaete = new List<string>();
                foreach (var item in addressModels)
                {
                    // 目标内库位对应的外库位
                    string addressee = item.LocatNo.Substring(0, 6) + "01";
                    // 判断目标库位的外库位是否存在货物   (正常情况下正在移入情况不存在,因为移库先移入里面,后移入外面)
                    //SlotStatus 0: 空储位 1:有货  2:正在入库  3:正在出库   4:正在移入  5:正在移出
                    sqlString = $"select count(*) from SysStorageLocat where LocatNo = '{addressee}' and Status = '0' and Flag in ('0','1') ; ";
                    var rowNum = Db.Ado.SqlQuery<int>(sqlString).First();
                    if (rowNum == 0)
                    {
                        continue;
                    }
                    else
                    {
                        nowAddress = item.LocatNo;
                        break;
                    }
                }
            }
            if (nowAddress == "")
            {
                // 判断同巷道外排空库位
                sqlString = $@"select LocatNo,[Row],[Column],Layer, (ABS(Row-{row}) + ABS([Column]-{lie}) + ABS(Layer-{ceng}))  as distNum
                                from SysStorageLocat
                                where Flag = '0' and Status = '0' and Depth = '01' and RoadwayNo = '{roadWay}' and AreaNo  in '{category}'
                                order by distNum;";
                var adderModeling = Db.Ado.SqlQuery<AddressCls>(sqlString).ToList();
                if (adderModeling.Count > 0)
                {
                    nowAddress = adderModeling[0].LocatNo;
                }
                else
                {
                    // 库内不存在空储位
                    nowAddress = "";
                }
            }
            return nowAddress;
        }
        //获取平库托盘信息
        public List<BoxInfo> GetPingKuInfoByPallet(string soNo, string palletNo)
        {
            try
            {
                var info = Db.Queryable<BllExportAllot>().Where(m => m.SONo == soNo && m.PalletNo == palletNo && m.IsDel == "0");
                if (info.Count() == 0)
                {
                    throw new Exception("未查询到托盘分配下发的信息");
                }
                var data = info.GroupBy(m => new { m.SkuNo, m.SkuName, m.LotNo }).Select(m => new BoxInfo()
                {
                    SkuNo = m.SkuNo,
                    SkuName = m.SkuName,
                    LotNo = m.LotNo
                }).ToList();
                return data;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 平库出库完成
        /// </summary>
        /// <param name="soNo">单据号</param>
        /// <param name="palletNo">托盘码</param>
        /// <param name="userId">操作人</param>
        public void PlaneExportSuccess(string soNo, string palletNo, int userId)
        {
            try
            {
                #region 托盘信息
                //获取托盘信息
                var pallet = Db.Queryable<SysPallets>().First(p => p.IsDel == "0" && p.PalletNo == palletNo);
                //验证托盘信息是否为空
                if (pallet == null)
                {
                    throw new Exception("托盘信息不存在,请检查!");
                }
                if (pallet.Status == "0")
                {
                    throw new Exception("托盘未使用,请检查!");
                }
                #endregion
                #region 托盘是否在平库验证
                var result = Db.Queryable<DataStockDetail>().First(m => m.PalletNo == palletNo);
                if (result == null)
                {
                    throw new Exception("库存信息中不存在该托盘信息,请检查!");
                }
                if (result.WareHouseNo != "W02")//W02:零箱库
                {
                    throw new Exception("该托盘未在平库内,请检查!");
                }
                #endregion
                #region 验证储位状态是否正常
                var locat = Db.Queryable<SysStorageLocat>().First(a=>a.IsDel == "0" && a.LocatNo == result.LocatNo);
                if (locat == null)
                {
                    throw new Exception("未获取到对应储位信息,请检查!");
                }
                if (locat.Status != "3")
                {
                    throw new Exception("当前储位不是出库中,请检查!");
                }
                #endregion
                //获取库存明细信息
                var stockDetail = Db.Queryable<DataStockDetail>().Where(s => s.IsDel == "0" && s.PalletNo == palletNo).ToList();
                //验证库存明细信息是否存在
                if (stockDetail == null)
                {
                    throw new Exception("库存明细不存在,请检查库存信息!");
                }
                Db.BeginTran();
                try
                {
                    foreach (var item in stockDetail)
                    {
                        if (item.SkuNo == "100099")//判断是否是空托出库
                        {
                            //判断总库存是否为0,如果为0删除 否则减去数量
                            var stock = Db.Queryable<DataStock>().First(m => m.SkuNo == "100099");
                            if (stock != null)
                            {
                                if (item.LockQty != null)
                                {
                                    stock.Qty -= item.LockQty.Value;
                                    stock.LockQty -= item.LockQty.Value;
                                    Db.Updateable(stock).ExecuteCommand();
                                }
                                if (stock.Qty == 0)
                                {
                                    Db.Deleteable(stock).ExecuteCommand();
                                }
                            }
                            //托盘状态改为未使用
                            var sCode = Db.Queryable<SysPallets>().First(m => m.PalletNo == item.PalletNo);
                            if (sCode != null)
                            {
                                sCode.Status = "0";
                                Db.Updateable(sCode).ExecuteCommand();
                            }
                            Db.Deleteable(item).ExecuteCommand();
                            continue;
                        }
                        item.LocatNo = "";//储位更改(改为空)
                        item.WareHouseNo = "";//所属仓库更改(改为空)
                        item.RoadwayNo = "";//所属巷道更改(改为空)
                        item.AreaNo = "";//所属区域更改(改为空)
                        Db.Updateable(item).ExecuteCommand();
                    }
                    //变更储位状态
                    locat.Status = "0";//储位更改(改为空储位)
                    Db.Updateable(locat).ExecuteCommand();
                    //出库流水(更改状态)
                    var allot = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.Status == "1" && m.PalletNo == palletNo && m.SONo == soNo).ToList();
                    foreach (var item in allot)
                    {
                        if (item.SkuNo == "100099")
                        {
                            item.Status = "5";
                            item.CompleteQty += stockDetail[0].Qty;
                        }
                        else
                        {
                            item.Status = "2";
                        }
                    }
                    Db.Updateable(allot).ExecuteCommand();
                    #region 添加出库操作日志记录信息
                    //添加操作日志记录
                    var k = new OperationSOServer().AddLogOperationSo("出库作业", "拣货明细", soNo, "完成", $"用PDA完成了单据号为{soNo}的平库出库", userId);
                    #endregion
                    Db.CommitTran();
                }
                catch (Exception e)
                {
                    Db.RollbackTran();
                    throw new Exception(e.Message);
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        //根据托盘号获取取样类型
        public string GetSampleType(string palletNo)
        {
            try
            {
                var type = "";
                var detail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.PalletNo == palletNo);
                if (detail == null)
                {
                    throw new Exception("当前托盘未在库存中");
                }
                //怎么判断当前托盘是库外要取样的托盘,正常出库剩余托盘目前这种情况也能拣货啊,也没有分配信息
                var allot = Db.Queryable<BllExportAllot>().First(m =>
                    m.IsDel == "0" && m.PalletNo == palletNo && m.Status != "5" && m.Status != "6");
                if (allot != null)
                {
                    var soNo = Db.Queryable<BllExportNotice>()
                        .First(m => m.IsDel == "0" && m.SONo == allot.SONo);
                    if (soNo == null)
                    {
                        throw new Exception("未找到托盘上出库单据信息");
                    }
                    if (soNo.Type != "3")
                    {
                        throw new Exception("该托盘不是取样托盘");
                    }
                    type = "0";//库内取样
                }
                else
                {
                    //判断当前托盘是否是在平库或库外
                    type = "1";//库前取样
                }
                return type;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        //根据托盘号获取入库单据
        public List<string> GetAsnNoByPallet(string palletNo)
        {
            try
            {
                var type = "";
                var detail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.PalletNo == palletNo);
                if (detail == null)
                {
                    throw new Exception("当前托盘未在库存中");
                }
                var list = new List<string>();
                if (string.IsNullOrWhiteSpace(detail.ASNNo))
                {
                    throw new Exception("未查询到该托盘的入库单信息");
                }
                list.Add(detail.ASNNo);
                return list;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        //取样出库拣货(标签)
        public void SampleSoSetPick(string soType, string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, string pickQty1, string asnNo, int userId)
        {
            Db.BeginTran();
            try
            {
                if (string.IsNullOrWhiteSpace(soType))
                {
                    throw new Exception("取样标识不能为空");
                }
                //soType: 0库内取样,有出库单及分配信息; 1库前取样,反向添加出库单及分配信息
                if (soType == "1")
                {
                    #region 判断
                    if (string.IsNullOrWhiteSpace(asnNo))
                    {
                        throw new Exception("入库单不能为空");
                    }
                    if (string.IsNullOrWhiteSpace(palletNo))
                    {
                        throw new Exception("托盘码不能为空");
                    }
                    if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)
                    {
                        throw new Exception("追溯条码和拣货数量不能同时输入");
                    }
                    //先判断是否是库外取样托盘
                    var allot = Db.Queryable<BllExportAllot>().First(m =>
                        m.IsDel == "0" && m.PalletNo == palletNo && m.Status != "5" && m.Status != "6");
                    if (allot != null)
                    {
                        throw new Exception("当前托盘不属于库前取样");
                    }
                    //库存明细
                    var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.ASNNo == asnNo && m.PalletNo == palletNo);
                    if (stockDetail == null)
                    {
                        throw new Exception("未查询到该托盘的库存明细信息!");
                    }
                    var sku = Db.Queryable<SysMaterials>().First(m => m.IsDel == "0" && m.SkuNo == stockDetail.SkuNo);
                    if (sku == null)
                    {
                        throw new Exception("未查询到当前托盘上的物料信息");
                    }
                    //库存总表
                    var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                    if (stock == null)
                    {
                        throw new Exception("未查询到该托盘分配的库存信息!");
                    }
                    //出库单
                    var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.AsnSampleNo == asnNo);
                    //创建出库单
                    if (notice == null || notice.Status == "6")
                    {
                        var billNo = "";
                        var bl = true;
                        do
                        {
                            //获取自增单据号
                            billNo = new Common().GetMaxNo("SO");
                            var no = billNo;
                            bl = Db.Queryable<BllExportNotice>().Any(m => m.SONo == no);
                        } while (bl);
                        var addNotice = new BllExportNotice()
                        {
                            SONo = billNo,
                            Type = "3",
                            Status = "4",
                            Origin = "WMS",
                            AsnSampleNo = asnNo,
                            IsWave = "0",
                            WaveNo = "",
                            IsDespatch = "0",
                            CompleteTime = DateTime.Now,
                            CreateUser = userId,
                        };
                        var n = Db.Insertable(addNotice).ExecuteReturnEntity();
                        notice = n;
                    }
                    //创建出库单明细
                    var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.SONo == notice.SONo && m.SkuNo == stockDetail.SkuNo && m.LotNo.Contains(stockDetail.LotNo));
                    if (noticeDetail == null)
                    {
                        var addNoticeDetail = new BllExportNoticeDetail()
                        {
                            SONo = notice.SONo,
                            SkuNo = sku.SkuNo,
                            SkuName = sku.SkuName,
                            Standard = sku.Standard,
                            LotNo = stockDetail.LotNo,
                            LotText = "",
                            Qty = 0,
                            AllotQty = 0,
                            FactQty = 0,
                            CompleteQty = 0,
                            PackagNo = sku.PackagNo,
                            Price = sku.Price,
                            //Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * pickQty,
                            IsBale = "",
                            IsBelt = "",
                            SupplierLot = stock.SupplierLot,
                            IsWave = "0",
                            WaveNo = "",
                            IsIssueLotNo = "0",
                            Status = "3",
                            CreateUser = userId,
                        };
                        var m = Db.Insertable(addNoticeDetail).ExecuteReturnEntity();
                        noticeDetail = m;
                    }
                    //出库分配信息
                    var allot2 = Db.Queryable<BllExportAllot>().First(m => m.IsDel == "0" && m.Status == "5" && m.SONo == notice.SONo && m.PalletNo == palletNo);
                    if (allot2 == null)
                    {
                        //添加分配表信息
                        var addAllot = new BllExportAllot
                        {
                            SONo = notice.SONo,
                            WaveNo = "",
                            SODetailNo = noticeDetail.Id,
                            StockId = stockDetail.Id,
                            LotNo = stockDetail.LotNo,
                            LotText = stockDetail.LotText,
                            SupplierLot = stockDetail.SupplierLot,
                            SkuNo = sku.SkuNo,
                            SkuName = sku.SkuName,
                            Standard = sku.Standard,
                            PalletNo = palletNo,
                            IsBale = "0", //是否裹包
                            IsBelt = "0", //是否打带
                            Qty = 0,
                            CompleteQty = 0,
                            Status = "5",
                            LogisticsId = notice.LogisticsId,
                            IsAdvance = "0",
                            OutMode = "",//出库口
                            CreateUser = userId,
                            UpdateTime = DateTime.Now
                        };
                        var fp = Db.Insertable(addAllot).ExecuteReturnEntity();
                        allot2 = fp;
                    }
                    #endregion
                    //判断是散支拣货还是数量拣货
                    var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货
                    List<DataBoxInfo> boxInfos;
                    var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo);
                    if (boxInfo.Count() == 0)
                    {
                        throw new Exception("未查询到该箱码及追溯码的信息");
                    }
                    boxInfos = boxInfo.ToList();
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot2.Id && m.PalletNo == palletNo).ToList();
                    if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货
                    {
                        boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList();
                        if (boxInfos.Count() == 0)
                        {
                            throw new Exception("未查询到该箱码及追溯码的信息");
                        }
                        if (boxInfos.Count() > 1)
                        {
                            throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!");
                        }
                        if (boxInfos.Any(m => m.PalletNo != palletNo))
                        {
                            throw new Exception("该托盘与箱码没有绑定关系");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                            {
                                throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                            }
                        }
                        biaoShi = "1";
                    }
                    else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货
                    {
                        if (boxInfo.Count() > 1)
                        {
                            throw new Exception("该箱码内存在支码不能进行数量拣货");
                        }
                        decimal boxQty = boxInfo.First().Qty;
                        if (Convert.ToInt32(pickQty1) > boxQty)
                        {
                            throw new Exception("拣货数量不能大于箱内数量");
                        }
                        biaoShi = "2";
                    }
                    else //整箱拣货
                    {
                        if (boxInfo.Count() == 0)
                        {
                            throw new Exception("未查询到该箱码的信息");
                        }
                        if (boxInfo.Any(m => m.PalletNo != palletNo))
                        {
                            throw new Exception("该托盘与箱码没有绑定关系");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo))
                            {
                                throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货");
                            }
                        }
                    }
                    decimal pickQty = 0;//拣货的数量
                    var comList = new List<BllCompleteDetail>();
                    foreach (var item in boxInfos)
                    {
                        //if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                        //{
                        //    throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                        //}
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
                            SONo = notice.SONo,
                            SODetailNo = noticeDetail.Id,
                            ExportAllotId = allot2.Id,
                            StockId = allot2.StockId,
                            BoxNo = item.BoxNo,
                            BoxNo2 = item.BoxNo2,
                            BoxNo3 = item.BoxNo3,
                            LotNo = allot2.LotNo,
                            LotText = allot2.LotText,
                            SupplierLot = allot2.SupplierLot,
                            SkuNo = allot2.SkuNo,
                            SkuName = allot2.SkuName,
                            Standard = allot2.Standard,
                            PalletNo = palletNo,
                            CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty,
                            InspectMark = "1",
                            CreateUser = userId
                        };
                        comList.Add(completeDetail);
                        if (biaoShi != "2")
                        {
                            //删除库存箱码明细
                            Db.Deleteable(item).ExecuteCommand();
                        }
                        else//数量拣货
                        {
                            if (decimal.Parse(pickQty1) == item.Qty)
                            {
                                //删除库存箱码明细
                                Db.Deleteable(item).ExecuteCommand();
                            }
                            else
                            {
                                item.Qty -= decimal.Parse(pickQty1);
                                item.BitBoxMark = "1";//零箱标识
                                item.InspectMark = "1";//抽检箱标识
                                Db.Updateable(item).ExecuteCommand();
                            }
                        }
                        pickQty += biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty;
                    }
                    //改变库内箱码是否零箱信息
                    if (biaoShi == "1")
                    {
                        var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList();
                        foreach (var item in boxSurplusList)
                        {
                            item.BitBoxMark = "1";
                            item.InspectMark = "1";
                            Db.Updateable(item).ExecuteCommand();
                        }
                    }
                    Db.Insertable(comList).ExecuteCommand();
                    //修改出库分配信息
                    allot2.Qty += pickQty;
                    allot2.CompleteQty += pickQty;
                    Db.Updateable(allot2).ExecuteCommand();
                    //删除或修改库存明细
                    stockDetail.BitPalletMark = "1";//修改为零托标识
                    stockDetail.Qty -= pickQty;
                    if (stockDetail.Qty <= 0)
                    {
                        Db.Deleteable(stockDetail).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                    stock.Qty -= pickQty;
                    if (stock.Qty <= 0)
                    {
                        Db.Deleteable(stock).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stock).ExecuteCommand();
                    }
                    var num2 = Db.Queryable<DataStockDetail>().Count(m => m.IsDel == "0" && m.PalletNo == palletNo);
                    if (num2 <= 0)
                    {
                        //改变托盘状态
                        var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                        if (pallet == null)
                        {
                            throw new Exception("未在托盘表中查询到托盘信息");
                        }
                        pallet.Status = "0";
                        Db.Updateable(pallet).ExecuteCommand();
                    }
                    //修改出库单明细拣货数量
                    noticeDetail.Qty += pickQty;
                    noticeDetail.AllotQty += pickQty;
                    noticeDetail.FactQty += pickQty;
                    noticeDetail.CompleteQty += pickQty;
                    noticeDetail.Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * noticeDetail.Qty;
                    Db.Updateable(noticeDetail).ExecuteCommand();
                }
                else if (soType == "0")
                {
                    #region 判断
                    if (string.IsNullOrWhiteSpace(soNo))
                    {
                        throw new Exception("出库单据不能为空");
                    }
                    if (string.IsNullOrWhiteSpace(soDetailId))
                    {
                        throw new Exception("出库物料-批次不能为空");
                    }
                    if (string.IsNullOrWhiteSpace(palletNo))
                    {
                        throw new Exception("托盘码不能为空");
                    }
                    if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)
                    {
                        throw new Exception("追溯条码和拣货数量不能同时输入");
                    }
                    //出库单
                    var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == soNo);
                    if (notice == null)
                    {
                        throw new Exception("未查询到该出库单的信息");
                    }
                    if (notice.Status != "3")
                    {
                        throw new Exception("出库单的状态不是正在执行,不能拣货");
                    }
                    //出库单明细
                    var noticeDetail = Db.Queryable<BllExportNoticeDetail>()
                        .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId));
                    if (noticeDetail == null)
                    {
                        throw new Exception("未查询到该出库单明细的信息");
                    }
                    //出库分配信息
                    var allot = Db.Queryable<BllExportAllot>().First(m =>
                        m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo &&
                        m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo);
                    if (allot == null)
                    {
                        throw new Exception("未查询到该托盘的分配信息");
                    }
                    //剩余拣货数量(待拣减去已拣)
                    var needQty = allot.Qty - allot.CompleteQty;
                    //库存明细
                    var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.Id == allot.StockId);
                    if (stockDetail == null)
                    {
                        throw new Exception("未查询到该托盘分配的库存明细信息!");
                    }
                    //库存总表
                    var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                    if (stock == null)
                    {
                        throw new Exception("未查询到该托盘分配的库存信息!");
                    }
                    #endregion
                    var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货
                    List<DataBoxInfo> boxInfos;
                    var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo);
                    if (boxInfo.Count() == 0)
                    {
                        throw new Exception("未查询到该箱码及追溯码的信息");
                    }
                    boxInfos = boxInfo.ToList();
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList();
                    if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货
                    {
                        boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList();
                        if (boxInfos.Count() == 0)
                        {
                            throw new Exception("未查询到该箱码及追溯码的信息");
                        }
                        if (boxInfos.Count() > 1)
                        {
                            throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!");
                        }
                        if (boxInfos.Any(m => m.PalletNo != palletNo))
                        {
                            throw new Exception("该托盘与箱码没有绑定关系");
                        }
                        var boxQty = boxInfos.First().Qty;
                        if (boxQty > needQty)
                        {
                            throw new Exception("拣货数量不能大于剩余待拣数量");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                            {
                                throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                            }
                        }
                        biaoShi = "1";
                    }
                    else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货
                    {
                        if (boxInfo.Count() > 1)
                        {
                            throw new Exception("该箱码内存在支码不能进行数量拣货");
                        }
                        decimal boxQty = boxInfo.First().Qty;
                        if (Convert.ToDecimal(pickQty1) > boxQty)
                        {
                            throw new Exception("拣货数量不能大于箱内数量");
                        }
                        if (Convert.ToDecimal(pickQty1) > needQty)
                        {
                            throw new Exception("拣货数量不能大于剩余待拣数量");
                        }
                        biaoShi = "2";
                    }
                    else //整箱拣货
                    {
                        if (boxInfo.Count() == 0)
                        {
                            throw new Exception("未查询到该箱码的信息");
                        }
                        if (boxInfo.Any(m => m.PalletNo != palletNo))
                        {
                            throw new Exception("该托盘与箱码没有绑定关系");
                        }
                        var boxQty = boxInfo.GroupBy(m => m.BoxNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList();
                        if (boxQty[0] > needQty)
                        {
                            throw new Exception("拣货数量不能大于箱内剩余待拣数量");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo))
                            {
                                throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货");
                            }
                        }
                    }
                    decimal pickQty = 0;//拣货的数量
                    var comList = new List<BllCompleteDetail>();
                    foreach (var item in boxInfos)
                    {
                        //if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                        //{
                        //    throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                        //}
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
                            SONo = soNo,
                            SODetailNo = int.Parse(soDetailId),
                            ExportAllotId = allot.Id,
                            StockId = allot.StockId,
                            BoxNo = item.BoxNo,
                            BoxNo2 = item.BoxNo2,
                            BoxNo3 = item.BoxNo3,
                            LotNo = allot.LotNo,
                            LotText = allot.LotText,
                            SupplierLot = allot.SupplierLot,
                            SkuNo = allot.SkuNo,
                            SkuName = allot.SkuName,
                            Standard = allot.Standard,
                            PalletNo = palletNo,
                            CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty,
                            CreateUser = userId
                        };
                        comList.Add(completeDetail);
                        if (biaoShi != "2")
                        {
                            pickQty += item.Qty;
                            //删除库存箱码明细
                            Db.Deleteable(item).ExecuteCommand();
                        }
                        else//数量拣货
                        {
                            if (decimal.Parse(pickQty1) == item.Qty)
                            {
                                pickQty += item.Qty;
                                //删除库存箱码明细
                                Db.Deleteable(item).ExecuteCommand();
                            }
                            else
                            {
                                pickQty += decimal.Parse(pickQty1);
                                item.Qty -= decimal.Parse(pickQty1);
                                item.BitBoxMark = "1";//零箱标识
                                Db.Updateable(item).ExecuteCommand();
                            }
                        }
                    }
                    //改变库内箱码是否零箱信息
                    if (biaoShi == "1")
                    {
                        var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList();
                        foreach (var item in boxSurplusList)
                        {
                            item.BitBoxMark = "1";
                            Db.Updateable(item).ExecuteCommand();
                        }
                    }
                    Db.Insertable(comList).ExecuteCommand();
                    //修改出库分配信息
                    allot.CompleteQty += pickQty;
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.UpdateTime = DateTime.Now;
                    if (allot.Status == "5")
                    {
                        //判断该托盘是否还存在物料 存在改为待回库 待回库完成后改为已完成
@@ -618,6 +3347,8 @@
                    //修改出库单信息
                    Db.Updateable(notice).ExecuteCommand();
                }
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId);
                Db.CommitTran();
            }
            catch (Exception e)
@@ -627,369 +3358,1390 @@
            }
        }
        /// <summary>
        /// 下发空托出库
        /// </summary>
        /// <param name="model"> </param>
        /// <param name="userId"> </param>
        /// <param name="url"> </param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public string IssuePlnOutHouse(OutModePalletVm model, int userId,string url)
        //取样出库拣货(无标签)
        public void SampleSoSetQtyPick(string soType, string soNo, string soDetailId, string palletNo, string PickQty, string asnNo, int userId)
        {
            Db.BeginTran();
            try
            {
                string strMsg = "";
                var outDtoList = new List<OutCommandDto>(); //出库数据的集合
                //获取当前时间
                DateTime serverTime = Db.GetDate();
                //获取库存明细是否小于等于该垛数
                string str = "select * from DataStockDetail where IsDel = '0' and SkuNo = '100099' and Status = '0' ";
                var stockDetail = Db.Ado.SqlQuery<DataStockDetail>(str);
                if (stockDetail.Count > 0)
                if (string.IsNullOrWhiteSpace(soType))
                {
                    //判断是否大于需要垛数
                    if (stockDetail.Count< int.Parse(model.Num))
                    throw new Exception("取样标识不能为空");
                }
                if (soType == "1")
                {
                    if (string.IsNullOrWhiteSpace(asnNo))
                    {
                        strMsg = "需要垛数大于库存垛数,请重新输入!";
                        return strMsg;
                        throw new Exception("入库单据不能为空");
                    }
                }
                //获取库存总表信息
                var stock = Db.Queryable<DataStock>().First(s => s.IsDel == "0" && s.SkuNo == "100099");
                //验证库存总表是否为空
                if (stock == null)
                {
                    strMsg = "库存信息不存在,请核查!";
                    return strMsg;
                }
                int i = 0;
                Db.BeginTran();
                //遍历库存信息
                foreach (var s in stockDetail)
                {
                    //获取储位信息
                    var locat = Db.Queryable<SysStorageLocat>().First(l => l.LocatNo == s.LocatNo && l.IsDel == "0" && l.WareHouseNo == "W01");
                    if (locat != null)
                    if (string.IsNullOrWhiteSpace(palletNo))
                    {
                        if (locat.Status != "1")
                        throw new Exception("托盘码不能为空");
                    }
                    //先判断是否是库外取样托盘
                    var allot = Db.Queryable<BllExportAllot>().First(m =>
                        m.IsDel == "0" && m.PalletNo == palletNo && m.Status != "5" && m.Status != "6");
                    if (allot != null)
                    {
                        throw new Exception("当前托盘不属于库前取样");
                    }
                    //库存明细
                    var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.ASNNo == asnNo && m.PalletNo == palletNo);
                    if (stockDetail == null)
                    {
                        throw new Exception("未查询到该托盘的库存明细信息!");
                    }
                    var sku = Db.Queryable<SysMaterials>().First(m => m.IsDel == "0" && m.SkuNo == stockDetail.SkuNo);
                    if (sku == null)
                    {
                        throw new Exception("未查询到当前托盘上的物料信息");
                    }
                    //库存总表
                    var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                    if (stock == null)
                    {
                        throw new Exception("未查询到该托盘分配的库存信息!");
                    }
                    //出库单
                    var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.AsnSampleNo == asnNo);
                    //创建出库单
                    if (notice == null || notice.Status == "6")
                    {
                        var billNo = "";
                        var bl = true;
                        do
                        {
                            continue;
                        }
                        //更改储位状态为出库中
                        locat.Status = "3"; //3 出库中
                        locat.UpdateTime = serverTime; //修改时间
                        locat.UpdateUser = userId; //修改人
                        //修改储位信息
                        Db.Updateable(locat).ExecuteCommand();
                            //获取自增单据号
                            billNo = new Common().GetMaxNo("SO");
                            var no = billNo;
                            bl = Db.Queryable<BllExportNotice>().Any(m => m.SONo == no);
                        } while (bl);
                        var addNotice = new BllExportNotice()
                        {
                            SONo = billNo,
                            Type = "3",
                            Status = "4",
                            Origin = "WMS",
                            AsnSampleNo = asnNo,
                            IsWave = "0",
                            WaveNo = "",
                            IsDespatch = "0",
                            CompleteTime = DateTime.Now,
                            CreateUser = userId,
                        };
                        var n = Db.Insertable(addNotice).ExecuteReturnEntity();
                        notice = n;
                    }
                    //增加库存锁定数量
                    //stock.AllotQty +=
                    stock.LockQty += (int)s.Qty; //锁定数量
                    stock.UpdateTime = serverTime; //修改时间
                    stock.UpdateUser = userId; //修改人
                    //修改库存总表信息
                    Db.Updateable(stock).ExecuteCommand();
                    //增加库存明细锁定数量
                    //s.AllotQty +=
                    s.LockQty += (int)s.Qty; //锁定数量
                    s.UpdateTime = serverTime; //修改时间
                    s.UpdateUser = userId; //修改人
                    s.Status = "2"; //2 已分配
                    //修改库存明细信息
                    Db.Updateable(s).ExecuteCommand();
                    #region 分配
                    //添加分配表信息
                    var allot = new BllExportAllot
                    //创建出库单明细
                    var noticeDetail = Db.Queryable<BllExportNoticeDetail>().First(m => m.IsDel == "0" && m.SONo == notice.SONo && m.SkuNo == stockDetail.SkuNo && m.LotNo.Contains(stockDetail.LotNo));
                    if (noticeDetail == null)
                    {
                        SONo = "",
                        WaveNo = "",
                        SODetailNo = 0,
                        StockId = s.Id,
                        LotNo = "",
                        LotText = "",
                        SupplierLot = "",
                        SkuNo = s.SkuNo,
                        SkuName = s.SkuName,
                        Standard = s.Standard,
                        PalletNo = s.PalletNo,
                        IsBale = "0", //是否裹包
                        IsBelt = "0", //是否打带
                        var addNoticeDetail = new BllExportNoticeDetail()
                        {
                            SONo = notice.SONo,
                            SkuNo = sku.SkuNo,
                            SkuName = sku.SkuName,
                            Standard = sku.Standard,
                            LotNo = stockDetail.LotNo,
                            LotText = "",
                            Qty = 0,
                            AllotQty = 0,
                            FactQty = 0,
                            CompleteQty = 0,
                            PackagNo = sku.PackagNo,
                            Price = sku.Price,
                            //Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * pickQty,
                            IsBale = "",
                            IsBelt = "",
                            SupplierLot = stock.SupplierLot,
                            IsWave = "0",
                            WaveNo = "",
                            IsIssueLotNo = "0",
                            Status = "3",
                            CreateUser = userId,
                        //BoxexQty = s.Qty,
                        Qty = (int)s.Qty,
                        CompleteQty = 0,
                        Status = "1",
                        LogisticsId = 0,
                        IsAdvance = "0",
                        OutMode = model.OutMode,//出库口
                        };
                        var m = Db.Insertable(addNoticeDetail).ExecuteReturnEntity();
                        noticeDetail = m;
                    }
                    //出库分配信息
                    var allot2 = Db.Queryable<BllExportAllot>().First(m => m.IsDel == "0" && m.Status == "5" && m.SONo == notice.SONo && m.PalletNo == palletNo);
                    if (allot2 == null)
                    {
                        //添加分配表信息
                        var addAllot = new BllExportAllot
                        {
                            SONo = notice.SONo,
                            WaveNo = "",
                            SODetailNo = noticeDetail.Id,
                            StockId = stockDetail.Id,
                            LotNo = stockDetail.LotNo,
                            LotText = stockDetail.LotText,
                            SupplierLot = stockDetail.SupplierLot,
                            SkuNo = sku.SkuNo,
                            SkuName = sku.SkuName,
                            Standard = sku.Standard,
                            PalletNo = palletNo,
                            IsBale = "0", //是否裹包
                            IsBelt = "0", //是否打带
                        CreateUser = userId,
                        CreateTime = DateTime.Now
                    };
                    Db.Insertable(allot).ExecuteCommand();
                            Qty = 0,
                            CompleteQty = 0,
                            Status = "5",
                            LogisticsId = notice.LogisticsId,
                            IsAdvance = "0",
                            OutMode = "",//出库口
                            CreateUser = userId,
                            UpdateTime = DateTime.Now
                        };
                        var fp = Db.Insertable(addAllot).ExecuteReturnEntity();
                        allot2 = fp;
                    }
                    //获取当前托盘拣货明细
                    var complete = Db.Queryable<BllCompleteDetail>().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.ExportAllotId == allot2.Id && a.StockId == stockDetail.Id);
                    //判读是否存在拣货明细
                    int isComplete = 0;
                    if (complete != null)
                    {
                        isComplete = 1;
                    }
                    var comList = new List<BllCompleteDetail>();
                    //判断是否存在拣货明细
                    if (isComplete == 0)
                    {
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
                            SONo = notice.SONo,
                            SODetailNo = noticeDetail.Id,
                            ExportAllotId = allot2.Id,
                            StockId = allot2.StockId,
                            BoxNo = "",
                            BoxNo2 = "",
                            BoxNo3 = "",
                            LotNo = allot2.LotNo,
                            LotText = allot2.LotText,
                            SupplierLot = allot2.SupplierLot,
                            SkuNo = allot2.SkuNo,
                            SkuName = allot2.SkuName,
                            Standard = allot2.Standard,
                            PalletNo = palletNo,
                            CompleteQty = decimal.Parse(PickQty),
                            InspectMark = "1",
                            CreateUser = userId
                        };
                        comList.Add(completeDetail);
                        //添加拣货明细
                        Db.Insertable(comList).ExecuteCommand();
                    }
                    else if (isComplete == 1)
                    {
                        complete.CompleteQty += decimal.Parse(PickQty);
                        complete.UpdateUser = userId;
                        complete.UpdateTime = Db.GetDate();
                        Db.Updateable(complete).ExecuteCommand();
                    }
                    //修改出库分配信息
                    allot2.Qty += decimal.Parse(PickQty);
                    allot2.CompleteQty += decimal.Parse(PickQty);
                    Db.Updateable(allot2).ExecuteCommand();
                    int isDel = 0;
                    //删除或修改库存明细
                    stockDetail.BitPalletMark = "1";//修改为零托标识
                    stockDetail.InspectMark = "1";//修改为抽检托标识
                    stockDetail.Qty -= decimal.Parse(PickQty);
                    if (stockDetail.Qty == stockDetail.LockQty && stockDetail.Qty != 0)
                    {
                        stockDetail.Status = "2";
                    }
                    else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0)
                    {
                        stockDetail.Status = "1";
                    }
                    else
                    {
                        stockDetail.Status = "0";
                    }
                    if (stockDetail.Qty <= 0)
                    {
                        Db.Deleteable(stockDetail).ExecuteCommand();
                    }
                    else
                    {
                        isDel = 1;
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                    //删除或修改库存
                    stock.Qty -= int.Parse(PickQty);
                    if (stock.Qty <= 0)
                    {
                        Db.Deleteable(stock).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stock).ExecuteCommand();
                    }
                    //改变托盘状态为:未使用
                    var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                    if (pallet == null)
                    {
                        throw new Exception("未在托盘表中查询到托盘信息");
                    }
                    //判断托盘上物料是否拣货完毕
                    if (isDel == 0)
                    {
                        pallet.Status = "0";
                        Db.Updateable(pallet).ExecuteCommand();
                    }
                    //修改出库单明细拣货数量
                    noticeDetail.Qty += decimal.Parse(PickQty);
                    noticeDetail.AllotQty += decimal.Parse(PickQty);
                    noticeDetail.FactQty += decimal.Parse(PickQty);
                    noticeDetail.CompleteQty += decimal.Parse(PickQty);
                    noticeDetail.Money = string.IsNullOrWhiteSpace(sku.Price.ToString()) ? null : sku.Price * noticeDetail.Qty;
                    Db.Updateable(noticeDetail).ExecuteCommand();
                }
                else if (soType == "0")
                {
                    #region 判断
                    if (string.IsNullOrWhiteSpace(soNo))
                    {
                        throw new Exception("出库单据不能为空");
                    }
                    //if (string.IsNullOrWhiteSpace(soDetailId))
                    //{
                    //    throw new Exception("出库物料-批次不能为空");
                    //}
                    if (string.IsNullOrWhiteSpace(palletNo))
                    {
                        throw new Exception("托盘码不能为空");
                    }
                    //出库单
                    var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == soNo);
                    if (notice == null)
                    {
                        throw new Exception("未查询到该出库单的信息");
                    }
                    if (notice.Status != "3")
                    {
                        throw new Exception("出库单的状态不是正在执行,不能拣货");
                    }
                    //出库单明细
                    var noticeDetail = Db.Queryable<BllExportNoticeDetail>()
                        .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId));
                    if (noticeDetail == null)
                    {
                        throw new Exception("未查询到该出库单明细的信息");
                    }
                    //出库分配信息
                    var allot = Db.Queryable<BllExportAllot>().First(m =>
                        m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo &&
                        m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo);
                    if (allot == null)
                    {
                        throw new Exception("未查询到该托盘的分配信息");
                    }
                    //剩余拣货数量(待拣减去已拣)
                    var needQty = allot.Qty - allot.CompleteQty;
                    if (decimal.Parse(PickQty) > needQty)
                    {
                        throw new Exception("拣货数量不能大于托内剩余待拣数量");
                    }
                    //库存明细
                    var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.Id == allot.StockId);
                    if (stockDetail == null)
                    {
                        throw new Exception("未查询到该托盘分配的库存明细信息!");
                    }
                    //库存总表
                    var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                    if (stock == null)
                    {
                        throw new Exception("未查询到该托盘分配的库存信息!");
                    }
                    #endregion
                    #region 添加出库任务信息
                    //获取当前托盘拣货明细
                    var complete = Db.Queryable<BllCompleteDetail>().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.ExportAllotId == allot.Id && a.StockId == stockDetail.Id);
                    var taskNo = new Common().GetMaxNo("TK");
                    var exTask = new LogTask    //出库任务
                    //判读是否存在拣货明细
                    int isComplete = 0;
                    if (complete != null)
                    {
                        TaskNo = taskNo,
                        Sender = "WMS",
                        Receiver = "PDA",
                        IsSuccess = 1, //是否下发成功 0失败 1成功
                        StartLocat = locat == null ? "零箱库" : s.LocatNo,//起始位置
                        EndLocat = model.OutMode,//目标位置
                        PalletNo = s.PalletNo,//托盘码
                        IsSend = 1,//是否可再次下发
                        IsCancel = 1,//是否可取消
                        IsFinish = 1,//是否可完成
                        Type = "1",//任务类型 0 入库任务 1 出库任务  2 移库任务
                        Status = "1",//任务状态0:等待执行1正在执行2执行完成
                        OrderType = "1",//0 入库单 1 出库单  2 盘点单  3 移库单
                        CreateTime = serverTime, //创建时间
                        CreateUser = userId, //创建人
                        Msg = "Pda空托从" + locat == null ? "零箱库" : s.LocatNo + "到" + model.OutMode + "的出库任务", //关键信息
                        //FinishDate = serverTime, //完成时间
                    };
                    outDtoList.Add(new OutCommandDto()
                    {
                        PalletNo = exTask.PalletNo,//托盘号
                        StartLocate = exTask.StartLocat, // 起始位置
                        StartRoadway = locat.RoadwayNo, //所属巷道
                        EndLocate = "", // 目标位置
                        TaskNo = exTask.TaskNo, // 任务号
                        TaskType = "1",// 任务类型 (出库)
                        OutMode = model.OutMode,  //目标地址
                        Order = 1
                    });
                    Db.Insertable(exTask).ExecuteCommand();
                    #endregion
                    i += 1;
                    if (i == int.Parse(model.Num))
                    {
                        //需求垛数已达到 可以出库了
                        break;
                        isComplete = 1;
                    }
                }
                if (outDtoList.Count > 0)
                {
                    // 正式运行程序放开
                    var list2 = outDtoList.Select(m => m.TaskNo).ToList();
                    var jsonData = JsonConvert.SerializeObject(outDtoList);
                    string response = "";
                    try
                    var comList = new List<BllCompleteDetail>();
                    //判断是否存在拣货明细
                    if (isComplete == 0)
                    {
                        var time1 = DateTime.Now;//发送时间 .ToString("yyyy-MM-dd HH:mm:ss")
                        response = HttpHelper.DoPost(url, jsonData, "下发给WCS出库命令", "WCS");
                        var time2 = DateTime.Now;//返回时间 .ToString("yyyy-MM-dd HH:mm:ss")
                        ////解析返回数据
                        var wcsModel = JsonConvert.DeserializeObject<WcsModel>(response);
                        if (wcsModel.StatusCode == 0)
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
                            //更改任务的发送返回时间//
                            new TaskServer().EditTaskIssueOk(list2, time1, time2);
                                str += "下发成功";
                        }
                        if (wcsModel.StatusCode == -1)
                        {
                            new TaskServer().EditTaskIssueNo(list2, time1, time2, wcsModel.Msg);
                            throw new Exception(wcsModel.Msg);
                        }
                            SONo = soNo,
                            SODetailNo = int.Parse(soDetailId),
                            ExportAllotId = allot.Id,
                            StockId = allot.StockId,
                            BoxNo = "",
                            BoxNo2 = "",
                            BoxNo3 = "",
                            LotNo = allot.LotNo,
                            LotText = allot.LotText,
                            SupplierLot = allot.SupplierLot,
                            SkuNo = allot.SkuNo,
                            SkuName = allot.SkuName,
                            Standard = allot.Standard,
                            PalletNo = palletNo,
                            CompleteQty = decimal.Parse(PickQty),
                            CreateUser = userId,
                            CreateTime = Db.GetDate(),
                        };
                        comList.Add(completeDetail);
                        //添加拣货明细
                        Db.Insertable(comList).ExecuteCommand();
                    }
                    catch (Exception ex)
                    else if (isComplete == 1)
                    {
                        throw new Exception(ex.Message);
                        complete.CompleteQty += decimal.Parse(PickQty);
                        complete.UpdateUser = userId;
                        complete.UpdateTime = Db.GetDate();
                        Db.Updateable(complete).ExecuteCommand();
                    }
                    //修改出库分配信息
                    allot.CompleteQty += decimal.Parse(PickQty);
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.UpdateTime = DateTime.Now;
                    Db.Updateable(allot).ExecuteCommand();
                    int isDel = 0;
                    //删除或修改库存明细
                    stockDetail.BitPalletMark = "1";//修改为零托标识
                    stockDetail.Qty -= decimal.Parse(PickQty);
                    stockDetail.LockQty -= decimal.Parse(PickQty);
                    if (stockDetail.Qty == stockDetail.LockQty)
                    {
                        stockDetail.Status = "2";
                    }
                    else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0)
                    {
                        stockDetail.Status = "1";
                    }
                    else
                    {
                        stockDetail.Status = "0";
                    }
                    if (stockDetail.Qty <= 0)
                    {
                        Db.Deleteable(stockDetail).ExecuteCommand();
                    }
                    else
                    {
                        isDel = 1;
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                    //删除或修改库存
                    stock.Qty -= decimal.Parse(PickQty);
                    stock.LockQty -= decimal.Parse(PickQty);
                    if (stock.Qty <= 0)
                    {
                        Db.Deleteable(stock).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stock).ExecuteCommand();
                    }
                    //改变托盘状态为:未使用
                    var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                    if (pallet == null)
                    {
                        throw new Exception("未在托盘表中查询到托盘信息");
                    }
                    //判断托盘上物料是否拣货完毕
                    if (isDel == 0)
                    {
                        pallet.Status = "0";
                        Db.Updateable(pallet).ExecuteCommand();
                    }
                    //修改出库单明细拣货数量
                    noticeDetail.CompleteQty += decimal.Parse(PickQty);
                    Db.Updateable(noticeDetail).ExecuteCommand();
                    var num = Db.Queryable<BllExportNoticeDetail>()
                        .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty);
                    if (num <= 0)
                    {
                        notice.Status = "4"; //更改为执行完成
                    }
                    //修改出库单信息
                    Db.Updateable(notice).ExecuteCommand();
                }
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "空托出库", i+"", "下发", $"用PDA下发了 {i} 个空托垛", userId);
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货出库", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo}的拣货操作", userId);
                Db.CommitTran();
                return "";
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        //获取平库托盘信息
        public List<BoxInfo> GetPingKuInfoByPallet(string soNo, string palletNo)
        {
            try
            {
                var info = Db.Queryable<BllExportAllot>().Where(m => m.SONo == soNo && m.PalletNo == palletNo && m.IsDel == "0");
                if (info.Count() == 0)
                {
                    throw new Exception("未查询到托盘分配下发的信息");
                }
                var data = info.GroupBy(m => new { m.SkuNo, m.SkuName, m.LotNo }).Select(m => new BoxInfo()
                {
                    SkuNo = m.SkuNo,
                    SkuName = m.SkuName,
                    LotNo = m.LotNo
                }).ToList();
                return data;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        #region 拣货拼托
        /// <summary>
        /// 平库出库完成
        /// 拼托出库pda拣货-标签
        /// </summary>
        /// <param name="soNo">单据号</param>
        /// <param name="palletNo">托盘码</param>
        /// <param name="userId">操作人</param>
        public void PlaneExportSuccess(string soNo, string palletNo, int userId)
        /// <param name="soNo"></param>
        /// <param name="soDetailId"></param>
        /// <param name="palletNo"></param>
        /// <param name="boxNo"></param>
        /// <param name="boxNo3"></param>
        /// <param name="pickQty1"></param>
        /// <param name="palletNoNew"></param>
        /// <param name="userId"></param>
        public void SoSetPinPick(string soNo, string soDetailId, string palletNo, string boxNo, string boxNo3, string pickQty1, string palletNoNew, int userId)
        {
            Db.BeginTran();
            try
            {
                #region 托盘信息
                var nowDate = DateTime.Now;//当前时间
                #region 判断
                //获取托盘信息
                var pallet = Db.Queryable<SysPallets>().First(p => p.IsDel == "0" && p.PalletNo == palletNo);
                //验证托盘信息是否为空
                if (pallet == null)
                if (string.IsNullOrWhiteSpace(soNo))
                {
                    throw new Exception("托盘信息不存在,请检查!");
                    throw new Exception("出库单据不能为空");
                }
                if (pallet.Status == "0")
                if (string.IsNullOrWhiteSpace(soDetailId))
                {
                    throw new Exception("托盘未使用,请检查!");
                    throw new Exception("出库物料-批次不能为空");
                }
                #endregion
                #region 托盘是否在平库验证
                var result = Db.Queryable<DataStockDetail>().First(m => m.PalletNo == palletNo);
                if (result == null)
                if (string.IsNullOrWhiteSpace(palletNo))
                {
                    throw new Exception("库存信息中不存在该托盘信息,请检查!");
                    throw new Exception("托盘码不能为空");
                }
                if (!string.IsNullOrEmpty(boxNo3) && !string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)
                {
                    throw new Exception("追溯条码和拣货数量不能同时输入");
                }
                if (string.IsNullOrWhiteSpace(palletNoNew))
                {
                    throw new Exception("新托盘码不能为空");
                }
                if (palletNo == palletNoNew)//原托盘与新托盘一致
                {
                    if (!string.IsNullOrEmpty(boxNo))
                    {
                        throw new Exception("原托盘与新托盘一致,请选择整托出库");
                    }
                }
                if (result.WareHouseNo!="W02")//W02:零箱库
                //出库单
                var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == soNo);
                if (notice == null)
                {
                    throw new Exception("该托盘未在零箱库,请检查!");
                    throw new Exception("未查询到该出库单的信息");
                }
                if (notice.Type != "1" && notice.Type != "2" && notice.Type != "3")
                {
                    if (notice.Status != "3")
                    {
                        throw new Exception("出库单的状态不是正在执行,不能拣货");
                    }
                }
                //出库单明细
                var noticeDetail = Db.Queryable<BllExportNoticeDetail>()
                    .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId));
                if (noticeDetail == null)
                {
                    throw new Exception("未查询到该出库单明细的信息");
                }
                //出库分配信息
                var allot = Db.Queryable<BllExportAllot>().First(m =>
                    m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo &&
                    m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo);
                if (allot == null)
                {
                    throw new Exception("未查询到该托盘的分配信息");
                }
                //剩余拣货数量(待拣减去已拣)
                var needQty = allot.Qty - allot.CompleteQty;
                #endregion
                //获取库存明细信息
                var stockDetail = Db.Queryable<DataStockDetail>().Where(s => s.IsDel == "0" &&  s.PalletNo == palletNo).ToList();
                //验证库存明细信息是否存在
                //库存明细
                var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.Id == allot.StockId);
                if (stockDetail == null)
                {
                    throw new Exception("库存明细不存在,请检查库存信息!");
                    throw new Exception("未查询到该托盘分配的库存明细信息!");
                }
                //库存总表
                var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                if (stock == null)
                {
                    throw new Exception("未查询到该托盘分配的库存信息!");
                }
                Db.BeginTran();
                #endregion
                try
                #region 拼托信息
                var sdId = 0;
                bool isNew = false;
                var pinStockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew);
                if (pinStockDetail != null)
                {
                    foreach (var item in stockDetail)
                    if (palletNo != palletNoNew)//非整托拣货
                    {
                        if (item.SkuNo == "100099")//判断是否是空托出库
                        if (pinStockDetail.SONo != notice.SONo)
                        {
                            //判断总库存是否为0,如果为0删除 否则减去数量
                            var stock = Db.Queryable<DataStock>().First(m => m.SkuNo == "100099");
                            if (stock != null)
                            {
                                if (item.LockQty != null)
                                {
                                    stock.Qty -= item.LockQty.Value;
                                    stock.LockQty -= item.LockQty.Value;
                                    Db.Updateable(stock).ExecuteCommand();
                                }
                                if (stock.Qty == 0)
                                {
                                    Db.Deleteable(stock).ExecuteCommand();
                                }
                            }
                            //托盘状态改为未使用
                            var sCode = Db.Queryable<SysPallets>().First(m => m.PalletNo == item.PalletNo);
                            if (sCode != null)
                            {
                                sCode.Status = "0";
                                Db.Updateable(sCode).ExecuteCommand();
                            }
                            Db.Deleteable(item).ExecuteCommand();
                            continue;
                            throw new Exception("拼托托盘上只能放同一个出库单下的物料!");
                        }
                        item.LocatNo = "";//储位更改(改为空)
                        item.WareHouseNo = "";//所属仓库更改(改为空)
                        item.RoadwayNo = "";//所属巷道更改(改为空)
                        item.AreaNo = "";//所属区域更改(改为空)
                        Db.Updateable(item).ExecuteCommand();
                        if (pinStockDetail.SkuName != stockDetail.SkuName || pinStockDetail.LotNo != stockDetail.LotNo)
                        {
                            isNew = true;
                        }
                    }
                    //出库流水(更改状态)
                    var allot = Db.Queryable<BllExportAllot>().Where(m => m.IsDel == "0" && m.Status == "1" && m.PalletNo == palletNo && m.SONo == soNo).ToList();
                    sdId = pinStockDetail.Id;
                }
                else
                {
                    isNew = true;
                    foreach (var item in allot)
                    var newPalletInfo = Db.Queryable<SysPallets>().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew && m.Status == "0");
                    if (newPalletInfo == null)
                    {
                        if (item.SkuNo == "100099")
                        throw new Exception("新托盘信息不存在或已被使用!");
                    }
                    //修改新托盘状态
                    newPalletInfo.Status = "1";
                    Db.Updateable(newPalletInfo).ExecuteCommand();
                }
                var sd = new DataStockDetail();
                if (isNew)
                {
                    sd.LotNo = stockDetail.LotNo;
                    sd.LotText = stockDetail.LotText;
                    sd.SupplierLot = stockDetail.SupplierLot;
                    sd.SkuNo = stockDetail.SkuNo;
                    sd.SkuName = stockDetail.SkuName;
                    sd.Standard = stockDetail.Standard;
                    sd.FrozenQty = 0;
                    sd.InspectQty = 0;
                    sd.ASNNo = "";
                    sd.ASNDetailNo = null;
                    sd.SONo = soNo;//出库单号
                    sd.WareHouseNo = "";
                    sd.RoadwayNo = "";
                    sd.AreaNo = "";
                    sd.LocatNo = "";
                    sd.PalletNo = palletNoNew;
                    sd.PalletNo2 = "";
                    sd.PalletNo3 = "";
                    //PalletType = item.PalletType,
                    sd.CompleteTime = nowDate;
                    sd.ProductionTime = stockDetail.ProductionTime;
                    sd.ExpirationTime = stockDetail.ExpirationTime;
                    sd.Status = "2";//状态,已分配
                    sd.InspectMark = stockDetail.InspectMark;
                    sd.InspectStatus = stockDetail.InspectStatus;
                    sd.BitPalletMark = "0";
                    sd.PackagNo = noticeDetail.PackagNo;
                    sd.IsBale = stockDetail.IsBale;
                    sd.IsBelt = stockDetail.IsBelt;
                    sd.Demo = stockDetail.Demo;
                    sd.OwnerName = stockDetail.OwnerName;
                    sd.OwnerNo = stockDetail.OwnerNo;
                    sd.SupplierName = stockDetail.SupplierName;
                    sd.SupplierNo = stockDetail.SupplierNo;
                    sd.IsDel = "0";
                    sd.CreateUser = userId;
                    sd.CreateTime = nowDate;
                    //新增拼托库存明细信息
                    sdId = Db.Insertable(sd).ExecuteReturnIdentity();
                }
                #endregion
                decimal pickQty = 0;//拣货的数量
                if (string.IsNullOrWhiteSpace(boxNo))//整托拣货
                {
                    List<DataBoxInfo> boxInfos;
                    var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.PalletNo == palletNo);//找到托盘上所有箱码
                    boxInfos = boxInfo.ToList();
                    if (boxInfo.Count() <= 0)
                    {
                        throw new Exception("该托盘上没有可拣货的箱子");
                    }
                    var boxQty = boxInfo.GroupBy(m => m.PalletNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList();
                    if (boxQty[0] > needQty)
                    {
                        throw new Exception("拣货数量不能大于箱内剩余待拣数量");
                    }
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList();
                    var comList = new List<BllCompleteDetail>();
                    foreach (var item in boxInfos)
                    {
                        if (comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                        {
                            item.Status = "5";
                            item.CompleteQty += stockDetail[0].Qty;
                            throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                        }
                        else
                        if (item.SkuNo != allot.SkuNo || item.LotNo != allot.LotNo)
                        {
                            item.Status = "2";
                            throw new Exception("当前托盘上有其他不同物料批次,拣货失败");
                        }
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
                            SONo = soNo,
                            SODetailNo = int.Parse(soDetailId),
                            ExportAllotId = allot.Id,
                            StockId = allot.StockId,
                            BoxNo = item.BoxNo,
                            BoxNo2 = item.BoxNo2,
                            BoxNo3 = item.BoxNo3,
                            LotNo = allot.LotNo,
                            LotText = allot.LotText,
                            SupplierLot = allot.SupplierLot,
                            SkuNo = allot.SkuNo,
                            SkuName = allot.SkuName,
                            Standard = allot.Standard,
                            PalletNo = palletNo,
                            CompleteQty = item.Qty,
                            CreateUser = userId
                        };
                        comList.Add(completeDetail);
                        if (palletNo != palletNoNew)
                        {
                            item.StockDetailId = sdId;
                            item.BindNo = null;//托盘绑定号
                            item.PalletNo = palletNoNew;
                        }
                        item.Status = "5";//箱支状态,0:未组托  1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货
                        //修改库存箱码明细
                        Db.Updateable(item).ExecuteCommand();
                        pickQty += item.Qty;
                    }
                    //添加拣货明细
                    Db.Insertable(comList).ExecuteCommand();
                    //修改出库分配信息
                    allot.CompleteQty += pickQty;
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.UpdateTime = DateTime.Now;
                    Db.Updateable(allot).ExecuteCommand();
                    if (palletNo != palletNoNew)
                    {
                        //删除原托盘库存明细
                        Db.Deleteable(stockDetail).ExecuteCommand();
                        //改变原托盘状态为:未使用
                        var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                        if (pallet == null)
                        {
                            throw new Exception("未在托盘表中查询到托盘信息");
                        }
                        pallet.Status = "0";
                        Db.Updateable(pallet).ExecuteCommand();
                    }
                    else
                    {
                        stockDetail.SONo = soNo;
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                    //修改出库单明细拣货数量
                    noticeDetail.CompleteQty += pickQty;
                    noticeDetail.Status = "2";
                    Db.Updateable(noticeDetail).ExecuteCommand();
                    var num = Db.Queryable<BllExportNoticeDetail>()
                        .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty);
                    if (num <= 0)
                    {
                        notice.Status = "4"; //更改为执行完成
                        noticeDetail.Status = "3";
                        Db.Updateable(noticeDetail).ExecuteCommand();
                    }
                    //修改出库单信息
                    Db.Updateable(notice).ExecuteCommand();
                }
                else
                {
                    var biaoShi = "0";//0:整箱拣货、1:散支拣货、2:数量拣货
                    List<DataBoxInfo> boxInfos;
                    var boxInfo = Db.Queryable<DataBoxInfo>().Where(m => m.IsDel == "0" && m.BoxNo == boxNo && m.StockDetailId == stockDetail.Id);
                    if (boxInfo.Count() == 0)
                    {
                        throw new Exception("未查询到该箱码及追溯码的信息");
                    }
                    boxInfos = boxInfo.ToList();
                    var comDetailList = Db.Queryable<BllCompleteDetail>().Where(m => m.IsDel == "0" && m.ExportAllotId == allot.Id && m.PalletNo == palletNo).ToList();
                    if (!string.IsNullOrWhiteSpace(boxNo3)) //散支拣货
                    {
                        boxInfos = boxInfos.Where(m => m.BoxNo3 == boxNo3).ToList();
                        if (boxInfos.Count() == 0)
                        {
                            throw new Exception("未查询到该箱码及追溯码的信息");
                        }
                        if (boxInfos.Count() > 1)
                        {
                            throw new Exception("该追溯支码的信息大于1条,信息错误,请核实!");
                        }
                        if (boxInfos.Any(m => m.PalletNo != palletNo))
                        {
                            throw new Exception("该托盘与箱码没有绑定关系");
                        }
                        var boxQty = boxInfos.First().Qty;
                        if (boxQty > needQty)
                        {
                            throw new Exception("拣货数量不能大于剩余待拣数量");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo3 == item.BoxNo3))
                            {
                                throw new Exception($"当前{item.BoxNo}中{item.BoxNo3}已拣货完成,请勿重复拣货");
                            }
                        }
                        biaoShi = "1";
                    }
                    else if (!string.IsNullOrEmpty(pickQty1) && decimal.Parse(pickQty1) > 0)//数量拣货
                    {
                        if (boxInfo.Count() > 1)
                        {
                            throw new Exception("该箱码内存在支码不能进行数量拣货");
                        }
                        decimal boxQty = boxInfo.First().Qty;
                        if (Convert.ToInt32(pickQty1) > boxQty)
                        {
                            throw new Exception("拣货数量不能大于箱内数量");
                        }
                        if (Convert.ToInt32(pickQty1) > needQty)
                        {
                            throw new Exception("拣货数量不能大于剩余待拣数量");
                        }
                        biaoShi = "2";
                    }
                    else //整箱拣货
                    {
                        if (boxInfo.Count() == 0)
                        {
                            throw new Exception("未查询到该箱码的信息");
                        }
                        if (boxInfo.Any(m => m.PalletNo != palletNo))
                        {
                            throw new Exception("该托盘与箱码没有绑定关系");
                        }
                        var boxQty = boxInfo.GroupBy(m => m.BoxNo).Select(m => SqlFunc.AggregateSum(m.Qty)).ToList();
                        if (boxQty[0] > needQty)
                        {
                            throw new Exception("拣货数量不能大于箱内剩余待拣数量");
                        }
                        foreach (var item in boxInfos)
                        {
                            if (biaoShi != "2" && comDetailList.Any(m => m.BoxNo == item.BoxNo))
                            {
                                throw new Exception($"当前{item.BoxNo}已拣货完成,请勿重复拣货");
                            }
                        }
                    }
                    var comList = new List<BllCompleteDetail>();
                    foreach (var item in boxInfos)
                    {
                        //添加拣货明细
                        var completeDetail = new BllCompleteDetail()
                        {
                            SONo = soNo,
                            SODetailNo = int.Parse(soDetailId),
                            ExportAllotId = allot.Id,
                            StockId = allot.StockId,
                            BoxNo = item.BoxNo,
                            BoxNo2 = item.BoxNo2,
                            BoxNo3 = item.BoxNo3,
                            LotNo = allot.LotNo,
                            LotText = allot.LotText,
                            SupplierLot = allot.SupplierLot,
                            SkuNo = allot.SkuNo,
                            SkuName = allot.SkuName,
                            Standard = allot.Standard,
                            PalletNo = palletNo,
                            CompleteQty = biaoShi == "2" ? decimal.Parse(pickQty1) : item.Qty,
                            CreateUser = userId
                        };
                        comList.Add(completeDetail);
                        if (biaoShi == "0")//整箱拣货
                        {
                            //修改库存箱码明细
                            item.StockDetailId = sdId;
                            item.BindNo = null;//托盘绑定号
                            item.PalletNo = palletNoNew;
                            item.Status = "5";//箱支状态,0:未组托  1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货
                            Db.Updateable(item).ExecuteCommand();
                            pickQty += item.Qty;
                        }
                        else if (biaoShi == "1")//散支拣货
                        {
                            //修改库存箱码明细
                            item.StockDetailId = sdId;
                            item.BindNo = null;//托盘绑定号
                            item.PalletNo = palletNoNew;
                            item.BoxNo = item.BoxNo3;//将支码赋给箱码
                            item.BitBoxMark = "1";//零箱标记
                            item.Status = "5";//箱支状态,0:未组托  1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货
                            Db.Updateable(item).ExecuteCommand();
                            pickQty += item.Qty;
                        }
                        else//数量拣货
                        {
                            var boxInfo2 = Db.Queryable<DataBoxInfo>().First(m => m.IsDel == "0" && m.BoxNo == boxNo && m.StockDetailId == sdId);
                            if (decimal.Parse(pickQty1) == item.Qty)
                            {
                                //修改库存箱码明细
                                item.StockDetailId = sdId;
                                item.BindNo = null;//托盘绑定号
                                item.PalletNo = palletNoNew;
                                item.Status = "5";//箱支状态,0:未组托  1:已组托 2:已入库 3:已出库 4:已分配 5:已拣货
                                Db.Updateable(item).ExecuteCommand();
                            }
                            else
                            {
                                if (boxInfo2 == null)
                                {
                                    var dataBoxInfo = new DataBoxInfo()
                                    {
                                        StockDetailId = sdId,
                                        BindNo = item.BindNo,
                                        BoxNo = item.BoxNo,
                                        BoxNo2 = item.BoxNo2,
                                        BoxNo3 = item.BoxNo3,
                                        PalletNo = item.PalletNo,
                                        PalletNo2 = item.PalletNo2,
                                        PalletNo3 = item.PalletNo3,
                                        Qty = decimal.Parse(pickQty1),
                                        FullQty = item.FullQty,
                                        Status = "5",
                                        LotNo = item.LotNo,
                                        LotText = item.LotText,
                                        SkuNo = item.SkuNo,
                                        SkuName = item.SkuName,
                                        Standard = item.Standard,
                                        ProductionTime = item.ProductionTime,
                                        SupplierLot = item.SupplierLot,
                                        InspectMark = item.InspectMark,
                                        BitBoxMark = "1",
                                        InspectStatus = item.InspectStatus,
                                        InspectTime = item.InspectTime,
                                    };
                                    Db.Insertable(dataBoxInfo).ExecuteCommand();
                                }
                                else
                                {
                                    boxInfo2.Qty += decimal.Parse(pickQty1);
                                    item.BitBoxMark = boxInfo2.Qty>= boxInfo2.FullQty? "0":"1" ;//零箱标识
                                    Db.Updateable(boxInfo2).ExecuteCommand();
                                }
                                item.Qty -= decimal.Parse(pickQty1);
                                item.BitBoxMark = "1";//零箱标识
                                if (item.Qty<=0)
                                {
                                    Db.Deleteable(item).ExecuteCommand();
                                }
                                else
                                {
                                    Db.Updateable(item).ExecuteCommand();
                                }
                            }
                            pickQty += decimal.Parse(pickQty1);
                        }
                    }
                    //改变库内箱码是否零箱信息
                    if (biaoShi == "1")
                    {
                        var boxSurplusList = boxInfo.Where(m => m.BoxNo3 != boxNo3).ToList();
                        foreach (var item in boxSurplusList)
                        {
                            item.BitBoxMark = "1";
                            Db.Updateable(item).ExecuteCommand();
                        }
                    }
                    Db.Insertable(comList).ExecuteCommand();
                    //修改出库分配信息
                    allot.CompleteQty += pickQty;
                    allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                    allot.UpdateTime = DateTime.Now;
                    if (allot.Status == "5")
                    {
                        //判断该托盘是否还存在物料 存在改为待回库 待回库完成后改为已完成
                    }
                    Db.Updateable(allot).ExecuteCommand();
                    #region 添加出库操作日志记录信息
                    //删除或修改库存明细
                    stockDetail.BitPalletMark = "1";//修改为零托标识
                    stockDetail.Qty -= pickQty;
                    stockDetail.LockQty -= pickQty;
                    if (stockDetail.Qty == stockDetail.LockQty)
                    {
                        stockDetail.Status = "2";
                    }
                    else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0)
                    {
                        stockDetail.Status = "1";
                    }
                    else
                    {
                        stockDetail.Status = "0";
                    }
                    //添加操作日志记录
                    var k = new OperationSOServer().AddLogOperationSo("出库作业", "拣货明细", soNo, "完成", $"用PDA完成了单据号为{soNo}的平库出库", userId);
                    if (stockDetail.Qty <= 0)
                    {
                        Db.Deleteable(stockDetail).ExecuteCommand();
                    }
                    else
                    {
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                    var num2 = Db.Queryable<DataStockDetail>().Count(m => m.IsDel == "0" && m.PalletNo == palletNo);
                    if (num2 <= 0)
                    {
                        //改变托盘状态
                        var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                        if (pallet == null)
                        {
                            throw new Exception("未在托盘表中查询到托盘信息");
                        }
                        pallet.Status = "0";
                        Db.Updateable(pallet).ExecuteCommand();
                    }
                    //修改出库单明细拣货数量
                    noticeDetail.CompleteQty += pickQty;
                    noticeDetail.Status = "2";
                    Db.Updateable(noticeDetail).ExecuteCommand();
                    #endregion
                    Db.CommitTran();
                    var num = Db.Queryable<BllExportNoticeDetail>()
                        .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty);
                    if (num <= 0)
                    {
                        notice.Status = "4"; //更改为执行完成
                        noticeDetail.Status = "3";
                        Db.Updateable(noticeDetail).ExecuteCommand();
                    }
                    //修改出库单信息
                    Db.Updateable(notice).ExecuteCommand();
                }
                catch (Exception e)
                if (isNew)
                {
                    Db.RollbackTran();
                    throw new Exception(e.Message);
                    var sd2 = Db.Queryable<DataStockDetail>().First(m=>m.Id == sdId);
                    sd2.Qty = pickQty;
                    sd2.LockQty = pickQty;
                    Db.Updateable(sd2).ExecuteCommand();
                }
                else
                {
                    if (palletNo != palletNoNew)
                    {
                        //修改拼托托盘库存明细
                        pinStockDetail.Qty += pickQty;
                        pinStockDetail.LockQty += pickQty;
                        Db.Updateable(pinStockDetail).ExecuteCommand();
                    }
                }
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货拼托", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的原托盘码为:{palletNo},新托盘码为:{palletNoNew}的拣货拼托操作", userId);
                Db.CommitTran();
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        /// <summary>
        /// 拼托出库pda拣货-数量
        /// </summary>
        /// <param name="soNo"></param>
        /// <param name="soDetailId"></param>
        /// <param name="palletNo"></param>
        /// <param name="PickQty"></param>
        /// <param name="palletNoNew"></param>
        /// <param name="userId"></param>
        public void SoSetQtyPinPick(string soNo, string soDetailId, string palletNo, string PickQty, string palletNoNew, int userId)
        {
            Db.BeginTran();
            try
            {
                var nowDate = DateTime.Now;//当前时间
                #region 判断
                if (string.IsNullOrWhiteSpace(soNo))
                {
                    throw new Exception("出库单据不能为空");
                }
                //if (string.IsNullOrWhiteSpace(soDetailId))
                //{
                //    throw new Exception("出库物料-批次不能为空");
                //}
                if (string.IsNullOrWhiteSpace(palletNo))
                {
                    throw new Exception("托盘码不能为空");
                }
                if (string.IsNullOrWhiteSpace(palletNoNew))
                {
                    throw new Exception("新托盘码不能为空");
                }
                //出库单
                var notice = Db.Queryable<BllExportNotice>().First(m => m.IsDel == "0" && m.SONo == soNo);
                if (notice == null)
                {
                    throw new Exception("未查询到该出库单的信息");
                }
                if (notice.Status != "3")
                {
                    throw new Exception("出库单的状态不是正在执行,不能拣货");
                }
                //出库单明细
                var noticeDetail = Db.Queryable<BllExportNoticeDetail>()
                    .First(m => m.IsDel == "0" && m.Id == int.Parse(soDetailId));
                if (noticeDetail == null)
                {
                    throw new Exception("未查询到该出库单明细的信息");
                }
                //出库分配信息
                var allot = Db.Queryable<BllExportAllot>().First(m =>
                    m.IsDel == "0" && (m.Status == "2" || m.Status == "3") && m.SONo == soNo &&
                    m.SODetailNo == int.Parse(soDetailId) && m.PalletNo == palletNo);
                if (allot == null)
                {
                    throw new Exception("未查询到该托盘的分配信息");
                }
                //剩余拣货数量(待拣减去已拣)
                var needQty = allot.Qty - allot.CompleteQty;
                if (decimal.Parse(PickQty) > needQty)
                {
                    throw new Exception("拣货数量不能大于托内剩余待拣数量");
                }
                //库存明细
                var stockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.Id == allot.StockId);
                if (stockDetail == null)
                {
                    throw new Exception("未查询到该托盘分配的库存明细信息!");
                }
                //库存总表
                var stock = Db.Queryable<DataStock>().First(a => a.IsDel == "0" && a.SkuNo == stockDetail.SkuNo && a.LotNo == stockDetail.LotNo);
                if (stock == null)
                {
                    throw new Exception("未查询到该托盘分配的库存信息!");
                }
                if (palletNo == palletNoNew)//原托盘与新托盘一致
                {
                    if (decimal.Parse(PickQty) != stockDetail.Qty)
                    {
                        throw new Exception("原托盘与新托盘一致,需要把托盘上所有数量拣货");
                    }
                }
                #endregion
                #region 拼托信息
                bool isNew = false;
                var pinStockDetail = Db.Queryable<DataStockDetail>().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew);
                if (pinStockDetail != null)
                {
                    if (palletNo != palletNoNew)//非整托拣货
                    {
                        if (pinStockDetail.SONo != notice.SONo)
                        {
                            throw new Exception("拼托托盘上只能放同一个出库单下的物料!");
                        }
                        if (pinStockDetail.SkuName != stockDetail.SkuName || pinStockDetail.LotNo != stockDetail.LotNo)
                        {
                            isNew = true;
                        }
                    }
                }
                else
                {
                    isNew = true;
                    var newPalletInfo = Db.Queryable<SysPallets>().First(m => m.IsDel == "0" && m.PalletNo == palletNoNew && m.Status == "0");
                    if (newPalletInfo == null)
                    {
                        throw new Exception("新托盘信息不存在或已被使用!");
                    }
                    //修改新托盘状态
                    newPalletInfo.Status = "1";
                    Db.Updateable(newPalletInfo).ExecuteCommand();
                }
                if (isNew)
                {
                    var sd = new DataStockDetail();
                    sd.LotNo = stockDetail.LotNo;
                    sd.LotText = stockDetail.LotText;
                    sd.SupplierLot = stockDetail.SupplierLot;
                    sd.SkuNo = stockDetail.SkuNo;
                    sd.SkuName = stockDetail.SkuName;
                    sd.Standard = stockDetail.Standard;
                    sd.Qty = decimal.Parse(PickQty);
                    sd.LockQty = decimal.Parse(PickQty);
                    sd.FrozenQty = 0;
                    sd.InspectQty = 0;
                    sd.ASNNo = "";
                    sd.ASNDetailNo = null;
                    sd.SONo = soNo;//出库单号
                    sd.WareHouseNo = "";
                    sd.RoadwayNo = "";
                    sd.AreaNo = "";
                    sd.LocatNo = "";
                    sd.PalletNo = palletNoNew;
                    sd.PalletNo2 = "";
                    sd.PalletNo3 = "";
                    //PalletType = item.PalletType,
                    sd.CompleteTime = nowDate;
                    sd.ProductionTime = stockDetail.ProductionTime;
                    sd.ExpirationTime = stockDetail.ExpirationTime;
                    sd.Status = "2";//状态,已分配
                    sd.InspectMark = stockDetail.InspectMark;
                    sd.InspectStatus = stockDetail.InspectStatus;
                    sd.BitPalletMark = "0";
                    sd.PackagNo = noticeDetail.PackagNo;
                    sd.IsBale = stockDetail.IsBale;
                    sd.IsBelt = stockDetail.IsBelt;
                    sd.Demo = stockDetail.Demo;
                    sd.OwnerName = stockDetail.OwnerName;
                    sd.OwnerNo = stockDetail.OwnerNo;
                    sd.SupplierName = stockDetail.SupplierName;
                    sd.SupplierNo = stockDetail.SupplierNo;
                    sd.IsDel = "0";
                    sd.CreateUser = userId;
                    sd.CreateTime = nowDate;
                    //新增拼托库存明细信息
                    Db.Insertable(sd).ExecuteReturnIdentity();
                }
                else
                {
                    if (palletNo != palletNoNew)
                    {
                        //修改拼托托盘库存明细
                        pinStockDetail.Qty += decimal.Parse(PickQty);
                        pinStockDetail.LockQty += decimal.Parse(PickQty);
                        Db.Updateable(pinStockDetail).ExecuteCommand();
                    }
                    else
                    {
                        pinStockDetail.SONo = soNo;
                        Db.Updateable(pinStockDetail).ExecuteCommand();
                    }
                }
                #endregion
                //获取当前托盘拣货明细
                var complete = Db.Queryable<BllCompleteDetail>().First(a => a.IsDel == "0" && a.PalletNo == palletNo && a.SONo == notice.SONo && a.SODetailNo == noticeDetail.Id && a.ExportAllotId == allot.Id && a.StockId == stockDetail.Id);
                //判读是否存在拣货明细
                int isComplete = 0;
                if (complete != null)
                {
                    isComplete = 1;
                }
                var comList = new List<BllCompleteDetail>();
                //判断是否存在拣货明细
                isComplete = 0;//所有无箱码或一级箱码拣货时,拣货明细应重新插入数据(体现多次拣货流程记录)
                if (isComplete == 0)
                {
                    //添加拣货明细
                    var completeDetail = new BllCompleteDetail()
                    {
                        SONo = soNo,
                        SODetailNo = int.Parse(soDetailId),
                        ExportAllotId = allot.Id,
                        StockId = allot.StockId,
                        BoxNo = "",
                        BoxNo2 = "",
                        BoxNo3 = "",
                        LotNo = allot.LotNo,
                        LotText = allot.LotText,
                        SupplierLot = allot.SupplierLot,
                        SkuNo = allot.SkuNo,
                        SkuName = allot.SkuName,
                        Standard = allot.Standard,
                        PalletNo = palletNo,
                        CompleteQty = decimal.Parse(PickQty),
                        CreateUser = userId,
                        CreateTime = Db.GetDate(),
                    };
                    comList.Add(completeDetail);
                    //添加拣货明细
                    Db.Insertable(comList).ExecuteCommand();
                }
                else if (isComplete == 1)
                {
                    complete.CompleteQty += decimal.Parse(PickQty);
                    complete.UpdateUser = userId;
                    complete.UpdateTime = Db.GetDate();
                    Db.Updateable(complete).ExecuteCommand();
                }
                //修改出库分配信息
                allot.CompleteQty += decimal.Parse(PickQty);
                allot.Status = allot.Qty == allot.CompleteQty ? "5" : "3";
                allot.UpdateTime = DateTime.Now;
                Db.Updateable(allot).ExecuteCommand();
                int isDel = 0;
                if (palletNo != palletNoNew)
                {
                    //删除或修改库存明细
                    stockDetail.BitPalletMark = "1";//修改为零托标识
                    stockDetail.Qty -= decimal.Parse(PickQty);
                    stockDetail.LockQty -= decimal.Parse(PickQty);
                    if (stockDetail.Qty == stockDetail.LockQty)
                    {
                        stockDetail.Status = "2";
                    }
                    else if (stockDetail.Qty > stockDetail.LockQty && stockDetail.LockQty > 0)
                    {
                        stockDetail.Status = "1";
                    }
                    else
                    {
                        stockDetail.Status = "0";
                    }
                    if (stockDetail.Qty <= 0)
                    {
                        Db.Deleteable(stockDetail).ExecuteCommand();
                    }
                    else
                    {
                        isDel = 1;
                        Db.Updateable(stockDetail).ExecuteCommand();
                    }
                }
                else
                {
                    isDel = 1;
                }
                //判断托盘上物料是否拣货完毕
                if (isDel == 0)
                {
                    //改变托盘状态为:未使用
                    var pallet = Db.Queryable<SysPallets>().First(m => m.PalletNo == palletNo && m.IsDel == "0");
                    if (pallet == null)
                    {
                        throw new Exception("未在托盘表中查询到托盘信息");
                    }
                    pallet.Status = "0";
                    Db.Updateable(pallet).ExecuteCommand();
                }
                //修改出库单明细拣货数量
                noticeDetail.CompleteQty += decimal.Parse(PickQty);
                noticeDetail.Status = "2";
                Db.Updateable(noticeDetail).ExecuteCommand();
                var num = Db.Queryable<BllExportNoticeDetail>()
                    .Count(m => m.IsDel == "0" && m.SONo == soNo && m.CompleteQty < m.Qty);
                if (num <= 0)
                {
                    notice.Status = "4"; //更改为执行完成
                    noticeDetail.Status = "3";
                    Db.Updateable(noticeDetail).ExecuteCommand();
                }
                //修改出库单信息
                Db.Updateable(notice).ExecuteCommand();
                //添加操作日志记录
                var k = new OperationSOServer().AddLogOperationSo("PDA模块", "拣货拼托", soNo, "拣货", $"在PDA上对出库单号为:{soNo}的托盘码为:{palletNo},新托盘码为:{palletNoNew}的拣货操作", userId);
                Db.CommitTran();
            }
            catch (Exception e)
            {
                Db.RollbackTran();
                throw new Exception(e.Message);
            }
        }
        #endregion
    }
}