====== Sample ASP App in C# ====== Please see [[taxengine:install:getting_started|Getting Started]] for help with using the KampData TaxEngine. 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(); /// /// The CopyToTaxEngine method provides the TaxEngine with the information entered on the webpage. /// 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; } } /// /// 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. /// /// /// 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. /// 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(); } } /// /// Clears line item level fields on the webpage. /// private void ClearLine() { txtZip.Text = string.Empty; txtCity.Text = string.Empty; txtState.Text = string.Empty; txtLineSched.Text = string.Empty; } /// /// Clears document level fields on the webpage. /// private void ClearDoc() { txtSubtotal.Text = string.Empty; txtTax.Text = string.Empty; txtTotal.Text = string.Empty; } /// /// 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. /// 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; } } /// /// 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. /// 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:sample_code|Sample Code]] \\ [[taxengine:integration:code_samples:dex_sample_code|Sample Code in Dexterity]]