edf-tool 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. edf_tool-0.1.0/.gitignore +22 -0
  2. edf_tool-0.1.0/AGENTS.md +113 -0
  3. edf_tool-0.1.0/CHANGELOG.md +16 -0
  4. edf_tool-0.1.0/LICENSE +28 -0
  5. edf_tool-0.1.0/PKG-INFO +276 -0
  6. edf_tool-0.1.0/README.md +253 -0
  7. edf_tool-0.1.0/config.example.json +60 -0
  8. edf_tool-0.1.0/docs/images/sample-edf-request-letter.png +0 -0
  9. edf_tool-0.1.0/docs/images/sample-invoice.png +0 -0
  10. edf_tool-0.1.0/pyproject.toml +44 -0
  11. edf_tool-0.1.0/skills/edf-tool/SKILL.md +53 -0
  12. edf_tool-0.1.0/src/edf_tool/__init__.py +3 -0
  13. edf_tool-0.1.0/src/edf_tool/__main__.py +5 -0
  14. edf_tool-0.1.0/src/edf_tool/banks/__init__.py +22 -0
  15. edf_tool-0.1.0/src/edf_tool/banks/hdfc_services.py +138 -0
  16. edf_tool-0.1.0/src/edf_tool/cli.py +516 -0
  17. edf_tool-0.1.0/src/edf_tool/config.py +340 -0
  18. edf_tool-0.1.0/src/edf_tool/data/edf.1 +286 -0
  19. edf_tool-0.1.0/src/edf_tool/data/hdfc_services_2026_09.xlsx +0 -0
  20. edf_tool-0.1.0/src/edf_tool/errors.py +29 -0
  21. edf_tool-0.1.0/src/edf_tool/generate.py +124 -0
  22. edf_tool-0.1.0/src/edf_tool/history.py +44 -0
  23. edf_tool-0.1.0/src/edf_tool/invoice.py +140 -0
  24. edf_tool-0.1.0/src/edf_tool/mantext.py +94 -0
  25. edf_tool-0.1.0/src/edf_tool/office.py +38 -0
  26. edf_tool-0.1.0/src/edf_tool/paths.py +52 -0
  27. edf_tool-0.1.0/src/edf_tool/pdf.py +156 -0
  28. edf_tool-0.1.0/src/edf_tool/png.py +124 -0
  29. edf_tool-0.1.0/src/edf_tool/signature.py +97 -0
  30. edf_tool-0.1.0/src/edf_tool/textutil.py +91 -0
  31. edf_tool-0.1.0/src/edf_tool/validate.py +77 -0
  32. edf_tool-0.1.0/src/edf_tool/xlsx.py +223 -0
  33. edf_tool-0.1.0/tests/helpers.py +62 -0
  34. edf_tool-0.1.0/tests/test_cli.py +112 -0
  35. edf_tool-0.1.0/tests/test_hdfc.py +108 -0
  36. edf_tool-0.1.0/tests/test_units.py +110 -0
