xMatix contains two different TDS comparisons:
- Deductee-side Form 26AS reconciliation compares tax-credit rows reported by deductors with the internal tax-credit adapters for the same financial year.
- Deductor-side TDS reconciliation compares tax your company deducted with Filed quarterly-return lines and Deposited/Verified challans.
They answer different questions and use different code paths. Do not use one comparison's status or screen actions as evidence for the other.
Form 26AS: current supported boundary
The data model contains Form26ASStatement, Form26ASLine and Form26ASReconciliationEntry. The backend statement handler exposes PerformForm26ASReconciliation, which can replace and rebuild persisted result entries for one statement.
There is currently no Form 26AS file parser or Form26ASLine handler in the runtime. Creating a statement header or attaching its file does not populate line rows, validate them, or calculate Total/Valid/Error row counts. The current New Form 26AS screen shows only that generic header, so it is not useful evidence of the documented import/reconciliation workflow and is intentionally omitted.
Step 1 — Create the statement and retain the source
Create one statement header for the exact financial year in YYYY-YY or YYYY-YYYY form and attach the downloaded file as evidence if your tenant uses File Assets. A file attachment is archival evidence only; saving it does not parse the file.
Set header status and row-control totals only through a controlled import process that can substantiate those values. The reconciliation engine updates matched/mismatch/missing/extra counts and Reconciled At; it does not calculate Total Rows, Valid Rows or Error Rows.
Step 2 — Populate Form26ASLine explicitly
Use a reviewed data import or integration to create Form26ASLine rows linked by Form26ASStatementId. At minimum, map and validate PAN, TAN, section code, financial year, amount paid and TDS amount. Retain deductor name, transaction date, quarter and booking status where the source supplies them.
Because no line handler currently validates an inserted row, your import must assign ValidationStatus deliberately:
- rows marked Invalid are excluded by the reconciliation engine;
- rows marked Valid are included; and
- rows left Pending or blank are also included because the engine excludes only the explicit Invalid value.
Reconcile imported row count and tax totals to the original file outside the generic header form before continuing.
Step 3 — Run the persisted backend reconciliation
Where the tenant's metadata exposes the statement action, run Perform Form 26AS Reconciliation on the intended header. The backend refuses a statement still marked Parsing or one without a valid financial year. No seeded action definition was found during this review, so an absent button can mean the handler exists but the tenant metadata has not exposed it.
The engine normalizes and groups both sides by:
PAN + TAN + section code + financial year
It sums Amount Paid and TDS per key and compares both values with zero-rupee tolerance. It replaces prior reconciliation entries, clears old line reconciliation states and records:
| Result | Meaning |
|---|---|
| Match | Both grouped values are identical |
| Unmatched | The key exists on both sides, but Amount Paid or TDS differs |
| Missing in 26AS | Internal tax-credit data has the key; the imported statement does not |
| Missing in books | The imported statement has the key; the internal adapters do not |
After the action commits, verify the persisted Form26ASReconciliationEntry rows and header counts, not just what a widget happens to render.
Step 4 — Investigate and rerun
Trace each non-match to the source credit and imported lines. Correct books only when the books are wrong; otherwise obtain a deductor correction and import the authoritative portal change. A rerun replaces the previous result set, so compare before/after counts and retain evidence of the correction.
Important limitation of the current Form 26AS widget
The Form26ASReconciliation widget is a separate client-side comparison. It does not call PerformForm26ASReconciliation or read the persisted reconciliation entries described above. It currently:
- groups the two sides by TAN only;
- classifies a match by rounded TDS equality, without comparing Amount Paid or the full PAN/TAN/section/FY key;
- loads all TDS transaction rows because its intended TDS/source filter is disabled; and
- keeps Customer Correction, Books Correction, Add in Book, Ignore and Follow-up selections only in React screen state.
Those visible action labels are lost on reload and are not an audited remediation record. Use the widget as an exploratory view only. For a statutory tie-out, use the controlled line import and persisted backend result, or clearly document that the backend action is not exposed in the tenant.
Deductor-side books, returns and challans
The TDS Reconciliation widget uses the server's deductor-side engine. For one partner account, financial-year start and Nature (TDS or TCS), it compares:
- non-reversed, positive withholding transactions in the financial year;
- deductee lines from Filed quarterly returns; and
- Deposited or Verified challans and the amounts Filed returns utilized.
It reports quarter totals, deductions not reported, Filed return lines whose live books row is absent, carried deductions and deposited-versus-utilized challan differences. Unlike the Form 26AS widget's local labels, its offered remediation paths call server services—for example challan allocation/deposit, adding an eligible deduction to an open return, creating a correction route, or moving a deposited unreported row to a later open return. Each action still enforces its own state and required inputs; a refused action must be resolved from the reason returned by the server.
Run this comparison after deposits and return filing states are current. Read each two-line row carefully: return evidence and books evidence remain separate even when the quarter's grand totals happen to agree.
Expected result
For Form 26AS, every source line was loaded by an explicit controlled import and the persisted engine compared the full statutory key with exact values. For deductor reconciliation, live withholding rows, Filed return lines and paid challans are tied by quarter, with every exception either remediated through a supported server action or retained with an owner and evidence.
Common questions
Why did attaching the Form 26AS file create no lines?
No runtime parser is implemented. Populate Form26ASLine through a controlled import or integration and link every row to the statement.
Why do the widget buckets disagree with persisted counts?
They are different algorithms. The widget groups by TAN and compares TDS client-side; the backend groups by PAN, TAN, section and financial year and compares both Amount Paid and TDS.
Why was a Pending Form 26AS line included?
The backend excludes only ValidationStatus = Invalid. Pending or blank rows remain eligible, so the import must set validation status reliably.
How exact is the backend comparison?
Exact to the rupee value stored: the tolerance constant is zero for both grouped Amount Paid and grouped TDS.
