feat: 9610汇总下单关联出口资质,并补齐批量模板字段
All checks were successful
Build and Deploy / deploy (push) Successful in 58s
All checks were successful
Build and Deploy / deploy (push) Successful in 58s
下单/导入在 9610Summary 时校验并落库 ExportQualificationId(可回落默认备案),写入 9610 申报企业信息;专线小包模板长宽高改必填并增加资质备案列。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
dd4644e914
commit
ddb8efba15
2
db.sql
2
db.sql
@ -124,6 +124,7 @@ CREATE TABLE `t_order` (
|
|||||||
`ConsigneeCountryName` VARCHAR(64) NULL COMMENT '国家中文名称',
|
`ConsigneeCountryName` VARCHAR(64) NULL COMMENT '国家中文名称',
|
||||||
`CargoAttribute` VARCHAR(32) NULL COMMENT '货物属性:general/electronics/sensitive',
|
`CargoAttribute` VARCHAR(32) NULL COMMENT '货物属性:general/electronics/sensitive',
|
||||||
`ExportCustomsMode` VARCHAR(32) NULL COMMENT '出口报关方式',
|
`ExportCustomsMode` VARCHAR(32) NULL COMMENT '出口报关方式',
|
||||||
|
`ExportQualificationId` INT NULL COMMENT '出口资质备案 Id(t_customer_export_qualification.Id)',
|
||||||
`PredeclareFailReason` VARCHAR(512) NULL COMMENT '预报失败原因',
|
`PredeclareFailReason` VARCHAR(512) NULL COMMENT '预报失败原因',
|
||||||
`AllocationPendingReason` VARCHAR(512) NULL COMMENT '待排货原因(排货或渠道买价未匹配)',
|
`AllocationPendingReason` VARCHAR(512) NULL COMMENT '待排货原因(排货或渠道买价未匹配)',
|
||||||
`AllocationScheme` VARCHAR(32) NULL COMMENT '最近一次排货方案 costLowest/timeFastest/overallBest/designated',
|
`AllocationScheme` VARCHAR(32) NULL COMMENT '最近一次排货方案 costLowest/timeFastest/overallBest/designated',
|
||||||
@ -204,6 +205,7 @@ CREATE TABLE `t_order` (
|
|||||||
KEY `idx_ord_source_ctime` (`OrderSource`, `CreateTime`),
|
KEY `idx_ord_source_ctime` (`OrderSource`, `CreateTime`),
|
||||||
KEY `idx_order_pickup` (`PickupOrderId`),
|
KEY `idx_order_pickup` (`PickupOrderId`),
|
||||||
KEY `idx_order_inbound_method` (`InboundMethod`),
|
KEY `idx_order_inbound_method` (`InboundMethod`),
|
||||||
|
KEY `idx_order_export_qualification` (`ExportQualificationId`),
|
||||||
KEY `idx_ord_fulfillment_customer` (`FulfillmentType`, `CustomerId`, `OrderStatus`)
|
KEY `idx_ord_fulfillment_customer` (`FulfillmentType`, `CustomerId`, `OrderStatus`)
|
||||||
) COMMENT='订单表';
|
) COMMENT='订单表';
|
||||||
|
|
||||||
|
|||||||
24
sql/migrate_order_export_qualification_id.sql
Normal file
24
sql/migrate_order_export_qualification_id.sql
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
-- 存量库:t_order 增加出口资质备案 Id(9610Summary 选用)
|
||||||
|
-- 可重复执行。
|
||||||
|
|
||||||
|
SET @db := DATABASE();
|
||||||
|
|
||||||
|
SET @exists := (
|
||||||
|
SELECT COUNT(1)
|
||||||
|
FROM information_schema.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA = @db
|
||||||
|
AND TABLE_NAME = 't_order'
|
||||||
|
AND COLUMN_NAME = 'ExportQualificationId'
|
||||||
|
);
|
||||||
|
|
||||||
|
SET @sql := IF(
|
||||||
|
@exists = 0,
|
||||||
|
'ALTER TABLE `t_order`
|
||||||
|
ADD COLUMN `ExportQualificationId` INT NULL COMMENT ''出口资质备案 Id(t_customer_export_qualification.Id)'' AFTER `ExportCustomsMode`,
|
||||||
|
ADD KEY `idx_order_export_qualification` (`ExportQualificationId`)',
|
||||||
|
'SELECT ''t_order.ExportQualificationId already exists'' AS info'
|
||||||
|
);
|
||||||
|
|
||||||
|
PREPARE stmt FROM @sql;
|
||||||
|
EXECUTE stmt;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
@ -48,18 +48,21 @@ public class CreateCustomerExportQualificationInput
|
|||||||
[StringLength(200)]
|
[StringLength(200)]
|
||||||
public string DomesticConsignor { get; set; } = string.Empty;
|
public string DomesticConsignor { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required]
|
||||||
[StringLength(64)]
|
[StringLength(64)]
|
||||||
public string? DomesticConsignorCustomsCode { get; set; }
|
public string DomesticConsignorCustomsCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
[StringLength(200)]
|
[StringLength(200)]
|
||||||
public string ProducerName { get; set; } = string.Empty;
|
public string ProducerName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required]
|
||||||
[StringLength(64)]
|
[StringLength(64)]
|
||||||
public string? ProducerCustomsCode { get; set; }
|
public string ProducerCustomsCode { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[Required]
|
||||||
[StringLength(100)]
|
[StringLength(100)]
|
||||||
public string? CustomsPort { get; set; }
|
public string CustomsPort { get; set; } = string.Empty;
|
||||||
|
|
||||||
public bool IsDefault { get; set; }
|
public bool IsDefault { get; set; }
|
||||||
|
|
||||||
|
|||||||
@ -205,6 +205,11 @@ public class OrderOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ExportCustomsMode { get; set; }
|
public string? ExportCustomsMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出口资质备案 Id。
|
||||||
|
/// </summary>
|
||||||
|
public int? ExportQualificationId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 预报失败原因(草稿订单)。
|
/// 预报失败原因(草稿订单)。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -45,6 +45,11 @@ public class OrderParcelCreateInput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ExportCustomsMode { get; set; }
|
public string? ExportCustomsMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出口资质备案 Id(ExportCustomsMode=9610Summary 时必填)。
|
||||||
|
/// </summary>
|
||||||
|
public int? ExportQualificationId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 仓库主键。
|
/// 仓库主键。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -86,10 +86,10 @@ public class CustomerExportQualificationService : ApplicationService
|
|||||||
CompanyName = input.CompanyName.Trim(),
|
CompanyName = input.CompanyName.Trim(),
|
||||||
SocialCreditCode = input.SocialCreditCode.Trim(),
|
SocialCreditCode = input.SocialCreditCode.Trim(),
|
||||||
DomesticConsignor = input.DomesticConsignor.Trim(),
|
DomesticConsignor = input.DomesticConsignor.Trim(),
|
||||||
DomesticConsignorCustomsCode = TrimOrNull(input.DomesticConsignorCustomsCode),
|
DomesticConsignorCustomsCode = input.DomesticConsignorCustomsCode.Trim(),
|
||||||
ProducerName = input.ProducerName.Trim(),
|
ProducerName = input.ProducerName.Trim(),
|
||||||
ProducerCustomsCode = TrimOrNull(input.ProducerCustomsCode),
|
ProducerCustomsCode = input.ProducerCustomsCode.Trim(),
|
||||||
CustomsPort = TrimOrNull(input.CustomsPort),
|
CustomsPort = input.CustomsPort.Trim(),
|
||||||
IsDefault = input.IsDefault ? (byte)1 : (byte)0,
|
IsDefault = input.IsDefault ? (byte)1 : (byte)0,
|
||||||
Remark = TrimOrNull(input.Remark)
|
Remark = TrimOrNull(input.Remark)
|
||||||
};
|
};
|
||||||
@ -115,10 +115,10 @@ public class CustomerExportQualificationService : ApplicationService
|
|||||||
entity.CompanyName = input.CompanyName.Trim();
|
entity.CompanyName = input.CompanyName.Trim();
|
||||||
entity.SocialCreditCode = input.SocialCreditCode.Trim();
|
entity.SocialCreditCode = input.SocialCreditCode.Trim();
|
||||||
entity.DomesticConsignor = input.DomesticConsignor.Trim();
|
entity.DomesticConsignor = input.DomesticConsignor.Trim();
|
||||||
entity.DomesticConsignorCustomsCode = TrimOrNull(input.DomesticConsignorCustomsCode);
|
entity.DomesticConsignorCustomsCode = input.DomesticConsignorCustomsCode.Trim();
|
||||||
entity.ProducerName = input.ProducerName.Trim();
|
entity.ProducerName = input.ProducerName.Trim();
|
||||||
entity.ProducerCustomsCode = TrimOrNull(input.ProducerCustomsCode);
|
entity.ProducerCustomsCode = input.ProducerCustomsCode.Trim();
|
||||||
entity.CustomsPort = TrimOrNull(input.CustomsPort);
|
entity.CustomsPort = input.CustomsPort.Trim();
|
||||||
entity.IsDefault = input.IsDefault ? (byte)1 : (byte)0;
|
entity.IsDefault = input.IsDefault ? (byte)1 : (byte)0;
|
||||||
entity.Remark = TrimOrNull(input.Remark);
|
entity.Remark = TrimOrNull(input.Remark);
|
||||||
|
|
||||||
@ -183,10 +183,25 @@ public class CustomerExportQualificationService : ApplicationService
|
|||||||
throw new BusinessException("境内发货人不能为空");
|
throw new BusinessException("境内发货人不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(input.DomesticConsignorCustomsCode))
|
||||||
|
{
|
||||||
|
throw new BusinessException("境内发货人海关代码不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(input.ProducerName))
|
if (string.IsNullOrWhiteSpace(input.ProducerName))
|
||||||
{
|
{
|
||||||
throw new BusinessException("生产销售单位不能为空");
|
throw new BusinessException("生产销售单位不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(input.ProducerCustomsCode))
|
||||||
|
{
|
||||||
|
throw new BusinessException("生产销售单位海关代码不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(input.CustomsPort))
|
||||||
|
{
|
||||||
|
throw new BusinessException("备案海关港口地不能为空");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Expression<Func<CustomerExportQualification, bool>> BuildPredicate(
|
private static Expression<Func<CustomerExportQualification, bool>> BuildPredicate(
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
using Fake.DependencyInjection;
|
using Fake.DependencyInjection;
|
||||||
|
using Oms.Domain.CustomersAggregate.Entities;
|
||||||
|
using Oms.Domain.CustomersAggregate.Repositories;
|
||||||
using Oms.Domain.OrdersAggregate.Consts;
|
using Oms.Domain.OrdersAggregate.Consts;
|
||||||
using Oms.Domain.OrdersAggregate.Entities;
|
using Oms.Domain.OrdersAggregate.Entities;
|
||||||
using Oms.Domain.OrdersAggregate.Repositories;
|
using Oms.Domain.OrdersAggregate.Repositories;
|
||||||
@ -13,15 +15,18 @@ public class Customs9610OrderWriter : IScopedDependency
|
|||||||
private readonly ICustoms9610OrderRepository _headerRepository;
|
private readonly ICustoms9610OrderRepository _headerRepository;
|
||||||
private readonly ICustoms9610OrderItemRepository _itemRepository;
|
private readonly ICustoms9610OrderItemRepository _itemRepository;
|
||||||
private readonly IOrderRepository _orderRepository;
|
private readonly IOrderRepository _orderRepository;
|
||||||
|
private readonly ICustomerExportQualificationRepository _exportQualificationRepository;
|
||||||
|
|
||||||
public Customs9610OrderWriter(
|
public Customs9610OrderWriter(
|
||||||
ICustoms9610OrderRepository headerRepository,
|
ICustoms9610OrderRepository headerRepository,
|
||||||
ICustoms9610OrderItemRepository itemRepository,
|
ICustoms9610OrderItemRepository itemRepository,
|
||||||
IOrderRepository orderRepository)
|
IOrderRepository orderRepository,
|
||||||
|
ICustomerExportQualificationRepository exportQualificationRepository)
|
||||||
{
|
{
|
||||||
_headerRepository = headerRepository;
|
_headerRepository = headerRepository;
|
||||||
_itemRepository = itemRepository;
|
_itemRepository = itemRepository;
|
||||||
_orderRepository = orderRepository;
|
_orderRepository = orderRepository;
|
||||||
|
_exportQualificationRepository = exportQualificationRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpsertFromOrderAsync(Order order, CancellationToken cancellationToken = default)
|
public async Task UpsertFromOrderAsync(Order order, CancellationToken cancellationToken = default)
|
||||||
@ -55,6 +60,7 @@ public class Customs9610OrderWriter : IScopedDependency
|
|||||||
var grossWeight = ResolveGrossWeight(weights);
|
var grossWeight = ResolveGrossWeight(weights);
|
||||||
var serviceNo = order.ServiceNo?.Trim() ?? string.Empty;
|
var serviceNo = order.ServiceNo?.Trim() ?? string.Empty;
|
||||||
var clientNo = FirstNonEmpty(order.ClientNo, order.ServiceNo) ?? string.Empty;
|
var clientNo = FirstNonEmpty(order.ClientNo, order.ServiceNo) ?? string.Empty;
|
||||||
|
var qualification = await ResolveQualificationAsync(order, cancellationToken);
|
||||||
|
|
||||||
if (existing != null
|
if (existing != null
|
||||||
&& string.Equals(existing.Status, Customs9610StatusCodes.Declared, StringComparison.OrdinalIgnoreCase))
|
&& string.Equals(existing.Status, Customs9610StatusCodes.Declared, StringComparison.OrdinalIgnoreCase))
|
||||||
@ -98,6 +104,8 @@ public class Customs9610OrderWriter : IScopedDependency
|
|||||||
header.PreRecordFlag = "1";
|
header.PreRecordFlag = "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ApplyQualification(header, qualification);
|
||||||
|
|
||||||
header.GrossWeight = grossWeight;
|
header.GrossWeight = grossWeight;
|
||||||
header.Currency = FirstNonEmpty(order.DeclaredCurrency, header.Currency, "CNY")!;
|
header.Currency = FirstNonEmpty(order.DeclaredCurrency, header.Currency, "CNY")!;
|
||||||
header.DestCountry = FirstNonEmpty(order.ConsigneeCountry, header.DestCountry) ?? string.Empty;
|
header.DestCountry = FirstNonEmpty(order.ConsigneeCountry, header.DestCountry) ?? string.Empty;
|
||||||
@ -141,6 +149,50 @@ public class Customs9610OrderWriter : IScopedDependency
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<CustomerExportQualification?> ResolveQualificationAsync(
|
||||||
|
Order order,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (order.CustomerId is not > 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (order.ExportQualificationId is > 0)
|
||||||
|
{
|
||||||
|
var owned = await _exportQualificationRepository.GetOwnedAsync(
|
||||||
|
order.ExportQualificationId.Value,
|
||||||
|
order.CustomerId.Value,
|
||||||
|
cancellationToken);
|
||||||
|
if (owned != null)
|
||||||
|
{
|
||||||
|
return owned;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await _exportQualificationRepository.GetDefaultAsync(
|
||||||
|
order.CustomerId.Value,
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyQualification(Customs9610Order header, CustomerExportQualification? qualification)
|
||||||
|
{
|
||||||
|
if (qualification == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
header.EcomCorpCode = Truncate(
|
||||||
|
FirstNonEmpty(qualification.DomesticConsignorCustomsCode, qualification.SocialCreditCode),
|
||||||
|
18);
|
||||||
|
header.EcomCorpName = Truncate(
|
||||||
|
FirstNonEmpty(qualification.CompanyName, qualification.DomesticConsignor),
|
||||||
|
100);
|
||||||
|
header.ProducerCode = Truncate(qualification.ProducerCustomsCode, 18);
|
||||||
|
header.ProducerName = Truncate(qualification.ProducerName, 100);
|
||||||
|
header.ActualSellerCode = Truncate(qualification.SocialCreditCode, 18);
|
||||||
|
}
|
||||||
|
|
||||||
private static decimal ResolveGrossWeight(IReadOnlyList<OrderWeight> weights)
|
private static decimal ResolveGrossWeight(IReadOnlyList<OrderWeight> weights)
|
||||||
{
|
{
|
||||||
var forecast = weights.FirstOrDefault(x =>
|
var forecast = weights.FirstOrDefault(x =>
|
||||||
|
|||||||
@ -200,6 +200,7 @@ public partial class OrderService
|
|||||||
: null,
|
: null,
|
||||||
RequestId = order.RequestId,
|
RequestId = order.RequestId,
|
||||||
ExportCustomsMode = order.ExportCustomsMode,
|
ExportCustomsMode = order.ExportCustomsMode,
|
||||||
|
ExportQualificationId = order.ExportQualificationId,
|
||||||
PredeclareFailReason = string.IsNullOrWhiteSpace(order.PredeclareFailReason)
|
PredeclareFailReason = string.IsNullOrWhiteSpace(order.PredeclareFailReason)
|
||||||
? null
|
? null
|
||||||
: order.PredeclareFailReason.Trim(),
|
: order.PredeclareFailReason.Trim(),
|
||||||
|
|||||||
@ -40,6 +40,8 @@ public partial class OrderService
|
|||||||
private static readonly ConcurrentDictionary<int, byte> InboundBillingInFlight = new();
|
private static readonly ConcurrentDictionary<int, byte> InboundBillingInFlight = new();
|
||||||
|
|
||||||
private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService<ICustomerRepository>();
|
private ICustomerRepository CustomerRepository => LazyServiceProvider.GetRequiredService<ICustomerRepository>();
|
||||||
|
private ICustomerExportQualificationRepository ExportQualificationRepository =>
|
||||||
|
LazyServiceProvider.GetRequiredService<ICustomerExportQualificationRepository>();
|
||||||
|
|
||||||
private IMemberLevelRepository MemberLevelRepository => LazyServiceProvider.GetRequiredService<IMemberLevelRepository>();
|
private IMemberLevelRepository MemberLevelRepository => LazyServiceProvider.GetRequiredService<IMemberLevelRepository>();
|
||||||
|
|
||||||
@ -409,6 +411,39 @@ public partial class OrderService
|
|||||||
throw new BusinessException("出口报关方式不合法");
|
throw new BusinessException("出口报关方式不合法");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var is9610Summary = string.Equals(
|
||||||
|
input.ExportCustomsMode,
|
||||||
|
ExportCustomsModeCodes.Mode9610Summary,
|
||||||
|
StringComparison.OrdinalIgnoreCase);
|
||||||
|
if (is9610Summary)
|
||||||
|
{
|
||||||
|
CustomerExportQualification? qualification = null;
|
||||||
|
if (input.ExportQualificationId is > 0)
|
||||||
|
{
|
||||||
|
qualification = await ExportQualificationRepository.GetOwnedAsync(
|
||||||
|
input.ExportQualificationId.Value,
|
||||||
|
input.CustomerId!.Value);
|
||||||
|
if (qualification == null)
|
||||||
|
{
|
||||||
|
throw new BusinessException("出口资质备案不存在或不属于当前客户");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qualification = await ExportQualificationRepository.GetDefaultAsync(input.CustomerId!.Value);
|
||||||
|
if (qualification == null)
|
||||||
|
{
|
||||||
|
throw new BusinessException("9610汇总申报必须选择出口资质备案(或先维护默认备案)");
|
||||||
|
}
|
||||||
|
|
||||||
|
input.ExportQualificationId = qualification.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input.ExportQualificationId = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(input.DeclaredCurrency))
|
if (string.IsNullOrWhiteSpace(input.DeclaredCurrency))
|
||||||
{
|
{
|
||||||
throw new BusinessException("申报币种不能为空");
|
throw new BusinessException("申报币种不能为空");
|
||||||
@ -1906,6 +1941,7 @@ public partial class OrderService
|
|||||||
ConsigneeCountryName = consigneeCountryName,
|
ConsigneeCountryName = consigneeCountryName,
|
||||||
CargoAttribute = input.CargoAttribute ?? CargoAttributeCodes.General,
|
CargoAttribute = input.CargoAttribute ?? CargoAttributeCodes.General,
|
||||||
ExportCustomsMode = input.ExportCustomsMode,
|
ExportCustomsMode = input.ExportCustomsMode,
|
||||||
|
ExportQualificationId = input.ExportQualificationId,
|
||||||
WarehouseId = input.WarehouseId,
|
WarehouseId = input.WarehouseId,
|
||||||
CustomerId = input.CustomerId,
|
CustomerId = input.CustomerId,
|
||||||
OrderSource = orderSource,
|
OrderSource = orderSource,
|
||||||
|
|||||||
@ -110,10 +110,11 @@ public static class OrderTemplateFieldRegistry
|
|||||||
Add("warehouseId", "发货仓库", true, "select", "warehouse", "basic", "1", hint: "从下拉选择发货仓库 ID");
|
Add("warehouseId", "发货仓库", true, "select", "warehouse", "basic", "1", hint: "从下拉选择发货仓库 ID");
|
||||||
Add("actualWeight", "实重(kg)", true, "number", example: "1.2", hint: "包裹实际重量,单位千克");
|
Add("actualWeight", "实重(kg)", true, "number", example: "1.2", hint: "包裹实际重量,单位千克");
|
||||||
Add("quantity", "包裹件数", true, "number", example: "1", hint: "一般为 1");
|
Add("quantity", "包裹件数", true, "number", example: "1", hint: "一般为 1");
|
||||||
Add("length", "长(cm)", false, "number", example: "10", hint: "选填,用于材积计费");
|
Add("length", "长(cm)", true, "number", example: "10", hint: "必填,用于材积计费");
|
||||||
Add("width", "宽(cm)", false, "number", example: "10", hint: "选填,用于材积计费");
|
Add("width", "宽(cm)", true, "number", example: "10", hint: "必填,用于材积计费");
|
||||||
Add("height", "高(cm)", false, "number", example: "10", hint: "选填,用于材积计费");
|
Add("height", "高(cm)", true, "number", example: "10", hint: "必填,用于材积计费");
|
||||||
Add("exportCustomsMode", "出口报关", false, "select", "export_customs_mode", "basic", "9610Simple", hint: "不选则按简易申报");
|
Add("exportCustomsMode", "出口报关", false, "select", "export_customs_mode", "basic", "9610Simple", hint: "不选则按简易申报;填 9610Summary 时需有默认出口资质或填备案Id");
|
||||||
|
Add("exportQualificationId", "出口资质备案Id", false, "number", example: "1", hint: "9610汇总申报时填写;留空则用客户默认备案");
|
||||||
|
|
||||||
Add("receiver.recipientsName", "收件人姓名", true, group: "receiver", example: "John Smith", hint: "必填");
|
Add("receiver.recipientsName", "收件人姓名", true, group: "receiver", example: "John Smith", hint: "必填");
|
||||||
Add("receiver.phone", "收件人手机", true, group: "receiver", example: "13900139000", hint: "必填");
|
Add("receiver.phone", "收件人手机", true, group: "receiver", example: "13900139000", hint: "必填");
|
||||||
@ -167,11 +168,12 @@ public static class OrderTemplateFieldRegistry
|
|||||||
Add("clientNo", "客户单号", true, example: "C202604230001", hint: "您自己的订单编号,同一客户不可重复");
|
Add("clientNo", "客户单号", true, example: "C202604230001", hint: "您自己的订单编号,同一客户不可重复");
|
||||||
Add("productCode", "运输方式", true, "select", "sales_product", "basic", "PROD001", hint: "从下拉选择产品编码");
|
Add("productCode", "运输方式", true, "select", "sales_product", "basic", "PROD001", hint: "从下拉选择产品编码");
|
||||||
Add("cargoAttribute", "货物属性", true, "select", "cargo_attribute", "basic", "general", hint: "普货选 general");
|
Add("cargoAttribute", "货物属性", true, "select", "cargo_attribute", "basic", "general", hint: "普货选 general");
|
||||||
Add("exportCustomsMode", "出口报关方式", false, "select", "export_customs_mode", "basic", "9610Simple", hint: "不选则简易申报");
|
Add("exportCustomsMode", "出口报关方式", false, "select", "export_customs_mode", "basic", "9610Simple", hint: "不选则简易申报;填 9610Summary 时需有默认出口资质或填备案Id");
|
||||||
|
Add("exportQualificationId", "出口资质备案Id", false, "number", example: "1", hint: "9610汇总申报时填写;留空则用客户默认备案");
|
||||||
Add("warehouseId", "发货仓库", true, "select", "warehouse", "basic", "1", hint: "从下拉选择仓库 ID");
|
Add("warehouseId", "发货仓库", true, "select", "warehouse", "basic", "1", hint: "从下拉选择仓库 ID");
|
||||||
Add("length", "长(cm)", false, "number", example: "10", hint: "材积计费用");
|
Add("length", "长(cm)", true, "number", example: "10", hint: "必填,材积计费用");
|
||||||
Add("width", "宽(cm)", false, "number", example: "10", hint: "材积计费用");
|
Add("width", "宽(cm)", true, "number", example: "10", hint: "必填,材积计费用");
|
||||||
Add("height", "高(cm)", false, "number", example: "10", hint: "材积计费用");
|
Add("height", "高(cm)", true, "number", example: "10", hint: "必填,材积计费用");
|
||||||
Add("actualWeight", "实重(kg)", true, "number", example: "1.2", hint: "必填");
|
Add("actualWeight", "实重(kg)", true, "number", example: "1.2", hint: "必填");
|
||||||
Add("isCod", "是否COD", false, "boolean", example: "false", hint: "货到付款填 true");
|
Add("isCod", "是否COD", false, "boolean", example: "false", hint: "货到付款填 true");
|
||||||
Add("codCurrency", "COD币种", false, "select", "currency", example: "USD", hint: "COD 订单填写");
|
Add("codCurrency", "COD币种", false, "select", "currency", example: "USD", hint: "COD 订单填写");
|
||||||
|
|||||||
@ -20,6 +20,10 @@ public static class OrderTemplateHeaderMatcher
|
|||||||
["产品编码"] = "productCode",
|
["产品编码"] = "productCode",
|
||||||
["货物属性"] = "cargoAttribute",
|
["货物属性"] = "cargoAttribute",
|
||||||
["出口报关方式"] = "exportCustomsMode",
|
["出口报关方式"] = "exportCustomsMode",
|
||||||
|
["出口报关"] = "exportCustomsMode",
|
||||||
|
["出口资质备案Id"] = "exportQualificationId",
|
||||||
|
["出口资质备案"] = "exportQualificationId",
|
||||||
|
["资质备案Id"] = "exportQualificationId",
|
||||||
["仓库"] = "warehouseId",
|
["仓库"] = "warehouseId",
|
||||||
["仓库ID"] = "warehouseId",
|
["仓库ID"] = "warehouseId",
|
||||||
["长cm"] = "length",
|
["长cm"] = "length",
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public static class OrderTemplateRowMapper
|
|||||||
|
|
||||||
private static readonly HashSet<string> ForceNumberFields = new(StringComparer.OrdinalIgnoreCase)
|
private static readonly HashSet<string> ForceNumberFields = new(StringComparer.OrdinalIgnoreCase)
|
||||||
{
|
{
|
||||||
"warehouseId", "length", "width", "height", "actualWeight", "codSum", "declaredSum", "quantity",
|
"warehouseId", "exportQualificationId", "length", "width", "height", "actualWeight", "codSum", "declaredSum", "quantity",
|
||||||
"receiver.taxType", "receiver.certificateType", "items[0].unitPrice", "items[0].unitWeight",
|
"receiver.taxType", "receiver.certificateType", "items[0].unitPrice", "items[0].unitWeight",
|
||||||
"items[0].quantity", "items[0].amount", "items[0].weight"
|
"items[0].quantity", "items[0].amount", "items[0].weight"
|
||||||
};
|
};
|
||||||
@ -75,9 +75,28 @@ public static class OrderTemplateRowMapper
|
|||||||
}
|
}
|
||||||
|
|
||||||
ApplyDerivedDeclarationFields(input);
|
ApplyDerivedDeclarationFields(input);
|
||||||
|
ApplyParcelDimensionDefaults(input);
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ApplyParcelDimensionDefaults(OrderParcelCreateInput input)
|
||||||
|
{
|
||||||
|
if (!input.Length.HasValue || input.Length <= 0)
|
||||||
|
{
|
||||||
|
input.Length = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.Width.HasValue || input.Width <= 0)
|
||||||
|
{
|
||||||
|
input.Width = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.Height.HasValue || input.Height <= 0)
|
||||||
|
{
|
||||||
|
input.Height = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void ApplyDerivedDeclarationFields(OrderParcelCreateInput input)
|
private static void ApplyDerivedDeclarationFields(OrderParcelCreateInput input)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(input.DeclaredCurrency))
|
if (string.IsNullOrWhiteSpace(input.DeclaredCurrency))
|
||||||
|
|||||||
@ -10,6 +10,10 @@ public interface ICustomerExportQualificationRepository : IRepository<CustomerEx
|
|||||||
int customerId,
|
int customerId,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
Task<CustomerExportQualification?> GetDefaultAsync(
|
||||||
|
int customerId,
|
||||||
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
Task ClearDefaultAsync(
|
Task ClearDefaultAsync(
|
||||||
int customerId,
|
int customerId,
|
||||||
int? excludeId = null,
|
int? excludeId = null,
|
||||||
|
|||||||
@ -52,6 +52,12 @@ public class Order : OmsAuditedAggregateRoot
|
|||||||
|
|
||||||
public string? ExportCustomsMode { get; set; }
|
public string? ExportCustomsMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 出口资质备案 Id(9610 汇总申报选用)。
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public int? ExportQualificationId { get; set; }
|
||||||
|
|
||||||
public string? PredeclareFailReason { get; set; }
|
public string? PredeclareFailReason { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -18,6 +18,13 @@ public class CustomerExportQualificationRepository
|
|||||||
return FirstOrDefaultAsync(x => x.Id == id && x.CustomerId == customerId, cancellationToken);
|
return FirstOrDefaultAsync(x => x.Id == id && x.CustomerId == customerId, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<CustomerExportQualification?> GetDefaultAsync(
|
||||||
|
int customerId,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return FirstOrDefaultAsync(x => x.CustomerId == customerId && x.IsDefault == 1, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ClearDefaultAsync(
|
public async Task ClearDefaultAsync(
|
||||||
int customerId,
|
int customerId,
|
||||||
int? excludeId = null,
|
int? excludeId = null,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user