| using System; | 
| using System.Collections.Generic; | 
| using System.Linq; | 
| using System.Text; | 
| using System.Threading.Tasks; | 
| using WIDESEA_Core.BaseServices; | 
| using WIDESEA_Core; | 
| using WIDESEA_IInboundRepository; | 
| using WIDESEA_IInboundService; | 
| using WIDESEA_Model.Models; | 
| using WIDESEA_DTO.ERP; | 
| using WIDESEA_Core.BaseRepository; | 
| using WIDESEA_IBasicRepository; | 
| using WIDESEA_IOutboundService; | 
| using WIDESEA_Common.OrderEnum; | 
| using WIDESEA_Common.CommonEnum; | 
| using WIDESEA_Core.Helper; | 
| using Microsoft.AspNetCore.Mvc.RazorPages; | 
| using WIDESEA_External.ERPService; | 
| using WIDESEA_InboundRepository; | 
| using WIDESEA_IStockRepository; | 
| using WIDESEA_Common.StockEnum; | 
| using WIDESEA_Core.Enums; | 
| using WIDESEA_External.Model; | 
| using SqlSugar; | 
|   | 
| namespace WIDESEA_InboundService | 
| { | 
|     public class TakeStockOrderService : ServiceBase<Dt_TakeStockOrder, ITakeStockOrderRepository>, ITakeStockOrderService | 
|     { | 
|         public ITakeStockOrderRepository Repository => BaseDal; | 
|         private readonly IUnitOfWorkManage _unitOfWorkManage; | 
|         private readonly IBasicRepository _basicRepository; | 
|         private readonly IInvokeERPService _invokeERPService; | 
|         private readonly ITakeStockOrderDetailRepository _takeStockOrderDetailRepository; | 
|         private readonly IStockInfoRepository _stockInfoRepository; | 
|         private readonly IStockInfoDetailRepository _stockInfoDetailRepository; | 
|         public TakeStockOrderService(ITakeStockOrderRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IBasicRepository basicRepository,IInvokeERPService invokeERPService,ITakeStockOrderDetailRepository takeStockOrderDetailRepository,IStockInfoRepository stockInfoRepository,IStockInfoDetailRepository stockInfoDetailRepository) : base(BaseDal) | 
|         { | 
|             _unitOfWorkManage = unitOfWorkManage; | 
|             _basicRepository = basicRepository; | 
|             _invokeERPService = invokeERPService; | 
|             _takeStockOrderDetailRepository= takeStockOrderDetailRepository; | 
|             _stockInfoRepository= stockInfoRepository; | 
|             _stockInfoDetailRepository= stockInfoDetailRepository; | 
|         } | 
|         /// <summary> | 
|         /// 新增 | 
|         /// </summary> | 
|         public override WebResponseContent AddData(SaveModel saveModel) | 
|         { | 
|             Dt_Warehouse? warehouse = null; | 
|             if (saveModel.MainData.TryGetValue(nameof(Dt_TakeStockOrder.WarehouseId).FirstLetterToLower(), out object? warehouseId) && warehouseId != null && !string.IsNullOrEmpty(warehouseId.ToString())) | 
|             { | 
|                 warehouse = _basicRepository.WarehouseRepository.QueryFirst(x => x.WarehouseId == warehouseId.ObjToInt()); | 
|                 if (warehouse == null) | 
|                     return WebResponseContent.Instance.Error("未找到仓库信息"); | 
|             } | 
|   | 
|             if (saveModel.DetailData.Count>0) | 
|             { | 
|                 for (int i = 0; i < saveModel.DetailData.Count; i++) | 
|                 { | 
|                     if (saveModel.DetailData[i].TryGetValue(nameof(Dt_TakeStockOrderDetail.MaterielCode).FirstLetterToLower(), out object? materielCode) && materielCode != null && !string.IsNullOrEmpty(materielCode.ToString())) | 
|                     { | 
|                         Dt_MaterielInfo materielInfo = _basicRepository.MaterielInfoRepository.QueryFirst(x => x.MaterielCode == materielCode.ToString() && x.WarehouseId == warehouse.WarehouseId); | 
|                         if (materielInfo == null) return WebResponseContent.Instance.Error($"未找到本仓库物料{materielCode}信息"); | 
|                         saveModel.DetailData[i].Add(nameof(Dt_TakeStockOrderDetail.MaterielName).FirstLetterToLower(),materielInfo.MaterielName); | 
|                         saveModel.DetailData[i].Add(nameof(Dt_TakeStockOrderDetail.MaterielSpec).FirstLetterToLower(), materielInfo.MaterielSpec); | 
|                         saveModel.DetailData[i].Add(nameof(Dt_TakeStockOrderDetail.Unit).FirstLetterToLower(), materielInfo.MaterielUnit); | 
|                     } | 
|                 } | 
|             } | 
|             saveModel.MainData.Add(nameof(Dt_TakeStockOrder.TakeStockStatus).FirstLetterToLower(), TakeStockStatusEnum.未盘点.ObjToInt()); | 
|             return base.AddData(saveModel);  | 
|         } | 
|         /// <summary> | 
|         /// 获取对应仓库盘点单 | 
|         /// </summary> | 
|         /// <returns></returns> | 
|         public WebResponseContent GetTakeStockOrders(SaveModel saveModel) | 
|         { | 
|             WebResponseContent content =new WebResponseContent(); | 
|             try | 
|             { | 
|                 int pageNo = saveModel.MainData["pageNo"].ObjToInt(); | 
|                 string? orderNo = saveModel.MainData["orderNo"].ToString(); | 
|                 int warehouseId = saveModel.MainData["warehouseId"].ObjToInt(); | 
|                 List<Dt_TakeStockOrder> takeStockOrders = new List<Dt_TakeStockOrder>(); | 
|                 if (string.IsNullOrEmpty(orderNo)) | 
|                 { | 
|                     takeStockOrders = Db.Queryable<Dt_TakeStockOrder>().Where(x => x.TakeStockStatus < TakeStockStatusEnum.盘点完成.ObjToInt() && x.WarehouseId == warehouseId).ToPageList(pageNo, 5); | 
|                 } | 
|                 else | 
|                 { | 
|                     takeStockOrders = Db.Queryable<Dt_TakeStockOrder>().Where(x => (x.OrderNo.Contains(orderNo) && x.TakeStockStatus < TakeStockStatusEnum.盘点完成.ObjToInt() && x.WarehouseId == warehouseId)).ToPageList(pageNo, 5); | 
|                 } | 
|                 content.OK(data: takeStockOrders); | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 通过盘点单号+框号获取盘点信息详情 | 
|         /// </summary> | 
|         /// <param name="saveModel"></param> | 
|         /// <returns></returns> | 
|         public WebResponseContent GetTakeDetailInfo(SaveModel saveModel) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 string? orderNo = saveModel.MainData["orderNo"].ToString(); | 
|                 string? takePalletCode = saveModel.MainData["takePalletCode"].ToString(); | 
|                 Dt_TakeStockOrderDetail takeStockOrderDetail=new Dt_TakeStockOrderDetail(); | 
|                 if (!string.IsNullOrEmpty(orderNo) && !string.IsNullOrEmpty(takePalletCode)) | 
|                 { | 
|                     //获取盘点明细 | 
|                     takeStockOrderDetail = BaseDal.Db.Queryable<Dt_TakeStockOrder, Dt_TakeStockOrderDetail>((master, detail) => master.Id == detail.TakeStockId) | 
|                     .Where((master, detail) => master.OrderNo == orderNo && detail.TakePalletCode== takePalletCode) | 
|                     .Select((master, detail) => detail).First(); | 
|                     if (takeStockOrderDetail==null) | 
|                     { | 
|                         return content.Error($"盘点单{orderNo}中未找到{takePalletCode}盘点明细"); | 
|                     } | 
|                     if (takeStockOrderDetail.TakeDetalStatus != TakeStockDetailStatusEnum.盘点出库完成.ObjToInt()) | 
|                     { | 
|                         return content.Error($"盘点单{orderNo}中未找到{takePalletCode}可盘状态"); | 
|                     } | 
|                     Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x=>x.PalletCode== takePalletCode && x.StockStatus==StockStatusEmun.盘点出库完成.ObjToInt()).Includes(x=>x.Details).First(); | 
|                     if (stockInfo == null) | 
|                     { | 
|                         return content.Error($"未找到{takePalletCode}盘点库存状态"); | 
|                     } | 
|                     content.OK(data: takeStockOrderDetail); | 
|                 } | 
|                 else | 
|                 { | 
|                     return content.Error("请求信息为空"); | 
|                 } | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         /// <summary> | 
|         /// 盘点操作 | 
|         /// </summary> | 
|         /// <param name="saveModel"></param> | 
|         /// <returns></returns> | 
|         public WebResponseContent MatPicking(SaveModel saveModel) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 int id = saveModel.MainData["id"].ObjToInt(); | 
|                 decimal stockNum =saveModel.MainData["num"].ObjToDecimal(); | 
|                 if (stockNum<0) | 
|                 { | 
|                     return content.Error("盘亏不能为负"); | 
|                 } | 
|                 if (id>0) | 
|                 { | 
|                     //获取盘点详情 | 
|                     Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetailRepository.QueryFirst(x=>x.Id== id); | 
|                     if (takeStockOrderDetail.TakeDetalStatus != TakeStockDetailStatusEnum.盘点出库完成.ObjToInt()) | 
|                     { | 
|                         return content.Error("非可盘点状态"); | 
|                     } | 
|                     Dt_TakeStockOrder takeStockOrder = BaseDal.Db.Queryable<Dt_TakeStockOrder>().Where(x => x.Id == takeStockOrderDetail.TakeStockId).Includes(x => x.Details).First(); | 
|                     if (takeStockOrder.TakeStockStatus != TakeStockStatusEnum.盘点中.ObjToInt()) | 
|                     { | 
|                         return content.Error("非可盘点状态"); | 
|                     } | 
|                     //获取库存 | 
|                     Dt_StockInfo stockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == takeStockOrderDetail.TakePalletCode && x.StockStatus == StockStatusEmun.盘点出库完成.ObjToInt()).Includes(x => x.Details).First(); | 
|                     List<Dt_StockInfoDetail> addStockDetails = new List<Dt_StockInfoDetail>(); | 
|                     List<Dt_StockInfoDetail> delStockDetails = new List<Dt_StockInfoDetail>(); | 
|                     List<Dt_StockInfoDetail> updateStockDetails = new List<Dt_StockInfoDetail>(); | 
|                     if (stockInfo == null || stockInfo.Details.Count<=0 || stockInfo.Details==null) | 
|                     { | 
|                         return content.Error("未找到库存"); | 
|                     } | 
|                     takeStockOrderDetail.Qty = (float)stockNum; | 
|                     takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.盘点完成.ObjToInt(); | 
|                     int stockCount=stockInfo.Details.Count; | 
|                     //判断是否盘赢还是盘亏 | 
|                     if (takeStockOrderDetail.SysQty< takeStockOrderDetail.Qty) //盘赢 | 
|                     { | 
|                         //float stockMaxQty = stockInfo.Details.Max(x => x.StockQuantity); | 
|                         //float stockMinQty = stockInfo.Details.Min(x => x.StockQuantity); | 
|                         Dt_StockInfoDetail? addstockInfoDetail = stockInfo.Details?.FirstOrDefault(); | 
|                         addstockInfoDetail.Id = 0; | 
|                         addstockInfoDetail.StockQuantity = (takeStockOrderDetail.Qty - takeStockOrderDetail.SysQty); | 
|                         addStockDetails.Add(addstockInfoDetail); | 
|                     } | 
|                     else if (takeStockOrderDetail.Qty==0) //盘亏 | 
|                     { | 
|                         delStockDetails.AddRange(stockInfo.Details); | 
|                     } | 
|                     else if(takeStockOrderDetail.SysQty > takeStockOrderDetail.Qty) //盘亏 | 
|                     { | 
|                         decimal totalQty = (takeStockOrderDetail.SysQty - takeStockOrderDetail.Qty).ObjToDecimal(); | 
|                         while (totalQty>0) | 
|                         { | 
|                             Dt_StockInfoDetail addstockInfoDetail=stockInfo.Details.OrderByDescending(x => x.Id).FirstOrDefault(); | 
|                             decimal stockQty = addstockInfoDetail.StockQuantity.ObjToDecimal(); | 
|                             if (stockQty < totalQty) | 
|                             { | 
|                                 delStockDetails.Add(addstockInfoDetail); | 
|                                 stockInfo.Details.Remove(addstockInfoDetail); | 
|                                 totalQty -= stockQty; | 
|                             } | 
|                             else if (stockQty >= totalQty) | 
|                             { | 
|                                 stockQty-=totalQty; | 
|                                 if (stockQty==0) | 
|                                 { | 
|                                     delStockDetails.Add(addstockInfoDetail); | 
|                                     stockInfo.Details.Remove(addstockInfoDetail); | 
|                                 } | 
|                                 else | 
|                                 { | 
|                                     addstockInfoDetail.StockQuantity = (float)stockQty; | 
|                                     updateStockDetails.Add(addstockInfoDetail); | 
|                                     stockInfo.Details.Remove(addstockInfoDetail); | 
|                                 } | 
|                                 totalQty = 0; | 
|                             } | 
|                              | 
|                         } | 
|                     } | 
|                     List<Dt_TakeStockOrderDetail> takeStockOrderDetails=new List<Dt_TakeStockOrderDetail>(); | 
|                     Dt_Warehouse warehouse = _basicRepository.WarehouseRepository.QueryFirst(x=>x.WarehouseId==takeStockOrder.WarehouseId); | 
|                     List<Dt_TakeStockOrderDetail> overTakeStockOrderDetails = takeStockOrder.Details.Where(x => x.TakeDetalStatus == TakeStockDetailStatusEnum.盘点完成.ObjToInt()).ToList(); | 
|                     if ((overTakeStockOrderDetails.Count + 1) == takeStockOrder.Details.Count) | 
|                     { | 
|                         takeStockOrder.TakeStockStatus = TakeStockStatusEnum.盘点完成.ObjToInt(); | 
|                         takeStockOrderDetails.AddRange(overTakeStockOrderDetails); | 
|                         takeStockOrderDetails.Add(takeStockOrderDetail); | 
|                     } | 
|                     //数据操作 | 
|                     _unitOfWorkManage.BeginTran(); | 
|                     if (stockCount== delStockDetails.Count) | 
|                     { | 
|                         _stockInfoRepository.DeleteAndMoveIntoHty(stockInfo, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成); | 
|                     } | 
|                     else | 
|                     { | 
|                         stockInfo.StockStatus = StockStatusEmun.盘点库存完成.ObjToInt(); | 
|                         _stockInfoRepository.UpdateData(stockInfo); | 
|                         if (stockInfo.Details!=null && stockInfo.Details.Count>0) | 
|                         { | 
|                             stockInfo.Details.ForEach(x => | 
|                             { | 
|                                 x.Status = StockStatusEmun.盘点库存完成.ObjToInt(); | 
|                             }); | 
|                         } | 
|                     } | 
|                     if (delStockDetails.Count>0) | 
|                     { | 
|                         _stockInfoDetailRepository.DeleteAndMoveIntoHty(delStockDetails, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成); | 
|                     } | 
|                     if (addStockDetails.Count>0) | 
|                     { | 
|                         addStockDetails.ForEach(x => | 
|                         { | 
|                             x.Status = StockStatusEmun.盘点库存完成.ObjToInt(); | 
|                         }); | 
|                         _stockInfoDetailRepository.AddData(addStockDetails); | 
|                     } | 
|                     if (updateStockDetails.Count>0) | 
|                     { | 
|                         updateStockDetails.ForEach(x => | 
|                         { | 
|                             x.Status = StockStatusEmun.盘点库存完成.ObjToInt(); | 
|                         }); | 
|                         _stockInfoDetailRepository.UpdateData(updateStockDetails); | 
|                     } | 
|                     _takeStockOrderDetailRepository.UpdateData(takeStockOrderDetail); | 
|                     BaseDal.UpdateData(takeStockOrder); | 
|                     //提交ERP逻辑 | 
|                     //if (takeStockOrder.TakeStockStatus== TakeStockStatusEnum.盘点完成.ObjToInt()) | 
|                     //{ | 
|                     //    ERPTakeStockModel eRPTakeStock = new ERPTakeStockModel() | 
|                     //    { | 
|                     //        Way = 1, | 
|                     //        UniqueTag = takeStockOrder.Id.ToString(), | 
|                     //        Code = takeStockOrder.OrderNo, | 
|                     //        FiscalPeriotime = takeStockOrder.CreateDate.ToString("yyyy-MM-dd"), | 
|                     //        Name=takeStockOrder.OrderNo, | 
|                     //        WarehouseCode= warehouse.WarehouseCode, | 
|                     //        Createuser=takeStockOrder.Creater, | 
|                     //        Createtime= takeStockOrder.CreateDate.ToString("yyyy-MM-dd HH:mm:ss"), | 
|                     //        Details=new List<TakeDetailsItem>() | 
|                     //    }; | 
|                     //    foreach (var item in takeStockOrderDetails) | 
|                     //    { | 
|                     //        TakeDetailsItem takeDetailsItem = new TakeDetailsItem() | 
|                     //        { | 
|                     //            MaterialsCode=item.MaterielCode, | 
|                     //            LocationCode=item.LocationCode, | 
|                     //            Lotno=item.BatchNo, | 
|                     //            Sysqty=item.SysQty.ObjToDecimal(), | 
|                     //            Qty=item.Qty.ObjToDecimal() | 
|                     //        }; | 
|                     //        eRPTakeStock.Details.Add(takeDetailsItem); | 
|                     //    } | 
|                     //    string response = _invokeERPService.InvokeTakeStockApi(eRPTakeStock); | 
|                     //    ErpRequestContent erpRequestContent = response.DeserializeObject<ErpRequestContent>(); | 
|                     //    if (erpRequestContent.res != 1) | 
|                     //    { | 
|                     //        throw new Exception("同步ERP失败,错误信息:" + erpRequestContent.Data); | 
|                     //    } | 
|                     //} | 
|                     _unitOfWorkManage.CommitTran(); | 
|                     content.OK("盘点成功"); | 
|                 } | 
|                 else | 
|                 { | 
|                     return content.Error("请求信息为空"); | 
|                 } | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 _unitOfWorkManage.RollbackTran(); | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|         public WebResponseContent DisEnableTakeOrder(int id) | 
|         { | 
|             WebResponseContent content = new WebResponseContent(); | 
|             try | 
|             { | 
|                 //获取盘点单 | 
|                 Dt_TakeStockOrder takeStockOrder = BaseDal.QueryFirst(x=>x.Id==id); | 
|                 if (takeStockOrder!=null) | 
|                 { | 
|                     takeStockOrder.TakeStockStatus = TakeStockStatusEnum.盘点关闭.ObjToInt(); | 
|                     BaseDal.UpdateData(takeStockOrder); | 
|                     content.OK("关闭盘点成功!"); | 
|                 } | 
|             } | 
|             catch (Exception ex) | 
|             { | 
|                 content.Error(ex.Message); | 
|             } | 
|             return content; | 
|         } | 
|     } | 
| } |