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); }
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))); }
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); }
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); }
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); }
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); }
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); }
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); }
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))); } }
private IEnumerable <net.taxcloud.api.CartItem> ConvertCartItems(CartItemCollection cartItems, int customerID) { Customer customer = new Customer(customerID); return(ConvertCartItems(cartItems, customer)); }
private IEnumerable <net.taxcloud.api.CartItem> ConvertCartItems(CartItemCollection cartItems, Customer customer) { return(ConvertCartItems(cartItems, customer, cartItems.CouponList, cartItems.QuantityDiscountList)); }
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); }
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)); }
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); }