feat: 店铺创建运单支持基本信息覆盖,无事务时同步执行创单副作用
All checks were successful
Build and Deploy / deploy (push) Successful in 1m0s
All checks were successful
Build and Deploy / deploy (push) Successful in 1m0s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
264c3a5dcb
commit
7ed8fd8e8a
@ -364,6 +364,60 @@ public class PlatformStoreOrderMatchInventoryOutput
|
|||||||
public string? ClientNo { get; set; }
|
public string? ClientNo { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 店铺订单创建运单时填写的运单基本信息(对齐下单页基本信息)。
|
||||||
|
/// </summary>
|
||||||
|
public class PlatformStoreOrderParcelBasicInput
|
||||||
|
{
|
||||||
|
/// <summary>客户单号;空则沿用平台订单号。</summary>
|
||||||
|
public string? ClientNo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>货物属性:general / electronics / sensitive。</summary>
|
||||||
|
public string? CargoAttribute { get; set; }
|
||||||
|
|
||||||
|
/// <summary>实重(kg)。</summary>
|
||||||
|
public decimal? ActualWeight { get; set; }
|
||||||
|
|
||||||
|
/// <summary>包裹数量。</summary>
|
||||||
|
public int? Quantity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>长(cm)。</summary>
|
||||||
|
public decimal? Length { get; set; }
|
||||||
|
|
||||||
|
/// <summary>宽(cm)。</summary>
|
||||||
|
public decimal? Width { get; set; }
|
||||||
|
|
||||||
|
/// <summary>高(cm)。</summary>
|
||||||
|
public decimal? Height { get; set; }
|
||||||
|
|
||||||
|
/// <summary>出口报关方式。</summary>
|
||||||
|
public string? ExportCustomsMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>出口资质备案 Id(9610Summary 时必填)。</summary>
|
||||||
|
public int? ExportQualificationId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>电商平台编码(9610Summary 时必填)。</summary>
|
||||||
|
public string? PlatformCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>到仓方式:selfShip / doorPickup。</summary>
|
||||||
|
public string? InboundMethod { get; set; }
|
||||||
|
|
||||||
|
/// <summary>上门揽收发件地址簿 Id。</summary>
|
||||||
|
public int? SenderAddressId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>期望揽收时间。</summary>
|
||||||
|
public DateTime? ExpectPickupTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>揽收方向。</summary>
|
||||||
|
public string? PickupDirection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>承运商编码。</summary>
|
||||||
|
public string? CarrierCode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>承运服务。</summary>
|
||||||
|
public string? CarrierService { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class PlatformStoreOrderBatchCreateLogisticsInput
|
public class PlatformStoreOrderBatchCreateLogisticsInput
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
@ -373,6 +427,9 @@ public class PlatformStoreOrderBatchCreateLogisticsInput
|
|||||||
|
|
||||||
public int? CustomerId { get; set; }
|
public int? CustomerId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>运单基本信息(创建运单/代发运单必填)。</summary>
|
||||||
|
public PlatformStoreOrderParcelBasicInput? ParcelBasic { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public List<PlatformStoreOrderBatchCreateItemInput> Items { get; set; } = [];
|
public List<PlatformStoreOrderBatchCreateItemInput> Items { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -387,6 +444,9 @@ public class PlatformStoreOrderBatchCreateFulfillInput
|
|||||||
|
|
||||||
public int? CustomerId { get; set; }
|
public int? CustomerId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>运单基本信息(创建运单/代发运单必填)。</summary>
|
||||||
|
public PlatformStoreOrderParcelBasicInput? ParcelBasic { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public List<PlatformStoreOrderBatchCreateItemInput> Items { get; set; } = [];
|
public List<PlatformStoreOrderBatchCreateItemInput> Items { get; set; } = [];
|
||||||
}
|
}
|
||||||
@ -396,6 +456,9 @@ public class PlatformStoreOrderBatchCreateItemInput
|
|||||||
[Required]
|
[Required]
|
||||||
public int StoreOrderId { get; set; }
|
public int StoreOrderId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>覆盖本单客户单号;空则用 ParcelBasic.ClientNo 或平台订单号。</summary>
|
||||||
|
public string? ClientNo { get; set; }
|
||||||
|
|
||||||
public OrderParcelReceiverInput? Receiver { get; set; }
|
public OrderParcelReceiverInput? Receiver { get; set; }
|
||||||
|
|
||||||
public List<OrderStockBindSaveItemInput> BindItems { get; set; } = [];
|
public List<OrderStockBindSaveItemInput> BindItems { get; set; } = [];
|
||||||
|
|||||||
@ -174,11 +174,11 @@ public partial class OrderService
|
|||||||
// 4. 保存草稿:不做预报计费。9610、上门揽收与订单一起提交。
|
// 4. 保存草稿:不做预报计费。9610、上门揽收与订单一起提交。
|
||||||
if (input.SaveAsDraft)
|
if (input.SaveAsDraft)
|
||||||
{
|
{
|
||||||
await EventBus.PublishAsync(new OrderParcelCustoms9610UpsertIntegrationEvent
|
await RunParcelCreateSideEffectsAsync(
|
||||||
{
|
order,
|
||||||
OrderId = order.Id,
|
input,
|
||||||
PlatformCode = input.PlatformCode
|
operatorId,
|
||||||
});
|
includeForecastAndLabel: false);
|
||||||
var draftOutput = await BuildParcelCreateOutputAsync(order);
|
var draftOutput = await BuildParcelCreateOutputAsync(order);
|
||||||
await TryAttachPickupAfterParcelCreateAsync(input, draftOutput);
|
await TryAttachPickupAfterParcelCreateAsync(input, draftOutput);
|
||||||
return draftOutput;
|
return draftOutput;
|
||||||
@ -199,21 +199,13 @@ public partial class OrderService
|
|||||||
order.UpdateTime = DateTime.Now;
|
order.UpdateTime = DateTime.Now;
|
||||||
await OrderRepository.UpdateAsync(order);
|
await OrderRepository.UpdateAsync(order);
|
||||||
|
|
||||||
// 6. 与订单同一事务写入 Outbox。Commit 后由 Fake 投递;任一条失败则整单回滚。
|
// 6. 有事务 UoW 时写 Outbox;无事务(店铺订单创建运单等)则同步执行,避免 Outbox 拒发。
|
||||||
// 轨迹不在此列:要等预报消费端排货拿到 ChannelCode 再发。
|
// 轨迹不在此列:要等预报消费端排货拿到 ChannelCode 再发。
|
||||||
var authorization = CaptureRequestAuthorization();
|
await RunParcelCreateSideEffectsAsync(
|
||||||
await EventBus.PublishAsync(new OrderParcelCustoms9610UpsertIntegrationEvent
|
order,
|
||||||
{
|
input,
|
||||||
OrderId = order.Id,
|
operatorId,
|
||||||
PlatformCode = input.PlatformCode
|
includeForecastAndLabel: true);
|
||||||
});
|
|
||||||
await EnqueueForecastBillingAsync(order, input.CouponInstanceId, operatorId, authorization);
|
|
||||||
await EventBus.PublishAsync(new OrderParcelLabelGenerateIntegrationEvent
|
|
||||||
{
|
|
||||||
OrderId = order.Id,
|
|
||||||
OperatorUserId = operatorId
|
|
||||||
});
|
|
||||||
await AutoTriggerRuntimeService.EnqueueFireAsync(order.Id, AutoTriggerTiming.OrderCreate, operatorId);
|
|
||||||
|
|
||||||
var output = await BuildParcelCreateOutputAsync(order);
|
var output = await BuildParcelCreateOutputAsync(order);
|
||||||
output.ForecastBillingQueued = string.Equals(
|
output.ForecastBillingQueued = string.Equals(
|
||||||
@ -225,6 +217,87 @@ public partial class OrderService
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创单后置:9610 / 预报计费 / 面单 / 自动触发。
|
||||||
|
/// 环境有事务 UoW 时走 Outbox;否则同步执行(店铺订单创建运单无 [UnitOfWork])。
|
||||||
|
/// </summary>
|
||||||
|
private async Task RunParcelCreateSideEffectsAsync(
|
||||||
|
Order order,
|
||||||
|
OrderParcelCreateInput input,
|
||||||
|
int operatorId,
|
||||||
|
bool includeForecastAndLabel)
|
||||||
|
{
|
||||||
|
var uowManager = LazyServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
||||||
|
var useOutbox = OmsOutboxUnitOfWork.IsAmbientTransactional(uowManager);
|
||||||
|
var authorization = CaptureRequestAuthorization();
|
||||||
|
|
||||||
|
if (useOutbox)
|
||||||
|
{
|
||||||
|
await EventBus.PublishAsync(new OrderParcelCustoms9610UpsertIntegrationEvent
|
||||||
|
{
|
||||||
|
OrderId = order.Id,
|
||||||
|
PlatformCode = input.PlatformCode
|
||||||
|
});
|
||||||
|
if (includeForecastAndLabel)
|
||||||
|
{
|
||||||
|
await EnqueueForecastBillingAsync(order, input.CouponInstanceId, operatorId, authorization);
|
||||||
|
await EventBus.PublishAsync(new OrderParcelLabelGenerateIntegrationEvent
|
||||||
|
{
|
||||||
|
OrderId = order.Id,
|
||||||
|
OperatorUserId = operatorId
|
||||||
|
});
|
||||||
|
await AutoTriggerRuntimeService.EnqueueFireAsync(
|
||||||
|
order.Id,
|
||||||
|
AutoTriggerTiming.OrderCreate,
|
||||||
|
operatorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await TryUpsertCustoms9610Async(order, input.PlatformCode);
|
||||||
|
if (!includeForecastAndLabel)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var payloadJson = JsonConvert.SerializeObject(new ForecastBillingJobPayload
|
||||||
|
{
|
||||||
|
CouponInstanceId = input.CouponInstanceId,
|
||||||
|
Authorization = authorization
|
||||||
|
});
|
||||||
|
await ProcessForecastBillingForBatchAsync(
|
||||||
|
order.Id,
|
||||||
|
payloadJson,
|
||||||
|
operatorId,
|
||||||
|
authorization: authorization);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var labelResult = await GenerateLabelPdfForBatchAsync(order.Id);
|
||||||
|
if (!labelResult.Success)
|
||||||
|
{
|
||||||
|
LazyServiceProvider.GetRequiredService<ILoggerFactory>()
|
||||||
|
.CreateLogger("Oms.ParcelCreate")
|
||||||
|
.LogWarning(
|
||||||
|
"Label generate failed OrderId={OrderId} Error={Error}",
|
||||||
|
order.Id,
|
||||||
|
labelResult.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LazyServiceProvider.GetRequiredService<ILoggerFactory>()
|
||||||
|
.CreateLogger("Oms.ParcelCreate")
|
||||||
|
.LogWarning(ex, "Label generate failed OrderId={OrderId}", order.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
await AutoTriggerRuntimeService.FireByOrderIdAsync(
|
||||||
|
order.Id,
|
||||||
|
AutoTriggerTiming.OrderCreate,
|
||||||
|
operatorId);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task TryUpsertCustoms9610Async(Order order, string? platformCode = null)
|
private async Task TryUpsertCustoms9610Async(Order order, string? platformCode = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@ -14,6 +14,7 @@ using Oms.Application.Labeling;
|
|||||||
using Oms.Application.Shared;
|
using Oms.Application.Shared;
|
||||||
using Oms.Application.Storage;
|
using Oms.Application.Storage;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using Oms.Application.Messaging;
|
||||||
using Oms.Application.Messaging.ParcelCreate;
|
using Oms.Application.Messaging.ParcelCreate;
|
||||||
using Oms.Application.Services.Orders.Batch;
|
using Oms.Application.Services.Orders.Batch;
|
||||||
using Oms.Domain.ChannelsAggregate.Repositories;
|
using Oms.Domain.ChannelsAggregate.Repositories;
|
||||||
@ -722,16 +723,37 @@ public partial class OrderService : ApplicationService
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await EventBus.PublishAsync(new OrderParcelPickupAttachIntegrationEvent
|
var uowManager = LazyServiceProvider.GetRequiredService<IUnitOfWorkManager>();
|
||||||
|
if (OmsOutboxUnitOfWork.IsAmbientTransactional(uowManager))
|
||||||
|
{
|
||||||
|
await EventBus.PublishAsync(new OrderParcelPickupAttachIntegrationEvent
|
||||||
|
{
|
||||||
|
OrderId = output.OrderId,
|
||||||
|
CustomerId = input.CustomerId,
|
||||||
|
SenderAddressId = input.SenderAddressId.Value,
|
||||||
|
WarehouseId = input.WarehouseId.Value,
|
||||||
|
PickupDirection = input.PickupDirection,
|
||||||
|
CarrierCode = input.CarrierCode,
|
||||||
|
CarrierService = input.CarrierService,
|
||||||
|
ExpectPickupTime = input.ExpectPickupTime.Value
|
||||||
|
});
|
||||||
|
output.PickupQueued = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 无事务 UoW(店铺订单创建运单)时同步挂接揽收,避免 Outbox 拒发
|
||||||
|
var pickupService = LazyServiceProvider.GetRequiredService<PickupOrderService>();
|
||||||
|
await pickupService.CreateForParcelInternalAsync(new PickupOrderCreateInput
|
||||||
{
|
{
|
||||||
OrderId = output.OrderId,
|
|
||||||
CustomerId = input.CustomerId,
|
CustomerId = input.CustomerId,
|
||||||
SenderAddressId = input.SenderAddressId.Value,
|
SenderAddressId = input.SenderAddressId.Value,
|
||||||
|
Direction = PickupDirectionCodes.NormalizeOrDefault(input.PickupDirection),
|
||||||
WarehouseId = input.WarehouseId.Value,
|
WarehouseId = input.WarehouseId.Value,
|
||||||
PickupDirection = input.PickupDirection,
|
|
||||||
CarrierCode = input.CarrierCode,
|
CarrierCode = input.CarrierCode,
|
||||||
CarrierService = input.CarrierService,
|
CarrierService = input.CarrierService,
|
||||||
ExpectPickupTime = input.ExpectPickupTime.Value
|
ExpectPickupTime = input.ExpectPickupTime.Value,
|
||||||
|
OrderIds = [output.OrderId],
|
||||||
|
Remark = null
|
||||||
});
|
});
|
||||||
output.PickupQueued = true;
|
output.PickupQueued = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ using System.Text.Json;
|
|||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using Fake.Application;
|
using Fake.Application;
|
||||||
using Oms.Application.Dtos.Orders;
|
using Oms.Application.Dtos.Orders;
|
||||||
|
using Oms.Application.Dtos.PlatformStore;
|
||||||
using Oms.Domain.OrdersAggregate.Consts;
|
using Oms.Domain.OrdersAggregate.Consts;
|
||||||
using Oms.Domain.OrdersAggregate.Entities;
|
using Oms.Domain.OrdersAggregate.Entities;
|
||||||
using Oms.Domain.SystemAggregate.Entities;
|
using Oms.Domain.SystemAggregate.Entities;
|
||||||
@ -59,6 +60,105 @@ public static class PlatformStoreOrderParcelBuilder
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将下单页同款「运单基本信息」覆盖到组装好的小包入参。
|
||||||
|
/// </summary>
|
||||||
|
public static void ApplyParcelBasic(
|
||||||
|
OrderParcelCreateInput parcelInput,
|
||||||
|
PlatformStoreOrderParcelBasicInput? basic,
|
||||||
|
string? clientNoOverride = null)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(clientNoOverride))
|
||||||
|
{
|
||||||
|
parcelInput.ClientNo = clientNoOverride.Trim();
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrWhiteSpace(basic?.ClientNo))
|
||||||
|
{
|
||||||
|
parcelInput.ClientNo = basic.ClientNo.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.CargoAttribute))
|
||||||
|
{
|
||||||
|
parcelInput.CargoAttribute = basic.CargoAttribute.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.ActualWeight is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.ActualWeight = basic.ActualWeight;
|
||||||
|
parcelInput.ChargeableWeight = basic.ActualWeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.Quantity is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.Quantity = basic.Quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.Length is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.Length = basic.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.Width is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.Width = basic.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.Height is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.Height = basic.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.ExportCustomsMode))
|
||||||
|
{
|
||||||
|
parcelInput.ExportCustomsMode = basic.ExportCustomsMode.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.ExportQualificationId is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.ExportQualificationId = basic.ExportQualificationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.PlatformCode))
|
||||||
|
{
|
||||||
|
parcelInput.PlatformCode = basic.PlatformCode.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.InboundMethod))
|
||||||
|
{
|
||||||
|
parcelInput.InboundMethod = basic.InboundMethod.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.SenderAddressId is > 0)
|
||||||
|
{
|
||||||
|
parcelInput.SenderAddressId = basic.SenderAddressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (basic.ExpectPickupTime.HasValue && basic.ExpectPickupTime != default)
|
||||||
|
{
|
||||||
|
parcelInput.ExpectPickupTime = basic.ExpectPickupTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.PickupDirection))
|
||||||
|
{
|
||||||
|
parcelInput.PickupDirection = basic.PickupDirection.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.CarrierCode))
|
||||||
|
{
|
||||||
|
parcelInput.CarrierCode = basic.CarrierCode.Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(basic.CarrierService))
|
||||||
|
{
|
||||||
|
parcelInput.CarrierService = basic.CarrierService.Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 按平台商品行组装小包入参(不要求库内 SKU 映射;用于创建物流 / 物流&代发)。
|
/// 按平台商品行组装小包入参(不要求库内 SKU 映射;用于创建物流 / 物流&代发)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -411,7 +411,8 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
input.WarehouseId,
|
input.WarehouseId,
|
||||||
input.Items,
|
input.Items,
|
||||||
requireBind: false,
|
requireBind: false,
|
||||||
requireWmsProductGroup: false);
|
requireWmsProductGroup: false,
|
||||||
|
parcelBasic: input.ParcelBasic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -432,7 +433,8 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
input.WarehouseId,
|
input.WarehouseId,
|
||||||
input.Items,
|
input.Items,
|
||||||
requireBind: true,
|
requireBind: true,
|
||||||
requireWmsProductGroup: false);
|
requireWmsProductGroup: false,
|
||||||
|
parcelBasic: input.ParcelBasic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -454,7 +456,8 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
input.WarehouseId,
|
input.WarehouseId,
|
||||||
input.Items,
|
input.Items,
|
||||||
requireBind: true,
|
requireBind: true,
|
||||||
requireWmsProductGroup: true);
|
requireWmsProductGroup: true,
|
||||||
|
parcelBasic: input.ParcelBasic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<PlatformStoreOrderBatchCreateLogisticsOutput> BatchCreateLogisticsInternalAsync(
|
private async Task<PlatformStoreOrderBatchCreateLogisticsOutput> BatchCreateLogisticsInternalAsync(
|
||||||
@ -463,7 +466,8 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
int? warehouseId,
|
int? warehouseId,
|
||||||
List<PlatformStoreOrderBatchCreateItemInput> items,
|
List<PlatformStoreOrderBatchCreateItemInput> items,
|
||||||
bool requireBind,
|
bool requireBind,
|
||||||
bool requireWmsProductGroup = false)
|
bool requireWmsProductGroup = false,
|
||||||
|
PlatformStoreOrderParcelBasicInput? parcelBasic = null)
|
||||||
{
|
{
|
||||||
if (items == null || items.Count == 0)
|
if (items == null || items.Count == 0)
|
||||||
{
|
{
|
||||||
@ -512,7 +516,9 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
warehouseId,
|
warehouseId,
|
||||||
resolvedProductCode,
|
resolvedProductCode,
|
||||||
itemInput.Receiver,
|
itemInput.Receiver,
|
||||||
requireBind ? itemInput.BindItems : null);
|
requireBind ? itemInput.BindItems : null,
|
||||||
|
parcelBasic,
|
||||||
|
itemInput.ClientNo);
|
||||||
item.Success = true;
|
item.Success = true;
|
||||||
item.Message = requireWmsProductGroup
|
item.Message = requireWmsProductGroup
|
||||||
? $"已创建代发订单 {result.ServiceNo} 并绑定"
|
? $"已创建代发订单 {result.ServiceNo} 并绑定"
|
||||||
@ -548,7 +554,9 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
int? warehouseId,
|
int? warehouseId,
|
||||||
string productCode,
|
string productCode,
|
||||||
OrderParcelReceiverInput? receiver,
|
OrderParcelReceiverInput? receiver,
|
||||||
List<OrderStockBindSaveItemInput>? bindItems)
|
List<OrderStockBindSaveItemInput>? bindItems,
|
||||||
|
PlatformStoreOrderParcelBasicInput? parcelBasic = null,
|
||||||
|
string? clientNoOverride = null)
|
||||||
{
|
{
|
||||||
var order = await GetOrderOrThrowAsync(customerId, storeOrderId);
|
var order = await GetOrderOrThrowAsync(customerId, storeOrderId);
|
||||||
await EnsureCanCreateLogisticsAsync(order);
|
await EnsureCanCreateLogisticsAsync(order);
|
||||||
@ -572,6 +580,11 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
throw new BusinessException("请指定发货仓库");
|
throw new BusinessException("请指定发货仓库");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parcelBasic != null && resolvedWarehouseId is not > 0)
|
||||||
|
{
|
||||||
|
throw new BusinessException("请选择仓库");
|
||||||
|
}
|
||||||
|
|
||||||
var parcelInput = PlatformStoreOrderParcelBuilder.BuildFromPlatformLines(
|
var parcelInput = PlatformStoreOrderParcelBuilder.BuildFromPlatformLines(
|
||||||
order,
|
order,
|
||||||
lines,
|
lines,
|
||||||
@ -580,6 +593,7 @@ public class PlatformStoreOrderService : ApplicationService
|
|||||||
resolvedWarehouseId,
|
resolvedWarehouseId,
|
||||||
customerId,
|
customerId,
|
||||||
receiver);
|
receiver);
|
||||||
|
PlatformStoreOrderParcelBuilder.ApplyParcelBasic(parcelInput, parcelBasic, clientNoOverride);
|
||||||
|
|
||||||
var parcelOutput = await OrderService.CreateParcelForBatchAsync(
|
var parcelOutput = await OrderService.CreateParcelForBatchAsync(
|
||||||
parcelInput,
|
parcelInput,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user