示例#1
0
        public void EmptyYourBasket()
        {
            using (var context = GetContextWithData())
                using (var controller = new BasketController(context))
                {
                    BasketRequest model = new BasketRequest();
                    model.ClientId = "A120";
                    model.Quantity = 1;
                    model.SKU      = "P113";

                    IActionResult result = controller.Add(model);
                    Assert.IsType <OkResult>(result);

                    model          = new BasketRequest();
                    model.ClientId = "A120";
                    model.Quantity = 1;
                    model.SKU      = "P113";

                    result = controller.Add(model);
                    Assert.IsType <OkResult>(result);

                    controller.EmptyBasket("A120");
                    List <BasketRequest> list = (List <BasketRequest>)controller.Get("A120");
                    Assert.True(list.Count == 0);
                }
        }
        public IActionResult Add([FromBody] BasketRequest model)
        {
            BasketResponse response = new BasketResponse();

            response.Error   = BasketError.ModelIsNotValid;
            response.Success = false;

            if (ModelState.IsValid)
            {
                var validationResult = model.Validate();
                if (validationResult == BasketError.NoError)
                {
                    response.Error = new BasketOperations(_context).AddOrUpdateBasketItem(model);
                    if (response.Error == BasketError.NoError)
                    {
                        return(Ok());
                    }
                    else
                    {
                        return(BadRequest(response));
                    }
                }
            }

            return(BadRequest(response));
        }
示例#3
0
        public void CheckAddProductsToABasket()
        {
            using (var context = GetContextWithData())
                using (var controller = new BasketController(context))
                {
                    BasketRequest model = new BasketRequest();
                    model.ClientId = "A120";
                    model.Quantity = 1;
                    model.SKU      = "P113";

                    IActionResult result = controller.Add(model);
                    Assert.IsType <OkResult>(result);

                    model          = new BasketRequest();
                    model.ClientId = "A120";
                    model.Quantity = 1;
                    model.SKU      = "P113";

                    result = controller.Add(model);
                    Assert.IsType <OkResult>(result);

                    List <BasketRequest> list = (List <BasketRequest>)controller.Get("A120");
                    Assert.NotNull(list);
                    Assert.Single(list);
                    Assert.True(list[0].SKU == "P113" && list[0].TotalPrice == 280 && list[0].Quantity == 2);
                }
        }
        public ActionResult <ApiResponse> BasketHandlerWithRedirect([FromBody] BasketRequest request)
        {
            var response = new ApiResponse();

            response.RedirectUrl = "http://example.org";
            return(response);
        }
        public ActionResult <ApiResponse> BasketHandlerWithMessage([FromBody] BasketRequest request)
        {
            var response = new ApiResponse();

            response.Message = $"I received information about a basket named {request.Citation.Title.EnglishUS}. It has {request.ItemIdentifers.Length} items in it.";
            return(response);
        }
示例#6
0
 public override Task <BasketReply> AddBasket(BasketRequest request, ServerCallContext context)
 {
     return(Task.FromResult(new BasketReply
     {
         Message = "Hello " + request.Name
     }));
 }
示例#7
0
        public override async Task <BoolValue> DeleteBasketItemByProductId(BasketRequest request, ServerCallContext context)
        {
            BoolValue status  = new BoolValue();
            var       options = new DistributedCacheEntryOptions()
                                .SetSlidingExpiration(TimeSpan.FromHours(2));
            var userId = _httpContextAccessor.HttpContext.User?.FindFirst(x => x.Type.Equals("sub"))?.Value;

            if (userId != null)
            {
                List <BasketItem> basketItems;
                var basketItemsJson = await _cache.GetStringAsync(userId);

                if (!string.IsNullOrEmpty(basketItemsJson))
                {
                    basketItems = JsonSerializer.Deserialize <List <BasketItem> >(basketItemsJson);
                    var basketItem = basketItems.Where(b => b.ProductId == request.ProductId).SingleOrDefault();
                    if (basketItem != null)
                    {
                        basketItems.Remove(basketItem);
                        var basketItemsSeriliazeJson = JsonSerializer.Serialize(basketItems);
                        await _cache.SetStringAsync(userId, basketItemsSeriliazeJson, options);

                        status.Value = true;
                        return(await Task.FromResult(status));
                    }
                }
            }
            status.Value = false;
            return(await Task.FromResult(status));
        }
示例#8
0
        public async Task <IAsyncResult> AddItem(BasketRequest request, string token)
        {
            var          basketApi = RestService.For <IBasket>(UrlHelpers.BaseUrl);
            IAsyncResult result    = await basketApi.AddItemToBasket(request, token);

            return(result);
        }
