feat: 同一产品/渠道下卖价买价费用项唯一,禁止重复新增
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
1b6e91b09d
commit
79099776a5
@ -388,10 +388,11 @@ public partial class SalesProductService
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// 保险/偏远费等附加费用项的计费条件校验。
|
||||
/// 保险/偏远费等附加费用项的计费条件校验;同一提交批次内费用项不可重复。
|
||||
/// </summary>
|
||||
private static void ValidateBillingPriceItemRules(IReadOnlyList<SalesProductPriceSaveInput> prices)
|
||||
{
|
||||
EnsureUniqueCostItemsInBatch(prices.Select(x => x.CostItem));
|
||||
foreach (var price in prices)
|
||||
{
|
||||
var costItem = price.CostItem?.Trim() ?? string.Empty;
|
||||
@ -417,6 +418,44 @@ public partial class SalesProductService
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同一销售产品下每种费用项只能有一条卖价配置。
|
||||
/// </summary>
|
||||
private async Task EnsureCostItemUniqueAsync(int salesProductId, string? costItem, int? excludePriceId)
|
||||
{
|
||||
var trimmed = costItem?.Trim() ?? string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(trimmed))
|
||||
{
|
||||
throw new Fake.Application.BusinessException("费用项不能为空");
|
||||
}
|
||||
|
||||
var existing = await SalesProductRepository.GetPricesAsync(salesProductId);
|
||||
var duplicated = existing.Any(p =>
|
||||
(!excludePriceId.HasValue || p.Id != excludePriceId.Value)
|
||||
&& string.Equals(p.CostItem?.Trim(), trimmed, StringComparison.OrdinalIgnoreCase));
|
||||
if (duplicated)
|
||||
{
|
||||
throw new Fake.Application.BusinessException(
|
||||
$"该产品已存在费用项「{trimmed}」,同一产品下每种费用项只能有一条");
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureUniqueCostItemsInBatch(IEnumerable<string?> costItems)
|
||||
{
|
||||
var duplicates = costItems
|
||||
.Select(x => x?.Trim() ?? string.Empty)
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
.GroupBy(x => x, StringComparer.OrdinalIgnoreCase)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(g => g.Key)
|
||||
.ToList();
|
||||
if (duplicates.Count > 0)
|
||||
{
|
||||
throw new Fake.Application.BusinessException(
|
||||
$"同一产品下费用项不能重复:{string.Join("、", duplicates)}");
|
||||
}
|
||||
}
|
||||
|
||||
private static string? NormalizeAdditionalServices(string? raw)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
|
||||
@ -159,6 +159,7 @@ public partial class SalesProductService : ApplicationService
|
||||
{
|
||||
await GetProductOrThrowAsync(input.SalesProductId);
|
||||
ValidateBillingPriceItemRules([input]);
|
||||
await EnsureCostItemUniqueAsync(input.SalesProductId, input.CostItem, excludePriceId: null);
|
||||
await SalesProductRepository.InsertPriceAsync(
|
||||
new SalesProductPrice
|
||||
{
|
||||
@ -190,6 +191,7 @@ public partial class SalesProductService : ApplicationService
|
||||
}
|
||||
|
||||
ValidateBillingPriceItemRules([input]);
|
||||
await EnsureCostItemUniqueAsync(input.SalesProductId, input.CostItem, excludePriceId: price.Id);
|
||||
price.SerialNumber = input.SerialNumber;
|
||||
price.Status = input.Status;
|
||||
price.PriceName = input.PriceName;
|
||||
|
||||
@ -329,10 +329,11 @@ public partial class ServiceChannelService
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 买价偏远费等附加费用项的计费条件校验。
|
||||
/// 买价偏远费等附加费用项的计费条件校验;同一提交批次内费用项不可重复。
|
||||
/// </summary>
|
||||
private static void ValidateBillingPriceItemRules(IReadOnlyList<ServiceChannelPriceSaveInput> prices)
|
||||
{
|
||||
EnsureUniqueCostItemsInBatch(prices.Select(x => x.CostItem));
|
||||
foreach (var price in prices)
|
||||
{
|
||||
var costItem = price.CostItem?.Trim() ?? string.Empty;
|
||||
@ -349,6 +350,44 @@ public partial class ServiceChannelService
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同一服务渠道下每种费用项只能有一条买价配置。
|
||||
/// </summary>
|
||||
private async Task EnsureCostItemUniqueAsync(int serviceChannelId, string? costItem, int? excludePriceId)
|
||||
{
|
||||
var trimmed = costItem?.Trim() ?? string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(trimmed))
|
||||
{
|
||||
throw new Fake.Application.BusinessException("费用项不能为空");
|
||||
}
|
||||
|
||||
var existing = await ServiceChannelRepository.GetPricesAsync(serviceChannelId);
|
||||
var duplicated = existing.Any(p =>
|
||||
(!excludePriceId.HasValue || p.Id != excludePriceId.Value)
|
||||
&& string.Equals(p.CostItem?.Trim(), trimmed, StringComparison.OrdinalIgnoreCase));
|
||||
if (duplicated)
|
||||
{
|
||||
throw new Fake.Application.BusinessException(
|
||||
$"该渠道已存在费用项「{trimmed}」,同一渠道下每种费用项只能有一条");
|
||||
}
|
||||
}
|
||||
|
||||
private static void EnsureUniqueCostItemsInBatch(IEnumerable<string?> costItems)
|
||||
{
|
||||
var duplicates = costItems
|
||||
.Select(x => x?.Trim() ?? string.Empty)
|
||||
.Where(x => !string.IsNullOrWhiteSpace(x))
|
||||
.GroupBy(x => x, StringComparer.OrdinalIgnoreCase)
|
||||
.Where(g => g.Count() > 1)
|
||||
.Select(g => g.Key)
|
||||
.ToList();
|
||||
if (duplicates.Count > 0)
|
||||
{
|
||||
throw new Fake.Application.BusinessException(
|
||||
$"同一渠道下费用项不能重复:{string.Join("、", duplicates)}");
|
||||
}
|
||||
}
|
||||
|
||||
private static ServiceChannelGroupListOutput MapGroupListOutput(ServiceChannelGroup entity)
|
||||
{
|
||||
return new ServiceChannelGroupListOutput
|
||||
|
||||
@ -223,6 +223,7 @@ public partial class ServiceChannelService : ApplicationService
|
||||
{
|
||||
await GetEntityOrThrowAsync(input.ServiceChannelId);
|
||||
ValidateBillingPriceItemRules([input]);
|
||||
await EnsureCostItemUniqueAsync(input.ServiceChannelId, input.CostItem, excludePriceId: null);
|
||||
await ServiceChannelRepository.InsertPriceAsync(
|
||||
new ServiceChannelPrice
|
||||
{
|
||||
@ -254,6 +255,7 @@ public partial class ServiceChannelService : ApplicationService
|
||||
}
|
||||
|
||||
ValidateBillingPriceItemRules([input]);
|
||||
await EnsureCostItemUniqueAsync(input.ServiceChannelId, input.CostItem, excludePriceId: price.Id);
|
||||
price.SerialNumber = input.SerialNumber;
|
||||
price.Status = input.Status;
|
||||
price.PriceName = input.PriceName;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user