/// <summary> /// Initializes a new instance of the <see cref="OrderProcessor"/> class. /// </summary> /// /// <param name="configuration">The configuration to use for influencing order processing behavior.</param> /// <param name="ecommerceClient">The client to use for interacting with the eCommerce service.</param> /// <param name="orderStorage">The storage to use for orders.</param> /// <param name="skuMetadataProcessor">The processor for the metadata associated with a SKU.</param> /// <param name="logger">The logger to be used for emitting telemetry from the controller.</param> /// <param name="clock">The clock instance to use for date/time related operations.</param> /// <param name="jsonSerializerSettings">The settings to use for JSON serializerion.</param> /// public OrderProcessor(OrderProcessorConfiguration configuration, IEcommerceClient ecommerceClient, IOrderStorage orderStorage, ISkuMetadataProcessor skuMetadataProcessor, ILogger logger, IClock clock, JsonSerializerSettings jsonSerializerSettings) { this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); this.ecommerceClient = ecommerceClient ?? throw new ArgumentNullException(nameof(ecommerceClient)); this.orderStorage = orderStorage ?? throw new ArgumentNullException(nameof(orderStorage)); this.skuMetadataProcessor = skuMetadataProcessor ?? throw new ArgumentNullException(nameof(skuMetadataProcessor)); this.Log = logger ?? throw new ArgumentNullException(nameof(logger)); this.clock = clock ?? throw new ArgumentNullException(nameof(clock)); this.jsonSerializerSettings = jsonSerializerSettings ?? throw new ArgumentNullException(nameof(jsonSerializerSettings)); this.rng = new Random(); }
/// <summary> /// Performs the actions needed build a <see cref="CreateOrderMessage" /> from the /// <see cref="OrderDetails" /> of an order. /// </summary> /// /// <param name="configuration">The configuration to use for bulding the message.</param> /// <param name="log">The logging instance to use for emitting information.</param> /// <param name="skuMetadataProcessor">The processor for SKU metadata.</param> /// <param name="partner">The partner associated with the order.</param> /// <param name="transactionId">The identifier to use for the transaction associated with this unique submission.</param> /// <param name="orderAssets">The set of assets associated with the order.</param> /// <param name="orderDetails">The details about the order.</param> /// <param name="serializerSettings">The settings to use for serialization operations.</param> /// <param name="correlationId">An optional identifier used to correlate activities across the disparate parts of processing, including external interations.</param> /// <param name="emulatedResult">An optional emulated result to use in place of building the message.</param> /// /// <returns>The result of the operation.</returns> /// protected virtual async Task <OperationResult> BuildCreateOrderMessageFromDetailsAsync(OrderProcessorConfiguration configuration, ILogger log, ISkuMetadataProcessor skuMetadataProcessor, string partner, string transactionId, IReadOnlyDictionary <string, string> orderAssets, OrderDetails orderDetails, JsonSerializerSettings serializerSettings, string correlationId = null, OperationResult emulatedResult = null) { OperationResult result; try { if (emulatedResult != null) { result = emulatedResult; } else { // Base the message on the order details that were received. var message = orderDetails.ToCreateOrderMessage(); // Populate the static values message.TransactionId = transactionId; message.Identity.PartnerCode = partner; message.Identity.PartnerSubCode = configuration.PartnerSubCode; message.Identity.PartnerRegionCode = configuration.PartnerSubCode; message.Shipping.ShippingInstruction = ShipWhen.ShipAsItemsAreAvailable; message.Instructions.Priority = OrderPriority.Normal; message.PartnerMetadata = new PartnerOrderMetadata { OrderDateUtc = this.clock.GetCurrentInstant().ToDateTimeUtc() }; // Process the line items against the SKU metadata to generate the necessary line item detail. var itemDetail = new Dictionary <string, string>(); foreach (var item in orderDetails.LineItems) { var itemTemplate = await skuMetadataProcessor.RenderOrderTemplateAsync(new OrderTemplateMetadata { Sku = item.ProductCode, TotalSheets = item.TotalSheetCount, AdditionalSheets = item.AdditionalSheetCount, AssetUrl = ((orderAssets.TryGetValue(item.LineItemId, out var value)) ? value : null), LineItemCount = orderDetails.Recipients.SelectMany(recipient => recipient.OrderedItems).Where(orderedItem => orderedItem.LineItemId == item.LineItemId).Sum(orderedItem => (int)orderedItem.Quantity), NumberOfRecipients = orderDetails.Recipients.Count(recipient => recipient.OrderedItems.Any(orderedItem => orderedItem.LineItemId == item.LineItemId)) }); itemDetail.Add(item.LineItemId, itemTemplate); }