예제 #1
0
        public decimal GetTaxRate(Customer customer, CartItemCollection cartItems, IEnumerable <OrderOption> orderOptions)
        {
            if (!customer.HasAtLeastOneAddress() || !cartItems.Any())
            {
                return(0m);
            }

            // Return the cached value if it's present and still valid
            string  lastCartHash    = HttpContext.Current.Items["TaxCloud.CartHash"] as string;
            decimal?lastTaxAmount   = HttpContext.Current.Items["TaxCloud.TaxAmount"] as decimal?;
            string  currentCartHash = GetCartHash(cartItems, customer, orderOptions);

            if (lastTaxAmount != null && currentCartHash == lastCartHash)
            {
                return(lastTaxAmount.Value);
            }

            // Create line items for all cart items and shipping selections

            decimal taxAmount = 0M;

            List <CouponObject> CouponList           = cartItems.CouponList;
            List <QDObject>     QuantityDiscountList = cartItems.QuantityDiscountList;

            if (Shipping.GetDistinctShippingAddressIDs(cartItems).Count == 1)
            {
                IEnumerable <net.taxcloud.api.CartItem> refCartitems = ConvertCartItems(cartItems, customer);

                net.taxcloud.api.Address destAddress = ConvertAddress(customer.PrimaryShippingAddress);

                refCartitems = refCartitems.Concat(CreateCartShippingLineItem(customer, cartItems, orderOptions)).Concat(CreateOrderOptionLineItems(orderOptions));
                taxAmount    = lookupTaxRate(customer.CustomerID.ToString(), refCartitems.ToArray(), refOrigin, destAddress);
            }
            else
            {
                List <int> shipAddresses = Shipping.GetDistinctShippingAddressIDs(cartItems);
                foreach (int _addressID in shipAddresses)
                {
                    net.taxcloud.api.Address destAddress = ConvertAddress(_addressID);

                    IEnumerable <CartItem> tmpcic = cartItems.Where(r => r.ShippingAddressID == _addressID);

                    IEnumerable <net.taxcloud.api.CartItem> refCartitems = ConvertCartItems(tmpcic, customer, CouponList, QuantityDiscountList);

                    refCartitems = refCartitems.Concat(CreateCartShippingLineItem(customer, tmpcic, orderOptions));
                    if (_addressID == customer.PrimaryShippingAddressID)
                    {
                        refCartitems = refCartitems.Concat(CreateOrderOptionLineItems(orderOptions));
                    }

                    taxAmount += lookupTaxRate(customer.CustomerID.ToString(), refCartitems.ToArray(), refOrigin, destAddress);
                }
            }

            //Cache the tax amount
            HttpContext.Current.Items["TaxCloud.CartHash"]  = currentCartHash;
            HttpContext.Current.Items["TaxCloud.TaxAmount"] = taxAmount;

            return(taxAmount);
        }
예제 #2
0
 static public bool IsAllFreeShippingComponents(CartItemCollection CartItems)
 {
     // CartItemCollection inherits from List, so .Count in C# doesn't directly
     // translate to LINQ in VB. Use .Where(Func predicate).Count() instead...
     //JH 10.20.2010  - free shipping componentes include freeshipping, not shipable, not email gift card, and download products (as it was in 8012)
     return(CartItems.All(ci => ci.FreeShipping || !ci.Shippable || ci.IsDownload || GiftCard.s_IsEmailGiftCard(ci.ProductID)));
 }
예제 #3
0
        static public bool ShippingIsAllValid(CartItemCollection CartItems)
        {
            bool isRealTime = Shipping.GetActiveShippingCalculationID().Equals(ShippingCalculationEnum.UseRealTimeRates);

            // EVERY non-download item must have a shipping address and shipping method:
            foreach (CartItem c in CartItems)
            {
                if (isRealTime)
                {
                    String selMethod = c.ShippingMethod.Split('|')[0];

                    if (selMethod == AppLogic.AppConfig("RTShipping.CallForShippingPrompt") || selMethod == AppLogic.GetString("RTShipping.LocalPickupMethodName", Customer.Current.LocaleSetting))
                    {
                        return(true);
                    }
                }

                if (!c.IsDownload && !c.FreeShipping && !GiftCard.s_IsEmailGiftCard(c.ProductID) && c.Shippable)
                {
                    // at the time this routine is called, ALL of these must be filled in!
                    if (c.ShippingAddressID == 0 || c.ShippingMethodID == 0 || c.ShippingMethod.Length == 0)
                    {
                        return(false);
                    }
                }
            }

            // if any invalid state/country/shipping method combinations found, then shipping is not valid:
            List <int> AlreadyCheckedAddressIDs = new List <int>();

            foreach (CartItem c in CartItems)
            {
                if (!AlreadyCheckedAddressIDs.Contains(c.ShippingAddressID))
                {
                    if (!c.IsDownload && !c.FreeShipping && !c.IsSystem && !GiftCard.s_IsEmailGiftCard(c.ProductID) && !c.Shippable)
                    {
                        Address sa = new Address();
                        sa.LoadFromDB(c.ShippingAddressID);

                        if (sa.State.Trim().Length == 0)
                        {
                            throw new ArgumentException("State field in address record is BLANK. That is not allowed!");
                        }
                        if (sa.Country.Trim().Length == 0)
                        {
                            throw new ArgumentException("Country field in address record is BLANK. That is not allowed!");
                        }
                        if (!Shipping.ShippingMethodIsValid(c.ShippingMethodID, sa.State, sa.Country))
                        {
                            return(false);
                        }
                    }
                }
                AlreadyCheckedAddressIDs.Add(c.ShippingAddressID);
            }
            // all seems ok
            return(true);
        }