示例#9
0
        public override Task <BasketResponse> RemoveFromBasket(BasketRequest request, ServerCallContext context)
        {
            if (request.ProductId.IsEmpty())
            {
                throw new Exception("Invalid product");
            }


            var product = _kernel.GetEntity <eShop.ProductEntities.Entities.Product>(externalId: Guid.Parse(request.ProductId));

            if (product.IsNull())
            {
                throw new Exception("Invalid product");
            }
            else
            {
                var basketProduct = _kernel.GetEntities <eShop.ProductEntities.Entities.Basket>()
                                    .FirstOrDefault(basket => basket.ProductId == product.Id && basket.CreatedById == _audience.EntityId());
                _kernel.DeleteEntity(basketProduct, saveChanges: true);
            }

            return(Task.FromResult(new BasketResponse
            {
                ProductId = product.ExternalId.ToString()
            }));
        }
示例#10
0
        public override Task <BasketResponse> AddToBacket(BasketRequest request, ServerCallContext context)
        {
            if (request.ProductId.IsEmpty())
            {
                throw new Exception("Invalid product");
            }

            var product = _kernel.GetEntity <eShop.ProductEntities.Entities.Product>(externalId: Guid.Parse(request.ProductId));

            if (product.IsNull())
            {
                throw new Exception("Invalid product");
            }
            else
            {
                _kernel.AddEntity <eShop.ProductEntities.Entities.Basket>(new eShop.ProductEntities.Entities.Basket
                {
                    Product = product
                }, saveChanges: true);
            }

            return(Task.FromResult(new BasketResponse
            {
                ProductId = product.ExternalId.ToString()
            }));
        }
示例#11
0
        public async Task OnBasketReceived(BasketRequest basketRequest)
        {
            log.Debug("PosManager: On basket received.");
            if (basketRequest == null || basketRequest.BasketDetail == null)
            {
                log.Error("PosManager: BasketRequest is null or BasketDetail is null.Simply return.");
                return;
            }

            if (isInitialized == false)
            {
                log.Error("PosManager: Pos is not initialized.Enqueue BasketQueue.");
                basketQueue.Enqueue(basketRequest);
                return;
            }

            switch (basketRequest.Type.ToLower())
            {
            case "create":
                await CreateBasket(basketRequest.BasketDetail);

                break;

            case "clear":
                ClearBasket(basketRequest.BasketDetail);
                break;
            }
        }
        public Basket Invoke(BasketRequest request)
        {
            var basket = GetBasket();
            basket.Shipping = _shippingCalculator.CalculateShipping(basket);

            return basket;
        }
示例#13
0
        public Basket Invoke(BasketRequest request)
        {
            var basket = GetBasket();

            basket.Shipping = _shippingCalculator.CalculateShipping(basket);

            return(basket);
        }
示例#14
0
        public async Task <IActionResult> Add([FromBody] BasketRequest basketRequest)
        {
            var newBasket = mapper.Map <Basket>(basketRequest);

            var basket = await basketService.AddAsync(newBasket);

            return(Ok(basket));
        }
示例#15
0
        public async Task <IActionResult> Get([FromQuery] BasketRequest basketRequest)
        {
            var query = _mapper.Map <BasketRequest, BasketQuery>(basketRequest);
            var model = await _mediatr.Send(query);

            var result = _mapper.Map <IList <Domain.Basket>, IList <BasketViewModel> >(model);

            return(result == null || result.Count == 0 ? NotFound("Not Found") : (IActionResult)Ok(result));
        }
