|
Home > Archive > Commerce Server General > May 2005 > C# Custom Pipeline Component
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
C# Custom Pipeline Component
|
|
|
| If anyone has developed a C# Pipeline component will you please contact me.
I am starting to think that no one uses Commerce Server 2002!
sirgilligan@yahoo.com
| |
| Colin Bowern 2005-05-18, 8:50 pm |
| Geoff,
Here's a sample pipeline component I wrote to calculate taxes. As always
use at your own risk. 
Cheers,
Colin
#region References
using Microsoft.CommerceServer.Runtime;
using Microsoft.CommerceServer.Interop;
using Microsoft.CommerceServer.Interop.Caching;
using Microsoft.CommerceServer.Interop.Orders;
using System;
using System.Runtime.InteropServices;
#endregion
namespace OCC.CSPipeline
{
/// <summary>
/// This component calculates the tax on items in the shipments that are
flagged as taxable
/// on a regional and country level. It assumes the order has been split
up into shipments
/// using the Splitter component.
/// </summary>
[GuidAttribute("80851810-FD43-4efd-968A-F740CB55C445")]
public class CalculateTax :
IPipelineComponentAdmin, IPipelineComponent,
IPipelineComponentDescription, IPersistDictionary
{
#region Data Members
// ProgID of Component - Keep this consistent with the real ProgID
private const String ProgId = "OCC.CSPipeline.CalculateTax";
// Status codes for pipeline components
private const Int32 StatusSuccess = 1; // success
private const Int32 StatusWarning = 2; // warning
private const Int32 StatusError = 3; // error
private bool isDirty; // indicates that values of this component must be
persisted
#endregion
#region Constructor
/// <summary>
/// Initialize instance member variables
/// </summary>
public CalculateTax()
{
isDirty = false;
this.InitNew();
}
#endregion
#region IPersistDictionary Interfaces
public String GetProgID()
{
return ProgId;
}
public void InitNew()
{
}
public Int32 IsDirty()
{
return Convert.ToInt32(isDirty);
}
public void Load(Object pDispDict)
{
}
public void Save(Object pDispDict, Int32 fSameAsLoad)
{
}
#endregion
/// <summary>
/// main function for this component.
/// For each shipment cycle through the line items and determine
/// if a minimum value or the summation of a fixed percentage of
/// each item should be used as the shipping rate.
/// </summary>
/// <param name="pdispOrder"></param>
/// <param name="pdispContext"></param>
/// <param name="Flags"></param>
/// <returns></returns>
public Int32 Execute(Object pdispOrder, Object pdispContext, Int32 Flags)
{
decimal OrderTaxTotalCountry, OrderTaxTotalRegion;
decimal ShipmentTaxTotalCountry, ShipmentTaxTotalRegion;
decimal ItemTaxTotalCountry, ItemTaxTotalRegion;
decimal CountryTaxRate, RegionTaxRate;
decimal ItemCurrentPrice, ShippingTotal;
IDictionary Address, Addresses, Order, Context, Item;
ISimpleList Items, ShipmentsToProcess;
IMessageManager MessageManager;
Object ErrorMessage;
Int32 ReturnValue;
string ShippingAddressId;
// Set default return value
ReturnValue = StatusSuccess;
Order = null;
try
{
// initialize the Order and Context dictionaries
Order = (IDictionary) pdispOrder;
Context = (IDictionary) pdispContext;
// initialize the Addresses data structure, Orderform.Items, and
MessageManager objects
Addresses = (IDictionary)Order[OrderFormFields.Addresses];
Items = (ISimpleList)Order[OrderFormFields.Items];
MessageManager = (IMessageManager)
Context[ContextFields.MessageManager];
// retrive the shipments that must be processed
ShipmentsToProcess = (ISimpleList)Order[OrderFormFields.Shipments];
// Set the starting tax values.
OrderTaxTotalCountry = 0;
OrderTaxTotalRegion = 0;
// For each shipment retrieve the line items in the shipment and
determine which tax rate
// to use based on the flags on the line item and shipping address
foreach (IDictionary Shipment in ShipmentsToProcess)
{
// Set the starting tax values.
ShipmentTaxTotalCountry = 0;
ShipmentTaxTotalRegion = 0;
RegionTaxRate = 0;
CountryTaxRate = 0;
// Retrieve shipping address
ShippingAddressId =
Shipment[ShipmentFields.ShippingAddressId].ToString();
Address = (IDictionary) Addresses[ShippingAddressId];
// Get the tax rate for the shipment address
if((Address[OrderAddressFields.CountryCode]!=DBNull.Value)||(Address[OrderAddressFields.CountryCode]!=null))
{
CountryTaxRate = this.GetTaxRate(Context,
Convert.ToString(Address[OrderAddressFields.CountryCode]), null);
if(CountryTaxRate != 0)
CountryTaxRate = CountryTaxRate / 100;
if((Address[OrderAddressFields.RegionCode]!=DBNull.Value)||(Address[OrderAddressFields.RegionCode]!=null))
{
RegionTaxRate = this.GetTaxRate(Context,
Convert.ToString(Address[OrderAddressFields.CountryCode]),
Convert.ToString(Address[OrderAddressFields.RegionCode]));
if(RegionTaxRate != 0)
RegionTaxRate = RegionTaxRate / 100;
}
}
// iterate over all the items and sum up the shipment item total
foreach (Int32 ItemIndex in
(ISimpleList)Shipment[ShipmentFields.ItemIndexes])
{
Item = (IDictionary)Items[ItemIndex];
ItemCurrentPrice =
Convert.ToDecimal(Item[LineItemFields.CurrentPrice]);
ItemTaxTotalCountry = 0;
ItemTaxTotalRegion = 0;
if(Item[LineItemFields.TaxableRegion]==DBNull.Value)
throw new ArgumentOutOfRangeException(LineItemFiel
ds.TaxableRegion);
if(Item[LineItemFields.TaxableCountry]==DBNull.Value)
throw new ArgumentOutOfRangeException(LineItemFiel
ds.TaxableCountry);
// Determine if tax is applicable
if((RegionTaxRate >
0)&&(Item[LineItemFields.TaxableRegion]!=DBNull.Value)&&(Convert.ToInt32(Item[LineItemFields.TaxableRegion])
== 1))
ItemTaxTotalRegion = RoundCurrency(Order, ItemCurrentPrice *
RegionTaxRate);
if((CountryTaxRate >
0)&&(Item[LineItemFields.TaxableCountry]!=DBNull.Value)&&(Convert.ToInt32(Item[LineItemFields.TaxableCountry])
== 1))
ItemTaxTotalCountry = RoundCurrency(Order, ItemCurrentPrice *
CountryTaxRate);
ItemTaxTotalCountry = RoundCurrency(Order, ItemTaxTotalCountry);
ItemTaxTotalRegion = RoundCurrency(Order, ItemTaxTotalRegion);
// Calculate item level fields
Item[LineItemFields.TaxIncluded] = 0;
Item[LineItemFields.TaxTotal] = new
CurrencyWrapper(ItemTaxTotalCountry + ItemTaxTotalRegion);
Item[LineItemFields.TaxTotalCountry] = new
CurrencyWrapper(ItemTaxTotalCountry);
Item[LineItemFields.TaxTotalRegion] = new
CurrencyWrapper(ItemTaxTotalRegion);
// Update shipment level fields
ShipmentTaxTotalCountry += ItemTaxTotalCountry;
ShipmentTaxTotalRegion += ItemTaxTotalRegion;
}
// Determine if tax is applicable to shipping charges
if(Shipment[ShipmentFields.ShippingTotal]!=DBNull.Value)
{
ShippingTotal =
Convert.ToDecimal(Shipment[ShipmentFields.ShippingTotal]);
if(RegionTaxRate > 0)
ShipmentTaxTotalRegion += ShippingTotal * RegionTaxRate;
if(CountryTaxRate > 0)
ShipmentTaxTotalCountry += ShippingTotal * CountryTaxRate;
}
ShipmentTaxTotalCountry = RoundCurrency(Order,
ShipmentTaxTotalCountry);
ShipmentTaxTotalRegion = RoundCurrency(Order, ShipmentTaxTotalRegion);
// Calculate shipment level fields
Shipment[ShipmentFields.TaxIncluded] = 0;
Shipment[ShipmentFields.TaxTotal] = new
CurrencyWrapper(ShipmentTaxTotalCountry + ShipmentTaxTotalRegion);
Shipment[ShipmentFields.TaxTotalCountry] = new
CurrencyWrapper(ShipmentTaxTotalCountry)
;
Shipment[ShipmentFields.TaxTotalRegion] = new
CurrencyWrapper(ShipmentTaxTotalRegion);
// Update order level fields
OrderTaxTotalCountry += ShipmentTaxTotalCountry;
OrderTaxTotalRegion += ShipmentTaxTotalRegion;
}
OrderTaxTotalCountry = RoundCurrency(Order, OrderTaxTotalCountry);
OrderTaxTotalRegion = RoundCurrency(Order, OrderTaxTotalRegion);
// Calculate order level fields
Order[OrderFormFields.TaxIncluded] = 0;
Order[OrderFormFields.TaxTotal] = new
CurrencyWrapper(OrderTaxTotalCountry + OrderTaxTotalRegion);
Order[OrderFormFields.TaxTotalCountry] = new
CurrencyWrapper(OrderTaxTotalCountry);
Order[OrderFormFields.TaxTotalRegion] = new
CurrencyWrapper(OrderTaxTotalRegion);
}
// an error has occured. Add the error message to the basket errors and
// set the "error" as the pipeline component error level
catch (Exception ex)
{
AdminLib.AdminEventLogClass aec = new AdminLib.AdminEventLogClass();
aec.WriteErrorEvent(this.GetProgID(), ex.ToString());
// Write to Basket Errors
ErrorMessage = ex.Message;
((ISimpleList)Order[OrderFormFields.BasketErrors]).Add(ref
ErrorMessage);
return StatusError;
}
return ReturnValue;
}
private decimal GetTaxRate(IDictionary Context, string CountryCode, string
RegionCode)
{
decimal returnValue;
Dictionary TaxRates, Countries, States;
ICacheManager cacheManager;
if(CountryCode==null)
return 0;
// Set the default return value.
returnValue = 0;
// Get the tax rate cache
//CacheManager
cacheManager = (ICacheManager) Context[ContextFields.CacheManager];
TaxRates = (Microsoft.CommerceServer.Runtime.Dictionary)
cacheManager.GetCache(CacheManagerItems.SampleRegionalTaxCache);
// Get the list of countries in the tax rate cache
Countries = (Dictionary) TaxRates["cache"];
// If the country exists in the list of available country tax
// rates look for the region.
if(Countries[CountryCode]!=null)
{
try
{
States = (Dictionary) Countries[CountryCode];
// If region code has not specified use "@" to get the
// country level tax rate
if((RegionCode==null)&&(States["@"]!=null))
returnValue = Convert.ToDecimal(States["@"]);
else if(States[RegionCode]!=null)
returnValue = Convert.ToDecimal(States[RegionCode]);
}
catch (System.InvalidCastException)
{
// Messy way to deal with country or region codes not existing in
// the SampleRegionalTaxCache table.
return 0;
}
}
return returnValue;
}
/// <summary>
/// Internal helper function to round currency values
/// based on the degree of precision specified by the
/// _currency_decimal_places key in the OrderForm dictionary
/// </summary>
/// <param name="Order"></param>
/// <param name="Currency"></param>
/// <returns></returns>
private decimal RoundCurrency(IDictionary Order, decimal Currency)
{
// retrieve the degree of precision from the OrderForm dictionary
Object DecimalPlaces = Order[OrderFormFields.DecimalPlaces];
// assert that a non null value has been retrieved
if (DecimalPlaces != DBNull.Value)
{
// represents the precision level specified
Int32 Precision = Convert.ToInt32(DecimalPlaces);
// if the precision level is greater than 0 then round
// the currency value to the desired number of significant
// digits. Otherwise (negative precision level) divide by
// 10^(precision level), round dropping digits to the right
// of the decimal, and then multiply by 10*(precision level)
//
// For example if precision == -2 and currency == 1234.56 then
// this algorithm will return 1200
if (Precision > 0)
{
return Convert.ToDecimal(Math.Round(Currency, Precision));
}
else
{
Int32 f = 1;
while (Precision <0)
{
f *= 10;
Precision +=1;
}
Currency = Currency / f;
Currency = Math.Round(Currency);
Currency = Currency * f;
}
}
return Currency;
}
/// <summary>
/// Use this method to prepare the component for execution in one of two
modes: design mode
/// or execution mode. In design mode, which is useful for running the
Pipeline Editor,
/// errors are more easily tolerated. Execution mode (the default) is
analogous to production mode.
/// </summary>
/// <param name="fEnable">Indicates whether the component should be run in
design mode (True) or execution mode (False).</param>
public void EnableDesign(Int32 fEnable) {}
/// <summary>
/// This method returns an IDictionary pointer for the user interface to
read the
/// configuration data for the component.
/// </summary>
/// <returns></returns>
public Object GetConfigData()
{
Object Dictionary = new DictionaryClass();
this.Save(Dictionary, Convert.ToInt32(false));
return Dictionary;
}
/// <summary>
/// This method takes a pointer to an object containing the configuration
information
/// for the component. This object must implement the IDictionary
interface.
/// </summary>
/// <param name="pdispDict"></param>
public void SetConfigData(Object pdispDict)
{
IDictionary Dictionary = (IDictionary) pdispDict;
this.Load(Dictionary);
}
/// <summary>
/// Returns an array of strings containing the ContextValuesRead
/// </summary>
/// <returns></returns>
public System.Object ContextValuesRead()
{
object[] contextValuesRead = new object[3];
contextValuesRead[0] = ContextFields.CacheManager;
contextValuesRead[1] = ContextFields.CacheManager + "." +
CacheManagerItems.SampleRegionalTaxCache;
contextValuesRead[2] = ContextFields.MessageManager;
return contextValuesRead;
}
/// <summary>
/// Returns an array of strings containing the ContextValuesRead
/// </summary>
/// <returns></returns>
public System.Object ValuesRead()
{
object[] valuesRead = new object[11];
valuesRead[0] = "order." + OrderFormFields.Addresses;
valuesRead[1] = "order." + OrderFormFields.Items;
valuesRead[2] = "order." + OrderFormFields.DecimalPlaces;
valuesRead[3] = "shipment." + ShipmentFields.ItemIndexes;
valuesRead[4] = "shipment." + ShipmentFields.ShippingAddressId;
valuesRead[5] = "shipment." + ShipmentFields.ShippingTotal;
valuesRead[6] = "item." + LineItemFields.TaxableCountry;
valuesRead[7] = "item." + LineItemFields.TaxableRegion;
valuesRead[8] = "item." + LineItemFields.CurrentPrice;
valuesRead[9] = "address." + OrderAddressFields.RegionCode;
valuesRead[10] = "address." + OrderAddressFields.CountryCode;
return valuesRead;
}
/// <summary>
/// Returns an array of strings containing the ValuesWritten
/// </summary>
/// <returns></returns>
public System.Object ValuesWritten()
{
object[] valuesWritten = new object[14];
valuesWritten[0] = "order." + OrderFormFields.BasketErrors;
valuesWritten[1] = "order." + OrderFormFields.PurchaseErrors;
valuesWritten[2] = "order." + OrderFormFields.TaxIncluded;
valuesWritten[3] = "order." + OrderFormFields.TaxTotal;
valuesWritten[4] = "order." + OrderFormFields.TaxTotalCountry;
valuesWritten[5] = "order." + OrderFormFields.TaxTotalRegion;
valuesWritten[6] = "shipment." + ShipmentFields.TaxIncluded;
valuesWritten[7] = "shipment." + ShipmentFields.TaxTotal;
valuesWritten[8] = "shipment." + ShipmentFields.TaxTotalCountry;
valuesWritten[9] = "shipment." + ShipmentFields.TaxTotalRegion;
valuesWritten[10] = "item." + LineItemFields.TaxIncluded;
valuesWritten[11] = "item." + LineItemFields.TaxTotal;
valuesWritten[12] = "item." + LineItemFields.TaxTotalCountry;
valuesWritten[13] = "item." + LineItemFields.TaxTotalRegion;
return valuesWritten;
}
private struct OrderAddressFields
{
public const string RegionCode = "region_code";
public const string CountryCode = "country_code";
}
private struct LineItemFields
{
#region Flags
public const string TaxableRegion = "_product_TaxableRegion";
public const string TaxableCountry = "_product_TaxableCountry";
#endregion
#region Totals
public const string CurrentPrice = "_cy_iadjust_currentprice";
public const string TaxIncluded = "_cy_tax_included";
public const string TaxTotal = "_cy_tax_total";
public const string TaxTotalCountry = "_cy_tax_total_country";
public const string TaxTotalRegion = "_cy_tax_total_region";
#endregion
}
private struct ShipmentFields
{
#region Identifiers
public const string ItemIndexes = "ItemIndexes";
public const string ShippingAddressId = "shipping_address_id";
#endregion
#region Totals
public const string ShippingTotal = "_cy_shipping_total";
public const string TaxIncluded = "_cy_tax_included";
public const string TaxTotal = "_cy_tax_total";
public const string TaxTotalCountry = "_cy_tax_total_country";
public const string TaxTotalRegion = "_cy_tax_total_region";
#endregion
}
private struct OrderFormFields
{
#region Totals
public const string DecimalPlaces = "_currency_decimal_places";
public const string TaxIncluded = "_cy_tax_included";
public const string TaxTotal = "_cy_tax_total";
public const string TaxTotalCountry = "_cy_tax_total_country";
public const string TaxTotalRegion = "_cy_tax_total_region";
#endregion
#region Collections
public const string Shipments = "shipments";
public const string Items = "items";
public const string Addresses = "addresses";
#endregion
#region Messages
public const string BasketErrors = "_Basket_Errors";
public const string PurchaseErrors = "_Purchase_Errors";
#endregion
}
private struct ContextFields
{
public const string CacheManager = "CacheManager";
public const string MessageManager = "MessageManager";
}
private struct CacheManagerItems
{
public const string SampleRegionalTaxCache = "SampleRegionalTaxCache";
}
}
}
| |
|
| Thanks. Great help.
Thanks so very much. I was afraid I would have to invest a lot of time
learning VB Script and use Scriptor only!
:-)
(JUST SEEN STARWARS! This is a good day!)
"Colin Bowern" wrote:
> Geoff,
>
> Here's a sample pipeline component I wrote to calculate taxes. As always
> use at your own risk. 
>
> Cheers,
> Colin
>
> #region References
> using Microsoft.CommerceServer.Runtime;
> using Microsoft.CommerceServer.Interop;
> using Microsoft.CommerceServer.Interop.Caching;
> using Microsoft.CommerceServer.Interop.Orders;
> using System;
> using System.Runtime.InteropServices;
> #endregion
>
> namespace OCC.CSPipeline
> {
> /// <summary>
> /// This component calculates the tax on items in the shipments that are
> flagged as taxable
> /// on a regional and country level. It assumes the order has been split
> up into shipments
> /// using the Splitter component.
> /// </summary>
> [GuidAttribute("80851810-FD43-4efd-968A-F740CB55C445")]
> public class CalculateTax :
> IPipelineComponentAdmin, IPipelineComponent,
> IPipelineComponentDescription, IPersistDictionary
> {
> #region Data Members
> // ProgID of Component - Keep this consistent with the real ProgID
> private const String ProgId = "OCC.CSPipeline.CalculateTax";
>
> // Status codes for pipeline components
> private const Int32 StatusSuccess = 1; // success
> private const Int32 StatusWarning = 2; // warning
> private const Int32 StatusError = 3; // error
>
> private bool isDirty; // indicates that values of this component must be
> persisted
> #endregion
>
> #region Constructor
> /// <summary>
> /// Initialize instance member variables
> /// </summary>
> public CalculateTax()
> {
> isDirty = false;
> this.InitNew();
> }
> #endregion
>
> #region IPersistDictionary Interfaces
> public String GetProgID()
> {
> return ProgId;
> }
>
> public void InitNew()
> {
>
> }
>
> public Int32 IsDirty()
> {
> return Convert.ToInt32(isDirty);
> }
>
>
> public void Load(Object pDispDict)
> {
> }
>
> public void Save(Object pDispDict, Int32 fSameAsLoad)
> {
> }
> #endregion
>
> /// <summary>
> /// main function for this component.
> /// For each shipment cycle through the line items and determine
> /// if a minimum value or the summation of a fixed percentage of
> /// each item should be used as the shipping rate.
> /// </summary>
> /// <param name="pdispOrder"></param>
> /// <param name="pdispContext"></param>
> /// <param name="Flags"></param>
> /// <returns></returns>
> public Int32 Execute(Object pdispOrder, Object pdispContext, Int32 Flags)
> {
> decimal OrderTaxTotalCountry, OrderTaxTotalRegion;
> decimal ShipmentTaxTotalCountry, ShipmentTaxTotalRegion;
> decimal ItemTaxTotalCountry, ItemTaxTotalRegion;
> decimal CountryTaxRate, RegionTaxRate;
> decimal ItemCurrentPrice, ShippingTotal;
> IDictionary Address, Addresses, Order, Context, Item;
> ISimpleList Items, ShipmentsToProcess;
> IMessageManager MessageManager;
> Object ErrorMessage;
> Int32 ReturnValue;
> string ShippingAddressId;
>
> // Set default return value
> ReturnValue = StatusSuccess;
> Order = null;
>
> try
> {
> // initialize the Order and Context dictionaries
> Order = (IDictionary) pdispOrder;
> Context = (IDictionary) pdispContext;
>
> // initialize the Addresses data structure, Orderform.Items, and
> MessageManager objects
> Addresses = (IDictionary)Order[OrderFormFields.Addresses];
> Items = (ISimpleList)Order[OrderFormFields.Items];
> MessageManager = (IMessageManager)
> Context[ContextFields.MessageManager];
>
> // retrive the shipments that must be processed
> ShipmentsToProcess = (ISimpleList)Order[OrderFormFields.Shipments];
>
> // Set the starting tax values.
> OrderTaxTotalCountry = 0;
> OrderTaxTotalRegion = 0;
>
> // For each shipment retrieve the line items in the shipment and
> determine which tax rate
> // to use based on the flags on the line item and shipping address
> foreach (IDictionary Shipment in ShipmentsToProcess)
> {
> // Set the starting tax values.
> ShipmentTaxTotalCountry = 0;
> ShipmentTaxTotalRegion = 0;
> RegionTaxRate = 0;
> CountryTaxRate = 0;
>
> // Retrieve shipping address
> ShippingAddressId =
> Shipment[ShipmentFields.ShippingAddressId].ToString();
> Address = (IDictionary) Addresses[ShippingAddressId];
>
> // Get the tax rate for the shipment address
> if((Address[OrderAddressFields.CountryCode]!=DBNull.Value)||(Address[OrderAddressFields.CountryCode]!=null))
> {
> CountryTaxRate = this.GetTaxRate(Context,
> Convert.ToString(Address[OrderAddressFields.CountryCode]), null);
> if(CountryTaxRate != 0)
> CountryTaxRate = CountryTaxRate / 100;
>
> if((Address[OrderAddressFields.RegionCode]!=DBNull.Value)||(Address[OrderAddressFields.RegionCode]!=null))
> {
> RegionTaxRate = this.GetTaxRate(Context,
> Convert.ToString(Address[OrderAddressFields.CountryCode]),
> Convert.ToString(Address[OrderAddressFields.RegionCode]));
> if(RegionTaxRate != 0)
> RegionTaxRate = RegionTaxRate / 100;
> }
> }
>
> // iterate over all the items and sum up the shipment item total
> foreach (Int32 ItemIndex in
> (ISimpleList)Shipment[ShipmentFields.ItemIndexes])
> {
> Item = (IDictionary)Items[ItemIndex];
>
> ItemCurrentPrice =
> Convert.ToDecimal(Item[LineItemFields.CurrentPrice]);
> ItemTaxTotalCountry = 0;
> ItemTaxTotalRegion = 0;
>
> if(Item[LineItemFields.TaxableRegion]==DBNull.Value)
> throw new ArgumentOutOfRangeException(LineItemFiel
ds.TaxableRegion);
>
> if(Item[LineItemFields.TaxableCountry]==DBNull.Value)
> throw new ArgumentOutOfRangeException(LineItemFiel
ds.TaxableCountry);
>
> // Determine if tax is applicable
> if((RegionTaxRate >
> 0)&&(Item[LineItemFields.TaxableRegion]!=DBNull.Value)&&(Convert.ToInt32(Item[LineItemFields.TaxableRegion])
> == 1))
> ItemTaxTotalRegion = RoundCurrency(Order, ItemCurrentPrice *
> RegionTaxRate);
>
> if((CountryTaxRate >
> 0)&&(Item[LineItemFields.TaxableCountry]!=DBNull.Value)&&(Convert.ToInt32(Item[LineItemFields.TaxableCountry])
> == 1))
> ItemTaxTotalCountry = RoundCurrency(Order, ItemCurrentPrice *
> CountryTaxRate);
>
> ItemTaxTotalCountry = RoundCurrency(Order, ItemTaxTotalCountry);
> ItemTaxTotalRegion = RoundCurrency(Order, ItemTaxTotalRegion);
>
> // Calculate item level fields
> Item[LineItemFields.TaxIncluded] = 0;
> Item[LineItemFields.TaxTotal] = new
> CurrencyWrapper(ItemTaxTotalCountry + ItemTaxTotalRegion);
> Item[LineItemFields.TaxTotalCountry] = new
> CurrencyWrapper(ItemTaxTotalCountry);
> Item[LineItemFields.TaxTotalRegion] = new
> CurrencyWrapper(ItemTaxTotalRegion);
>
> // Update shipment level fields
> ShipmentTaxTotalCountry += ItemTaxTotalCountry;
> ShipmentTaxTotalRegion += ItemTaxTotalRegion;
> }
>
> // Determine if tax is applicable to shipping charges
> if(Shipment[ShipmentFields.ShippingTotal]!=DBNull.Value)
> {
> ShippingTotal =
> Convert.ToDecimal(Shipment[ShipmentFields.ShippingTotal]);
> if(RegionTaxRate > 0)
> ShipmentTaxTotalRegion += ShippingTotal * RegionTaxRate;
> if(CountryTaxRate > 0)
> ShipmentTaxTotalCountry += ShippingTotal * CountryTaxRate;
> }
>
> ShipmentTaxTotalCountry = RoundCurrency(Order,
> ShipmentTaxTotalCountry);
> ShipmentTaxTotalRegion = RoundCurrency(Order, ShipmentTaxTotalRegion);
>
> // Calculate shipment level fields
> Shipment[ShipmentFields.TaxIncluded] = 0;
> Shipment[ShipmentFields.TaxTotal] = new
> CurrencyWrapper(ShipmentTaxTotalCountry + ShipmentTaxTotalRegion);
> Shipment[ShipmentFields.TaxTotalCountry] = new
> CurrencyWrapper(ShipmentTaxTotalCountry)
;
> Shipment[ShipmentFields.TaxTotalRegion] = new
> CurrencyWrapper(ShipmentTaxTotalRegion);
>
> // Update order level fields
> OrderTaxTotalCountry += ShipmentTaxTotalCountry;
> OrderTaxTotalRegion += ShipmentTaxTotalRegion;
> }
>
> OrderTaxTotalCountry = RoundCurrency(Order, OrderTaxTotalCountry);
> OrderTaxTotalRegion = RoundCurrency(Order, OrderTaxTotalRegion);
>
> // Calculate order level fields
> Order[OrderFormFields.TaxIncluded] = 0;
> Order[OrderFormFields.TaxTotal] = new
> CurrencyWrapper(OrderTaxTotalCountry + OrderTaxTotalRegion);
> Order[OrderFormFields.TaxTotalCountry] = new
> CurrencyWrapper(OrderTaxTotalCountry);
> Order[OrderFormFields.TaxTotalRegion] = new
> CurrencyWrapper(OrderTaxTotalRegion);
> }
> // an error has occured. Add the error message to the basket errors and
> // set the "error" as the pipeline component error level
> catch (Exception ex)
> {
> AdminLib.AdminEventLogClass aec = new AdminLib.AdminEventLogClass();
> aec.WriteErrorEvent(this.GetProgID(), ex.ToString());
> // Write to Basket Errors
> ErrorMessage = ex.Message;
> ((ISimpleList)Order[OrderFormFields.BasketErrors]).Add(ref
> ErrorMessage);
> return StatusError;
> }
>
> return ReturnValue;
> }
>
> private decimal GetTaxRate(IDictionary Context, string CountryCode, string
> RegionCode)
> {
> decimal returnValue;
> Dictionary TaxRates, Countries, States;
> ICacheManager cacheManager;
>
> if(CountryCode==null)
> return 0;
>
> // Set the default return value.
> returnValue = 0;
>
> // Get the tax rate cache
>
> //CacheManager
> cacheManager = (ICacheManager) Context[ContextFields.CacheManager];
> TaxRates = (Microsoft.CommerceServer.Runtime.Dictionary)
> cacheManager.GetCache(CacheManagerItems.SampleRegionalTaxCache);
>
> // Get the list of countries in the tax rate cache
> Countries = (Dictionary) TaxRates["cache"];
>
> // If the country exists in the list of available country tax
> // rates look for the region.
> if(Countries[CountryCode]!=null)
> {
> try
> {
> States = (Dictionary) Countries[CountryCode];
>
> // If region code has not specified use "@" to get the
> // country level tax rate
|
|
|
|
|