예제 #4
0
        static public List <int> GetDistinctShippingAddressIDs(CartItemCollection cic)
        {
            List <int> addressIDs = new List <int>();

            //String tmpS = ",";
            foreach (CartItem c in cic)
            {
                if (!addressIDs.Contains(c.ShippingAddressID))
                {
                    addressIDs.Add(c.ShippingAddressID);
                }
            }
            return(addressIDs);
        }
예제 #5
0
파일: AvaTax.cs 프로젝트: lulzzz/BrandStore
        private Line CreateLineItem(CartItem cartItem, Avalara.AvaTax.Adapter.AddressService.Address destinationAddress)
        {
            decimal extendedPrice;

            if (cartItem.ThisShoppingCart == null)
            {
                // Order line items
                using (var promotionsDataContext = new AspDotNetStorefront.Promotions.Data.EntityContextDataContext())
                {
                    // Sum the discount for every PromotionLineItem that applies to the current cart item.
                    // A gift product's line item price is already discounted, so don't include the discount when IsAGift is true.
                    var lineItemDiscountAmount = promotionsDataContext.PromotionLineItems
                                                 .Where(pli => !pli.isAGift)
                                                 .Where(pli => pli.shoppingCartRecordId == cartItem.ShoppingCartRecordID)
                                                 .Sum(pli => (decimal?)pli.discountAmount);

                    extendedPrice = cartItem.Price + (lineItemDiscountAmount ?? 0);
                }
            }
            else
            {
                // Shopping cart items
                CartItemCollection cartItems = cartItem.ThisShoppingCart.CartItems;
                extendedPrice = Prices.LineItemPrice(cartItem, cartItems.CouponList, cartItems.QuantityDiscountList, cartItem.ThisCustomer);
            }

            Line lineItem = new Line
            {
                ItemCode           = cartItem.SKU,
                Description        = cartItem.ProductName,
                Amount             = extendedPrice,
                Qty                = (double)cartItem.Quantity,
                Discounted         = true,
                DestinationAddress = destinationAddress,
            };

            if (cartItem.IsTaxable)
            {
                var lineItemTaxClass = new TaxClass(cartItem.TaxClassID);
                lineItem.TaxCode = lineItemTaxClass.TaxCode;
            }
            else
            {
                lineItem.TaxCode = "NT";
            }

            lineItem.TaxOverride.TaxDate = System.DateTime.Today;

            return(lineItem);
        }
예제 #6
0
        public static CartItemCollection GetMultiShipOrder_ShipmentCollection_AsCartItemCollection(Order order)
        {
            CartItemCollection cartItems = new CartItemCollection();

            using (SqlConnection dbconn = new SqlConnection(DB.GetDBConn()))
            {
                dbconn.Open();
                using (IDataReader rs = DB.GetRS("Select MultiShipOrder_ShipmentId from MultiShipOrder_Shipment with (NOLOCK) where OrderNumber=" + order.OrderNumber.ToString(), dbconn))
                {
                    while (rs.Read())
                    {
                        MultiShipOrder_Shipment shipment = new MultiShipOrder_Shipment(DB.RSFieldInt(rs, "MultiShipOrder_ShipmentId"));

                        CartItem ciShipping = new CartItem();
                        ciShipping.VariantID = Prices.GetShippingProductVariant();

                        CartItemCollection ciSingleShippingCollection = new CartItemCollection();
                        ciShipping.ShippingAddressID = shipment.ShippingAddressId;
                        ciShipping.BillingAddressID  = shipment.BillingAddressId;

                        //If we do not otherwise apply a shipping method here, our
                        //item will become invalid during the ShippingIsAllValid routine.
                        ciShipping.ShippingMethodID = shipment.ShippingMethodId;

                        //Take note that we're referencing the current items product ID
                        //for later use when combining the collections.
                        ciShipping.ProductID        = 1;
                        ciShipping.ThisShoppingCart = order.CartItems[0].ThisShoppingCart;
                        ciShipping.CartType         = CartTypeEnum.ShoppingCart;
                        ciShipping.ThisCustomer     = order.CartItems[0].ThisCustomer;
                        if (order.CartItems.IsAllFreeShippingComponents)
                        {
                            ciShipping.IsTaxable = false;
                        }
                        ciShipping.Quantity   = 1;
                        ciShipping.Shippable  = false;
                        ciShipping.SKU        = "SHIPPING";
                        ciShipping.TaxClassID = AppLogic.AppConfigUSInt("ShippingTaxClassID");

                        //We can use the ShippingTotal method, but we should send the item itself
                        //over for proper shipping cost evaluation.
                        ciShipping.Price     = shipment.ShippingAmount;
                        ciShipping.IsTaxable = ciShipping.Price > System.Decimal.Zero ? true : false;
                        cartItems.Add(ciShipping);
                    }
                }
            }
            return(cartItems);
        }
