using Admin.NET.Core.Service; using Admin.NET.Application.Entity; using Microsoft.AspNetCore.Http; using System.Data; using System.Web; using System.Text; using NewLife.Reflection; using Admin.NET.Core; using Admin.NET.Application.CommonHelper; namespace Admin.NET.Application; /// /// DO单服务 /// [ApiDescriptionSettings(ApplicationConst.WmsOrderGroupName, Order = 100)] public class WmsOrderDeliverService : IDynamicApiController, ITransient { private readonly SqlSugarRepository _rep; private readonly SqlSugarRepository _WmsOrderDeliverDetailsRep; private readonly SqlSugarRepository _BaseCustomerRep; private readonly SqlSugarRepository _wmsMaterialRep; private readonly SqlSugarRepository _repSNRep; private readonly SqlSugarRepository _WmsNoCreateRuleRep; private readonly SqlSugarRepository _wareActionLogRep; public WmsOrderDeliverService(SqlSugarRepository rep, SqlSugarRepository wmsOrderDeliverDetailsRep, SqlSugarRepository baseCustomerRep, SqlSugarRepository wmsMaterialRep, SysConfigService sysConfigService, SqlSugarRepository repSNRep, SqlSugarRepository wmsNoCreateRuleRep , SqlSugarRepository wareActionLogRep ) { _rep = rep; _WmsOrderDeliverDetailsRep = wmsOrderDeliverDetailsRep; _BaseCustomerRep = baseCustomerRep; _wmsMaterialRep = wmsMaterialRep; _repSNRep = repSNRep; _WmsNoCreateRuleRep = wmsNoCreateRuleRep; _wareActionLogRep = wareActionLogRep; } /// /// 分页查询DO单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Page")] [Description("WmsOrderDeliver/Page")] public async Task> Page(WmsOrderDeliverInput input) { var query = CommonPageFilter(input); return await query .OrderBy(x => x.DoStatus).OrderByDescending(x => x.CreateTime) //.OrderBuilder(input, "", "Id") .ToPagedListAsync(input.Page, input.PageSize); } /// /// 不分页查询DO单 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "List")] [Description("WmsOrderDeliver/List")] public async Task> List([FromQuery] WmsOrderDeliverInput input) { var query = CommonPageFilter(input); return await query.OrderBuilder(input, "", "Id").Select().ToListAsync(); } /// /// 增加DO单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Add")] [Description("WmsOrderDeliver/Add")] public async Task Add(AddWmsOrderDeliverInput input) { var entity = input.Adapt(); //重复性验证 await CheckExist(entity); await _rep.InsertAsync(entity); return entity.Id; } /// /// 取消DO单-ly /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Delete")] [Description("WmsOrderDeliver/Delete")] public async Task Delete(DeleteWmsOrderDeliverInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); entity.DoStatus = OrderStatusEnum.已取消; entity.DoStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已取消); var OrderDetails = await _WmsOrderDeliverDetailsRep.AsQueryable() .Where(x => x.DoId == entity.Id) .Where(u => u.IsDelete == false) .Select() .ToListAsync(); //取消明细 List deleteWareOrderDetails = new List(); var deleteList = OrderDetails.Where(x => x.IsDelete == false).ToList(); foreach (var item in deleteList) { if (item.DoDetailStatus != OrderStatusEnum.新建) { throw Oops.Oh($"物料{item.MaterialCode}的状态{item.DoDetailStatus},不允许取消"); } if (item.DeliverQuantity > 0) { throw Oops.Oh($"物料{item.MaterialCode}的已发货数量{item.DeliverQuantity}大于0,不允许取消"); } item.DoDetailStatus = OrderStatusEnum.已取消; item.DoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已取消); deleteWareOrderDetails.Add(item); } try { await _rep.AsTenant().BeginTranAsync(); await _rep.UpdateAsync(entity); //更新状态 await _WmsOrderDeliverDetailsRep.UpdateRangeAsync(deleteWareOrderDetails); //更新状态 await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } //var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); ////await _rep.FakeDeleteAsync(entity); //假删除 //await _rep.DeleteAsync(entity); //真删除 } /// /// 关闭DO单-ly0712 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "CloseOrder")] [Description("WmsOrderDeliver/CloseOrder")] public async Task CloseOrder(DeleteWmsOrderDeliverInput input) { var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002); if (entity.DoStatus == OrderStatusEnum.已完成 || entity.DoStatus == OrderStatusEnum.已取消) { throw Oops.Oh($"单据状态{entity.DoStatusName},不允许操作!"); } entity.DoStatus = OrderStatusEnum.已关闭; entity.DoStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭); var OrderDetails = await _WmsOrderDeliverDetailsRep.AsQueryable() .Where(x => x.DoId == entity.Id) .Where(u => u.IsDelete == false) .Select() .ToListAsync(); //关闭明细 List deleteWareOrderDetails = new List(); var deleteList = OrderDetails.Where(x => x.IsDelete == false).ToList(); foreach (var item in deleteList) { //if (item.DoDetailStatus == OrderStatusEnum.NewBuild) //{ // throw Oops.Oh($"物料{item.MaterialCode}的状态{item.DoDetailStatus},不允许关闭"); //} item.DoDetailStatus = OrderStatusEnum.已关闭; item.DoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭); deleteWareOrderDetails.Add(item); } // ----------------记录操作日志 List addWareActionLogList = new List(); string actionTitle = $"{OrderTypeEnum.DO单}{entity.DeliverNo}{GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.已关闭)}";//操作履历标题 var idWmsLogAction = Yitter.IdGenerator.YitIdHelper.NextId(); WmsLogAction wareActionLog = LogActionHelper.CreateWmsLogAction(idWmsLogAction, actionTitle); addWareActionLogList.Add(wareActionLog); // ----------------记录操作日志 try { await _rep.AsTenant().BeginTranAsync(); await _rep.UpdateAsync(entity); //更新状态 await _WmsOrderDeliverDetailsRep.UpdateRangeAsync(deleteWareOrderDetails); //更新状态 await _wareActionLogRep.InsertRangeAsync(addWareActionLogList); //操作日志 await _rep.AsTenant().CommitTranAsync(); } catch { await _rep.AsTenant().RollbackTranAsync(); throw; } } /// /// 更新DO单 /// /// /// [HttpPost] [ApiDescriptionSettings(Name = "Update")] [Description("WmsOrderDeliver/Update")] public async Task Update(UpdateWmsOrderDeliverInput input) { var entity = input.Adapt(); //重复性验证 await CheckExist(entity,true); await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); } /// /// 获取DO单 /// /// /// [HttpGet] [ApiDescriptionSettings(Name = "Detail")] [Description("WmsOrderDeliver/Detail")] public async Task Detail([FromQuery] QueryByIdWmsOrderDeliverInput input) { return await _rep.GetFirstAsync(u => u.Id == input.Id); } #region 导入 /// /// Excel模板导入DO单功能-ly /// /// Excel模板文件 /// 导入的记录数 [HttpPost] [ApiDescriptionSettings(Name = "ImportExcel")] [Description("WmsOrderDeliver/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); //按照单号规则生成单号 - 查找最新的创建的一条单据记录 var newestOrder = await _rep.AsQueryable().OrderBy(it => it.CreateTime, OrderByType.Desc) .FirstAsync(); //按照单号规则生成单号-ly var DoNo = await SerialUtilOrder.GetSerialOrder(OrderTypeEnum.DO单, _WmsNoCreateRuleRep, _repSNRep, (int)BusinessTypeEnum.客户发运, newestOrder == null? null: newestOrder.DeliverNo); if (DoNo == null || DoNo == "") { DoNo = Yitter.IdGenerator.YitIdHelper.NextId().ToString(); } var DoId = Yitter.IdGenerator.YitIdHelper.NextId(); //主表 addListAll.OrderDeliver.DeliverNo = Convert.ToString(DoNo); addListAll.OrderDeliver.Id = DoId; addListAll.OrderDeliver.OrderType = OrderTypeEnum.DO单; addListAll.OrderDeliver.OrderTypeName = GetEnumDescriptionUtil.GetEnumDescription(OrderTypeEnum.DO单); addListAll.OrderDeliver.BusinessType = BusinessTypeEnum.客户发运; addListAll.OrderDeliver.BusinessTypeName = GetEnumDescriptionUtil.GetEnumDescription(BusinessTypeEnum.客户发运); addListAll.OrderDeliver.OrderSocure = SourceByEnum.导入; addListAll.OrderDeliver.DoStatus = OrderStatusEnum.新建; addListAll.OrderDeliver.DoStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); var Info_BaseCustomer = await _BaseCustomerRep.GetFirstAsync(u => u.CustCode == addListAll.OrderDeliver.CustCode); if (Info_BaseCustomer == null) { throw Oops.Oh("客户编号不存在!"); } addListAll.OrderDeliver.CustName = 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($"物料不存在!"); } if (addListAll.OrderDeliverDetails.GroupBy(g => new { g.DoLineNumber}).Any(g => g.Count() > 1)) { 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.DoNo = Convert.ToString(DoNo); item.DoId = DoId; item.DoDetailStatus = OrderStatusEnum.新建; item.DoDetailStatusName = GetEnumDescriptionUtil.GetEnumDescription(OrderStatusEnum.新建); item.MaterialName = materials.MaterialName; item.DeliverQuantity = 0; item.CreateMovementQuantity=0; item.SNP = materials.SNP; item.Unit = materials.MaterialUnit; item.CustCode = addListAll.OrderDeliver.CustCode; item.CustName = Info_BaseCustomer.CustChinaName; item.DoLineNumber = OrderHelper.AutoCompleEBELP(item.DoLineNumber, 4); } try { await _rep.AsTenant().BeginTranAsync(); await _rep.InsertAsync(addListAll.OrderDeliver); //插入主表 await _WmsOrderDeliverDetailsRep.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 WmsOrderDeliverExportOutput(); var addItem = new WmsOrderDeliver(); var detailsMaterial = new List(); int index = dataStartLine;//模版列名开始行 foreach (System.Data.DataRow row in dataTable.Rows) { index++; //导入模版定制化代码(替换模版使用) var addItemMaterial = new WmsOrderDeliverDetails(); #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(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.DoLineNumber = (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 && _CustCode != addItem.CustCode) { throw Oops.Oh($"DO单客户编号要相同!"); } if (!string.IsNullOrEmpty(_CustCode)) { addItem.CustCode = (string)(_CustCode.Trim()); } if (index == 4) { addItem.ErpOrderNo = (string)(_ErpOrderNo.Trim()); } if (index > 4 && (string)_ErpOrderNo != (string)addItem.ErpOrderNo) { throw Oops.Oh($"第{index}行ERP单号要相同!"); } if (index == 4) { addItem.Remark = (string)(_Remark.Trim()); } if (index > 4 && _Remark != (string)addItem.Remark) { throw Oops.Oh($"第{index}行备注要相同!"); } #endregion detailsMaterial.Add(addItemMaterial); } detailsAll.OrderDeliver = addItem; detailsAll.OrderDeliverDetails = detailsMaterial; return detailsAll; } /// /// 根据版本下载DO单的Excel导入模板 /// /// 下载的模板文件 [HttpGet] [ApiDescriptionSettings(Name = "DownloadExcelTemplate")] [Description("WmsOrderDeliver/DownloadExcelTemplate")] public IActionResult DownloadExcelTemplate() { string _path = TemplateConst.EXCEL_TEMPLATEFILE_导入模版路径 + $"\\DO单{TemplateConst.EXCEL_TEMPLATEFILE_导入模版名称后缀}.xlsx"; var fileName = HttpUtility.UrlEncode($"导入模板(DO单).xlsx", Encoding.GetEncoding("UTF-8")); return new FileStreamResult(new FileStream(_path, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName }; } #endregion #region 私有方法 /// /// 公共查询DO单条件 /// /// /// private ISugarQueryable CommonPageFilter(WmsOrderDeliverInput input) { var query = _rep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.DeliverNo.Contains(input.SearchKey.Trim()) || u.CustCode.Contains(input.SearchKey.Trim()) || u.CustName.Contains(input.SearchKey.Trim()) || u.ErpOrderNo.Contains(input.SearchKey.Trim()) || u.Erp_CreateUserName.Contains(input.SearchKey.Trim()) || u.Erp_UpdateUserName.Contains(input.SearchKey.Trim()) || u.Remark.Contains(input.SearchKey.Trim()) || u.CreateUserName.Contains(input.SearchKey.Trim()) || u.UpdateUserName.Contains(input.SearchKey.Trim()) ) .WhereIF(!string.IsNullOrWhiteSpace(input.DeliverNo), u => u.DeliverNo.Contains(input.DeliverNo.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(input.OrderSocure.HasValue, u => u.OrderSocure == input.OrderSocure) .WhereIF(input.DoStatus.HasValue, u => u.DoStatus == input.DoStatus) .WhereIF(!string.IsNullOrWhiteSpace(input.DoStatusName), u => u.DoStatusName.Contains(input.DoStatusName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.CustCode), u => u.CustCode.Contains(input.CustCode.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.CustName), u => u.CustName.Contains(input.CustName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.ErpOrderNo), u => u.ErpOrderNo.Contains(input.ErpOrderNo.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Erp_CreateUserName), u => u.Erp_CreateUserName.Contains(input.Erp_CreateUserName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Erp_UpdateUserName), u => u.Erp_UpdateUserName.Contains(input.Erp_UpdateUserName.Trim())) .WhereIF(!string.IsNullOrWhiteSpace(input.Remark), u => u.Remark.Contains(input.Remark.Trim())) .Select(); if(input.Erp_CreateTimeRange != null && input.Erp_CreateTimeRange.Count >0) { DateTime? start= input.Erp_CreateTimeRange[0].Value.AddDays(-1); query = query.WhereIF(start.HasValue, u => u.Erp_CreateTime > start); if (input.Erp_CreateTimeRange.Count >1 && input.Erp_CreateTimeRange[1].HasValue) { var end = input.Erp_CreateTimeRange[1].Value.AddDays(1); query = query.Where(u => u.Erp_CreateTime < end); } } if(input.Erp_UpdateTimeRange != null && input.Erp_UpdateTimeRange.Count >0) { DateTime? start= input.Erp_UpdateTimeRange[0].Value.AddDays(-1); query = query.WhereIF(start.HasValue, u => u.Erp_UpdateTime > start); if (input.Erp_UpdateTimeRange.Count >1 && input.Erp_UpdateTimeRange[1].HasValue) { var end = input.Erp_UpdateTimeRange[1].Value.AddDays(1); query = query.Where(u => u.Erp_UpdateTime < end); } } return query; } /// /// 重复性验证 /// /// 验证对象 /// 是否是编辑 /// private async Task CheckExist( WmsOrderDeliver input,bool isEdit=false) { //没有配置组合校验,不需要验重 //没有配置单独校验,不需要验重 } /// /// 根据组合校验和单独校验验证数据是否已存在-导入时验证 /// /// /// private async Task CheckExisitForImport(List inputs) { if (inputs?.Count <= 0) { throw Oops.Oh($"导入数据不能为空"); } //根据组合校验验证表格中中是否已存在相同数据 //根据单独校验验证表格中中是否已存在相同数据 } #endregion }