private OrderDetailsViewModel.DeliveryItem BuildDeliveryRow(OrderOverview orderOverview, ShippingInfo shippingInfo, bool includeVat, Currency currency)
        {
            var shipmentRows = orderOverview.Shipments?.SelectMany(x => x.Rows.Where(y => y.ShippingInfoSystemId.GetValueOrDefault() == shippingInfo.SystemId));
            var shipmentCost = shipmentRows == null ? 0 :
                               includeVat?shipmentRows.Select(x => x.TotalIncludingVat).Sum() : shipmentRows.Select(x => x.TotalExcludingVat).Sum();

            var order              = orderOverview.SalesOrder;
            var channel            = _channelService.Get(order.ChannelSystemId.Value);
            var shippingOptionName = string.Empty;

            if (channel is not null)
            {
                var country     = _countryService.Get(order.CountryCode);
                var countryLink = channel.CountryLinks.FirstOrDefault(x => x.CountrySystemId == country.SystemId);

                if (shippingInfo != null)
                {
                    shippingOptionName = countryLink?.ShippingOptions.FirstOrDefault(x => x.Id.Equals(shippingInfo.ShippingOption))?.Name;
                }
            }

            var model = new OrderDetailsViewModel.DeliveryItem
            {
                DeliveryId           = shippingInfo.SystemId,
                DeliveryMethodTitle  = shippingOptionName,
                DeliveryRowTotalCost = currency.Format(shipmentCost, true, CultureInfo.CurrentUICulture)
            };

            model.Address.MapFrom(shippingInfo.ShippingAddress);

            return(model);
        }
        /// <summary>
        ///     Validates the specified order carrier.
        /// </summary>
        /// <param name="orderCarrier">The order carrier.</param>
        /// <param name="checkoutFlowInfo">The checkout flow info.</param>
        public void Validate(OrderCarrier orderCarrier, CheckoutFlowInfo checkoutFlowInfo)
        {
            //get allowed delivery methods, if configuration is missing, consider all delivery methods as allowed.
            var allowedDeliveryMethodIDs = _channelService.Get(orderCarrier.ChannelID)?.CountryLinks?.FirstOrDefault(x => x.CountrySystemId == orderCarrier.CountryID)?.DeliveryMethodSystemIds ??
                                           _moduleECommerce.DeliveryMethods.GetAll().Select(x => x.ID).ToList();

            foreach (var delivery in orderCarrier.Deliveries)
            {
                var deliveryMethod = _moduleECommerce.DeliveryMethods.Get(delivery.DeliveryMethodID, _moduleECommerce.AdminToken);
                if (deliveryMethod != null && allowedDeliveryMethodIDs.Contains(deliveryMethod.ID))
                {
                    continue;
                }

                if (allowedDeliveryMethodIDs.Count > 0)
                {
                    var payload = new DeliveryPayloadInfo
                    {
                        DeliveryAddress  = delivery.Address,
                        DeliveryMethodId = allowedDeliveryMethodIDs[0]
                    };
                    _moduleECommerce.CheckoutFlow.EditDelivery(orderCarrier, delivery.ID, payload, _moduleECommerce.AdminToken);
                }
                throw new PreOrderValidationException("accelerator.validation.deliverymethod.nolongersupported".AsAngularResourceString());
            }
        }
