Tax amount override in free text invoices

Introduction

One of the common issues we encounter when importing free text invoices into Dynamics AX is overriding the tax. Usually AX calculates the tax when sales invoice lines are inserted into the free text invoice. On some occasions, such as when integrating AX with external systems, users will want the tax calculated by AX to be overridden with the value form the external system so that the tax in  both system matches to the penny.

Override the tax manually

To override tax manually in free text invoices, go to Sales ledger/Common/Free text invoices/All free text invoices. Choose one of the free text invoices that has not been posted yet (e.g. no invoice Id was assigned). Then from the action pane, click on VAT under Details group. This will open a form that will look like this…

B1

Click on the Adjustment tab and you will see the following:

B2

In the form above, you can tick the “Override calculated VAT” field and then set the new tax value in the “Actual VAT amount” text box. Before you close the form, click apply.

Override the tax in x++

We will do the same exercise but from x++ code. There are many blogs and articles on how to do this but in order not to jump into different websites to get the code, I copied the code from a random website here below and then added my code afterwards.

So, the original code will look something like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void FreeTextTaxAdjust(Args _args)  
{  
  CustInvoiceTable    custInvoiceTable;  
  CustInvoiceCalcTax  custInvoiceCalcTax;  
  TaxFreeInvoice      taxFreeInvoice;  
  TaxRegulation       taxRegulation;  
  ;  
 
  ttsbegin;  
 
  select firstonly custInvoiceTable  
  where custInvoiceTable.RecId == 54371652769;  
 
  custInvoiceCalcTax = new CustInvoiceCalcTax_Table(custInvoiceTable);  
  taxFreeInvoice     = new TaxFreeInvoice(custInvoiceCalcTax);  
  taxFreeInvoice.calc();  
  taxRegulation = TaxRegulation::newTaxRegulation(taxFreeInvoice);  
  taxRegulation.allocateAmount(2.01);  
  taxRegulation.saveTaxRegulation();  
 
  ttscommit;  
}

As shown in the code above, this will override the total tax amount of the free text invoice from the automatically calculated £2 to £2.01. The issue with this is that AX will merge the taxes by the VAT code. So, if in the form above we had two tax codes (STD and RED) instead of only one tax code (STD), then the code above will not handle it. The code above will only allow inserting the total tax amount for both tax codes. It will not allow splitting the values for each tax code.

I managed to fix the issue by splitting the above into two steps:

  1. A method to get the tax code. In my case, I cross reference the Tax Group with the Tax Item Group to get the tax code. This can be done by using the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static TaxCode CWFGetCrossRefTaxCode(TaxGroup _taxGroup, 
                                            TaxItemGroup _taxItemGroup)
{
    TaxOnItem           taxOnItem;
    TaxGroupData        taxGroupData;
    TaxTable            taxTable;
    ;
 
    select firstonly TaxCode from taxTable
    join firstonly TaxGroup, TaxCode from taxGroupData
    where taxGroupData.TaxCode == taxTable.TaxCode
       && taxGroupData.TaxGroup == _taxGroup
    join firstonly TaxItemGroup, TaxCode from taxOnItem
    where taxOnItem.TaxCode == taxTable.TaxCode
       && taxOnItem.TaxItemGroup == _taxItemGroup;
 
    return taxTable.TaxCode;
}
  1. Use the tax code from the method above and pass it to the method below along with the new tax amount:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public static void CWFCalculateTax(TaxCode _taxCode, 
                                   TaxAmount _taxAmount, 
                                   CustInvoiceTable _custInvoiceTable)
{
    CustInvoiceCalcTax          custInvoiceCalcTax;
    TaxFreeInvoice              taxFreeInvoice;
    TaxRegulation               taxRegulation;
    TmpTaxWorkTrans             tmpTaxWorkTrans;
    TmpTaxRegulation            tmpTaxRegulation;
    ;
 
    ttsbegin;
 
    custInvoiceCalcTax = new CustInvoiceCalcTax_Table(_custInvoiceTable);
    taxFreeInvoice     = new TaxFreeInvoice(custInvoiceCalcTax, true, true, true);
    taxFreeInvoice.calcTax();
 
    taxRegulation = TaxRegulation::newTaxRegulation(taxFreeInvoice);
    tmpTaxRegulation = taxRegulation.tmpTaxRegulation();
    tmpTaxWorkTrans = taxRegulation.tmpTaxWorkTrans();
 
    while select tmpTaxRegulation
    where tmpTaxRegulation.TaxCode == _taxCode
    {
        tmpTaxRegulation.SourceRegulateAmountCur = _taxAmount;
        tmpTaxRegulation.OverrideCalculatedTax = NoYes::Yes;
        tmpTaxRegulation.update();
    }
 
    while select tmpTaxWorkTrans
        where tmpTaxWorkTrans.TaxCode == _taxCode
    {
        tmpTaxWorkTrans.SourceRegulateAmountCur = _taxAmount;
        tmpTaxWorkTrans.update();
    }
 
    taxRegulation.setTmpTaxWorkTransTmpData(tmpTaxWorkTrans);
    taxRegulation.saveTaxRegulation();
    ttscommit;
}

With the code above, I managed to override the tax amount for multiple tax codes only when I’ve updated the table TmpTaxWorkTrans.

Happy DAXing!