using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Services; using Win_in.Sfs.Shared.Domain; using Win_in.Sfs.Shared.Domain.Shared; namespace Win_in.Sfs.Basedata.Domain; public class BomManager : DomainService, IBomManager { private readonly IBomRepository _repository; private readonly IItemBasicRepository _itemBasicRepository; public BomManager(IBomRepository repository, IItemBasicRepository itemBasicRepository) { _repository = repository; _itemBasicRepository = itemBasicRepository; } /// /// 获取对应的Bom信息 /// /// /// /// /// public virtual async Task> GetRecursiveListAsync(string productItemCode, DateTime validTime, bool isRecursive = true) { List totalBoms = new List(); var boms = await _repository.GetListAsync(p => p.Product == productItemCode && (p.BeginTime <= validTime) && (p.EndTime >= validTime)).ConfigureAwait(false); if (isRecursive) { foreach (var bom in boms) { if (bom.Component == bom.Product) { totalBoms.AddRange(boms); continue; } //获取下级Bom,如果有就继续,没有就完事 await GetListWithValidTimeAsync(totalBoms, bom, validTime, 1).ConfigureAwait(false); } } else { foreach (var bom in boms) { var item = await _itemBasicRepository.FindAsync(p => p.Code == bom.Component).ConfigureAwait(false); if (item is { IsPhantom: true }) { await GetRecursiveListAsync(bom.Component, validTime, isRecursive).ConfigureAwait(false); } else { totalBoms.Add(bom); }; } } return totalBoms; } /// /// 递归获取bom /// /// /// /// /// /// private async Task GetListWithValidTimeAsync(List totalBoms, Bom bom, DateTime validTime, decimal multipleQty) { var subboms = await _repository.GetListAsync(p => p.Product == bom.Product && p.BeginTime <= validTime && p.EndTime >= validTime).ConfigureAwait(false); if (subboms == null || subboms.Count == 0) { //根据bom多层放大倍数,第一次传过来的是1 bom.ComponentQty *= multipleQty; totalBoms.Add(bom); return; } else { foreach (var subbom in subboms) { //获取下级Bom,如果有就继续,没有就完事 await GetListWithValidTimeAsync(totalBoms, subbom, validTime, subbom.ComponentQty * multipleQty).ConfigureAwait(false); } } } /// /// 执行导入 /// public virtual async Task ImportDataAsync(List mergeEntities, List deleteEntities = null) { if (deleteEntities != null && deleteEntities.Count > 0) { await _repository.BulkDeleteAsync(deleteEntities).ConfigureAwait(false); } await _repository.BulkMergeAsync(mergeEntities).ConfigureAwait(false); } /// /// 所有子物料号 /// /// /// public virtual async Task> GetListOfProductAsync(string product) { return await _repository.GetListAsync(p => p.Product == product).ConfigureAwait(false); } public virtual async Task> GetListWithPhantomItemAsync(string productItemCode, string mfgOp, DateTime validTime, bool onlyFromProductionPlan) { var where = BuildExpression(productItemCode, mfgOp, validTime, onlyFromProductionPlan); var entities = await (await _repository.GetDbSetAsync().ConfigureAwait(false)).AsNoTracking().Where(where).ToListAsync().ConfigureAwait(false); var phantomItemBoms = await GetPhantomItemBomsAsync(entities, mfgOp, validTime, onlyFromProductionPlan).ConfigureAwait(false); return phantomItemBoms; } private static Expression> BuildExpression(string productItemCode, string mfgOp, DateTime validTime, bool onlyFromProductionPlan) { Expression> where = p => p.Product == productItemCode // && p.MFGOp == mfgOp && p.ComponentQty > 0 && (p.BeginTime <= validTime) && (p.EndTime >= validTime); if (onlyFromProductionPlan) { where = where.And(p => p.DistributionType == EnumDistributionType.FromProductionPlan); } return where; } private async Task> GetPhantomItemBomsAsync(List productBoms, string mfgOp, DateTime validTime, bool onlyFromProductionPlan) { var result = new List(); foreach (var bom in productBoms) { var item = await _itemBasicRepository.FirstOrDefaultAsync(p => p.Code == bom.Component).ConfigureAwait(false); if (item == null) { throw new UserFriendlyException($"代码为 {bom.Component} 的物品信息不存在."); } if (item.IsPhantom) { var where = BuildExpression(item.Code, mfgOp, validTime, onlyFromProductionPlan); var query = (await _repository.GetDbSetAsync().ConfigureAwait(false)).AsNoTracking().Where(where); Console.WriteLine(query.ToString()); var phantomItemBoms = await query.ToListAsync().ConfigureAwait(false); //递归获取下层BOM的子零件为虚零件的BOM var nextLevelBoms = await GetPhantomItemBomsAsync(phantomItemBoms, mfgOp, validTime, onlyFromProductionPlan).ConfigureAwait(false); result.AddRange(nextLevelBoms); } else { result.Add(bom); } } return result; } /// /// 所有父物料号 /// /// /// public virtual async Task> GetListOfComponentAsync(string component) { return await _repository.GetListAsync(p => p.Component == component).ConfigureAwait(false); } }