How to calculate total tax for a Sales order using X++
Today, I will show, how to calculate tax in D365 FO (AX) through code
Scenario 1: To find Sales Totals values for Sales order in D365
Here, my requirement is to export Sales Totals component's value through custom data entity. I have applied below logic, hope it will help you...
Accounts receivable/ All sales orders/ select any Sales order/ Sales order button group/ View/ Totals public void postLoad()
{
SalesLine salesLineLoc;
SalesTable salesTableLoc = SalesTable::find(this.SalesId);
SalesTotals totals;
super();
select sum(LineAmount) from salesLineLoc
where salesLineLoc.SalesId == salesTableLoc.SalesId;
this.SubTotalAmount = salesLineLoc.LineAmount;
// No problem if the total is not negative
totals = SalesTotals::construct(salesTableLoc, SalesUpdate::All);
totals.calc();
this.TotalEndDisc = conPeek(totals.displayFields(), TradeTotals::posEndDisc());
this.TotalLineDisc = conPeek(totals.displayFields(), TradeTotals::posLineDisc());
this.TotalCharges = conPeek(totals.displayFields(), TradeTotals::posMarkup());
this.InvoiceAmount = conPeek(totals.displayFields(), TradeTotals::posTotalAmount());
salesLineLoc = null;
salesLineLoc = SalesLine::findInventTransId(this.InventTransId);
if (salesTableLoc.HSChangedInD365 == NoYes::No)
{
this.WebShippingTaxAmount = salesTableLoc.HSWebChargeTaxAmountCur;
this.TotalTaxAmount = salesTableLoc.HSTotalWebTaxAmountCur;
this.LineTaxAmount = salesLineLoc.HSWebLineTaxAmountCur;
}
else
{
this.TotalTaxAmount = conPeek(totals.displayFields(), TradeTotals::posTaxTotal());
//this.TotalTaxAmount = abs(salesTotals.tax().totalTaxAmountCalculated()); // Total calculated sales tax amount
//this.TotalTaxAmount = abs(salesTotals.tax().totalTaxAmount()); // Total actual sales tax amount
totals.tax().sourceSingleLine(true, true);
this.LineTaxAmount = totals.tax().totalRegulatedTaxAmountSingleLine(salesLineLoc.TableId, salesLineLoc.RecId); // sales line actual tax amount
//this.LineTaxAmount = salesTotals.tax().totalTaxAmountSingleLine(salesLineLoc.TableId, salesLineLoc.RecId); // sales line calculated tax amount
// to get calculated tax for a particular charge line associated with a sales order.
MarkupTrans markupTransLoc;
select firstonly markupTransLoc
where markupTransLoc.MarkupCode == HSIntegrationParameters::find().PaidByCustomer //'CUSTFRGHT'
&& markupTransLoc.TransRecId == salesTableLoc.RecId
&& markupTransLoc.TransTableId == tableNum(SalesTable);
this.WebShippingTaxAmount = abs(totals.tax().taxPrLine(tableNum(MarkupTrans), markupTransLoc.RecId));
}
}
//You have to pass these values to the functions whether it comes from PurchLine or SalesLine or any other table.
//This may not work for Avalara tax engine then follow below scenarios...
Tax::calcTaxAmount(purchLine.TaxGroup, purchLine.TaxItemGroup, Systemdateget(), purchLine.CurrencyCode, purchLine.LineAmount, TaxModuleType::Purch);
Scenario 2.1: To calculate tax for each Sales order line in D365
I have written display method in SalesLine table to show line-wise calculated sales tax. This method can be utilized in multiple places...
public display TaxAmountCur displayLineTaxAmount()
{
salesTable salesTable;
SalesTotals salesTotals;
TaxAmountCur taxAmountCur;
salesTable = SalesTable::find(this.SalesId, false);
salesTotals = SalesTotals::construct(salesTable, SalesUpdate::All);
salesTotals.calc();
salesTotals.tax().sourceSingleLine(true, true);
taxAmountCur = salesTotals.tax().totalTaxAmountSingleLine(this.TableId, this.RecId);
return TaxAmountCur;
}
Scenario 2.2: To calculate tax for each Sales order line in D365
I have written display method in SalesLine table to show line-wise calculated sales tax. This method can be utilized in multiple places...
public display TaxAmount displayLineTaxAmount()
{
SalesLine salesLineLoc;
select firstonly salesLineLoc
where salesLineLoc.RecId == this.RecId;
return Tax::calcTaxAmount(salesLineLoc.TaxGroup,
salesLineLoc.TaxItemGroup,
Systemdateget(),
salesLineLoc.CurrencyCode,
salesLineLoc.LineAmount,
TaxModuleType::Sales);
}
Scenario 3: To calculate tax for Sales order in D365
I have written display method in SalesTable table to show total calculated sales tax. This method can be utilized in multiple places...
public display TaxAmountCur displayTotalTaxAmount()
{
salesTable salesTable;
SalesTotals salesTotals;
TaxAmountCur taxAmountCur;
salesTable = SalesTable::find(this.SalesId, false);
salesTotals = SalesTotals::construct(salesTable, SalesUpdate::All);
salesTotals.calc();
taxAmountCur = abs(salesTotals.tax().totalTaxAmount());
return TaxAmountCur;
}
Add display method as a data field in Field groups in a table
ScenariScenario 4: To calculate tax for each Purchase order line in D365.
I have written display method in PurchLine table to show line-wise calculated purch tax. This method can be utilized in multiple places...
public display TaxAmountCur totalTaxAmount(boolean _adjustTaxSign = true, boolean _includeUseTax = false)
{
PurchTotals purchTotals;
TaxAmountCur taxAmountCur;
purchTotals = PurchTotals::newPurchTable(this.purchTable());
purchTotals.calc();
purchTotals.tax().sourceSingleLine(true, true);
taxAmountCur = purchTotals.tax().totalTaxAmountSingleLine(this.TableId, this.RecId, _adjustTaxSign, _includeUseTax);
return taxAmountCur;
}
Scenario 5: To calculate tax for Purchase order in D365
I have written display method in PurchTable table to show total calculated purch tax. This method can be utilized in multiple places...
public display TaxAmountCur totalTaxAmount(boolean _adjustTaxSign = true, boolean _includeUseTax = false)
{
PurchTotals purchTotals;
TaxAmountCur taxAmountCur;
purchTotals = PurchTotals::newPurchTable(this.purchTable());
purchTotals.calc();
taxAmountCur = purchTotals.tax().totalTaxAmount();
return taxAmountCur;
}
Scenario 6: To calculate tax for GL journal in D365
I have written display method in LedgerJournalTrans table to show total calculated tax. This method can be utilized in multiple places...
public display TaxAmountCur totalTaxAmount(boolean _adjustTaxSign = true, boolean _includeUseTax = false)
{
TaxCalculation taxCalculation;
LedgerJournalTrans ledgerJournalTrans;
TmpTaxWorkTrans tmpTaxWorkTrans;
TaxAmountCur taxAmountCur;
ledgerJournalTrans = LedgerJournalTrans::findRecId(5637293082, false);
// This is from `\Classes\LedgerJournalEngine\getShowTax`
taxCalculation = LedgerJournalTrans::getTaxInstance(ledgerJournalTrans.JournalNum,
ledgerJournalTrans.Voucher,
ledgerJournalTrans.Invoice,
true,
null,
false,
ledgerJournalTrans.TransDate);
taxCalculation.sourceSingleLine(true, false);
// This is from `\Classes\TaxTmpWorkTransForm\initTax`
tmpTaxWorkTrans.setTmpData(taxCalculation.tmpTaxWorkTrans());
// This is the temporary table that is populated
while select tmpTaxWorkTrans
{
// This is from `\Classes\TaxTmpWorkTransForm\getSourceBaseAmountCur`
taxAmountCur = (tmpTaxWorkTrans.SourceTaxAmountCur * tmpTaxWorkTrans.taxChangeDisplaySign(null));
// This just outputs some data
info(strFmt("%1: %2", tmpTaxWorkTrans.TaxCode, taxAmountCur));
}
return taxAmountCur;
}
--------------------------------
Happy DAXing...