Offline Indian Income Tax computation tool for salaried individuals with ESOP/ESPP/RSU
Project description
itr-tool
Offline Indian Income Tax computation tool for salaried individuals with ESOP/ESPP/RSU.
Privacy-first, fully offline CLI. Parses Form 16, AIS, 26AS, E-Trade exports, broker P&L, and mutual fund reports. Computes tax under both old and new regimes, generates ITR-1/ITR-2 JSON, Statement of Total Income (STI), and PDF computation sheets.
Table of Contents
- Installation
- Quick Start
- Folder Structure
- Supported File Types
- config.yaml Reference
- Commands
- Interactive Config Wizard
- Encrypted Files & Passwords
- Vestwise ESOP/ESPP Workbook
- Outputs
- Multi-Year Usage
- FAQ
Installation
# Clone and install
git clone <repo-url>
cd itr-tool
pip install -e .
# Verify
itr-tool --version
itr-tool --help
Requirements: Python 3.11+
Key dependencies (installed automatically):
form16x— Form 16 PDF parseritd-aisparser— AIS JSON decryptorpdfplumber— PDF text extraction (fallback for encrypted/unusual PDFs)yfinance— Stock price lookup for ESOP sale price resolutionopenpyxl— Excel workbook generationrich— Beautiful CLI output
Quick Start
# 1. Organize your documents (see Folder Structure below)
# 2. Run the tool — it will guide you through config interactively
itr-tool compute "C:\Users\Me\IT\2026-27"
# Or skip the interactive wizard if config.yaml already exists
itr-tool compute "C:\Users\Me\IT\2026-27" --no-wizard
# Just create/update config.yaml without computing
itr-tool init "C:\Users\Me\IT\2026-27"
Folder Structure
Create one folder per assessment year (AY = FY + 1). The folder name should be the AY (e.g. 2026-27 for FY 2025-26).
IT/
└── 2026-27/ # Assessment Year folder
├── config.yaml # Personal details, deductions, bank accounts
│
├── Form 16/ # Employer Form 16 PDFs
│ ├── Employer1_Form16.pdf # (any naming works)
│ └── Employer2_Form16B.pdf # supports Part A + Part B splits
│
├── Employer/ # Employer perquisite workings
│ └── perquisite.pdf # ESOP perquisite rate extraction
│
├── E-Trade/ # E-Trade exports for ESOP/ESPP
│ ├── BenefitHistory.xlsx # ★ REQUIRED for Vestwise workbook
│ ├── G&L_Expanded_*.xlsx # Gains & Losses — STCG/LTCG
│ └── (can have multiple year files)
│
├── Stocks/ # Brokerage & MF reports
│ ├── taxpnl-*.xlsx # Broker tax P&L (Zerodha/Groww)
│ └── *Capital_Gains*.xlsx # Mutual fund CG report
│
├── IT/ # Income Tax department documents
│ ├── *_AIS*.json # AIS JSON (encrypted)
│ ├── *_AIS*.pdf # AIS PDF
│ ├── *_TIS*.pdf # TIS PDF
│ ├── *-26AS*.pdf # Form 26AS
│ └── Form16*.pdf # Form 16 from IT portal
│
├── Bank/ # Bank statements (optional)
│ └── *.pdf / *.csv
│
└── output/ # ← Generated automatically
├── STI_2025-26_Name.txt # Statement of Total Income
├── ITR2_AY202627.json # ITR-2 JSON (or ITR1_*)
├── TaxComputation_2025-26.pdf# PDF computation sheet
└── ESOP_Summary_2025-26.xlsx # Vestwise ESOP workbook
Accepted subfolder names
The tool scans for these folder name variants (case-sensitive on Linux, case-insensitive on Windows):
| Category | Accepted folder names |
|---|---|
| Form 16 | Form 16, form16, Form16, form 16, To Send |
| E-Trade | E-Trade, etrade, e-trade, ESOP ESPP, ESOP |
| Employer perq | Employer, employer |
| Brokerage | Stocks, stocks, broker, MF Stocks, mf, MF |
| IT dept | IT, it |
| Bank | Bank, bank, Bank Statements |
Files in the root of the AY folder are also scanned (e.g. Form16B.pdf at root level).
Supported File Types
| Type | Format | Auto-detected by | What it extracts |
|---|---|---|---|
| Form 16 | Folder name or form16 in filename |
Salary, TDS, perquisites, employer details | |
| AIS JSON | JSON | ais in filename, .json extension |
Interest, dividends, TDS credits |
| AIS PDF | ais in filename, .pdf extension |
(metadata only — used for verification) | |
| 26AS | 26as or form26 in filename |
(metadata only) | |
| E-Trade G&L | XLSX | G&L_Expanded in filename |
ESOP sale transactions, STCG/LTCG |
| E-Trade Benefit | XLSX | BenefitHistory in filename |
Grant vesting history, Schedule FA |
| Employer Perq | Perquisite workings filename pattern | Perquisite exchange rates for ESOP valuation | |
| Broker P&L | XLSX | taxpnl in filename |
Dividends, equity trades |
| MF CG Report | XLSX | capital_gains in filename |
Mutual fund capital gains |
| Bank Statement | PDF/CSV | In bank/ folder |
Interest income extraction |
config.yaml Reference
The config.yaml file contains data that cannot be auto-extracted from documents — personal details, deductions, property info, and bank accounts. The interactive wizard helps you create this file.
# ─── Personal Details ───
pan: ABCDE1234F
name: Your Full Name
father_name: Father Name
dob: 1990-01-15 # YYYY-MM-DD format
address: "123, Example Street"
city: Mumbai
state: Maharashtra
pincode: "400001"
email: taxpayer@example.com
phone: "9800000000"
aadhaar: "XXXX XXXX XXXX" # optional
# ─── Financial Year ───
financial_year: "2025-26"
assessment_year: "2026-27" # auto-derived if omitted
regime: both # old | new | both
# ─── AIS Password ───
ais_password: ABCDE1234F15011990 # PAN + DOB(DDMMYYYY)
# ─── Deductions (Chapter VI-A) — Old Regime Only ───
deductions:
80c:
epf: 150000 # Employee PF contribution
ppf: 0 # Public Provident Fund
elss: 50000 # ELSS mutual funds
lic: 0 # LIC premium
tuition_fees: 0 # Children tuition fees
housing_principal: 0 # Housing loan principal
fd_5year: 0 # 5-year tax saver FD
other: 0
80d:
self_premium: 25000 # Medical insurance — self/family
parents_premium: 25000 # Medical insurance — parents
preventive_checkup: 5000 # Health checkup (max 5K)
80ccd:
employee_nps: 0 # NPS employee contribution (80CCD1)
additional_nps: 50000 # Additional NPS (80CCD1B, max 50K)
employer_nps: 0 # Employer NPS (80CCD2, new regime eligible)
80e: 0 # Education loan interest (no limit)
80g: 0 # Donations
80gg: 0 # Rent paid (if no HRA from employer)
# ─── HRA Exemption ───
hra:
rent_paid_annual: 360000 # Total rent paid in the FY
is_metro: true # Delhi/Mumbai/Kolkata/Chennai
# ─── House Property ───
house_property:
- type: self_occupied # self_occupied | let_out
loan_interest: 200000 # Annual housing loan interest
# - type: let_out
# rent_received: 240000
# municipal_taxes: 12000
# loan_interest: 180000
# ─── Property Capital Gains ───
property_transactions: []
# - description: "Apartment in Chennai"
# purchase_date: "2010-06-15"
# sale_date: "2025-09-10"
# purchase_cost: 3600000
# improvement_cost: 200000
# sale_consideration: 8500000
# stamp_duty_value: 8200000 # for S.50C check
# tds_buyer: 85000 # TDS u/s 194IA
# exemption_54: 5000000 # Reinvestment in new house
# exemption_54f: 0
# ─── Prior Year Losses (Brought Forward) ───
prior_year_losses:
hp_loss_bf: 50000 # House property loss B/F
stcg_loss_bf: 10000 # Short-term CG loss B/F
ltcg_loss_bf: 25000 # Long-term CG loss B/F
source_ay: "2025-26"
# ─── Bank Accounts (for refund) ───
banks:
- name: Example Bank
ifsc: EXAM0001234
account: "123456789012"
type: savings # savings | current
- name: Another Bank
ifsc: ANOT0005678
account: "987654321098"
type: savings
What's auto-extracted (no config needed)
| Data | Source | Auto-detected |
|---|---|---|
| Salary (gross, 17(1), 17(2), 17(3)) | Form 16 | Yes |
| TDS on salary | Form 16 | Yes |
| Employer name & TAN | Form 16 | Yes |
| ESOP perquisite details | Form 12BA / Employer perquisite PDF | Yes |
| ESOP/ESPP STCG & LTCG | E-Trade G&L Expanded | Yes |
| Bank interest | AIS JSON | Yes |
| Dividends | AIS JSON / Broker P&L | Yes |
| TDS on interest/dividends | AIS JSON | Yes |
| MF capital gains | MF CG report | Yes |
| SBI TTBR exchange rates | Downloaded from GitHub | Yes |
What you must enter in config.yaml
| Data | Why |
|---|---|
| PAN, name, DOB, address | Not reliably in all Form 16 formats |
| Deductions (80C/D/CCD/E/G) | Not in any document — only you know |
| HRA details | Rent receipts aren't parsed |
| House property info | Loan interest certificate not parsed |
| Property sale transactions | Sale deed details not in standard docs |
| Prior year losses | From previous year's ITR acknowledgment |
| Bank accounts | For refund credit — IFSC, account number |
Commands
itr-tool compute <FOLDER>
Main command — full pipeline: parse → wizard → compute → generate reports.
itr-tool compute "C:\Users\Me\IT\2026-27"
# Options:
--regime old|new|both # Default: both (compare and recommend)
--fy 2025-26 # Auto-detected from config.yaml
--ais-password PAN+DOB # Or set in config.yaml
--output /path/to/out # Default: <FOLDER>/output/
--no-wizard # Skip interactive config wizard
itr-tool init <FOLDER>
Just run the config wizard — scan documents, auto-fill, prompt, save config.yaml. No tax computation.
itr-tool init "C:\Users\Me\IT\2026-27"
itr-tool parse <TYPE> <FILE>
Parse a single document and display structured JSON output.
itr-tool parse form16 "Form 16.pdf"
itr-tool parse ais "AIS.json" --password ABCDE1234F15011990
itr-tool parse auto "some_file.xlsx" # auto-detect type
itr-tool verify <FOLDER>
Cross-verify Form 16 vs AIS vs 26AS for discrepancies before filing.
itr-tool verify "C:\Users\Me\IT\2026-27"
itr-tool formats
Display supported file types and expected folder structure.
Interactive Config Wizard
When you run itr-tool compute (without --no-wizard), or itr-tool init, the tool:
- Scans all subfolders and detects parseable files
- Parses Form 16, AIS, E-Trade, etc. to auto-detect PAN, salary, TDS
- Shows auto-detected salary (read-only, from Form 16)
- Walks through each config section interactively:
┌─ Configuration Wizard ────────────────────────────────┐
│ Press Enter to accept the shown value, │
│ or type a new value. │
│ Values in [brackets] are auto-detected or existing. │
└───────────────────────────────────────────────────────┘
── 1. Personal Details ──
Financial Year [2025-26]:
PAN [ABCDE1234F]:
Full Name [Your Name]:
...
── 2. Salary (auto-detected from Form 16) ──
Employer 1: ACME TECH PVT LTD TAN: DELA12345B Gross: 22,50,000 TDS: 5,20,000
(not editable in config — extracted from documents)
── 3. Deductions (Chapter VI-A) ──
Section 80C (limit Rs.1,50,000):
EPF contribution [1,50,000]:
ELSS mutual funds [50,000]:
...
── 4. HRA Exemption ──
── 5. House Property Income ──
── 6. Property Capital Gains ──
── 7. Prior Year Losses ──
── 8. Bank Accounts ──
┌─ Configuration Summary ──────────────┐
│ Personal │ PAN: ABCDE1234F FY: ... │
│ Deductions│ 80C: 1,50,000 80D: ... │
│ ... │ │
└───────────────────────────────────────┘
Save this configuration? [Y/n]:
After saving, the tool reloads the config and proceeds with tax computation.
Encrypted Files & Passwords
Password-protected files the tool handles:
| File | Common password | How the tool handles it |
|---|---|---|
| AIS JSON | PAN + DOB (ABCDE1234F15011990) |
Set ais_password in config.yaml, or prompted |
| Form 16 PDF | Varies by employer (DOB, employee ID) | Prompted interactively with 3 retries |
| 26AS PDF | Usually PAN lowercase + DOB | Not parsed yet (metadata only) |
Password prompt behavior:
🔒 Form 16 PDF file is encrypted: Employer_Form16B.pdf
Type password and press Enter. Type 'skip' to skip this file.
Password (attempt 1/3): ********
✗ Wrong password. 2 attempt(s) remaining.
Password (attempt 2/3): ********
✓ Password accepted
- 3 attempts per file — wrong/empty counts as a failed attempt
- Type
skipto skip a file immediately - Password is hidden while typing (like sudo)
- Password cache — once a password works for one Form 16, it's auto-tried for the next Form 16
- AIS password — set it in
config.yamlto avoid prompts every run
Vestwise ESOP/ESPP Workbook
If an E-Trade/BenefitHistory.xlsx file is found in any subfolder, the tool automatically runs Vestwise to generate a detailed ESOP/ESPP tax workbook.
Required input
| File | Where to get it | Location |
|---|---|---|
| BenefitHistory.xlsx | E-Trade → My Account → Benefits → Export to Excel | E-Trade/BenefitHistory.xlsx |
What Vestwise generates
The output is a multi-sheet Excel workbook (ESOP_Summary_YYYY-YY.xlsx) with:
| Sheet | Contents |
|---|---|
| Grant Summary | All grants, vested/unvested/sold quantities, current status |
| Sales History | Every sale transaction with acquisition cost, sale proceeds, STCG/LTCG |
| Year-wise Tax Summary | Capital gains aggregated by FY with subtotals |
| Schedule FA (Table A3) | Foreign asset disclosure — shares held on Dec 31 each year |
| Validation | Cross-checks against E-Trade data, flags discrepancies |
Key features
- SBI TTBR rates — Rule 115 compliant USD→INR conversion (auto-downloaded from GitHub)
- Sale price resolution — priority: override file → E-Trade xlsx → yfinance closing price
- STCG vs LTCG classification — 24-month holding period for unlisted/foreign shares
- Tax rate calculation — LTCG 12.5%, STCG at slab rate (30%)
- Sale price overrides — persisted in
vestwise_data/sale_price_overrides.csvfor accuracy
Note
Vestwise runs automatically as Phase 4 when BenefitHistory.xlsx is detected. No additional config needed.
Outputs
All outputs go to <FOLDER>/output/:
| File | Description |
|---|---|
STI_YYYY-YY_Name.txt |
Statement of Total Income — full text report with 7 annexures |
ITR2_AY*.json or ITR1_AY*.json |
ITR JSON ready for upload to IT portal (auto-selects form) |
TaxComputation_YYYY-YY.pdf |
PDF computation sheet |
ESOP_Summary_YYYY-YY.xlsx |
Vestwise ESOP workbook (if BenefitHistory.xlsx found) |
ITR Form Auto-Selection
The tool automatically determines whether to generate ITR-1 (Sahaj) or ITR-2:
| Condition | Form |
|---|---|
| Salary + interest only, ≤ 50L, no CG, no foreign assets, ≤ 1 HP | ITR-1 |
| Has ESOP/equity capital gains | ITR-2 |
| Has property capital gains | ITR-2 |
| Has foreign assets (ESOP shares) | ITR-2 |
| Multiple house properties | ITR-2 |
| Total income > 50L | ITR-2 |
Multi-Year Usage
The tool supports running against multiple financial years. Create separate AY folders:
IT/
├── 2021-22/ # FY 2020-21
├── 2022-23/ # FY 2021-22
├── 2023-24/ # FY 2022-23
├── 2024-25/ # FY 2023-24
├── 2025-26/ # FY 2024-25
└── 2026-27/ # FY 2025-26
Each folder needs its own config.yaml (the wizard creates it). Rule packs for FY 2020-21 through 2025-26 are included, covering slab rates, deduction limits, CII tables, and CG rates for each year.
# Run for a specific year
itr-tool compute "IT/2026-27" --no-wizard
# Run all years (batch)
for dir in IT/202*; do itr-tool compute "$dir" --no-wizard; done
FAQ
Q: Do I need to sort files into exact subfolder names?
No. The tool scans 20+ folder name variants. Form 16/, form16/, To Send/Form 16/ all work. Files in the root folder are also detected.
Q: What if I have multiple employers? Put all Form 16 PDFs in the same folder. The tool deduplicates by employer TAN and aggregates salary from all employers.
Q: What if form16x can't parse my Form 16? The tool has a pdfplumber fallback parser with regex-based extraction. If both fail (e.g. scanned/image PDF), you'll see a warning. Consider entering salary manually in a future release.
Q: Is my data sent anywhere? No. Everything runs offline on your machine. The only network call is downloading SBI TTBR exchange rates from a public GitHub CSV (and optional yfinance stock price lookup). No data is uploaded.
Q: How do I update deductions after filing?
Edit config.yaml directly or run itr-tool init <folder> to re-run the wizard.
Q: What Python version do I need? Python 3.11 or newer.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file itr_tool-1.0.1.tar.gz.
File metadata
- Download URL: itr_tool-1.0.1.tar.gz
- Upload date:
- Size: 408.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53bb8838ee10991d58594891abc5e4e664412de6245ba86cce0493a43b3efba9
|
|
| MD5 |
68d9fd88b474ec095397b4febb1b8f88
|
|
| BLAKE2b-256 |
2ab9063d5793b30032feadba1048ba22404d660f294eb4a0019f7803852194d7
|
File details
Details for the file itr_tool-1.0.1-py3-none-any.whl.
File metadata
- Download URL: itr_tool-1.0.1-py3-none-any.whl
- Upload date:
- Size: 495.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2366c368d525138fae34ff98469842382833619abaecac5f604d3d8b541fb94d
|
|
| MD5 |
394fcb6b31e681e332d8249bc0658398
|
|
| BLAKE2b-256 |
518c9915224343d022e1236307d4199fb9c01c9a53d68f1f188221b8c760b8b9
|