From 0c7abdfcf701eecacebec6aa9f2cbe69836d7da5 Mon Sep 17 00:00:00 2001 From: zhaoxinyu <89237069@qq.com> Date: Wed, 3 Apr 2024 16:18:31 +0800 Subject: [PATCH] =?UTF-8?q?bom=E7=BB=93=E6=9E=84=E5=88=86=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Boms/BomAppService.cs | 5 + .../Enum/EnumBomSelectedType.cs | 24 ++++ .../Boms/BomComponent.cs | 21 +++ .../Boms/BomManager.cs | 132 ++++++++++++++++++ .../Win_in.Sfs.Basedata.Domain.csproj | 1 + ...uipmentDbContextModelCreatingExtensions.cs | 2 + .../Balances/BalanceAppService.cs | 7 +- .../Notes/MesNotes/MesNoteAppService.cs | 27 ++-- .../ProductionReturnNoteAppService.cs | 2 - .../ProductionReturnRequestAppService.cs | 22 ++- .../Transactions/MesNoteEventHandler.cs | 23 +-- .../ProductionReturnNoteEventHandler.cs | 5 +- 12 files changed, 239 insertions(+), 32 deletions(-) create mode 100644 be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Enum/EnumBomSelectedType.cs create mode 100644 be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomComponent.cs diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Application/Boms/BomAppService.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Application/Boms/BomAppService.cs index ec2e12831..1aaf547e5 100644 --- a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Application/Boms/BomAppService.cs +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Application/Boms/BomAppService.cs @@ -199,3 +199,8 @@ public class BomAppService : } + + + + + diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Enum/EnumBomSelectedType.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Enum/EnumBomSelectedType.cs new file mode 100644 index 000000000..6db151b9e --- /dev/null +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain.Shared/Enum/EnumBomSelectedType.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; + +namespace Win_in.Sfs.Basedata.Domain.Shared; + +public enum EnumBomSelectedType +{ + /// + /// 树状 + /// + [Display(Name = "树装")] + Tree = 0, + /// + /// 一维 + /// + [Display(Name = "一维")] + Dimension = 1, + + /// + /// 最终子节点 + /// + [Display(Name = "最终子节点")] + Last = 2, + +} diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomComponent.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomComponent.cs new file mode 100644 index 000000000..9a61976a2 --- /dev/null +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomComponent.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Win_in.Sfs.Basedata.Boms; +public class BomComponent +{ + public string Root { get; set; } + public string Component { get; set; } + public string ComponentUom { get; set; } + public decimal ComponentQty { get; set; } + + + public string ParentComponent { get; set; } + + public decimal SumQty { get; set; } + public int Level { get; set; } + public List SubComponents { get; set; } +} diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomManager.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomManager.cs index 2be49a698..2b2db9cb3 100644 --- a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomManager.cs +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Boms/BomManager.cs @@ -4,9 +4,13 @@ using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using NetTopologySuite.Geometries; +using Omu.ValueInjecter; using Volo.Abp; using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Services; +using Win_in.Sfs.Basedata.Boms; +using Win_in.Sfs.Basedata.Domain.Shared; using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Shared; @@ -213,4 +217,132 @@ public class BomManager : DomainService, IBomManager } return lst; } + + /// + /// Bom操作 + /// + /// + /// + /// + private async Task> GetSubcomponentsRecursiveLast(BomComponent p_component, EnumBomSelectedType p_type + ) + { + List lastList = new List(); + List dimensionList=new List(); + var treeList=await GetSubcomponentsRecursive(p_component, 1, p_component.ComponentQty, p_component.Component, + (rs) => lastList.Add(rs) + , + (rs1)=>{ + dimensionList.Add(rs1); + }).ConfigureAwait(false); + + + + List lastBomList = new List(); + List dimensionBomList = new List(); + List treeBomList = new List(); + foreach (var itm in dimensionList) + { + Bom bom = new Bom(); + bom.InjectFrom(itm); + dimensionBomList.Add(bom); + } + foreach (var itm in lastList) + { + Bom bom = new Bom(); + bom.InjectFrom(itm); + lastBomList.Add(bom); + } + foreach (var itm in treeList) + { + Bom bom = new Bom(); + bom.InjectFrom(itm); + treeBomList.Add(bom); + } + List returnList=new List(); + switch (p_type) + { + case EnumBomSelectedType.Last: + returnList.AddRange(lastBomList); + break; + case EnumBomSelectedType.Tree: + returnList.AddRange(treeBomList); + break; + case EnumBomSelectedType.Dimension: + returnList.AddRange(dimensionBomList); + break; + } + return returnList; + } + + /// + /// 层级、拆解、一维结构、树状结构 + /// + /// 上级组件(初始时为根元素) + /// 层级一般为1 + /// 累计数量 + /// 根 + /// 拆解到最终零件时 + /// 树型转成一维表用 + /// + private async Task> GetSubcomponentsRecursive(BomComponent p_component, int level, decimal sumQty, string root, Action p_actionLast, + Action p_actionDimension + ) + { + List subComponents = new List(); + // 假设 GetComponentsByProduct 方法可获取某个物料号下的所有子零件 + List directSubComponents =await GetComponentsByProduct(p_component.Component).ConfigureAwait(false); + + if (!directSubComponents.Any() && level != 1)//不是根元素 + { + p_actionLast(p_component); + } + foreach (var component in directSubComponents) + { + component.Root = root; + component.SumQty = sumQty * component.ComponentQty; + component.ParentComponent = p_component.Component; + component.Level = level; + component.SubComponents =await GetSubcomponentsRecursive(component, level + 1, sumQty * component.ComponentQty, component.Root, p_actionLast, p_actionDimension).ConfigureAwait(false); + p_actionDimension(component); + subComponents.Add(component); + } + return subComponents; + } + + private async Task> GetComponentsByProduct(string product) + { + + var list= await _repository.GetListAsync(p => p.Product == product).ConfigureAwait(false); + List components = new List(); + foreach (var component in list) + { + BomComponent bomComponent = new BomComponent(); + bomComponent.InjectFrom(component); + components.Add(bomComponent); + } + + + // 其他物料号的子零件信息类似添加 + return components; + } + + + + + + + + + + + + + + + + + + + } diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Win_in.Sfs.Basedata.Domain.csproj b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Win_in.Sfs.Basedata.Domain.csproj index 7caf3bd8e..2011bcbb2 100644 --- a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Win_in.Sfs.Basedata.Domain.csproj +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.Domain/Win_in.Sfs.Basedata.Domain.csproj @@ -8,6 +8,7 @@ + diff --git a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.EntityFrameworkCore/Equipments/EquipmentDbContextModelCreatingExtensions.cs b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.EntityFrameworkCore/Equipments/EquipmentDbContextModelCreatingExtensions.cs index e45466955..1d2edbf0f 100644 --- a/be/Modules/BaseData/src/Win_in.Sfs.Basedata.EntityFrameworkCore/Equipments/EquipmentDbContextModelCreatingExtensions.cs +++ b/be/Modules/BaseData/src/Win_in.Sfs.Basedata.EntityFrameworkCore/Equipments/EquipmentDbContextModelCreatingExtensions.cs @@ -21,6 +21,8 @@ public static class EquipmentDbContextModelCreatingExtensions //Properties b.Property(q => q.Code).IsRequired().HasMaxLength(SfsPropertyConst.CodeLength).IsRequired(true); + b.Property(q => q.Model).HasMaxLength(SfsPropertyConst.CodeLength); + b.Property(q => q.Model).HasMaxLength(SfsPropertyConst.CodeLength); b.Property(q => q.LocCode).HasMaxLength(SfsPropertyConst.CodeLength); diff --git a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/Balances/BalanceAppService.cs b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/Balances/BalanceAppService.cs index a8408e666..dc94a25de 100644 --- a/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/Balances/BalanceAppService.cs +++ b/be/Modules/Inventory/src/Win_in.Sfs.Wms.Inventory.Application/Balances/BalanceAppService.cs @@ -50,7 +50,7 @@ public class BalanceAppService ILocationAclService locationAclService, IItemBasicAclService itemBasicAclService, IItemBasicAppService itemBasicAppService, - IStdCostPriceSheetAppService stdCostPriceSheetAppService) : base(repository) + IStdCostPriceSheetAppService stdCostPriceSheetAppService) : base(repository) { _repository = repository; _transferLogManager = transferLogManager; @@ -654,24 +654,19 @@ public class BalanceAppService { input.Condition.Filters.Add(new Filter("ContainerCode", listInput.containerCode)); } - if (listInput.locationTypes != null && listInput.locationTypes.Any()) { var locationCodes = (await _locationAclService.GetListByTypesAsync(listInput.locationTypes).ConfigureAwait(false)).Select(t => t.Code).ToList(); - if (locationCodes.Any()) { input.Condition.Filters.Add(new Filter("LocationCode", JsonSerializer.Serialize(locationCodes), "In")); } } - if (listInput.inventoryStatuses != null && listInput.inventoryStatuses.Any()) { input.Condition.Filters.Add(new Filter("Status", JsonSerializer.Serialize(listInput.inventoryStatuses), "In")); } - var balanceDTOs = await GetPagedListByFilterAsync(input, false).ConfigureAwait(false); - return balanceDTOs; } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/MesNotes/MesNoteAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/MesNotes/MesNoteAppService.cs index 5b154ffb1..66fcf43a8 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/MesNotes/MesNoteAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/MesNotes/MesNoteAppService.cs @@ -17,9 +17,11 @@ namespace Win_in.Sfs.Wms.Store.Application; using System.Collections.Generic; using System.Linq; using IdentityModel; +using Omu.ValueInjecter; using Volo.Abp; using Volo.Abp.Domain.Entities; using Volo.Abp.ObjectMapping; +using Win_in.Sfs.Basedata.Domain; using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Shared; using Win_in.Sfs.Shared.Event; @@ -33,11 +35,14 @@ public class MesNoteAppService : IMesNoteAppService { private readonly ILocationAppService _locationAppService; - private readonly IItemBasicAppService _itemBasicAppService; + private readonly IBomAppService _bomAppService; + private readonly IItemBasicAppService _itemBasicAppService; private readonly IBalanceAppService _balanceAppService; public MesNoteAppService( + IBomAppService bomAppService, IMesNoteRepository repository, ILocationAppService locationAppService, IItemBasicAppService itemBasicAppService,IBalanceAppService balanceAppService) : base(repository) { + _bomAppService = bomAppService; _locationAppService = locationAppService; _itemBasicAppService = itemBasicAppService; _balanceAppService = balanceAppService; @@ -51,22 +56,17 @@ public class MesNoteAppService : var number = string.IsNullOrEmpty(entity.Number) ? await GenerateNumberAsync(nameof(MesNote), entity.ActiveDate).ConfigureAwait(false) : entity.Number; entity.SetIdAndNumberWithDetails(GuidGenerator, number); - - - - - + SfsInventoryRequestInputBase pm = new SfsInventoryRequestInputBase(); + // pm.Condition.Filters.Add(new Filter() { Column="", Action= }); + // _balanceAppService.GetBalancePagedListByFilterAsync(); foreach (var detail in entity.Details) { var fromLocation=await _locationAppService.GetByCodeAsync(detail.FromLocationCode).ConfigureAwait(false); var toLocation =await _locationAppService.GetByCodeAsync(detail.ToLocationCode).ConfigureAwait(false); var itemBasicDto =await _itemBasicAppService.GetByCodeAsync(detail.ItemCode).ConfigureAwait(false); - if (fromLocation == null) { - throw new UserFriendlyException($"库位为空"); - } detail.SetIdAndNumber(GuidGenerator, entity.Id, entity.Number); detail.FromLocationArea = fromLocation.AreaCode; @@ -82,14 +82,12 @@ public class MesNoteAppService : detail.StdPackQty = itemBasicDto.StdPackQty; #region 添加校验 + //RecommendBalanceRequestInput rInput = new RecommendBalanceRequestInput(); //rInput.ItemCode = detail.ItemCode; //rInput.Locations = new List() { detail.FromLocationCode }; //rInput.Qty = detail.Qty; //rInput.Statuses = new List { EnumInventoryStatus.OK }; - - - //var balanceLst = await _balanceAppService.GetRecommendBalancesByLocationsAsync(rInput).ConfigureAwait(false); //var first = balanceLst.FirstOrDefault(); //if (first != null) @@ -103,6 +101,7 @@ public class MesNoteAppService : //{ // throw new UserFriendlyException($"库存数量不足"); //} + #endregion } @@ -129,4 +128,8 @@ public class MesNoteAppService : return await GetPagedListAsync(expression, requestInput.SkipCount, requestInput.MaxResultCount, requestInput.Sorting, includeDetails, cancellationToken).ConfigureAwait(false); } + + + + } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ProductionReturnNotes/ProductionReturnNoteAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ProductionReturnNotes/ProductionReturnNoteAppService.cs index 3577dcc3c..5202e5882 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ProductionReturnNotes/ProductionReturnNoteAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Notes/ProductionReturnNotes/ProductionReturnNoteAppService.cs @@ -37,9 +37,7 @@ public class ProductionReturnNoteAppService : public override async Task CreateAsync(ProductionReturnNoteEditInput input) { var entity = ObjectMapper.Map(input); - await _ProductionReturnNoteManager.CreateAsync(entity).ConfigureAwait(false); - var dto = ObjectMapper.Map(entity); return dto; } diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ProductionReturnRequests/ProductionReturnRequestAppService.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ProductionReturnRequests/ProductionReturnRequestAppService.cs index 617bc4e55..c8756eb35 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ProductionReturnRequests/ProductionReturnRequestAppService.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Application/Requests/ProductionReturnRequests/ProductionReturnRequestAppService.cs @@ -32,6 +32,10 @@ public class ProductionReturnRequestAppService : private readonly IPurchaseOrderAppService _purchaseOrderApp; private readonly IItemBasicAppService _itemBasicAppService; private readonly ILocationAppService _locationAppService; + private readonly IBalanceAppService _balanceAppservice; + + + public ProductionReturnRequestAppService( IProductionReturnRequestRepository repository, @@ -39,7 +43,11 @@ public class ProductionReturnRequestAppService : IItemStoreRelationAppService itemStoreRelationApp, IPurchaseOrderAppService purchaseOrderApp, IItemBasicAppService itemBasicAppService, - ILocationAppService locationAppService) + ILocationAppService locationAppService, + IBalanceAppService _balanceAppservice + + + ) : base(repository, productionRequestReturnManager) { _productionReturnRequestManager = productionRequestReturnManager; @@ -58,6 +66,18 @@ public class ProductionReturnRequestAppService : //[Authorize(ProductionReturnRequestPermissions.Create)] public override async Task CreateAsync(ProductionReturnRequestEditInput input) { + + + + + + //SfsInventoryRequestInputBase sfsRequestInput = new SfsInventoryRequestInputBase(); + //sfsRequestInput.Condition + + + + + var entity = ObjectMapper.Map(input); await _productionReturnRequestManager.CreateAsync(entity).ConfigureAwait(false); diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/MesNoteEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/MesNoteEventHandler.cs index e0ea1d327..d8b70a01f 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/MesNoteEventHandler.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/MesNoteEventHandler.cs @@ -40,18 +40,24 @@ public class MesNoteEventHandler private async Task AddTransactionsAsync(List MesNotes) { - //如果WMS管理报废库,生成库存转移 - if (await SettingManager.IsTrueAsync(StoreSettings.Common.EnableScrapLocation).ConfigureAwait(false)) - { + //if (await SettingManager.IsTrueAsync(StoreSettings.Common.EnableScrapLocation).ConfigureAwait(false)) + //{ + // var transferLogs = new List(); + // foreach (var MesNote in MesNotes) + // { + // transferLogs.AddRange(BuildTransferLogs(MesNote)); + // } + // await TransferLogAppService.AddManyAsync(transferLogs).ConfigureAwait(false); + //} + //else + //{ var transferLogs = new List(); foreach (var MesNote in MesNotes) { transferLogs.AddRange(BuildTransferLogs(MesNote)); } await TransferLogAppService.AddManyAsync(transferLogs).ConfigureAwait(false); - } - else - { + var transactions = new List(); foreach (var MesNote in MesNotes) { @@ -59,7 +65,7 @@ public class MesNoteEventHandler } await TransactionAppService.AddManyAsync(transactions).ConfigureAwait(false); - } + //} } private List BuildTransferLogs(MesNote MesNote) @@ -68,13 +74,11 @@ public class MesNoteEventHandler foreach (var detail in MesNote.Details.Where(detail => detail.Qty != 0)) { var transferLog = ObjectMapper.Map(detail); - transferLog.TransType = TransType; transferLog.TransSubType = Enum.Parse(MesNote.Type); transferLog.Worker = MesNote.Worker; transferLog.DocNumber = MesNote.Number; transferLog.JobNumber = MesNote.JobNumber; - transferLogs.Add(transferLog); } @@ -88,7 +92,6 @@ public class MesNoteEventHandler foreach (var detail in deliverNote.Details) { var transaction = ObjectMapper.Map(detail); - transaction.TransType = TransType; transaction.TransInOut = EnumTransInOut.Out; transaction.Worker = deliverNote.Worker; diff --git a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/ProductionReturnNoteEventHandler.cs b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/ProductionReturnNoteEventHandler.cs index ac43185d9..5429793b0 100644 --- a/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/ProductionReturnNoteEventHandler.cs +++ b/be/Modules/Store/src/Win_in.Sfs.Wms.Store.Event/Transactions/ProductionReturnNoteEventHandler.cs @@ -16,6 +16,10 @@ public class ProductionReturnNoteEventHandler : StoreInventoryEventHandlerBase , ILocalEventHandler> , ILocalEventHandler>> + + + + { private const EnumTransType TransType = EnumTransType.ProductionReturn; @@ -57,7 +61,6 @@ public class ProductionReturnNoteEventHandler private async Task AddTransactionsAsync(List ProductionReturnNotes) { - var inboundTransactions = new List(); //如果要做库存事务汇总,可以修改此处