diff --git a/src/Oms.Application/Shared/PriceAreaSnapshotHelper.cs b/src/Oms.Application/Shared/PriceAreaSnapshotHelper.cs index d06e44f..ab0bd80 100644 --- a/src/Oms.Application/Shared/PriceAreaSnapshotHelper.cs +++ b/src/Oms.Application/Shared/PriceAreaSnapshotHelper.cs @@ -1,5 +1,6 @@ using Oms.Application.Dtos.Channels; using Oms.Application.Dtos.Orders; +using Oms.Application.Services.Orders; using Oms.Domain.ChannelsAggregate.Entities; using Oms.Domain.ChannelsAggregate.Repositories; @@ -11,7 +12,7 @@ namespace Oms.Application.Shared; public static class PriceAreaSnapshotHelper { /// - /// 按产品 PriceAreaId 加载分区头与明细写入快照。 + /// 按产品 PriceAreaId(或从卖价明细分区推断)加载分区头与明细写入快照。 /// public static async Task ApplyPriceAreaToSnapshotAsync( SalesProductPricePublishSnapshotDto snapshot, @@ -19,7 +20,12 @@ public static class PriceAreaSnapshotHelper IKpiAreaRepository kpiAreaRepository, CancellationToken cancellationToken = default) { - if (!product.PriceAreaId.HasValue || product.PriceAreaId <= 0) + var priceAreaId = await ResolvePriceAreaIdAsync( + product, + snapshot, + kpiAreaRepository, + cancellationToken); + if (!priceAreaId.HasValue) { snapshot.PriceAreaId = null; snapshot.PriceAreaName = null; @@ -27,13 +33,48 @@ public static class PriceAreaSnapshotHelper return; } - snapshot.PriceAreaId = product.PriceAreaId; - var area = await kpiAreaRepository.FirstOrDefaultAsync(x => x.Id == product.PriceAreaId.Value, cancellationToken); + snapshot.PriceAreaId = priceAreaId; + var area = await kpiAreaRepository.FirstOrDefaultAsync(x => x.Id == priceAreaId.Value, cancellationToken); snapshot.PriceAreaName = area?.Name; - var infos = await kpiAreaRepository.GetAllInfosByAreaIdAsync(product.PriceAreaId.Value, cancellationToken); + var infos = await kpiAreaRepository.GetAllInfosByAreaIdAsync(priceAreaId.Value, cancellationToken); snapshot.PriceAreaInfos = infos.Select(MapInfoOutput).ToList(); } + internal static async Task ResolvePriceAreaIdAsync( + SalesProduct product, + SalesProductPricePublishSnapshotDto snapshot, + IKpiAreaRepository kpiAreaRepository, + CancellationToken cancellationToken = default) + { + if (product.PriceAreaId is > 0) + { + return product.PriceAreaId; + } + + var zoneKeys = ParcelBillingCalculator.CollectDistinctDetailZoneKeys(snapshot); + foreach (var zoneKey in zoneKeys) + { + if (!int.TryParse(zoneKey.Trim(), out var zoneId) || zoneId <= 0) + { + continue; + } + + var area = await kpiAreaRepository.FirstOrDefaultAsync(x => x.Id == zoneId, cancellationToken); + if (area != null) + { + return zoneId; + } + + var info = await kpiAreaRepository.GetInfoByIdAsync(zoneId, cancellationToken); + if (info != null) + { + return info.AreaId; + } + } + + return null; + } + private static KpiAreaInfoOutput MapInfoOutput(KpiAreaInfo entity) => new() {