yanjinhui
4 天以前 f42e4c5c9f91d983ae2e87d3b6b600d1c8e54087
н¨Îļþ¼Ð/WIDESEA_WMSServer/WIDESEA_SquareCabinServices/DeliveryOrderServices.cs
@@ -1,5 +1,10 @@
using HslCommunication;
using MailKit.Search;
using Microsoft.Data.SqlClient;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using OfficeOpenXml.Style;
using Org.BouncyCastle.Asn1.X509;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,7 +13,9 @@
using WIDESEA_Common;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.OrderEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
@@ -25,846 +32,787 @@
namespace WIDESEA_SquareCabinServices
{
    public class DeliveryOrderServices : ServiceBase<Dt_DeliveryOrder, IRepository<Dt_DeliveryOrder>>, IDeliveryOrderServices
    public partial class DeliveryOrderServices : ServiceBase<Dt_DeliveryOrder, IRepository<Dt_DeliveryOrder>>, IDeliveryOrderServices
    {
        static string SearchDate = "";
        private readonly IBasicService _basicService;
        private readonly ICabinOrderServices _cabinOrderServices;
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IInventory_BatchServices _inventory_BatchServices;
        private readonly ILocationInfoService _locationInfoService;
        private readonly IInventoryInfoService _inventoryInfoService;
        private readonly IDeliveryOrderDetailServices _deliveryOrderDetailServices;
        private readonly ISupplyTaskService _supplyTaskService;
        private readonly ISupplyTaskHtyService _supplyTaskHtyService;
        private readonly ITacticsService _tacticsService;
        private readonly IMaterielInfoService _materielInfoService;
        private readonly IMessageInfoService _messageInfoService;
        public IRepository<Dt_DeliveryOrder> Repository => BaseDal;
        public DeliveryOrderServices(IRepository<Dt_DeliveryOrder> BaseDal, IBasicService basicService, IUnitOfWorkManage unitOfWorkManage, IInventory_BatchServices inventory_BatchServices, IInventoryInfoService inventoryInfoService, IDeliveryOrderDetailServices deliveryOrderDetailServices, ISupplyTaskService supplyTaskService) : base(BaseDal)
        public DeliveryOrderServices(IRepository<Dt_DeliveryOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage, IInventory_BatchServices inventory_BatchServices, IInventoryInfoService inventoryInfoService, IDeliveryOrderDetailServices deliveryOrderDetailServices, ISupplyTaskService supplyTaskService, ICabinOrderServices cabinOrderServices, ITacticsService tacticsService, ISupplyTaskHtyService supplyTaskHtyService, IMessageInfoService messageInfoService, IMaterielInfoService materielInfoService, ILocationInfoService locationInfoService) : base(BaseDal)
        {
            _basicService = basicService;
            _unitOfWorkManage = unitOfWorkManage;
            _deliveryOrderDetailServices = deliveryOrderDetailServices;
            _supplyTaskService = supplyTaskService;
            _inventory_BatchServices = inventory_BatchServices;
            _inventoryInfoService = inventoryInfoService;
            _cabinOrderServices = cabinOrderServices;
            _tacticsService = tacticsService;
            _supplyTaskHtyService = supplyTaskHtyService;
            _messageInfoService = messageInfoService;
            _materielInfoService = materielInfoService;
            _locationInfoService = locationInfoService;
        }
        public override WebResponseContent UpdateData(SaveModel saveModel)
        {
            return base.UpdateData(saveModel);
        }
        #region åˆ›å»ºå‡ºåº“单
        /// <summary>
        /// èŽ·å–ä¸Šæ¸¸å‡ºåº“å• 0成功1失败
        /// åˆ›å»ºå‡ºåº“单
        /// </summary>
        /// <param name="searchDate"></param>
        /// <param name="outorder"></param>
        /// <returns></returns>
        //public WebResponseContent GetUpstreamOutOrder()
        //{
        //    var responseContent = new WebResponseContent();
        //    try
        //    {
        //        // è¯·æ±‚地址
        //        var url = "http://121.37.118.63:80/GYZ2/95fck/outOrder";
        //        //if (string.IsNullOrEmpty(SearchDate)) SearchDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        //        //// è¯·æ±‚参数
        //        var requestData = new
        //        {
        //            //searchDate = SearchDate
        //            searchDate = "2022-10-10 20:45:16"  // æ­£ç¡®çš„æ ¼å¼
        //        };
        //        //SearchDate = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd HH:mm:ss");
        //        // å‘起请求
        //        var result = HttpHelper.Post(url, requestData.ToJsonString());
        //        // ååºåˆ—化
        //        var response = JsonConvert.DeserializeObject<UpstreamResponse<UpstramOutOrderInfo>>(result);
        //        if (response.resultCode != "0")
        //        {
        //            SendErrorToUpstream(3, "", response.resultMsg ?? "上游接口返回失败", "");
        //            return responseContent.Error(response.resultMsg ?? "上游接口返回失败");
        //        }
        //        if (response.data == null || !response.data.Any())
        //        {
        //            return responseContent.OK("无新出库单数据");
        //        }
        //        // èŽ·å–æ‰€æœ‰å·²å­˜åœ¨çš„å‡ºåº“å•å·
        //        var existingOutOrderNos = BaseDal.Db.Queryable<Dt_DeliveryOrder>()
        //            .Select(x => x.Out_no)
        //            .ToList();
        //        // è¿‡æ»¤æŽ‰å·²å­˜åœ¨çš„出库单
        //        var newOutOrders = response.data
        //            .Where(outorder => !existingOutOrderNos.Contains(outorder.order_no))//order_no出库单号
        //            .ToList();
        //        if (!newOutOrders.Any())
        //        {
        //            return responseContent.OK("所有出库单已存在,无需新增");
        //        }
        //        Db.Ado.BeginTran();
        //        try
        //        {
        //            List<Dt_DeliveryOrder> _DeliveryOrders = new List<Dt_DeliveryOrder>();
        //            ////存储出库单号
        //            //List<string> orderNos = new List<string>();
        //            foreach (var outorder in newOutOrders)
        //            {
        //                var entityOrder = new Dt_DeliveryOrder
        //                {
        //                    Out_no = outorder.order_no,
        //                    Out_type = outorder.order_type,
        //                    Client_no = outorder.client_no,
        //                    Client_name = outorder.client_name,
        //                    Account_time = outorder.account_time,
        //                    Warehouse_no=outorder.warehouse_no,
        //                    OutStatus = "未完成",
        //                    //Details = outorder.details.Select(d => new Dt_DeliveryOrderDetail
        //                    //{
        //                    //    // InsertNav ä¼šè‡ªåŠ¨è®¾ç½®å…³è”å­—æ®µ DeliveryOrderId
        //                    //    Goods_no = d.goods_no,
        //                    //    Order_qty = d.order_qty,
        //                    //    Batch_num = d.batch_num,
        //                    //    Exp_date = d.exp_date,
        //                    //    OotDetailStatus = "新建",
        //                    //    Status = outorder.warehouse_no == "001" ? 0 : 2, //如果是001房那么将状态设置为0,2为人工处理
        //                    //}).ToList()
        //                };
        //                #region æ ¹æ®å‡ºåº“单详情查找物料名称、批次的库存信息(Dt_InventoryInfo);根据先入先出,CreateDate
        //                //根据物料名称查找物料信息
        //                foreach (var item in outorder.details)
        //                {
        //                    // å°†ä¸Šæ¸¸å‡ºåº“数量转为正数
        //                    item.order_qty = Math.Abs(item.order_qty);
        //                    var medication = BaseDal.Db.Queryable<Dt_MedicineGoods>()
        //                        .Where(m => m.Goods_no == item.goods_no)
        //                        .First();
        //                }
        //                //根据箱规判断是否有散件,计算出散件数量和整件数
        //                //根据入库时间分组,有散件就优先分配立库数量,整件优先分配平库数量
        //                #endregion
        //                _DeliveryOrders.Add(entityOrder);
        //            };
        //            // ä½¿ç”¨ InsertNav ä¸€æ¬¡æ€§æ’入主表和子表数据
        //            BaseDal.Db.InsertNav(_DeliveryOrders).Include(x => x.Details).ExecuteCommand();
        //            // è¿™é‡Œå¯ä»¥æ·»åŠ ä¸‹å‘åˆ° WCS çš„逻辑
        //            // var result = EdiOut(); // å‘给下游
        //            Db.Ado.CommitTran();
        //            return responseContent.OK("同步出库单成功");
        //        }
        //        catch (Exception ex)
        //        {
        //            Db.Ado.RollbackTran();
        //            SendErrorToUpstream(3, "", ex.Message, "");
        //            return responseContent.Error("同步失败: " + ex.Message);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        // å…¨å±€å¼‚常时,也推送异常给上游
        //        SendErrorToUpstream(3, "", ex.Message, "");
        //        return responseContent.Error("同步失败: " + ex.Message);
        //    }
        //}
        public WebResponseContent GetUpstreamOutOrder()
        public WebResponseContent CreateOutboundOrder(UpstramOutOrderInfo outorder)
        {
            var responseContent = new WebResponseContent();
            WebResponseContent webResponseContent = new WebResponseContent();
            try
            {
                var url = "http://121.37.118.63:80/GYZ2/95fck/outOrder";
                var requestData = new
                Dt_Tactics tactics = _tacticsService.Repository.QueryFirst(x => x.TacticeName == "出库策略");
                #region ç‰¹æ®Šåº“房出库
                string WareCodeMJ = WarehouseEnum.麻精库.ObjToInt().ToString("000");
                string WareCodeLD = WarehouseEnum.冷冻库.ObjToInt().ToString("000");
                if (outorder.warehouse_no == WareCodeMJ || outorder.warehouse_no == WareCodeLD)
                {
                    searchDate = "2022-10-10 20:45:16"
                };
                var result = HttpHelper.Post(url, requestData.ToJsonString());
                var response = JsonConvert.DeserializeObject<UpstreamResponse<UpstramOutOrderInfo>>(result);
                if (response.resultCode != "0")
                {
                    SendErrorToUpstream(3, "", response.resultMsg ?? "上游接口返回失败", "");
                    return responseContent.Error(response.resultMsg ?? "上游接口返回失败");
                }
                if (response.data == null || !response.data.Any())
                {
                    return responseContent.OK("无新出库单数据");
                }
                // å·²å­˜åœ¨å‡ºåº“单号
                var existingOutOrderNos = BaseDal.Db.Queryable<Dt_DeliveryOrder>()
                    .Select(x => x.Out_no)
                    .ToList();
                // æ–°å‡ºåº“单
                var newOutOrders = response.data
                    .Where(outorder => !existingOutOrderNos.Contains(outorder.order_no))
                    .ToList();
                if (!newOutOrders.Any())
                {
                    return responseContent.OK("所有出库单已存在,无需新增");
                }
                Db.Ado.BeginTran();
                try
                {
                    List<Dt_DeliveryOrder> _DeliveryOrders = new List<Dt_DeliveryOrder>();
                    foreach (var outorder in newOutOrders)
                    #region æ·»åŠ å‡ºåº“å•
                    var entityOrder = new Dt_DeliveryOrder
                    {
                        var entityOrder = new Dt_DeliveryOrder
                        Out_no = outorder.order_no,
                        Out_type = outorder.order_type,
                        Client_no = outorder.client_no,
                        Client_name = outorder.client_name,
                        Account_time = outorder.account_time,
                        Warehouse_no = outorder.warehouse_no,
                        OutStatus = "新建",
                        Details = outorder.details.Select(d => new Dt_DeliveryOrderDetail
                        {
                            Out_no = outorder.order_no,
                            Out_type = outorder.order_type,
                            Client_no = outorder.client_no,
                            Client_name = outorder.client_name,
                            Account_time = outorder.account_time,
                            Warehouse_no = outorder.warehouse_no,
                            OutStatus = "未完成",
                            Details = new List<Dt_DeliveryOrderDetail>()
                        };
                        // éåŽ†å‡ºåº“æ˜Žç»†
                        foreach (var item in outorder.details)
                            Reservoirarea = outorder.warehouse_no,
                            Goods_no = d.goods_no,
                            Order_qty = Math.Abs(d.order_qty), // å‡ºåº“数量转为正数
                            Batch_num = d.batch_num,
                            Exp_date = d.exp_date,
                            OotDetailStatus = "新建",
                            Status = 2, // pad平库,无需同步
                        }).ToList()
                    };
                    #endregion
                    #region å¤„理库存、库存批次、添加出库任务
                    List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
                    List<Dt_Inventory_Batch> batchesUp = new List<Dt_Inventory_Batch>();
                    List<Dt_InventoryInfo> inventoryInfosUp = new List<Dt_InventoryInfo>();
                    var inventory_Batchs = _inventory_BatchServices.Repository.QueryData(x => entityOrder.Details.Select(e => e.Goods_no).Contains(x.MaterielCode));
                    var InventoryInfos = _inventoryInfoService.Repository.QueryData(x => entityOrder.Details.Select(e => e.Goods_no).Contains(x.MaterielCode) && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.AvailableQuantity > 0 && x.WarehouseCode == outorder.warehouse_no);
                    foreach (var item in entityOrder.Details)
                    {
                        Dt_Inventory_Batch? inventory_Batch = inventory_Batchs.Where(x => x.MaterielCode == item.Goods_no && x.BatchNo == item.Batch_num).FirstOrDefault();
                        if (inventory_Batch == null) throw new Exception($"未找到出库单号【{entityOrder.Out_no}】中物料编号【{item.Goods_no}】物料批次【{item.Batch_num}】的库存批次信息");
                        if (inventory_Batch.AvailableQuantity < item.Order_qty) throw new Exception($"出库单号【{entityOrder.Out_no}】中物料编号【{item.Goods_no}】物料批次【{item.Batch_num}】的库存批次信息可用数量不足");
                        inventory_Batch.AvailableQuantity -= item.Order_qty;
                        inventory_Batch.OutboundQuantity += item.Order_qty;
                        List<Dt_InventoryInfo> dt_InventoryInfos = InventoryInfos.Where(x => x.MaterielCode == item.Goods_no && x.BatchNo == item.Batch_num).ToList();
                        if (dt_InventoryInfos.Count < 1) throw new Exception($"出库单号【{entityOrder.Out_no}】中物料编号【{item.Goods_no}】物料批次【{item.Batch_num}】的可用库存不足");
                        #region æŒ‰å‡ºåº“策略查找库存
                        if (tactics.SelectTactice == TacticsEnum.ComeOutonFirstTime.ObjToInt())
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.ValidityPeriod).ToList();
                        else
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.InDate).ToList();
                        #endregion
                        var Order_qty = item.Order_qty;//出库单数量
                        foreach (var InventoryInfo in dt_InventoryInfos)
                        {
                            //  1️⃣ è½¬ä¸ºæ­£æ•°ï¼ˆä¸Šæ¸¸å¯èƒ½ä¼ è´Ÿæ•°ï¼‰
                            item.order_qty = Math.Abs(item.order_qty);
                            decimal orderQty = (decimal)item.order_qty;
                            //  2️⃣ æŸ¥ç‰©æ–™åŸºç¡€ä¿¡æ¯ï¼ˆèŽ·å–ç®±è§„ï¼‰
                            var medication = BaseDal.Db.Queryable<Dt_MedicineGoods>()
                                .Where(m => m.Goods_no == item.goods_no)
                                .First();
                            if (medication == null)
                            if (Order_qty <= 0) break;
                            if (InventoryInfo.AvailableQuantity <= Order_qty)
                            {
                                SendErrorToUpstream(3, "", $"找不到物料信息:{item.goods_no}", "");
                                continue;
                                Order_qty -= InventoryInfo.AvailableQuantity;
                                InventoryInfo.OutboundQuantity += InventoryInfo.AvailableQuantity;
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = InventoryInfo.WarehouseCode,
                                    BatchNo = InventoryInfo.BatchNo,
                                    MaterielName = InventoryInfo.MaterielName,
                                    MaterielCode = InventoryInfo.MaterielCode,
                                    MaterielSpec = InventoryInfo.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = outorder.order_type == "1" ? TaskTypeEnum.Out.ObjToInt() : TaskTypeEnum.InReturn.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = InventoryInfo.LocationCode,
                                    OrderNo = entityOrder.Out_no,
                                    StockQuantity = InventoryInfo.AvailableQuantity,
                                    SupplyQuantity = 0,
                                    Remark = "出库"
                                };
                                supplyTasks.Add(supplyTask);
                                InventoryInfo.AvailableQuantity = 0;
                            }
                            decimal boxQty = medication.BoxQty <= 0 ? 1 : medication.BoxQty;
                            //  3️⃣ è®¡ç®—整件与散件数量
                            var fullBoxes = (int)(orderQty / boxQty);   // æ•´ä»¶ç®±æ•°
                            var partialQty = orderQty % boxQty;         // æ•£ä»¶æ•°é‡
                            // è‹¥ä¸Šæ¸¸ç»™äº†æ‰¹æ¬¡å·ï¼Œåˆ™ä¼˜å…ˆåŒ¹é…
                            string requestedBatch = string.IsNullOrEmpty(item.batch_num) ? null : item.batch_num;
                            // helper: æŸ¥è¯¢åº“存函数(按入库时间升序)
                            Func<int, List<Dt_InventoryInfo>> queryInventoryByStockStatus = (stockStatus) =>
                            else
                            {
                                var q = BaseDal.Db.Queryable<Dt_InventoryInfo>()
                                    .Where(i => i.MaterielCode == item.goods_no &&
                                                (i.StockQuantity - i.OutboundQuantity) > 0 &&
                                                i.StockStatus == stockStatus);
                                if (!string.IsNullOrEmpty(requestedBatch))
                                    q = q.Where(i => i.BatchNo == requestedBatch);
                                return q.OrderBy(i => i.InDate).ToList();
                            };
                            // 4️⃣分配散件(优先立库 Status=0)
                            decimal remainingPartial = partialQty;
                            if (remainingPartial > 0)
                            {
                                var invList_ly = queryInventoryByStockStatus(1);
                                foreach (var inv in invList_ly)
                                InventoryInfo.AvailableQuantity -= Order_qty;
                                InventoryInfo.OutboundQuantity += Order_qty;
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    if (remainingPartial <= 0) break;
                                    decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                    if (available <= 0) continue;
                                    decimal use = Math.Min(available, remainingPartial);
                                    var detail = new Dt_DeliveryOrderDetail
                                    {
                                        Goods_no = item.goods_no,
                                        Order_qty = use,
                                        Batch_num = inv.BatchNo,
                                        Exp_date = inv.ValidityPeriod,
                                        OotDetailStatus = "新建",
                                        Status = 0, //立库
                                        Reservoirarea = inv.LocationCode
                                    };
                                    entityOrder.Details.Add(detail);
                                    inv.OutboundQuantity += (float)use;
                                    BaseDal.Db.Updateable(inv).ExecuteCommand();
                                    remainingPartial -= use;
                                }
                                // ç«‹åº“不够 â†’ å¹³åº“è¡¥ (Status=2)
                                if (remainingPartial > 0)
                                {
                                    var invList_pk = queryInventoryByStockStatus(2);
                                    foreach (var inv in invList_pk)
                                    {
                                        if (remainingPartial <= 0) break;
                                        decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                        if (available <= 0) continue;
                                        decimal use = Math.Min(available, remainingPartial);
                                        var detail = new Dt_DeliveryOrderDetail
                                        {
                                            Goods_no = item.goods_no,
                                            Order_qty = use,
                                            Batch_num = inv.BatchNo,
                                            Exp_date = inv.ValidityPeriod,
                                            OotDetailStatus = "新建",
                                            Status = 2, //平库
                                            Reservoirarea = inv.LocationCode
                                        };
                                        entityOrder.Details.Add(detail);
                                        inv.OutboundQuantity += (float)use;
                                        BaseDal.Db.Updateable(inv).ExecuteCommand();
                                        remainingPartial -= use;
                                    }
                                }
                                if (remainingPartial > 0)
                                {
                                    SendErrorToUpstream(3, "", $"出库单[{outorder.order_no}]物料[{item.goods_no}]散件库存不足,未分配:{remainingPartial}", "");
                                }
                                    WarehouseCode = InventoryInfo.WarehouseCode,
                                    BatchNo = InventoryInfo.BatchNo,
                                    MaterielName = InventoryInfo.MaterielName,
                                    MaterielCode = InventoryInfo.MaterielCode,
                                    MaterielSpec = InventoryInfo.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = outorder.order_type == "1" ? TaskTypeEnum.Out.ObjToInt() : TaskTypeEnum.InReturn.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = InventoryInfo.LocationCode,
                                    OrderNo = entityOrder.Out_no,
                                    StockQuantity = Order_qty,
                                    SupplyQuantity = 0,
                                    Remark = "出库"
                                };
                                supplyTasks.Add(supplyTask);
                                Order_qty = 0;
                            }
                            //分配整件(优先平库 Status=2)
                            int remainingFullBoxes = fullBoxes;
                            if (remainingFullBoxes > 0)
                            {
                                var invList_pk = queryInventoryByStockStatus(2);
                                foreach (var inv in invList_pk)
                                {
                                    if (remainingFullBoxes <= 0) break;
                                    decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                    if (available < boxQty) continue;
                                    int canProvideBoxes = (int)(available / boxQty);
                                    if (canProvideBoxes <= 0) continue;
                                    int useBoxes = Math.Min(canProvideBoxes, remainingFullBoxes);
                                    decimal useQty = useBoxes * boxQty;
                                    var detail = new Dt_DeliveryOrderDetail
                                    {
                                        Goods_no = item.goods_no,
                                        Order_qty = useQty,
                                        Batch_num = inv.BatchNo,
                                        Exp_date = inv.ValidityPeriod,
                                        OotDetailStatus = "新建",
                                        Status = 2, //平库
                                        Reservoirarea = inv.LocationCode
                                    };
                                    entityOrder.Details.Add(detail);
                                    inv.OutboundQuantity += (float)useQty;
                                    BaseDal.Db.Updateable(inv).ExecuteCommand();
                                    remainingFullBoxes -= useBoxes;
                                }
                                // å¹³åº“不够 â†’ ç«‹åº“è¡¥ (Status=1)
                                if (remainingFullBoxes > 0)
                                {
                                    var invList_ly = queryInventoryByStockStatus(1);
                                    foreach (var inv in invList_ly)
                                    {
                                        if (remainingFullBoxes <= 0) break;
                                        decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                        if (available < boxQty) continue;
                                        int canProvideBoxes = (int)(available / boxQty);
                                        if (canProvideBoxes <= 0) continue;
                                        int useBoxes = Math.Min(canProvideBoxes, remainingFullBoxes);
                                        decimal useQty = useBoxes * boxQty;
                                        var detail = new Dt_DeliveryOrderDetail
                                        {
                                            Goods_no = item.goods_no,
                                            Order_qty = useQty,
                                            Batch_num = inv.BatchNo,
                                            Exp_date = inv.ValidityPeriod,
                                            OotDetailStatus = "新建",
                                            Status = 0, //立库(补整箱)
                                            Reservoirarea = inv.LocationCode
                                        };
                                        entityOrder.Details.Add(detail);
                                        inv.OutboundQuantity += (float)useQty;
                                        BaseDal.Db.Updateable(inv).ExecuteCommand();
                                        remainingFullBoxes -= useBoxes;
                                    }
                                }
                                if (remainingFullBoxes > 0)
                                {
                                    decimal unfilledQty = remainingFullBoxes * boxQty;
                                    SendErrorToUpstream(3, "", $"出库单[{outorder.order_no}]物料[{item.goods_no}]整箱库存不足,未分配数量:{unfilledQty}", "");
                                }
                            }
                            inventoryInfosUp.Add(InventoryInfo);
                        }
                        _DeliveryOrders.Add(entityOrder);
                        batchesUp.Add(inventory_Batch);
                    }
                    // æ’入主表+明细
                    BaseDal.Db.InsertNav(_DeliveryOrders)
                        .Include(x => x.Details)
                        .ExecuteCommand();
                    Db.Ado.CommitTran();
                    return responseContent.OK("同步出库单成功");
                    _unitOfWorkManage.BeginTran();
                    _supplyTaskService.AddData(supplyTasks);
                    _inventory_BatchServices.UpdateData(batchesUp);
                    _inventoryInfoService.UpdateData(inventoryInfosUp);
                    BaseDal.Db.CopyNew().InsertNav(entityOrder).Include(x => x.Details).ExecuteCommand();
                    _unitOfWorkManage.CommitTran();
                    #endregion
                }
                catch (Exception ex)
                #endregion
                else
                {
                    Db.Ado.RollbackTran();
                    SendErrorToUpstream(3, "", ex.Message, "");
                    return responseContent.Error("同步失败: " + ex.Message);
                }
            }
            catch (Exception ex)
            {
                SendErrorToUpstream(3, "", ex.Message, "");
                return responseContent.Error("同步失败: " + ex.Message);
            }
        }
        /// <summary>
        /// è¿‡æ»¤æ²¡æœ‰å¯¹å•†å“è¿›è¡Œç»´æŠ¤çš„出库单进行过滤
        /// </summary>
        /// <returns></returns>
        public WebResponseContent GetUpstreamOutOrder2()
        {
            var responseContent = new WebResponseContent();
            try
            {
                var url = "http://121.37.118.63:80/GYZ2/95fck/outOrder";
                var requestData = new
                {
                    searchDate = "2022-10-10 20:45:16"
                };
                var result = HttpHelper.Post(url, requestData.ToJsonString());
                var response = JsonConvert.DeserializeObject<UpstreamResponse<UpstramOutOrderInfo>>(result);
                if (response.resultCode != "0")
                {
                    SendErrorToUpstream(3, "", response.resultMsg ?? "上游接口返回失败", "");
                    return responseContent.Error(response.resultMsg ?? "上游接口返回失败");
                }
                if (response.data == null || !response.data.Any())
                {
                    return responseContent.OK("无新出库单数据");
                }
                // å·²å­˜åœ¨å‡ºåº“单号
                var existingOutOrderNos = BaseDal.Db.Queryable<Dt_DeliveryOrder>()
                    .Select(x => x.Out_no)
                    .ToList();
                // æ–°å‡ºåº“单
                var newOutOrders = response.data
                    .Where(outorder => !existingOutOrderNos.Contains(outorder.order_no))
                    .ToList();
                if (!newOutOrders.Any())
                {
                    return responseContent.OK("所有出库单已存在,无需新增");
                }
                Db.Ado.BeginTran();
                try
                {
                    List<Dt_DeliveryOrder> _DeliveryOrders = new List<Dt_DeliveryOrder>();
                    List<string> orderNos = new();
                    foreach (var outorder in newOutOrders)
                    string WareCodeDJ = WarehouseEnum.大件库.ObjToInt().ToString("000");
                    string WareCodeLK = WarehouseEnum.立库.ObjToInt().ToString("000");
                    #region åˆ›å»ºå¤§ä»¶åº“、立库出库头表
                    var entityOrder = new Dt_DeliveryOrder
                    {
                        bool skipOrder = false; // æ ‡è®°æ˜¯å¦è·³è¿‡è¯¥å…¥åº“单
                        var entityOrder = new Dt_DeliveryOrder
                        Out_no = outorder.order_no,
                        Out_type = outorder.order_type,
                        OutStatus = "新建",
                        Client_name = outorder.client_name,
                        Account_time = outorder.account_time,
                        Client_no = outorder.client_no,
                        Warehouse_no = WareCodeDJ,
                        Details = new List<Dt_DeliveryOrderDetail>()
                    };
                    var entityOrderLK = new Dt_DeliveryOrder
                    {
                        Out_no = outorder.order_no,
                        Out_type = outorder.order_type,
                        OutStatus = "新建",
                        Client_name = outorder.client_name,
                        Account_time = outorder.account_time,
                        Client_no = outorder.client_no,
                        Warehouse_no = WareCodeLK,
                        Details = new List<Dt_DeliveryOrderDetail>()
                    };
                    #endregion
                    #region æŸ¥æ‰¾åº“å­˜
                    List<Dt_Inventory_Batch> batchesUp = new List<Dt_Inventory_Batch>();
                    List<Dt_InventoryInfo> inventoryInfosUp = new List<Dt_InventoryInfo>();
                    List<Dt_SupplyTask> supplyTasks = new List<Dt_SupplyTask>();
                    List<Dt_MaterielInfo> materielInfos = _materielInfoService.Repository.QueryData(x => outorder.details.Select(e => e.goods_no).Contains(x.MaterielCode));
                    var inventory_Batchs = _inventory_BatchServices.Repository.QueryData(x => outorder.details.Select(e => e.goods_no).Contains(x.MaterielCode));
                    var InventoryInfos = _inventoryInfoService.Repository.QueryData(x => outorder.details.Select(e => e.goods_no).Contains(x.MaterielCode) && x.StockStatus == StockStatusEmun.入库完成.ObjToInt() && x.AvailableQuantity > 0 && (x.WarehouseCode == WareCodeDJ || x.WarehouseCode == WareCodeLK));
                    foreach (var detail in outorder.details)
                    {
                        #region æŸ¥è¯¢åº“存批次和库存
                        Dt_Inventory_Batch? inventory_Batch = inventory_Batchs.Where(x => x.MaterielCode == detail.goods_no && x.BatchNo == detail.batch_num).FirstOrDefault();
                        if (inventory_Batch == null) throw new Exception($"未找到出库单号【{outorder.order_no}】中物料编号【{detail.goods_no}】物料批次【{detail.batch_num}】的库存批次信息");
                        if (inventory_Batch.AvailableQuantity < detail.order_qty) throw new Exception($"出库单号【{outorder.order_no}】中物料编号【{detail.goods_no}】物料批次【{detail.batch_num}】的库存批次信息可用数量不足");
                        inventory_Batch.AvailableQuantity -= detail.order_qty;
                        inventory_Batch.OutboundQuantity += detail.order_qty;
                        List<Dt_InventoryInfo> dt_InventoryInfos = InventoryInfos.Where(x => x.MaterielCode == inventory_Batch.MaterielCode && x.BatchNo == inventory_Batch.BatchNo).ToList();
                        if (dt_InventoryInfos.Count < 1) throw new Exception($"出库单号【{outorder.order_no}】中物料编号【{detail.goods_no}】物料批次【{detail.batch_num}】的可用库存不足");
                        #endregion
                        #region æŒ‰å‡ºåº“策略查找库存
                        if (tactics.SelectTactice == TacticsEnum.ComeOutonFirstTime.ObjToInt())
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.ValidityPeriod).ToList();
                        else
                            dt_InventoryInfos = dt_InventoryInfos.OrderBy(x => x.InDate).ToList();
                        #endregion
                        var Order_qty = Math.Abs(detail.order_qty);//出库单数量
                        #region æ ¹æ®ç‰©æ–™ç¼–码查询物料信息
                        Dt_MaterielInfo? materielInfo = materielInfos.Where(x => x.MaterielCode == detail.goods_no).FirstOrDefault();
                        if (materielInfo == null) throw new Exception($"未找到药品编码【{detail.goods_no}】的信息");
                        if (!Enum.IsDefined(typeof(MaterielSourceTypeEnum), materielInfo.MaterielSourceType))
                            throw new Exception($"请设置药品编号【{detail.goods_no}】的属性分类");
                        #endregion
                        #region å¤§ä»¶
                        if (materielInfo.MaterielSourceType == MaterielSourceTypeEnum.PurchasePart)//如果物料是大件
                        {
                            Out_no = outorder.order_no,
                            Out_type = outorder.order_type,
                            Client_no = outorder.client_no,
                            Client_name = outorder.client_name,
                            Account_time = outorder.account_time,
                            Warehouse_no = outorder.warehouse_no,
                            OutStatus = "未完成",
                            Details = new List<Dt_DeliveryOrderDetail>()
                        };
                        // éåŽ†å‡ºåº“æ˜Žç»†
                        foreach (var item in outorder.details)
                        {
                            //  1️⃣ è½¬ä¸ºæ­£æ•°ï¼ˆä¸Šæ¸¸å¯èƒ½ä¼ è´Ÿæ•°ï¼‰
                            item.order_qty = Math.Abs(item.order_qty);
                            decimal orderQty = (decimal)item.order_qty;
                            //  2️⃣ æŸ¥ç‰©æ–™åŸºç¡€ä¿¡æ¯ï¼ˆèŽ·å–ç®±è§„ï¼‰
                            var medication = BaseDal.Db.Queryable<Dt_MaterielInfo>()
                                .Where(m => m.MaterielCode == item.goods_no)
                                .First();
                            //如果物料信息不存在,跳过整个入库单
                            if (medication == null)
                            #region æ·»åŠ å‡ºåº“è¯¦æƒ…
                            Dt_DeliveryOrderDetail orderDetail = new Dt_DeliveryOrderDetail()
                            {
                                skipOrder = true;
                                Console.WriteLine($"跳过入库单 {outorder.order_no},原因:未找到商品 [{item.goods_no}] çš„物料信息。");
                                break;
                            }
                            //  è‹¥ç‰©æ–™ä¸å­˜åœ¨æˆ– MaterielSourceType ä¸ºç©ºï¼Œåˆ™è·³è¿‡æ•´ä¸ªå‡ºåº“单
                            if (medication == null || !Enum.IsDefined(typeof(MaterielSourceTypeEnum), medication.MaterielSourceType))
                            {
                                skipOrder = true;
                                break;
                            }
                            if (medication == null)
                            {
                                SendErrorToUpstream(3, "", $"找不到物料信息:{item.goods_no}", "");
                                continue;
                            }
                            decimal boxQty = medication.BoxQty <= 0 ? 1 : medication.BoxQty;
                            //  3️⃣ è®¡ç®—整件与散件数量
                            var fullBoxes = (int)(orderQty / boxQty);   // æ•´ä»¶ç®±æ•°
                            var partialQty = orderQty % boxQty;         // æ•£ä»¶æ•°é‡
                            // è‹¥ä¸Šæ¸¸ç»™äº†æ‰¹æ¬¡å·ï¼Œåˆ™ä¼˜å…ˆåŒ¹é…
                            string requestedBatch = string.IsNullOrEmpty(item.batch_num) ? null : item.batch_num;
                            // helper: æŸ¥è¯¢åº“存函数(按入库时间升序)
                            // å®šä¹‰ä¸€ä¸ªå§”托变量:输入int参数,返回List<Dt_InventoryInfo>
                            Func<int, List<Dt_InventoryInfo>> queryInventoryByStockStatus = (stockStatus) =>
                            {
                                // 1. åˆ›å»ºåŸºç¡€æŸ¥è¯¢
                                var q = BaseDal.Db.Queryable<Dt_InventoryInfo>()
                                    .Where(i => i.MaterielCode == item.goods_no &&           // ç‰©æ–™ç¼–号匹配
                                                (i.StockQuantity - i.OutboundQuantity) > 0 && // å¯ç”¨åº“å­˜>0
                                                i.StockStatus == stockStatus);               // åº“存状态匹配
                                // 2. æ¡ä»¶ç­›é€‰ï¼ˆå¦‚果有批次号要求)
                                if (!string.IsNullOrEmpty(requestedBatch))
                                    q = q.Where(i => i.BatchNo == requestedBatch);
                                // 3. æ‰§è¡ŒæŸ¥è¯¢å¹¶è¿”回结果
                                return q.OrderBy(i => i.InDate).ToList();  // æŒ‰å…¥åº“时间排序
                                Reservoirarea = entityOrder.Warehouse_no,
                                Goods_no = detail.goods_no,
                                Order_qty = detail.order_qty,
                                Batch_num = detail.batch_num,
                                Exp_date = detail.exp_date,
                                OotDetailStatus = "新建",
                                Order_Outqty = 0,
                                Status = 2
                            };
                            // 4️⃣分配散件(优先立库 Status=0)
                            decimal remainingPartial = partialQty;
                            if (remainingPartial > 0)
                            entityOrder.Details.Add(orderDetail);
                            #endregion
                            #region è®¡ç®—库存、添加出库任务
                            foreach (var InventoryInfo in dt_InventoryInfos)
                            {
                                var invList_ly = queryInventoryByStockStatus(0);
                                foreach (var inv in invList_ly)
                                if (Order_qty <= 0) break;
                                if (InventoryInfo.AvailableQuantity < Order_qty)
                                {
                                    if (remainingPartial <= 0) break;
                                    decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                    if (available <= 0) continue;
                                    decimal use = Math.Min(available, remainingPartial);
                                    var detail = new Dt_DeliveryOrderDetail
                                    Order_qty -= InventoryInfo.AvailableQuantity;
                                    InventoryInfo.OutboundQuantity += InventoryInfo.AvailableQuantity;
                                    Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                    {
                                        Goods_no = item.goods_no,
                                        Order_qty = use,
                                        Batch_num = inv.BatchNo,
                                        Exp_date = inv.ValidityPeriod,
                                        OotDetailStatus = "新建",
                                        Status = 0, //立库
                                        Reservoirarea = inv.LocationCode
                                        WarehouseCode = InventoryInfo.WarehouseCode,
                                        BatchNo = InventoryInfo.BatchNo,
                                        MaterielName = InventoryInfo.MaterielName,
                                        MaterielCode = InventoryInfo.MaterielCode,
                                        MaterielSpec = InventoryInfo.MaterielSpec,
                                        TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                        TaskType = outorder.order_type == "1" ? TaskTypeEnum.Out.ObjToInt() : TaskTypeEnum.InReturn.ObjToInt(),
                                        CreateDate = DateTime.Now,
                                        Creater = App.User.UserName ?? "System",
                                        LocationCode = InventoryInfo.LocationCode,
                                        OrderNo = entityOrder.Out_no,
                                        StockQuantity = InventoryInfo.AvailableQuantity,
                                        SupplyQuantity = 0,
                                        Remark = "出库"
                                    };
                                    entityOrder.Details.Add(detail);
                                    inv.OutboundQuantity += (float)use;
                                    BaseDal.Db.Updateable(inv).ExecuteCommand();
                                    remainingPartial -= use;
                                    supplyTasks.Add(supplyTask);
                                    InventoryInfo.AvailableQuantity = 0;
                                }
                                // ç«‹åº“不够 â†’ å¹³åº“è¡¥ (Status=2)
                                if (remainingPartial > 0)
                                else
                                {
                                    var invList_pk = queryInventoryByStockStatus(2);
                                    foreach (var inv in invList_pk)
                                    InventoryInfo.AvailableQuantity -= Order_qty;
                                    InventoryInfo.OutboundQuantity += Order_qty;
                                    Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                    {
                                        if (remainingPartial <= 0) break;
                                        decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                        if (available <= 0) continue;
                                        decimal use = Math.Min(available, remainingPartial);
                                        var detail = new Dt_DeliveryOrderDetail
                                        {
                                            Goods_no = item.goods_no,
                                            Order_qty = use,
                                            Batch_num = inv.BatchNo,
                                            Exp_date = inv.ValidityPeriod,
                                            OotDetailStatus = "新建",
                                            Status = 2, //平库
                                            Reservoirarea = inv.LocationCode
                                        };
                                        entityOrder.Details.Add(detail);
                                        inv.OutboundQuantity += (float)use;
                                        BaseDal.Db.Updateable(inv).ExecuteCommand();
                                        remainingPartial -= use;
                                    }
                                }
                                if (remainingPartial > 0)
                                {
                                    SendErrorToUpstream(3, "", $"出库单[{outorder.order_no}]物料[{item.goods_no}]散件库存不足,未分配:{remainingPartial}", "");
                                        WarehouseCode = InventoryInfo.WarehouseCode,
                                        BatchNo = InventoryInfo.BatchNo,
                                        MaterielName = InventoryInfo.MaterielName,
                                        MaterielCode = InventoryInfo.MaterielCode,
                                        MaterielSpec = InventoryInfo.MaterielSpec,
                                        TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                        TaskType = outorder.order_type == "1" ? TaskTypeEnum.Out.ObjToInt() : TaskTypeEnum.InReturn.ObjToInt(),
                                        CreateDate = DateTime.Now,
                                        Creater = App.User.UserName ?? "System",
                                        LocationCode = InventoryInfo.LocationCode,
                                        OrderNo = entityOrder.Out_no,
                                        StockQuantity = Order_qty,
                                        SupplyQuantity = 0,
                                        Remark = "出库"
                                    };
                                    supplyTasks.Add(supplyTask);
                                    Order_qty = 0;
                                }
                            }
                            //分配整件(优先平库 Status=2)
                            int remainingFullBoxes = fullBoxes;
                            if (remainingFullBoxes > 0)
                            {
                                var invList_pk = queryInventoryByStockStatus(2);
                                foreach (var inv in invList_pk)
                                {
                                    if (remainingFullBoxes <= 0) break;
                                    decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                    if (available < boxQty) continue;
                                    int canProvideBoxes = (int)(available / boxQty);
                                    if (canProvideBoxes <= 0) continue;
                                    int useBoxes = Math.Min(canProvideBoxes, remainingFullBoxes);
                                    decimal useQty = useBoxes * boxQty;
                                    var detail = new Dt_DeliveryOrderDetail
                                    {
                                        Goods_no = item.goods_no,
                                        Order_qty = useQty,
                                        Batch_num = inv.BatchNo,
                                        Exp_date = inv.ValidityPeriod,
                                        OotDetailStatus = "新建",
                                        Status = 2, //平库
                                        Reservoirarea = inv.LocationCode
                                    };
                                    entityOrder.Details.Add(detail);
                                    inv.OutboundQuantity += (float)useQty;
                                    BaseDal.Db.Updateable(inv).ExecuteCommand();
                                    remainingFullBoxes -= useBoxes;
                                }
                                // å¹³åº“不够 â†’ ç«‹åº“è¡¥ (Status=1)
                                if (remainingFullBoxes > 0)
                                {
                                    var invList_ly = queryInventoryByStockStatus(1);
                                    foreach (var inv in invList_ly)
                                    {
                                        if (remainingFullBoxes <= 0) break;
                                        decimal available = (decimal)(inv.StockQuantity - inv.OutboundQuantity);
                                        if (available < boxQty) continue;
                                        int canProvideBoxes = (int)(available / boxQty);
                                        if (canProvideBoxes <= 0) continue;
                                        int useBoxes = Math.Min(canProvideBoxes, remainingFullBoxes);
                                        decimal useQty = useBoxes * boxQty;
                                        var detail = new Dt_DeliveryOrderDetail
                                        {
                                            Goods_no = item.goods_no,
                                            Order_qty = useQty,
                                            Batch_num = inv.BatchNo,
                                            Exp_date = inv.ValidityPeriod,
                                            OotDetailStatus = "新建",
                                            Status = 0, //立库(补整箱)
                                            Reservoirarea = inv.LocationCode
                                        };
                                        entityOrder.Details.Add(detail);
                                        inv.OutboundQuantity += (float)useQty;
                                        BaseDal.Db.Updateable(inv).ExecuteCommand();
                                        remainingFullBoxes -= useBoxes;
                                    }
                                }
                                // â—如果跳过该单,则直接continue,不保存
                                if (skipOrder)
                                {
                                    Console.WriteLine($"跳过入库单 {outorder.order_no},因为存在未定义物料属性的商品。");
                                    continue;
                                }
                                if (remainingFullBoxes > 0)
                                {
                                    decimal unfilledQty = remainingFullBoxes * boxQty;
                                    SendErrorToUpstream(3, "", $"出库单[{outorder.order_no}]物料[{item.goods_no}]整箱库存不足,未分配数量:{unfilledQty}", "");
                                }
                            }
                            #endregion
                            inventoryInfosUp.AddRange(dt_InventoryInfos);
                            batchesUp.Add(inventory_Batch);
                            //_inventory_BatchServices.Repository.UpdateData(inventory_Batch);
                            //_inventoryInfoService.Repository.UpdateData(dt_InventoryInfos);
                            //_supplyTaskService.AddData(supplyTasks);
                        }
                        _DeliveryOrders.Add(entityOrder);
                    }
                    // æ’入主表+明细
                    BaseDal.Db.InsertNav(_DeliveryOrders)
                        .Include(x => x.Details)
                        .ExecuteCommand();
                    Db.Ado.CommitTran();
                    return responseContent.OK("同步出库单成功");
                }
                catch (Exception ex)
                {
                    Db.Ado.RollbackTran();
                    SendErrorToUpstream(3, "", ex.Message, "");
                    return responseContent.Error("同步失败: " + ex.Message);
                }
            }
            catch (Exception ex)
            {
                SendErrorToUpstream(3, "", ex.Message, "");
                return responseContent.Error("同步失败: " + ex.Message);
            }
        }
        /// <summary>
        /// å‡ºåº“单推送给 WCS
        /// </summary>
        /// <returns></returns>
        public WebResponseContent EdiOut()
        {
            var responseContent = new WebResponseContent();
            try
            {
                // 1. æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„订单(表头=新建 && åŒ…含有效明细)
                var outOrders = BaseDal.Db.CopyNew().Queryable<Dt_DeliveryOrder>()
                    .Where(o => o.OutStatus == "新建")
                    .Includes(o => o.Details, d => d.MedicineGoods)
                    .ToList();
                // 2. å†è¿‡æ»¤æŽ‰ä¸ç¬¦åˆæ¡ä»¶çš„æ˜Žç»†ï¼ˆåªä¿ç•™ Status=0 ï¼‰
                foreach (var order in outOrders)
                {
                    order.Details = order.Details.Where(d => d.Status == 0).ToList();
                }
                if (outOrders == null || !outOrders.Any())
                {
                    Console.WriteLine("没有符合条件的订单需要推送");
                    return responseContent.Error("没有符合条件的订单需要推送");
                }
                foreach (var order in outOrders)
                {
                    try
                    {
                        string materialCode = "YY";//默认值
                                                   //获取当前订单的第一个明细项
                        var firstDetail = order.Details.FirstOrDefault();
                        if (firstDetail?.MedicineGoods != null && !string.IsNullOrEmpty(firstDetail.MedicineGoods.MaterielErpType))
                        {
                            //如果条件满足,将物料代码设置为第一个明细项对应的药品物料代码
                            materialCode = firstDetail.MedicineGoods.MaterielErpType;
                        }
                        // 3. ç»„装 DTO
                        var ediDto = new TowcsDto.ToediOutInfo
                        {
                            customerCode = "905",
                            materialCode = materialCode,
                            externalOrderNo = order.Out_no,
                            outOrderType = order.Out_type == "1" ? "10" : order.Out_type == "2" ? "20" : "30",
                            priority = 1,
                            Is_cancel = 0,
                            details = order.Details.Select(d => new TowcsDto.ToeOutdiInDetail
                            {
                                batchNo = d.Batch_num,
                                productCode = d.Goods_no,
                                productName = d.MedicineGoods?.MaterielName,
                                productSpecifications = d.MedicineGoods?.MaterielModel,
                                quantity = (int)d.Order_qty,
                                //stocktakingDetails = order.Out_type == "3"
                                //    ? new List<ToOutediInStock>
                                //      {
                                //  new ToOutediInStock { palletCode = "FC00001", quantity = d.Order_qty.ToString() }
                                //      }
                                //    : null
                            }).ToList()
                        };
                        // 4. è°ƒç”¨æŽ¥å£
                        var url = "http://172.16.1.2:9357/file-admin/api/out/ediOut";
                        var result = HttpHelper.Post(url, ediDto.ToJsonString());
                        var resp = JsonConvert.DeserializeObject<TowcsDto.TowcsResponse<object>>(result);
                        if (resp != null && resp.code == "0")
                        {
                            // æ›´æ–°è¡¨å¤´çŠ¶æ€
                            BaseDal.Db.Updateable<Dt_DeliveryOrder>()
                              .SetColumns(o => new Dt_DeliveryOrder { OutStatus = "开始" })
                              .Where(o => o.Id == order.Id)
                              .ExecuteCommand();
                            // æ›´æ–°æ˜Žç»†çŠ¶æ€
                            BaseDal.Db.Updateable<Dt_DeliveryOrderDetail>()
                              .SetColumns(d => new Dt_DeliveryOrderDetail { Status = 1, OotDetailStatus = "已完成" })
                              .Where(d => d.DeliveryOrderId == order.Id && d.Status == 0)
                              .ExecuteCommand();
                            Console.WriteLine($"订单 {order.Out_no} æŽ¨é€æˆåŠŸ");
                        }
                        #endregion
                        else
                        {
                            SendErrorToUpstream(3, order.Out_no, resp?.msg ?? "WCS æŽ¨é€å¤±è´¥", "");
                            Console.WriteLine($"订单 {order.Out_no} æŽ¨é€å¤±è´¥ï¼š{resp?.msg}");
                            if (materielInfo.BoxQty < 1) throw new Exception($"请设置药品编号【{detail.goods_no}】的箱规数量");
                            Dt_DeliveryOrderDetail orderDetail = null;
                            Dt_DeliveryOrderDetail orderDetailLK = null;
                            var ys = Order_qty % materielInfo.BoxQty; //不能整除箱规的散件数
                            var xs = (int)(Order_qty / materielInfo.BoxQty);//保留整数
                            #region æ•£ä»¶ä¼˜å…ˆåˆ†é…ç«‹åº“
                            if (ys > 0)
                            {
                                orderDetailLK = new Dt_DeliveryOrderDetail()
                                {
                                    Reservoirarea = entityOrderLK.Warehouse_no,
                                    Goods_no = detail.goods_no,
                                    Order_qty = ys,
                                    Batch_num = detail.batch_num,
                                    Exp_date = detail.exp_date,
                                    OotDetailStatus = "新建",
                                    Order_Outqty = 0,
                                    Status = 0
                                };
                            }
                            #endregion
                            #region æ•´ä»¶ä¼˜å…ˆåˆ†é…å¤§ä»¶åº“,计划库存,添加出库任务
                            foreach (var item in dt_InventoryInfos.Where(x => x.WarehouseCode == WareCodeDJ))
                            {
                                if (xs <= 0 || item.AvailableQuantity <= 0) break;
                                decimal outqty = 0;
                                while (item.AvailableQuantity > 0 && xs > 0)
                                {
                                    xs--;
                                    if (orderDetail == null)
                                    {
                                        orderDetail = new Dt_DeliveryOrderDetail()
                                        {
                                            Reservoirarea = entityOrder.Warehouse_no,
                                            Goods_no = detail.goods_no,
                                            Order_qty = materielInfo.BoxQty,
                                            Batch_num = detail.batch_num,
                                            Exp_date = detail.exp_date,
                                            OotDetailStatus = "新建",
                                            Order_Outqty = 0,
                                            Status = 2
                                        };
                                        item.AvailableQuantity -= materielInfo.BoxQty;
                                        item.OutboundQuantity += materielInfo.BoxQty;
                                        outqty += materielInfo.BoxQty;
                                    }
                                    else
                                    {
                                        orderDetail.Order_qty += materielInfo.BoxQty;
                                        item.AvailableQuantity -= materielInfo.BoxQty;
                                        item.OutboundQuantity += materielInfo.BoxQty;
                                        outqty += materielInfo.BoxQty;
                                    }
                                }
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = item.WarehouseCode,
                                    BatchNo = item.BatchNo,
                                    MaterielName = item.MaterielName,
                                    MaterielCode = item.MaterielCode,
                                    MaterielSpec = item.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = outorder.order_type == "1" ? TaskTypeEnum.Out.ObjToInt() : TaskTypeEnum.InReturn.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = item.LocationCode,
                                    OrderNo = entityOrder.Out_no,
                                    StockQuantity = outqty,
                                    SupplyQuantity = 0,
                                    Remark = "出库"
                                };
                                supplyTasks.Add(supplyTask);
                                inventoryInfosUp.Add(item);
                                //_inventoryInfoService.Repository.UpdateData(item);
                            }
                            #endregion
                            #region åˆ†é…å®Œå¤§ä»¶åº“如果还有箱数,再选择分配立库
                            if (xs > 0)
                            {
                                if (orderDetailLK == null)
                                {
                                    orderDetailLK = new Dt_DeliveryOrderDetail()
                                    {
                                        Reservoirarea = entityOrderLK.Warehouse_no,
                                        Goods_no = detail.goods_no,
                                        Order_qty = xs * materielInfo.BoxQty,
                                        Batch_num = detail.batch_num,
                                        Exp_date = detail.exp_date,
                                        OotDetailStatus = "新建",
                                        Order_Outqty = 0,
                                        Status = 0
                                    };
                                }
                                else
                                {
                                    orderDetailLK.Order_qty += xs * materielInfo.BoxQty;
                                }
                            }
                            #endregion
                            #region ç«‹åº“出库单,修改立库库存,添加立库出库任务
                            if (orderDetailLK != null)
                            {
                                #region æ·»åŠ å‡ºåº“ä»»åŠ¡ã€ä¿®æ”¹åº“å­˜ä¿¡æ¯
                                Dt_InventoryInfo? inventoryInfo = dt_InventoryInfos.FirstOrDefault(x => x.WarehouseCode == WareCodeLK);
                                if (inventoryInfo == null)
                                    throw new Exception($"未找到物料编号【{detail.goods_no}】物料批次【{detail.batch_num}】在立库中的库存信息;所需数量【{orderDetailLK.Order_qty}】请补货");
                                inventoryInfo.AvailableQuantity -= orderDetailLK.Order_qty;
                                inventoryInfo.OutboundQuantity += orderDetailLK.Order_qty;
                                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                                {
                                    WarehouseCode = inventoryInfo.WarehouseCode,
                                    BatchNo = inventoryInfo.BatchNo,
                                    MaterielName = inventoryInfo.MaterielName,
                                    MaterielCode = inventoryInfo.MaterielCode,
                                    MaterielSpec = inventoryInfo.MaterielSpec,
                                    TaskStatus = SupplyStatusEnum.NewOut.ObjToInt(),
                                    TaskType = outorder.order_type == "1" ? TaskTypeEnum.Out.ObjToInt() : TaskTypeEnum.InReturn.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName ?? "System",
                                    LocationCode = inventoryInfo.LocationCode,
                                    OrderNo = entityOrder.Out_no,
                                    StockQuantity = orderDetailLK.Order_qty,
                                    SupplyQuantity = 0,
                                    Remark = "出库"
                                };
                                supplyTasks.Add(supplyTask);
                                #endregion
                                //_inventoryInfoService.Repository.UpdateData(inventoryInfo);
                                inventoryInfosUp.Add(inventoryInfo);
                                entityOrderLK.Details.Add(orderDetailLK);
                            }
                            #endregion
                            if (orderDetail != null) entityOrder.Details.Add(orderDetail);
                            batchesUp.Add(inventory_Batch);
                            //_inventory_BatchServices.Repository.UpdateData(inventory_Batch);
                            //_supplyTaskService.AddData(supplyTasks);
                        }
                        //删除全部状为已完成的明细和表头,移入历史表
                    }
                    try
                    {
                        _unitOfWorkManage.BeginTran();
                        _supplyTaskService.AddData(supplyTasks);
                        _inventory_BatchServices.UpdateData(batchesUp);
                        _inventoryInfoService.UpdateData(inventoryInfosUp);
                        if (entityOrder.Details.Count > 0)
                            BaseDal.Db.CopyNew().InsertNav(entityOrder).Include(x => x.Details).ExecuteCommand();
                        if (entityOrderLK.Details.Count > 0)
                            BaseDal.Db.CopyNew().InsertNav(entityOrderLK).Include(x => x.Details).ExecuteCommand();
                        _unitOfWorkManage.CommitTran();
                    }
                    catch (Exception ex)
                    {
                        SendErrorToUpstream(3, order.Out_no, ex.Message, "");
                        Console.WriteLine($"订单 {order.Out_no} æŽ¨é€å¼‚常:{ex.Message}");
                        _unitOfWorkManage.RollbackTran();
                    }
                    #endregion
                }
                return responseContent.OK("出库订单推送完成");
                webResponseContent.OK();
            }
            catch (Exception ex)
            {
                Console.WriteLine("EdiOut å¼‚常:" + ex.Message);
                return responseContent.Error("出库订单推送失败:" + ex.Message);
                _messageInfoService.AddMessageInfo(MessageGroupByEnum.OutOrderAlarm, (outorder.order_type == "3" ? "入库退货" : "正常出库") + $":单号【{outorder.order_no}】", ex.Message);
                webResponseContent.Error(ex.Message);
            }
            return webResponseContent;
        }
        #endregion
        #region åˆ›å»ºç›˜äºå‡ºåº“单
        public WebResponseContent CreateCheckOutOrder(UpstramOutOrderInfo order)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                string WareCodeMJ = WarehouseEnum.麻精库.ObjToInt().ToString("000");
                string WareCodeLD = WarehouseEnum.冷冻库.ObjToInt().ToString("000");
                List<Dt_SupplyTask_Hty> supplyTask_Hties = new List<Dt_SupplyTask_Hty>();
                List<Dt_Inventory_Batch> batchesUp = new List<Dt_Inventory_Batch>();
                List<Dt_InventoryInfo> infosUp = new List<Dt_InventoryInfo>();
                var codes = order.details.Select(x => x.goods_no).ToList();
                #region ç‰¹æ®Šåº“房
                if (order.warehouse_no == WareCodeMJ || order.warehouse_no == WareCodeLD)
                {
                    List<Dt_Inventory_Batch> inventory_Batchs = _inventory_BatchServices.Repository.QueryData(x => codes.Contains(x.MaterielCode));
                    List<Dt_InventoryInfo> _InventoryInfos = _inventoryInfoService.Repository.QueryData(x => codes.Contains(x.MaterielCode));
                    #region åº“存、库存批次平账
                    foreach (var item in order.details)
                    {
                        //找库存批次信息
                        Dt_Inventory_Batch inventory_Batch = inventory_Batchs.Where(x => x.MaterielCode == item.goods_no && x.BatchNo == item.batch_num).First();
                        var Qty = Math.Abs(inventory_Batch.SupplyQuantity);
                        if (Qty != item.order_qty) throw new Exception($"盘亏出库单【{order.order_no}】物料编号【{item.goods_no}】物料批次【{item.batch_num}】的盘亏数量有误");
                        //找所有库存
                        List<Dt_InventoryInfo> inventoryInfos = _InventoryInfos.Where(x => x.MaterielCode == inventory_Batch.MaterielCode && x.BatchNo == inventory_Batch.BatchNo).ToList();
                        foreach (var inventoryInfo in inventoryInfos)
                        {
                            #region æ·»åŠ ç›˜äºå‡ºåº“ä»»åŠ¡
                            if (inventoryInfo.StockQuantity != inventoryInfo.SupplyQuantity)
                            {
                                Dt_SupplyTask_Hty supplyTask_Hty = new Dt_SupplyTask_Hty()
                                {
                                    WarehouseCode = inventoryInfo.WarehouseCode,
                                    OperateType = OperateTypeEnum.自动完成.ToString(),
                                    InsertTime = DateTime.Now,
                                    TaskStatus = SupplyStatusEnum.OutFinish.ObjToInt(),
                                    BatchNo = inventoryInfo.BatchNo,
                                    MaterielName = inventoryInfo.MaterielName,
                                    MaterielCode = inventoryInfo.MaterielCode,
                                    MaterielSpec = inventoryInfo.MaterielSpec,
                                    TaskType = TaskTypeEnum.ChenckOut.ObjToInt(),
                                    CreateDate = DateTime.Now,
                                    Creater = App.User.UserName,
                                    LocationCode = inventoryInfo.LocationCode,
                                    OrderNo = order.order_no,
                                    StockQuantity = Math.Abs(inventoryInfo.SupplyQuantity),
                                    SupplyQuantity = 0,
                                    Remark = "盘亏入库"
                                };
                                //_supplyTaskHtyService.AddData(supplyTask_Hty);
                                supplyTask_Hties.Add(supplyTask_Hty);
                            }
                            #endregion
                            inventoryInfo.StockQuantity += inventoryInfo.SupplyQuantity;
                            inventoryInfo.AvailableQuantity = inventoryInfo.StockQuantity;
                            inventoryInfo.SupplyQuantity = 0;
                            inventoryInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                        }
                        inventory_Batch.StockQuantity += inventory_Batch.SupplyQuantity;
                        inventory_Batch.AvailableQuantity = inventory_Batch.StockQuantity;
                        inventory_Batch.SupplyQuantity = 0;
                        infosUp.AddRange(inventoryInfos);
                        batchesUp.Add(inventory_Batch);
                        //_inventoryInfoService.UpdateData(inventoryInfos);
                        //_inventory_BatchServices.UpdateData(inventory_Batch);
                    }
                    #endregion
                    #region åˆ›å»ºç›˜ç‚¹å•
                    var entityOrder = new Dt_DeliveryOrder
                    {
                        Out_no = order.order_no,
                        Out_type = order.order_type,
                        Client_no = order.client_no,
                        Client_name = order.client_name,
                        OutStatus = "已完成",
                        Account_time = order.account_time,
                        Warehouse_no = order.warehouse_no,
                        Details = order.details.Select(d => new Dt_DeliveryOrderDetail
                        {
                            Goods_no = d.goods_no,
                            Order_qty = Math.Abs(d.order_qty),
                            Order_Outqty = Math.Abs(d.order_qty),
                            Batch_num = d.batch_num,
                            Exp_date = d.exp_date,
                            Reservoirarea = order.warehouse_no,
                            OotDetailStatus = "已完成",
                            Status = 2,
                        }).ToList()
                    };
                    _unitOfWorkManage.BeginTran();
                    _supplyTaskHtyService.AddData(supplyTask_Hties);
                    _inventoryInfoService.UpdateData(infosUp);
                    _inventory_BatchServices.UpdateData(batchesUp);
                    BaseDal.Db.InsertNav(entityOrder).Include(it => it.Details).ExecuteCommand();
                    _unitOfWorkManage.CommitTran();
                    #endregion
                }
                #endregion
                else
                {
                    List<Dt_DeliveryOrder> deliveryOrdersAdd = new List<Dt_DeliveryOrder>();
                    string WareCodeLK = WarehouseEnum.立库.ObjToInt().ToString("000");
                    string WareCodeDJ = WarehouseEnum.大件库.ObjToInt().ToString("000");
                    List<Dt_Inventory_Batch> inventory_Batchs = _inventory_BatchServices.Repository.QueryData(x => codes.Contains(x.MaterielCode));
                    List<Dt_InventoryInfo> _InventoryInfos = _inventoryInfoService.Repository.QueryData(x => codes.Contains(x.MaterielCode));
                    foreach (var item in order.details)
                    {
                        //找库存批次信息
                        Dt_Inventory_Batch inventory_Batch = inventory_Batchs.Where(x => x.MaterielCode == item.goods_no && x.BatchNo == item.batch_num).First();
                        var Qty = Math.Abs(inventory_Batch.SupplyQuantity);
                        if (Qty != item.order_qty) throw new Exception($"盘亏出库单【{order.order_no}】物料编号【{item.goods_no}】物料批次【{item.batch_num}】的盘亏数量有误");
                        //找所有库存
                        List<Dt_InventoryInfo> inventoryInfos = _InventoryInfos.Where(x => x.MaterielCode == inventory_Batch.MaterielCode && x.BatchNo == inventory_Batch.BatchNo).ToList();
                        //获取立库盘点差异数.。。。。。。。。。。。。
                        var inventoryLK = inventoryInfos.Where(x => x.WarehouseCode == WareCodeLK).First();
                        //var LkQty = Math.Abs(inventoryLK.SupplyQuantity);
                        var LkQty = inventoryLK.SupplyQuantity;
                        //获取大件库盘点差异数
                        var inventoryDJ = inventoryInfos.Where(x => x.WarehouseCode == WareCodeDJ).ToList();
                        //var DJQty = Math.Abs(inventoryDJ.Sum(x => x.SupplyQuantity));
                        var DJQty = inventoryDJ.Sum(x => x.SupplyQuantity);
                        var count = Math.Abs(LkQty + DJQty);
                        if (count != Qty) throw new Exception($"【{order.order_no}】物料编号【{item.goods_no}】物料批次【{item.batch_num}】的物料信息与物料批次信息盘亏数量不符");
                        if (LkQty == 0)//立库无差异
                        {
                            #region åº“存、库存批次平账
                            foreach (var inventoryInfo in inventoryInfos)
                            {
                                #region æ·»åŠ ç›˜äºå‡ºåº“ä»»åŠ¡
                                if (inventoryInfo.StockQuantity != inventoryInfo.SupplyQuantity)
                                {
                                    Dt_SupplyTask_Hty supplyTask_Hty = new Dt_SupplyTask_Hty()
                                    {
                                        WarehouseCode = inventoryInfo.WarehouseCode,
                                        OperateType = OperateTypeEnum.自动完成.ToString(),
                                        InsertTime = DateTime.Now,
                                        TaskStatus = SupplyStatusEnum.OutFinish.ObjToInt(),
                                        BatchNo = inventoryInfo.BatchNo,
                                        MaterielName = inventoryInfo.MaterielName,
                                        MaterielCode = inventoryInfo.MaterielCode,
                                        MaterielSpec = inventoryInfo.MaterielSpec,
                                        TaskType = TaskTypeEnum.ChenckOut.ObjToInt(),
                                        CreateDate = DateTime.Now,
                                        Creater = App.User.UserName,
                                        LocationCode = inventoryInfo.LocationCode,
                                        OrderNo = order.order_no,
                                        StockQuantity = Math.Abs(inventoryInfo.SupplyQuantity),
                                        SupplyQuantity = 0,
                                        Remark = "盘亏入库"
                                    };
                                    //_supplyTaskHtyService.AddData(supplyTask_Hty);
                                    supplyTask_Hties.Add(supplyTask_Hty);
                                }
                                #endregion
                                inventoryInfo.StockQuantity += inventoryInfo.SupplyQuantity;
                                inventoryInfo.AvailableQuantity = inventoryInfo.StockQuantity;
                                inventoryInfo.SupplyQuantity = 0;
                                inventoryInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                            }
                            //_inventoryInfoService.UpdateData(inventoryInfos);
                            inventory_Batch.StockQuantity += inventory_Batch.SupplyQuantity;
                            inventory_Batch.AvailableQuantity = inventory_Batch.StockQuantity;
                            inventory_Batch.SupplyQuantity = 0;
                            //_inventory_BatchServices.UpdateData(inventory_Batch);
                            infosUp.AddRange(inventoryInfos);
                            batchesUp.Add(inventory_Batch);
                            #endregion
                            #region åˆ›å»ºå¤§ä»¶åº“盘点单
                            var entityOrder = new Dt_DeliveryOrder
                            {
                                Out_no = order.order_no,
                                Out_type = order.order_type,
                                Client_no = order.client_no,
                                Account_time = order.account_time,
                                OutStatus = "已完成",
                                Client_name = order.client_name,
                                Warehouse_no = WareCodeDJ,
                                Details = order.details.Select(d => new Dt_DeliveryOrderDetail
                                {
                                    Goods_no = d.goods_no,
                                    Order_qty = Math.Abs(d.order_qty),
                                    Order_Outqty = Math.Abs(d.order_qty),
                                    Batch_num = d.batch_num,
                                    Exp_date = d.exp_date,
                                    Reservoirarea = WareCodeDJ,
                                    OotDetailStatus = "已完成",
                                    Status = 2,
                                }).ToList()
                            };
                            //Db.InsertNav(entityOrder).Include(it => it.Details).ExecuteCommand();
                            //Repository.AddData(entityOrder);
                            deliveryOrdersAdd.Add(entityOrder);
                            #endregion
                        }
                        else
                        {
                            #region å¤§ä»¶åº“库存平账
                            inventoryInfos = inventoryInfos.Where(x => x.WarehouseCode == WareCodeDJ).ToList();
                            foreach (var inventoryInfo in inventoryInfos)
                            {
                                #region æ·»åŠ ç›˜äºå‡ºåº“ä»»åŠ¡
                                if (inventoryInfo.StockQuantity != inventoryInfo.SupplyQuantity)
                                {
                                    Dt_SupplyTask_Hty supplyTask_Hty = new Dt_SupplyTask_Hty()
                                    {
                                        WarehouseCode = inventoryInfo.WarehouseCode,
                                        OperateType = OperateTypeEnum.自动完成.ToString(),
                                        InsertTime = DateTime.Now,
                                        TaskStatus = SupplyStatusEnum.OutFinish.ObjToInt(),
                                        BatchNo = inventoryInfo.BatchNo,
                                        MaterielName = inventoryInfo.MaterielName,
                                        MaterielCode = inventoryInfo.MaterielCode,
                                        MaterielSpec = inventoryInfo.MaterielSpec,
                                        TaskType = TaskTypeEnum.ChenckOut.ObjToInt(),
                                        CreateDate = DateTime.Now,
                                        Creater = App.User.UserName,
                                        LocationCode = inventoryInfo.LocationCode,
                                        OrderNo = order.order_no,
                                        StockQuantity = Math.Abs(inventoryInfo.SupplyQuantity),
                                        SupplyQuantity = 0,
                                        Remark = "盘亏出库"
                                    };
                                    //_supplyTaskHtyService.AddData(supplyTask_Hty);
                                    supplyTask_Hties.Add(supplyTask_Hty);
                                }
                                #endregion
                                inventoryInfo.StockQuantity += inventoryInfo.SupplyQuantity;
                                inventoryInfo.AvailableQuantity = inventoryInfo.StockQuantity;
                                inventoryInfo.SupplyQuantity = 0;
                                inventoryInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                            }
                            //_inventoryInfoService.UpdateData(inventoryInfos);
                            infosUp.AddRange(inventoryInfos);
                            #endregion
                            #region åˆ›å»ºå¤§ä»¶åº“盘点单
                            if (DJQty != 0)
                            {
                                var cabinOrder = new Dt_DeliveryOrder
                                {
                                    Out_no = order.order_no,
                                    Out_type = order.order_type,
                                    Client_name = order.client_name,
                                    Account_time = order.account_time,
                                    OutStatus = "已完成",
                                    Client_no = order.client_no,
                                    Warehouse_no = WareCodeDJ,
                                    Details = order.details.Select(d => new Dt_DeliveryOrderDetail
                                    {
                                        Goods_no = d.goods_no,
                                        Order_qty = DJQty,
                                        Order_Outqty = DJQty,
                                        Batch_num = d.batch_num,
                                        Exp_date = d.exp_date,
                                        Reservoirarea = WareCodeDJ,
                                        OotDetailStatus = "已完成",
                                        Status = 2,
                                    }).ToList()
                                };
                                //Repository.AddData(cabinOrder);
                                //Db.InsertNav(cabinOrder).Include(it => it.Details).ExecuteCommand();
                                deliveryOrdersAdd.Add(cabinOrder);
                            }
                            #endregion
                            //这里
                            #region åˆ›å»ºç«‹åº“盘点单
                            var entityOrder = new Dt_DeliveryOrder
                            {
                                Out_no = order.order_no,
                                Out_type = order.order_type,
                                Client_no = order.client_no,
                                Account_time = order.account_time,
                                OutStatus = "新建",
                                Client_name = order.client_name,
                                Warehouse_no = WareCodeLK,
                                Details = order.details.Select(d => new Dt_DeliveryOrderDetail
                                {
                                    Goods_no = d.goods_no,
                                    Order_qty = Math.Abs(LkQty), //给下游WCS的是要整数
                                    Batch_num = d.batch_num,
                                    Exp_date = d.exp_date,
                                    Reservoirarea = WareCodeLK,
                                    OotDetailStatus = "新建",
                                    Status = 0,
                                }).ToList()
                            };
                            //Db.InsertNav(entityOrder).Include(it => it.Details).ExecuteCommand();
                            //Repository.AddData(entityOrder);
                            deliveryOrdersAdd.Add(entityOrder);
                            #endregion
                        }
                        //return WebResponseContent.Instance.OK("成功");
                    }
                    _unitOfWorkManage.BeginTran();
                    _supplyTaskHtyService.AddData(supplyTask_Hties);
                    _inventoryInfoService.UpdateData(infosUp);
                    _inventory_BatchServices.UpdateData(batchesUp);
                    BaseDal.Db.InsertNav(deliveryOrdersAdd).Include(it => it.Details).ExecuteCommand();
                    _unitOfWorkManage.CommitTran();
                }
                return WebResponseContent.Instance.OK("成功");
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                content.Error(ex.Message);
            }
            return content;
        }
        #endregion
        //盘点 æ‹¿æ•´ä¸ªæ‰¹æ¬¡ä¿¡æ¯è¡¨çš„商品批号和商品编号来进行盘点
