taxengine:integration:code_samples:c_sample_code
This is an old revision of the document!
Table of Contents
Sample Code
Please see Getting Started for help with using the KampData TaxEngine.
Console App in C#
using System;
using System.Runtime.InteropServices;
using System.Collections;
//Add the KDTaxEngine.dll as a reference.
using KampData.TaxEngine.API;
using KampData.TaxEngine.API.Enums;
namespace TaxEngineConsoleApp
{
/// <summary>
/// The CSharpClient object is a simple example of how the KampData
/// TaxEngine can be utilized from a 3rd party application. This sample
/// is not intended to be comprehensive. It simply illustrates the access
/// methods.
/// </summary>
/// <remarks>To use the KampData TaxEngine in this sample, or in any other
/// project, you must first setup the SOP module from the KDControlCenter.exe's
/// Transaction Source Module Setup window. Please see "Getting Started"in the
/// KDTaxEngine.chm help file for more information.</remarks>
class CSharpClient
{
[STAThread]
static void Main(string[] args)
{
string zip;
bool abort = false;
ArrayList cities = new ArrayList();
ArrayList counties = new ArrayList();
ArrayList states = new ArrayList();
string server = @"Microsoft SQL Server";
string userId = "User";
string password = "p@ssw0rd";
string companyDatabase = "TWO";
Int16 timeOutSeconds = 60;
bool displayProgessBar = true;
string loginMessage = "";
string message = "";
/// KampData.Portal object must be instantiated.
Portal txEngn = new Portal();
try
{
try
{
/// The Portal.Login method makes the connection to SQL Server and
/// prepares the tax engine for use.
loginMessage = txEngn.Login(server, userId, password, companyDatabase, timeOutSeconds, displayProgessBar);
}
catch (Exception e)
{
loginMessage = e.Message;
}
if (loginMessage != "")
{
abort = true;
Console.WriteLine(loginMessage);
Console.WriteLine("Press enter to continue");
Console.ReadLine(); // to hold window open displaying error message
}
if (!abort)
{
/// Set the docType and module using the values you have setup
/// in the KDWindowClient.exe's Transaction Source Module Setup
/// and Document Type Setup windows. In the SOP module, invoices are
/// docType 3.
Int16 docType = 3;
string module = "SOP";
/// You must assign a document number at this point. You can use a
/// document number generated by your order entry software
/// that will call the TaxEngine, or you can use the following code
/// to generate a document number.
string docNumber = txEngn.NextDocumentNumber(module);
/// Initialize the document.
txEngn.Document(docNumber, docType, module);
/// DocSaleOrPurchase defaults to Sales, so the following line
/// is unnecessary. However, you can set it to Purchases if desired.
txEngn.DocSaleOrPurchase = SalesOrPurchases.Sales;
/// You would normally set your customer ID at this point along with
/// any other document defaults. For purposes of this demonstration,
/// we will skip that step.
//txEngn.DocCustomerID = "ADAMPARK0001";
/// We now add a line to the order. The addressing and taxation
/// features occur on the line level. This step is required to
/// instantiate a line object. We recommend using the lineNumber
/// as it exists in your order entry system. Doing so ensures that
/// the TaxEngine line and the order entry line can be matched and
/// verified.
int lineNumber = 1;
txEngn.LineAdd(lineNumber);
do
{
/// We now provide the ZIP code.
Console.WriteLine("Enter a ZIP code");
zip = Console.ReadLine();
if (zip == "" || zip.ToUpper() == "EXIT")
break;
try
{
txEngn.LineZip = zip;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("");
continue;
}
/*
* At this point, the Portal object will have identified and made
* available the default city, county and state for the ZIP provided.
* Also, the default tax schedule will be identified, and made available.
* The following call prints these defaults:
*/
Console.WriteLine("Count found: {0} Default: {1}, [{2}] {3} {4}",
txEngn.LineAddressesInZip(), txEngn.LineCity, txEngn.LineCounty, txEngn.LineState, txEngn.LineZip);
/*
* Some ZIP codes are valid for more than one city, county and or state.
* The Portal object can provide ArrayLists of the available choices.
* The ArrayLists include:
* All States in the current ZIP.
* All Cities in the current state and ZIP.
* All Counties in the current city, state and ZIP.
*
* For example, if you change the city, then the list of possible counties
* may changes.
*
* You select the state, city and county in the same manner that you select
* the ZIP. (ie txEngn.LineCity = "New Orleans";)
*/
if (txEngn.LineAddressesInZip() > 1)
{
states = txEngn.LineStatesInZip();
Console.WriteLine("States in ZIP:");
foreach (string state in states)
{
Console.WriteLine(" State of {0}", state);
}
if (states.Count > 1)
{
Console.WriteLine("Enter a state. Press enter for {0}", txEngn.LineState);
string state = Console.ReadLine();
if (state != "")
txEngn.LineState = state;
}
cities = txEngn.LineCitiesInStateAndZip();
Console.WriteLine("Cities in {0} state and {1} ZIP:",
txEngn.LineState, txEngn.LineZip);
foreach (string city in cities)
{
Console.WriteLine(" City of: {0}", city);
}
if (cities.Count > 1)
{
bool cityNotChosen = true;
while (cityNotChosen)
{
Console.WriteLine("Enter a city. Press enter for {0}", txEngn.LineCity);
string city = Console.ReadLine();
if (city == "")
{
cityNotChosen = false;
}
else
{
try
{
txEngn.LineCity = city;
cityNotChosen = false;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
counties = txEngn.LineCountiesInCityStateAndZip();
Console.WriteLine("Counties in {0}, {1} {2}:",
txEngn.LineCity, txEngn.LineState, txEngn.LineZip);
foreach (string county in counties)
{
Console.WriteLine(" County of {0}", county);
}
if (counties.Count > 1)
{
bool countyNotChosen = true;
while (countyNotChosen)
{
Console.WriteLine("Enter a county. Press enter for {0}", txEngn.LineCounty);
string county = Console.ReadLine();
if (county == "")
{
countyNotChosen = false;
}
else
{
try
{
txEngn.LineCounty = county;
countyNotChosen = false;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
}
/// In city limits is assumed. This line exists here only to
/// illustrate that this option can be set after the city has
/// been specified.
txEngn.LineInCityLimits = true;
txEngn.LineTaxScheduleSelect();
Console.WriteLine("Tax schedule [{0}] {1} Rate: {2}",
txEngn.LineTaxScheduleID, txEngn.LineTaxScheduleDescription,
txEngn.LineInitialTaxPercent);
txEngn.LineItemUnitPrice = 100;
txEngn.LineItemQuantity = 1;
txEngn.DocCalculateTax();
Console.WriteLine();
message = "ID";
message = message.PadRight(80);
message = message.Insert(17, "Description");
message = message.Insert(48, "Total");
message = message.Insert(58, "Taxable");
message = message.Insert(68, "Tax");
message = message.Trim();
Console.WriteLine(message);
// This code displays the Microsoft Dynamics GP tax details
// that were used.
foreach (TrxTaxDetail trxDtl in txEngn.DocTaxDetails(TaxDetails.Transaction))
{
message = trxDtl.ID;
message = message.PadRight(80);
message = message.Insert(17, trxDtl.Description);
message = message.Insert(48, trxDtl.TotalAmount.ToString());
message = message.Insert(58, trxDtl.TaxedAmount.ToString());
message = message.Insert(68, trxDtl.TaxAmount.ToString());
message = message.Trim();
Console.WriteLine(message);
}
Console.WriteLine();
}
while (zip != "" && zip.ToUpper() != "EXIT");
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
Console.WriteLine("Press enter to continue");
Console.ReadLine(); // to hold window open displaying error message
}
}
}
}
ASP App in C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web.Security;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.InteropServices;
using System.Text;
//Add a reference to the KDTaxEngine.dll and then enter the using statements below.
using KampData.TaxEngine.API;
using KampData.TaxEngine.API.Enums;
namespace eStore
{
public partial class eStore : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
try
{
/// The Login method makes the connection to Microsoft SQL Server®
/// and prepares the TaxEngine for use.
loginMessage = txEngn.Login
(server, userId, password, companyDatabase, timeOutSeconds, showProgressBar);
/// The TestMode property can help by returning more information for
/// TaxEngine errors and may be useful when building or debugging
/// your integration.
txEngn.TestMode = false;
}
catch (Exception ea)
{
loginMessage = ea.Message;
}
if (loginMessage != "")
{
txtMessage.Text = loginMessage;
}
}
// Enter your Microsoft Dynamics® GP login.
private string server = @"SQLServerName";
private string userId = "sa";
private string password = "p@ssw0rd";
private string companyDatabase = "TWO";
private short timeOutSeconds = 30;
private bool showProgressBar = true;
private string loginMessage = "";
/// Set the Transaction Source Module.
/// For this example, I have created a transaction source module called
/// WEB in the KDControlCenter's Transaction Source Modules window. Using
/// this module will help me track which transactions were calculated
/// from my web site if I choose to begin saving transaction history in the
/// TaxEngine's built-in transaction history tables.
private string module = "WEB";
/// Set the Document Type as configured for the selected module in the
/// KDControlCenter's Document Type Setup window.
/// In this example, invoice = docType 3.
private Int16 docType = 3;
/// If your website generates document numbers, then you could set
/// that doc number here.
private string docNumber;
/// The KampData.TaxEngine.Portal class serves as your access point to the
/// TaxEngine's API methods and properties.
Portal txEngn = new Portal();
/// <summary>
/// The CopyToTaxEngine method provides the TaxEngine with the information entered on the webpage.
/// </summary>
private void CopyToTaxEngine()
{
try
{
txtMessage.Text = "";
if (txtDocNumber.Text == string.Empty)
{
/// The NextDocumentNumber method gets the next document number from the module setup
/// table (DzTe0420). If you do not use document numbers of your own, then you this
/// method can provide them for you.
docNumber = txEngn.NextDocumentNumber(module);
txtDocNumber.Text = docNumber;
}
// Clear out any previously loaded documents.
txEngn.DocClear();
/// Create a new TaxEngine document. Until it has been saved, posted, or deleted,
/// the document exists only as a temporary record in the Transaction Document
/// table. Saving and/or posting the document is only necessary if you intend to
/// keep a record of historcal data in the TaxEngine's built-in, history tables.
/// The TaxEngine's built-in, history tables are completely separate from
/// Microsoft Dynamics® GP's transaction history tables.
txEngn.Document(txtDocNumber.Text, docType, module);
/// Set the DocSaleOrPurchase property to indicate whether the document is subject
/// to sales or purchases/use tax rates.
txEngn.DocSaleOrPurchase = SalesOrPurchases.Sales;
if (txEngn.DocLoaded())
{
/// Set the DocCustomerID property equal to the Microsoft Dynamics® GP customer ID.
txEngn.DocCustomerID = txtCustomer.Text;
/// Set the DocDefaultShipToAddressID property equal to the Microsoft Dynamics® GP
/// customer address ID.
txEngn.DocDefaultShipToAddressID = txtAddress.Text;
/// You can iterate through multiple line items, adding each to the document one at
/// a time. For this example, we are adding only one line item.
int linesInOrder = 1;
for (int lineNumber = 1; lineNumber <= linesInOrder; lineNumber++)
{
/// Add a line to the document with the LineAdd method. The addressing, tax
/// schedule selection, and tax calculation features occur at the line item level.
/// We recommend using the same line numbers that are used in your order entry
/// system whenever possible to help ensure that the TaxEngine line and the order
/// entry line can be matched and verified.
if (txtLineNumber.Text != string.Empty)
txEngn.LineAdd(Convert.ToInt32(txtLineNumber.Text));
else
{
txEngn.LineAdd(lineNumber);
txtLineNumber.Text = lineNumber.ToString();
}
if (txEngn.LineExists)
{
if (txtAddress.Text != string.Empty)
{
/// The LineShipToAddressID allows you to enter documents with multiple
/// ship to addresses. For this example, we do not actually change the
/// line's address.
txEngn.LineShipToAddressID = txtAddress.Text;
/// Setting the LineUseExemptSchedules property equal to true enables the
/// TaxEngine to return the exempt tax schedule ID values for tax exempt
/// line items. This option works in conjunction with DynamicZip's
/// "Create ZIP Code Exempt Schedules" option in the DynamicZip Setup
/// window.
txEngn.LineUseExemptSchedules = true;
/// The TaxEngine has built-in ArrayList methods that can be used to
/// populate drop down list fields. Using ddl fields with these methods
/// can help ensure address entry accuracy.
/// For example:
/// ArrayList states = new ArrayList();
/// states = txEngn.LineStatesInZip();
/// You could then set the values of a State ddl field equal to the
/// values stored in LineStatesInZip.
/// However, for this example, we are only using plain text fields.
/// The code below allows for updating the line properties based on the
/// address entered on the webpage.
if (txtZip.Text != string.Empty)
txEngn.LineZip = txtZip.Text;
if (txtCity.Text != string.Empty)
txEngn.LineCity = txtCity.Text;
if (txtCounty.Text != string.Empty)
txEngn.LineCounty = txtCounty.Text;
if (txtState.Text != string.Empty)
txEngn.LineState = txtState.Text;
}
/// Add the inventory item information for the current line.
txEngn.LineItemNumber = txtItemNumber.Text;
txEngn.LineItemUnitPrice = Convert.ToDecimal(txtPrice.Text);
txEngn.LineItemQuantity = Convert.ToDecimal(txtQuantity.Text);
}
}
/// The DocTaxScheduleSelect method selects the tax schedule ID for all lines.
txEngn.DocTaxScheduleSelect();
}
}
catch (Exception copyTo)
{
txtMessage.Text = copyTo.Message;
}
}
/// <summary>
/// The CopyFromTaxEngine method returns the values used and calculation results from the TaxEngine to
/// the webpage. Depending on the level of complexity that your integration requires, you may find that
/// you only need the document's total tax amount or you may find that you need as much as every line's
/// tax schedule ID, taxable amount, and tax amount plus the document's exempt amount, total's, etc.
/// </summary>
/// <remarks>
/// Before the code can call the CopyFromTaxEngine method, it must call the CopyToTaxEngine method.
/// Failure to do so will result in a null object reference error.
/// </remarks>
private void CopyFromTaxEngine()
{
if (txEngn.DocLoaded())
{
/// Update the webpage to ensure that it matches/displays the current document level values.
txtCustomer.Text = txEngn.DocCustomerID;
txtDocNumber.Text = txEngn.DocNumber;
if (txtAddress.Text == string.Empty)
txtAddress.Text = txEngn.DocDefaultShipToAddressID;
if (txtDocSched.Text == string.Empty)
txtDocSched.Text = txEngn.DocDefaultTaxScheduleID;
if (txtShippingMethod.Text == string.Empty)
txtShippingMethod.Text = txEngn.DocDefaultShippingMethod;
/// We call the ClearLine method clear the line item level fields on the webpage. This will help
/// ensure that the webpage accurately reflects the values that are being used in the TaxEngine's
/// tax calculations.
ClearLine();
/// We will now retrieve information from the line items to demonstrate the TaxEngine's results.
for (int lineIndex = 0; lineIndex < txEngn.LineCount; lineIndex++)
{
try
{
txEngn.LineIndex = lineIndex;
if (txEngn.LineExists)
{
/// We use the TaxEngine's line item values to update the webpage.
txtZip.Text = txEngn.LineZip;
txtCity.Text = txEngn.LineCity;
txtCounty.Text = txEngn.LineCounty;
txtState.Text = txEngn.LineState;
txtLineSched.Text = txEngn.LineTaxScheduleID;
txtRate.Text = txEngn.LineInitialTaxPercent.ToString() + "%";
}
else
{
txtAddress.Text = txEngn.DocDefaultShipToAddressID;
txtMessage.Text = txtMessage.Text + " Line index " +
lineIndex.ToString() + " not found.";
}
}
catch (Exception exc)
{
txtMessage.Text += " " + exc.Message;
if (txEngn.LineRequirementsMet == false)
txtMessage.Text += " " + txEngn.LineRequirements;
}
}
/// Here we are populating fields on the webpage with the tax calculation results.
txtTaxableSales.Text = txEngn.DocTaxableAmount.ToString();
txtSubtotal.Text = txEngn.DocExtendedPrice.ToString();
txtTax.Text = txEngn.DocTaxAmount.ToString();
txtTotal.Text = txEngn.DocTotalAmount.ToString();
/// Now that we have obtained all of the information that we need from the TaxEngine,
/// the DocDelete method can be called. This method will clear the temporary
/// record for this document from the Transaction Document table (DzTe0010).
/// If you would like to retain a separate set of transaction history in the
/// TaxEngine's built-in, history tables, then the document could instead be saved
/// or posted by calling the DocSave or DocPost methods, respectively.
/// For the purpose of this example, history is not being kept in the TaxEngine's
/// tables, so the transaction is now deleted.
txEngn.DocDelete();
}
else
{
ClearLine();
ClearDoc();
}
}
/// <summary>
/// Clears line item level fields on the webpage.
/// </summary>
private void ClearLine()
{
txtZip.Text = string.Empty;
txtCity.Text = string.Empty;
txtState.Text = string.Empty;
txtLineSched.Text = string.Empty;
}
/// <summary>
/// Clears document level fields on the webpage.
/// </summary>
private void ClearDoc()
{
txtSubtotal.Text = string.Empty;
txtTax.Text = string.Empty;
txtTotal.Text = string.Empty;
}
/// <summary>
/// The btnCalculate_Click calls the TaxEngine to calculate tax and
/// then populates the txtMessage field on the webpage with the tax
/// amounts broken down by Tax Detail ID.
/// Tax is based on the item number, customer ID, ship to address,
/// item quantity, and unit price.
/// This process demonstrates how the TaxEngine honors DynamicZip
/// and Microsoft Dynamics® GP tax related settings, as well as the
/// values that the TaxEngine is able to return.
/// </summary>
protected void btnCalculate_Click(object sender, EventArgs e)
{
string newFieldValue;
StringBuilder taxDetails = new StringBuilder();
int[] columnWidth = new int[4];
columnWidth[0] = 16;
columnWidth[1] = 31;
columnWidth[2] = 15;
columnWidth[3] = 11;
try
{
/// Update the TaxEngine with the values on the webpage.
CopyToTaxEngine();
/// The DocCalculateTax method calculates tax for each line item in the
/// document. This method must be called for tax to be calculated.
txEngn.DocCalculateTax();
newFieldValue = "Tax Detail ID";
newFieldValue = newFieldValue.PadRight(columnWidth[0]);
taxDetails.Append(newFieldValue);
newFieldValue = "Tax Detail Description";
newFieldValue = newFieldValue.PadRight(columnWidth[1]);
taxDetails.Append(newFieldValue);
newFieldValue = "Taxable Amount";
newFieldValue = newFieldValue.PadRight(columnWidth[2]);
taxDetails.Append(newFieldValue);
newFieldValue = "Tax Amount";
newFieldValue = newFieldValue.PadRight(columnWidth[3]);
taxDetails.AppendLine(newFieldValue);
foreach (TrxTaxDetail trxDtl in txEngn.DocTaxDetails(TaxDetails.Transaction))
{
newFieldValue = trxDtl.ID;
newFieldValue = newFieldValue.PadRight(columnWidth[0]);
taxDetails.Append(newFieldValue);
newFieldValue = trxDtl.Description;
newFieldValue = newFieldValue.PadRight(columnWidth[1]);
taxDetails.Append(newFieldValue);
newFieldValue = trxDtl.TaxedAmount.ToString();
newFieldValue = newFieldValue.PadRight(columnWidth[2]);
taxDetails.Append(newFieldValue);
newFieldValue = trxDtl.TaxAmount.ToString();
newFieldValue = newFieldValue.PadRight(columnWidth[3]);
taxDetails.AppendLine(newFieldValue);
}
txtMessage.Text = taxDetails.ToString();
/// Update the webpage with the values retrieved from the TaxEngine.
CopyFromTaxEngine();
}
catch (Exception ea)
{
txtMessage.Text = ea.Message;
}
}
/// <summary>
/// The btnSaveDoc_Click saves the document to the TaxEngine's built-in,
/// transaction history tables. This process does not save the transaction to
/// Microsoft Dynamics® GP, but rather is meant to demonstrate the TaxEngine's
/// ability to retain a seperate set of transaction history records for
/// printing reports from the KDControlCenter.exe.
/// Please note that transactions can also be imported from Microsoft Dynamics® GP
/// into the TaxEngine's history tables via the KDControlCenter's TE Document
/// Import window. See the TaxEngine Online Help (KDTaxEngine.chm) for more
/// information.
/// </summary>
protected void btnSaveDoc_Click(object sender, EventArgs e)
{
try
{
/// Copy the information from the webpage to the TaxEngine.
CopyToTaxEngine();
/// Save the document to the TaxEngine's history tables.
txEngn.DocSave();
/// Clear fields and prepare for the next document.
txtCustomer.Text = string.Empty;
txtAddress.Text = string.Empty;
ClearLine();
ClearDoc();
/// Display a confirmation message.
txtMessage.Text = "Document Number " + docNumber + " saved.";
}
catch (Exception saveException)
{
txtMessage.Text = saveException.Message;
}
}
}
}
taxengine/integration/code_samples/c_sample_code.1429140916.txt.gz · Last modified: (external edit)
