using Admin.NET.Core.Service; using Admin.NET.Application.Entity; using Microsoft.AspNetCore.Http; using StackExchange.Redis; using Admin.NET.Application; using MimeKit; using static SKIT.FlurlHttpClient.Wechat.Api.Models.ProductOrderGetResponse.Types.Order.Types; using System.Linq.Dynamic.Core; using Admin.NET.Core; using AngleSharp.Dom; using Admin.NET.Core.Helper.ExcelHelper; using System.Web; using System.Data; using System.Text; using Newtonsoft.Json; namespace Admin.NET.Application; /// /// 采购订单服务 /// [ApiDescriptionSettings(ApplicationConst.WmsOrderGroupName, Order = 100)] public class WmsOrderPurchaseService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _purchaseOrderDetailsRep; private readonly SqlSugarRepository _BaseCustomerRep; private readonly SqlSugarRepository _wmsMaterialRep; private readonly SqlSugarRepository _v_ware_PurchaseOrderDetailsForPDARep; private readonly SqlSugarRepository _WmsBaseBusinessTypeRep; private readonly SqlSugarRepository _WmsNoCreateRuleRep; private readonly SqlSugarRepository _repSNRep; private readonly SqlSugarRepository _repAdapterManagement; private readonly SqlSugarRepository _repAdapterCategories; private readonly SqlSugarRepository _repRecordAdapter; private readonly SqlSugarRepository _wmsOrderAsnDetailsRep; public WmsOrderPurchaseService( SqlSugarRepository rep , SqlSugarRepository purchaseOrderDetailsRep , SqlSugarRepository BaseCustomerRep , SqlSugarRepository wmsMaterialRep , SqlSugarRepository v_ware_PurchaseOrderDetailsForPDARep, SqlSugarRepository WmsBaseBusinessTypeRep , SqlSugarRepository wmsNoCreateRuleRep, SqlSugarRepository repRecordAdapter, SqlSugarRepository repAdapterManagement, SqlSugarRepository repAdapterCategories, SqlSugarRepository wmsOrderAsnDetailsRep ) { _rep = rep; _purchaseOrderDetailsRep = purchaseOrderDetailsRep; _BaseCustomerRep = BaseCustomerRep; _wmsMaterialRep = wmsMaterialRep; _v_ware_PurchaseOrderDetailsForPDARep = v_ware_PurchaseOrderDetailsForPDARep; _WmsBaseBusinessTypeRep = WmsBaseBusinessTypeRep; _WmsNoCreateRuleRep = wmsNoCreateRuleRep; _repAdapterManagement = repAdapterManagement; _repAdapterCategories = repAdapterCategories; _repRecordAdapter = repRecordAdapter; _wmsOrderAsnDetailsRep = wmsOrderAsnDetailsRep; } /// /// 分页查询采购订单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Page")] [Description("WmsOrderPurchase/Page")] public async Task> Page(WmsOrderPurchaseInput input) { List list1 = new List(); var query = CommonPageFilter(input); //var query2 = CommonPageFilter(input).Select().ToList(); //foreach (var item in query2) //{ // item.CreateASNQuantity = 1; //} //return await query2.Where(v => v.IsDelete == false).OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize); return await query.OrderBy(x => x.PoStatus).OrderByDescending(x => x.CreateTime) //.OrderBuilder(input) .ToPagedListAsync(input.Page, input.PageSize); } /// /// 不分页查询采购订单 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "List")] [Description("WmsOrderPurchase/List")] public async Task> List([FromQuery] WmsOrderPurchaseInput input) { var query = CommonPageFilter(input); return await query.OrderBuilder(input).Select().ToListAsync(); } /// /// 增加采购订单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Add")] [Description("WmsOrderPurchase/Add")] public async Task Add(DiyAddWmsOrderPurchaseInput input) { if (input.purchaseOrderDetails is null || input.purchaseOrderDetails.Count == 0) { throw Oops.Oh("明细不能为空"); } var hearId = await AddOrderEFsql(input); return hearId; } private async Task AddOrderEFsql(DiyAddWmsOrderPurchaseInput input) { var hearId = Yitter.IdGenerator.YitIdHelper.NextId(); //新增表头 var warehousOrder = input.Adapt(); warehousOrder.Id = hearId; warehousOrder.OrderType = OrderTypeEnum.PO单; warehousOrder.OrderTypeName = OrderTypeEnum.PO单.GetDescription(); warehousOrder.BusinessType = input.BusinessType; var entity = await _WmsBaseBusinessTypeRep.GetFirstAsync(u => u.BusinessTypeValue == input.BusinessType); if (entity == null) { throw Oops.Oh("业务类型名称获取失败"); } warehousOrder.BusinessTypeName = entity.BusinessTypeName; // 获取当前时间 DateTime currentTime = DateTime.Now; // 格式化为年月日字符串 string formattedDate = currentTime.ToString("yyyyMMdd"); //按照单号规则生成单号 - 查找最新的创建的一条单据记录 var newestOrder = await _rep.AsQueryable().Where(p => p.OrderType == OrderTypeEnum.PO单).Where(p => p.PurchaseNo.Contains(formattedDate)).OrderBy(it => it.CreateTime, OrderByType.Desc) .FirstAsync(); //按照单号规则生成单号 warehousOrder.PurchaseNo = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.PO单, _WmsNoCreateRuleRep, _repSNRep, warehousOrder.BusinessType, newestOrder == null ? null : newestOrder.PurchaseNo); if (warehousOrder.PurchaseNo == null || warehousOrder.PurchaseNo == "") { warehousOrder.PurchaseNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); } warehousOrder.OrderTypeName = ((int)input.OrderType).ToString(); warehousOrder.OrderSocure = GetEnumDescriptionUtil.GetEnumDescription(SourceByEnum.自建); warehousOrder.PoStatus = OrderStatusEnum.新建; warehousOrder.PoStatusName = GetEnumDescriptionUtil.GetEnumDescription(warehousOrder.PoStatus); warehousOrder.Quantity = (decimal)input.purchaseOrderDetails.Sum(x => x.Quantity); warehousOrder.GoodsQuantity = (decimal)input.purchaseOrderDetails.Sum(x => x.GoodsQuantity); var Info_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == input.SupplierCode); if (Info_BaseCustomer != null) { warehousOrder.SupplierName = Info_BaseCustomer.CustChinaName; } else { throw Oops.Oh($"请选择供应商编号!"); } warehousOrder.Dock = input.Dock; warehousOrder.ErpOrderNo = input.ErpOrderNo; warehousOrder.ProjectNo = input.ProjectNo; warehousOrder.FactoryId = 1; //?? //新增明细 var warehousOrderDetails1 = input.purchaseOrderDetails.Adapt>(); // PurchaseOrderHelper.CalcPurchaseOrderDeliveryQuantity(warehousOrder, warehousOrderDetails1); foreach (var w in warehousOrderDetails1) { if (w.Quantity == 0) { throw Oops.Oh("创建失败:数量需要大于0"); } var materials = await _wmsMaterialRep.GetFirstAsync(u => u.MaterialCode == w.MaterialCode && u.IsDisabled == false); if (materials == null) { throw Oops.Oh("物料:" + w.MaterialCode + "不可用"); } if (String.IsNullOrEmpty(w.ErpCode)) { throw Oops.Oh("物料:" + w.MaterialCode + "ERP库存地必填"); } w.Id = Yitter.IdGenerator.YitIdHelper.NextId(); w.PoId = hearId; w.PoNo = warehousOrder.PurchaseNo; w.PoLineNumber = w.PoLineNumber; w.MaterialCode = w.MaterialCode; w.MaterialName = w.MaterialName; w.Quantity = w.Quantity; w.PoDetailStatus = OrderStatusEnum.新建; w.PoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); w.PlannedStartTime = w.PlannedStartTime; w.PlannedEndTime = w.PlannedEndTime; w.SupplierCode = warehousOrder.SupplierCode.ToString(); w.SupplierName = warehousOrder.SupplierName.ToString(); w.SupplierBatch = w.SupplierBatch; w.ErpCode = w.ErpCode; w.Unit = w.Unit; w.ProjectNo = input.ProjectNo; w.Dock = input.Dock; w.ErpOrderNo = warehousOrder.ErpOrderNo; } try { await _rep.AsTenant().BeginTranAsync(); //插入主表 await _rep.InsertAsync(warehousOrder); //插入明细表 await _purchaseOrderDetailsRep.InsertRangeAsync(warehousOrderDetails1); await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } return hearId; } /// /// 增加适配器记录CC /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "CCAddAdapterLogs")] [Description("WmsOrderPurchase/CCAddAdapterLogs")] [AllowAnonymous] public async Task CCAddAdapterLogs(WCSWriteAdapterLogsInput wcsInput) { var getAdapterModel = await _repAdapterManagement.AsQueryable().FirstAsync(p => p.AdapterMethodName.Contains("PO单接收")); string OrderADapter = JsonConvert.SerializeObject(wcsInput.OPOrderAdapterAdd); string Message = JsonConvert.SerializeObject(wcsInput.AdapterReturnMassageObject); //插入一条记录,初始化记录的时候一定要先将记录变成未处理 if (getAdapterModel == null) throw Oops.Oh("当前接口地址不正确,未找到相应适配器"); var newRecordAdapter = new WmsAdapterRecord() { AdapterCategoryId = getAdapterModel.AdapterCategoryId, AdapterName = getAdapterModel.AdapterName, CategoryName = getAdapterModel.CategoryName, AdapterId = getAdapterModel.Id, AdapterMethodName = getAdapterModel.AdapterMethodName, RequestSoure = "CC", AdapterSID = wcsInput.SID, BeginTime = DateTime.Now, DealWithStatus = AdapterLogDealWithEnum.未处理, ErrMessage = wcsInput.AdapterReturnMassageObject.Message, // ErrMessage = wcsInput.ErrMessage == null ? "" : wcsInput.ErrMessage, AdapterInput = OrderADapter, AdapterReturnMassage = Message, OrderNo = wcsInput.AdapterReturnMassageObject.Result.ToString() }; await _repRecordAdapter.InsertAsync(newRecordAdapter); } /// /// 增加采购订单CC /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "CCAddPoOrder")] [Description("WmsOrderPurchase/CCAddPoOrder")] [AllowAnonymous] public async Task CCAddPoOrder([FromBody] string AddPoOrderData) { var input = JsonConvert.DeserializeObject(AddPoOrderData); if (input.purchaseOrderDetails is null || input.purchaseOrderDetails.Count == 0) { throw Oops.Oh("明细不能为空"); } var PoOrderNo = await CCAddOrderEFsql(input); return PoOrderNo; } /// /// 增加收货适配器记录 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "ReceivingAdapterLogs")] [Description("WmsOrderPurchase/ReceivingAdapterLogs")] [AllowAnonymous] public async Task ReceivingAdapterLogs(ReceivingAdapterLogsInput input) { var getAdapterModel = await _repAdapterManagement.AsQueryable().FirstAsync(p => p.AdapterMethodName.Contains("PO单收货")); string OrderADapter = JsonConvert.SerializeObject(input); //string Message = JsonConvert.SerializeObject(input.AdapterReturnMassageObject); var PoOrderNoList = new List(); foreach (var item in input.OPOrderReceivingAdapterAdd) { var POOrderNo = await _wmsOrderAsnDetailsRep.AsQueryable().FirstAsync(p => p.Id == item.OrderAsnDetailsId); PoOrderNoList.Add(POOrderNo.PoNo ?? "0"); } var OrderNO = ""; int index = 1; foreach (var item in PoOrderNoList) { if (index < PoOrderNoList.Count()) { OrderNO += item + ","; } else { OrderNO += item; } index++; } //插入一条记录,初始化记录的时候一定要先将记录变成未处理 if (getAdapterModel == null) throw Oops.Oh("当前接口地址不正确,未找到相应适配器"); var newRecordAdapter = new WmsAdapterRecord() { AdapterCategoryId = getAdapterModel.AdapterCategoryId, AdapterName = getAdapterModel.AdapterName, CategoryName = getAdapterModel.CategoryName, AdapterId = getAdapterModel.Id, AdapterMethodName = getAdapterModel.AdapterMethodName, RequestSoure = "PDA收货", // AdapterSID = input.SID, BeginTime = DateTime.Now, DealWithStatus = AdapterLogDealWithEnum.未处理, ErrMessage = "", // ErrMessage = wcsInput.ErrMessage == null ? "" : wcsInput.ErrMessage, AdapterInput = OrderADapter, AdapterReturnMassage = "", OrderNo = OrderNO, PushCount = 1, AdapterSID = "0", KeyCode = input.KeyCode.ToString() }; await _repRecordAdapter.InsertAsync(newRecordAdapter); } private async Task CCAddOrderEFsql(DiyAddWmsOrderPurchaseInput input) { var hearId = Yitter.IdGenerator.YitIdHelper.NextId(); //新增表头 var warehousOrder = input.Adapt(); warehousOrder.Id = hearId; warehousOrder.OrderType = OrderTypeEnum.PO单; warehousOrder.OrderTypeName = OrderTypeEnum.PO单.GetDescription(); warehousOrder.BusinessType = input.BusinessType; var entity = await _WmsBaseBusinessTypeRep.GetFirstAsync(u => u.BusinessTypeValue == input.BusinessType); if (entity == null) { throw Oops.Oh("业务类型名称获取失败"); } warehousOrder.BusinessTypeName = entity.BusinessTypeName; // 获取当前时间 DateTime currentTime = DateTime.Now; // 格式化为年月日字符串 string formattedDate = currentTime.ToString("yyyyMMdd"); //按照单号规则生成单号 - 查找最新的创建的一条单据记录 var newestOrder = await _rep.AsQueryable().Where(p => p.OrderType == OrderTypeEnum.PO单).Where(p => p.PurchaseNo.Contains(formattedDate)).OrderBy(it => it.CreateTime, OrderByType.Desc) .FirstAsync(); //按照单号规则生成单号 warehousOrder.PurchaseNo = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.PO单, _WmsNoCreateRuleRep, _repSNRep, warehousOrder.BusinessType, newestOrder == null ? null : newestOrder.PurchaseNo); if (warehousOrder.PurchaseNo == null || warehousOrder.PurchaseNo == "") { warehousOrder.PurchaseNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); } warehousOrder.OrderTypeName = ((int)input.OrderType).ToString(); warehousOrder.OrderSocure = GetEnumDescriptionUtil.GetEnumDescription(SourceByEnum.自建); warehousOrder.PoStatus = OrderStatusEnum.新建; warehousOrder.PoStatusName = GetEnumDescriptionUtil.GetEnumDescription(warehousOrder.PoStatus); warehousOrder.Quantity = (decimal)input.purchaseOrderDetails.Sum(x => x.Quantity); warehousOrder.GoodsQuantity = (decimal)input.purchaseOrderDetails.Sum(x => x.GoodsQuantity); var Info_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == input.SupplierCode); if (Info_BaseCustomer != null) { warehousOrder.SupplierName = Info_BaseCustomer.CustChinaName; } else { throw Oops.Oh($"请选择供应商编号!"); } warehousOrder.Dock = input.Dock; warehousOrder.ErpOrderNo = input.ErpOrderNo; warehousOrder.ProjectNo = input.ProjectNo; warehousOrder.FactoryId = 1; //?? //新增明细 var warehousOrderDetails1 = input.purchaseOrderDetails.Adapt>(); // PurchaseOrderHelper.CalcPurchaseOrderDeliveryQuantity(warehousOrder, warehousOrderDetails1); foreach (var w in warehousOrderDetails1) { if (w.Quantity == 0) { throw Oops.Oh("创建失败:数量需要大于0"); } var materials = await _wmsMaterialRep.GetFirstAsync(u => u.MaterialCode == w.MaterialCode && u.IsDisabled == false); if (materials == null) { throw Oops.Oh("物料:" + w.MaterialCode + "不可用"); } w.Id = Yitter.IdGenerator.YitIdHelper.NextId(); w.PoId = hearId; w.PoNo = warehousOrder.PurchaseNo; w.PoLineNumber = w.PoLineNumber; w.MaterialCode = w.MaterialCode; w.MaterialName = w.MaterialName; w.Quantity = w.Quantity; w.PoDetailStatus = OrderStatusEnum.新建; w.PoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); w.PlannedStartTime = w.PlannedStartTime; w.PlannedEndTime = w.PlannedEndTime; w.SupplierCode = warehousOrder.SupplierCode.ToString(); w.SupplierName = warehousOrder.SupplierName.ToString(); w.SupplierBatch = w.SupplierBatch; w.ErpCode = w.ErpCode; w.Unit = w.Unit; w.ProjectNo = input.ProjectNo; w.Dock = input.Dock; w.ErpOrderNo = warehousOrder.ErpOrderNo; } try { await _rep.AsTenant().BeginTranAsync(); //插入主表 await _rep.InsertAsync(warehousOrder); //插入明细表 await _purchaseOrderDetailsRep.InsertRangeAsync(warehousOrderDetails1); await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } return warehousOrder.PurchaseNo; } /// /// ly-取消采购订单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Delete")] [Description("WmsOrderPurchase/Delete")] public async Task Delete(DeleteWmsOrderPurchaseInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); entity.PoStatus = OrderStatusEnum.已取消; entity.PoStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已取消); var purchaseOrderDetails = await _purchaseOrderDetailsRep.AsQueryable() .Where(x => x.PoId == entity.Id) .Where(u => u.IsDelete == false) .Select() .ToListAsync(); //删明细 List deleteWarePurchaseOrderDetails = new List(); var deleteList = purchaseOrderDetails.Where(x => x.IsDelete == false).ToList(); foreach (var item in deleteList) { if (item.PoDetailStatus != OrderStatusEnum.新建) { throw Oops.Oh($"物料{item.MaterialCode}的状态{item.PoDetailStatus},不允许取消"); } if (item.GoodsQuantity > 0) { throw Oops.Oh($"物料{item.MaterialCode}的已收数量{item.GoodsQuantity}大于0,不允许取消"); } item.PoDetailStatus = OrderStatusEnum.已取消; item.PoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已取消); deleteWarePurchaseOrderDetails.Add(item); } try { await _rep.AsTenant().BeginTranAsync(); await _rep.UpdateAsync(entity); //更新状态 await _purchaseOrderDetailsRep.UpdateRangeAsync(deleteWarePurchaseOrderDetails); //更新状态 await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } /// /// 更新采购订单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Update")] [Description("WmsOrderPurchase/Update")] public async Task Update(DiyAddWmsOrderPurchaseInput input) { if (input.purchaseOrderDetails is null || input.purchaseOrderDetails.Count == 0) { throw Oops.Oh("明细不能为空"); } // CheckWarePurchaseOrderDetails(input.purchaseOrderDetails); var dbOrder = await _rep.GetFirstAsync(w => w.PurchaseNo == input.PurchaseNo); if (dbOrder == null) { throw Oops.Oh($"订单{input.PurchaseNo}不存在"); } dbOrder.SupplierCode = input.SupplierCode; dbOrder.SupplierName = input.SupplierName; dbOrder.Dock = input.Dock; dbOrder.ErpOrderNo = input.ErpOrderNo; dbOrder.Remark = input.Remark; dbOrder.ProjectNo = input.ProjectNo; dbOrder.FactoryId = 1; //??? var purchaseOrderDetails = await _purchaseOrderDetailsRep.AsQueryable() .Where(x => x.PoId == dbOrder.Id) .Where(u => u.IsDelete == false) .Select() .ToListAsync(); //验证数量是否正确 foreach (var item in input.purchaseOrderDetails) { if (item.Quantity < item.GoodsQuantity) { throw Oops.Oh($"物料{item.MaterialCode}的采购数量{item.Quantity}不能小于已收数量{item.GoodsQuantity}"); } } List addWarePurchaseOrderDetails = new List(); List updateWarePurchaseOrderDetails = new List(); List deleteWarePurchaseOrderDetails = new List(); //寻找更新的 var updateList = purchaseOrderDetails.Where(x => input.purchaseOrderDetails.Any(p => p.PoLineNumber == x.PoLineNumber && p.MaterialCode == x.MaterialCode)).ToList(); foreach (var item in updateList) { var orderDetails = input.purchaseOrderDetails.FirstOrDefault(x => x.MaterialCode == item.MaterialCode && x.Id == item.Id); if (orderDetails == null) { continue; } else { if (String.IsNullOrEmpty(orderDetails.ErpCode)) { throw Oops.Oh("物料:" + item.MaterialCode + "ERP库存地必填"); } item.Quantity = (decimal)orderDetails.Quantity; item.PoLineNumber = orderDetails.PoLineNumber; item.PlannedStartTime = orderDetails.PlannedStartTime; item.PlannedEndTime = orderDetails.PlannedEndTime; item.SupplierCode = input.SupplierCode; item.SupplierName = input.SupplierName; item.SupplierBatch = orderDetails.SupplierBatch; item.ErpCode = orderDetails.ErpCode; item.Unit = orderDetails.Unit;//update by liuwq 20240613 item.ProjectNo = input.ProjectNo; item.Dock = input.Dock; item.ErpOrderNo = dbOrder.ErpOrderNo; } //item.DeliveryQuantity = input.purchaseOrderDetails.Where(x => x.WarematerialCode == item.WarematerialCode && x.Id == item.Id).First().DeliveryQuantity; if (item.Quantity < item.GoodsQuantity) { throw Oops.Oh($"物料{item.MaterialCode}的采购数量{item.Quantity}不能小于已收数量{item.GoodsQuantity}"); } //变更明细的状态 // PurchaseOrderHelper.SetSignstatusForPurchaseOrder(item, dbOrder.PurchaseNo, _purchaseOrderRep, _purchaseOrderDetailsRep); updateWarePurchaseOrderDetails.Add(item); } //寻找删除的 var deleteList = purchaseOrderDetails.Where(x => !input.purchaseOrderDetails.Any(p => p.PoLineNumber == x.PoLineNumber && p.MaterialCode == x.MaterialCode)).ToList(); foreach (var item in deleteList) { if (item.GoodsQuantity > 0) { throw Oops.Oh($"物料{item.MaterialCode}的已收数量{item.GoodsQuantity}大于0,不允许删除"); } deleteWarePurchaseOrderDetails.Add(item); } //寻找新增的 var addList = input.purchaseOrderDetails.Where(x => !purchaseOrderDetails.Any(p => p.PoLineNumber == x.PoLineNumber && p.MaterialCode == x.MaterialCode)).ToList(); foreach (var w in addList) { //TODO 要改成 在循环外查询数据库 update by liuwq 20240613 var materials = await _wmsMaterialRep.GetFirstAsync(u => u.MaterialCode == w.MaterialCode && u.IsDisabled == false); if (materials == null) { throw Oops.Oh("物料:" + w.MaterialCode + "不可用"); } if (String.IsNullOrEmpty(w.ErpCode)) { throw Oops.Oh("物料:" + w.MaterialCode + "ERP库存地必填"); } WmsOrderPurchaseDetails warePurchaseOrderDetails = new WmsOrderPurchaseDetails() { Id = Yitter.IdGenerator.YitIdHelper.NextId(), PoId = dbOrder.Id, PoNo = dbOrder.PurchaseNo, PoLineNumber = w.PoLineNumber, MaterialCode = w.MaterialCode, MaterialName = w.MaterialName, Quantity = (decimal)w.Quantity, PoDetailStatus = OrderStatusEnum.新建, PoDetailStatusName = OrderStatusEnum.新建.GetDescription(), PlannedStartTime = w.PlannedStartTime, PlannedEndTime = w.PlannedEndTime, SupplierCode = input.SupplierCode, SupplierName = input.SupplierName, SupplierBatch = w.SupplierBatch, Unit = w.Unit,//update by liuwq 20240613 ErpCode = w.ErpCode, ErpOrderNo = dbOrder.ErpOrderNo }; addWarePurchaseOrderDetails.Add(warePurchaseOrderDetails); } try { await _rep.AsTenant().BeginTranAsync(); if (addWarePurchaseOrderDetails.Count > 0) { await _purchaseOrderDetailsRep.InsertRangeAsync(addWarePurchaseOrderDetails); } if (updateWarePurchaseOrderDetails.Count > 0) { await _purchaseOrderDetailsRep.UpdateRangeAsync(updateWarePurchaseOrderDetails); } if (deleteWarePurchaseOrderDetails.Count > 0) { await _purchaseOrderDetailsRep.DeleteAsync(deleteWarePurchaseOrderDetails); } CalcPurchaseOrderDeliveryQuantity(dbOrder, input.purchaseOrderDetails);//计算并赋值 主订单的需求数 await _rep.UpdateAsync(dbOrder); await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } public static void CalcPurchaseOrderDeliveryQuantity(WmsOrderPurchase order, List details) { order.Quantity = (decimal)details.Sum(x => x.Quantity); } /// /// 设置采购订单的状态 /// /// /// public static void SetSignstatusForPurchaseOrder(WmsOrderPurchaseDetails purchaseOrderDetail, string purchaseOrderNo, SqlSugarRepository _rep, SqlSugarRepository _purchaseOrderDetailsRep ) { if (purchaseOrderDetail.GoodsQuantity == 0) { // purchaseOrderDetail.PoDetailStatus = OrderStatusEnum.待收货; } else if (purchaseOrderDetail.GoodsQuantity < 0) { throw Oops.Oh($"采购单号{purchaseOrderNo},行号{purchaseOrderDetail.PoLineNumber},物料号{purchaseOrderDetail.MaterialCode}收货数量{purchaseOrderDetail.GoodsQuantity}不能小于0"); } else { if (purchaseOrderDetail.GoodsQuantity == purchaseOrderDetail.Quantity) { // purchaseOrderDetail.SignStatus = EnumSignStatus.收货完成; } else if (purchaseOrderDetail.GoodsQuantity < purchaseOrderDetail.Quantity) { // purchaseOrderDetail.SignStatus = EnumSignStatus.收货中; } else { throw Oops.Oh($"采购单号{purchaseOrderNo},行号{purchaseOrderDetail.PoLineNumber},物料号{purchaseOrderDetail.MaterialCode}" + $"收货数量{purchaseOrderDetail.GoodsQuantity}不能大于总数量{purchaseOrderDetail.Quantity}"); } } //更新主表的状态 数量更新后,更新 状态 var do_order = _rep.GetFirstAsync(x => x.PurchaseNo == purchaseOrderNo && x.IsDelete == false); var do_orderDetails = _purchaseOrderDetailsRep.AsQueryable().Where(x => x.PoId == do_order.Id && x.IsDelete == false).ToListAsync(); // var do_orderDetails = orderDetails.Where(x => x.PurchaseOrderId == order.Id && x.IsDeleted == false).ToList(); //计算总量 //var all_qty = do_orderDetails.Sum(x => x.DeliveryQuantity); // order.SignStatus = OrderCommonHelper.UpdateSignStatus(all_qty, do_orderDetails.Sum(x => x.GoodsQuantity)); // do_order.GoodsQuantity = do_orderDetails.Sum(x => x.GoodsQuantity); // UpdatePurchaseOrderStatus(do_order, do_orderDetails); } /// /// 获取采购订单 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [Description("WmsOrderPurchase/Detail")] public async Task Detail([FromQuery] QueryByIdWmsOrderPurchaseInput input) { return await _rep.GetFirstAsync(u => u.Id == input.Id); } /// /// po单主表明细导出 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "POOrderExcelOutting")] [Description("WmsOrderPurchase/POOrderExcelOutting")] [AllowAnonymous] public async Task POOrderExcelOutting([FromQuery] WmsOrderPurchaseInput input) { var vs = (from p in _purchaseOrderDetailsRep.AsQueryable().ToList() join m in _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.PurchaseNo), u => u.PurchaseNo.Contains(input.PurchaseNo.Trim())) .WhereIF(input.OrderType.HasValue, u => u.OrderType == input.OrderType) .WhereIF(!string.IsNullOrWhiteSpace(input.OrderTypeName), u => u.OrderTypeName.Contains(input.OrderTypeName.Trim())) .WhereIF(input.BusinessType.HasValue, u => u.BusinessType == input.BusinessType) .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessTypeName), u => u.BusinessTypeName.Contains(input.BusinessTypeName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.OrderSocure), u => u.OrderSocure.Contains(input.OrderSocure.Trim())) .WhereIF(input.PoStatus.HasValue, u => u.PoStatus == input.PoStatus) .WhereIF(!string.IsNullOrWhiteSpace(input.PoStatusName), u => u.PoStatusName.Contains(input.PoStatusName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.SupplierCode), u => u.SupplierCode.Contains(input.SupplierCode.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.SupplierName), u => u.SupplierName.Contains(input.SupplierName.Trim())) // .WhereIF(!string.IsNullOrWhiteSpace(input.Dock), u => u.Dock.Contains(input.Dock.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ErpOrderNo), u => u.ErpOrderNo.Contains(input.ErpOrderNo.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ProjectNo), u => u.ProjectNo.Contains(input.ProjectNo.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), u => u.Remark.Contains(input.Remark.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Erp_CreatedUserName), u => u.Erp_CreatedUserName.Contains(input.Erp_CreatedUserName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Erp_UpdatedUserName), u => u.Erp_UpdatedUserName.Contains(input.Erp_UpdatedUserName.Trim())).ToList() on p.PoId equals m.Id select new WmsOrderPurchaseExcelOutput { //Id = m.Id, PurchaseNo = m.PurchaseNo, //OrderTypeName = m.OrderTypeName, BusinessTypeName = m.BusinessTypeName, OrderSocure = m.OrderSocure, PoStatusName = m.PoStatusName, SupplierCode = m.SupplierCode, SupplierName = m.SupplierName, ErpOrderNo = m.ErpOrderNo, ProjectNo = m.ProjectNo, CreateTime = m.CreateTime, UpdateTime = m.UpdateTime, CreateUserName = m.CreateUserName, UpdateUserName = m.UpdateUserName, MaterialName = p.MaterialName, MaterialCode = p.MaterialCode, PoLineNumber = p.PoLineNumber, Unit = p.Unit, Quantity = p.Quantity, GoodsQuantity = p.GoodsQuantity, PoDetailStatusName = p.PoDetailStatusName, SupplierBatch = p.SupplierBatch, ErpCode = p.ErpCode, PlannedEndTime = p.PlannedEndTime, PlannedStartTime = p.PlannedStartTime, //Batch = p.Batch, //Dock = p.Dock }).ToList(); var fileName = "PO单详情"; var excelBaseResult = new Excel2003Result(vs, fileName, false, "PO单导出详情"); return new FileStreamResult(excelBaseResult.GetExcelStream(), "application/vnd.ms-excel"); } #region 私有方法 /// /// 公共查询采购订单条件 /// /// /// private ISugarQueryable CommonPageFilter(WmsOrderPurchaseInput input) { List list1 = new List(); var query = _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.PurchaseNo.Contains(input.SearchKey.Trim()) || u.SupplierCode.Contains(input.SearchKey.Trim()) || u.SupplierName.Contains(input.SearchKey.Trim()) || u.ErpOrderNo.Contains(input.SearchKey.Trim()) || u.ProjectNo.Contains(input.SearchKey.Trim()) ) .WhereIF(!string.IsNullOrWhiteSpace(input.PurchaseNo), u => u.PurchaseNo.Contains(input.PurchaseNo.Trim())) .WhereIF(input.OrderType.HasValue, u => u.OrderType == input.OrderType) .WhereIF(!string.IsNullOrWhiteSpace(input.OrderTypeName), u => u.OrderTypeName.Contains(input.OrderTypeName.Trim())) .WhereIF(input.BusinessType.HasValue, u => u.BusinessType == input.BusinessType) .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessTypeName), u => u.BusinessTypeName.Contains(input.BusinessTypeName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.OrderSocure), u => u.OrderSocure.Contains(input.OrderSocure.Trim())) .WhereIF(input.PoStatus.HasValue, u => u.PoStatus == input.PoStatus) .WhereIF(!string.IsNullOrWhiteSpace(input.PoStatusName), u => u.PoStatusName.Contains(input.PoStatusName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.SupplierCode), u => u.SupplierCode.Contains(input.SupplierCode.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.SupplierName), u => u.SupplierName.Contains(input.SupplierName.Trim())) // .WhereIF(!string.IsNullOrWhiteSpace(input.Dock), u => u.Dock.Contains(input.Dock.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ErpOrderNo), u => u.ErpOrderNo.Contains(input.ErpOrderNo.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ProjectNo), u => u.ProjectNo.Contains(input.ProjectNo.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), u => u.Remark.Contains(input.Remark.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Erp_CreatedUserName), u => u.Erp_CreatedUserName.Contains(input.Erp_CreatedUserName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Erp_UpdatedUserName), u => u.Erp_UpdatedUserName.Contains(input.Erp_UpdatedUserName.Trim())) .Select(); return query; } /// /// 重复性验证 /// /// 验证对象 /// 是否是编辑 /// private async Task CheckExist(WmsOrderPurchase input, bool isEdit = false) { //没有配置组合校验,不需要验重 //没有配置单独校验,不需要验重 } #endregion /// /// PDA收货 /// 根据AsN单号和物料编码获取采购明细 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "QueryDetailsPda")] [Description("WmsOrderPurchase/QueryDetailsPda")] public async Task> QueryDetailsPda([FromQuery] QueryPurchaseOrderDetailsInput input) { var query = _v_ware_PurchaseOrderDetailsForPDARep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.MaterialCode), u => u.MaterialCode == input.MaterialCode) .WhereIF(!string.IsNullOrWhiteSpace(input.AsnNo), u => u.AsnNo == input.AsnNo) .WhereIF(!string.IsNullOrWhiteSpace(input.SN_1d), u => u.SN_1d == input.SN_1d) .WhereIF(!string.IsNullOrWhiteSpace(input.SN_2d), u => u.SN_2d == input.SN_2d) .Where(u => u.IsFreeze != true || u.IsFreeze == null) .Where(u => u.AsnStatus != OrderStatusEnum.已关闭) //ly-关闭的不可再收货 .Select(); return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize); } #region 导入 /// /// Excel模板导入PO单功能-ly /// /// Excel模板文件 /// 导入的记录数 [HttpPost] [ApiDescriptionSettings(Name = "ImportExcel")] [Description("WmsOrderPurchase/ImportExcel")] public async Task ImportExcelAsync(IFormFile file) { int _HeadStartLine = 2;//第1行是说明,第2行是列名 int _DataStartLine = 3;//第3行开始是数据 DataTable importDataTable = ExcelUtil.ImportExcelToDataTable(file, _HeadStartLine, _DataStartLine); var addListAll = await CommonImport(importDataTable, _DataStartLine); // 获取当前时间 DateTime currentTime = DateTime.Now; // 格式化为年月日字符串 string formattedDate = currentTime.ToString("yyyyMMdd"); //按照单号规则生成单号 - 查找最新的创建的一条单据记录 var newestOrder = await _rep.AsQueryable().Where(p => p.OrderType == OrderTypeEnum.PO单).Where(p => p.PurchaseNo.Contains(formattedDate)).OrderBy(it => it.CreateTime, OrderByType.Desc) .FirstAsync(); //按照单号规则生成单号-ly var PoNo = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.PO单, _WmsNoCreateRuleRep, _repSNRep, (int)BusinessTypeEnum.客户发运, newestOrder == null ? null : newestOrder.PurchaseNo); if (PoNo == null || PoNo == "") { PoNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); } var DoId = Yitter.IdGenerator.YitIdHelper.NextId(); //主表 addListAll.OrderDeliver.PurchaseNo = Convert.ToString(PoNo); addListAll.OrderDeliver.Id = DoId; addListAll.OrderDeliver.OrderType = OrderTypeEnum.PO单; addListAll.OrderDeliver.OrderTypeName = GetEnumDescriptionUtil.GetEnumDescription(OrderTypeEnum.PO单); addListAll.OrderDeliver.BusinessType = (int)BusinessTypeEnum.采购收货; addListAll.OrderDeliver.BusinessTypeName = GetEnumDescriptionUtil.GetEnumDescription(BusinessTypeEnum.采购收货); addListAll.OrderDeliver.OrderSocure = "导入"; //(string)SourceByEnum.导入 addListAll.OrderDeliver.PoStatus = OrderStatusEnum.新建; addListAll.OrderDeliver.PoStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); var Info_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == addListAll.OrderDeliver.SupplierCode); if (Info_BaseCustomer == null) { throw Oops.Oh("客户编号不存在!"); } addListAll.OrderDeliver.SupplierName = Info_BaseCustomer.CustChinaName; //检验物料不存在 List queryCodeList = addListAll.OrderDeliverDetails.Select(v => v.MaterialCode).Distinct().ToList(); var handleList = await _wmsMaterialRep.GetListAsync(u => queryCodeList.Contains(u.MaterialCode) && u.IsDelete == false); if (handleList == null || handleList.Count <= 0) { throw Oops.Oh($"物料不存在!"); } //明细表 foreach (var item in addListAll.OrderDeliverDetails) { var materials = handleList.Where(u => u.MaterialCode == item.MaterialCode).FirstOrDefault(); if (materials == null) { throw Oops.Oh("物料:" + item.MaterialCode + "不存在"); } item.PoNo = Convert.ToString(PoNo); item.PoId = DoId; item.PoDetailStatus = OrderStatusEnum.新建; item.PoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); item.MaterialName = materials.MaterialName; item.Quantity = 0; item.CreateASNQuantity = 0; //item.SNP = materials.SNP; item.SupplierCode = addListAll.OrderDeliver.SupplierCode; item.SupplierName = Info_BaseCustomer.CustChinaName; } try { await _rep.AsTenant().BeginTranAsync(); await _rep.InsertAsync(addListAll.OrderDeliver); //插入主表 await _purchaseOrderDetailsRep.InsertRangeAsync(addListAll.OrderDeliverDetails); //插入明细表 await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } return 200; } /// /// DataTable转换实体对象列表 /// /// /// 模版列名开始行 /// private async Task CommonImport(DataTable dataTable, int dataStartLine) { var detailsAll = new WmsOrderPurchaseExportOutput(); var addItem = new WmsOrderPurchase(); var detailsMaterial = new List(); int index = dataStartLine;//模版列名开始行 foreach (System.Data.DataRow row in dataTable.Rows) { index++; //导入模版定制化代码(替换模版使用) var addItemMaterial = new WmsOrderPurchaseDetails(); #region 定义变量 var _DeliverNo = "";//PO单号 var _CustCode = "";//客户编号 var MaterialCode = "";//物料编号 var DoLineNumber = "";//行号 var Quantity = "";//需求数 var _ErpOrderNo = "";//ERP单号 var _Remark = "";//备注 #endregion #region 取值 MaterialCode = row["物料编号"]?.ToString(); DoLineNumber = row["行号"]?.ToString(); Quantity = row["需求数"]?.ToString(); _CustCode = row["供应商编号"]?.ToString(); _ErpOrderNo = row["ERP单号"]?.ToString(); _Remark = row["备注"]?.ToString(); #endregion #region 验证 //if (string.IsNullOrEmpty(_DeliverNo)) //{ // throw Oops.Oh($"第{index}行[DO单号]{_DeliverNo}不能为空!"); //} //if(!string.IsNullOrEmpty(_DeliverNo)) //{ // addItem.DeliverNo = (string)(_DeliverNo.Trim()); // } if (string.IsNullOrEmpty(MaterialCode)) { throw Oops.Oh($"第{index}行[物料编号]{MaterialCode}不能为空!"); } if (!string.IsNullOrEmpty(MaterialCode)) { addItemMaterial.MaterialCode = (string)(MaterialCode.Trim()); } if (string.IsNullOrEmpty(DoLineNumber)) { throw Oops.Oh($"第{index}行[行号]{DoLineNumber}不能为空!"); } if (!string.IsNullOrEmpty(DoLineNumber)) { addItemMaterial.PoLineNumber = (string)(DoLineNumber.Trim()); } if (string.IsNullOrEmpty(Quantity)) { throw Oops.Oh($"第{index}行[需求数]{Quantity}不能为空!"); } decimal qty = Convert.ToDecimal(Quantity.Trim()); if (qty <= 0) { throw Oops.Oh($"第{index}行[需求数]{Quantity}不能小于0!"); } addItemMaterial.Quantity = qty; //if (string.IsNullOrEmpty(_CustCode)) //{ // throw Oops.Oh($"第{index}行[客户编号]{_CustCode}不能为空!"); //} if (index == 4) { if (string.IsNullOrEmpty(_CustCode)) { throw Oops.Oh($"第{index}行[客户编号]{_CustCode}不能为空!"); } if (!string.IsNullOrEmpty(_CustCode)) { addItem.SupplierCode = (string)(_CustCode.Trim()); } if (!string.IsNullOrEmpty(_Remark)) { addItem.Remark = (string)(_Remark.Trim()); } if (!string.IsNullOrEmpty(_ErpOrderNo)) { addItem.ErpOrderNo = (string)(_ErpOrderNo.Trim()); } } #endregion detailsMaterial.Add(addItemMaterial); } //验重 //await CheckExisitForImport(details); // await CheckExisitForImport(detailsMaterial); detailsAll.OrderDeliver = addItem; detailsAll.OrderDeliverDetails = detailsMaterial; return detailsAll; } /// /// 根据版本下载PO单的Excel导入模板 /// /// 下载的模板文件 [HttpGet] [ApiDescriptionSettings(Name = "DownloadExcelTemplate")] [Description("WmsOrderPurchase/DownloadExcelTemplate")] public IActionResult DownloadExcelTemplate() { string _path = TemplateConst.EXCEL_TEMPLATEFILE_导入模版路径 + $"\\PO单{TemplateConst.EXCEL_TEMPLATEFILE_导入模版名称后缀}.xlsx"; var fileName = HttpUtility.UrlEncode($"导入模板(PO单).xlsx", Encoding.GetEncoding("UTF-8")); return new FileStreamResult(new FileStream(_path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; } #endregion }