示例#16
0
        static async System.Threading.Tasks.Task MainAsync(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.WriteLine("Request a new token...");
            Console.WriteLine("");
            BasketService bs = new BasketService("test1", "test1");
            await bs.CreateToken();

            if (bs != null)
            {
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine("Token");
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(bs.Token);
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine("");
                Console.WriteLine("Token expired date");
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(bs.TokenExpiredDate.ToString());
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Token creation is failed.");
            }

            await ShowProducts(bs.AuthorizationToken);

            Console.WriteLine("");

            BasketRequest request = new BasketRequest();

            request.ClientId = "A300";
            request.SKU      = "A111";
            request.Quantity = 1;
            bool addResult = await bs.AddItem(request);

            if (addResult)
            {
                Console.WriteLine("Add a new item in the basket");
                Console.ForegroundColor = ConsoleColor.White;
                await ShowProducts(bs.AuthorizationToken);
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Add a new item in the basket is failed!");
            }

            await ShowBasket(bs, "A300");

            Console.WriteLine("");
            Console.WriteLine("Done.");
            Console.ReadKey();
        }
        /// <summary>
        /// Return a new basket request.  The basket will have two lines in it, for three items.  Set required and common basket attributes in the header too.
        /// </summary>
        /// <param name="companyKey">The company key which indicates to Promo which company to create the product within.
        /// Company keys are visible in the Administration Portal, within Company Management under Configuration</param>
        /// <returns>A new BasketRequest.</returns>
        public static BasketRequest GetBasketRequest(string companyKey, bool getMissedPromotions)
        {
            BasketRequest basketRequest = new BasketRequest()
            {
                // Required attributes
                CompanyKey   = companyKey,
                SaleDateTime = DateTime.UtcNow,
                Id           = Guid.NewGuid().ToString(), // Each basket must have a unique ID (though where a basket is submitted multiple times it should maintain the same ID).

                // Indicate whether we want to get missed promotions
                GetMissedPromotions = getMissedPromotions,

                // Additional basket attributes
                DeliveryPrice  = 10.99M,
                DeliveryMethod = "NEXTDAY",

                CustomerGroup = "NORMAL",
                Channel       = "RETAIL",
                StoreGroup    = "LONDON",
                Store         = "KINGSTON"
            };

            // We can add basket level custom attributes if needed
            basketRequest.AddCustomAttribute("testbasket", "true");

            // We must have one or mote items in the basket.  A basket item can have a quantity greater than one if required.

            BasketRequestItem basketRequestItem1 = new BasketRequestItem()
            {
                // We must always have a line number, price and quantity, and then a ProductCode and optionally a VariantCode.
                Id          = 1,
                Price       = 27.56M,
                Quantity    = 2,
                ProductCode = "PR-25", // This is the 'adidas Consortium Campus 80s Running Shoes' from the sample product set.
            };

            basketRequest.AddItem(basketRequestItem1);

            BasketRequestItem basketRequestItem2 = new BasketRequestItem()
            {
                Id          = 2,
                Price       = 15.00M,
                Quantity    = 1,
                ProductCode = "PR-29"       // This is the 'Custom T-Shirt' from the sample product set.
            };

            // We can also add custom attributes against an item in the basket if needed
            basketRequestItem1.AddCustomAttribute("message", "This is my t-shirt!");
            basketRequest.AddItem(basketRequestItem2);

            return(basketRequest);
        }
示例#18
0
        public async Task <bool> AddItem(BasketRequest request)
        {
            try
            {
                IAsyncResult result = await bs.AddItem(request, AuthorizationToken);

                return(true);
            }
            catch (Exception ex)
            {
            }
            return(false);
        }
示例#19
0
        public void AddProductToABasket()
        {
            using (var context = GetContextWithData())
                using (var controller = new BasketController(context))
                {
                    BasketRequest model = new BasketRequest();
                    model.ClientId = "A111";
                    model.Quantity = 1;
                    model.SKU      = "P113";

                    IActionResult result = controller.Add(model);
                    Assert.IsType <OkResult>(result);
                }
        }
示例#20
0
        public async Task <BasketResponse> RemoveToBasket([Required] BasketRequest request)
        {
            if (!ModelState.IsValid)
            {
                throw new Exception("Invalid model");
            }
            var response = await GrpcCallerService.CallService(urlGrpc : GRPCUrl.ProductService, logger : _logger, func : async channel =>
            {
                var client = new Basket.BasketClient(channel);
                _logger.LogDebug("Grpc remove backet {@request}", request);
                return(await client.RemoveFromBasketAsync(request));
            });

            return(response);
        }
示例#21
0
        public BasketServiceResponse <Basket> GetBaskets(BasketRequest req, List <ServiceLogRecord> logRecords = null)
        {
            var response = new BasketServiceResponse <Basket>();

            var baskets = new List <Basket>();

            #region [ Envelope settings ]

            // Create the including fields according to the envelope
            var includes = new List <string>();
            includes.Add("BasketItems");

            #endregion

            #region [ Filters ]

            // Check for filters
            Expression <Func <Basket, bool> > filterPredicate = PredicateBuilder.New <Basket>(true);

            // Add the filters
            if (req.BasketIds.Any())
            {
                filterPredicate = filterPredicate.And(r => req.BasketIds.Contains(r.BasketID));
            }
            if (req.UserIds.Any())
            {
                filterPredicate = filterPredicate.And(m => req.UserIds.Contains(m.UserID));
            }

            #endregion

            // Make the query
            if (filterPredicate.Parameters.Count > 0)
            {
                baskets = _basketServiceBase.GetIncluding(filterPredicate, includes.ToArray()).Result;
            }
            else
            {
                baskets = _basketServiceBase.GetAllIncluding(includes.ToArray()).Result;
            }

            response.Type   = Headstone.Common.ServiceResponseTypes.Success;
            response.Result = baskets;

            return(response);
        }