Example #3
0
        /// <summary>
        ///     Validates the specified order carrier.
        /// </summary>
        /// <param name="orderCarrier">The order carrier.</param>
        /// <param name="checkoutFlowInfo">The checkout flow info.</param>
        public void Validate(OrderCarrier orderCarrier, CheckoutFlowInfo checkoutFlowInfo)
        {
            //get allowed payment methods, if configuration is missing, consider all payment methods as allowed.
            var allowedPaymentMethodIDs = _channelService.Get(orderCarrier.ChannelID)?.CountryLinks?.FirstOrDefault(x => x.CountrySystemId == orderCarrier.CountryID)?.PaymentMethodSystemIds ??
                                          _moduleECommerce.PaymentMethods.GetAll().Select(x => x.ID).ToList();

            foreach (var paymentInfo in orderCarrier.PaymentInfo)
            {
                var paymentMethod = _moduleECommerce.PaymentMethods.Get(paymentInfo.PaymentMethod, paymentInfo.PaymentProvider, _moduleECommerce.AdminToken);
                if (paymentMethod != null && allowedPaymentMethodIDs.Contains(paymentMethod.ID))
                {
                    continue;
                }

                if (allowedPaymentMethodIDs.Count > 0)
                {
                    var defaultPaymentmethod = _moduleECommerce.PaymentMethods.Get(allowedPaymentMethodIDs[0], _moduleECommerce.AdminToken);
                    if (defaultPaymentmethod != null)
                    {
                        _moduleECommerce.CheckoutFlow.AddPaymentInfo(orderCarrier, defaultPaymentmethod.PaymentProviderName, defaultPaymentmethod.Name, paymentInfo.BillingAddress, _moduleECommerce.AdminToken);
                    }
                }
                throw new PreOrderValidationException("accelerator.validation.paymentmethod.nolongersupported".AsAngularResourceString());
            }
        }
Example #4
0
        public virtual List <DeliveryMethodViewModel> Build(string countryCode, string currencyCode)
        {
            var currency = _currencyService.Get(currencyCode);

            if (currency == null)
            {
                return(new List <DeliveryMethodViewModel>());
            }
            var countrySystemId = _countryService.Get(countryCode)?.SystemId;
            var channelSystemId = _requestModelAccessor.RequestModel.ChannelModel?.Channel?.SystemId;

            List <DeliveryMethodViewModel> deliveryMethods = new List <DeliveryMethodViewModel>();
            var channel = _channelService.Get(channelSystemId.HasValue ? channelSystemId.Value : Guid.Empty);

            foreach (var shippingOption in channel?.CountryLinks?.Where(x => x.CountrySystemId == countrySystemId)?.SelectMany(x => x.ShippingOptions))
            {
                var fee = shippingOption.Fee ?? 0m;
                deliveryMethods.Add(new DeliveryMethodViewModel
                {
                    Id             = shippingOption.Id,
                    FormattedPrice = currency.Format(shippingOption.Fee ?? 0, true, CultureInfo.CurrentCulture),
                    Name           = string.IsNullOrWhiteSpace(shippingOption.Name) ? shippingOption.Id.ToString() : shippingOption.Name,
                    Price          = shippingOption.Fee
                });
            }

            return(deliveryMethods);
        }
