feat: 揽收单支持改信息/件重尺/重算费用,创建后自动预报下游
All checks were successful
Build and Deploy / deploy (push) Successful in 1m1s
All checks were successful
Build and Deploy / deploy (push) Successful in 1m1s
创建成功后自动下游预报回写承运单号并升为已预约;详情可改揽收信息与件重尺并按卖买价重算。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
6852135774
commit
358738c333
@ -176,6 +176,44 @@ public class PickupOrderRescheduleInput
|
|||||||
public DateTime ExpectPickupTime { get; set; }
|
public DateTime ExpectPickupTime { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改揽收信息(未支付且 draft/scheduled)。
|
||||||
|
/// </summary>
|
||||||
|
public class PickupOrderUpdateInfoInput
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int? WarehouseId { get; set; }
|
||||||
|
|
||||||
|
public int? SenderAddressId { get; set; }
|
||||||
|
|
||||||
|
public DateTime? ExpectPickupTime { get; set; }
|
||||||
|
|
||||||
|
public string? CarrierService { get; set; }
|
||||||
|
|
||||||
|
public string? CarrierWaybillNo { get; set; }
|
||||||
|
|
||||||
|
[StringLength(512)]
|
||||||
|
public string? Remark { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改件重尺(未支付;不改费用,需另行重算)。
|
||||||
|
/// </summary>
|
||||||
|
public class PickupOrderUpdateMeasureInput
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public decimal TotalActualWeight { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MinLength(1)]
|
||||||
|
public List<PickupPackageSizeOutput> PackageSizes { get; set; } = [];
|
||||||
|
}
|
||||||
|
|
||||||
public class PickupOrderRejectItem
|
public class PickupOrderRejectItem
|
||||||
{
|
{
|
||||||
public int OrderId { get; set; }
|
public int OrderId { get; set; }
|
||||||
|
|||||||
@ -74,15 +74,66 @@ public class PickupOrderFeePushService : IScopedDependency
|
|||||||
var pickup = await _pickupOrderRepository.GetByCarrierWaybillNoAsync(carrierWaybillNo)
|
var pickup = await _pickupOrderRepository.GetByCarrierWaybillNoAsync(carrierWaybillNo)
|
||||||
?? throw new BusinessException($"揽收单不存在:承运运单号 {carrierWaybillNo}");
|
?? throw new BusinessException($"揽收单不存在:承运运单号 {carrierWaybillNo}");
|
||||||
|
|
||||||
if (pickup.PayStatus == PickupPayStatusCodes.Paid)
|
EnsureCanReceiveMeasure(pickup);
|
||||||
|
|
||||||
|
return await ApplyMeasureAndBillAsync(
|
||||||
|
pickup,
|
||||||
|
input.TotalActualWeight,
|
||||||
|
sizes,
|
||||||
|
input.CarrierFreightWeight,
|
||||||
|
input.CarrierQuotedFreightAmount,
|
||||||
|
input.CarrierQuotedReceivableAmount,
|
||||||
|
input.ValueInfoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按已保存(或入参)件重尺,用当前承运服务卖价/买价重算出账。
|
||||||
|
/// </summary>
|
||||||
|
public async Task<PickupOpenApiPushFeeResult> RecalcByPickupAsync(
|
||||||
|
PickupOrder pickup,
|
||||||
|
decimal? totalActualWeightOverride = null,
|
||||||
|
IReadOnlyList<PickupPackageSizeOutput>? sizesOverride = null)
|
||||||
|
{
|
||||||
|
EnsureCanReceiveMeasure(pickup);
|
||||||
|
|
||||||
|
var weight = totalActualWeightOverride ?? pickup.TotalActualWeight ?? 0;
|
||||||
|
if (weight <= 0)
|
||||||
{
|
{
|
||||||
throw new BusinessException("揽收单已支付,拒绝修改件重尺与费用");
|
throw new BusinessException("请先填写实重后再重算费用");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PickupOrderStatusCodes.IsTerminal(pickup.Status)
|
var sizes = sizesOverride != null && sizesOverride.Count > 0
|
||||||
&& pickup.Status != PickupOrderStatusCodes.Inbound)
|
? NormalizeSizes(sizesOverride.ToList())
|
||||||
|
: NormalizeSizes(
|
||||||
|
OmsDocHelper.DeserializeJson<List<PickupPackageSizeOutput>>(pickup.PackageSizesJson));
|
||||||
|
if (sizes.Count == 0)
|
||||||
{
|
{
|
||||||
throw new BusinessException("当前揽收单状态不可接收件重尺");
|
throw new BusinessException("请先填写件重尺尺寸后再重算费用");
|
||||||
|
}
|
||||||
|
|
||||||
|
return await ApplyMeasureAndBillAsync(pickup, weight, sizes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PickupOpenApiPushFeeResult> ApplyMeasureAndBillAsync(
|
||||||
|
PickupOrder pickup,
|
||||||
|
decimal totalActualWeight,
|
||||||
|
IReadOnlyList<PickupPackageSizeOutput> sizes,
|
||||||
|
decimal? carrierFreightWeight = null,
|
||||||
|
decimal? carrierQuotedFreightAmount = null,
|
||||||
|
decimal? carrierQuotedReceivableAmount = null,
|
||||||
|
List<PickupCarrierValueFeeOutput>? valueInfoList = null)
|
||||||
|
{
|
||||||
|
if (totalActualWeight <= 0)
|
||||||
|
{
|
||||||
|
throw new BusinessException("totalActualWeight 必须大于 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalizedSizes = sizes is List<PickupPackageSizeOutput> list
|
||||||
|
? NormalizeSizes(list)
|
||||||
|
: NormalizeSizes(sizes.ToList());
|
||||||
|
if (normalizedSizes.Count == 0)
|
||||||
|
{
|
||||||
|
throw new BusinessException("packageSizes 不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(pickup.CarrierService))
|
if (string.IsNullOrWhiteSpace(pickup.CarrierService))
|
||||||
@ -93,14 +144,14 @@ public class PickupOrderFeePushService : IScopedDependency
|
|||||||
var product = await _salesProductRepository.GetByProductCodeAsync(pickup.CarrierService.Trim())
|
var product = await _salesProductRepository.GetByProductCodeAsync(pickup.CarrierService.Trim())
|
||||||
?? throw new BusinessException($"未找到承运服务对应销售产品「{pickup.CarrierService}」");
|
?? throw new BusinessException($"未找到承运服务对应销售产品「{pickup.CarrierService}」");
|
||||||
|
|
||||||
var totalVolume = sizes.Sum(x => x.Length * x.Width * x.Height * x.Count);
|
var totalVolume = normalizedSizes.Sum(x => x.Length * x.Width * x.Height * x.Count);
|
||||||
var weightRow = new OrderWeight
|
var weightRow = new OrderWeight
|
||||||
{
|
{
|
||||||
Type = OrderWeightTypeCodes.Receive,
|
Type = OrderWeightTypeCodes.Receive,
|
||||||
Length = totalVolume,
|
Length = totalVolume,
|
||||||
Width = 1,
|
Width = 1,
|
||||||
Height = 1,
|
Height = 1,
|
||||||
ActualWeight = input.TotalActualWeight,
|
ActualWeight = totalActualWeight,
|
||||||
Cubic = ParcelBillingCalculator.CalculateCubic(totalVolume, 1, 1)
|
Cubic = ParcelBillingCalculator.CalculateCubic(totalVolume, 1, 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,17 +238,33 @@ public class PickupOrderFeePushService : IScopedDependency
|
|||||||
var freight = receivableFees.FirstOrDefault()?.Amount ?? receivableTotal;
|
var freight = receivableFees.FirstOrDefault()?.Amount ?? receivableTotal;
|
||||||
var other = Math.Max(0, receivableTotal - freight);
|
var other = Math.Max(0, receivableTotal - freight);
|
||||||
|
|
||||||
pickup.TotalActualWeight = input.TotalActualWeight;
|
pickup.TotalActualWeight = totalActualWeight;
|
||||||
pickup.VolumetricWeight = volumetricWeight;
|
pickup.VolumetricWeight = volumetricWeight;
|
||||||
pickup.ChargeableWeight = chargeableWeight;
|
pickup.ChargeableWeight = chargeableWeight;
|
||||||
pickup.PackageSizesJson = OmsDocHelper.SerializeJson(sizes);
|
pickup.PackageSizesJson = OmsDocHelper.SerializeJson(normalizedSizes);
|
||||||
pickup.CarrierFreightWeight = input.CarrierFreightWeight;
|
if (carrierFreightWeight.HasValue)
|
||||||
pickup.CarrierQuotedFreightAmount = input.CarrierQuotedFreightAmount;
|
|
||||||
pickup.CarrierQuotedReceivableAmount = input.CarrierQuotedReceivableAmount;
|
|
||||||
pickup.CarrierQuoteJson = OmsDocHelper.SerializeJson(new PickupCarrierQuoteOutput
|
|
||||||
{
|
{
|
||||||
ValueInfoList = input.ValueInfoList ?? []
|
pickup.CarrierFreightWeight = carrierFreightWeight;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if (carrierQuotedFreightAmount.HasValue)
|
||||||
|
{
|
||||||
|
pickup.CarrierQuotedFreightAmount = carrierQuotedFreightAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (carrierQuotedReceivableAmount.HasValue)
|
||||||
|
{
|
||||||
|
pickup.CarrierQuotedReceivableAmount = carrierQuotedReceivableAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueInfoList != null)
|
||||||
|
{
|
||||||
|
pickup.CarrierQuoteJson = OmsDocHelper.SerializeJson(new PickupCarrierQuoteOutput
|
||||||
|
{
|
||||||
|
ValueInfoList = valueInfoList
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pickup.ReceivableFeeJson = OmsDocHelper.SerializeJson(receivableFees);
|
pickup.ReceivableFeeJson = OmsDocHelper.SerializeJson(receivableFees);
|
||||||
pickup.PayableFeeJson = OmsDocHelper.SerializeJson(payableFees);
|
pickup.PayableFeeJson = OmsDocHelper.SerializeJson(payableFees);
|
||||||
pickup.FreightAmount = freight;
|
pickup.FreightAmount = freight;
|
||||||
@ -211,15 +278,29 @@ public class PickupOrderFeePushService : IScopedDependency
|
|||||||
return new PickupOpenApiPushFeeResult
|
return new PickupOpenApiPushFeeResult
|
||||||
{
|
{
|
||||||
PickupNo = pickup.PickupNo,
|
PickupNo = pickup.PickupNo,
|
||||||
TotalActualWeight = input.TotalActualWeight,
|
TotalActualWeight = totalActualWeight,
|
||||||
ChargeableWeight = chargeableWeight,
|
ChargeableWeight = chargeableWeight,
|
||||||
VolumetricWeight = volumetricWeight,
|
VolumetricWeight = volumetricWeight,
|
||||||
ReceivableAmount = receivableTotal,
|
ReceivableAmount = receivableTotal,
|
||||||
CarrierPayableAmount = payableTotal,
|
CarrierPayableAmount = payableTotal,
|
||||||
CarrierQuotedFreightAmount = input.CarrierQuotedFreightAmount
|
CarrierQuotedFreightAmount = pickup.CarrierQuotedFreightAmount
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EnsureCanReceiveMeasure(PickupOrder pickup)
|
||||||
|
{
|
||||||
|
if (pickup.PayStatus == PickupPayStatusCodes.Paid)
|
||||||
|
{
|
||||||
|
throw new BusinessException("揽收单已支付,拒绝修改件重尺与费用");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PickupOrderStatusCodes.IsTerminal(pickup.Status)
|
||||||
|
&& pickup.Status != PickupOrderStatusCodes.Inbound)
|
||||||
|
{
|
||||||
|
throw new BusinessException("当前揽收单状态不可接收件重尺");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<(decimal VolumetricWeight, decimal ChargeableWeight)> CalculateChargeableAsync(
|
private async Task<(decimal VolumetricWeight, decimal ChargeableWeight)> CalculateChargeableAsync(
|
||||||
SalesProduct product,
|
SalesProduct product,
|
||||||
OrderWeight weight)
|
OrderWeight weight)
|
||||||
|
|||||||
@ -69,6 +69,9 @@ public class PickupOrderService : ApplicationService
|
|||||||
private IPickupBigBagTrackSyncer PickupBigBagTrackSyncer =>
|
private IPickupBigBagTrackSyncer PickupBigBagTrackSyncer =>
|
||||||
LazyServiceProvider.GetRequiredService<IPickupBigBagTrackSyncer>();
|
LazyServiceProvider.GetRequiredService<IPickupBigBagTrackSyncer>();
|
||||||
|
|
||||||
|
private PickupOrderFeePushService PickupOrderFeePushService =>
|
||||||
|
LazyServiceProvider.GetRequiredService<PickupOrderFeePushService>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建揽收单并挂载物流单(原子:全部校验通过才落库)。
|
/// 创建揽收单并挂载物流单(原子:全部校验通过才落库)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -274,6 +277,19 @@ public class PickupOrderService : ApplicationService
|
|||||||
await OrderRepository.UpdateAsync(order);
|
await OrderRepository.UpdateAsync(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 已选承运服务时:创建后自动预报下游拿承运运单号(失败不影响建单)
|
||||||
|
if (!string.IsNullOrWhiteSpace(entity.CarrierService))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await DownstreamForwardCoreAsync(entity);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 建单已成功,预报失败由列表「预报下游」重试
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return await MapOutputAsync(entity, includeOrders: true);
|
return await MapOutputAsync(entity, includeOrders: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,6 +567,213 @@ public class PickupOrderService : ApplicationService
|
|||||||
return await MapOutputAsync(pickup, includeOrders: true);
|
return await MapOutputAsync(pickup, includeOrders: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改揽收信息(未支付且 draft/scheduled)。
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("/order/pickup-order/update-info")]
|
||||||
|
public async Task<PickupOrderOutput> UpdateInfoAsync([FromBody] PickupOrderUpdateInfoInput input)
|
||||||
|
{
|
||||||
|
var pickup = await GetOwnedPickupOrThrowAsync(input.Id);
|
||||||
|
EnsureUnpaidEditable(pickup);
|
||||||
|
if (!PickupOrderStatusCodes.IsMutableBinding(pickup.Status))
|
||||||
|
{
|
||||||
|
throw new BusinessException("当前状态不可修改揽收信息");
|
||||||
|
}
|
||||||
|
|
||||||
|
var warehouseChanged = false;
|
||||||
|
var expectTimeChanged = false;
|
||||||
|
var senderChanged = false;
|
||||||
|
|
||||||
|
if (input.WarehouseId is > 0 && input.WarehouseId.Value != pickup.WarehouseId)
|
||||||
|
{
|
||||||
|
var warehouse = await WarehouseAddressRepository.FirstOrDefaultAsync(x => x.Id == input.WarehouseId.Value);
|
||||||
|
if (warehouse == null)
|
||||||
|
{
|
||||||
|
throw new BusinessException("仓库不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
pickup.WarehouseId = input.WarehouseId.Value;
|
||||||
|
warehouseChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.SenderAddressId is > 0 && input.SenderAddressId.Value != pickup.SenderAddressId)
|
||||||
|
{
|
||||||
|
var senderAddress = await CustomerSenderAddressRepository.GetOwnedAsync(
|
||||||
|
input.SenderAddressId.Value,
|
||||||
|
pickup.CustomerId);
|
||||||
|
if (senderAddress == null)
|
||||||
|
{
|
||||||
|
throw new BusinessException("揽收地址不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
var addressType = string.IsNullOrWhiteSpace(senderAddress.AddressType)
|
||||||
|
? CustomerAddressTypeCodes.Sender
|
||||||
|
: senderAddress.AddressType;
|
||||||
|
if (!CustomerAddressTypeCodes.IsPickupEligible(addressType))
|
||||||
|
{
|
||||||
|
throw new BusinessException("揽收单请选择「国内揽收」类型地址");
|
||||||
|
}
|
||||||
|
|
||||||
|
string? senderCountryCode = null;
|
||||||
|
if (senderAddress.Country.HasValue)
|
||||||
|
{
|
||||||
|
var country = await CountryRepository.FirstOrDefaultAsync(x => x.Id == senderAddress.Country.Value);
|
||||||
|
senderCountryCode = country?.CountryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
pickup.SenderAddressId = senderAddress.Id;
|
||||||
|
pickup.SenderName = senderAddress.SenderName ?? string.Empty;
|
||||||
|
pickup.SenderCompany = senderAddress.Company;
|
||||||
|
pickup.SenderCountry = senderAddress.Country;
|
||||||
|
pickup.SenderCountryCode = senderCountryCode;
|
||||||
|
pickup.SenderProvince = senderAddress.Province;
|
||||||
|
pickup.SenderCity = senderAddress.City;
|
||||||
|
pickup.SenderZipCode = senderAddress.ZipCode;
|
||||||
|
pickup.SenderStreetAddress1 = senderAddress.StreetAddress1 ?? string.Empty;
|
||||||
|
pickup.SenderStreetAddress2 = senderAddress.StreetAddress2;
|
||||||
|
pickup.SenderStreetAddress3 = senderAddress.StreetAddress3;
|
||||||
|
pickup.SenderHouseNumber = senderAddress.HouseNumber;
|
||||||
|
pickup.SenderPhone = senderAddress.Phone;
|
||||||
|
pickup.SenderTelePhone = senderAddress.TelePhone;
|
||||||
|
pickup.SenderEmail = senderAddress.Email;
|
||||||
|
senderChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.ExpectPickupTime.HasValue && input.ExpectPickupTime.Value != default)
|
||||||
|
{
|
||||||
|
pickup.ExpectPickupTime = input.ExpectPickupTime.Value;
|
||||||
|
expectTimeChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.CarrierService != null)
|
||||||
|
{
|
||||||
|
var carrierService = NormalizeOptional(input.CarrierService);
|
||||||
|
if (carrierService == null)
|
||||||
|
{
|
||||||
|
throw new BusinessException("承运服务不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
pickup.CarrierService = carrierService;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.CarrierWaybillNo != null)
|
||||||
|
{
|
||||||
|
pickup.CarrierWaybillNo = NormalizeOptional(input.CarrierWaybillNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.Remark != null)
|
||||||
|
{
|
||||||
|
pickup.Remark = NormalizeOptional(input.Remark);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入承运运单号后 draft → scheduled(已预约)
|
||||||
|
if (!string.IsNullOrWhiteSpace(pickup.CarrierWaybillNo)
|
||||||
|
&& pickup.Status == PickupOrderStatusCodes.Draft)
|
||||||
|
{
|
||||||
|
pickup.Status = PickupOrderStatusCodes.Scheduled;
|
||||||
|
}
|
||||||
|
|
||||||
|
await PickupOrderRepository.UpdateAsync(pickup);
|
||||||
|
|
||||||
|
if (warehouseChanged || expectTimeChanged || senderChanged)
|
||||||
|
{
|
||||||
|
var lines = await PickupOrderLineRepository.GetByPickupOrderIdAsync(pickup.Id);
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
var order = await OrderRepository.FirstOrDefaultAsync(x => x.Id == line.OrderId);
|
||||||
|
if (order == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (warehouseChanged)
|
||||||
|
{
|
||||||
|
order.WarehouseId = pickup.WarehouseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectTimeChanged)
|
||||||
|
{
|
||||||
|
order.PickupTime = pickup.ExpectPickupTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (senderChanged)
|
||||||
|
{
|
||||||
|
order.CustomerSenderAddressId = pickup.SenderAddressId;
|
||||||
|
}
|
||||||
|
|
||||||
|
await OrderRepository.UpdateAsync(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await MapOutputAsync(pickup, includeOrders: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改件重尺(未支付;仅落库,不改费用)。
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("/order/pickup-order/update-measure")]
|
||||||
|
public async Task<PickupOrderOutput> UpdateMeasureAsync([FromBody] PickupOrderUpdateMeasureInput input)
|
||||||
|
{
|
||||||
|
var pickup = await GetOwnedPickupOrThrowAsync(input.Id);
|
||||||
|
EnsureUnpaidEditable(pickup);
|
||||||
|
if (PickupOrderStatusCodes.IsTerminal(pickup.Status)
|
||||||
|
&& pickup.Status != PickupOrderStatusCodes.Inbound)
|
||||||
|
{
|
||||||
|
throw new BusinessException("当前状态不可修改件重尺");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.TotalActualWeight <= 0)
|
||||||
|
{
|
||||||
|
throw new BusinessException("实重必须大于 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
var sizes = (input.PackageSizes ?? [])
|
||||||
|
.Select(x => new PickupPackageSizeOutput
|
||||||
|
{
|
||||||
|
Length = x.Length,
|
||||||
|
Width = x.Width,
|
||||||
|
Height = x.Height,
|
||||||
|
Count = x.Count <= 0 ? 1 : x.Count
|
||||||
|
})
|
||||||
|
.Where(x => x.Length > 0 && x.Width > 0 && x.Height > 0)
|
||||||
|
.ToList();
|
||||||
|
if (sizes.Count == 0)
|
||||||
|
{
|
||||||
|
throw new BusinessException("请至少填写一条有效尺寸(长宽高)");
|
||||||
|
}
|
||||||
|
|
||||||
|
pickup.TotalActualWeight = input.TotalActualWeight;
|
||||||
|
pickup.PackageSizesJson = OmsDocHelper.SerializeJson(sizes);
|
||||||
|
pickup.UpdateTime = DateTime.Now;
|
||||||
|
await PickupOrderRepository.UpdateAsync(pickup);
|
||||||
|
return await MapOutputAsync(pickup, includeOrders: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按当前件重尺与承运服务重算费用。
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("/order/pickup-order/recalc-fee")]
|
||||||
|
public async Task<PickupOrderOutput> RecalcFeeAsync([FromBody] PickupOrderIdInput input)
|
||||||
|
{
|
||||||
|
var pickup = await GetOwnedPickupOrThrowAsync(input.Id);
|
||||||
|
EnsureUnpaidEditable(pickup);
|
||||||
|
await PickupOrderFeePushService.RecalcByPickupAsync(pickup);
|
||||||
|
return await MapOutputAsync(pickup, includeOrders: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureUnpaidEditable(PickupOrder pickup)
|
||||||
|
{
|
||||||
|
if (pickup.PayStatus == PickupPayStatusCodes.Paid)
|
||||||
|
{
|
||||||
|
throw new BusinessException("已支付不可修改");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pickup.Status is PickupOrderStatusCodes.Cancelled or PickupOrderStatusCodes.Failed)
|
||||||
|
{
|
||||||
|
throw new BusinessException("当前状态不可修改");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 客户支付揽收运费(余额)。
|
/// 客户支付揽收运费(余额)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -930,6 +1153,14 @@ public class PickupOrderService : ApplicationService
|
|||||||
public async Task<OrderDownstreamForwardResult> DownstreamForwardAsync([FromBody] PickupOrderIdInput input)
|
public async Task<OrderDownstreamForwardResult> DownstreamForwardAsync([FromBody] PickupOrderIdInput input)
|
||||||
{
|
{
|
||||||
var pickup = await GetOwnedPickupOrThrowAsync(input.Id);
|
var pickup = await GetOwnedPickupOrThrowAsync(input.Id);
|
||||||
|
return await DownstreamForwardCoreAsync(pickup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预报下游核心:回写承运运单号,draft 升为 scheduled。
|
||||||
|
/// </summary>
|
||||||
|
private async Task<OrderDownstreamForwardResult> DownstreamForwardCoreAsync(PickupOrder pickup)
|
||||||
|
{
|
||||||
if (string.IsNullOrWhiteSpace(pickup.CarrierService))
|
if (string.IsNullOrWhiteSpace(pickup.CarrierService))
|
||||||
{
|
{
|
||||||
throw new BusinessException("请先选择承运服务后再预报下游");
|
throw new BusinessException("请先选择承运服务后再预报下游");
|
||||||
@ -974,6 +1205,14 @@ public class PickupOrderService : ApplicationService
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 拿到承运运单号后 draft → scheduled(已预约)
|
||||||
|
if (!string.IsNullOrWhiteSpace(pickup.CarrierWaybillNo)
|
||||||
|
&& pickup.Status == PickupOrderStatusCodes.Draft)
|
||||||
|
{
|
||||||
|
pickup.Status = PickupOrderStatusCodes.Scheduled;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(pickup.CarrierCode)
|
if (string.IsNullOrWhiteSpace(pickup.CarrierCode)
|
||||||
&& !string.IsNullOrWhiteSpace(creds.SupplierCode))
|
&& !string.IsNullOrWhiteSpace(creds.SupplierCode))
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user