@@ -874,7 +822,7 @@
            try
            {
                // 1️⃣ æŸ¥æ‰¾æŒ‡å®šæ‰¹æ¬¡ä¸Žç‰©æ–™çš„库存信息
                var batchInfo = BaseDal.Db.Queryable<Dt_Inventory_Batch>()
                var batchInfo = BaseDal.Db.CopyNew().Queryable<Dt_Inventory_Batch>()
                    .Where(x => x.BatchNo == batchNo && x.MaterielCode == goodsNo)
                    .First();
@@ -932,203 +880,11 @@
        }
        /// <summary>
        /// å‡ºåº“报完成接口
        /// æŸ¥è¯¢å‡ºåº“单列表
        /// </summary>
        /// <param name="out_no">出库单号</param>
        /// <param name="saveModel"></param>
        /// <returns></returns>
        public WebResponseContent CompleteAllOutOrders()
        {
            var responseContent = new WebResponseContent();
            try
            {
                // æŸ¥æ‰¾æ‰€æœ‰â€œå¼€å§‹â€çŠ¶æ€çš„å‡ºåº“å•
                var orders = BaseDal.Db.Queryable<Dt_DeliveryOrder>()
                    .Where(o => o.OutStatus == "开始")
                    .ToList();
                if (orders == null || !orders.Any())
                {
                    return responseContent.OK("暂无需要处理的出库单");
                }
                int successCount = 0;
                int failCount = 0;
                foreach (var order in orders)
                {
                    try
                    {
                        Db.Ado.BeginTran();
                        // æŸ¥è¯¢è¯¥å•的明细
                        var details = BaseDal.Db.Queryable<Dt_DeliveryOrderDetail>()
                            .Where(d => d.DeliveryOrderId == order.Id)
                            .ToList();
                        // åˆ¤æ–­æ˜Žç»†æ˜¯å¦å…¨éƒ¨å®Œæˆ
                        var completedCount = details.Count(d => d.OotDetailStatus == "已完成");
                        var totalCount = details.Count;
                        if (totalCount > 0 && completedCount == totalCount)
                        {
                            // æ›´æ–°çŠ¶æ€ä¸ºå·²å®Œæˆ
                            BaseDal.Db.Updateable<Dt_DeliveryOrder>()
                                .SetColumns(o => o.OutStatus == "已完成")
                                .Where(o => o.Id == order.Id)
                                .ExecuteCommand();
                            // è°ƒç”¨ä¸Šæ¸¸æŽ¥å£
                            var url = "http://121.37.118.63:80/GYZ2/95fck/outOrderOk";
                            var requestDate = new
                            {
                                order_no = order.Out_no
                            };
                            var result = HttpHelper.Post(url, requestDate.ToJsonString());
                            var response = JsonConvert.DeserializeObject<UpstreamOrderResponse>(result);
                            if (response.resultCode == "0")
                            {
                                // âœ… æ’入历史表(表头 + æ˜Žç»†ï¼‰
                                var orderHistory = new Dt_DeliveryOrder_Hty
                                {
                                    Id = order.Id,
                                    Out_no = order.Out_no,
                                    Out_type = order.Out_type,
                                    Client_no = order.Client_no,
                                    Client_name = order.Client_name,
                                    Account_time = order.Account_time,
                                    Warehouse_no = order.Warehouse_no,
                                    OutStatus = "已完成",
                                    Details = details.Select(d => new Dt_DeliveryOrderDetail
                                    {
                                        Id = d.Id,
                                        DeliveryOrderId = d.DeliveryOrderId,
                                        Reservoirarea = d.Reservoirarea,
                                        Goods_no = d.Goods_no,
                                        Order_qty = d.Order_qty,
                                        Batch_num = d.Batch_num,
                                        Exp_date = d.Exp_date,
                                        OotDetailStatus = d.OotDetailStatus,
                                        Status = d.Status
                                    }).ToList()
                                };
                                // æ’入表头历史
                                var historyId = BaseDal.Db.Insertable(orderHistory).ExecuteReturnIdentity();
                                // æ’入明细历史(带新外键)
                                var detailHistories = details.Select(d => new Dt_DeliveryOrderDetail_Hty
                                {
                                    Id = d.Id,
                                    DeliveryOrderId = order.Id,
                                    Reservoirarea = d.Reservoirarea,
                                    Goods_no = d.Goods_no,
                                    Order_qty = d.Order_qty,
                                    Batch_num = d.Batch_num,
                                    Exp_date = d.Exp_date,
                                    OotDetailStatus = d.OotDetailStatus,
                                    Status = d.Status
                                }).ToList();
                                BaseDal.Db.Insertable(detailHistories).ExecuteCommand();
                                // åˆ é™¤åŽŸå§‹æ•°æ®ï¼ˆæ˜Žç»† â†’ è¡¨å¤´ï¼‰
                                BaseDal.Db.Deleteable<Dt_DeliveryOrderDetail>().Where(d => d.DeliveryOrderId == order.Id).ExecuteCommand();
                                BaseDal.Db.Deleteable<Dt_DeliveryOrder>().Where(o => o.Id == order.Id).ExecuteCommand();
                                Db.Ado.CommitTran();
                                successCount++;
                            }
                            else
                            {
                                Db.Ado.RollbackTran();
                                failCount++;
                                SendErrorToUpstream(4, "", $"上游接口返回失败: {response.resultMsg}", order.Out_no);
                            }
                        }
                        else
                        {
                            // æœ‰æœªå®Œæˆæ˜Žç»†ï¼Œä¸æ›´æ–°
                            Db.Ado.RollbackTran();
                        }
                    }
                    catch (Exception ex)
                    {
                        Db.Ado.RollbackTran();
                        failCount++;
                        SendErrorToUpstream(1, "", ex.Message, order.Out_no);
                    }
                }
                return responseContent.OK($"批量处理完成:成功 {successCount} å•,失败 {failCount} å•。");
            }
            catch (Exception ex)
            {
                return responseContent.Error("批量处理失败:" + ex.Message);
            }
        }
        /// <summary>
        /// æŽ¨é€å¼‚常信息给上游系统 1.入库单接口;2.入库单报完成接口;3.出库单接口;4.出库报完成接口;5.药品基础信息同步接口;6.供应商信息接口;7.客户信息接口;8.库存查询接口
        /// </summary>
        public void SendErrorToUpstream(int type, string code, string message, string remark)
        {
            try
            {
                var url = "http://121.37.118.63:80/GYZ2/95fck/exceptionLog";
                var requestData = new
                {
                    type = type.ToString(),
                    code = code,
                    message = message,
                    remark = remark
                };
                var result = HttpHelper.Post(url, requestData.ToJsonString());
                // å¯ä»¥ååºåˆ—化检查 resultCode æ˜¯å¦ä¸º0
            }
            catch (Exception e)
            {
                // è¿™é‡Œä¸è¦å†æŠ›å¼‚常了,避免死循环
                Console.WriteLine("异常接口推送失败:" + e.Message);
            }
        }
        public WebResponseContent GetPdDeliveryOrders(SaveModel saveModel)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                int pageNo = saveModel.MainData["pageNo"].ObjToInt();
                string warehouseCode = saveModel.MainData["warehouseId"].ToString();
                string orderNo = saveModel.MainData["orderNo"].ToString();
                List<Dt_DeliveryOrder> dt_ReceiveOrders = new List<Dt_DeliveryOrder>();
                if (string.IsNullOrEmpty(orderNo))
                {
                    dt_ReceiveOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => (x.OutStatus == "新建" || x.OutStatus == "开始") && x.Warehouse_no == warehouseCode && x.Out_type == "3").Includes(x => x.Details).OrderByDescending(x => x.CreateDate).ToPageList(pageNo, 5);
                }
                else
                {
                    dt_ReceiveOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => (x.Out_no.Contains(orderNo) || x.Client_no.Contains(orderNo)) && (x.OutStatus == "新建" || x.OutStatus == "开始" && x.Out_type == "3") && x.Warehouse_no == warehouseCode).OrderByDescending(x => x.CreateDate).Includes(x => x.Details).ToPageList(pageNo, 5);
                }
                content.OK(data: dt_ReceiveOrders);
            }
            catch (Exception)
            {
                throw;
            }
            return content;
        }
        public WebResponseContent GetDeliveryOrders(SaveModel saveModel)
        {
            WebResponseContent content = new WebResponseContent();
@@ -1140,11 +896,11 @@
                List<Dt_DeliveryOrder> dt_ReceiveOrders = new List<Dt_DeliveryOrder>();
                if (string.IsNullOrEmpty(orderNo))
                {
                    dt_ReceiveOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => (x.OutStatus == "新建" || x.OutStatus == "开始") && x.Warehouse_no == warehouseCode && x.Out_type != "3").Includes(x => x.Details).OrderByDescending(x => x.CreateDate).ToPageList(pageNo, 5);
                    dt_ReceiveOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => (x.OutStatus == "新建" || x.OutStatus == "开始") && x.Warehouse_no == warehouseCode && x.Out_type != "20").Includes(x => x.Details).OrderByDescending(x => x.CreateDate).ToPageList(pageNo, 5);
                }
                else
                {
                    dt_ReceiveOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => (x.Out_no.Contains(orderNo) || x.Client_no.Contains(orderNo)) && (x.OutStatus == "新建" || x.OutStatus == "开始" && x.Out_type != "3") && x.Warehouse_no == warehouseCode).OrderByDescending(x => x.CreateDate).Includes(x => x.Details).ToPageList(pageNo, 5);
                    dt_ReceiveOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => (x.Out_no.Contains(orderNo) || x.Client_no.Contains(orderNo)) && (x.OutStatus == "新建" || x.OutStatus == "开始") && x.Out_type != "20" && x.Warehouse_no == warehouseCode).OrderByDescending(x => x.CreateDate).Includes(x => x.Details).ToPageList(pageNo, 5);
                }
                content.OK(data: dt_ReceiveOrders);