Example #5
0
        public void Setup(GlobalModel globalModel, Guid?pageSystemId)
        {
            var channel = _channelService.Get(globalModel.ChannelSystemId);

            _requestModelAccessor.RequestModel = new RequestModelImpl(_httpContextAccessor.HttpContext.GetCartContext(),
                                                                      _countryService)
            {
                _channelModel     = new Lazy <ChannelModel>(() => channel.MapTo <ChannelModel>()),
                _searchQuery      = new Lazy <SearchQuery>(() => default), //filterContext.HttpContext.MapTo<SearchQuery>()),
        public override IEnumerable <(CultureInfo, IDocument)> BuildIndexDocuments(IndexQueueItem item)
        {
            var page = _pageService.Get(item.SystemId);

            if (page == null)
            {
                yield break;
            }

            var cultureContentCache = new ConcurrentDictionary <CultureInfo, ISet <string> >();
            var permissions         = _searchPermissionService.GetPermissions(page);
            var blocks  = page.Blocks.Items.SelectMany(x => x.Items).Select(y => _blockService.Get(((BlockItemLink)y).BlockSystemId)).ToList();
            var isBrand = false;
            var isNews  = false;

            if (_keyLookupService.TryGetId <PageFieldTemplate>(page.FieldTemplateSystemId, out var templateId))
            {
                isBrand = PageTemplateNameConstants.Brand.Equals(templateId, StringComparison.OrdinalIgnoreCase);
                isNews  = PageTemplateNameConstants.News.Equals(templateId, StringComparison.OrdinalIgnoreCase);
            }

            foreach (var channelLink in page.ChannelLinks)
            {
                var channel = _channelService.Get(channelLink.ChannelSystemId);
                if (channel is null)
                {
                    // Orphaned category link exists, skip to create new index document.
                    continue;
                }

                var cultureInfo = _languageService.Get(channel.WebsiteLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                if (cultureInfo is null)
                {
                    // Channel does not have a culture.
                    continue;
                }

                var localization = page.Localizations[cultureInfo];
                yield return(cultureInfo, new PageDocument
                {
                    PageSystemId = page.SystemId,
                    Content = cultureContentCache.GetOrAdd(cultureInfo, _ => _contentBuilderService.BuildContent <PageFieldTemplate, WebsiteArea>(page.FieldTemplateSystemId, cultureInfo, page.Fields)),
                    PublishDateTime = page.PublishedAtUtc ?? DateTimeOffset.MinValue,
                    Name = localization.Name,
                    ChannelSystemId = channel.SystemId,
                    WebsiteSystemId = page.WebsiteSystemId,
                    ChannelStartDateTime = channelLink.StartDateTimeUtc ?? DateTimeOffset.MinValue,
                    ChannelEndDateTime = channelLink.EndDateTimeUtc ?? DateTimeOffset.MaxValue,
                    Permissions = permissions,
                    Blocks = GetBlocks(blocks, cultureInfo, channel.SystemId),
                    IsBrand = isBrand,
                    IsNews = isNews,
                    NewsDate = isNews ? page.Fields.GetValue <DateTimeOffset>(PageFieldNameConstants.NewsDate) : DateTimeOffset.MinValue,
                    ParentPages = GetParenPages(page)
                });
            }
        }
        public ActionResult ExportPackage(DeploymentViewModel.ExportViewModel exportForm)
        {
            var model = _deploymentViewModelBuilder.Build(ShowExport());

            if (!Guid.TryParse(exportForm.ChannelSystemId, out var channelSystemId) ||
                !Guid.TryParse(exportForm.FolderSystemId, out var folderSystemId))
            {
                return(View(nameof(Index), model));
            }

            var channel = _channelService.Get(channelSystemId);

            _package.Type = channel.Localizations.CurrentCulture.Name.Replace(" ", "");
            var website = _websiteService.Get(channel.WebsiteSystemId.GetValueOrDefault());

            var assortment = GetAssortment(channel);

            if (assortment == null)
            {
                return(View(nameof(Index), model));
            }

            var deliveryMethodCarriers = ModuleECommerce.Instance.DeliveryMethods.GetAll().Select(x => x.GetAsCarrier()).ToList();
            var paymentMethodCarriers  = ModuleECommerce.Instance.PaymentMethods.GetAll().Select(paymentMethod => paymentMethod.GetAsCarrier()).ToList();

            var structureInfo = _packageService.Export(new PackageInfo
            {
                Assortment      = assortment,
                Folder          = _folderService.Get(folderSystemId),
                Channel         = channel,
                Website         = website,
                DeliveryMethods = deliveryMethodCarriers,
                PaymentMethods  = paymentMethodCarriers,
            });

            _package.PersistStructureInfo(structureInfo);

            model.ExportMessage = "accelerator.deployment.export.success".AsAngularResourceString();

            return(View(nameof(Index), model));
        }
Example #8
0
        private void BuildPrices(VariantInfo pageModel, Variant entity, Currency currency, Guid channelSystemId)
        {
            var channel           = _channelService.Get(channelSystemId);
            var productPriceModel = _priceModelBuilder.Build(entity, currency, channel);

            if (productPriceModel.Price == null)
            {
                return;
            }
            pageModel.ListPrice            = productPriceModel.Price.Price;
            pageModel.VatPercentage        = productPriceModel.Price.VatPercentage;
            pageModel.CampaignPriceWithVat = productPriceModel.CampaignPrice.PriceWithVat;
        }
Example #9
0
        private bool IncludeVat(Cart cart)
        {
            if (cart.Order.ChannelSystemId.HasValue)
            {
                var channel = _channelService.Get(cart.Order.ChannelSystemId.Value);
                if (channel != null)
                {
                    return(channel.ShowPricesWithVat);
                }
            }

            return(_requestModelAccessor.RequestModel.ChannelModel.Channel.ShowPricesWithVat);
        }
Example #10
0
        public async void Get_null_record()
        {
            var mock = new ServiceMockFacade <IChannelRepository>();

            mock.RepositoryMock.Setup(x => x.Get(It.IsAny <string>())).Returns(Task.FromResult <Channel>(null));
            var service = new ChannelService(mock.LoggerMock.Object,
                                             mock.RepositoryMock.Object,
                                             mock.ModelValidatorMockFactory.ChannelModelValidatorMock.Object,
                                             mock.BOLMapperMockFactory.BOLChannelMapperMock,
                                             mock.DALMapperMockFactory.DALChannelMapperMock);

            ApiChannelResponseModel response = await service.Get(default(string));

            response.Should().BeNull();
            mock.RepositoryMock.Verify(x => x.Get(It.IsAny <string>()));
        }
        private void BuildPrices(VariantInfo pageModel, Variant entity, Currency currency, Guid channelSystemId)
        {
            var channel     = _channelService.Get(channelSystemId);
            var cartContext = _cartContextAccessor.CartContext;
            var country     = (cartContext == null) ? _requestModelAccessor.RequestModel.CountryModel.Country
                                                : _countryService.Get(cartContext.CountryCode);
            var productPriceModel = _priceModelBuilder.Build(entity, currency, channel, country);

            if (productPriceModel.Price == null)
            {
                return;
            }
            pageModel.ListPrice            = productPriceModel.Price.Price;
            pageModel.VatPercentage        = productPriceModel.Price.VatPercentage;
            pageModel.CampaignPriceWithVat = productPriceModel.CampaignPrice.PriceWithVat;
        }
        public virtual string GetPaymentInfoDescription(Guid deliveryMethodId, Guid channelId)
        {
            var method = moduleECommerce.DeliveryMethods.Get(deliveryMethodId, SecurityToken.CurrentSecurityToken);

            if (method == null)
            {
                return(null);
            }

            var channel = channelService.Get(channelId);

            if (channel == null || channel.WebsiteLanguageSystemId == null)
            {
                return(null);
            }

            return(method.GetDisplayName((Guid)channel.WebsiteLanguageSystemId));
        }
Example #13
0
        public override IEnumerable <(CultureInfo, IDocument)> BuildIndexDocuments(IndexQueueItem item)
        {
            var category = _categoryService.Get(item.SystemId);

            if (category == null)
            {
                yield break;
            }

            var cultureContentCache = new ConcurrentDictionary <CultureInfo, ISet <string> >();
            var permissions         = _searchPermissionService.GetPermissions(category);

            foreach (var channelLink in category.ChannelLinks)
            {
                var channel = _channelService.Get(channelLink.ChannelSystemId);
                if (channel is null)
                {
                    // Orphaned category link exists, skip to create new index document.
                    continue;
                }

                var cultureInfo = _languageService.Get(channel.WebsiteLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                if (cultureInfo is null)
                {
                    // Channel does not have a culture.
                    continue;
                }

                var localization = category.Localizations[cultureInfo];
                yield return(cultureInfo, new CategoryDocument
                {
                    CategorySystemId = category.SystemId,
                    Content = cultureContentCache.GetOrAdd(cultureInfo, _ => _contentBuilderService.BuildContent <CategoryFieldTemplate, ProductArea>(category.FieldTemplateSystemId, cultureInfo, category.Fields)),
                    Name = localization.Name,
                    ChannelSystemId = channel.SystemId,
                    Permissions = permissions,
                    Assortment = category.AssortmentSystemId,
                    Organizations = category.Fields.GetValue <IList <PointerItem> >(ProductFieldNameConstants.OrganizationsPointer)?.Select(x => x.EntitySystemId).ToHashSet()
                                    ?? new HashSet <Guid> {
                        Guid.Empty
                    }
                });
            }
        }
        private string GetOrderConfirmationPageUrl(SalesOrder order)
        {
            var channel     = _channelService.Get(order.ChannelSystemId.GetValueOrDefault());
            var website     = _websiteService.Get(channel.WebsiteSystemId.GetValueOrDefault());
            var pointerPage = website.Fields.GetValue <PointerPageItem>(AcceleratorWebsiteFieldNameConstants.OrderConfirmationPage);

            if (pointerPage == null)
            {
                throw new CheckoutException("Order is created, order confirmation page is missing.");
            }

            var channelSystemId = pointerPage.ChannelSystemId != Guid.Empty ? pointerPage.ChannelSystemId : order.ChannelSystemId.Value;
            var url             = _urlService.GetUrl(_pageService.Get(pointerPage.EntitySystemId), new PageUrlArgs(channelSystemId));

            if (string.IsNullOrEmpty(url))
            {
                throw new CheckoutException("Order is created, order confirmation page is missing.");
            }

            return($"{url}?orderId={order.SystemId}");
        }
        public virtual List <PaymentOptionViewModel> Build(CartContext cartContext)
        {
            var paymentOptions = new List <PaymentOptionViewModel>();

            if (cartContext != null)
            {
                var channel         = _channelService.Get(cartContext.ChannelSystemId.GetValueOrDefault());
                var countrySystemId = _countryService.Get(cartContext.CountryCode)?.SystemId;
                var currency        = _currencyService.Get(cartContext.CurrencyCode);

                foreach (var paymentOption in channel?.CountryLinks?.Where(x => x.CountrySystemId == countrySystemId)?.SelectMany(x => x.PaymentOptions))
                {
                    paymentOptions.Add(new PaymentOptionViewModel
                    {
                        Id             = paymentOption.Id,
                        FormattedPrice = currency?.Format(paymentOption.Fee ?? 0m, true, CultureInfo.CurrentCulture),
                        Name           = string.IsNullOrWhiteSpace(paymentOption.Name) ? paymentOption.Id.ToString() : paymentOption.Name,
                        Price          = paymentOption.Fee
                    });
                }
            }
            return(paymentOptions);
        }
Example #16
0
        public void UpdatePropertyReferences(StructureInfo structureInfo, PackageInfo packageInfo)
        {
            var website = _websiteService.Get(structureInfo.Id(packageInfo.Website.SystemId)).MakeWritableClone();

            AddProperties <WebsiteArea>(structureInfo, structureInfo.Website.Website.Fields, website.Fields, false);
            _websiteService.Update(website);

            var channel = _channelService.Get(packageInfo.Channel.SystemId).MakeWritableClone();

            channel.CountryLinks = structureInfo.Website.Channel.CountryLinks.Select(x => new ChannelToCountryLink(structureInfo.Id(x.CountrySystemId))
            {
                DeliveryMethodSystemIds = x.DeliveryMethodSystemIds.Select(z => ModuleECommerce.Instance.DeliveryMethods.Get(packageInfo.DeliveryMethods.Find(zz => zz.ID == z)?.Name ?? string.Empty, ModuleECommerce.Instance.AdminToken)?.ID ?? Guid.Empty).Where(z => z != Guid.Empty).ToList(),
                PaymentMethodSystemIds  = x.PaymentMethodSystemIds.Select(z =>
                {
                    var payment = packageInfo.PaymentMethods.Find(zz => zz.ID == z);
                    if (payment == null)
                    {
                        return(Guid.Empty);
                    }
                    return(ModuleECommerce.Instance.PaymentMethods.Get(payment.Name, payment.PaymentProviderName, ModuleECommerce.Instance.AdminToken)?.ID ?? Guid.Empty);
                }).Where(z => z != Guid.Empty).ToList(),
            }).ToList();
            AddProperties <GlobalizationArea>(structureInfo, structureInfo.Website.Channel.Fields, channel.Fields, false, new List <string> {
                SystemFieldDefinitionConstants.Name
            });
            _channelService.Update(channel);

            var inventory = _inventoryService.Get(packageInfo.Inventory.SystemId).MakeWritableClone();

            inventory.CountryLinks = structureInfo.ProductCatalog.Inventory.CountryLinks.Select(x => new InventoryToCountryLink(structureInfo.Id(x.CountrySystemId))).ToList();
            _inventoryService.Update(inventory);

            var priceList = _priceListService.Get(packageInfo.PriceList.SystemId).MakeWritableClone();

            priceList.CountryLinks = structureInfo.ProductCatalog.PriceList.CountryLinks.Select(x => new PriceListToCountryLink(structureInfo.Id(x.CountrySystemId))).ToList();
            _priceListService.Update(priceList);
        }
        public override IEnumerable <(CultureInfo, IDocument)> BuildIndexDocuments(IndexQueueItem item)
        {
            var channels = _channelService.GetAll().Where(x => x.ProductLanguageSystemId.HasValue && x.ProductLanguageSystemId.Value != Guid.Empty).ToList();

            var baseProduct = _baseProductService.Get(item.SystemId);

            if (baseProduct == null)
            {
                // Product is removed.
                // BuildRemoveIndexDocuments will be invoked by the removing of product.
                yield break;
            }

            var productFieldTemplate = _fieldTemplateService.Get <ProductFieldTemplate>(baseProduct.FieldTemplateSystemId);

            if (productFieldTemplate == null)
            {
                // Field template is removed, all products with this template is also removed.
                // BuildRemoveIndexDocuments will be invoked by the removing of product.
                yield break;
            }

            var displayTemplate = _displayTemplateService.Get <ProductDisplayTemplate>(productFieldTemplate.DisplayTemplateSystemId);

            if (displayTemplate == null)
            {
                // Display template is removed, all products with template that using the display template is also removed.
                // BuildRemoveIndexDocuments will be invoked by the removing of product.
                yield break;
            }

            var variants = _variantService.GetByBaseProduct(baseProduct.SystemId).ToList();

            if (variants.Count == 0)
            {
                // No variants exists for the BaseProduct, remove any existing document from index
                foreach (var channel in channels.GroupBy(x => x.ProductLanguageSystemId))
                {
                    var cultureInfo = _languageService.Get(channel.First().ProductLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                    if (cultureInfo is null)
                    {
                        continue;
                    }
                    yield return(cultureInfo, RemoveByFieldDocument.Create <ProductDocument, Guid>(x => x.BaseProductSystemId, item.SystemId));
                }
                yield break;
            }

            var productDocuments     = CreateModelsPerChannel(baseProduct, productFieldTemplate, displayTemplate, ref variants);
            var usedVariantSystemIds = productDocuments.SelectMany(x => x.VariantSystemIds).ToHashSet();
            var usedChannelSystemIds = productDocuments.Select(x => x.ChannelSystemId).ToHashSet();

            // Remove all documents for all channel-combinations
            foreach (var channel in channels.Where(x => !usedChannelSystemIds.Contains(x.SystemId)))
            {
                var cultureInfo = _languageService.Get(channel.ProductLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                if (cultureInfo is null)
                {
                    continue;
                }

                yield return(cultureInfo, new RemoveDocument(new ProductDocument {
                    ArticleNumber = baseProduct.Id, ChannelSystemId = channel.SystemId
                }));

                foreach (var variant in variants)
                {
                    yield return(cultureInfo, new RemoveDocument(new ProductDocument {
                        ArticleNumber = variant.Id, ChannelSystemId = channel.SystemId
                    }));
                }
            }

            var context = new Context(_contentBuilderService)
            {
                BaseProduct   = baseProduct,
                UsedVariants  = variants.Where(x => usedVariantSystemIds.Contains(x.SystemId)).ToList(),
                Permissions   = _searchPermissionService.GetPermissions(baseProduct),
                FieldTemplate = productFieldTemplate
            };

            context.Prices = BuildPriceData(context);

            foreach (var model in productDocuments)
            {
                var currentVariants = variants.Where(x => model.VariantSystemIds.Contains(x.SystemId)).ToList();
                var channel         = _channelService.Get(model.ChannelSystemId);
                if (channel is null)
                {
                    // Orphaned category link exists, skip to create new index document.
                    continue;
                }

                var cultureInfo = _languageService.Get(channel.ProductLanguageSystemId.GetValueOrDefault())?.CultureInfo;
                if (cultureInfo is null || currentVariants.Count == 0)
                {
                    // Channel does not have a culture or we don't have any variants in this channel.
                    continue;
                }

                PopulateProductDocument(model, cultureInfo, currentVariants, context, !displayTemplate.UseVariantUrl);
                yield return(cultureInfo, model);
            }
        }
        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);
            }
        }