예제 #7
0
        static public decimal GetShipByItemCharge(int ShippingMethodID, CartItemCollection cartItems)
        {
            decimal tmp = System.Decimal.Zero;

            foreach (CartItem c in cartItems)
            {
                if (!c.IsDownload)
                {
                    int     Q  = c.Quantity;
                    decimal PR = Shipping.GetVariantShippingCost(c.VariantID, ShippingMethodID) * Q;
                    tmp += PR;
                }
            }
            return(tmp);
        }
예제 #8
0
        public decimal GetTaxRate(Customer customer, CartItemCollection cartItems, IEnumerable <OrderOption> orderOptions)
        {
            if (!Enabled)
            {
                throw new InvalidOperationException("AvalaraInactiveException");
            }

            if (!customer.HasAtLeastOneAddress() || !cartItems.Any())
            {
                return(0m);
            }

            // Create line items for all cart items and shipping selections
            var cartItemAddressGroups = GroupCartItemsByShippingAddress(cartItems, customer.PrimaryShippingAddressID);
            var lineItems             = CreateItemAndShippingLineItems(cartItemAddressGroups, (shipmentAddressId, shipmentAddress, shipmentCartItems) => CreateCartShippingLineItem(shipmentAddress, customer, shipmentCartItems, orderOptions));

            // Create line items for order options using the first shipping address as the destination
            var firstShippingAddress = LoadAvalaraAddress(cartItemAddressGroups.First().Key);

            lineItems = lineItems.Concat(CreateOrderOptionLineItems(orderOptions, firstShippingAddress));

            var discountAmount = -cartItems.DiscountResults.Sum(dr => dr.OrderTotal);               // This value is returned as negative, but Avalara expectes a positive

            // Build and submit the tax request
            var taxRequest = BuildTaxRequest(customer, GetOriginAddress(), DocumentType.SalesOrder);

            taxRequest.Discount = discountAmount;

            // Add each line to the request, setting the line number sequentially
            var lineItemIndex = 1;

            foreach (var line in lineItems)
            {
                line.No = (lineItemIndex++).ToString();
                taxRequest.Lines.Add(line);
            }

            var taxService = CreateTaxService();
            var taxResult  = taxService.GetTax(taxRequest);

            foreach (Message message in taxResult.Messages)
            {
                LogErrorMessage(message);
            }

            return(taxResult.TotalTax);
        }
예제 #9
0
파일: AvaTax.cs 프로젝트: lulzzz/BrandStore
        private string GetCartHash(CartItemCollection cartItems, Customer customer, IEnumerable <OrderOption> orderOptions)
        {
            var originAddress = GetOriginAddress();

            string cartComposite = cartItems
                                   .Select(c => new
            {
                CartItem = c,
                Address  = new Address(c.ShippingAddressID)
            })
                                   .Aggregate(
                String.Format("{0}_{1}_{2}_{3}_{4}_{5}_{6}_{7}_{8}_{9}_{10}",
                              originAddress.City,
                              originAddress.Region,
                              originAddress.PostalCode,
                              customer.PrimaryShippingAddress.City,
                              customer.PrimaryShippingAddress.State,
                              customer.PrimaryShippingAddress.Zip,
                              customer.LevelHasNoTax,
                              cartItems.DiscountResults.Sum(dr => dr.OrderTotal),
                              cartItems.DiscountResults.Sum(dr => dr.ShippingTotal),
                              cartItems.DiscountResults.Sum(dr => dr.LineItemTotal),
                              orderOptions.Aggregate("_", (s, oo) => String.Format("{0}_{1}_{2}_{3}", s, oo.ID, oo.TaxClassID, oo.Cost))),
                (s, o) => String.Format("{0}_{1}_{2}_{3}_{4}_{5}_{6}_{7}_{8}",
                                        s,
                                        o.CartItem.ShoppingCartRecordID,
                                        o.CartItem.VariantID,
                                        o.CartItem.Quantity,
                                        o.CartItem.Price,
                                        o.CartItem.IsTaxable,
                                        o.CartItem.TaxClassID,
                                        o.CartItem.ShippingAddressID,
                                        o.CartItem.ShippingMethodID)
                );

            using (var md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create())
            {
                var hash = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(cartComposite));
                return(hash.Aggregate(String.Empty, (s, b) => String.Format("{0}{1:x2}", s, b)));
            }
        }