示例#22
0
        public override async Task <CustomerBasketResponse> GetBasketById(BasketRequest request, ServerCallContext context)
        {
            _logger.LogInformation("Begin grpc call from method {Method} for basket id {Id}", context.Method, request.Id);

            var data = await _repository.GetBasketAsync(request.Id);

            if (data != null)
            {
                context.Status = new Status(StatusCode.OK, $"Basket with id {request.Id} do exist");

                return(MapToCustomerBasketResponse(data));
            }
            else
            {
                context.Status = new Status(StatusCode.NotFound, $"Basket with id {request.Id} do not exist");
            }

            return(new CustomerBasketResponse());
        }
示例#23
0
        public void TryAddProductToABasket()
        {
            using (var context = GetContextWithData())
                using (var controller = new BasketController(context))
                {
                    BasketRequest model = new BasketRequest();
                    model.ClientId = "A111";
                    model.Quantity = 1;
                    model.SKU      = "P116";

                    IActionResult result = controller.Add(model);
                    Assert.IsType <BadRequestObjectResult>(result);

                    BasketResponse value = (BasketResponse)((Microsoft.AspNetCore.Mvc.ObjectResult)result).Value;
                    Assert.Equal(BasketError.ProductNotAvailable, value.Error);
                    Assert.False(value.Success);
                    Assert.Equal(0, (int)value.SuccessResult);
                }
        }
示例#24
0
        /// <summary>
        /// Adds the or update basket item.
        /// </summary>
        /// <param name="basketItem">The basket item.</param>
        /// <returns>BasketError.</returns>
        public BasketError AddOrUpdateBasketItem(BasketRequest basketItem)
        {
            BasketError rtn = BasketError.ProductNotAvailable;

            if (po.IsAvailable(basketItem.SKU, basketItem.Quantity))
            {
                Tuple <bool, decimal> update = po.UpdateQuantity(basketItem.SKU, basketItem.Quantity);
                List <BasketRequest>  list   = _context.Baskets.Where(b => b.ClientId.Trim().ToLower() == basketItem.ClientId.Trim().ToLower() &&
                                                                      b.SKU.Trim().ToLower() == basketItem.SKU.Trim().ToLower()).ToList();
                if (list.Count() > 0)
                {
                    if (list.Count == 1)
                    {
                        list.SingleOrDefault().Quantity  += basketItem.Quantity;
                        list.SingleOrDefault().TotalPrice = list.SingleOrDefault().Quantity *update.Item2;
                        _context.SaveChanges();
                        rtn = BasketError.NoError;
                    }
                    else
                    {
                        rtn = BasketError.DuplicatedSKU;
                    }
                }
                else
                {
                    if (update.Item1)
                    {
                        basketItem.TotalPrice += basketItem.Quantity * update.Item2;
                        _context.Baskets.Add(basketItem);
                        _context.SaveChanges();

                        rtn = BasketError.NoError;
                    }
                }
            }

            return(rtn);
        }
