Hi,
you will need to use a custom
eCommerce provider and create your own implementation of EvaluateShoppingCartContent method in a
CustomShoppingCartInfoProvider.
The code of original method is here:
/// <summary>
/// Evaluates shopping cart content - calculates all taxes, discounts and subtotals.
/// </summary>
/// <param name="shoppingCart">Shopping cart object with all neccessary data for calculation.</param>
/// <param name="evaluateForInvoice">Indicates if shopping cart content is evaluated for invoice.</param>
public static void EvaluateShoppingCartContent(ShoppingCartInfo shoppingCart, bool evaluateForInvoice)
{
if (shoppingCart == null)
{
throw new Exception("[ShoppingCartInfoProvider.EvaluateShoppingCartContent]: No shopping cart given.");
}
DebugHelper.SetContext("ShoppingCart");
// Prepare the tables
DataTable contentTable = ShoppingCartInfo.CreateContentTable();
DataTable taxTable = ShoppingCartInfo.CreateTaxTable();
bool isCartInDatabase = (Ecommerce.ShoppingCartInfoProvider.GetShoppingCartInfo(shoppingCart.ShoppingCartID) != null);
// Clear shopping cart hashtables
shoppingCart.ClearShoppingCartHashtables();
if ((shoppingCart.CartItems != null) && (shoppingCart.CartItems.Count > 0))
{
// Get dataset of SKUs and their taxes
DataSet taxClassesDS = Ecommerce.TaxClassInfoProvider.GetTaxClassesForCart(shoppingCart);
DataView taxClassView = null;
if (!DataHelper.DataSourceIsEmpty(taxClassesDS))
{
taxClassView = taxClassesDS.Tables[0].DefaultView;
}
// Get dataset of SKUs and their state taxes
DataSet stateTaxClassesDS = Ecommerce.TaxClassInfoProvider.GetStateTaxClassesForCart(shoppingCart);
DataView stateTaxClassView = null;
if (!DataHelper.DataSourceIsEmpty(stateTaxClassesDS))
{
stateTaxClassView = stateTaxClassesDS.Tables[0].DefaultView;
}
bool taxIDSupplied = ((shoppingCart.CustomerInfoObj != null) && (shoppingCart.CustomerInfoObj.CustomerTaxRegistrationID != ""));
shoppingCart.ItemsNotAvailable = false;
// Reload shopping cart items data
ReloadShoppingCartItemSKUData(shoppingCart, evaluateForInvoice);
// Evaluate items
foreach (ShoppingCartItemInfo cartItem in shoppingCart.CartItems)
{
string skuError = "";
// Check availability of the product and its product options
if (shoppingCart.CheckAvailableItems && (cartItem.SKUObj != null))
{
// Check whether product is enabled or not
if (!cartItem.SKUObj.SKUEnabled)
{
skuError = ResHelper.GetString("Ecommerce.UpdateShoppingCart.ProductDisabled");
shoppingCart.ItemsNotAvailable = true;
}
// If SKU should be selled only when available
else if (cartItem.SKUObj.SKUSellOnlyAvailable)
{
int availableUnits = ValidationHelper.GetInteger(shoppingCart.CartAvailableSKUs[cartItem.SKUID], 0);
// If there are not enough available items
if (availableUnits < 0)
{
shoppingCart.ItemsNotAvailable = true;
// If it is a product option
// OR it is a product with some product options
// OR there is another shopping cart item with the same SKU
// -> do not update SKU units in shoping cart to the maximum allowed quantity, display error message only
if ((cartItem.IsProductOption) ||
(cartItem.ProductOptions.Count > 0) ||
(ValidationHelper.GetInteger(shoppingCart.CartSKUOccurences[cartItem.SKUID], 0) > 1))
{
// Order item units cannot be increased by specified quantity
if (shoppingCart.IsCreatedFromOrder)
{
skuError += string.Format(ResHelper.GetString("Ecommerce.OrderItems.MaximumAvailableQuantity"), cartItem.SKUObj.SKUAvailableItems);
}
// Product units cannot be set to maximum allowed quantity
else
{
skuError += string.Format(ResHelper.GetString("Ecommerce.UpdateShoppingCart.MaximumAvailableQuantity"), cartItem.SKUObj.SKUAvailableItems);
}
}
// other cases -> update SKU units in shoping cart to the maximum allowed quantity
else
{
// Order item units were increased by maximum allowed quantity
if (shoppingCart.IsCreatedFromOrder)
{
skuError += string.Format(ResHelper.GetString("Ecommerce.OrderItems.ItemsNotAvailable"), cartItem.SKUObj.SKUAvailableItems);
}
// Product units were set to maximum allowed quantity
else
{
skuError += string.Format(ResHelper.GetString("Ecommerce.UpdateShoppingCart.ItemsNotAvailable"), cartItem.SKUObj.SKUAvailableItems);
}
// Set product units to maximum available quantity
cartItem.CartItemUnits = cartItem.SKUObj.SKUAvailableItems + ValidationHelper.GetInteger(shoppingCart.OrderSKUItems[cartItem.SKUID], 0);
if (isCartInDatabase)
{
// Update product units in database
Ecommerce.ShoppingCartItemInfoProvider.SetShoppingCartItemInfo(cartItem);
}
}
}
// If there is enough available items to cover demand for zero items
else if (cartItem.CartItemUnits == 0)
{
shoppingCart.ItemsNotAvailable = true;
// User can increase zero quantity up to the maximum available items
if (availableUnits > 0)
{
skuError += string.Format(ResHelper.GetString("Ecommerce.UpdateShoppingCart.IncreaseProductNumber"), cartItem.SKUObj.SKUAvailableItems);
}
// User need to remove product from shopping to continue shopping
else
{
skuError += ResHelper.GetString("Ecommerce.UpdateShoppingCart.ProductDisabled");
}
}
}
}
// Apply discount
double unitPrice = cartItem.SKUObj.SKUPrice;
double unitPriceAfterDiscount = GetSKUPriceAfterDiscount(shoppingCart, cartItem, shoppingCart.DiscountCouponInfoObj, shoppingCart.DiscountLevelInfoObj);
double unitDiscount = unitPrice - unitPriceAfterDiscount;
// Calculate tax per one unit
double unitPriceWithTax = unitPriceAfterDiscount;
double unitTax = 0;
double taxValue = 0;
bool isFlat = false;
ArrayList usedStateTaxClasses = new ArrayList();
if (stateTaxClassView != null)
{
// Filter state tax class value for specified product
stateTaxClassView.RowFilter = "SKUID = " + cartItem.SKUID.ToString() + " AND StateID = " + shoppingCart.StateID;
foreach (DataRowView stateRow in stateTaxClassView)
{
if (taxIDSupplied && ValidationHelper.GetBoolean(stateRow["TaxClassZeroIfIDSupplied"], false))
{
// Zero tax if Tax ID is supplied
unitTax = 0;
}
else
{
// Use state tax value
taxValue = ValidationHelper.GetDouble(stateRow["TaxValue"], 0);
isFlat = ValidationHelper.GetBoolean(stateRow["IsFlatValue"], false);
// Apply the tax
unitTax = TaxClassInfoProvider.GetTaxValue(unitPriceAfterDiscount, taxValue, isFlat);
unitPriceWithTax += unitTax;
}
// Evaluate summary for each tax class
ShoppingCartInfo.AddTaxSummary(taxTable, stateRow.Row, Ecommerce.ExchangeTableInfoProvider.ApplyExchangeRate(unitTax * cartItem.CartItemUnits, shoppingCart.ExchangeRate));
// Mark tax class as state tax class
usedStateTaxClasses.Add(ValidationHelper.GetDouble(stateRow["TaxClassID"], 0));
}
}
// Evaluate taxes
if (taxClassView != null)
{
// Filter country tax class value for specified product
taxClassView.RowFilter = "SKUID = " + cartItem.SKUID.ToString();
foreach (DataRowView row in taxClassView)
{
if (!usedStateTaxClasses.Contains(ValidationHelper.GetDouble(row["TaxClassID"], 0)))
{
if (taxIDSupplied && ValidationHelper.GetBoolean(row["TaxClassZeroIfIDSupplied"], false))
{
// Zero tax if Tax ID is supplied
unitTax = 0;
}
else
{
// Use country tax value
taxValue = ValidationHelper.GetDouble(row["TaxValue"], 0);
isFlat = ValidationHelper.GetBoolean(row["IsFlatValue"], false);
// Apply the tax
unitTax = TaxClassInfoProvider.GetTaxValue(unitPriceAfterDiscount, taxValue, isFlat);
unitPriceWithTax += unitTax;
}
// Evaluate summary for each tax class
ShoppingCartInfo.AddTaxSummary(taxTable, row.Row, Ecommerce.ExchangeTableInfoProvider.ApplyExchangeRate(unitTax * cartItem.CartItemUnits, shoppingCart.ExchangeRate));
}
}
}
// Calculate totals
double subTotal = unitPriceWithTax * cartItem.CartItemUnits;
double subTotalDefaultCurrency = subTotal;
double taxSummary = (unitPriceWithTax - unitPriceAfterDiscount) * cartItem.CartItemUnits;
// Apply the exchange rates
subTotal = Ecommerce.ExchangeTableInfoProvider.ApplyExchangeRate(subTotal, shoppingCart.ExchangeRate);
taxSummary = Ecommerce.ExchangeTableInfoProvider.ApplyExchangeRate(taxSummary, shoppingCart.ExchangeRate);
unitDiscount = Ecommerce.ExchangeTableInfoProvider.ApplyExchangeRate(unitDiscount, shoppingCart.ExchangeRate);
unitPrice = Ecommerce.ExchangeTableInfoProvider.ApplyExchangeRate(unitPrice, shoppingCart.ExchangeRate);
// Add item row to the content table
DataRow newRow = shoppingCart.CreateShoppingCartContentRow(contentTable, cartItem, unitPrice, unitDiscount, taxSummary, subTotal, subTotalDefaultCurrency, skuError);
contentTable.Rows.Add(newRow);
}
}
// Assign the tables
shoppingCart.ShoppingCartContentTable = contentTable;
shoppingCart.ShoppingCartTaxTable = taxTable;
DebugHelper.ReleaseContext();
}
This method is used when content of shopping cart is recalculated, therefore you can modify taxes here.
Best regards,
Ivana Tomanickova