Exemple #1
0
        public decimal CalculateTax(string countryCode, int?regionId, int?taxClassId, decimal price)
        {
            TaxZone taxZone = taxZoneService.Find(countryCode, regionId);

            if (taxZone == null)
            {
                return(0m);
            }

            return(taxRateService.CalculateTax(taxZone.Id, taxClassId, price));
        }
        public ActionResult Checkout(ShoppingCartCheckoutViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(JsonValidationError());
            }

            // Get cart contents
            ShoppingCart cart = GetOrCreateCart();

            if (!cart.ShoppingCartItems.Any())
            {
                return(JsonError("Your shopping cart is empty!"));
            }

            // Check quantity
            foreach (ShoppingCartItem cartItem in cart.ShoppingCartItems)
            {
                Product product = db.Products.Find(cartItem.ProductId);
                int?    qty     = null;
                if (cartItem.ProductSkuId.HasValue && cartItem.ProductSku.Quantity.HasValue)
                {
                    qty = cartItem.ProductSku.Quantity.Value;
                }
                if (qty == null && product.Quantity.HasValue)
                {
                    qty = product.Quantity.Value;
                }
                if (qty.HasValue && qty < cartItem.Quantity)
                {
                    return(JsonError(string.Format("The requested quantity for \"{0}\" is not available", product.Name)));
                }
            }

            // Get current user (or create a new one)
            User user = null;

            if (User.Identity.IsAuthenticated)
            {
                user = customerService.Find(currentUser.User.Id);
            }
            if (user == null)
            {
                var userModel = new CustomerViewModel
                {
                    FirstName   = model.BillingAddress.FirstName,
                    LastName    = model.BillingAddress.LastName,
                    Company     = model.BillingAddress.Company,
                    PhoneNumber = model.BillingAddress.Phone,
                    Email       = model.Email
                };
                try
                {
                    user = customerService.AddOrUpdate(userModel);
                }
                catch (ArgumentException err)
                {
                    return(JsonError(err.Message));
                }

                customerService.LoginUser(HttpContext, user);
            }

            // Get addresses
            var billingAddress = Mapper.Map <Address>(model.BillingAddress);

            billingAddress.Type = AddressType.Billing;

            var shippingAddress = Mapper.Map <Address>(model.SameShippingAddress
                ? model.BillingAddress
                : model.ShippingAddress);

            shippingAddress.Type = AddressType.Shipping;

            var defaultBillingAddress = customerService.GetAddress(user.Id, AddressType.Billing);

            if (defaultBillingAddress == null)
            {
                // Add default billing address
                defaultBillingAddress           = Mapper.Map <Address>(model.BillingAddress);
                defaultBillingAddress.Type      = AddressType.Billing;
                defaultBillingAddress.IsPrimary = true;
                user.Addresses.Add(defaultBillingAddress);
            }

            var defaultShippingAddress = customerService.GetAddress(user.Id, AddressType.Shipping);

            if (defaultShippingAddress == null)
            {
                // Add default shipping address
                defaultShippingAddress = Mapper.Map <Address>(model.SameShippingAddress
                    ? model.BillingAddress
                    : model.ShippingAddress);
                defaultShippingAddress.Type      = AddressType.Shipping;
                defaultShippingAddress.IsPrimary = true;
                user.Addresses.Add(defaultShippingAddress);
            }

            db.SaveChanges();

            // Create order
            var order = new Order
            {
                UserId          = user.Id,
                BillingAddress  = billingAddress,
                ShippingAddress = shippingAddress,
                DatePlaced      = DateTime.Now,
                DateUpdated     = DateTime.Now,
                IPAddress       = Request.UserHostAddress,
                UserComments    = model.UserComments,
                Status          = OrderStatus.AwaitingPayment
            };

            db.Orders.Add(order);

            TaxZone taxZone = taxZoneService.Find(billingAddress.CountryCode, billingAddress.RegionId);

            foreach (ShoppingCartItem cartItem in cart.ShoppingCartItems)
            {
                Product    product    = db.Products.Find(cartItem.ProductId);
                ProductSku productSku = cartItem.ProductSku;

                if (productSku != null && productSku.Quantity.HasValue)
                {
                    productSkuService.RemoveQuantity(productSku.Id, cartItem.Quantity);
                }
                else if (product.Quantity.HasValue)
                {
                    productService.RemoveQuantity(product.Id, cartItem.Quantity);
                }

                decimal price = product.SalePrice ?? product.Price;
                if (cartItem.ProductSkuId.HasValue && cartItem.ProductSku.Price.HasValue)
                {
                    price = cartItem.ProductSku.Price.Value;
                }

                var cartItemOptions  = JsonConvert.DeserializeObject <ShoppingCartItemOptionViewModel[]>(cartItem.Options);
                var orderItemOptions = Mapper.Map <OrderItemOption[]>(cartItemOptions);

                var orderItem = new OrderItem
                {
                    Order        = order,
                    ProductId    = product.Id,
                    ProductSkuId = cartItem.ProductSkuId,
                    Quantity     = cartItem.Quantity,
                    Options      = JsonConvert.SerializeObject(orderItemOptions),
                    ItemPrice    = price
                };

                db.OrderItems.Add(orderItem);

                order.Subtotal += cartItem.Quantity * price;

                if (taxZone != null)
                {
                    order.TaxAmount += taxRateService.CalculateTax(taxZone.Id, product.TaxClassId, price * cartItem.Quantity);
                }
            }

            ShippingMethod shippingMethod = db.ShippingMethods.Find(model.ShippingMethodId);

            order.ShippingAmount = shippingService.CalculateShipping(shippingMethod,
                                                                     cart.ShoppingCartItems.Sum(i => i.Quantity),
                                                                     cart.ShoppingCartItems.Sum(i => i.Quantity * i.Product.Weight),
                                                                     order.Subtotal, shippingAddress).GetValueOrDefault();

            order.Total = order.Subtotal + order.ShippingAmount;
            if (!settings.Get <bool>(SettingField.TaxIncludedInPrices))
            {
                order.Total += order.TaxAmount;
            }

            db.SaveChanges();

            return(JsonSuccess(new { orderId = order.Id, paymentMethodId = model.PaymentMethodId }));
        }