示例#25
0
 private async void OnBasketReceived(object sender, BasketRequest basketCommand)
 {
     log.Debug("App: Received basket with basketId:{0}", basketCommand.BasketDetail.BasketID);
     await posManager.OnBasketReceived(basketCommand);
 }
        public static BasketRequest ToQixolPromosBasketRequest(this IList<ShoppingCartItem> cart)
        {
            IProductService _productService = EngineContext.Current.Resolve<IProductService>();
            IPriceCalculationService _priceCalculationService = EngineContext.Current.Resolve<IPriceCalculationService>();
            IWorkContext _workContext = EngineContext.Current.Resolve<IWorkContext>();
            IStoreContext _storeContext = EngineContext.Current.Resolve<IStoreContext>();
            IGenericAttributeService _genericAttributeService = EngineContext.Current.Resolve<IGenericAttributeService>();
            PromoSettings _promoSettings = EngineContext.Current.Resolve<PromoSettings>();
            IPromoUtilities _promoUtilities = EngineContext.Current.Resolve<IPromoUtilities>();
            IOrderTotalCalculationService _orderTotalCalculationService = EngineContext.Current.Resolve<IOrderTotalCalculationService>();
            ICurrencyService _currencyService = EngineContext.Current.Resolve<ICurrencyService>();
            IShoppingCartService _shoppingCartService = EngineContext.Current.Resolve<IShoppingCartService>();
            IProductMappingService _productMappingService = EngineContext.Current.Resolve<IProductMappingService>();
            IAttributeValueService _attributeValueService = EngineContext.Current.Resolve<IAttributeValueService>();
            IShippingService _shippingService = EngineContext.Current.Resolve<IShippingService>();
            ICheckoutAttributeParser _checkoutAttributeParser = EngineContext.Current.Resolve<ICheckoutAttributeParser>();
            ICheckoutAttributeService _checkoutAttributeService = EngineContext.Current.Resolve<ICheckoutAttributeService>();
            IGiftCardService _giftCardService = EngineContext.Current.Resolve<IGiftCardService>();
            ICountryService _countryService = EngineContext.Current.Resolve<ICountryService>();
            IStateProvinceService _stateProvinceService = EngineContext.Current.Resolve<IStateProvinceService>();
            IPluginFinder _pluginFinder = EngineContext.Current.Resolve<IPluginFinder>();

            Customer customer = _workContext.CurrentCustomer;

            var basketResponse = _promoUtilities.GetBasketResponse();

            // remove the previous response
            _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketResponse, null, _storeContext.CurrentStore.Id);

            IList<BasketRequestItem> items = new List<BasketRequestItem>();

            Decimal orderTotal = Decimal.Zero;

            #region remove any items added by promo engine
            // remove any items added by promo engine that were NOT split from the original basket

            // get the selectedShippingOption - if it's not null will need to save this after removing products from the cart
            ShippingOption selectedShippingOption = _workContext.CurrentCustomer.GetAttribute<ShippingOption>(SystemCustomerAttributeNames.SelectedShippingOption, _storeContext.CurrentStore.Id);

            if (basketResponse != null && basketResponse.Items != null)
            {
                var generatedItems = (from bri in basketResponse.Items where bri.SplitFromLineId == 0 && bri.Generated && !bri.IsDelivery select bri).ToList();
                foreach (var generatedItem in generatedItems)
                {
                    int productId = 0;
                    if (!int.TryParse(generatedItem.ProductCode, out productId))
                    {
                        var attributeValueMappingItems = _attributeValueService.RetrieveAllForAttribute(EntityAttributeName.CheckoutAttribute);
                        var attributeValueMappingItem = (from ca in attributeValueMappingItems where ca.Code.Equals((generatedItem.ProductCode ?? string.Empty), StringComparison.InvariantCultureIgnoreCase) select ca).FirstOrDefault();
                        if (attributeValueMappingItems == null)
                            throw new KeyNotFoundException(string.Format("No attributeValueMappingItem for product code {0}", generatedItem.ProductCode));
                    }
                    else
                    {
                        Product product = _productService.GetProductById(productId);

                        ProductMappingItem productMappingItem = _productMappingService.RetrieveFromVariantCode(productId, generatedItem.VariantCode);

                        string attributesXml = string.Empty;

                        if (productMappingItem != null)
                            attributesXml = productMappingItem.AttributesXml;

                        var addedItem = _shoppingCartService.FindShoppingCartItemInTheCart(cart, ShoppingCartType.ShoppingCart, product, attributesXml);
                        if (addedItem != null)
                        {
                            int generatedItemQuantity = Decimal.ToInt32(generatedItem.Quantity);
                            int newQuantity = addedItem.Quantity - generatedItemQuantity;
                            _shoppingCartService.UpdateShoppingCartItem(_workContext.CurrentCustomer, addedItem.Id, addedItem.AttributesXml,
                                addedItem.CustomerEnteredPrice, addedItem.RentalStartDateUtc, addedItem.RentalEndDateUtc, newQuantity, false);
                        }
                    }
                }
            }

            cart = customer.ShoppingCartItems.ToList();

            if (selectedShippingOption != null)
                _genericAttributeService.SaveAttribute<ShippingOption>(_workContext.CurrentCustomer, SystemCustomerAttributeNames.SelectedShippingOption, selectedShippingOption, _storeContext.CurrentStore.Id);

            #endregion

            #region build basket items

            // If we no longer have items in the shopping cart, do not return a basket Request so we don't call Promo unnecessarily
            if (cart.Count < 1)
                return null;

            foreach (var shoppingCartItem in cart)
            {
                Product product = _productService.GetProductById(shoppingCartItem.ProductId);

                string productCode = product.Id.ToString();
                string barcode = product.Gtin;
                string variantCode = string.Empty;

                var productMappingItem = _productMappingService.RetrieveFromShoppingCartItem(shoppingCartItem);
                if (productMappingItem != null)
                    variantCode = productMappingItem.VariantCode;

                // DM Cope with baskets in current currency
                decimal usePrice = _priceCalculationService.GetUnitPrice(shoppingCartItem, includeDiscounts: false);
                if (_promoSettings.UseSelectedCurrencyWhenSubmittingBaskets && _workContext.WorkingCurrency.Rate != 1)
                    usePrice = _currencyService.ConvertFromPrimaryExchangeRateCurrency(usePrice, _workContext.WorkingCurrency);

                BasketRequestItem item = new BasketRequestItem()
                {
                    // Hotfix - 2016-10-17 - START
                    //Barcode = barcode,
                    // Hotfix - 2016-10-17 - END
                    Id = shoppingCartItem.Id,
                    Price = usePrice,
                    ProductCode = productCode,
                    Quantity = (byte)shoppingCartItem.Quantity,
                    VariantCode = variantCode
                };

                items.Add(item);

                // DM Cope with baskets in current currency
                decimal subTotalAmount = _priceCalculationService.GetSubTotal(shoppingCartItem, includeDiscounts: false);
                if (_promoSettings.UseSelectedCurrencyWhenSubmittingBaskets && _workContext.WorkingCurrency.Rate != 1)
                    subTotalAmount = _currencyService.ConvertFromPrimaryExchangeRateCurrency(subTotalAmount, _workContext.WorkingCurrency);

                orderTotal += subTotalAmount;
            }

            #endregion

            #region coupons

            IList<BasketRequestCoupon> coupons = new List<BasketRequestCoupon>();
            string discountcouponcode = customer.GetAttribute<string>(SystemCustomerAttributeNames.DiscountCouponCode);
            if (!string.IsNullOrEmpty(discountcouponcode))
            {
                BasketRequestCoupon coupon = new BasketRequestCoupon()
                {
                    Code = discountcouponcode,
                };
                coupons.Add(coupon);
            }

            #endregion

            #region shipping

            ShippingOption shippingOption = (selectedShippingOption != null ? selectedShippingOption :
                GetDefaultShippingOption(_shippingService, _workContext, _storeContext, _countryService, _stateProvinceService, _genericAttributeService));
            string shippingOptionName = (shippingOption != null ? shippingOption.Name : string.Empty);

            string shippingIntegrationCode = shippingOptionName;

            // Is there an Integration code for the specified shipping option?
            IList<ShippingMethod> shippingMethods = _shippingService.GetAllShippingMethods();
            var specifiedShippingMethod = (from sm in shippingMethods where sm.Name.Equals(shippingOptionName, StringComparison.InvariantCultureIgnoreCase) select sm).FirstOrDefault();
            if (specifiedShippingMethod != null)
            {
                // TODO: why is there a namespace issue here?
                Qixol.Nop.Promo.Core.Domain.AttributeValues.AttributeValueMappingItem integrationMappingItem = _attributeValueService.Retrieve(specifiedShippingMethod.Id, EntityAttributeName.DeliveryMethod);
                if (integrationMappingItem != null && !string.IsNullOrEmpty(integrationMappingItem.Code))
                    shippingIntegrationCode = integrationMappingItem.Code;
            }

            decimal deliveryPrice = 0M;
            string deliveryMethod = string.Empty;

            if (cart.RequiresShipping())
            {
                global::Nop.Core.Domain.Discounts.Discount appliedDiscount = null;                
                deliveryPrice = _orderTotalCalculationService.AdjustShippingRate(selectedShippingOption != null ? selectedShippingOption.Rate : 0M, cart, out appliedDiscount);

                // DM Cope with baskets in current currency
                if (_promoSettings.UseSelectedCurrencyWhenSubmittingBaskets && _workContext.WorkingCurrency.Rate != 1)
                    deliveryPrice = _currencyService.ConvertFromPrimaryExchangeRateCurrency(deliveryPrice, _workContext.WorkingCurrency);

                deliveryMethod = shippingIntegrationCode;
                orderTotal += deliveryPrice;
            }

            #endregion

            #region customer role mapping

            AttributeValueMappingItem customerGroupAttributeValueMappingItem = null;
            string customerGroupIntegrationCode = string.Empty;
            int priority = int.MinValue;
            foreach (CustomerRole customerRole in customer.CustomerRoles)
            {
                AttributeValueMappingItem attributeValueMappingItem = _attributeValueService.Retrieve(customerRole.Id, EntityAttributeName.CustomerRole);
                if (attributeValueMappingItem != null && !string.IsNullOrEmpty(attributeValueMappingItem.Code))
                {
                    if (attributeValueMappingItem.Priority.HasValue)
                    {
                        if (attributeValueMappingItem.Priority.Value > priority)
                        {
                            priority = attributeValueMappingItem.Priority.Value;
                            customerGroupAttributeValueMappingItem = attributeValueMappingItem;
                        }
                    }
                    else
                    {
                        customerGroupAttributeValueMappingItem = attributeValueMappingItem;
                    }
                }
            }

            if (customerGroupAttributeValueMappingItem != null)
            {
                customerGroupIntegrationCode = customerGroupAttributeValueMappingItem.Code;
            }

            #endregion

            #region store mapping

            string storeIntegrationCode = string.Empty;

            AttributeValueMappingItem storeAttributeValueMappingItem = _attributeValueService.Retrieve(_storeContext.CurrentStore.Id, EntityAttributeName.Store);

            if (storeAttributeValueMappingItem != null && !string.IsNullOrEmpty(storeAttributeValueMappingItem.Code))
                storeIntegrationCode = storeAttributeValueMappingItem.Code;

            #endregion

            #region checkout attributes

            string checkoutAttributesXml = _workContext.CurrentCustomer.GetAttribute<string>(SystemCustomerAttributeNames.CheckoutAttributes, _genericAttributeService, _storeContext.CurrentStore.Id);
            List<CheckoutAttribute> checkoutAttributes = _checkoutAttributeParser.ParseCheckoutAttributes(checkoutAttributesXml).ToList();

            int basketItemId = (from i in items orderby i.Id descending select i.Id).FirstOrDefault();

            foreach (CheckoutAttribute checkoutAttribute in checkoutAttributes)
            {
                List<string> checkoutAttributeValueIds = _checkoutAttributeParser.ParseValues(checkoutAttributesXml, checkoutAttribute.Id).ToList();

                decimal priceAdjustment = decimal.Zero;

                foreach (string checkoutAttributeValueId in checkoutAttributeValueIds)
                {
                    int id;
                    if (int.TryParse(checkoutAttributeValueId, out id))
                    {
                        CheckoutAttributeValue checkoutAttributeValue = _checkoutAttributeService.GetCheckoutAttributeValueById(id);

                        if (checkoutAttributeValue.PriceAdjustment > 0)
                        {
                            priceAdjustment += checkoutAttributeValue.PriceAdjustment;
                        }
                    }
                }

                string checkoutAttributeValueVariantCode = null;

                if (checkoutAttributeValueIds.Count == 1)
                {
                    checkoutAttributeValueVariantCode = checkoutAttributeValueIds.First();
                }

                if (priceAdjustment > decimal.Zero)
                {
                    basketItemId++;

                    // DM Cope with baskets in current currency
                    if (_promoSettings.UseSelectedCurrencyWhenSubmittingBaskets && _workContext.WorkingCurrency.Rate != 1)
                        priceAdjustment = _currencyService.ConvertFromPrimaryExchangeRateCurrency(priceAdjustment, _workContext.WorkingCurrency);

                    BasketRequestItem checkoutAttributeBasketItem = new BasketRequestItem()
                    {
                        Id = basketItemId,
                        ProductCode = checkoutAttribute.ProductCode(),
                        VariantCode = checkoutAttributeValueVariantCode,
                        Price = priceAdjustment,
                        Quantity = 1,
                        IsDelivery = false
                    };

                    items.Add(checkoutAttributeBasketItem);

                    orderTotal += priceAdjustment;
                }
            }

            #endregion

            #region gift cards

            // DO NOT APPLY GIFT CARDS at this point
            // as they are a form of tender, only send with a confirmed basket
            // the promo engine needs the full ordertotal for calculations

            #region Applied gift cards

            //decimal resultTemp = orderTotal;
            //List<BasketRequestCustomAttribute> customAttributes = new List<BasketRequestCustomAttribute>();
            //List<AppliedGiftCard> appliedGiftCards = new List<AppliedGiftCard>();

            //if (!cart.IsRecurring())
            //{
            //    //we don't apply gift cards for recurring products
            //    var giftCards = _giftCardService.GetActiveGiftCardsAppliedByCustomer(customer);
            //    if (giftCards != null)
            //    {
            //        foreach (var gc in giftCards)
            //        {
            //            if (resultTemp > decimal.Zero)
            //            {
            //                decimal remainingAmount = gc.GetGiftCardRemainingAmount();
            //                decimal amountCanBeUsed = decimal.Zero;
            //                if (resultTemp > remainingAmount)
            //                    amountCanBeUsed = remainingAmount;
            //                else
            //                    amountCanBeUsed = resultTemp;

            //                //reduce subtotal
            //                resultTemp -= amountCanBeUsed;

            //                var appliedGiftCard = new AppliedGiftCard();
            //                appliedGiftCard.GiftCard = gc;
            //                appliedGiftCard.AmountCanBeUsed = amountCanBeUsed;
            //                appliedGiftCards.Add(appliedGiftCard);
            //            }
            //        }

            //        customAttributes.Add(new BasketRequestCustomAttribute()
            //        {
            //            Name = "giftcardscanbeused",
            //            Value = "true"
            //        });

            //        customAttributes.Add(new BasketRequestCustomAttribute()
            //        {
            //            Name = "giftcardscanbeusedvalue",
            //            Value = appliedGiftCards.Sum(agc => agc.AmountCanBeUsed).ToString()
            //        });
            //    }
            //}

            //if (resultTemp < decimal.Zero)
            //    resultTemp = decimal.Zero;
            ////if (_shoppingCartSettings.RoundPricesDuringCalculation)
            ////    resultTemp = RoundingHelper.RoundPrice(resultTemp);

            //orderTotal = resultTemp;

            #endregion

            #endregion

            #region basket

            var basketUniqueReference = _workContext.CurrentCustomer.GetAttribute<Guid>(PromoCustomerAttributeNames.PromoBasketUniqueReference, _storeContext.CurrentStore.Id);
            if (basketUniqueReference == Guid.Empty)
            {
                basketUniqueReference = Guid.NewGuid();
                _genericAttributeService.SaveAttribute<Guid>(customer, PromoCustomerAttributeNames.PromoBasketUniqueReference, basketUniqueReference, _storeContext.CurrentStore.Id);
            }

            BasketRequest basketRequest = new BasketRequest()
            {
                Id = basketUniqueReference.ToString(),
                CompanyKey = _promoSettings.CompanyKey,
                CustomerId = customer.Id.ToString(),
                BasketTotal = orderTotal,
                SaleDateTime = DateTime.UtcNow,
                Store = storeIntegrationCode,
                StoreGroup = _promoSettings.StoreGroup,
                Channel = _promoSettings.Channel,
                CustomerGroup = customerGroupIntegrationCode,
                DeliveryPrice = deliveryPrice,
                DeliveryMethod = shippingIntegrationCode,
                Coupons = coupons.ToList(),
                Items = items.ToList(),
                //CustomAttributes = customAttributes,
                Confirmed = false,
                CurrencyCode = _workContext.WorkingCurrency != null ? _workContext.WorkingCurrency.CurrencyCode : string.Empty
            };

            // DM Cope with baskets in current currency
            // Add a flag to the basket request indicating whether the values have been passed in customer currency or not.
            //  This will be used when we are extracting values from the cached basket response, but may also be useful on the Promo side in the future (i.e.
            //  when setting up promotions!).
            basketRequest.AddCustomAttribute("incustomercurrency", _promoSettings.UseSelectedCurrencyWhenSubmittingBaskets.ToString());

            // Add identifier for integration source ("nopCommerce")
            var promoPlugin = _pluginFinder.GetPluginDescriptorBySystemName("Misc.QixolPromo");
            basketRequest.AddCustomAttribute("integrationsource", string.Format("nopCommerce - plugin v{0}", promoPlugin.Version));

            string basketRequestString = basketRequest.ToXml();

            _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketRequest, basketRequestString, _storeContext.CurrentStore.Id);

            #endregion

            return basketRequest;
        }
        private BasketResponse SendBasketRequestTopromoService(BasketRequest basketRequest)
        {
            try
            {
                BasketServiceManager basketServiceManager = _promoSettings.GetBasketService();

                if (_promoSettings.LogMessages)
                {
                    var serializedBasketRequestData = basketRequest.ToXml();
                    _logger.InsertLog(global::Nop.Core.Domain.Logging.LogLevel.Information, "Qixol Promos basket request", serializedBasketRequestData, _workContext.CurrentCustomer);
                }

                _genericAttributeService.SaveAttribute<string>(_workContext.CurrentCustomer, PromoCustomerAttributeNames.PromoBasketResponse, null, _storeContext.CurrentStore.Id);

                BasketResponse basketResponse = basketServiceManager.SubmitBasket(basketRequest);

                // Grab from the request whether this basket is being submitted in customer currency or not.  This will then be serialized and saved with the basket response.
                var inCustomerCurrencyAttrib = basketRequest.CustomAttributes.Where(ca => string.Compare(ca.Name, "incustomercurrency", true) == 0).FirstOrDefault();
                if (inCustomerCurrencyAttrib != null && !string.IsNullOrEmpty(inCustomerCurrencyAttrib.Value))
                {
                    bool inCustomerCurrency = false;
                    bool.TryParse(inCustomerCurrencyAttrib.Value, out inCustomerCurrency);

                    if (inCustomerCurrency)
                        ConvertResponseFromCurrency(basketResponse, basketRequest.CurrencyCode);
                }

                var serializedBasketResponseData = basketResponse.ToXml();
                if (_promoSettings.LogMessages)
                {
                    _logger.InsertLog(global::Nop.Core.Domain.Logging.LogLevel.Information, "Qixol Promos basket response", serializedBasketResponseData, _workContext.CurrentCustomer);
                }

                _genericAttributeService.SaveAttribute<string>(_workContext.CurrentCustomer, PromoCustomerAttributeNames.PromoBasketResponse, serializedBasketResponseData, _storeContext.CurrentStore.Id);
            }
            catch (Exception ex)
            {
                _logger.Error("Failed in SendBasketRequestToPromoService", ex, _workContext.CurrentCustomer);
                _logger.InsertLog(global::Nop.Core.Domain.Logging.LogLevel.Information, "SendBasketRequestToPromoService", basketRequest.ToXml(), _workContext.CurrentCustomer);
            }

            return _promoUtilities.GetBasketResponse();

        }