protected SearchResult Transform(SearchQuery searchQuery, int totalHitCount, Func <IEnumerable <SearchResultItem> > transformResultFunc) { return(new SearchResult { Items = new Lazy <IEnumerable <SearchResultItem> >(() => { _targetGroupEngine.Process(new SearchEvent { SearchText = searchQuery.Text, TotalHits = totalHitCount }); return transformResultFunc(); }), PageSize = searchQuery.PageSize.GetValueOrDefault(100000), Total = totalHitCount }); }
public void PlaceOrder([NotNull] IPaymentWidgetOrder paymentWidgetOrder, bool isConfirmation) { this.Log().Debug("Provider order status {providerOrderStatus}.", paymentWidgetOrder.OrderStatus); Order order = null; OrderCarrier orderCarrier = null; if (paymentWidgetOrder.IsCompleted) { using (_distributedLockService.AcquireLock($"{nameof(PaymentWidgetService)}:{paymentWidgetOrder.ProviderOrderId}", TimeSpan.FromMinutes(1))) { //there is a time gap between when we last fetched order from Klarna to the time of aquiring the distributed lock. //just before the distributed lock was taken by this machine (but after this machine had fetched checkout order from klarna), //another machine in the server farm may have got the lock, and created the order and exited releasing the distributed lock. //That would cause this machine to aquire the lock, but we cannot use the existing checkoutorder because its out-dated. //therefore we have to refetch it one more time!. paymentWidgetOrder.Refresh(); if (paymentWidgetOrder.IsCompleted) { //save the order only if it is not saved already. order = TryFindOrder(); if (order == null) { this.Log().Debug("Create order."); // Replace the order carrier in the session from the one received from Klarna plugin. // The order carrier contains the inforamtion of the order that will be created. _cartAccessor.Cart.OrderCarrier = paymentWidgetOrder.OrderCarrier; var channel = _channelService.Get(_cartAccessor.Cart.OrderCarrier.ChannelID); if (channel?.WebsiteLanguageSystemId != null) { CultureInfo.CurrentUICulture = _languageService.Get(channel.WebsiteLanguageSystemId.Value)?.CultureInfo ?? CultureInfo.CurrentUICulture; } order = _cartAccessor.Cart.PlaceOrder(_securityToken, out var paymentInfos); this.Log().Debug("Order created, order id {orderId}, external order id {externalOrderId}.", order.ID, order.ExternalOrderID); } var paymentInfo = order.PaymentInfo.FirstOrDefault(x => x.PaymentProviderName == paymentWidgetOrder.PaymentProviderName); if (paymentInfo != null) { // If the Litium call to payment provider to "notify order created" fails, the payment will be in following states. // so execute payment need to be called again, to notify klarna of Litium order id. if (paymentInfo.PaymentStatus == PaymentStatus.Init || paymentInfo.PaymentStatus == PaymentStatus.ExecuteReserve || paymentInfo.PaymentStatus == PaymentStatus.Pending) { var checkoutFlowInfo = _cartAccessor.Cart.CheckoutFlowInfo; checkoutFlowInfo.SetValue("ProviderOrderIsCreated", true); var channel = _channelService.Get(order.ChannelID); CultureInfo.CurrentUICulture = _languageService.Get(channel.WebsiteLanguageSystemId.GetValueOrDefault())?.CultureInfo ?? CultureInfo.CurrentUICulture; checkoutFlowInfo.SetValue(CheckoutConstants.ClientLanguage, CultureInfo.CurrentUICulture.Name); checkoutFlowInfo.SetValue(CheckoutConstants.ClientTwoLetterISOLanguageName, CultureInfo.CurrentUICulture.TwoLetterISOLanguageName); this.Log().Debug("Execute payment."); var result = paymentInfo.ExecutePayment(checkoutFlowInfo, _securityToken); checkoutFlowInfo.SetValue(CheckoutConstants.ExecutePaymentResult, result); this.Log().Debug($"Payment executed{(result.Success ? string.Empty : " with error: " + result.ErrorMessage)}."); // The order carrier has changed, refetch the checkoutOrder with updated data. orderCarrier = order.GetAsCarrier(true, true, true, true, true, true); paymentWidgetOrder.Update(orderCarrier); this.Log().Debug("Provider order status changed to {providerOrderStatus}.", paymentWidgetOrder.OrderStatus); } } } } } if (isConfirmation && paymentWidgetOrder.IsCreated) { var placedOrder = order ?? TryFindOrder(); if (placedOrder != null) { _cartAccessor.Cart.OrderCarrier = orderCarrier ?? placedOrder.GetAsCarrier(true, true, true, true, true, true); if (order == null) { this.Log().Debug("Processing target group event for external order id {externalOrderId}.", placedOrder.ExternalOrderID); _targetGroupEngine.Process(new OrderEvent { Order = placedOrder }); } else { this.Log().Debug("Target group processing for external order id {externalOrderId} was executed with the order creation.", placedOrder.ExternalOrderID); } } } Order TryFindOrder() { var checkoutOrderCarrier = paymentWidgetOrder.OrderCarrier; var hasExternalOrderId = !string.IsNullOrEmpty(checkoutOrderCarrier.ExternalOrderID); var foundOrder = hasExternalOrderId ? _moduleECommerce.Orders.GetOrder(checkoutOrderCarrier.ExternalOrderID, _securityToken) : _moduleECommerce.Orders.GetOrder(checkoutOrderCarrier.ID, _securityToken); if (foundOrder == null) { if (hasExternalOrderId) { this.Log().Debug("No order exists for external order external id {externalOrderId}.", checkoutOrderCarrier.ExternalOrderID); } else { this.Log().Debug("No order exists for order id {orderId}.", checkoutOrderCarrier.ID); } var transactionNumber = checkoutOrderCarrier.PaymentInfo.FirstOrDefault()?.TransactionNumber; if (!string.IsNullOrEmpty(transactionNumber)) { this.Log().Debug("Try to find order based on transactionNumber {transactionNumber}.", transactionNumber); foundOrder = _moduleECommerce.Orders.GetOrdersByTransactionNumber(paymentWidgetOrder.PaymentProviderName, transactionNumber, _securityToken).FirstOrDefault(); if (foundOrder == null) { this.Log().Debug("No order based on transactionNumber {transactionNumber} was found.", transactionNumber); } } else { this.Log().Debug("No transaction number exists, or payment info missing. No order was found."); } } if (foundOrder != null) { this.Log().Debug("Persisted order is found, order id {orderId}, external order id {externalOrderId}.", foundOrder.ID, foundOrder.ExternalOrderID); } return(foundOrder); } }