Suite Utils
Back to Blog
NetSuite TipsSep 23, 2026 • 7 min read

Fix NetSuite Vendor Prepayment TDS Application Issue

Learn how to resolve NetSuite's vendor prepayment TDS application issue, preventing compliance exposure and ensuring accurate trade payables tie-out.

Sarah Jenkins, CPASarah Jenkins, CPAPrincipal Finance Automation Specialist
Fix NetSuite Vendor Prepayment TDS Application Issue
On this page

When a Vendor Prepayment with TDS deducted at the advance stage gets applied against a Vendor Bill in NetSuite India Localization, only the Basic + GST portion applies. The TDS leg remains stranded on the vendor account, the advance never fully clears, and TDS gets double-counted, once on the prepayment and again on the bill. This breaks the vendor sub-ledger tie-out to trade payables and creates a compliance exposure that surfaces in every period-end reconciliation.

The Mechanics Behind the Stranded TDS

In a standard SuiteTax India implementation, a Vendor Prepayment records three components: the basic amount, the GST liability, and the TDS deducted under Section 194C/194J. When you later create a Vendor Bill for the same expense and apply the prepayment, the application logic only matches the basic and GST lines. The TDS line from the prepayment has no corresponding reversal entry in the application transaction, so it stays open on the vendor ledger.

Worked example (simplified): Advance: Basic ₹100, TDS ₹10, Bank out ₹90. Bill: Expense ₹100, GST ₹18, TDS ₹10. Expected: Application reverses the advance TDS ₹10, net payable on Bill = ₹18, advance fully knocked off. Actual: Only ₹90 (Basic + GST) applies. The ₹10 TDS leg remains open on the vendor.

The control here is the Vendor Prepayment Application record, it must generate a reversing TDS line when the advance and bill fall in the same TDS period. Without it, your auditors will flag the unreconciled vendor balance.

Scenario Rules That Determine the Fix

The correct TDS treatment depends on the period relationship between the prepayment and the bill:

ScenarioRequired Behavior
Same TDS period (advance and bill in same quarter)Application must reverse the advance TDS leg so TDS isn't charged twice
Different period (advance TDS already deposited for closed period)Do NOT reverse in the application; handle double deduction via TDS return adjustment
No TDS on the BillNo reversal required; advance TDS stands as final deduction

Your configuration must enforce these rules automatically. Manual journal entries to clear stranded TDS defeat the audit trail and reintroduce the spreadsheet workaround.

Native Configuration Checklist

Before building custom logic, verify these SuiteTax India settings. Exact navigation paths vary by account configuration, use the global search (Alt+G) for "TDS Setup" if the menu path differs:

  1. TDS Section Mapping, Confirm the prepayment and bill use the same TDS section (e.g., 194C for contracts, 194J for professional fees). Mismatched sections prevent auto-reversal.
  2. TDS Period Alignment, At Setup > Accounting > Accounting Periods, ensure the TDS quarter (Q1–Q4) aligns with your posting periods. The application reversal only triggers when both transactions fall in the same TDS quarter.
  3. Vendor Prepayment Form, On the custom Vendor Prepayment form (if customized), verify the TDS Details subtab includes the TDS Amount and TDS Rate fields populated from the vendor's TDS master at Lists > Relationships > Vendors > TDS Details. Field IDs for these values are account-specific; confirm them in the Record Browser or via the NetSuite Connector field ID reference.
  4. Apply Prepayment Preference, At Setup > Accounting > Preferences > Vendor Prepayments, confirm Allow Partial Application is enabled. This doesn't fix TDS but permits partial knock-off while you resolve the reversal logic.

If all above are correct and the TDS leg still strands, the gap is in the application posting logic, a known limitation in the standard India Localization SuiteApp.

Customization Approach: SuiteScript 2.1 User Event Script

The cleanest fix is a User Event script on the Vendor Prepayment Application record (vendorprepaymentapplication) that inserts the reversing TDS line when conditions are met. This keeps the audit trail intact and avoids manual JEs.

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 * @NModuleScope SameAccount
 */
