Fix SuiteTax Partial Exemption Rounding Issue
SuiteTax rounds each half of a partial exemption separately, so the bill posts a penny over the supplier invoice. Fix it with a discount item.

On this page
A supplier bill using a partial exemption SuiteTax code landed £0.01 higher than the supplier's legal invoice. The VAT calculated to £415.39 instead of £415.38, and the Accounts Payable balance now shows a liability that doesn't match what you owe. This is a known SuiteTax rounding behavior, and there's a practical fix.
Why SuiteTax Calculates £415.39 Instead of £415.38
The problem starts with how SuiteTax splits a partial exemption into two tax components. When you apply a partial exemption code, NetSuite doesn't calculate one VAT amount at 20%. Instead, it breaks the calculation into a deductible portion and a non-deductible (recoverable) portion.
For your £2,076.92 net amount, the system generates:
| Tax Type | Rate | Calculation | Rounded Amount |
|---|---|---|---|
| VAT_GB_Deductible to Item Cost | 18.26% | £2,076.92 × 18.26% = £379.244592 | £379.25 |
| VAT_GB_REC | 1.74% | £2,076.92 × 1.74% = £36.138408 | £36.14 |
| Total VAT | 20.00% | £415.39 |
The supplier calculated £2,076.92 × 20% = £415.384, rounded down to £415.38. SuiteTax rounds each component separately, then adds them together. £379.25 + £36.14 = £415.39. That's your penny.
This isn't a configuration error. It's the arithmetic consequence of splitting one tax rate into two components and rounding at the line level. You can change rounding preferences in Setup > Accounting > Accounting Preferences > General Ledger, but you'll still get a variance because the two-component math produces a different result than the single-rate calculation.
The Manual Override Trap
You mentioned overriding the tax values after SuiteTax calculates them. That works for one-off transactions, but it breaks down when you're importing supplier bills in volume. Every override requires manual intervention, which means:
- Your AP clerk touches every partial exemption bill
- The audit trail shows a manual adjustment on each transaction
- Your import process can't handle the override automatically
From an audit perspective, this is where teams lose hours. The override isn't sustainable, and it introduces data entry risk on every single bill.
The Discount Item Solution
NetSuite's documented approach for tax rounding discrepancies uses discount items. This is the same mechanism NetSuite uses to reconcile register totals with ERP invoice amounts. The script creates a posting or nonposting discount item to absorb the rounding difference.
For your scenario, the fix works like this:
- Create a discount item specifically for tax rounding adjustments
- Apply the discount to the vendor bill to bring the total down to match the supplier's invoice
- Post the bill with the correct AP liability
Here's the practical setup:
Go to Lists > Accounting > Items > New
- Item Type: Discount
- Name: "Tax Rounding Adjustment"
- Account: Use the same expense account as the line items, or a dedicated rounding account
- Tax Code: Leave blank or set to Non-Taxable
- Is Taxable: Uncheck
When you enter the vendor bill, add the discount line for -£0.01. Your bill now shows:
| Line | Amount |
|---|---|
| Net Amount | £2,076.92 |
| VAT (per SuiteTax) | £415.39 |
| Discount | -£0.01 |
| Invoice Total | £2,492.30 |
The AP balance matches the supplier's legal invoice, and the £0.01 sits in your rounding account rather than inflating your supplier liability.
Automating the Adjustment for Imported Bills
If you're importing vendor bills, you don't want to manually add a discount line to each one. Instead, you can use a SuiteScript user event to apply the rounding adjustment automatically.
Here's a SuiteScript 2.1 example that runs after submit on vendor bill creation:
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/record', 'N/search'], function(record, search) {
function afterSubmit(context) {
if (context.type !== context.UserEventType.CREATE) return;
var billRecord = context.newRecord;
var taxTotal = Math.abs(billRecord.getValue({ fieldId: 'taxtotal' }));
var total = Math.abs(billRecord.getValue({ fieldId: 'total' }));
var lineCount = billRecord.getLineCount({ sublistId: 'item' });
// Calculate what the tax should be at the single-rate level
// This example assumes one tax code at 20% - adjust for your rates
var netAmount = 0;
for (var i = 0; i < lineCount; i++) {
var amount = billRecord.getSublistValue({
sublistId: 'item',
fieldId: 'amount',
line: i
});
netAmount += Math.abs(amount);
}
var expectedTax = Math.round(netAmount * 0.20 * 100) / 100;
var difference = Math.round((taxTotal - expectedTax) * 100) / 100;
if (difference !== 0) {
// Add a discount line to absorb the rounding difference
var discountItemId = findDiscountItem();
if (discountItemId) {
var line = billRecord.getLineCount({ sublistId: 'item' });
billRecord.selectNewLine({ sublistId: 'item' });
billRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'item',
value: discountItemId
});
billRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'quantity',
value: 1
});
billRecord.setCurrentSublistValue({
sublistId: 'item',
fieldId: 'rate',
value: -difference
});
billRecord.commitLine({ sublistId: 'item' });
}
}
}
function findDiscountItem() {
var items = search.create({
type: search.Type.ITEM,
filters: [
['itemtype', 'anyof', 'Discount'],
'and',
['isinactive', 'is', 'F']
],
columns: ['internalid']
});
var results = items.run().getRange({ start: 0, end: 1 });
return results.length > 0 ? results[0].getValue({ name: 'internalid' }) : null;
}
return {
afterSubmit: afterSubmit
};
});Deploy this script to the Vendor Bill record (record type vendorbill) with an After Submit trigger. The script compares SuiteTax's calculated tax against the expected single-rate amount and creates a discount line for the difference.
What About the Audit Trail?
Your auditors will want to see why that discount line exists. The discount item name "Tax Rounding Adjustment" tells the story. You can also add a memo on the discount line referencing the supplier's invoice number and the rounding variance.
If you need a cleaner trail, create a separate expense account called "Tax Rounding Differences" instead of using a standard expense account. Then you can run a report on that account to show all rounding adjustments for the period.
When to Open a NetSuite Case
The discount item approach solves the immediate problem, but you should still open a case with NetSuite support. This is a SuiteTax calculation behavior that affects any UK partial exemption at 20%. NetSuite may update the tax engine in a future release to round the combined components rather than each individually.
Include your exact transaction example in the case. Show the supplier's calculation, the SuiteTax breakdown, and the £0.01 variance. NetSuite support can escalate this to the tax engine team.
Test Before You Roll Out
Before applying the script to all imported bills, test it on a sandbox account with a few sample transactions. Verify that:
- The discount line posts to the correct account
- The AP balance matches the supplier invoice
- The VAT return still reports the correct amounts
- The audit trail shows the adjustment clearly
The discount item approach keeps your AP balances clean and your VAT reporting accurate. It's a supported pattern rather than a workaround. For more on SuiteTax capabilities and limitations, review the NetSuite Frequently Asked Questions and the NetSuite Connector tax handling documentation.


