using Oms.Application.Dtos.Orders;
using Oms.Application.Services.Orders;
using Oms.Domain.ChannelsAggregate.Entities;
using Oms.Domain.ChannelsAggregate.Repositories;
namespace Oms.Application.Shared;
///
/// 卖价发布:解析价区表 Id 并钉分区包引用(不内嵌 Infos)。
///
public static class PriceAreaSnapshotHelper
{
///
/// 写入 PriceAreaRefs(Ensure 分区包);Infos 仅 LIVE 路径由 PackService.LoadLive 填充。
///
public static async Task ApplyPriceAreaToSnapshotAsync(
SalesProductPricePublishSnapshotDto snapshot,
SalesProduct product,
IKpiAreaRepository kpiAreaRepository,
KpiAreaPackService packService,
string? publishUser = null,
CancellationToken cancellationToken = default)
{
var areaIds = await CollectResolvedPriceAreaIdsAsync(
product,
snapshot,
kpiAreaRepository,
cancellationToken);
snapshot.PriceAreaInfos = [];
if (areaIds.Count == 0)
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = null;
snapshot.PriceAreaRefs = [];
return;
}
var refs = new List();
foreach (var areaId in areaIds)
{
refs.Add(await packService.EnsurePackAsync(
areaId,
KpiAreaPackService.AreaTypePrice,
publishUser,
description: "sales-product-price-publish",
cancellationToken));
}
AssignPriceAreaRefs(snapshot, refs);
}
///
/// 同步态:解析价区 ContentHash / 已有包 Version,不 Ensure 新包。
///
public static async Task ApplyPriceAreaRefsForSyncAsync(
SalesProductPricePublishSnapshotDto snapshot,
SalesProduct product,
IKpiAreaRepository kpiAreaRepository,
KpiAreaPackService packService,
CancellationToken cancellationToken = default)
{
var areaIds = await CollectResolvedPriceAreaIdsAsync(
product,
snapshot,
kpiAreaRepository,
cancellationToken);
snapshot.PriceAreaInfos = [];
if (areaIds.Count == 0)
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = null;
snapshot.PriceAreaRefs = [];
return;
}
var refs = new List();
foreach (var areaId in areaIds)
{
refs.Add(await packService.ResolvePackRefForSyncAsync(areaId, cancellationToken));
}
AssignPriceAreaRefs(snapshot, refs);
}
private static void AssignPriceAreaRefs(
SalesProductPricePublishSnapshotDto snapshot,
List refs)
{
snapshot.PriceAreaRefs = refs;
if (refs.Count == 1)
{
snapshot.PriceAreaId = refs[0].AreaId;
snapshot.PriceAreaName = refs[0].AreaName;
}
else
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = string.Join(
"、",
refs.Select(x => x.AreaName).Where(x => !string.IsNullOrWhiteSpace(x)));
}
}
///
/// LIVE/模拟:不钉包,直接从当前库装载 Infos。
///
public static async Task ApplyLivePriceAreaInfosAsync(
SalesProductPricePublishSnapshotDto snapshot,
SalesProduct product,
IKpiAreaRepository kpiAreaRepository,
KpiAreaPackService packService,
CancellationToken cancellationToken = default)
{
var areaIds = await CollectResolvedPriceAreaIdsAsync(
product,
snapshot,
kpiAreaRepository,
cancellationToken);
await packService.LoadLiveInfosIntoPriceSnapshotAsync(snapshot, areaIds, cancellationToken);
}
///
/// 收集卖价明细(及产品 PriceAreaId)可解析到的全部价格分区表 Id,去重保序。
///
internal static async Task> CollectResolvedPriceAreaIdsAsync(
SalesProduct product,
SalesProductPricePublishSnapshotDto snapshot,
IKpiAreaRepository kpiAreaRepository,
CancellationToken cancellationToken = default)
{
var result = new List();
var seen = new HashSet();
void Add(int? areaId)
{
if (areaId is > 0 && seen.Add(areaId.Value))
{
result.Add(areaId.Value);
}
}
if (product.PriceAreaId is > 0)
{
Add(product.PriceAreaId);
}
var zoneKeys = ParcelBillingCalculator.CollectDistinctDetailZoneKeys(snapshot);
foreach (var zoneKey in zoneKeys)
{
Add(await TryResolveZoneKeyToAreaIdAsync(zoneKey, kpiAreaRepository, cancellationToken));
}
return result;
}
internal static async Task ResolvePriceAreaIdAsync(
SalesProduct product,
SalesProductPricePublishSnapshotDto snapshot,
IKpiAreaRepository kpiAreaRepository,
CancellationToken cancellationToken = default)
{
var ids = await CollectResolvedPriceAreaIdsAsync(
product,
snapshot,
kpiAreaRepository,
cancellationToken);
return ids.Count > 0 ? ids[0] : null;
}
///
/// 渠道买价发布:从明细推断价区表并钉包(与产品卖价分区独立)。
///
public static async Task ApplyChannelPriceAreaToSnapshotAsync(
ServiceChannelPricePublishSnapshotDto snapshot,
IKpiAreaRepository kpiAreaRepository,
KpiAreaPackService packService,
string? publishUser = null,
CancellationToken cancellationToken = default)
{
var areaIds = await CollectResolvedChannelPriceAreaIdsAsync(
snapshot,
kpiAreaRepository,
cancellationToken);
snapshot.PriceAreaInfos = [];
if (areaIds.Count == 0)
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = null;
snapshot.PriceAreaRefs = [];
return;
}
var refs = new List();
foreach (var areaId in areaIds)
{
refs.Add(await packService.EnsurePackAsync(
areaId,
KpiAreaPackService.AreaTypePrice,
publishUser,
description: "service-channel-price-publish",
cancellationToken));
}
AssignChannelPriceAreaRefs(snapshot, refs);
}
///
/// 渠道买价同步态:不 Ensure 新包。
///
public static async Task ApplyChannelPriceAreaRefsForSyncAsync(
ServiceChannelPricePublishSnapshotDto snapshot,
IKpiAreaRepository kpiAreaRepository,
KpiAreaPackService packService,
CancellationToken cancellationToken = default)
{
var areaIds = await CollectResolvedChannelPriceAreaIdsAsync(
snapshot,
kpiAreaRepository,
cancellationToken);
snapshot.PriceAreaInfos = [];
if (areaIds.Count == 0)
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = null;
snapshot.PriceAreaRefs = [];
return;
}
var refs = new List();
foreach (var areaId in areaIds)
{
refs.Add(await packService.ResolvePackRefForSyncAsync(areaId, cancellationToken));
}
AssignChannelPriceAreaRefs(snapshot, refs);
}
private static void AssignChannelPriceAreaRefs(
ServiceChannelPricePublishSnapshotDto snapshot,
List refs)
{
snapshot.PriceAreaRefs = refs;
if (refs.Count == 1)
{
snapshot.PriceAreaId = refs[0].AreaId;
snapshot.PriceAreaName = refs[0].AreaName;
}
else
{
snapshot.PriceAreaId = null;
snapshot.PriceAreaName = string.Join(
"、",
refs.Select(x => x.AreaName).Where(x => !string.IsNullOrWhiteSpace(x)));
}
}
///
/// 渠道买价 LIVE:不钉包,从当前库装 Infos。
///
public static async Task ApplyLiveChannelPriceAreaInfosAsync(
ServiceChannelPricePublishSnapshotDto snapshot,
IKpiAreaRepository kpiAreaRepository,
KpiAreaPackService packService,
CancellationToken cancellationToken = default)
{
var areaIds = await CollectResolvedChannelPriceAreaIdsAsync(
snapshot,
kpiAreaRepository,
cancellationToken);
await packService.LoadLiveInfosIntoChannelPriceSnapshotAsync(snapshot, areaIds, cancellationToken);
}
internal static async Task> CollectResolvedChannelPriceAreaIdsAsync(
ServiceChannelPricePublishSnapshotDto snapshot,
IKpiAreaRepository kpiAreaRepository,
CancellationToken cancellationToken = default)
{
var result = new List();
var seen = new HashSet();
void Add(int? areaId)
{
if (areaId is > 0 && seen.Add(areaId.Value))
{
result.Add(areaId.Value);
}
}
var zoneKeys = ParcelBillingCalculator.CollectDistinctDetailZoneKeys(snapshot);
foreach (var zoneKey in zoneKeys)
{
Add(await TryResolveZoneKeyToAreaIdAsync(zoneKey, kpiAreaRepository, cancellationToken));
}
return result;
}
private static async Task TryResolveZoneKeyToAreaIdAsync(
string zoneKey,
IKpiAreaRepository kpiAreaRepository,
CancellationToken cancellationToken)
{
if (!int.TryParse(zoneKey.Trim(), out var zoneId) || zoneId <= 0)
{
return null;
}
var area = await kpiAreaRepository.FirstOrDefaultAsync(x => x.Id == zoneId, cancellationToken);
if (area != null)
{
return zoneId;
}
var info = await kpiAreaRepository.GetInfoByIdAsync(zoneId, cancellationToken);
return info?.AreaId;
}
}