@@ -1157,101 +913,124 @@
            return content;
        }
        /// <summary>
        /// æŸ¥è¯¢å‡ºåº“/盘点单详情 çœ‹å‡ºåº“单明细。
        /// </summary>
        /// <param name="pageNo"></param>
        /// <param name="orderNo"></param>
        /// <param name="isPick"></param>
        /// <returns></returns>
        public WebResponseContent GetDeliveryOrderDetail(int pageNo, string orderNo, bool isPick)
        {
            WebResponseContent content = new WebResponseContent();
            Dt_DeliveryOrder cabinOrder = new Dt_DeliveryOrder();
            if (isPick)
                cabinOrder = Db.Queryable<Dt_DeliveryOrder>().Includes(x => x.Details).First(x => x.Out_no == orderNo && x.Out_type == "3");
                cabinOrder = Db.Queryable<Dt_DeliveryOrder>().Includes(x => x.Details).First(x => x.Out_no == orderNo && x.Out_type == "20");
            else
                cabinOrder = Db.Queryable<Dt_DeliveryOrder>().Includes(x => x.Details).First(x => x.Out_no == orderNo && x.Out_type != "3");
            List<Dt_DeliveryOrderDetail>? cabinOrderDetails = cabinOrder.Details?.Where(x => x.Reservoirarea == pageNo.ToString()).ToList();
                cabinOrder = Db.Queryable<Dt_DeliveryOrder>().Includes(x => x.Details).First(x => x.Out_no == orderNo && x.Out_type != "20");
            //List<Dt_DeliveryOrderDetail>? cabinOrderDetails = cabinOrder.Details?.Where(x => x.Reservoirarea == pageNo.ToString()).ToList();
            List<Dt_DeliveryOrderDetail>? cabinOrderDetails = cabinOrder.Details?.Where(x => x.Status == 2).ToList();
            content.OK(data: cabinOrderDetails);
            return content;
        }
        public WebResponseContent MatPicking(SaveModel saveModel)
        /// <summary>
        /// pad出库完成
        /// </summary>
        /// <param name="saveModel"></param>
        /// <returns></returns>
        public WebResponseContent OutFinish(SaveModel saveModel)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                var LocationCode = saveModel.MainData["LocationCode"].ToString();
                var orderNo = saveModel.MainData["orderNo"].ToString();
                var batchNo = saveModel.MainData["batchNo"].ToString();
                var Inqty = saveModel.MainData["Inqty"].ObjToInt();
                var warehouseCode = saveModel.MainData["warehouseCode"].ToString();
                Dt_DeliveryOrder cabinOrder = BaseDal.Db.Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == orderNo && x.Warehouse_no == warehouseCode && x.Out_type == "3").Includes(x => x.Details).First();
                if (cabinOrder == null) return WebResponseContent.Instance.Error($"盘点单已完成");
                Dt_DeliveryOrderDetail cabinOrderDetail = cabinOrder.Details.Where(x => x.Batch_num == batchNo && x.Reservoirarea == warehouseCode).First();
                if (cabinOrderDetail == null) return WebResponseContent.Instance.Error($"盘点单明细已完成");
                Dt_MaterielInfo materielInfo = _basicService.MaterielInfoService.Repository.QueryFirst(x => x.MaterielCode == cabinOrderDetail.Goods_no);
                if (materielInfo == null) return WebResponseContent.Instance.Error($"请维护物料编号【{cabinOrderDetail.Goods_no}】的物料信息");
                cabinOrderDetail.Order_Outqty += Inqty;
                if (cabinOrderDetail.Order_Outqty > cabinOrderDetail.Order_qty)
                    return WebResponseContent.Instance.Error($"实盘数量不可超出账面数量");
                #region å¤„理出库单,货位,库存,库存批次信息
                _unitOfWorkManage.BeginTran();
                #region å‡ºåº“单
                cabinOrder.OutStatus = "开始";
                var LocationCode = saveModel.MainData["locationCode"].ToString();
                var TaskId = saveModel.MainData["taskId"].ObjToInt();
                Dt_SupplyTask supplyTask = _supplyTaskService.Repository.QueryFirst(x => x.TaskId == TaskId && x.TaskStatus == SupplyStatusEnum.NewOut.ObjToInt());
                if (supplyTask == null) throw new Exception("当前出库任务已完成");
                if (supplyTask.LocationCode != LocationCode) throw new Exception($"当前出库货位【{LocationCode}】与任务分配货位不匹配");
                Dt_DeliveryOrder deliveryOrder = BaseDal.Db.Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == supplyTask.OrderNo && x.Warehouse_no == supplyTask.WarehouseCode).Includes(x => x.Details).First();
                if (deliveryOrder == null) return WebResponseContent.Instance.OK($"出库单已完成");
                content = OutTaskFinish(supplyTask, deliveryOrder);
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;
        }
        public WebResponseContent OutTaskFinish(Dt_SupplyTask supplyTask, Dt_DeliveryOrder deliveryOrder)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                Dt_DeliveryOrderDetail? cabinOrderDetail = deliveryOrder.Details.FirstOrDefault(x => x.Batch_num == supplyTask.BatchNo && x.Goods_no == supplyTask.MaterielCode);
                if (cabinOrderDetail == null) throw new Exception($"出库单明细未找到");
                Dt_MaterielInfo materielInfo = _materielInfoService.Repository.QueryFirst(x => x.MaterielCode == supplyTask.MaterielCode);
                if (materielInfo == null) throw new Exception($"请维护物料编号【{supplyTask.MaterielCode}】的物料信息");
                cabinOrderDetail.Order_Outqty += supplyTask.StockQuantity;
                if (cabinOrderDetail.Order_Outqty > cabinOrderDetail.Order_qty) throw new Exception($"出库数量不可超出单据数量");
                deliveryOrder.OutStatus = "开始";
                cabinOrderDetail.OotDetailStatus = "开始";
                if (cabinOrderDetail.Order_Outqty == cabinOrderDetail.Order_qty)
                {
                    cabinOrderDetail.OotDetailStatus = "已完成";
                    _deliveryOrderDetailServices.Repository.DeleteAndMoveIntoHty(cabinOrderDetail, OperateTypeEnum.自动完成);
                }
                else
                {
                    _deliveryOrderDetailServices.Repository.UpdateData(cabinOrderDetail);
                }
                var cabinOrder1 = BaseDal.Db.Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == cabinOrder.Out_no && x.Out_type == "3").Includes(x => x.Details).First();
                if (cabinOrder1.Details == null || cabinOrder1.Details.Count < 1) cabinOrder.OutStatus = "已完成";
                if (cabinOrder.OutStatus == "已完成")
                    Repository.DeleteAndMoveIntoHty(cabinOrder, OperateTypeEnum.自动完成);
                else
                    Repository.UpdateData(cabinOrder);
                #endregion
                if (cabinOrderDetail.Order_Outqty == cabinOrderDetail.Order_qty) cabinOrderDetail.OotDetailStatus = "已完成";
                #region åº“å­˜
                Dt_InventoryInfo inventoryInfo = _inventoryInfoService.Repository.QueryFirst(x => x.BatchNo == cabinOrderDetail.Batch_num && x.MaterielCode == cabinOrderDetail.Goods_no && x.LocationCode == LocationCode);
                if (inventoryInfo == null) return WebResponseContent.Instance.Error($"未找到货位【{LocationCode}】的库存信息");
                inventoryInfo.SupplyQuantity += Inqty;
                _inventoryInfoService.UpdateData(inventoryInfo);
                Dt_InventoryInfo inventoryInfo = _inventoryInfoService.Repository.QueryFirst(x => x.BatchNo == cabinOrderDetail.Batch_num && x.MaterielCode == cabinOrderDetail.Goods_no && x.LocationCode == supplyTask.LocationCode);
                if (inventoryInfo == null) throw new Exception($"未找到货位【{supplyTask.LocationCode}】的库存信息");
                inventoryInfo.StockQuantity -= supplyTask.StockQuantity;
                inventoryInfo.OutboundQuantity -= supplyTask.StockQuantity;
                #endregion
                #region ä»»åŠ¡è®°å½•
                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                Dt_LocationInfo location = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == supplyTask.LocationCode);
                #region è´§ä½
                if (supplyTask.WarehouseCode != WarehouseEnum.立库.ObjToInt().ToString("000"))
                {
                    WarehouseCode = cabinOrderDetail.Reservoirarea,
                    BatchNo = inventoryInfo.BatchNo,
                    MaterielName = inventoryInfo.MaterielName,
                    MaterielCode = inventoryInfo.MaterielCode,
                    MaterielSpec = inventoryInfo.MaterielSpec,
                    TaskType = TaskTypeEnum.OutInventory.ObjToInt(),
                    CreateDate = DateTime.Now,
                    Creater = App.User.UserName,
                    LocationCode = LocationCode,
                    OrderNo = cabinOrder.Out_no,
                    StockQuantity = inventoryInfo.StockQuantity,
                    SupplyQuantity = Inqty,
                    Remark = "盘点"
                };
                _supplyTaskService.AddData(supplyTask);
                #endregion
                #region åº“存批次
                Dt_Inventory_Batch inventory_Batch = _inventory_BatchServices.Repository.QueryFirst(x => x.BatchNo == inventoryInfo.BatchNo && x.MaterielCode == inventoryInfo.MaterielCode);
                if (inventory_Batch != null)
                {
                    inventory_Batch.SupplyQuantity += Inqty;
                    _inventory_BatchServices.UpdateData(inventory_Batch);
                    if (location == null)
                        return WebResponseContent.Instance.Error($"请维护货位编号【{supplyTask.LocationCode}】的货位信息");
                    Dt_InventoryInfo inventoryInfo1 = _inventoryInfoService.Repository.QueryFirst(x => x.LocationCode == supplyTask.LocationCode);
                    if (inventoryInfo1 == null) location.LocationStatus = LocationStatusEnum.Free.ObjToInt();
                }
                #endregion
                _unitOfWorkManage.CommitTran();
                #region åº“存批次 å¦‚果任务类型是调拨出库任务(8)就不修改批次库存
                Dt_Inventory_Batch inventory_Batch = _inventory_BatchServices.Repository.QueryFirst(x => x.BatchNo == inventoryInfo.BatchNo && x.MaterielCode ==
                    inventoryInfo.MaterielCode);
                if (supplyTask.TaskType != TaskTypeEnum.AllocatOut.ObjToInt())
                {
                    inventory_Batch.StockQuantity -= supplyTask.StockQuantity;
                    inventory_Batch.OutboundQuantity -= supplyTask.StockQuantity;
                }
                #endregion
                supplyTask.TaskStatus = SupplyStatusEnum.OutFinish.ObjToInt();
                content.OK(cabinOrderDetail.Order_Outqty.ToString());
                _unitOfWorkManage.BeginTran();
                if (inventory_Batch.StockQuantity <= 0)
                    _inventory_BatchServices.DeleteData(inventory_Batch);
                else
                    _inventory_BatchServices.UpdateData(inventory_Batch);
                _materielInfoService.UpdateData(materielInfo);
                if (inventoryInfo.StockQuantity <= 0)
                    _inventoryInfoService.DeleteData(inventoryInfo);
                else
                    _inventoryInfoService.UpdateData(inventoryInfo);
                if (location != null) _locationInfoService.UpdateData(location);
                _deliveryOrderDetailServices.UpdateData(cabinOrderDetail);
                _supplyTaskService.Repository.DeleteAndMoveIntoHty(supplyTask, OperateTypeEnum.人工完成);
                #region åˆ¤æ–­è¯¦æƒ…是否全部完成
                if (!_deliveryOrderDetailServices.Repository.QueryData(x => x.DeliveryOrderId == deliveryOrder.Id && x.OotDetailStatus != "已完成").Any())
                    deliveryOrder.OutStatus = "已完成";
                BaseDal.UpdateData(deliveryOrder);
                if (supplyTask.WarehouseCode == WarehouseEnum.立库.ObjToInt().ToString("000"))
                {
                    materielInfo.Business_qty -= supplyTask.StockQuantity;
                    if (materielInfo.Business_qty < materielInfo.MinQty)
                        CreateAllocatInOut(materielInfo);//创建调拨任务
                }
                #endregion
                _unitOfWorkManage.CommitTran();
                content.OK();
            }
            catch (Exception ex)
            {
@@ -1260,28 +1039,25 @@
            }
            return content;
        }
        public WebResponseContent FeedbackOut(SaveModel saveModel)
        public WebResponseContent OutTaskFinish(Dt_SupplyTask supplyTask)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                var LocationCode = saveModel.MainData["LocationCode"].ToString();
                var orderNo = saveModel.MainData["orderNo"].ToString();
                var batchNo = saveModel.MainData["batchNo"].ToString();
                var Inqty = saveModel.MainData["Inqty"].ObjToInt();
                var warehouseCode = saveModel.MainData["warehouseCode"].ToString();
                Dt_DeliveryOrder cabinOrder = BaseDal.Db.Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == orderNo && x.Warehouse_no == warehouseCode && x.Out_type != "3").Includes(x => x.Details).First();
                if (cabinOrder == null) return WebResponseContent.Instance.Error($"出库单已完成");
                Dt_DeliveryOrderDetail cabinOrderDetail = cabinOrder.Details.Where(x => x.Batch_num == batchNo && x.Reservoirarea == warehouseCode).First();
                if (cabinOrderDetail == null) return WebResponseContent.Instance.Error($"出库单明细已完成");
                Dt_MaterielInfo materielInfo = _basicService.MaterielInfoService.Repository.QueryFirst(x => x.MaterielCode == cabinOrderDetail.Goods_no);
                Dt_DeliveryOrder? cabinOrder = BaseDal.Db.CopyNew().Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == supplyTask.OrderNo && x.Warehouse_no == supplyTask.WarehouseCode).Includes(x => x.Details).First();
                if (cabinOrder == null) return WebResponseContent.Instance.OK($"出库单已完成");
                Dt_DeliveryOrderDetail? cabinOrderDetail = cabinOrder.Details.Where(x => x.Batch_num == supplyTask.BatchNo && x.Reservoirarea == supplyTask.WarehouseCode && x.Goods_no == supplyTask.MaterielCode).FirstOrDefault();
                if (cabinOrderDetail == null) return WebResponseContent.Instance.Error($"出库单明细未找到");
                Dt_MaterielInfo materielInfo = _materielInfoService.Repository.QueryFirst(x => x.MaterielCode == cabinOrderDetail.Goods_no);
                if (materielInfo == null) return WebResponseContent.Instance.Error($"请维护物料编号【{cabinOrderDetail.Goods_no}】的物料信息");
                cabinOrderDetail.Order_Outqty += Inqty;
                cabinOrderDetail.Order_Outqty += supplyTask.StockQuantity;
                if (cabinOrderDetail.Order_Outqty > cabinOrderDetail.Order_qty)
                    return WebResponseContent.Instance.Error($"出库数量不可超出单据数量");
                #region å¤„理出库单,货位,库存,库存批次信息
                _unitOfWorkManage.BeginTran();
                #region å¤„理出库单,货位,库存,库存批次信息,出库任务
                //_unitOfWorkManage.BeginTran();
                #region å‡ºåº“单
                cabinOrder.OutStatus = "开始";
