admin/src/Oms.Application/Shared/PriceAreaSnapshotHelper.cs
zzh 7827b4803e feat: slim rules/price publish snapshots with PostcodeRange (left,right]
Use slim DTOs without audit timestamps; migrate legacy LeftPostcode/RightPostcode on read.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-26 14:10:34 +08:00

78 lines
2.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
namespace Oms.Application.Shared;
/// <summary>
/// 将价格分区(t_kpi_area + t_kpi_area_info)固化进卖价发布快照。
/// </summary>
public static class PriceAreaSnapshotHelper
{
/// <summary>
/// 按产品 PriceAreaId(或从卖价明细分区推断)加载分区头与明细写入快照。
/// </summary>
public static async Task ApplyPriceAreaToSnapshotAsync(
SalesProductPricePublishSnapshotDto snapshot,
SalesProduct product,
IKpiAreaRepository kpiAreaRepository,
CancellationToken cancellationToken = default)
{
var priceAreaId = await ResolvePriceAreaIdAsync(
product,
snapshot,
kpiAreaRepository,
cancellationToken);
if (!priceAreaId.HasValue)
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = null;
snapshot.PriceAreaInfos = [];
return;
}
snapshot.PriceAreaId = priceAreaId;
var area = await kpiAreaRepository.FirstOrDefaultAsync(x => x.Id == priceAreaId.Value, cancellationToken);
snapshot.PriceAreaName = area?.Name;
var infos = await kpiAreaRepository.GetAllInfosByAreaIdAsync(priceAreaId.Value, cancellationToken);
snapshot.PriceAreaInfos = infos.Select(KpiAreaSnapshotMapper.MapToSnapshotRule).ToList();
}
internal static async Task<int?> 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;
}
}