예제 #10
0
        private IEnumerable <net.taxcloud.api.CartItem> ConvertCartItems(CartItemCollection cartItems, int customerID)
        {
            Customer customer = new Customer(customerID);

            return(ConvertCartItems(cartItems, customer));
        }
예제 #11
0
 private IEnumerable <net.taxcloud.api.CartItem> ConvertCartItems(CartItemCollection cartItems, Customer customer)
 {
     return(ConvertCartItems(cartItems, customer, cartItems.CouponList, cartItems.QuantityDiscountList));
 }
예제 #12
0
 static public bool HasFreeShippingComponents(CartItemCollection CartItems)
 {
     // CartItemCollection inherits from List, so .Count in C# doesn't directly
     // translate to LINQ in VB. Use .Where(Func predicate).Count() instead...
     return(CartItems.Where(ci => ci.FreeShipping).Count() > 0);
 }
예제 #13
0
파일: AvaTax.cs 프로젝트: lulzzz/BrandStore
 private IEnumerable <IGrouping <int, CartItem> > GroupCartItemsByShippingAddress(CartItemCollection cartItems, int defaultShippingAddressId)
 {
     return(cartItems
            .Select(ci => new
     {
         ShippingAddressId = ci.ShippingAddressID > 0 ? ci.ShippingAddressID : defaultShippingAddressId,
         CartItems = ci,
     })
            .GroupBy(o => o.ShippingAddressId, o => o.CartItems));
 }
예제 #14
0
파일: AvaTax.cs 프로젝트: lulzzz/BrandStore
        public decimal GetTaxRate(Customer customer, CartItemCollection cartItems, IEnumerable <OrderOption> orderOptions)
        {
            if (!Enabled)
            {
                throw new InvalidOperationException("AvalaraInactiveException");
            }

            if (!customer.HasAtLeastOneAddress() || !cartItems.Any())
            {
                return(0m);
            }

            // Return the cached value if it's present and still valid
            string  lastCartHash    = HttpContext.Current.Items["Avalara.CartHash"] as string;
            decimal?lastTaxAmount   = HttpContext.Current.Items["Avalara.TaxAmount"] as decimal?;
            string  currentCartHash = GetCartHash(cartItems, customer, orderOptions);

            if (lastTaxAmount != null && currentCartHash == lastCartHash)
            {
                return(lastTaxAmount.Value);
            }

            // Create line items for all cart items and shipping selections
            var cartItemAddressGroups = GroupCartItemsByShippingAddress(cartItems, customer.PrimaryShippingAddressID);
            var lineItems             = CreateItemAndShippingLineItems(cartItemAddressGroups, (shipmentAddressId, shipmentAddress, shipmentCartItems) => CreateCartShippingLineItem(shipmentAddress, customer, shipmentCartItems, orderOptions));

            // Create line items for order options using the first shipping address as the destination
            var firstShippingAddress = LoadAvalaraAddress(cartItemAddressGroups.First().Key);

            lineItems = lineItems.Concat(CreateOrderOptionLineItems(orderOptions, firstShippingAddress));

            decimal discountAmount = -cartItems.DiscountResults.Sum(dr => dr.OrderTotal);               // This value is returned as negative, but Avalara expectes a positive

            // Build and submit the tax request
            GetTaxRequest taxRequest = BuildTaxRequest(customer, GetOriginAddress(), DocumentType.SalesOrder);

            taxRequest.Discount = discountAmount;

            // Add each line to the request, setting the line number sequentially
            int lineItemIndex = 1;

            foreach (var line in lineItems)
            {
                line.No = (lineItemIndex++).ToString();
                taxRequest.Lines.Add(line);
            }

            TaxSvc       taxService = CreateTaxService();
            GetTaxResult taxResult  = taxService.GetTax(taxRequest);

            foreach (Message message in taxResult.Messages)
            {
                LogErrorMessage(message);
            }

            decimal taxAmount = taxResult.TotalTax;

            // Cache the tax amount
            HttpContext.Current.Items["Avalara.CartHash"]  = currentCartHash;
            HttpContext.Current.Items["Avalara.TaxAmount"] = taxAmount;

            return(taxAmount);
        }