> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dualentry.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How VAT and GST Work in Bulk Import

> Why Bulk Import calculates VAT and GST from your stored rates instead of importing tax totals, and why imported totals can differ slightly from the source.

When you bulk-import bills, invoices, and other tax-bearing transactions, you reference a VAT or GST rate that already exists in DualEntry. DualEntry then calculates the tax on each line itself. It never imports a tax amount or tax total calculated by another system.

This page explains why DualEntry works this way, how it matches your file to a rate, and why the imported totals can differ by a few cents from the system you exported them from. For the import workflow itself, see [Bulk Import: Load Records from a File](./bulk-import).

## Why DualEntry calculates tax instead of importing it

DualEntry builds VAT and GST returns from the rate on each transaction line and the amount that rate was applied to. Every tax amount in the ledger can be traced back to a specific rate, a taxable base, and a supply date. That trace is what makes the returns reproducible for an auditor.

An imported tax total breaks that trace. It records a number without the calculation behind it, so DualEntry could not show which rate produced it or recalculate it later. Source systems also round tax differently, for example per document rather than per line. Accepting their totals would mix several rounding conventions in one ledger.

For those reasons Bulk Import applies the same tax engine as a transaction entered in the app or through the API. The import file names the rate, and DualEntry does the arithmetic. For how that engine handles nexus, rates, and tax codes, see [Non-US Taxes](../../core-financials/tax-management/non-us-taxes).

## Which record types and lines carry tax

Bulk Import supports VAT and GST on six record types. Tax applies at the line level, so each line can carry its own rate or none.

The record types and the lines that accept a tax reference:

| Record type | Item lines | Expense lines |
| - | - | - |
| Bills | Yes | Yes |
| Vendor credits | Yes | Yes |
| Invoices | Yes | Not applicable |
| Cash sales | Yes | Not applicable |
| Customer credits | Yes | Not applicable |
| Direct expenses | Yes | Not applicable |

Direct expense lines are account lines, but they use the same item tax columns. Every one of these record types also gains an optional **Supply Date** header column. VAT and GST returns assign a transaction to a period by its supply date, not its posting date, so supply it whenever it differs from the transaction date.

## How a row is matched to a tax rate

Bulk Import matches a line to a rate using four columns together. On expense lines the same four columns are prefixed with `Expense`, for example **Expense Tax Name**.

The four tax columns on an item line:

| Column | What it holds | Example |
| - | - | - |
| **Tax Name** | The rate's name as it appears in Tax Setup, in any capitalization | `Standard` |
| **Tax Percent** | The rate's percentage, written as `20` or `20%` | `20` |
| **Tax Country** | The rate's country as an ISO 3166 two-letter code | `GB` |
| **Tax Regime** | `VAT` or `GST` | `VAT` |

The four columns work as a set. Leave all four blank and the line imports with no tax. Fill in any one of them and the other three become required for that line.

Rate names are not unique on their own. Two countries can each have a rate called Standard, and a country can keep an old and a new rate under the same name across a rate change. The combination of name, percent, country, and regime, together with the date check below, is what identifies one rate.

A matched rate also has to pass these checks:

* **Active**: archived rates are rejected, with a separate message from a rate that does not exist.
* **Effective on the date**: the rate's Valid From and Valid To range must include the line's date. Bulk Import uses the Supply Date if you provide one, then the transaction date, then the posting date.
* **Exactly one match**: if more than one active, in-date rate shares the same name, percent, and country, the row is rejected rather than guessed. Rename one of the rates in Tax Setup to make the combination unique.

Bulk Import does not create or edit rates. Every rate a file references must already exist under **Configuration → Tax Setup**. The company on the row also needs a [nexus](../../core-financials/tax-management/non-us-taxes#how-non-us-tax-works-in-dualentry) for that country, or the row fails when DualEntry saves it. A tax error fails only the record it belongs to. Other rows in the file still import. For the full list of messages, see [Bulk Import Errors](./bulk-import-errors).

## How DualEntry calculates tax on each line

DualEntry treats every imported line amount as net of tax. It multiplies the line's taxable amount by the matched rate and adds the result on top, so the document total is the net amount plus tax.

Three rules govern the arithmetic:

* **Per line**: tax is calculated separately for each line, and the document's tax is the sum of the line amounts.
* **Rounded to the cent**: each line's tax is rounded to two decimal places, with halves rounded up.
* **After discounts**: on sales records, the taxable amount is the line net of any discount.

GST tax codes with components, such as India's CGST and SGST split, follow the same approach. DualEntry calculates each component and the line's tax is their sum.

## Why imported totals can differ from the source system

Imported totals can differ from the source system even when every row imports cleanly. Most differences are a cent or two. Larger ones usually point to a problem in the source data rather than in the import.

### Rounding per document instead of per line

The most common cause of a small difference is a source system that rounds tax once on the document total instead of on each line. DualEntry always rounds per line.

For example, a bill has three lines of £0.99 each at the UK standard VAT rate of 20%:

| Method | Calculation | VAT |
| - | - | - |
| Per line (DualEntry) | £0.198 rounds to £0.20, three times | £0.60 |
| Per document | £2.97 × 20% = £0.594, rounded once | £0.59 |

The bill imports into DualEntry at £3.57 against £3.56 in the source. Each difference is small, but across thousands of historical documents they add up in AP or AR.

### Prices that include tax in the source

DualEntry has no tax-inclusive option in Bulk Import. If the source system stores gross, tax-inclusive line amounts, convert them to net amounts before import. Otherwise DualEntry adds tax on top of an amount that already contains it, and the document total is overstated by the full tax amount. Rounding during that conversion can also shift a line's net amount by a cent.

### A different or incorrect rate

A difference larger than rounding usually means the line references a different rate from the one the source system used. The source may have applied an outdated rate, calculated tax against the wrong base, or had its tax edited by hand. Since DualEntry recalculates from the rate you reference, it corrects those errors rather than carrying them forward. Confirm the rate on the row before treating the difference as an import problem.

DualEntry does not compare its totals against the source system's totals during import. Reconcile AP and AR balances against the source after a migration, as you would for any other cutover. For a structured approach, see [How to Validate a Migration](../../get-started/validate-a-migration).

## What Bulk Import does not do with tax

Some tax behavior is out of scope for Bulk Import:

* **No tax amount column**: the templates have no column for a tax amount or total. A tax total in your file has no field to map to.
* **No tax-inclusive amounts**: every line amount is treated as net of tax.
* **No US sales tax**: the tax columns accept only VAT and GST rates. US sales tax is not applied through Bulk Import. See [US Taxes](../../core-financials/tax-management/us-taxes) for how it is calculated on transactions.
* **No rate or nexus setup**: rates and nexuses must exist before you import.

Re-importing a record that matches an existing one on its match key updates the tax like any other field. If the file references a different rate, DualEntry recalculates the line with the new rate.

## Related

* [Bulk Import: Load Records from a File](./bulk-import)
* [Bulk Import Errors](./bulk-import-errors)
* [How to Fix a Failed Bulk Import](./fix-a-failed-bulk-import)
* [Non-US Taxes](../../core-financials/tax-management/non-us-taxes)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.