define(['N/record', 'N/search', 'N/runtime'],
    (record, search, runtime) => {

        // FIELD IDs ARE ACCOUNT-SPECIFIC — VERIFY IN YOUR SANDBOX FIRST
        // Use the Records Browser (Alt+Shift+R) or the [NetSuite Connector field ID guide](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_162611905808.html)
        const TDS_FIELDS = {
            amount: 'custbody_tds_amount',      // Example: custom body field for TDS Amount
            rate: 'custbody_tds_rate',          // Example: custom body field for TDS Rate
            section: 'custbody_tds_section',    // Example: custom body field for TDS Section
            period: 'custbody_tds_period'       // Example: custom body field for TDS Period
        };

        function beforeSubmit(context) {
            if (context.type !== context.UserEventType.CREATE &&
                context.type !== context.UserEventType.EDIT) return;

            const appRec = context.newRecord;
            const prepaymentId = appRec.getValue('prepayment');
            const billId = appRec.getValue('bill');

            if (!prepaymentId || !billId) return;

            const prepayment = record.load({
                type: record.Type.VENDOR_PREPAYMENT,
                id: prepaymentId
            });
            const bill = record.load({
                type: record.Type.VENDOR_BILL,
                id: billId
            });

            const prepayTDS = prepayment.getValue(TDS_FIELDS.amount) || 0;
            const billTDS = bill.getValue(TDS_FIELDS.amount) || 0;

            // Same TDS section & same TDS quarter = reverse advance TDS
            const sameSection = prepayment.getValue(TDS_FIELDS.section) ===
                                bill.getValue(TDS_FIELDS.section);
            const sameQuarter = prepayment.getValue(TDS_FIELDS.period) ===
                                bill.getValue(TDS_FIELDS.period);

            if (prepayTDS > 0 && billTDS > 0 && sameSection && sameQuarter) {
                // Insert reversing TDS line on the application sublist
                const lineCount = appRec.getLineCount({ sublistId: 'apply' });
                for (let i = 0; i < lineCount; i++) {
                    if (appRec.getSublistValue({ sublistId: 'apply', fieldId: 'apply', line: i })) {
                        // TDS reversal field on apply sublist is typically custom
                        const reversalField = 'custcol_tds_reversal_amount'; // VERIFY THIS FIELD ID
                        if (appRec.getSublistField({ sublistId: 'apply', fieldId: reversalField, line: i })) {
                            appRec.setSublistValue({
                                sublistId: 'apply',
                                fieldId: reversalField,
                                line: i,
                                value: -prepayTDS  // negative = reversal
                            });
                        }
                        break;
                    }
                }
            }
        }

        return { beforeSubmit };
    });

Deploy this script Before Submit on the vendorprepaymentapplication record with Execute As Role: Administrator. Test in Sandbox with these steps:

  1. Create Vendor Prepayment: Basic ₹100, TDS ₹10 (Section 194C, Q1 FY25).
  2. Create Vendor Bill: Expense ₹100, GST ₹18, TDS ₹10 (same Section 194C, Q1 FY25).
  3. Apply prepayment to bill via the Apply Prepayment action on the Vendor Bill.
  4. Open the resulting Vendor Prepayment Application record. Verify the TDS reversal line shows -10.
  5. Run the Vendor Prepayment Application report, the advance should show Fully Applied with zero balance.

Edge Cases That Break the Automation

Edge CaseHandling
Partial application (prepayment > bill)Script must prorate TDS reversal: reversal = prepayTDS * (appliedAmount / prepayTotal)
Multiple TDS sections on one billLoop through bill expense lines; match each to prepayment TDS section
Advance TDS already deposited (Form 26Q filed)Add a Do Not Reverse TDS checkbox on the Vendor Prepayment form; script skips reversal when checked
Service vs. Material itemsTDS section differs (194J vs 194C); script uses section match, so it works for both

From an audit perspective, the script's beforeSubmit execution leaves a clean system note: "TDS reversal auto-applied per Section 194C Q1 FY25." Your auditors will thank you. For details on system note structure, see the System Notes Guide.

Validation Before Production

Run this SuiteQL in Analytics > SuiteQL to confirm zero stranded TDS across vendors. Adjust field names to match your account's actual TDS field IDs:

SELECT v.entityid AS vendor, v.companyname,
       SUM(CASE WHEN t.type = 'Vendor Prepayment' THEN t.custbody_tds_amount ELSE 0 END) AS prepay_tds,
       SUM(CASE WHEN t.type = 'Vendor Prepayment Application' THEN t.custbody_tds_reversal_amount ELSE 0 END) AS app_reversal_tds,
       SUM(t.custbody_tds_amount) AS net_tds_balance
FROM transaction t
JOIN vendor v ON t.entity = v.id
WHERE t.custbody_tds_amount IS NOT NULL
  AND t.trandate >= '2025-04-01'
GROUP BY v.entityid, v.companyname
HAVING ABS(SUM(t.custbody_tds_amount)) > 0.01
ORDER BY net_tds_balance DESC;

Any row returned = a vendor with unreconciled TDS. Fix the script logic or the data before period close.

What to Check Next

If the SuiteScript deployment resolves the same-period reversal but your team still sees stranded TDS on cross-period advances, the next step is a Scheduled Script that runs monthly to generate a TDS Reconciliation Report, mapping each advance TDS to its bill application or Form 26Q deposit. That report becomes your control evidence for the quarterly TDS return filing.

About the author

Put these ideas to work.

Suite Utils builds small NetSuite tools that fix the specific thing breaking your day. Each one runs as a native SuiteScript SuiteApp inside your account. No sales call, no onboarding.

Browse the Tools

Enjoyed this one?

Get NetSuite tips like this in your inbox. No spam. Practical guides only.

Keep reading