- 预报/入库后按排货规则选服务渠道并写入渠道买价应付费用 - 排货发布快照 Providers 去除 CreateTime/UpdateTime - 出库扫描扩展 OutboundRecord 字段与 ApplyShipBillingByWaybillAsync - 服务渠道买价发布预览;按 ChargingStage 删除应付费用 Co-authored-by: Cursor <cursoragent@cursor.com>
80 lines
2.5 KiB
C#
80 lines
2.5 KiB
C#
using FluentAssertions;
|
|
using Oms.Application.Dtos.Channels;
|
|
using Oms.Application.Shared;
|
|
using Oms.Domain.ChannelsAggregate.Consts;
|
|
using Oms.Domain.ChannelsAggregate.Entities;
|
|
|
|
namespace Oms.Tests;
|
|
|
|
public class AllocationResolverTests
|
|
{
|
|
[Fact]
|
|
public void FilterProviders_ShouldRespectCustomerScope()
|
|
{
|
|
var providers = new List<SalesProductAllocationProviderSnapshotDto>
|
|
{
|
|
new() { SerialNumber = 1, ServiceChannelId = 1, CustomerIds = [10] },
|
|
new() { SerialNumber = 2, ServiceChannelId = 2, CustomerIds = [] },
|
|
new() { SerialNumber = 3, ServiceChannelId = null }
|
|
};
|
|
|
|
var filtered = AllocationResolver.FilterProviders(providers, 10);
|
|
filtered.Should().HaveCount(2);
|
|
filtered.Select(x => x.ServiceChannelId).Should().BeEquivalentTo([1, 2]);
|
|
}
|
|
|
|
[Fact]
|
|
public void SelectChannel_CostLowest_ShouldPickCheapest()
|
|
{
|
|
var candidates = BuildCandidates(
|
|
(1, 30m, 5, 10),
|
|
(2, 20m, 8, 20));
|
|
|
|
var channel = AllocationResolver.SelectChannel(AllocationSchemeCodes.CostLowest, candidates);
|
|
channel.Id.Should().Be(2);
|
|
}
|
|
|
|
[Fact]
|
|
public void SelectChannel_TimeFastest_ShouldPickLowestMinTime()
|
|
{
|
|
var candidates = BuildCandidates(
|
|
(1, 30m, 5, 10),
|
|
(2, 20m, 3, 20));
|
|
|
|
var channel = AllocationResolver.SelectChannel(AllocationSchemeCodes.TimeFastest, candidates);
|
|
channel.Id.Should().Be(2);
|
|
}
|
|
|
|
[Fact]
|
|
public void SelectChannel_OverallBest_ShouldPickHighestWeight()
|
|
{
|
|
var candidates = BuildCandidates(
|
|
(1, 30m, 5, 10),
|
|
(2, 20m, 8, 30));
|
|
|
|
var channel = AllocationResolver.SelectChannel(AllocationSchemeCodes.OverallBest, candidates);
|
|
channel.Id.Should().Be(2);
|
|
}
|
|
|
|
private static List<AllocationResolver.ChannelCandidate> BuildCandidates(
|
|
params (int channelId, decimal cost, int minTime, int weight)[] rows)
|
|
{
|
|
return rows.Select(row => new AllocationResolver.ChannelCandidate
|
|
{
|
|
Provider = new SalesProductAllocationProviderSnapshotDto
|
|
{
|
|
SerialNumber = row.channelId,
|
|
ServiceChannelId = row.channelId,
|
|
Weight = row.weight
|
|
},
|
|
Channel = new ServiceChannel
|
|
{
|
|
Id = row.channelId,
|
|
ChannelCode = $"CH-{row.channelId}",
|
|
MinTime = row.minTime
|
|
},
|
|
TotalPayableCost = row.cost
|
|
}).ToList();
|
|
}
|
|
}
|