@@ -1289,21 +1065,20 @@
                if (cabinOrderDetail.Order_Outqty == cabinOrderDetail.Order_qty)
                {
                    cabinOrderDetail.OotDetailStatus = "已完成";
                    _deliveryOrderDetailServices.Repository.DeleteAndMoveIntoHty(cabinOrderDetail, OperateTypeEnum.自动完成);
                    //_deliveryOrderDetailServices.Repository.DeleteAndMoveIntoHty(cabinOrderDetail, OperateTypeEnum.自动完成);
                }
                else
                {
                    _deliveryOrderDetailServices.Repository.UpdateData(cabinOrderDetail);
                }
                var cabinOrder1 = BaseDal.Db.Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == cabinOrder.Out_no && x.Out_type != "3").Includes(x => x.Details).First();
                if (cabinOrder1.Details == null || cabinOrder1.Details.Count < 1) cabinOrder.OutStatus = "已完成";
                _deliveryOrderDetailServices.Repository.UpdateData(cabinOrderDetail);
                var cabinOrder1 = BaseDal.Db.CopyNew().Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == cabinOrder.Out_no && x.Warehouse_no == supplyTask.WarehouseCode && x.Out_type != "20").Includes(x => x.Details).First();
                if (!cabinOrder1.Details.Where(x => x.OotDetailStatus != "已完成").Any())
                    cabinOrder.OutStatus = "已完成";
                Repository.UpdateData(cabinOrder);
                #endregion
                #region åº“å­˜
                Dt_InventoryInfo inventoryInfo = _inventoryInfoService.Repository.QueryFirst(x => x.BatchNo == cabinOrderDetail.Batch_num && x.MaterielCode == cabinOrderDetail.Goods_no && x.LocationCode == LocationCode);
                if (inventoryInfo == null) return WebResponseContent.Instance.Error($"未找到货位【{LocationCode}】的库存信息");
                inventoryInfo.StockQuantity -= Inqty;
                Dt_InventoryInfo inventoryInfo = _inventoryInfoService.Repository.QueryFirst(x => x.BatchNo == cabinOrderDetail.Batch_num && x.MaterielCode == cabinOrderDetail.Goods_no && x.LocationCode == supplyTask.LocationCode);
                if (inventoryInfo == null) return WebResponseContent.Instance.Error($"未找到货位【{supplyTask.LocationCode}】的库存信息");
                inventoryInfo.StockQuantity -= supplyTask.StockQuantity;
                inventoryInfo.OutboundQuantity -= supplyTask.StockQuantity;
                if (inventoryInfo.StockQuantity <= 0)
                    _inventoryInfoService.DeleteData(inventoryInfo);
                else
