ifrs16kit 1.0.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ayce Makbule (Lena) Acar
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.
@@ -0,0 +1,3 @@
1
+ include VIGNETTE.md
2
+ include TESTING.md
3
+ recursive-include tests *.py
@@ -0,0 +1,183 @@
1
+ Metadata-Version: 2.4
2
+ Name: ifrs16kit
3
+ Version: 1.0.0
4
+ Summary: Interactive IFRS 16 auditor re-performance tool producing liquid Excel workbooks
5
+ Author: Ayce Makbule (Lena) Acar
6
+ License-Expression: MIT
7
+ Keywords: IFRS 16,lease accounting,audit,re-performance,ISA 540,excel,openpyxl,right-of-use asset,lease liability
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Financial and Insurance Industry
10
+ Classifier: Topic :: Office/Business :: Financial :: Accounting
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Environment :: Console
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: openpyxl>=3.1
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=7.4; extra == "dev"
25
+ Requires-Dist: pytest-cov>=4.1; extra == "dev"
26
+ Dynamic: license-file
27
+
28
+ # LeaseAuditKit — Interactive IFRS 16 Re-performance Tool (LIQUID edition)
29
+
30
+ A standalone Python tool that re-performs a lessee's IFRS 16 lease accounting from first principles, independently of the client's own calculation, and delivers the result as a fully formula-driven ("liquid") Excel audit workbook. It is designed for the substantive re-performance of management's lease estimates under ISA 540 (accounting estimates), ISA 500 (audit evidence, including para A21 on re-performance), and ISA 230 (documentation).
31
+
32
+ Author: Ayce Makbule (Lena) Acar — MSc Business Analytics, Trinity College Dublin.
33
+
34
+ ## Why "liquid"?
35
+
36
+ Every derived figure in the generated workbook is a live Excel formula, not a hard-coded value. Change any dark-red input cell — lease term, IBR, payment frequency, country, depreciation method — and the entire model (liability, ROU asset, 120-period schedule, annual summary, journals, deferred tax) recalculates instantly inside Excel. The Python script never bakes numbers into the calculation sheets; it only writes the inputs and the formula fabric around them. A separate, independent Python engine re-computes the same figures so the auditor can verify the Excel model against a second implementation (a "two-engine" control).
37
+
38
+ ## Requirements
39
+
40
+ - Python 3.9+
41
+ - openpyxl (installed automatically as a dependency)
42
+ - Microsoft Excel (or LibreOffice) to fill the template and recalculate the output
43
+
44
+ Works from any environment: terminal, VS Code, Spyder, PyCharm.
45
+
46
+ ## Installation
47
+
48
+ From the package root (the folder containing `pyproject.toml`):
49
+
50
+ ```bash
51
+ pip install -e .
52
+ ```
53
+
54
+ The editable (`-e`) install means edits to `src/ifrs16kit/core.py` take
55
+ effect immediately without reinstalling. Installation registers both the
56
+ importable package (`import ifrs16kit`) and a terminal command
57
+ (`ifrs16kit`), usable from any directory.
58
+
59
+ ## Quick start
60
+
61
+ **Command line** (interactive flow):
62
+
63
+ ```bash
64
+ # Guided flow — 3 questions, then a fillable template
65
+ ifrs16kit
66
+
67
+ # Instant demo — runs the CALISMA golden benchmark end-to-end
68
+ ifrs16kit --demo
69
+ ```
70
+
71
+ **Spyder / notebook — interactive flow** (asks the questions, waits while you fill the template):
72
+
73
+ ```python
74
+ import ifrs16kit as lease
75
+ lease.run()
76
+ # 1. answers 3 questions in the console
77
+ # 2. writes IFRS16_Input.xlsx and PAUSES — open it in Excel, fill the
78
+ # dark-red cells, save, return to the console and press Enter
79
+ # 3. validates the template and writes IFRS16_Calculation.xlsx
80
+ ```
81
+
82
+ **Spyder / notebook — non-interactive two-step** (no questions; you control each step):
83
+
84
+ ```python
85
+ import ifrs16kit as lease
86
+
87
+ lease.demo() # instantly writes BOTH Excel files (golden case)
88
+
89
+ lease.create_input() # step 1: writes IFRS16_Input.xlsx → fill in Excel
90
+ lease.create_calculation() # step 2: reads it back → writes IFRS16_Calculation.xlsx
91
+ ```
92
+
93
+ `create_input()` accepts `country=`, `advance=`, `freq=` and a custom path;
94
+ `create_calculation()` accepts custom template/output paths.
95
+
96
+ **Python API** (programmatic — no interview, no template round-trip):
97
+
98
+ ```python
99
+ import ifrs16kit as lease
100
+
101
+ inp = lease.LeaseInputs(
102
+ entity="Example Co. Limited", country="Ireland",
103
+ commencement=__import__("datetime").date(2025, 1, 1),
104
+ term_years=2, freq=12, payment=650.0,
105
+ is_advance=True, ibr_annual=0.06, idc=600.0,
106
+ )
107
+
108
+ lease.cross_check(inp) # dict of key figures
109
+ lease.build_calculation_workbook(inp, "IFRS16_Calc.xlsx") # 10-sheet liquid workbook
110
+ lease.build_template({"country": "Ireland", "is_advance": True, "freq": 12},
111
+ "IFRS16_Input.xlsx") # blank input template
112
+ inp2 = lease.read_template("IFRS16_Input.xlsx") # validated read-back
113
+ ```
114
+
115
+ Public API: `LeaseInputs`, `cross_check`, `build_template`, `read_template`,
116
+ `build_calculation_workbook`, `print_summary`, plus the `COUNTRIES`,
117
+ `FREQUENCIES`, and `MAX_PERIODS` constants.
118
+
119
+ ## Workflow
120
+
121
+ 1. **Interview.** The script asks three questions: country/jurisdiction (Türkiye, Ireland, United Kingdom, UAE, Australia), payment timing (advance/arrears), and payment frequency (monthly, quarterly, semi-annual, annual).
122
+ 2. **Template.** It generates `IFRS16_Input.xlsx` — a single-sheet LIQUID input template. Only the dark-red, thick-bordered cells are editable inputs; everything else (total term, N, periodic rate, capacity checks) auto-calculates with live formulas. Dropdowns constrain frequency, timing, depreciation method, and country.
123
+ 3. **Fill and save.** Open the template in Excel, fill every dark-red cell, confirm the two green validation cells both say "OK", save, and return to the running script.
124
+ 4. **Validation.** The script reads the template back and validates it: non-empty entity, valid date, positive term/payment/useful life, IBR entered as a decimal or percentage below 100%, a whole number of payment periods, and N ≤ 120 (template capacity). Errors are listed cell-by-cell so they can be fixed and re-read without restarting.
125
+ 5. **Output.** It generates `IFRS16_Calculation.xlsx` — the full 10-sheet liquid workbook — and prints an independent Python cross-check of the key figures.
126
+
127
+ ## The generated workbook (10 sheets)
128
+
129
+ | Sheet | Contents |
130
+ |---|---|
131
+ | **Inputs** | All lease inputs plus live-linked key outputs (liability, ROU, totals) and country-driven framework/audit-standard lookups from Setup. |
132
+ | **Initial Measurement** | PV of lease payments period-by-period (IFRS 16 ¶26) and the ROU asset build-up (¶24: liability + IDC + prepayments − incentives + restoration). |
133
+ | **Lease Schedule** | 120-period-capacity amortisation and depreciation schedule (¶36 effective interest; ¶31 depreciation), with year tags and a Final Payment status flag. Rows self-hide beyond N. |
134
+ | **Annual Summary** | P&L impact and year-end balances by reporting year, a front-loading memo vs a straight-line charge, and five automated reconciliation checks (closing liability = 0, closing ROU = 0, principal = initial liability, expense = payments + IDC, front-loading sums to nil). |
135
+ | **Journals** | Initial-recognition entry with debit/credit balance check, plus representative Period 1 entries (payment, interest unwind, depreciation). |
136
+ | **Tax_Reconciliation** | Illustrative year-1 accounting-vs-cash-rental P&L difference and deferred-tax computation at the jurisdiction's rate. |
137
+ | **Findings** | Findings-and-recommendations register wired to the reconciliation checks — flags "Y" and a recommendation automatically when a check fails. |
138
+ | **Audit_Procedures** | 20 substantive procedures (P-1 to P-20) mapped to assertions (existence, completeness, accuracy, cut-off, classification, presentation). |
139
+ | **PBC_List** | 18-item prepared-by-client request list with purpose, format, and due dates. |
140
+ | **Setup** | Country lookup table driving currency, reporting framework, lease standard (IFRS 16 / TFRS 16 / AASB 16), audit standards (ISA / ISA (Ireland) / ISA (UK) / BDS / ASA 540-500-230), and illustrative tax rate. |
141
+
142
+ ## Colour and formatting conventions
143
+
144
+ - **Dark red fill, thick border, bold** — your input (client data / auditor assumptions)
145
+ - **Black** — formula / computed
146
+ - **Green font on light-green fill** — link to another sheet, or an automated check
147
+ - **Navy headers, Times New Roman throughout**
148
+
149
+ ## Calculation conventions
150
+
151
+ - Periodic discount rate uses the effective (compound) conversion: `(1 + IBR)^(1/frequency) − 1`, not simple pro-rata.
152
+ - Advance payments: the first payment is undiscounted (discount exponent `p − 1`); interest accrues on the opening liability net of the period's payment. Arrears: exponent `p`; interest on the full opening liability.
153
+ - Depreciation: straight-line over the shorter of the lease term and useful life (no ownership transfer assumed), or reducing balance at `1 − (1 − annual rate)^(1/frequency)` per period with a final-period write-off of the remaining carrying amount.
154
+
155
+ ## Verification
156
+
157
+ The tool ships with a golden benchmark (the CALISMA case: monthly advance, 24 periods, 6% IBR, 650/month, 600 IDC):
158
+
159
+ | Figure | Expected |
160
+ |---|---|
161
+ | Lease liability at commencement | 14,761.09 |
162
+ | ROU asset at commencement | 15,361.09 |
163
+ | Total interest over term | 838.91 |
164
+ | Total P&L charge | 16,200.00 |
165
+
166
+ Run `ifrs16kit --demo` and compare the console cross-check and `Inputs!B36:B42` of the generated workbook against these values. The five reconciliation checks on the Annual Summary sheet must all read "OK".
167
+
168
+ ## Files
169
+
170
+ | File | Role |
171
+ |---|---|
172
+ | `pyproject.toml` | Package metadata, dependency, and the `ifrs16kit` CLI entry point |
173
+ | `src/ifrs16kit/core.py` | The engine, template builder, validator, and workbook builder |
174
+ | `src/ifrs16kit/__init__.py` | Public API exports |
175
+ | `IFRS16_Input.xlsx` | Generated input template (step 2) |
176
+ | `IFRS16_Calculation.xlsx` | Generated liquid calculation workbook (step 5) |
177
+ | `VIGNETTE.md` | Worked example mapped to IFRS 16 paragraphs and ISA requirements |
178
+
179
+ The tool also runs without installation: `python src/ifrs16kit/core.py --demo`.
180
+
181
+ ## Limitations
182
+
183
+ Single lease, fixed payments, no mid-term modifications or remeasurements, no CPI-linked variable payments, template capacity of 120 payment periods. These are audit re-performance scoping choices, not engine defects: modifications and variable payments are covered qualitatively as procedures P-12 and P-13 on the Audit_Procedures sheet.
@@ -0,0 +1,156 @@
1
+ # LeaseAuditKit — Interactive IFRS 16 Re-performance Tool (LIQUID edition)
2
+
3
+ A standalone Python tool that re-performs a lessee's IFRS 16 lease accounting from first principles, independently of the client's own calculation, and delivers the result as a fully formula-driven ("liquid") Excel audit workbook. It is designed for the substantive re-performance of management's lease estimates under ISA 540 (accounting estimates), ISA 500 (audit evidence, including para A21 on re-performance), and ISA 230 (documentation).
4
+
5
+ Author: Ayce Makbule (Lena) Acar — MSc Business Analytics, Trinity College Dublin.
6
+
7
+ ## Why "liquid"?
8
+
9
+ Every derived figure in the generated workbook is a live Excel formula, not a hard-coded value. Change any dark-red input cell — lease term, IBR, payment frequency, country, depreciation method — and the entire model (liability, ROU asset, 120-period schedule, annual summary, journals, deferred tax) recalculates instantly inside Excel. The Python script never bakes numbers into the calculation sheets; it only writes the inputs and the formula fabric around them. A separate, independent Python engine re-computes the same figures so the auditor can verify the Excel model against a second implementation (a "two-engine" control).
10
+
11
+ ## Requirements
12
+
13
+ - Python 3.9+
14
+ - openpyxl (installed automatically as a dependency)
15
+ - Microsoft Excel (or LibreOffice) to fill the template and recalculate the output
16
+
17
+ Works from any environment: terminal, VS Code, Spyder, PyCharm.
18
+
19
+ ## Installation
20
+
21
+ From the package root (the folder containing `pyproject.toml`):
22
+
23
+ ```bash
24
+ pip install -e .
25
+ ```
26
+
27
+ The editable (`-e`) install means edits to `src/ifrs16kit/core.py` take
28
+ effect immediately without reinstalling. Installation registers both the
29
+ importable package (`import ifrs16kit`) and a terminal command
30
+ (`ifrs16kit`), usable from any directory.
31
+
32
+ ## Quick start
33
+
34
+ **Command line** (interactive flow):
35
+
36
+ ```bash
37
+ # Guided flow — 3 questions, then a fillable template
38
+ ifrs16kit
39
+
40
+ # Instant demo — runs the CALISMA golden benchmark end-to-end
41
+ ifrs16kit --demo
42
+ ```
43
+
44
+ **Spyder / notebook — interactive flow** (asks the questions, waits while you fill the template):
45
+
46
+ ```python
47
+ import ifrs16kit as lease
48
+ lease.run()
49
+ # 1. answers 3 questions in the console
50
+ # 2. writes IFRS16_Input.xlsx and PAUSES — open it in Excel, fill the
51
+ # dark-red cells, save, return to the console and press Enter
52
+ # 3. validates the template and writes IFRS16_Calculation.xlsx
53
+ ```
54
+
55
+ **Spyder / notebook — non-interactive two-step** (no questions; you control each step):
56
+
57
+ ```python
58
+ import ifrs16kit as lease
59
+
60
+ lease.demo() # instantly writes BOTH Excel files (golden case)
61
+
62
+ lease.create_input() # step 1: writes IFRS16_Input.xlsx → fill in Excel
63
+ lease.create_calculation() # step 2: reads it back → writes IFRS16_Calculation.xlsx
64
+ ```
65
+
66
+ `create_input()` accepts `country=`, `advance=`, `freq=` and a custom path;
67
+ `create_calculation()` accepts custom template/output paths.
68
+
69
+ **Python API** (programmatic — no interview, no template round-trip):
70
+
71
+ ```python
72
+ import ifrs16kit as lease
73
+
74
+ inp = lease.LeaseInputs(
75
+ entity="Example Co. Limited", country="Ireland",
76
+ commencement=__import__("datetime").date(2025, 1, 1),
77
+ term_years=2, freq=12, payment=650.0,
78
+ is_advance=True, ibr_annual=0.06, idc=600.0,
79
+ )
80
+
81
+ lease.cross_check(inp) # dict of key figures
82
+ lease.build_calculation_workbook(inp, "IFRS16_Calc.xlsx") # 10-sheet liquid workbook
83
+ lease.build_template({"country": "Ireland", "is_advance": True, "freq": 12},
84
+ "IFRS16_Input.xlsx") # blank input template
85
+ inp2 = lease.read_template("IFRS16_Input.xlsx") # validated read-back
86
+ ```
87
+
88
+ Public API: `LeaseInputs`, `cross_check`, `build_template`, `read_template`,
89
+ `build_calculation_workbook`, `print_summary`, plus the `COUNTRIES`,
90
+ `FREQUENCIES`, and `MAX_PERIODS` constants.
91
+
92
+ ## Workflow
93
+
94
+ 1. **Interview.** The script asks three questions: country/jurisdiction (Türkiye, Ireland, United Kingdom, UAE, Australia), payment timing (advance/arrears), and payment frequency (monthly, quarterly, semi-annual, annual).
95
+ 2. **Template.** It generates `IFRS16_Input.xlsx` — a single-sheet LIQUID input template. Only the dark-red, thick-bordered cells are editable inputs; everything else (total term, N, periodic rate, capacity checks) auto-calculates with live formulas. Dropdowns constrain frequency, timing, depreciation method, and country.
96
+ 3. **Fill and save.** Open the template in Excel, fill every dark-red cell, confirm the two green validation cells both say "OK", save, and return to the running script.
97
+ 4. **Validation.** The script reads the template back and validates it: non-empty entity, valid date, positive term/payment/useful life, IBR entered as a decimal or percentage below 100%, a whole number of payment periods, and N ≤ 120 (template capacity). Errors are listed cell-by-cell so they can be fixed and re-read without restarting.
98
+ 5. **Output.** It generates `IFRS16_Calculation.xlsx` — the full 10-sheet liquid workbook — and prints an independent Python cross-check of the key figures.
99
+
100
+ ## The generated workbook (10 sheets)
101
+
102
+ | Sheet | Contents |
103
+ |---|---|
104
+ | **Inputs** | All lease inputs plus live-linked key outputs (liability, ROU, totals) and country-driven framework/audit-standard lookups from Setup. |
105
+ | **Initial Measurement** | PV of lease payments period-by-period (IFRS 16 ¶26) and the ROU asset build-up (¶24: liability + IDC + prepayments − incentives + restoration). |
106
+ | **Lease Schedule** | 120-period-capacity amortisation and depreciation schedule (¶36 effective interest; ¶31 depreciation), with year tags and a Final Payment status flag. Rows self-hide beyond N. |
107
+ | **Annual Summary** | P&L impact and year-end balances by reporting year, a front-loading memo vs a straight-line charge, and five automated reconciliation checks (closing liability = 0, closing ROU = 0, principal = initial liability, expense = payments + IDC, front-loading sums to nil). |
108
+ | **Journals** | Initial-recognition entry with debit/credit balance check, plus representative Period 1 entries (payment, interest unwind, depreciation). |
109
+ | **Tax_Reconciliation** | Illustrative year-1 accounting-vs-cash-rental P&L difference and deferred-tax computation at the jurisdiction's rate. |
110
+ | **Findings** | Findings-and-recommendations register wired to the reconciliation checks — flags "Y" and a recommendation automatically when a check fails. |
111
+ | **Audit_Procedures** | 20 substantive procedures (P-1 to P-20) mapped to assertions (existence, completeness, accuracy, cut-off, classification, presentation). |
112
+ | **PBC_List** | 18-item prepared-by-client request list with purpose, format, and due dates. |
113
+ | **Setup** | Country lookup table driving currency, reporting framework, lease standard (IFRS 16 / TFRS 16 / AASB 16), audit standards (ISA / ISA (Ireland) / ISA (UK) / BDS / ASA 540-500-230), and illustrative tax rate. |
114
+
115
+ ## Colour and formatting conventions
116
+
117
+ - **Dark red fill, thick border, bold** — your input (client data / auditor assumptions)
118
+ - **Black** — formula / computed
119
+ - **Green font on light-green fill** — link to another sheet, or an automated check
120
+ - **Navy headers, Times New Roman throughout**
121
+
122
+ ## Calculation conventions
123
+
124
+ - Periodic discount rate uses the effective (compound) conversion: `(1 + IBR)^(1/frequency) − 1`, not simple pro-rata.
125
+ - Advance payments: the first payment is undiscounted (discount exponent `p − 1`); interest accrues on the opening liability net of the period's payment. Arrears: exponent `p`; interest on the full opening liability.
126
+ - Depreciation: straight-line over the shorter of the lease term and useful life (no ownership transfer assumed), or reducing balance at `1 − (1 − annual rate)^(1/frequency)` per period with a final-period write-off of the remaining carrying amount.
127
+
128
+ ## Verification
129
+
130
+ The tool ships with a golden benchmark (the CALISMA case: monthly advance, 24 periods, 6% IBR, 650/month, 600 IDC):
131
+
132
+ | Figure | Expected |
133
+ |---|---|
134
+ | Lease liability at commencement | 14,761.09 |
135
+ | ROU asset at commencement | 15,361.09 |
136
+ | Total interest over term | 838.91 |
137
+ | Total P&L charge | 16,200.00 |
138
+
139
+ Run `ifrs16kit --demo` and compare the console cross-check and `Inputs!B36:B42` of the generated workbook against these values. The five reconciliation checks on the Annual Summary sheet must all read "OK".
140
+
141
+ ## Files
142
+
143
+ | File | Role |
144
+ |---|---|
145
+ | `pyproject.toml` | Package metadata, dependency, and the `ifrs16kit` CLI entry point |
146
+ | `src/ifrs16kit/core.py` | The engine, template builder, validator, and workbook builder |
147
+ | `src/ifrs16kit/__init__.py` | Public API exports |
148
+ | `IFRS16_Input.xlsx` | Generated input template (step 2) |
149
+ | `IFRS16_Calculation.xlsx` | Generated liquid calculation workbook (step 5) |
150
+ | `VIGNETTE.md` | Worked example mapped to IFRS 16 paragraphs and ISA requirements |
151
+
152
+ The tool also runs without installation: `python src/ifrs16kit/core.py --demo`.
153
+
154
+ ## Limitations
155
+
156
+ Single lease, fixed payments, no mid-term modifications or remeasurements, no CPI-linked variable payments, template capacity of 120 payment periods. These are audit re-performance scoping choices, not engine defects: modifications and variable payments are covered qualitatively as procedures P-12 and P-13 on the Audit_Procedures sheet.
@@ -0,0 +1,39 @@
1
+ # TESTING — the ifrs16kit automated verification protocol
2
+
3
+ The suite verifies the package in six layers, from pure arithmetic up to a
4
+ fully automated version of the two-engine control described in VIGNETTE.md.
5
+
6
+ | Layer | File | What it proves |
7
+ |---|---|---|
8
+ | 1. Engine | `tests/test_engine.py` | The CALISMA golden benchmark (liability 14,761.09 · ROU 15,361.09 · interest 838.91); the periodic rate is an effective conversion; the liability matches an independent closed-form annuity ("third engine"); and across the full grid of frequency × timing × method × term × useful life, the accounting identities hold: closing liability = 0, liability + interest = payments, ROU = liability + IDC ± ¶24 items, total depreciation = ROU, closing ROU = 0, total P&L = payments + IDC. Includes the fractional useful-life regression. |
9
+ | 2. Template | `tests/test_template.py` | Required cells are generated blank (the cannot-run-on-example-values control); derived cells are live formulas including `B33 = MIN(B14,INT(B32))`; the four dropdowns exist; a user-style fill round-trips through `read_template` to the golden figures; and every validation rule rejects cell-by-cell (empty cells, IBR as whole percentage, non-whole N, N > 120, bad country/frequency/method/timing/date, non-positive amounts). |
10
+ | 3. Workbook | `tests/test_workbook.py` | Exactly ten sheets in documented order; the four core calculation sheets contain **zero** hard-coded numbers (the "liquid" claim); key outputs are cross-sheet links; the schedule is 120-row-capacity and row-guarded; the depreciation formula divides by the floored period count; Setup mirrors `COUNTRIES` exactly; Journals and Findings are wired across sheets; P-1…P-20 and the 18 PBC items are present; the workbook builds for all five jurisdictions. |
11
+ | 4. CLI & flow | `tests/test_cli.py` | `--demo` writes only `_DEMO` files and never touches real workbooks (regression); `python -m ifrs16kit` works; the full scripted interview → fill → validate → confirm → build flow completes; an invalid fill is rejected and the retry loop recovers; an existing filled template is detected and reused. |
12
+ | 5. API | `tests/test_api.py` | Every `__all__` export resolves; `__version__` equals the installed package metadata (single-sourcing); `create_input` / `create_calculation` work and reject bad arguments. |
13
+ | 6. Two-engine | `tests/test_excel_recalc.py` | LibreOffice recalculates the generated workbooks head-lessly and Excel's computed figures must equal `cross_check` within half a cent, for four scenarios (golden, arrears-quarterly, annual-UK-reducing-balance, fractional-life regression). All five Annual Summary reconciliation checks must read "OK". Skips when LibreOffice is absent; CI installs it. |
14
+
15
+ ## Running
16
+
17
+ ```bash
18
+ pip install -e .[dev]
19
+ pytest # layers 1–5 (~15 s); layer 6 auto-skips
20
+ pytest --cov=ifrs16kit --cov-report=term-missing
21
+ pytest tests/test_excel_recalc.py # layer 6, needs LibreOffice (soffice)
22
+ ```
23
+
24
+ If `soffice` is not on PATH, point `IFRS16KIT_SOFFICE` at a LibreOffice
25
+ binary (or a `.py` wrapper) before running layer 6.
26
+
27
+ ## Continuous integration
28
+
29
+ `.github/workflows/ci.yml` runs three jobs on every push and pull request:
30
+ layers 1–5 on Python 3.9 / 3.11 / 3.13 with a 90% coverage gate, layer 6 on
31
+ Ubuntu with `libreoffice-calc` installed, and a packaging job (`python -m
32
+ build` + `twine check`). A release is publishable only when all three are
33
+ green.
34
+
35
+ ## Extending
36
+
37
+ New calculation features need, at minimum: a golden value or identity in
38
+ layer 1, a formula/structure assertion in layer 3, and a recalc scenario in
39
+ layer 6 — so every figure stays proven twice, in Python and in Excel.
@@ -0,0 +1,139 @@
1
+ # Vignette — Re-performing a Lessee's IFRS 16 Calculation with ifrs16kit (LeaseAuditKit)
2
+
3
+ This vignette walks the CALISMA golden case end-to-end through the tool, mapping each step to the requirement in IFRS 16 it implements and the auditing standard (ISA) it supports. It is written from the perspective of an audit senior re-performing management's lease estimate as a substantive procedure.
4
+
5
+ ## The engagement scenario
6
+
7
+ Example Co. Limited (Ireland, EUR) leases a company car:
8
+
9
+ | Input | Value |
10
+ |---|---|
11
+ | Commencement date | 1 January 2025 |
12
+ | Lease term | 2 years (24 months) |
13
+ | Payment | €650 per month, **in advance** |
14
+ | Annual incremental borrowing rate (IBR) | 6.00% |
15
+ | Initial direct costs (IDC) | €600 |
16
+ | Prepayments / incentives / restoration | nil |
17
+ | Depreciation | Straight-line; useful life 60 months |
18
+
19
+ The client has recognised a lease liability and right-of-use (ROU) asset. Under ISA (Ireland) 540, the discounted liability is an accounting estimate; the auditor responds by **re-performing** the calculation independently — a form of audit evidence explicitly recognised in ISA (Ireland) 500 (re-performance, para A21). The tool documents that re-performance in a form retainable on file per ISA (Ireland) 230.
20
+
21
+ ## Step 1 — Configure
22
+
23
+ ```bash
24
+ ifrs16kit
25
+ ```
26
+
27
+ (Programmatic alternative for a scripted audit file: construct
28
+ `ifrs16kit.LeaseInputs(...)` directly and call
29
+ `build_calculation_workbook()` — see the README's Python API section.
30
+ The vignette follows the interactive route an audit senior would use.)
31
+
32
+ Three questions set the engagement conventions:
33
+
34
+ 1. **Country:** Ireland → the Setup lookup drives the currency (EUR €), reporting framework (IFRS, EU-adopted), lease standard (IFRS 16), audit standards (ISA (Ireland) 540/500/230), and an illustrative 12.5% tax rate. Choosing Türkiye, the UK, the UAE, or Australia swaps every one of these automatically (TFRS 16/BDS, UK-adopted IFRS, AASB 16/ASA, etc.).
35
+ 2. **Timing:** Advance.
36
+ 3. **Frequency:** Monthly (12/year).
37
+
38
+ ## Step 2 — The input template
39
+
40
+ The tool writes `IFRS16_Input.xlsx`. Only dark-red cells are inputs; the sheet is already "liquid":
41
+
42
+ - **Total term (B11)** `=B9*12+B10` — enter 2 years + 0 months and 24 appears.
43
+ - **N (B14)** `=B11/B13` — 24 monthly periods.
44
+ - **Periodic rate (B21)** `=(1+B20)^(1/B12)-1` = 0.4868% — an *effective* monthly conversion of the 6% annual IBR, not 0.5% simple pro-rata. This is the first common client error the re-performance can surface.
45
+ - Two green checks guard the template: capacity (N ≤ 120) and whole-number-of-periods (a 25-month term at quarterly frequency would fail here, before the auditor wastes any time downstream).
46
+
47
+ The auditor fills entity, asset, date, term, payment, IBR, IDC, and useful life, saves, and returns to the script.
48
+
49
+ ## Step 3 — Validation
50
+
51
+ `read_template()` re-reads the raw inputs and enforces the same rules in Python: valid date, positive amounts, IBR between 0 and 1, whole N, N ≤ 120. Validation failures are listed cell-by-cell (e.g. "IBR (B20) looks like a percentage — enter 0.06 or 6%") so the reviewer can trace every rejection to a specific cell — an ISA 230 documentation property.
52
+
53
+ ## Step 4 — Initial measurement (IFRS 16 ¶¶22–28)
54
+
55
+ The **Initial Measurement** sheet discounts each payment at the periodic rate. Because payments are in advance, the discount exponent is `p − 1`, so Period 1's €650 is undiscounted:
56
+
57
+ | Period | Payment | Factor | PV |
58
+ |---|---|---|---|
59
+ | 1 | 650.00 | 1.000000 | 650.00 |
60
+ | 2 | 650.00 | 0.995156 | 646.85 |
61
+ | … | … | … | … |
62
+ | 24 | 650.00 | 0.894329 | 581.31 |
63
+ | **Total (¶26)** | 15,600.00 | | **14,761.09** |
64
+
65
+ The ROU asset build-up applies ¶24 line by line:
66
+
67
+ | | |
68
+ |---|---|
69
+ | Lease liability at commencement | 14,761.09 |
70
+ | Add: initial direct costs | 600.00 |
71
+ | Add: prepaid payments | 0.00 |
72
+ | Less: incentives received | (0.00) |
73
+ | Add: restoration provision | 0.00 |
74
+ | **ROU asset at commencement (¶24)** | **15,361.09** |
75
+
76
+ Every one of these is an Excel formula referencing the Inputs sheet — the auditor (or reviewer) can change IDC to €1,000 and watch the ROU asset move to 15,761.09 with no code involved.
77
+
78
+ ## Step 5 — Subsequent measurement (¶36, ¶31)
79
+
80
+ The **Lease Schedule** sheet unwinds the liability using the effective interest method. For advance payments, interest accrues on the opening balance *net of* the period's payment:
81
+
82
+ `Interest_p = (Opening_p − Payment) × 0.48676%`
83
+
84
+ | Period | Opening | Interest | Principal | Closing | Depreciation |
85
+ |---|---|---|---|---|---|
86
+ | 1 | 14,761.09 | 68.69 | 581.31 | 14,179.78 | 640.05 |
87
+ | 2 | 14,179.78 | 65.86 | 584.14 | 13,595.63 | 640.05 |
88
+ | … | … | … | … | … | … |
89
+ | 24 | 650.00 | 0.00 | 650.00 | **0.00** | 640.05 |
90
+
91
+ Depreciation is straight-line over min(24, 60) = 24 periods: 15,361.09 ÷ 24 = 640.05 per period (¶31, no ownership transfer). The schedule is row-guarded to 120 periods — rows beyond N blank themselves out, so the same fabric serves a 6-month equipment lease or a 10-year property lease.
92
+
93
+ ## Step 6 — The audit assertions, automated
94
+
95
+ The **Annual Summary** sheet aggregates by reporting year and runs five reconciliation checks that correspond to the arithmetic assertions of the re-performance:
96
+
97
+ | Check | Balance | Status |
98
+ |---|---|---|
99
+ | Closing lease liability at end of term | ~0.00 | OK |
100
+ | Closing ROU asset at end of term | ~0.00 | OK |
101
+ | Total principal repaid − initial liability | 0.00 | OK |
102
+ | Total expense − (total payments + IDC) | 0.00 | OK |
103
+ | Sum of front-loading differences | ~0.00 | OK |
104
+
105
+ The front-loading memo quantifies the IFRS 16 expense profile against a straight-line equivalent: 2025 carries €214.97 *more* expense than straight-line, 2026 exactly €214.97 less — the characteristic front-loading of interest-bearing lease accounting, useful when explaining the P&L effect to the client or in an audit committee summary.
106
+
107
+ Any failed check propagates automatically to the **Findings** sheet, which flips the corresponding row to Adjustment = "Y" and switches the recommendation from "No adjustment required." to an investigation prompt.
108
+
109
+ ## Step 7 — Journals, tax, and the file
110
+
111
+ - **Journals** posts the commencement entry (Dr ROU 15,361.09; Cr liability 14,761.09; Cr cash — IDC 600.00) with a live debits-equals-credits check, plus representative Period 1 entries for the payment, interest unwind, and depreciation.
112
+ - **Tax_Reconciliation** contrasts the IFRS 16 P&L charge with a cash-rental deduction regime and computes the year-1 deferred tax at the Setup rate (12.5% for Ireland) — the temporary-difference mechanics an Irish or UK tax reviewer will ask about.
113
+ - **Audit_Procedures** (P-1 to P-20) and **PBC_List** (18 items) scope the wider IFRS 16 audit response beyond the single re-performed lease: completeness search via AP listings, IBR benchmarking, modifications, variable payments, expedients, FX, impairment, subleases, and sale-and-leaseback.
114
+
115
+ ## Step 8 — The two-engine control
116
+
117
+ Before writing the workbook, the tool prints an independent Python re-computation of the same figures (available programmatically as `ifrs16kit.cross_check(inp)`, which is how the package's own verification tests assert the golden values):
118
+
119
+ ```
120
+ Lease Liability (Day 1) : EUR 14,761.09 (IFRS 16, para 26)
121
+ ROU Asset (Day 1) : EUR 15,361.09 (IFRS 16, para 24)
122
+ Total Interest Expense : EUR 838.91
123
+ Closing liability : 0.000000 ✓ zero
124
+ Reconciliation: Liability + Interest = 15,600.00 = Total Payments ✓ RECONCILED
125
+ ```
126
+
127
+ The Excel model and the Python engine are two separate implementations of ¶¶24, 26, and 36. Agreement to the cent between them — and between both and the client's figure — is the re-performance evidence; disagreement with the client's figure is a finding, quantified and carried to the Findings sheet. This dual-implementation design addresses the reliability of the auditor's own tool (ISA 500's accuracy-and-completeness consideration for information produced by the auditor).
128
+
129
+ ## Standards map
130
+
131
+ | Tool element | IFRS 16 | ISA (Ireland) |
132
+ |---|---|---|
133
+ | PV of payments, discount rate | ¶26–¶27 | 540 ¶¶22–23 (estimate re-performance) |
134
+ | ROU cost build-up | ¶24 | 540 |
135
+ | Effective interest unwinding | ¶36 | 500 A21 (re-performance) |
136
+ | Depreciation basis | ¶31–¶32 | 500 |
137
+ | Reconciliation checks & findings | — | 540 ¶23, 450 (misstatement evaluation) |
138
+ | Templates, validation trail, workbook | — | 230 (documentation) |
139
+ | Procedures P-1–P-20, PBC list | ¶9, ¶42, ¶47, ¶B58, ¶99–103 | 500, 330 |
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ifrs16kit"
7
+ dynamic = ["version"]
8
+ description = "Interactive IFRS 16 auditor re-performance tool producing liquid Excel workbooks"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Ayce Makbule (Lena) Acar" }]
14
+ keywords = [
15
+ "IFRS 16", "lease accounting", "audit", "re-performance",
16
+ "ISA 540", "excel", "openpyxl", "right-of-use asset", "lease liability",
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 4 - Beta",
20
+ "Intended Audience :: Financial and Insurance Industry",
21
+ "Topic :: Office/Business :: Financial :: Accounting",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.9",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Programming Language :: Python :: 3.13",
28
+ "Operating System :: OS Independent",
29
+ "Environment :: Console",
30
+ ]
31
+ dependencies = ["openpyxl>=3.1"]
32
+
33
+ [project.optional-dependencies]
34
+ dev = ["pytest>=7.4", "pytest-cov>=4.1"]
35
+
36
+ # Fill these in once the GitHub repo is public, then rebuild:
37
+ # [project.urls]
38
+ # Homepage = "https://github.com/<user>/ifrs16kit"
39
+ # Repository = "https://github.com/<user>/ifrs16kit"
40
+ # Issues = "https://github.com/<user>/ifrs16kit/issues"
41
+
42
+ [project.scripts]
43
+ ifrs16kit = "ifrs16kit.core:main"
44
+
45
+ [tool.setuptools.packages.find]
46
+ where = ["src"]
47
+
48
+ [tool.setuptools.dynamic]
49
+ version = { attr = "ifrs16kit.__version__" }
50
+
51
+ [tool.pytest.ini_options]
52
+ testpaths = ["tests"]
53
+ addopts = "-q"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,43 @@
1
+ """
2
+ ifrs16kit — IFRS 16 auditor re-performance (LIQUID edition).
3
+
4
+ Public API
5
+ ----------
6
+ import ifrs16kit as lease
7
+ # or: from ifrs16kit import (
8
+ LeaseInputs, cross_check,
9
+ build_template, read_template, build_calculation_workbook,
10
+ COUNTRIES, FREQUENCIES,
11
+ )
12
+
13
+ Command line
14
+ ------------
15
+ ifrs16kit # guided interactive flow
16
+ ifrs16kit --demo # CALISMA golden case end-to-end
17
+ """
18
+
19
+ from .core import (
20
+ LeaseInputs,
21
+ create_input,
22
+ create_calculation,
23
+ demo,
24
+ cross_check,
25
+ build_template,
26
+ read_template,
27
+ build_calculation_workbook,
28
+ build_inputs_sheet,
29
+ print_summary,
30
+ COUNTRIES,
31
+ FREQUENCIES,
32
+ MAX_PERIODS,
33
+ main,
34
+ run,
35
+ )
36
+
37
+ __version__ = "1.0.0"
38
+
39
+ __all__ = [
40
+ "LeaseInputs", "create_input", "create_calculation", "demo", "cross_check", "build_template", "read_template",
41
+ "build_calculation_workbook", "build_inputs_sheet", "print_summary",
42
+ "COUNTRIES", "FREQUENCIES", "MAX_PERIODS", "main", "run", "__version__",
43
+ ]
@@ -0,0 +1,5 @@
1
+ """Allow `python -m ifrs16kit` to invoke the CLI."""
2
+ from .core import main
3
+
4
+ if __name__ == "__main__":
5
+ main()