Tuesday 15 September 2020

How to calculate total tax for a order in D365 using X++

 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...

No comments:

Post a Comment