tdsdesk
tdsdesk is a command-line TDS desk for Indian businesses. It reads a payments register and a deductee master, works out the section, rate and tax for every payment under FY-versioned rules (thresholds with catch-up, 206AA, 206AB, section 197 certificates, GST exclusion), allocates challans, computes section 201(1A) interest and the 234E fee, prepares 26Q return data and 16A certificate data, and reconciles against a 26AS-style statement.
Features
- FY-versioned rules data (
2024-25,2025-26) with citations; no rates in code. Effective-dated slabs (194H changed on 1-Oct-2024). - Sections 194C, 194J (professional and technical), 194I (plant and machinery, land and building), 194H, 194A, 194Q.
- Per deductee, per section threshold tracking with catch-up deduction at the crossing payment; 194Q on the excess only.
- Higher-rate rules 206AA (missing or inoperative PAN) and 206AB, and lower-deduction certificates with limit and validity window.
- TDS on the amount excluding separately stated GST; earlier-of-credit-and-payment date.
- Deposit due dates (7th, 30 April for March), interest 1% / 1.5% per month or part, late filing fee 234E.
- FIFO challan allocation by section group with shortfall and excess flags.
- 26Q deductee annexure (NSDL RPU-style columns, an intermediate format), section summary, challan details and 16A data as CSV.
explainprints the whole derivation for one payment;reconcilecompares with a 26AS-style CSV.
Install
cd tdsdesk
uv venv .venv && uv pip install -p .venv/bin/python -e '.[dev]'
source .venv/bin/activate
Quickstart
cd examples
tdsdesk compute payments.csv --deductees deductees.csv --fy 2025-26 -o tds.csv
tdsdesk thresholds --fy 2025-26 --only-crossed
tdsdesk interest -c challans.csv --as-on 2026-03-31
tdsdesk return 26Q --quarter Q2 --fy 2025-26 -c challans.csv -o out/ --filing-date 2025-11-10
tdsdesk explain P0046 -c challans.csv --as-on 2026-03-31
tdsdesk reconcile 26as.csv -c challans.csv --as-on 2026-03-31
payments.csv, deductees.csv and challans.csv are read from the current directory unless -p, -d, -c say otherwise.
Input files
deductees.csv: deductee_id, name, pan, type (individual|huf|company|firm), resident (Y/N), ldc_cert_no, ldc_section, ldc_limit, ldc_rate, ldc_valid_from, ldc_valid_to, specified_206ab (Y/N), pan_aadhaar_operative (Y/N)
payments.csv: payment_id, credit_date, payment_date, deductee_id, nature, amount, gst_amount, invoice_ref, deduction_date
(amount includes GST; gst_amount is the separately stated part; dates YYYY-MM-DD; deduction_date is optional and defaults to the earlier of credit and payment date.)
Natures: contract, professional_fees, technical_services, rent_land_building, rent_plant_machinery, commission, interest, purchase_of_goods.
challans.csv: bsr_code, date, challan_serial, amount, section (section as 194C, 94J, 94JB and similar).
26as.csv: pan, section, amount_paid, tax_deducted, tax_deposited.
Usage with real output
The examples/ data set is synthetic: 60 deductees (3 without PAN, 1 with an inoperative PAN, 1 non-resident, a 206AB-flagged vendor,
a section 197 certificate that expires on 30 Sep 2025), 900 payments across all sections, GST on most services, a few late
deductions, late challans and one short-paid challan. Regenerate it with python examples/generate.py.
compute
$ tdsdesk compute payments.csv --deductees deductees.csv --fy 2025-26 -o tds.csv
warning: non-resident deductee D056 Khan Enterprises & Co: payments skipped (27Q / sec. 195 is out of scope)
TDS computation FY 2025-26
┏━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Section ┃ Payments ┃ Base (excl. GST) ┃ Taxable base ┃ TDS ┃
┡━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ 194A │ 63 │ 253,100 │ 253,100 │ 28,510 │
│ 194C │ 234 │ 9,749,100 │ 9,749,100 │ 141,492 │
│ 194H │ 108 │ 577,600 │ 511,500 │ 21,948 │
│ 194I_LB │ 108 │ 5,242,500 │ 3,280,000 │ 328,000 │
│ 194I_PM │ 27 │ 720,000 │ 0 │ 0 │
│ 194J_PROF │ 162 │ 4,229,500 │ 4,229,500 │ 378,614 │
│ 194J_TECH │ 90 │ 3,140,100 │ 3,140,100 │ 62,802 │
│ 194Q │ 90 │ 44,153,600 │ 8,551,800 │ 23,654 │
│ TOTAL │ 882 │ 68,065,500 │ 29,715,100 │ 985,020 │
└───────────┴──────────┴──────────────────┴──────────────┴─────────┘
882 payments computed (18 skipped) -> /tmp/claude-1000/tds.csv
tds.csv holds one row per payment: status, catch-up base, taxable base, effective rate, rate basis and TDS.
thresholds
Thresholds FY 2025-26
┏━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┓
┃ ID ┃ Deductee ┃ Section ┃ Aggregate ┃ Threshold ┃ Headroom ┃ Pending ┃ State ┃
┡━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━┩
│ D001 │ Neha Gupta │ 194C │ 807,300 │ 100,000 │ - │ - │ crossed on 2025-05-09 │
│ D002 │ Sanjay Gupta │ 194J_PROF │ 288,700 │ 50,000 │ - │ - │ crossed on 2025-05-06 │
│ D003 │ Tara Khan │ 194I_LB │ 895,000 │ 600,000 │ - │ - │ crossed on 2025-09-18 │
│ D004 │ Meera Patil │ 194C │ 319,000 │ 100,000 │ - │ - │ crossed on 2025-07-14 │
│ D004 │ Meera Patil │ 194H │ 31,700 │ 20,000 │ - │ - │ crossed on 2026-02-21 │
interest and challan allocation
Interest u/s 201(1A), FY 2025-26
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Payment ┃ Section ┃ TDS ┃ Deducted ┃ Due ┃ Late deduction ┃ Late deposit ┃ Undeposited ┃ Undeposited int. ┃ Total ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ P0006 │ 194C │ 798 │ 2025-05-09 │ 2025-06-07 │ 16 │ 24 │ 0 │ 0 │ 40 │
│ P0059 │ 194C │ 790 │ 2025-06-03 │ 2025-07-07 │ 16 │ 0 │ 0 │ 0 │ 16 │
│ P0081 │ 194C │ 653 │ 2025-05-03 │ 2025-06-07 │ 0 │ 29 │ 0 │ 0 │ 29 │
│ P0083 │ 194C │ 408 │ 2025-05-04 │ 2025-06-07 │ 0 │ 18 │ 0 │ 0 │ 18 │
│ P0087 │ 194C │ 365 │ 2025-05-06 │ 2025-06-07 │ 0 │ 11 │ 0 │ 0 │ 11 │
└─────────┴───────────┴───────┴────────────┴────────────┴────────────────┴──────────────┴─────────────┴──────────────────┴───────┘
TDS deducted 985,020; deposited via challans 983,520; interest payable 811
flag: SHORTFALL P0894 (194C, deducted 2026-03-29): 404 not covered by any challan
flag: SHORTFALL P0895 (194C, deducted 2026-03-30): 1096 not covered by any challan
return 26Q
Form 26Q Q2 FY 2025-26
┏━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Section ┃ Deductees ┃ Amount paid ┃ TDS deducted ┃ TDS deposited ┃ Shortfall ┃
┡━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ 94A │ 6 │ 79,000 │ 9,070 │ 9,070 │ 0 │
│ 94C │ 13 │ 2,587,800 │ 41,517 │ 41,517 │ 0 │
│ 94H │ 7 │ 147,400 │ 9,536 │ 9,536 │ 0 │
│ 94IB │ 1 │ 635,000 │ 63,500 │ 63,500 │ 0 │
│ 94JA │ 4 │ 788,500 │ 15,770 │ 15,770 │ 0 │
│ 94JB │ 10 │ 1,182,600 │ 92,108 │ 92,108 │ 0 │
│ TOTAL │ 36 │ 5,420,300 │ 231,501 │ 231,501 │ 0 │
└─────────┴───────────┴─────────────┴──────────────┴───────────────┴───────────┘
annexure out/26Q_2025-26_Q2_deductee_annexure.csv
summary out/26Q_2025-26_Q2_summary.csv
challans out/26Q_2025-26_Q2_challans.csv
certificates out/16A_2025-26_Q2.csv
Due date 2025-10-31; filed 2025-11-10: 10 day(s) late, sec. 234E fee 2,000
Files written to out/: the deductee annexure, section summary, challan details and 16A_...csv.
explain
A catch-up crossing with GST excluded:
Payment P0046 (INV/2504/0046)
Deductee D026 Kestrel Software Pvt Ltd PAN TEGCC1123B type company
Nature technical_services -> section 194J_TECH (Fees for technical services / royalty on sale of films), NSDL code 94JA
Authority Sec. 194J(1)(ba): 2% on technical services, call centre and royalty for sale/distribution/exhibition of cinematographic films; same threshold proviso
Event date 2025-04-16 (earlier of credit 2025-04-16 / payment None)
Amount 42716 less GST 6516 = TDS base 36200
Threshold aggregate threshold 50000; aggregate 39600 -> 75800
Status aggregate_threshold_crossed
Catch-up 39600 of earlier payments deducted now, taxable base 75800 = 39600 + 36200
Rate 2% (before any section 197 certificate)
75800 x 2% = 1516 [normal]
TDS 1516 (rounded to the nearest rupee, sec. 288B)
Deducted on 2025-04-16 (quarter Q1); deposit due 2025-05-07
Challan 0510308/30002 dated 2025-05-06: 1516
Interest 201(1A)(i) late deduction 0; 201(1A)(ii) late deposit 0; undeposited 0; total 0
Note GST of 6516 excluded as separately stated
A deductee without PAN (206AA, 20%):
Payment P0298 (INV/2507/0298)
Deductee D034 Harbor Freight Pvt Ltd PAN not available type company
Nature commission -> section 194H (Commission or brokerage), NSDL code 94H
Authority Sec. 194H: rate 5% reduced to 2% w.e.f. 1-Oct-2024 (Finance (No.2) Act 2024); threshold per FY
Event date 2025-07-20 (earlier of credit 2025-07-20 / payment None)
Amount 8614 less GST 1314 = TDS base 7300
Threshold aggregate threshold 20000; aggregate 18000 -> 25300
Status aggregate_threshold_crossed
Catch-up 18000 of earlier payments deducted now, taxable base 25300 = 18000 + 7300
Rate 20% (before any section 197 certificate)
25300 x 20% = 5060 [206AA (no/inoperative PAN)]
TDS 5060 (rounded to the nearest rupee, sec. 288B)
Deducted on 2025-07-20 (quarter Q2); deposit due 2025-08-07
Challan 0510308/30013 dated 2025-08-04: 5060
Interest 201(1A)(i) late deduction 0; 201(1A)(ii) late deposit 0; undeposited 0; total 0
Note GST of 1314 excluded as separately stated
A catch-up under a section 197 certificate at 2%:
Payment P0058 (INV/2504/0058)
Deductee D031 Prism Consulting Pvt Ltd PAN NWSCW8150J type company
Nature professional_fees -> section 194J_PROF (Fees for professional services), NSDL code 94JB
Authority Sec. 194J(1)(b): 10% on professional services; proviso: no deduction if aggregate in FY does not exceed threshold
Event date 2025-04-21 (earlier of credit 2025-04-21 / payment 2025-05-30)
Amount 30916 less GST 4716 = TDS base 26200
Threshold aggregate threshold 50000; aggregate 36700 -> 62900
Status aggregate_threshold_crossed
Catch-up 36700 of earlier payments deducted now, taxable base 62900 = 36700 + 26200
Rate 10% (before any section 197 certificate)
62900 x 2% = 1258 [197 certificate LDC/2025/0042]
TDS 1258 (rounded to the nearest rupee, sec. 288B)
Deducted on 2025-04-21 (quarter Q1); deposit due 2025-05-07
Challan 0510308/30002 dated 2025-05-06: 1258
Interest 201(1A)(i) late deduction 0; 201(1A)(ii) late deposit 0; undeposited 0; total 0
Note GST of 4716 excluded as separately stated
206AB on FY 2024-25 (small hand-written data set in examples/fy2024-25/; the section was omitted from FY 2025-26):
Payment A2 (INV/002)
Deductee V1 Redwood Services Pvt Ltd PAN AABCR1234K type company
Nature professional_fees -> section 194J_PROF (Fees for professional services), NSDL code 94JB
Authority Sec. 194J(1)(b): 10% on professional services; proviso: no deduction if aggregate in FY does not exceed threshold
Event date 2024-07-12 (earlier of credit 2024-07-12 / payment None)
Amount 118000 less GST 18000 = TDS base 100000
Threshold aggregate threshold 30000; aggregate 0 -> 100000
Status aggregate_threshold_crossed
Rate 20% (before any section 197 certificate)
100000 x 20% = 20000 [206AB (specified person)]
TDS 20000 (rounded to the nearest rupee, sec. 288B)
Deducted on 2024-07-12 (quarter Q2); deposit due 2024-08-07
Challan 20000 not covered by any challan
Interest 201(1A)(i) late deduction 0; 201(1A)(ii) late deposit 0; undeposited 2700; total 2700
- 20000 not deposited as on 2025-03-31: 9 month(s) at 1.5%
Note GST of 18000 excluded as separately stated
reconcile
examples/26as.csv has a changed tax figure, a changed amount, a missing row and an extra row planted in it.
Reconciliation
┏━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ PAN ┃ Section ┃ Status ┃ Detail ┃
┡━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ CLPCX5938P │ 94H │ MISMATCH │ tds_deducted: books 1124 vs 26AS 624; tds_deposited: books 1124 vs 26AS 624 │
│ HFGCX7136P │ 94JB │ MISMATCH │ amount: books 104000 vs 26AS 129000 │
│ HYTPK7791G │ 94H │ MISSING_IN_26AS │ │
│ PANNOTAVBL │ 94A │ MISSING_IN_26AS │ │
│ PANNOTAVBL │ 94H │ MISSING_IN_26AS │ │
│ PANNOTAVBL │ 94Q │ MISSING_IN_26AS │ │
│ ZZZPZ9999Z │ 94C │ MISSING_IN_BOOKS │ │
└────────────┴─────────┴──────────────────┴─────────────────────────────────────────────────────────────────────────────┘
63 PAN/section pairs: 56 match, 7 need attention
Deductees without a PAN always appear as missing in 26AS, which is the expected result.
Configuration
No config file. Options common to all commands: --fy (default 2025-26), -d/--deductees, -p/--payments, -c/--challans,
--as-on (date for undeposited-tax interest, default today) and --no-194q (buyer turnover did not exceed 10 crore).
Exit status is 2 with a one-line message for bad input (unknown FY, bad CSV value with file and line, unknown nature).
Rules are the JSON files in src/tdsdesk/data/.
Architecture
| Module | Role |
|---|---|
rules.py, data/fy_*.json |
Load FY rules into typed objects |
loaders.py |
CSV parsing and validation with line numbers |
engine.py |
Thresholds, catch-up, rate selection, rounding |
challans.py |
FIFO challan allocation |
interest.py |
201(1A) interest and 234E fee |
dates.py |
Month-or-part counting, due dates, quarters, FY |
returns.py |
26Q, summary, challan and 16A CSVs |
recon.py |
26AS reconciliation |
explain.py |
Narrative derivation |
pipeline.py, cli.py |
Wiring and the Click commands |
Deeper documents: docs/rules.md (sections, rates, citations), docs/algorithms.md (catch-up, precedence, interest and FIFO with worked examples), docs/limitations.md.
Tests
.venv/bin/pytest
75 tests: every section's rate and threshold in both FYs including exact-boundary and catch-up cases, 206AA / 206AB / 197 precedence, GST exclusion, rounding, month-or-part table, due dates including March, hand-computed interest and fee, challan FIFO, return CSV shape and totals, explain, reconcile, loaders and the CLI against the example data.
Limitations
Resident deductees and Form 26Q only; the 26Q output is an intermediate CSV, not an FVU file; some precedence rules and thresholds are marked illustrative. Rules data should be verified against current law before use. See docs/limitations.md. This tool is not tax advice.