@@ -0,0 +1,22 @@
1
+ # Never commit personal data
2
+ /config.json
3
+ !config.example.json
4
+ /history.json
5
+ /signature.png
6
+ *.pdf
7
+ output/
8
+ EDF/
9
+ details.json
10
+ my-details.json
11
+
12
+ # Python
13
+ __pycache__/
14
+ *.py[cod]
15
+ *.egg-info/
16
+ build/
17
+ dist/
18
+ .venv/
19
+ .pytest_cache/
20
+
21
+ # OS
22
+ .DS_Store
@@ -0,0 +1,113 @@
1
+ # AGENTS.md: running edf-tool on someone's behalf
2
+
3
+ This file is for AI coding agents (Claude Code, Codex, Cursor, Copilot and others) that help a person install edf-tool and produce their monthly **export-of-services invoice + bank EDF form**. A ready-made skill version is in [`skills/edf-tool/SKILL.md`](skills/edf-tool/SKILL.md).
4
+
5
+ ## Ground rules (non-negotiable)
6
+
7
+ 1. **Keep everything local.** Never upload, paste or send the person's config, signature, invoices or bank forms to any website, API, gist, issue, chat log or remote repository. edf-tool itself never uses the network, so don't add anything that does.
8
+ 2. **Never commit personal data.** Don't put `config.json`, `signature.png`, `history.json`, generated PDFs/XLSX or a `details.json` into any git repository. If you write a temporary `details.json` for `edf init --from`, delete it straight after.
9
+ 3. **Confirm the money.** Before generating, read back the invoice number, dates, amount, fee and net amount to the person, and get a yes. These end up in a declaration to their bank under FEMA.
10
+ 4. **Only HDFC Bank's form is supported.** If the person banks elsewhere, say so plainly. Don't try to "make it fit" another bank's form.
11
+ 5. **Don't invent identifiers.** PAN, GSTIN, IFSC, account numbers, purpose and SAC codes must come from the person or their documents (GST certificate, bank statement, an earlier invoice). If something is missing, ask.
12
+ 6. **Not advice.** You may explain what a field means. Tax decisions (LUT/IGST, purpose code, SAC) are the person's or their CA's to make.
13
+
14
+ ## 1. Install
15
+
16
+ Pick whichever is available. Prefer a method that doesn't need sudo.
17
+
18
+ ```bash
19
+ uv tool install edf-tool # or: uvx edf-tool --help (no install)
20
+ pipx install edf-tool
21
+ brew install krushiraj/tap/edf-tool
22
+ uvx --from git+https://github.com/krushiraj/edf-tool edf --help # before the PyPI release exists
23
+ ```
24
+
25
+ Optional, for the bank form PDF: LibreOffice (`brew install --cask libreoffice` or `apt install libreoffice-calc`). Ask before installing it, since it's large (~1 GB).
26
+
27
+ Verify the install:
28
+
29
+ ```bash
30
+ edf --version
31
+ edf doctor --json
32
+ ```
33
+
34
+ ## 2. One-time setup
35
+
36
+ **Interactive** (best when the person is at the terminal): run `edf init` and let them answer.
37
+
38
+ **Non-interactive** (you collect the answers):
39
+
40
+ 1. Gather the details. Good sources:
41
+ - GST certificate: firm name, address, GSTIN
42
+ - PAN card
43
+ - Bank statement header: branch, branch address, IFSC, account number
44
+ - An earlier invoice or contract: client name and address, amount
45
+ - The payout platform (e.g. Deel): third-party payer name and address
46
+ 2. Write them to a temporary file using the shape of [`config.example.json`](config.example.json). Required keys:
47
+ - `exporter.firm_name`, `exporter.proprietor`, `exporter.address_lines` (2+ lines), `exporter.phone`, `exporter.email`, `exporter.pan`, `exporter.gstin`
48
+ - `bank.branch_name`, `bank.branch_address`, `bank.ifsc`, `bank.account_no`
49
+ - `client.name`, `client.address_lines` (last line = country)
50
+ - `third_party.enabled`, plus `third_party.name` and `third_party.address` when it's true
51
+ - `service.purpose_code`, `service.sac`, `service.scope`
52
+ - `defaults.amount`
53
+
54
+ Everything else has a sensible default.
55
+ 3. Import it, then delete the file:
56
+ ```bash
57
+ edf init --from /tmp/details.json --json && rm /tmp/details.json
58
+ ```
59
+ If the exit code is 2, the JSON's `error` lists each bad field with the reason, for example a GSTIN check digit or a PAN/GSTIN mismatch. Fix those and retry.
60
+ 4. Optionally save a signature: `edf signature set /path/to/signature.jpg --json`.
61
+ 5. `edf doctor --json` should return `"ok": true`.
62
+
63
+ ## 3. Every month
64
+
65
+ ```bash
66
+ # 1. preview: writes nothing
67
+ edf generate -y --dry-run --json
68
+ # 2. confirm the values with the person, then:
69
+ edf generate -y --invoice-date 31-10-2026 --amount 2400 --fee 6 --json
70
+ ```
71
+
72
+ - All dates are `DD-MM-YYYY`. If you leave a flag out, the suggested value is used:
73
+ - **Invoice number:** the next one in history.
74
+ - **Invoice date:** the last day of last month (or of this month after the 15th).
75
+ - **Work period:** the last day of the previous month to the invoice date.
76
+ - **Due date:** the invoice date.
77
+ - **Letter date:** today.
78
+ - **Amount and fee:** the config defaults.
79
+ - `--fee` is what the platform or a correspondent bank deducts before the money arrives. The bank form shows the amount after it as the Net Realisable Value.
80
+ - Add `--sign` to also get `*_signed.pdf` copies, if a signature is saved.
81
+ - The JSON result contains `files.invoice_pdf`, `files.edf_pdf`, `files.edf_xlsx` (and the `_signed` versions), plus `warnings` and `skipped`.
82
+
83
+ Exit codes:
84
+ - `0` OK
85
+ - `5` OK, but something was skipped (usually no LibreOffice, so there's no `edf_pdf`; tell the person)
86
+ - `3` bad input or invoice number already used (pick the next number, or `--force` only if they want to regenerate)
87
+ - `2` config problem
88
+ - `4` the bank form changed (stop and tell the person)
89
+
90
+ After generating, tell the person where the files are and what to do next:
91
+ - Sign the two PDFs, unless `--sign` was used.
92
+ - Add their firm's stamp if the branch wants it.
93
+ - Send the bank form PDF and the invoice PDF to the branch.
94
+
95
+ ## Useful commands
96
+
97
+ ```bash
98
+ edf config show --json # current details
99
+ edf config set defaults.amount 2500
100
+ edf config validate --json
101
+ edf history --json
102
+ edf sign INV-2026-10 --json # signed copies of an earlier invoice
103
+ edf man --plain # full manual as text
104
+ ```
105
+
106
+ Separate profiles (for a second client, or for testing) use `EDF_TOOL_HOME=/some/dir`. For tests, always use a throwaway `EDF_TOOL_HOME` and fake data from `config.example.json`.
107
+
108
+ ## Working on the code
109
+
110
+ - Pure standard library, Python ≥ 3.9. No dependencies; please keep it that way.
111
+ - Run the tests with `python3 -m unittest discover -s tests`, using fake data only.
112
+ - `tests/test_cli.py::NoNetworkTest` must keep passing: no networking imports anywhere.
113
+ - Bank adapters live in `src/edf_tool/banks/`; see CONTRIBUTING.md.
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-10-07
4
+
5
+ First release.
6
+
7
+ - `edf init`: interactive first-run setup with every required field validated (PAN, GSTIN check digit, IFSC, SAC, email, phone). `--from details.json` for scripts and agents.
8
+ - `edf generate`: makes the monthly invoice PDF, the filled HDFC EDF workbook (.xlsx), and a 2-page bank form PDF (Request Letter + Invoice Details).
9
+ - Suggests the next invoice number, work period and dates, and refuses to reuse an invoice number.
10
+ - Handles third-party payers (Deel, Remote, EORs), with their fee shown as the Net Realisable Value.
11
+ - Signing: `edf signature set <image>` removes the background; `--sign` / `edf sign` stamp the signature on both PDFs, and it can also go into the Excel file.
12
+ - Built-in PDF writer for the invoice (no browser needed). LibreOffice is optional, used only for the bank form PDF.
13
+ - `--json` on every command and documented exit codes, for agents.
14
+ - `edf doctor`, `edf config show|set|edit|validate`, `edf history`, `edf man`.
15
+ - Fully offline. The test suite fails if a networking module is ever imported.
16
+ - Bank support: HDFC Bank Export of Services EDF form (September 2026 version).
edf_tool-0.1.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Krushi Raj Tula
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ The bundled bank form (src/edf_tool/data/hdfc_services_2026_09.xlsx) is HDFC Bank's
26
+ customer form, included unchanged except for removed document metadata, so that the
27
+ tool can fill it in. It is not covered by the MIT license above. HDFC Bank is not
28
+ affiliated with, and does not endorse, this project.
@@ -0,0 +1,276 @@
1
+ Metadata-Version: 2.5
2
+ Name: edf-tool
3
+ Version: 0.1.0
4
+ Summary: Monthly export-of-services invoice + bank EDF form generator for Indian freelancers. Runs fully offline.
5
+ Project-URL: Homepage, https://github.com/krushiraj/edf-tool
6
+ Project-URL: Issues, https://github.com/krushiraj/edf-tool/issues
7
+ Project-URL: Changelog, https://github.com/krushiraj/edf-tool/blob/main/CHANGELOG.md
8
+ Author: Krushi Raj Tula
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: edf,export of services,fema,freelancer,gst,hdfc,india,invoice,lut,softex
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Topic :: Office/Business :: Financial :: Accounting
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+
24
+ # edf-tool
25
+
26
+ **Your monthly export-of-services paperwork in one command, entirely on your own computer.**
27
+
28
+ If you're an Indian freelancer or sole proprietor paid from abroad (directly or through Deel, Remote, an EOR and so on), your bank wants an **EDF (Export Declaration Form)** for each foreign payment. `edf` generates, every month:
29
+
30
+ | File | What it is |
31
+ |---|---|
32
+ | `…_INV-2026-10.pdf` | Your **invoice** to the client: GSTIN, PAN, SAC, IGST line, place of supply, amount in words |
33
+ | `…_EDF_INV-2026-10.xlsx` | The **bank's own EDF workbook**, filled in. The bank's formatting, dropdowns and logos are left untouched. |
34
+ | `…_EDF_Form_INV-2026-10.pdf` | **Two pages ready to sign and send**: the Request Letter and the Invoice Details |
35
+
36
+ > [!IMPORTANT]
37
+ > **Bank support: HDFC Bank only, for now.** edf-tool fills HDFC Bank's *"Request letter for Export of Services & EDF Filing Cum Disposal Instructions for Credit"* (the September 2026 version of the form). **Other banks may use a different format.** If your bank sends you a different form, edf-tool won't fill it, but [adding a bank](CONTRIBUTING.md#adding-a-bank) is one file. Always check every field before you submit. This is **not tax or legal advice**.
38
+
39
+ <p align="center">
40
+ <img src="docs/images/sample-invoice.png" width="44%" alt="Sample invoice (fake data)">
41
+ &nbsp;
42
+ <img src="docs/images/sample-edf-request-letter.png" width="44%" alt="Sample HDFC EDF request letter (fake data)">
43
+ </p>
44
+ <p align="center"><sub>Generated from the fake data in <code>config.example.json</code>.</sub></p>
45
+
46
+ ---
47
+
48
+ ## 🔒 Privacy: nothing leaves your machine
49
+
50
+ - **No network access, ever.** The code has no networking, sends no telemetry and doesn't check for updates. The test suite fails if any networking module is even imported.
51
+ - Your details (PAN, GSTIN, bank account, client) are stored only in `~/.config/edf-tool/config.json`, readable only by you (`0600`).
52
+ - Your signature is stored only in `~/.config/edf-tool/signature.png`.
53
+ - Generated files go to `~/Documents/EDF/<invoice no>/`, or wherever you choose.
54
+ - No Python packages are needed: it's pure standard library, so there's no third-party code to trust.
55
+ - PDFs are made locally. The invoice is drawn by edf itself, and the bank form PDF uses your own LibreOffice, run offline.
56
+
57
+ ---
58
+
59
+ ## Install
60
+
61
+ **Homebrew (macOS / Linux)**
62
+ ```bash
63
+ brew install krushiraj/tap/edf-tool
64
+ ```
65
+
66
+ **uv**: run it without installing, or install it as a tool
67
+ ```bash
68
+ uvx edf-tool --help # one-off run
69
+ uv tool install edf-tool # then just: edf
70
+ ```
71
+
72
+ **pipx / pip**
73
+ ```bash
74
+ pipx install edf-tool
75
+ # or: python3 -m pip install --user edf-tool
76
+ ```
77
+
78
+ **Straight from GitHub** (no PyPI needed)
79
+ ```bash
80
+ uvx --from git+https://github.com/krushiraj/edf-tool edf --help
81
+ ```
82
+
83
+ **Optional: LibreOffice**, used *only* to turn the bank workbook into a PDF. The invoice PDF and the Excel file work without it.
84
+ ```bash
85
+ brew install --cask libreoffice # macOS
86
+ sudo apt install libreoffice-calc # Debian/Ubuntu
87
+ ```
88
+
89
+ You need Python 3.9 or newer; macOS already includes it. Check everything with `edf doctor`.
90
+
91
+ ---
92
+
93
+ ## First run (one-time setup)
94
+
95
+ ```bash
96
+ edf init
97
+ ```
98
+
99
+ Setup asks for everything the bank form and the invoice need. **Every required field must be answered** and is checked as you type: PAN format, GSTIN format *and check digit*, GSTIN-matches-PAN, IFSC, SAC code, phone and email. It covers:
100
+
101
+ 1. **You:** business name, proprietor, address (as on your GST certificate), phone, email, PAN, GSTIN, IEC (or "Not applicable")
102
+ 2. **Your bank account:** branch, branch address, IFSC, account number
103
+ 3. **Your client:** legal name, address, country, registration/VAT number (optional)
104
+ 4. **Who sends the money:** the client directly, or a third party like Deel (name, address, relationship)
105
+ 5. **The service:** RBI purpose code (e.g. P0802), SAC code (e.g. 998314), description, scope
106
+ 6. **Monthly defaults:** usual amount, usual transfer fee, invoice number prefix
107
+ 7. *(optional)* **A picture of your signature**
108
+
109
+ If you run `edf generate` before setting up, it starts setup for you.
110
+
111
+ **Prefer a file?** Copy [`config.example.json`](config.example.json), fill it in, then:
112
+ ```bash
113
+ edf init --from my-details.json --signature ~/Desktop/signature.jpg
114
+ rm my-details.json # the details now live in ~/.config/edf-tool/
115
+ ```
116
+
117
+ ---
118
+
119
+ ## Every month
120
+
121
+ ```bash
122
+ edf generate
123
+ ```
124
+
125
+ ```
126
+ Monthly invoice + EDF (Enter accepts the [suggested] value)
127
+
128
+ Invoice date (DD-MM-YYYY) [30-09-2026]:
129
+ Invoice number [INV-2026-10]:
130
+ Work period start [31-08-2026]:
131
+ Work period end [30-09-2026]:
132
+ Due date [30-09-2026]:
133
+ Invoice amount (USD) [2400.00]:
134
+ Fee deducted before it reaches the bank [6.00]:
135
+ Date on the bank request letter [07-10-2026]:
136
+
137
+ Invoice INV-2026-10 dated 30-09-2026, due 30-09-2026
138
+ Client Example Corp LLC
139
+ Period August 31, 2026 to September 30, 2026
140
+ Amount USD 2,400.00 fee USD 6.00 net to bank USD 2,394.00
141
+ Generate these files? (yes/no) [yes]:
142
+
143
+ ✓ Files in ~/Documents/EDF/INV-2026-10
144
+ ```
145
+
146
+ Press **Enter** to accept each suggestion:
147
+ - **Invoice number:** the next number after the last one you made.
148
+ - **Invoice date:** the last day of last month (or of this month, if it's after the 15th).
149
+ - **Work period:** from the last day of the previous month to the invoice date.
150
+
151
+ edf won't let you reuse an invoice number unless you add `--force`.
152
+
153
+ **About the fee:** if Deel, or a correspondent bank, takes a fee before the money reaches you, enter it here. The bank form then declares the full **export value** (the invoice amount) and the lower **Net Realisable Value**, and explains the difference in the remarks. That's what lets your bank close the EDF cleanly when slightly less money arrives.
154
+
155
+ ### Signing
156
+
157
+ Pick whichever suits you:
158
+
159
+ - **macOS Preview** (or any PDF app): open the two PDFs and use Tools → Annotate → Signature.
160
+ - **No PDF signing app?** Save your signature once, and edf will stamp it for you:
161
+ ```bash
162
+ edf signature set ~/Desktop/my-signature.jpg # background removed automatically
163
+ edf generate --sign # also writes *_signed.pdf copies
164
+ edf sign INV-2026-10 # or sign one you've already generated
165
+ ```
166
+ Use a photo or scan of your signature on white paper. PNG works everywhere; on a Mac, JPG and HEIC work too.
167
+ - **In the Excel file:** once a signature is saved, it's placed on the signatory line automatically. You can turn this off with `edf config set output.embed_signature_in_excel false`.
168
+
169
+ Then send the **bank form PDF** and the **invoice PDF** to your branch, along with the `.xlsx` if they ask for it. Many branches also want your **firm's stamp/seal** next to the signature.
170
+
171
+ ---
172
+
173
+ ## Commands
174
+
175
+ | Command | What it does |
176
+ |---|---|
177
+ | `edf init` | First-run setup. `--from FILE` reads a JSON file, `--force` redoes setup, `--signature IMG` saves a signature |
178
+ | `edf generate` (`gen`) | This month's files. Flags: `--invoice-date`, `--invoice-no`, `--amount`, `--fee`, `--period-start/--period-end`, `--due-date`, `--letter-date`, `--sign`, `--dry-run`, `-y`, `--json` |
179
+ | `edf sign INV-…` | Signed PDFs for an invoice already generated |
180
+ | `edf signature set IMG \| show \| remove` | Manage your saved signature |
181
+ | `edf config show \| path \| edit \| validate` | Look at, open or check the config |
182
+ | `edf config set FIELD VALUE` | Change one value, e.g. `edf config set defaults.amount 2500` |
183
+ | `edf history` | Invoices generated so far |
184
+ | `edf doctor` | Checks the config, bank template, signature, LibreOffice and output folder |
185
+ | `edf banks` | Supported bank forms |
186
+ | `edf man` | The full manual (also `man edf` when installed with Homebrew) |
187
+
188
+ Every command accepts `--json` for machine-readable output, and has `--help` with examples.
189
+
190
+ **Exit codes:**
191
+ - `0` OK
192
+ - `2` config missing or invalid
193
+ - `3` bad input (date, amount, or an invoice number already used)
194
+ - `4` bank form doesn't match the known version
195
+ - `5` files written, but an optional step was skipped (e.g. no LibreOffice)
196
+ - `130` cancelled
197
+
198
+ ---
199
+
200
+ ## Configuration reference
201
+
202
+ The config lives in `~/.config/edf-tool/config.json`; run `edf config path` to see the exact location. Edit it with `edf config edit` or `edf config set`.
203
+
204
+ | Field | Example | Notes |
205
+ |---|---|---|
206
+ | `exporter.firm_name` | `ACME DEV STUDIO` | As on your GST certificate |
207
+ | `exporter.proprietor` | `Asha Kumar` | Signs the forms |
208
+ | `exporter.constitution` | `Sole Proprietorship` | |
209
+ | `exporter.address_lines` | `["12 MG Road", "Bengaluru, KA 560038", "India"]` | Your GST-registered address |
210
+ | `exporter.phone`, `exporter.email` | | Printed on the invoice and the bank form |
211
+ | `exporter.pan`, `exporter.gstin` | `ABCDE1234F`, `29ABCDE1234F1ZW` | Validated, including the GSTIN check digit |
212
+ | `exporter.iec` | `Not applicable` | Most service exporters don't have one |
213
+ | `bank.branch_name`, `bank.branch_address`, `bank.ifsc` | | From your bank statement |
214
+ | `bank.account_no`, `bank.fee_account_no` | | The account credited, and the account charges are debited from |
215
+ | `client.name`, `client.address_lines`, `client.country` | | The service recipient |
216
+ | `client.short_address` | `Example Corp LLC, San Francisco, CA, USA` | Used in narrow boxes |
217
+ | `client.registration_number`, `client.vat_id` | | Optional |
218
+ | `third_party.enabled` | `true` | Set to `true` if Deel, Remote or similar sends the money |
219
+ | `third_party.name`, `.address`, `.short_address`, `.country`, `.relationship` | `Deel, Inc.` | The bank must know about third-party payers (FEMA) |
220
+ | `service.purpose_code`, `.purpose_description` | `P0802`, `Software consulting / implementation` | RBI purpose code |
221
+ | `service.sac` | `998314` | 998314 IT design & development; 998313 IT consulting & support |
222
+ | `service.description`, `.short_description`, `.line_item`, `.scope` | | Wording on the invoice and the form |
223
+ | `service.currency` | `USD` | Any 3-letter code |
224
+ | `defaults.amount`, `defaults.payment_fee` | `2400`, `6` | Used as the suggestions each month |
225
+ | `defaults.invoice_prefix` | `INV-` | |
226
+ | `output.folder` | `~/Documents/EDF` | |
227
+ | `output.file_prefix` | `Acme_Dev` | |
228
+ | `output.embed_signature_in_excel` | `true` | |
229
+ | `bank_format` | `hdfc_services` | See `edf banks` |
230
+ | `bank_template` | *(unset)* | Optional path to a newer copy of the same bank form |
231
+
232
+ **More than one client?** Keep a separate profile for each one with `EDF_TOOL_HOME`:
233
+ ```bash
234
+ EDF_TOOL_HOME=~/.config/edf-tool-clientB edf init
235
+ EDF_TOOL_HOME=~/.config/edf-tool-clientB edf generate
236
+ ```
237
+
238
+ ---
239
+
240
+ ## Using it with AI agents
241
+
242
+ edf is built to be driven by coding agents (Claude Code, Codex, Cursor and so on) without anything leaving your machine:
243
+
244
+ - Everything works without prompts: `-y`, `--from`, and `--json` on every command, with documented exit codes.
245
+ - [`AGENTS.md`](AGENTS.md) has step-by-step setup and monthly instructions, plus guardrails.
246
+ - [`skills/edf-tool/SKILL.md`](skills/edf-tool/SKILL.md) is a ready-made agent skill. Copy it into your agent's skills folder, e.g. `~/.claude/skills/edf-tool/`.
247
+
248
+ Tell your agent: *"Set up edf-tool from github.com/krushiraj/edf-tool and generate this month's EDF."*
249
+
250
+ ---
251
+
252
+ ## Good to know
253
+
254
+ - **GST / LUT:** the invoice shows `IGST (0%)`. Exporting services without charging IGST requires a **Letter of Undertaking (LUT)**, filed for free on the GST portal (form RFD-11). Without an LUT, IGST is payable and then refunded. Check with your CA. You can change the tax line's wording with `edf config set defaults.igst_label "…"`.
255
+ - **IEC:** usually not required for exporting services; the form says "Not applicable".
256
+ - **The bank form version:** before filling anything, edf checks that the form's labels match the version it knows. If HDFC changes the form, edf stops with exit status 4 rather than writing into the wrong cells. Please [open an issue](https://github.com/krushiraj/edf-tool/issues), and remove your personal data from anything you attach.
257
+ - **Fees and realisation:** keep Deel's (or your bank's) statement showing the fee. Banks sometimes ask for it when they close the EDF.
258
+
259
+ ## Troubleshooting
260
+
261
+ | Problem | Fix |
262
+ |---|---|
263
+ | `No config found` | Run `edf init` |
264
+ | `EDF form PDF skipped` (exit status 5) | Install LibreOffice, or open the `.xlsx` and export the *REQUEST LETTER* and *Invoice Details 1* sheets as PDF |
265
+ | LibreOffice installed but not found | `export SOFFICE_PATH=/path/to/soffice` |
266
+ | Signature has a grey box around it | `edf signature set img.jpg --threshold 170` (a lower value removes more background) |
267
+ | An invoice number was already used | Use the next number, or add `--force` to regenerate it |
268
+ | Text cut off in a box on the bank form | Shorten `client.short_address`, `service.short_description` or `third_party.short_address` |
269
+
270
+ ## Contributing
271
+
272
+ Bug reports and new bank formats are welcome; see [CONTRIBUTING.md](CONTRIBUTING.md). The tests run with only fake data: `python3 -m unittest discover -s tests`.
273
+
274
+ ## License
275
+
276
+ MIT, © Krushi Raj Tula. The bundled HDFC form belongs to HDFC Bank. It's included unchanged apart from removed document metadata, and isn't covered by the MIT license. This project is not affiliated with or endorsed by HDFC Bank.