196 lines
7.1 KiB
C#
196 lines
7.1 KiB
C#
using Fake.DependencyInjection;
|
|
using Oms.Application.Dtos.Channels;
|
|
using Oms.Application.Integrations.Itfx;
|
|
using Oms.Domain.ChannelsAggregate.Entities;
|
|
using Oms.Domain.ChannelsAggregate.Repositories;
|
|
|
|
namespace Oms.Application.Shared;
|
|
|
|
/// <summary>
|
|
/// 为排货 Provider 快照补充渠道与 itfx 下游对接元数据。
|
|
/// </summary>
|
|
public class AllocationProviderSnapshotEnricher(
|
|
IServiceChannelRepository serviceChannelRepository,
|
|
IServiceChannelGroupRepository serviceChannelGroupRepository,
|
|
IItfxMetadataClient itfxMetadataClient) : IScopedDependency
|
|
{
|
|
public async Task EnrichAsync(
|
|
IList<SalesProductAllocationProviderSnapshotDto> providers,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (providers.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var channelIds = providers
|
|
.Where(x => x.ServiceChannelId.HasValue && x.ServiceChannelId.Value > 0)
|
|
.Select(x => x.ServiceChannelId!.Value)
|
|
.Distinct()
|
|
.ToArray();
|
|
if (channelIds.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var channels = await serviceChannelRepository.GetListAsync(x => channelIds.Contains(x.Id));
|
|
var channelMap = channels.ToDictionary(x => x.Id);
|
|
|
|
var groupIds = channels
|
|
.Where(x => x.GroupId.HasValue && x.GroupId.Value > 0)
|
|
.Select(x => x.GroupId!.Value)
|
|
.Distinct()
|
|
.ToArray();
|
|
var groups = groupIds.Length == 0
|
|
? []
|
|
: await serviceChannelGroupRepository.GetListAsync(x => groupIds.Contains(x.Id));
|
|
var groupMap = groups.ToDictionary(x => x.Id);
|
|
|
|
foreach (var provider in providers)
|
|
{
|
|
if (!provider.ServiceChannelId.HasValue
|
|
|| !channelMap.TryGetValue(provider.ServiceChannelId.Value, out var channel))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
ApplyChannelFields(provider, channel);
|
|
|
|
if (!channel.GroupId.HasValue || !groupMap.TryGetValue(channel.GroupId.Value, out var group))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
await ApplyGroupDownstreamFieldsAsync(provider, group, cancellationToken);
|
|
}
|
|
}
|
|
|
|
public async Task<ServiceChannelDownstreamSnapshotDto?> BuildDownstreamFromGroupAsync(
|
|
ServiceChannelGroup group,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var snapshot = new ServiceChannelDownstreamSnapshotDto
|
|
{
|
|
GroupId = group.Id,
|
|
GroupName = NullIfEmpty(group.Name),
|
|
AppId = group.AppId > 0 ? group.AppId : null,
|
|
ApiServiceProviderId = group.ApiServiceProviderId > 0 ? group.ApiServiceProviderId : null
|
|
};
|
|
|
|
await FillItfxMetadataAsync(snapshot, cancellationToken);
|
|
|
|
return snapshot.GroupId.HasValue
|
|
|| !string.IsNullOrWhiteSpace(snapshot.GroupName)
|
|
|| snapshot.AppId is > 0
|
|
|| !string.IsNullOrWhiteSpace(snapshot.AppKey)
|
|
|| !string.IsNullOrWhiteSpace(snapshot.AppName)
|
|
|| snapshot.ApiServiceProviderId is > 0
|
|
|| !string.IsNullOrWhiteSpace(snapshot.SupplierCode)
|
|
|| !string.IsNullOrWhiteSpace(snapshot.ApiServiceProviderName)
|
|
? snapshot
|
|
: null;
|
|
}
|
|
|
|
public static void ApplyChannelFields(SalesProductAllocationProviderSnapshotDto provider, ServiceChannel channel)
|
|
{
|
|
provider.ChannelCode = NullIfEmpty(channel.ChannelCode);
|
|
provider.ForecastCode = NullIfEmpty(channel.ForecastCode);
|
|
provider.GroupId = channel.GroupId;
|
|
if (string.IsNullOrWhiteSpace(provider.ServiceChannelName))
|
|
{
|
|
provider.ServiceChannelName = NullIfEmpty(channel.ChannelName);
|
|
}
|
|
}
|
|
|
|
public static void ApplyDownstreamFieldsToOrder(
|
|
Domain.OrdersAggregate.Entities.Order order,
|
|
SalesProductAllocationProviderSnapshotDto provider,
|
|
ServiceChannel? channelFallback = null)
|
|
{
|
|
order.DownstreamSupplierCode = NullIfEmpty(provider.SupplierCode);
|
|
order.DownstreamAppKey = NullIfEmpty(provider.AppKey);
|
|
order.DownstreamAppId = provider.AppId;
|
|
order.ChannelForecastCode = NullIfEmpty(provider.ForecastCode)
|
|
?? NullIfEmpty(channelFallback?.ForecastCode);
|
|
}
|
|
|
|
private async Task ApplyGroupDownstreamFieldsAsync(
|
|
SalesProductAllocationProviderSnapshotDto provider,
|
|
ServiceChannelGroup group,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
provider.GroupId = group.Id;
|
|
provider.GroupName = NullIfEmpty(group.Name);
|
|
provider.AppId = group.AppId > 0 ? group.AppId : null;
|
|
provider.ApiServiceProviderId = group.ApiServiceProviderId > 0 ? group.ApiServiceProviderId : null;
|
|
|
|
if (provider.AppId is > 0)
|
|
{
|
|
var app = await itfxMetadataClient.GetAppAsync(provider.AppId.Value, cancellationToken);
|
|
if (!string.IsNullOrWhiteSpace(app?.AppKey))
|
|
{
|
|
provider.AppKey = app.AppKey;
|
|
}
|
|
|
|
provider.AppName = NullIfEmpty(app?.Name);
|
|
}
|
|
|
|
if (provider.ApiServiceProviderId is > 0)
|
|
{
|
|
var sp = await itfxMetadataClient.GetServiceProviderAsync(
|
|
provider.ApiServiceProviderId.Value,
|
|
cancellationToken);
|
|
if (!string.IsNullOrWhiteSpace(sp?.Code))
|
|
{
|
|
provider.SupplierCode = sp.Code;
|
|
}
|
|
|
|
provider.ApiServiceProviderName = NullIfEmpty(sp?.Name);
|
|
}
|
|
}
|
|
|
|
private async Task FillItfxMetadataAsync(
|
|
ServiceChannelDownstreamSnapshotDto snapshot,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (snapshot.AppId is > 0)
|
|
{
|
|
var app = await itfxMetadataClient.GetAppAsync(snapshot.AppId.Value, cancellationToken);
|
|
if (!string.IsNullOrWhiteSpace(app?.AppKey))
|
|
{
|
|
snapshot.AppKey = app.AppKey;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(app?.AppSecret))
|
|
{
|
|
snapshot.AppSecret = app.AppSecret;
|
|
}
|
|
|
|
snapshot.AppName = NullIfEmpty(app?.Name);
|
|
}
|
|
|
|
if (snapshot.ApiServiceProviderId is > 0)
|
|
{
|
|
var sp = await itfxMetadataClient.GetServiceProviderAsync(
|
|
snapshot.ApiServiceProviderId.Value,
|
|
cancellationToken);
|
|
if (!string.IsNullOrWhiteSpace(sp?.Code))
|
|
{
|
|
snapshot.SupplierCode = sp.Code;
|
|
}
|
|
|
|
snapshot.ApiServiceProviderName = NullIfEmpty(sp?.Name);
|
|
}
|
|
}
|
|
|
|
private static string? NullIfEmpty(string? value) =>
|
|
string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
|
|
|
public static bool NeedsDownstreamEnrichment(SalesProductAllocationProviderSnapshotDto provider) =>
|
|
provider.ServiceChannelId is > 0
|
|
&& (string.IsNullOrWhiteSpace(provider.ChannelCode)
|
|
|| string.IsNullOrWhiteSpace(provider.ForecastCode)
|
|
|| string.IsNullOrWhiteSpace(provider.SupplierCode)
|
|
|| string.IsNullOrWhiteSpace(provider.AppKey));
|
|
}
|