@@ -1311,58 +1086,104 @@
                #endregion
                #region è´§ä½
                var location = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == LocationCode);
                if (location == null) return WebResponseContent.Instance.Error($"请维护货位编号【{LocationCode}】的货位信息");
                if (location.EnableStatus == EnableStatusEnum.Disable.ObjToInt())
                    return WebResponseContent.Instance.Error($"货位编号【{LocationCode}】已禁用,请恢复正常再使用");
                Dt_InventoryInfo inventoryInfo1 = _inventoryInfoService.Repository.QueryFirst(x => x.LocationCode == LocationCode);
                if (inventoryInfo1 == null)
                if (supplyTask.WarehouseCode != WarehouseEnum.立库.ObjToInt().ToString("000"))
                {
                    location.LocationStatus = LocationStatusEnum.Free.ObjToInt();
                    _basicService.LocationInfoService.UpdateData(location);
                    var location = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == supplyTask.LocationCode);
                    if (location == null)
                        return WebResponseContent.Instance.Error($"请维护货位编号【{supplyTask.LocationCode}】的货位信息");
                    //if (location.EnableStatus == EnableStatusEnum.Disable.ObjToInt())
                    //    return WebResponseContent.Instance.Error($"货位编号【{supplyTask.LocationCode}】已禁用,请恢复正常再使用");
                    Dt_InventoryInfo inventoryInfo1 = _inventoryInfoService.Repository.QueryFirst(x => x.LocationCode == supplyTask.LocationCode);
                    if (inventoryInfo1 == null)
                    {
                        location.LocationStatus = LocationStatusEnum.Free.ObjToInt();
                        _locationInfoService.UpdateData(location);
                    }
                }
                #endregion
                #region ä»»åŠ¡è®°å½•
                Dt_SupplyTask supplyTask = new Dt_SupplyTask()
                {
                    WarehouseCode = cabinOrderDetail.Reservoirarea,
                    BatchNo = inventoryInfo.BatchNo,
                    MaterielName = inventoryInfo.MaterielName,
                    MaterielCode = inventoryInfo.MaterielCode,
                    MaterielSpec = inventoryInfo.MaterielSpec,
                    TaskType = TaskTypeEnum.OutPick.ObjToInt(),
                    CreateDate = DateTime.Now,
                    Creater = App.User.UserName,
                    LocationCode = location.LocationCode,
                    OrderNo = cabinOrder.Out_no,
                    StockQuantity = Inqty,
                    SupplyQuantity = 0,
                    Remark = "出库"
                };
                _supplyTaskService.AddData(supplyTask);
                #endregion
                //_supplyTaskService.UpdateData(supplyTask);
                supplyTask.TaskNum = cabinOrderDetail.Id;
                supplyTask.TaskStatus = SupplyStatusEnum.OutFinish.ObjToInt();
                _supplyTaskService.Repository.DeleteAndMoveIntoHty(supplyTask, OperateTypeEnum.人工完成);
                #region åº“存批次
                Dt_Inventory_Batch inventory_Batch = _inventory_BatchServices.Repository.QueryFirst(x => x.BatchNo == inventoryInfo.BatchNo && x.MaterielCode == inventoryInfo.MaterielCode);
                if (inventory_Batch != null)
                #region åº“存批次 å¦‚果任务类型是调拨出库任务(8)就不修改批次库存
                if (supplyTask.TaskType != TaskTypeEnum.AllocatOut.ObjToInt())
                {
                    inventory_Batch.StockQuantity -= Inqty;
                    if (inventory_Batch.StockQuantity <= 0)
                        _inventory_BatchServices.DeleteData(inventory_Batch);
                    else
                        _inventory_BatchServices.UpdateData(inventory_Batch);
                    Dt_Inventory_Batch inventory_Batch = _inventory_BatchServices.Repository.QueryFirst(x => x.BatchNo == inventoryInfo.BatchNo && x.MaterielCode == inventoryInfo.MaterielCode);
                    if (inventory_Batch != null)
                    {
                        inventory_Batch.StockQuantity -= supplyTask.StockQuantity;
                        inventory_Batch.OutboundQuantity -= supplyTask.StockQuantity;
                        if (inventory_Batch.StockQuantity <= 0)
                            _inventory_BatchServices.DeleteData(inventory_Batch);
                        else
                            _inventory_BatchServices.UpdateData(inventory_Batch);
                    }
                }
                #endregion
                _unitOfWorkManage.CommitTran();
                if (supplyTask.WarehouseCode == WarehouseEnum.立库.ObjToInt().ToString("000"))
                {
                    materielInfo.Business_qty -= supplyTask.StockQuantity;
                    _materielInfoService.UpdateData(materielInfo);
                    if (materielInfo.Business_qty < materielInfo.MinQty)
                        CreateAllocatInOut(materielInfo);//创建调拨任务
                }
                //_unitOfWorkManage.CommitTran();
                #endregion
                content.OK(cabinOrderDetail.Order_Outqty.ToString());
                content.OK();
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                content.Error(ex.Message);
            }
            return content;
        }
        /// <summary>
        /// äººå·¥åœ¨å‡ºåº“单中点击完成按钮实现上报
        /// </summary>
        /// <param name="key">id</param>
        /// <returns></returns>
        public WebResponseContent FinishOutOrder(int key)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                Dt_DeliveryOrder deliveryOrder = BaseDal.QueryFirst(x => x.Id == key);
                List<Dt_DeliveryOrder> deliveryOrders = Db.Queryable<Dt_DeliveryOrder>().Where(x => x.Out_no == deliveryOrder.Out_no).Includes(x => x.Details).ToList();//找出所有出库单号相同的出库单
                List<Dt_DeliveryOrderDetail> deliveryOrderDetails = new List<Dt_DeliveryOrderDetail>();
                foreach (var item in deliveryOrders)
                {
                    if (item.Details != null) deliveryOrderDetails.AddRange(item.Details);
                    item.Modifier = App.User.UserName;
                    item.ModifyDate = DateTime.Now;
                    item.Details = null;
                }
                if (deliveryOrder.Out_type == OutOrderTypeEnum.Allocate.ObjToInt().ToString())
                {
                    _deliveryOrderDetailServices.Repository.DeleteAndMoveIntoHty(deliveryOrderDetails, OperateTypeEnum.人工完成);
                    BaseDal.DeleteAndMoveIntoHty(deliveryOrders, OperateTypeEnum.人工完成);
                }
                else
                {
                    var url = "http://121.37.118.63:80/GYZ2/95fck/outOrderOk";
                    if (deliveryOrder.Out_type == "3") url = "http://121.37.118.63:80/GYZ2/95fck/inOrderOk";
                    var requestDate = new
                    {
                        order_no = deliveryOrder.Out_no
                    };
                    var result = HttpHelper.Post(url, requestDate.ToJsonString());
                    var response = JsonConvert.DeserializeObject<UpstreamOrderResponse>(result);
                    if (response == null) throw new Exception("上报ERP出库单完成失败!");
                    if (response.resultCode != "0" && response.resultMsg != "未找到合法单据") throw new Exception(response.resultMsg);
                    _deliveryOrderDetailServices.Repository.DeleteAndMoveIntoHty(deliveryOrderDetails, OperateTypeEnum.人工完成);
                    BaseDal.DeleteAndMoveIntoHty(deliveryOrders, OperateTypeEnum.人工完成);
                }
                content.OK();
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;