using CMS.Plugin.HIAWms.Application.Contracts.Dtos.WmsMaterial; using CMS.Plugin.HIAWms.Application.Contracts.Services; using CMS.Plugin.HIAWms.Domain.Shared; using CmsQueryExtensions; using CMS.Plugin.HIAWms.Domain.WmsMaterial; using CmsQueryExtensions.Extension; using System.Linq.Expressions; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Data; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectMapping; using CmsQueryExtensions.Entitys; namespace CMS.Plugin.HIAWms.Application.Implements; /// /// 物料基础信息表应用服务 /// public class WmsMaterialAppService : CMSPluginAppService, IWmsMaterialAppService { private readonly IWmsMaterialRepository wmsMaterialRepository; /// /// Initializes a new instance of the class. /// /// The task job repository. public WmsMaterialAppService(IWmsMaterialRepository _WmsMaterialRepository) { wmsMaterialRepository = _WmsMaterialRepository; } /// /// 获取指定物料基础信息表 /// /// /// public virtual async Task GetAsync(Guid id) { return ObjectMapper.Map(await wmsMaterialRepository.GetAsync(id)); } /// /// 分页获取物料基础信息表 /// /// /// public virtual async Task> GetListAsync(GetWmsMaterialInput input) { Check.NotNull(input, nameof(input)); if (input.Sorting.IsNullOrWhiteSpace()) { input.Sorting = nameof(WmsMaterial.Sort); } #region 动态构造查询条件 //动态构造查询条件 var whereConditions = DynamicGetQueryParams(input); #endregion var count = await wmsMaterialRepository.GetCountAsync(whereConditions); var list = await wmsMaterialRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount); return new PagedResultDto(count, ObjectMapper.Map, List>(list)); } /// /// 动态构造查询条件 /// /// 输入参数 /// private FunReturnResultModel>> DynamicGetQueryParams(GetWmsMaterialInput input) { //动态构造查询条件 var whereConditions = WhereConditionsExtensions.GetWhereConditions(input); if (!whereConditions.IsSuccess) { throw new Exception("动态构造查询条件失败:" + whereConditions.ErrMsg); } //也可再次自定义构建查询条件 Expression> extendExpression = a => a.IsDeleted == false; // 使用 System.Linq.PredicateBuilder 的 And var pres = (System.Linq.Expressions.Expression>)(whereConditions.data); whereConditions.data = System.Linq.PredicateBuilder.And(pres, extendExpression); return whereConditions; } /// /// 新建物料基础信息表 /// /// /// /// public virtual async Task CreateAsync(WmsMaterialCreateDto input) { await CheckCreateOrUpdateDtoAsync(input); var exist = await wmsMaterialRepository.NameExistAsync(input.MaterialCode); if (exist) { throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.MaterialCode]); } var maxSort = await wmsMaterialRepository.GetMaxSortAsync(); var sort = input.Sort ?? maxSort; var insertObj = ObjectMapper.Map(input); insertObj.Sort = sort; input.MapExtraPropertiesTo(insertObj, MappingPropertyDefinitionChecks.None); insertObj.CreatorName = input.CreatorName;//创建人 await wmsMaterialRepository.InsertAsync(insertObj); //if (input.Sort.HasValue && insertObj.Sort != maxSort) //{ // await AdjustSortAsync(insertObj.Id, insertObj.Sort); //} return ObjectMapper.Map(insertObj); } /// /// 更新物料基础信息表 /// /// /// /// /// public virtual async Task UpdateAsync(Guid id, WmsMaterialUpdateDto input) { await CheckCreateOrUpdateDtoAsync(input); var updateObj = await wmsMaterialRepository.GetAsync(id); var exist = await wmsMaterialRepository.NameExistAsync(input.MaterialCode, updateObj.Id); if (exist) { throw new UserFriendlyException(L[CMSPluginDomainErrorCodes.NameAlreadyExists, input.MaterialCode]); } updateObj.SetConcurrencyStampIfNotNull(input.ConcurrencyStamp); input.MapExtraPropertiesTo(updateObj, MappingPropertyDefinitionChecks.None); updateObj.MaterialCode = input.MaterialCode; updateObj.IsValid = input.IsValid; updateObj.IsSelfMade = input.IsSelfMade; updateObj.Num = input.Num; updateObj.SelfNum = input.SelfNum; updateObj.MaterialName = input.MaterialName; updateObj.NullLength = input.NullLength; updateObj.PurchaseType = input.PurchaseType; updateObj.MaterialType = input.MaterialType; updateObj.PrimaryUnit = input.PrimaryUnit; updateObj.Standard = input.Standard; updateObj.OuterDiameter = input.OuterDiameter; updateObj.WallThickness = input.WallThickness; updateObj.MaterialQuality = input.MaterialQuality; updateObj.Length = input.Length; updateObj.IsMainBranch = input.IsMainBranch; updateObj.Factory = input.Factory; updateObj.Certification = input.Certification; updateObj.RedundantField1 = input.RedundantField1; updateObj.RedundantField2 = input.RedundantField2; updateObj.RedundantField3 = input.RedundantField3; updateObj.Remark = input.Remark; updateObj.LastModifierName = input.LastModifierName;//修改人 await wmsMaterialRepository.UpdateAsync(updateObj); return ObjectMapper.Map(updateObj); } /// /// 克隆物料基础信息表 /// /// /// public async Task> CloneAsync(IEnumerable ids) { //var wmsMaterials = new List(); //if (ids != null) //{ // var sort = await wmsMaterialRepository.GetMaxSortAsync(); // foreach (var id in ids) // { // var WmsMaterial = await wmsMaterialRepository.FindAsync(id); // if (WmsMaterial != null) // { // var name = WmsMaterial.Name + WmsMaterialConsts.CloneTag; // var notExist = false; // while (!notExist) // { // var exist = await wmsMaterialRepository.NameExistAsync(name); // if (exist || wmsMaterials.Any(x => x.Name == name)) // { // name += WmsMaterialConsts.CloneTag; // continue; // } // notExist = true; // } // //WmsMaterial = await wmsMaterialRepository.InsertAsync(WmsMaterial.Clone(GuidGenerator.Create(), name, sort++)); // wmsMaterials.Add(WmsMaterial); // } // } //} //return ObjectMapper.Map, List>(wmsMaterials); return new List(); } /// /// 删除单个物料基础信息表 /// /// /// public virtual Task DeleteAsync(Guid id) { return wmsMaterialRepository.DeleteAsync(id); } /// /// 删除多个物料基础信息表 /// /// /// public async Task DeleteManyAsync(IEnumerable ids) { foreach (var id in ids) { await DeleteAsync(id); } } /// /// 物理删除物料基础信息表 /// /// 物料ID /// /// public virtual async Task DeletePermanentlyAsync(Guid id, CancellationToken cancellationToken = default) { wmsMaterialRepository.DeletePermanentlyAsync(id); } /// /// 批量物理删除物料基础信息表(直接删除,不软删除) /// /// 要删除的物料ID列表 /// /// public virtual async Task BatchDeletePermanentlyAsync(IEnumerable ids, CancellationToken cancellationToken = default) { wmsMaterialRepository.BatchDeletePermanentlyAsync(ids); } /// /// 调整排序物料基础信息表 /// /// /// /// public virtual async Task AdjustSortAsync(Guid id, int sort) { var list = await wmsMaterialRepository.GetListAsync(null, nameof(WmsMaterial.Sort)); if (list != null && list.Any()) { var initSort = 1; list.ForEach(x => x.AdjustSort(initSort++)); var entity = list.FirstOrDefault(x => x.Id == id); if (entity != null) { if (sort == 1) { list.Where(x => x.Id != id).ToList()?.ForEach(x => x.AdjustSort(x.Sort + 1)); } else if (entity.Sort > sort) { list.Where(x => x.Id != id && x.Sort >= sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort + 1)); list.Where(x => x.Id != id && x.Sort < sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort - 1)); } else if (entity.Sort < sort) { list.Where(x => x.Id != id && x.Sort > sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort + 1)); list.Where(x => x.Id != id && x.Sort <= sort).ToList()?.ForEach(x => x.AdjustSort(x.Sort - 1)); } entity.AdjustSort(sort); } } await wmsMaterialRepository.UpdateManyAsync(list); } /// /// 导入物料基础信息表 /// /// /// /// public async Task ImportAsync(WmsMaterialsImportModel input, MyCurrentUser myCurrentUser) { Check.NotNull(input, nameof(input)); var wmsMaterialCreateDtos = new List<(int RowIndex, WmsMaterialCreateDto Item)>(); var wmsMaterialUpdateDtos = new List<(int RowIndex, Guid Id, WmsMaterialUpdateDto Item)>(); var importItems = input.WmsMaterials; if (importItems != null && importItems.Any()) { #region 导入校验 // 判断名称是否重复,并输出第几行重复 var duplicateWmsMaterials = importItems.GroupBy(x => x.MaterialCode).Where(x => x.Count() > 1).ToList(); if (duplicateWmsMaterials?.Any() == true) { var duplicateWmsMaterialMsgs = duplicateWmsMaterials.Select(x => $"第 {string.Join(",", x.Select(x => x.RowIndex))} 行:{x.Key} 名称重复"); var errorMsg = $"导入失败!配置, {string.Join(",", duplicateWmsMaterialMsgs)},终止导入"; throw new UserFriendlyException(errorMsg); } #endregion foreach (var impItem in importItems) { if (impItem.MaterialCode.IsNullOrWhiteSpace()) { continue; } if (impItem.MaterialCode.IsNullOrWhiteSpace()) { var errorMsg = $"导入失败!配置,第{impItem.RowIndex}行:WmsMaterial名称不能为空"; throw new UserFriendlyException(errorMsg); } var oldWmsMaterial = await wmsMaterialRepository.FindByNameAsync(impItem.MaterialCode); if (oldWmsMaterial != null) { var wmsMaterialUpdateDto = new WmsMaterialUpdateDto { MaterialCode = impItem.MaterialCode, IsValid = impItem.IsValid, IsSelfMade = impItem.IsSelfMade, Num = impItem.Num, SelfNum = impItem.SelfNum, MaterialName = impItem.MaterialName, NullLength = impItem.NullLength, PurchaseType = impItem.PurchaseType, MaterialType = impItem.MaterialType, PrimaryUnit = impItem.PrimaryUnit, Standard = impItem.Standard, OuterDiameter = impItem.OuterDiameter, WallThickness = impItem.WallThickness, MaterialQuality = impItem.MaterialQuality, Length = impItem.Length, IsMainBranch = impItem.IsMainBranch, Factory = impItem.Factory, Certification = impItem.Certification, RedundantField1 = impItem.RedundantField1, RedundantField2 = impItem.RedundantField2, RedundantField3 = impItem.RedundantField3, Remark = impItem.Remark, }; wmsMaterialUpdateDtos.Add((impItem.RowIndex, oldWmsMaterial.Id, wmsMaterialUpdateDto)); } else { var wmsMaterialCreateDto = new WmsMaterialCreateDto { MaterialCode = impItem.MaterialCode, IsValid = impItem.IsValid, IsSelfMade = impItem.IsSelfMade, Num = impItem.Num, SelfNum = impItem.SelfNum, MaterialName = impItem.MaterialName, NullLength = impItem.NullLength, PurchaseType = impItem.PurchaseType, MaterialType = impItem.MaterialType, PrimaryUnit = impItem.PrimaryUnit, Standard = impItem.Standard, OuterDiameter = impItem.OuterDiameter, WallThickness = impItem.WallThickness, MaterialQuality = impItem.MaterialQuality, Length = impItem.Length, IsMainBranch = impItem.IsMainBranch, Factory = impItem.Factory, Certification = impItem.Certification, RedundantField1 = impItem.RedundantField1, RedundantField2 = impItem.RedundantField2, RedundantField3 = impItem.RedundantField3, Remark = impItem.Remark, }; wmsMaterialCreateDtos.Add((impItem.RowIndex, wmsMaterialCreateDto)); } } } // 新增 foreach (var wmsMaterialDto in wmsMaterialCreateDtos) { try { wmsMaterialDto.Item.CreatorName = myCurrentUser.UserAccount;//创建人 await CreateAsync(wmsMaterialDto.Item); } catch (Exception e) { var errorMsg = $"导入失败!配置,第{wmsMaterialDto.RowIndex}行:{e.Message},终止导入"; throw new UserFriendlyException(errorMsg); } } // 更新 foreach (var wmsMaterialDto in wmsMaterialUpdateDtos) { try { wmsMaterialDto.Item.LastModifierName = myCurrentUser.UserAccount;//修改人 await UpdateAsync(wmsMaterialDto.Id, wmsMaterialDto.Item); } catch (Exception e) { var errorMsg = $"导入失败!配置,第{wmsMaterialDto.RowIndex}行:{e.Message},终止导入"; throw new UserFriendlyException(errorMsg); } } } /// /// 导出物料基础信息表 /// /// /// public async Task<(Dictionary Sheets, string FileName)> ExportAsync(GetWmsMaterialInput input) { Check.NotNull(input, nameof(input)); if (input.Sorting.IsNullOrWhiteSpace()) { input.Sorting = nameof(WmsMaterial.Sort); } #region 动态构造查询条件 //动态构造查询条件 var whereConditions = DynamicGetQueryParams(input); #endregion var list = await wmsMaterialRepository.GetListAsync(whereConditions, input.Sorting, input.MaxResultCount, input.SkipCount, includeDetails: true); var result = ObjectMapper.Map, List>(list); var sheets = new Dictionary { ["配置"] = ExportHelper.ConvertListToExportData(result), }; var fileName = "物料信息"; return (sheets, fileName); } /// /// 校验物料基础信息表,当新建或更新时 /// /// /// protected Task CheckCreateOrUpdateDtoAsync(WmsMaterialCreateOrUpdateDtoBase input) { Check.NotNull(input, nameof(input)); Check.NotNullOrWhiteSpace(input.MaterialCode, "物料编码(唯一标识)", 64); Check.NotNull(input.IsValid, "是否有效物料"); Check.NotNull(input.Num, "数量"); Check.NotNullOrWhiteSpace(input.MaterialName, "物料名称", 128); Check.NotNull(input.PurchaseType, "采购类型(枚举值)"); Check.NotNull(input.MaterialType, "物料类型(枚举值)"); Check.NotNull(input.OuterDiameter, "外径(单位:mm)"); Check.NotNull(input.WallThickness, "壁厚(单位:mm)"); Check.NotNull(input.Length, "长度(单位:m)"); Check.NotNull(input.IsMainBranch, "是否为主支管"); return Task.CompletedTask; } }