using Oms.Application.Dtos.Orders; using Oms.Domain.OrdersAggregate.Consts; using Oms.Domain.OrdersAggregate.Entities; using Oms.Domain.SystemAggregate.Repositories; namespace Oms.Application.Shared; /// /// 从订单表及关联子表组装 createOrderOne 标准请求体。 /// public static class OrderDownstreamCreateOneBodyBuilder { public static async Task BuildAsync( Order order, OrderSender? sender, OrderRecipient? recipient, IReadOnlyList declarations, IReadOnlyList weights, ICountryRepository countryRepository, CancellationToken cancellationToken = default) { var countryIds = new List(); if (sender?.Country is > 0) { countryIds.Add(sender.Country.Value); } if (recipient?.Country is > 0) { countryIds.Add(recipient.Country.Value); } var countries = countryIds.Count == 0 ? [] : await countryRepository.GetListAsync(x => countryIds.Contains(x.Id)); var idToCode = countries.ToDictionary(x => x.Id, x => x.CountryCode); var forecast = weights.FirstOrDefault(x => string.Equals(x.Type, OrderWeightTypeCodes.Forecast, StringComparison.OrdinalIgnoreCase)) ?? weights.FirstOrDefault(); return new OrderParcelCreateInput { RequestId = order.RequestId, ClientNo = order.ClientNo, TrackNo = order.TrackNo, ServiceNo = order.ServiceNo, ProductCode = order.ProductCode, ChannelCode = order.ChannelCode, CargoAttribute = order.CargoAttribute, ExportCustomsMode = order.ExportCustomsMode, WarehouseId = order.WarehouseId, CustomerId = order.CustomerId, Length = forecast?.Length, Width = forecast?.Width, Height = forecast?.Height, ActualWeight = forecast?.ActualWeight, VolumetricWeight = forecast?.VolumetricWeight, ChargeableWeight = forecast?.ChargeableWeight, Cubic = forecast?.Cubic, IsCod = order.IsCod > 0, CodCurrency = order.CodCurrency, CodSum = order.CodSum, DeclaredCurrency = order.DeclaredCurrency, DeclaredSum = order.DeclaredSum, Quantity = order.Quantity, Receiver = MapReceiver(recipient, order.ConsigneeCountry, idToCode), Sender = MapSender(sender, idToCode), Items = declarations.Select(MapItem).ToList() }; } private static string? ResolveCountryIso(int? countryId, string? orderConsigneeCountry, IReadOnlyDictionary idToCode) { if (!string.IsNullOrWhiteSpace(orderConsigneeCountry)) { var trimmed = orderConsigneeCountry.Trim(); if (trimmed.Length == 2) { return trimmed.ToUpperInvariant(); } } if (countryId is > 0 && idToCode.TryGetValue(countryId.Value, out var code) && !string.IsNullOrWhiteSpace(code)) { return code.Trim().ToUpperInvariant(); } return null; } private static OrderParcelReceiverInput? MapReceiver( OrderRecipient? recipient, string? orderConsigneeCountry, IReadOnlyDictionary idToCode) { if (recipient == null) { return string.IsNullOrWhiteSpace(orderConsigneeCountry) ? null : new OrderParcelReceiverInput { CountryCode = orderConsigneeCountry.Trim().ToUpperInvariant() }; } return new OrderParcelReceiverInput { RecipientsName = recipient.RecipientsName, CompanyName = recipient.CompanyName, Phone = recipient.Phone, TelePhone = recipient.TelePhone, Email = recipient.Email, CountryCode = ResolveCountryIso(recipient.Country, orderConsigneeCountry, idToCode), Province = recipient.Province, City = recipient.City, StreetNumber = recipient.StreetNumber, StreetAddress1 = recipient.StreetAddress1, StreetAddress2 = recipient.StreetAddress2, StreetAddress3 = recipient.StreetAddress3, ZipCode = recipient.ZipCode, TaxType = recipient.TaxType, TaxNo = recipient.TaxNo, CertificateType = recipient.CertificateType, CertificateNo = recipient.CertificateNo, Eori = recipient.Eori, Vat = recipient.Vat }; } private static OrderParcelSenderInput? MapSender(OrderSender? sender, IReadOnlyDictionary idToCode) { if (sender == null) { return null; } return new OrderParcelSenderInput { SenderName = sender.SenderName, Company = sender.Company, Phone = sender.Phone, TelePhone = sender.TelePhone, Email = sender.Email, CountryCode = ResolveCountryIso(sender.Country, null, idToCode), Province = sender.Province, City = sender.City, ZipCode = sender.ZipCode, StreetAddress1 = sender.StreetAddress1, StreetAddress2 = sender.StreetAddress2, StreetAddress3 = sender.StreetAddress3, HouseNumber = sender.HouseNumber }; } private static OrderParcelItemInput MapItem(OrderDeclaration x) => new() { CnName = x.CnName, EnName = x.EnName, Sku = x.Sku, Unit = x.Unit, UnitPrice = x.UnitPrice, UnitWeight = x.UnitWeight, Quantity = x.Quantity, Amount = x.Amount, Weight = x.Weight, ImHsCode = x.ImHsCode, ExHsCode = x.ExHsCode ?? x.HsCode, SkuImage = x.SkuImage, Category = x.Category, Brand = x.Brand, BrandType = x.BrandType, IsMagnetic = x.IsMagnetic > 0, Distribution = x.Distribution, Material = x.Material, EnMaterial = x.EnMaterial, Purpose = x.Purpose, Attributes = x.Attributes, OriginCountry = x.OriginCountry, SalesLink = x.SalesLink, Model = x.Model, Specifications = x.Specifications, Comment = x.Comment }; }