diff --git a/db.sql b/db.sql index 485e33b..3f1111e 100644 --- a/db.sql +++ b/db.sql @@ -118,6 +118,7 @@ CREATE TABLE `t_order` ( `ProductCode` VARCHAR(128) NULL COMMENT '产品编码', `ChannelCode` VARCHAR(128) NULL COMMENT '渠道编码', `DownstreamSupplierCode` VARCHAR(64) NULL COMMENT '下游 API 服务商编码 supplierCode', + `DownstreamSupplierName` VARCHAR(128) NULL COMMENT '下游 API 服务商名称', `DownstreamAppKey` VARCHAR(128) NULL COMMENT '下游 itfx 应用 AppKey', `DownstreamAppId` INT NULL COMMENT '下游 itfx 应用 Id', `ChannelForecastCode` VARCHAR(128) NULL COMMENT '渠道预报编码 ForecastCode', diff --git a/sql/migrate_20261009_order_warehouse.sql b/sql/migrate_20261009_order_warehouse.sql new file mode 100644 index 0000000..c8c2b84 --- /dev/null +++ b/sql/migrate_20261009_order_warehouse.sql @@ -0,0 +1,105 @@ +-- ============================================================================= +-- migrate_20261009_order_warehouse.sql +-- 汇总: +-- 1) t_order.DownstreamSupplierName(下游服务商名称) +-- 2) t_order_operation_log(运单操作日志) +-- 3) t_warehouse_address.Sort / Remark(仓库地址排序与备注) +-- 可重复执行。 +-- ============================================================================= + +SET @db := DATABASE(); + +-- ----------------------------------------------------------------------------- +-- 1) 订单:下游服务商名称 +-- ----------------------------------------------------------------------------- +SET @exists := ( + SELECT COUNT(1) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db + AND TABLE_NAME = 't_order' + AND COLUMN_NAME = 'DownstreamSupplierName' +); +SET @sql := IF( + @exists = 0, + 'ALTER TABLE `t_order` ADD COLUMN `DownstreamSupplierName` VARCHAR(128) NULL COMMENT ''下游 API 服务商名称'' AFTER `DownstreamSupplierCode`', + 'SELECT ''t_order.DownstreamSupplierName already exists'' AS info' +); +PREPARE stmt FROM @sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +-- ----------------------------------------------------------------------------- +-- 2) 运单操作日志表 +-- ----------------------------------------------------------------------------- +SET @tbl := ( + SELECT COUNT(1) + FROM information_schema.TABLES + WHERE TABLE_SCHEMA = @db + AND TABLE_NAME = 't_order_operation_log' +); +SET @sql := IF( + @tbl = 0, + 'CREATE TABLE `t_order_operation_log` ( + `Id` INT NOT NULL AUTO_INCREMENT COMMENT ''主键'', + `OrderId` INT NOT NULL COMMENT ''运单Id'', + `ServiceNo` VARCHAR(64) NULL COMMENT ''运单号冗余'', + `Action` VARCHAR(32) NOT NULL COMMENT ''动作码 editBasic/editWeight/recalcReceivable/recalcPayable/reallocate'', + `ActionName` VARCHAR(64) NOT NULL COMMENT ''动作中文名'', + `OperatorId` INT NOT NULL DEFAULT 0 COMMENT ''操作人用户Id'', + `OperatorName` VARCHAR(64) NULL COMMENT ''操作人展示名'', + `OperatorType` VARCHAR(16) NOT NULL DEFAULT ''staff'' COMMENT ''staff/customer/system/openapi'', + `Source` VARCHAR(16) NOT NULL DEFAULT ''pc'' COMMENT ''pc/h5/openapi/job'', + `ChangesJson` JSON NULL COMMENT ''字段 diff 数组 [{path,label,before,after}]'', + `Remark` VARCHAR(512) NULL COMMENT ''补充说明'', + `IsDeleted` TINYINT NOT NULL DEFAULT 0 COMMENT ''软删除:0-否,1-是'', + `ConcurrencyStamp` CHAR(36) NOT NULL DEFAULT (UUID()) COMMENT ''并发戳'', + `CreateUserId` INT NOT NULL DEFAULT 0 COMMENT ''创建人'', + `CreateTime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ''创建时间'', + `UpdateUserId` INT NULL COMMENT ''更新人'', + `UpdateTime` DATETIME NULL COMMENT ''更新时间'', + PRIMARY KEY (`Id`), + KEY `idx_ool_order_time` (`OrderId`, `CreateTime`), + KEY `idx_ool_service_no` (`ServiceNo`) + ) COMMENT=''运单操作日志''', + 'SELECT ''t_order_operation_log already exists'' AS info' +); +PREPARE stmt FROM @sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +-- ----------------------------------------------------------------------------- +-- 3) 仓库地址:展示排序 + 备注 +-- ----------------------------------------------------------------------------- +SET @col := ( + SELECT COUNT(1) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db + AND TABLE_NAME = 't_warehouse_address' + AND COLUMN_NAME = 'Sort' +); +SET @sql := IF( + @col = 0, + 'ALTER TABLE `t_warehouse_address` + ADD COLUMN `Sort` INT NULL DEFAULT NULL COMMENT ''展示排序,越小越靠前'' AFTER `ShippingAddress`', + 'SELECT ''t_warehouse_address.Sort already exists'' AS info' +); +PREPARE stmt FROM @sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +SET @col := ( + SELECT COUNT(1) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db + AND TABLE_NAME = 't_warehouse_address' + AND COLUMN_NAME = 'Remark' +); +SET @sql := IF( + @col = 0, + 'ALTER TABLE `t_warehouse_address` + ADD COLUMN `Remark` VARCHAR(512) NULL DEFAULT NULL COMMENT ''备注'' AFTER `Sort`', + 'SELECT ''t_warehouse_address.Remark already exists'' AS info' +); +PREPARE stmt FROM @sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; diff --git a/sql/migrate_order_downstream_supplier_name.sql b/sql/migrate_order_downstream_supplier_name.sql new file mode 100644 index 0000000..f3ba5ad --- /dev/null +++ b/sql/migrate_order_downstream_supplier_name.sql @@ -0,0 +1,22 @@ +-- 订单增加下游服务商名称(排货确认时写入 itfx 服务商名 / 分组名)。 +-- 可重复执行。 + +SET @db := DATABASE(); + +SET @exists := ( + SELECT COUNT(1) + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db + AND TABLE_NAME = 't_order' + AND COLUMN_NAME = 'DownstreamSupplierName' +); + +SET @sql := IF( + @exists = 0, + 'ALTER TABLE `t_order` ADD COLUMN `DownstreamSupplierName` VARCHAR(128) NULL COMMENT ''下游 API 服务商名称'' AFTER `DownstreamSupplierCode`', + 'SELECT ''t_order.DownstreamSupplierName already exists'' AS info' +); + +PREPARE stmt FROM @sql; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; diff --git a/src/Oms.Application/Dtos/Orders/OrderBindSnapshotVersionsDtos.cs b/src/Oms.Application/Dtos/Orders/OrderBindSnapshotVersionsDtos.cs new file mode 100644 index 0000000..2abfce4 --- /dev/null +++ b/src/Oms.Application/Dtos/Orders/OrderBindSnapshotVersionsDtos.cs @@ -0,0 +1,34 @@ +using System.ComponentModel.DataAnnotations; + +namespace Oms.Application.Dtos.Orders; + +/// +/// 切换订单绑定的销售产品规则/价格发布版本。 +/// +public class OrderBindSnapshotVersionsInput +{ + [Required] + public int Id { get; set; } + + /// + /// 目标规则版本;空表示不改。特殊值 CURRENT 表示绑定当前有效规则发布。 + /// + [StringLength(64)] + public string? RulesVersion { get; set; } + + /// + /// 目标价格版本;空表示不改。特殊值 CURRENT 表示绑定当前有效价格发布。 + /// + [StringLength(64)] + public string? PriceVersion { get; set; } + + /// + /// 绑定后是否立即重算应收(已支付会拒绝)。 + /// + public bool RecalculateReceivable { get; set; } + + /// + /// 绑定后是否立即重算应付(锁定当前渠道)。 + /// + public bool RecalculatePayable { get; set; } +} diff --git a/src/Oms.Application/Dtos/Orders/OrderOutput.cs b/src/Oms.Application/Dtos/Orders/OrderOutput.cs index a82aea9..4eaed1f 100644 --- a/src/Oms.Application/Dtos/Orders/OrderOutput.cs +++ b/src/Oms.Application/Dtos/Orders/OrderOutput.cs @@ -55,6 +55,11 @@ public class OrderOutput /// public string? DownstreamSupplierCode { get; set; } + /// + /// 下游 API 服务商名称。 + /// + public string? DownstreamSupplierName { get; set; } + /// /// 下游 itfx 应用 AppKey。 /// @@ -363,6 +368,16 @@ public class OrderOutput /// public decimal? ForecastPayableAmount { get; set; } + /// + /// 订单绑定的销售产品规则发布版本。 + /// + public string? SalesProductRulesVersion { get; set; } + + /// + /// 订单绑定的销售产品价格发布版本。 + /// + public string? SalesProductPriceVersion { get; set; } + /// /// 创建时间。 /// diff --git a/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs b/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs index 8a3d31c..527471a 100644 --- a/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs +++ b/src/Oms.Application/Services/Orders/OrderOperationLogSnapshot.cs @@ -28,6 +28,8 @@ public static class OrderOperationLogSnapshot ["payableAmount"] = "应付金额", ["downstreamServiceNo"] = "服务商单号", ["allocationScheme"] = "排货方案", + ["salesProductRulesVersion"] = "规则版本", + ["salesProductPriceVersion"] = "价格版本", ["isPaid"] = "是否已支付", ["sender.name"] = "发件人姓名", ["sender.phone"] = "发件人电话", @@ -70,6 +72,8 @@ public static class OrderOperationLogSnapshot ["payableAmount"] = FormatDecimal(order.PayableAmount), ["downstreamServiceNo"] = Norm(order.DownstreamServiceNo), ["allocationScheme"] = Norm(order.AllocationScheme), + ["salesProductRulesVersion"] = Norm(order.SalesProductRulesVersion), + ["salesProductPriceVersion"] = Norm(order.SalesProductPriceVersion), ["isPaid"] = FormatByte(order.IsPaid), }; } diff --git a/src/Oms.Application/Services/Orders/OrderService.Helpers.cs b/src/Oms.Application/Services/Orders/OrderService.Helpers.cs index c5d6e34..40f81fa 100644 --- a/src/Oms.Application/Services/Orders/OrderService.Helpers.cs +++ b/src/Oms.Application/Services/Orders/OrderService.Helpers.cs @@ -165,6 +165,7 @@ public partial class OrderService MaxTimeliness = product?.MaxTimeliness, ChannelCode = order.ChannelCode, DownstreamSupplierCode = order.DownstreamSupplierCode, + DownstreamSupplierName = order.DownstreamSupplierName, DownstreamAppKey = order.DownstreamAppKey, DownstreamAppId = order.DownstreamAppId, ChannelForecastCode = order.ChannelForecastCode, @@ -262,6 +263,12 @@ public partial class OrderService HasInsurance = hasInsurance, ForecastReceivableAmount = order.ForecastReceivableAmount, ForecastPayableAmount = order.ForecastPayableAmount, + SalesProductRulesVersion = string.IsNullOrWhiteSpace(order.SalesProductRulesVersion) + ? null + : order.SalesProductRulesVersion.Trim(), + SalesProductPriceVersion = string.IsNullOrWhiteSpace(order.SalesProductPriceVersion) + ? null + : order.SalesProductPriceVersion.Trim(), CreateTime = order.CreateTime, CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(order.CreateUserId, auditUserNameMap), UpdateTime = OmsDocHelper.NullIfDefault(order.UpdateTime), @@ -387,6 +394,7 @@ public partial class OrderService output.ChannelCode = null; output.ChannelName = null; output.DownstreamSupplierCode = null; + output.DownstreamSupplierName = null; output.DownstreamAppKey = null; output.DownstreamAppId = null; output.ChannelForecastCode = null; diff --git a/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs b/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs index b0e9653..9049e59 100644 --- a/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs +++ b/src/Oms.Application/Services/Orders/OrderService.OrderEdit.cs @@ -286,6 +286,127 @@ public partial class OrderService return (await MapOrderOutputsAsync([order])).First(); } + /// + /// 切换订单绑定的销售产品规则/价格发布版本(显式改契约后再重算)。 + /// + [HttpPost("/order/fee/bind-snapshot-versions")] + public async Task BindSnapshotVersionsAsync([FromBody] OrderBindSnapshotVersionsInput input) + { + var order = await GetOrderOrThrowAsync(input.Id); + var beforeSnap = await CaptureOrderAuditSnapshotAsync(order, includeFees: true); + + if (string.IsNullOrWhiteSpace(order.ProductCode)) + { + throw new BusinessException("订单未绑定销售产品,无法切换版本"); + } + + var product = await SalesProductRepository.GetByProductCodeAsync(order.ProductCode.Trim()); + if (product == null) + { + throw new BusinessException("销售产品不存在"); + } + + var wantRules = !string.IsNullOrWhiteSpace(input.RulesVersion); + var wantPrice = !string.IsNullOrWhiteSpace(input.PriceVersion); + if (!wantRules && !wantPrice) + { + throw new BusinessException("请至少指定规则版本或价格版本"); + } + + var remarkParts = new List(); + if (wantRules) + { + var resolved = await ResolveBindTargetVersionAsync( + product, + RulesOperatorType, + input.RulesVersion!.Trim(), + "规则"); + if (!string.Equals(order.SalesProductRulesVersion, resolved, StringComparison.Ordinal)) + { + remarkParts.Add($"rules:{order.SalesProductRulesVersion ?? "-"}→{resolved}"); + order.SalesProductRulesVersion = resolved; + } + } + + if (wantPrice) + { + var resolved = await ResolveBindTargetVersionAsync( + product, + PriceOperatorType, + input.PriceVersion!.Trim(), + "价格"); + if (!string.Equals(order.SalesProductPriceVersion, resolved, StringComparison.Ordinal)) + { + remarkParts.Add($"price:{order.SalesProductPriceVersion ?? "-"}→{resolved}"); + order.SalesProductPriceVersion = resolved; + } + } + + if (remarkParts.Count == 0 && !input.RecalculateReceivable && !input.RecalculatePayable) + { + throw new BusinessException("目标版本与当前绑定相同,且未勾选重算"); + } + + order.UpdateTime = DateTime.Now; + await OrderRepository.UpdateAsync(order); + + if (input.RecalculateReceivable) + { + EnsureReceivableMutable(order); + await RecalculateReceivableCoreAsync(order); + } + + if (input.RecalculatePayable) + { + await RecalculatePayableCoreAsync(order); + } + + order = await GetOrderOrThrowAsync(order.Id); + var afterSnap = await CaptureOrderAuditSnapshotAsync(order, includeFees: true); + await OperationLogWriter.TryWriteAsync( + order, + OrderOperationActionCodes.BindSnapshotVersions, + beforeSnap, + afterSnap, + remarkParts.Count == 0 ? null : string.Join(';', remarkParts)); + return (await MapOrderOutputsAsync([order])).First(); + } + + /// + /// 解析绑定目标版本:CURRENT 取当前有效发布,否则按版本号校验存在。 + /// + private async Task ResolveBindTargetVersionAsync( + SalesProduct product, + string operatorType, + string versionOrCurrent, + string label) + { + if (string.Equals(versionOrCurrent, "CURRENT", StringComparison.OrdinalIgnoreCase)) + { + var effective = await SalesProductRepository.GetEffectivePublishRecordAsync( + product.Id, + operatorType, + DateTime.Now); + if (effective == null || string.IsNullOrWhiteSpace(effective.Version)) + { + throw new BusinessException($"未命中当前有效{label}发布版本"); + } + + return effective.Version.Trim(); + } + + var record = await SalesProductRepository.GetPublishRecordByVersionAsync( + product.Id, + operatorType, + versionOrCurrent); + if (record == null || string.IsNullOrWhiteSpace(record.Version)) + { + throw new BusinessException($"未找到{label}发布版本:{versionOrCurrent}"); + } + + return record.Version.Trim(); + } + /// /// 重跑入库计费(应收 wipe+upsert + 排货应付)。用于队列投递失败或待排货补救。 /// @@ -1010,6 +1131,7 @@ public partial class OrderService // 重新排货:产品规则/分区与渠道买价均取当前有效发布,避免沿用下单时旧快照。 // 对账重算 / 普通重算应付:沿用订单快照绑定(分区等),买价仍由排货评估取当前有效发布。 + // 锁渠道重算应付:允许渠道不在旧规则排货池内(渠道已确认,只重算买价)。 var snapshotBinding = enforceReallocateGate ? await ResolveSnapshotBindingAsync(product, DateTime.Now) : await ResolveSnapshotBindingFromOrderAsync(product, order); @@ -1032,7 +1154,14 @@ public partial class OrderService billing, chargingStage, schemeOverride, - forceChannelId); + forceChannelId, + allowDesignatedOutsidePool: lockCurrentChannel); + + // 重新排货成功后写回规则版本,使后续重算应付与当前排货池一致;卖价版本保持契约,不随排货改写。 + if (enforceReallocateGate) + { + order.SalesProductRulesVersion = snapshotBinding.RulesVersion; + } if (string.Equals(order.OrderStatus, OrderStatusCodes.PendingAllocation, StringComparison.OrdinalIgnoreCase)) { diff --git a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs index 2fd317d..8f7bc82 100644 --- a/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs +++ b/src/Oms.Application/Services/Orders/OrderService.ParcelBilling.cs @@ -848,7 +848,8 @@ public partial class OrderService string chargingStage, string? _, string? schemeOverride = null, - int? forceServiceChannelId = null) + int? forceServiceChannelId = null, + bool allowDesignatedOutsidePool = false) { var evaluation = await EvaluateAllocationAsync( order, @@ -858,7 +859,8 @@ public partial class OrderService chargeableWeight, chargingStage, schemeOverride, - forceServiceChannelId); + forceServiceChannelId, + allowDesignatedOutsidePool); ApplyAllocationTraceToOrder(order, evaluation); @@ -928,7 +930,8 @@ public partial class OrderService decimal chargeableWeight, string chargingStage, string? schemeOverride, - int? forceServiceChannelId) + int? forceServiceChannelId, + bool allowDesignatedOutsidePool = false) { var warehouseName = await ResolveWarehouseNameAsync(order.WarehouseId); var providers = await ResolveAllocationProvidersAsync(product, snapshotBinding.Rules); @@ -985,27 +988,61 @@ public partial class OrderService if (designated.Count == 0) { var poolRow = providers.FirstOrDefault(x => x.ServiceChannelId == forceServiceChannelId.Value); - var failReason = poolRow == null - ? "指定渠道不在该销售产品排货池" - : "指定渠道不满足判断条件"; - if (poolRow != null - && skipped.All(x => x.ServiceChannelId != forceServiceChannelId.Value)) + // 重算应付锁定已确认渠道:渠道已在单上,不再用旧规则排货池/判断条件拦截,只重算买价。 + if (allowDesignatedOutsidePool) { - skipped.Add(new OrderAllocationSkippedOutput + var lockedChannel = await ServiceChannelRepository.FirstOrDefaultAsync(x => + x.Id == forceServiceChannelId.Value); + if (lockedChannel == null) { - ServiceChannelId = forceServiceChannelId.Value, - ChannelCode = poolRow.ChannelCode, - ChannelName = poolRow.ServiceChannelName ?? poolRow.ProviderName, - Stage = AllocationResolver.SkipStageCondition, - MatchCondition = AllocationResolver.TruncateMatchCondition(poolRow.MatchCondition), - Reason = failReason - }); + return BaseEval("订单服务渠道不存在,无法重算应付"); + } + + var lockedProvider = poolRow ?? new SalesProductAllocationProviderSnapshotDto + { + SalesProductId = product.Id, + ServiceChannelId = lockedChannel.Id, + ServiceChannelName = lockedChannel.ChannelName, + ProviderName = lockedChannel.ChannelName ?? lockedChannel.ChannelCode, + ChannelCode = lockedChannel.ChannelCode, + Weight = 0, + CustomerIds = [], + MatchCondition = null + }; + if (poolRow == null + || AllocationProviderSnapshotEnricher.NeedsDownstreamEnrichment(lockedProvider)) + { + await AllocationProviderSnapshotEnricher.EnrichAsync([lockedProvider]); + } + + filtered = [lockedProvider]; } + else + { + var failReason = poolRow == null + ? "指定渠道不在该销售产品排货池" + : "指定渠道不满足判断条件"; + if (poolRow != null + && skipped.All(x => x.ServiceChannelId != forceServiceChannelId.Value)) + { + skipped.Add(new OrderAllocationSkippedOutput + { + ServiceChannelId = forceServiceChannelId.Value, + ChannelCode = poolRow.ChannelCode, + ChannelName = poolRow.ServiceChannelName ?? poolRow.ProviderName, + Stage = AllocationResolver.SkipStageCondition, + MatchCondition = AllocationResolver.TruncateMatchCondition(poolRow.MatchCondition), + Reason = failReason + }); + } - return BaseEval(failReason); + return BaseEval(failReason); + } + } + else + { + filtered = designated; } - - filtered = designated; } if (filtered.Count == 0) @@ -1304,7 +1341,8 @@ public partial class OrderService OrderBillingContext billing, string chargingStage, string? schemeOverride = null, - int? forceServiceChannelId = null) => + int? forceServiceChannelId = null, + bool allowDesignatedOutsidePool = false) => ConfirmServiceChannelAndPayableAsync( order, product, @@ -1314,7 +1352,8 @@ public partial class OrderService chargingStage, billing.PriceTierKey, schemeOverride, - forceServiceChannelId); + forceServiceChannelId, + allowDesignatedOutsidePool); /// /// 尝试排货并写入应付;失败时不抛异常,写入 供运营补配置。 @@ -1325,7 +1364,8 @@ public partial class OrderService OrderBillingContext billing, string chargingStage, string? schemeOverride = null, - int? forceServiceChannelId = null) + int? forceServiceChannelId = null, + bool allowDesignatedOutsidePool = false) { try { @@ -1335,7 +1375,8 @@ public partial class OrderService billing, chargingStage, schemeOverride, - forceServiceChannelId); + forceServiceChannelId, + allowDesignatedOutsidePool); return true; } catch (BusinessException ex) diff --git a/src/Oms.Application/Shared/AllocationProviderSnapshotEnricher.cs b/src/Oms.Application/Shared/AllocationProviderSnapshotEnricher.cs index afb1ef4..4073363 100644 --- a/src/Oms.Application/Shared/AllocationProviderSnapshotEnricher.cs +++ b/src/Oms.Application/Shared/AllocationProviderSnapshotEnricher.cs @@ -108,6 +108,9 @@ public class AllocationProviderSnapshotEnricher( ServiceChannel? channelFallback = null) { order.DownstreamSupplierCode = NullIfEmpty(provider.SupplierCode); + order.DownstreamSupplierName = NullIfEmpty(provider.ApiServiceProviderName) + ?? NullIfEmpty(provider.GroupName) + ?? NullIfEmpty(provider.ProviderName); order.DownstreamAppKey = NullIfEmpty(provider.AppKey); order.DownstreamAppId = provider.AppId; order.ChannelForecastCode = NullIfEmpty(provider.ForecastCode) diff --git a/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs b/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs index 866ac0d..17d6f8b 100644 --- a/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs +++ b/src/Oms.Domain/OrdersAggregate/Consts/OrderOperationActionCodes.cs @@ -7,6 +7,7 @@ public static class OrderOperationActionCodes public const string RecalcReceivable = "recalcReceivable"; public const string RecalcPayable = "recalcPayable"; public const string Reallocate = "reallocate"; + public const string BindSnapshotVersions = "bindSnapshotVersions"; public static string GetActionName(string action) => action switch { @@ -15,6 +16,7 @@ public static class OrderOperationActionCodes RecalcReceivable => "重算应收", RecalcPayable => "重算应付", Reallocate => "重新排货", + BindSnapshotVersions => "切换价格/规则版本", _ => action }; } diff --git a/src/Oms.Domain/OrdersAggregate/Entities/Order.cs b/src/Oms.Domain/OrdersAggregate/Entities/Order.cs index 3aea651..2f2b77e 100644 --- a/src/Oms.Domain/OrdersAggregate/Entities/Order.cs +++ b/src/Oms.Domain/OrdersAggregate/Entities/Order.cs @@ -29,6 +29,12 @@ public class Order : OmsAuditedAggregateRoot /// public string? DownstreamSupplierCode { get; set; } + /// + /// 下游 API 服务商名称(itfx service provider name)。 + /// + [SugarColumn(Length = 128, IsNullable = true)] + public string? DownstreamSupplierName { get; set; } + /// /// 下游 itfx 应用 AppKey。 ///