@diy-accounting-uk/diya-gl 1.0.0

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 (157) hide show
  1. package/README.md +63 -0
  2. package/bin/diya-gl-mcp.js +10 -0
  3. package/bin/diya-gl-read-workbook.js +11 -0
  4. package/bin/diya-gl-recalc.js +10 -0
  5. package/bin/diya-gl-write-workbook.js +12 -0
  6. package/bin/diya-gl.js +24 -0
  7. package/bin/run-dist-bin.js +23 -0
  8. package/dist/app/bin/build-diya-gl-spec.js +680 -0
  9. package/dist/app/bin/build-packages.js +149 -0
  10. package/dist/app/bin/build-reconciliation-pages.js +1052 -0
  11. package/dist/app/bin/build-sitemaps.js +51 -0
  12. package/dist/app/bin/compliance-report.js +125 -0
  13. package/dist/app/bin/cross-package-reconciliation.js +92 -0
  14. package/dist/app/bin/diya-gl-mcp.js +27 -0
  15. package/dist/app/bin/export.js +318 -0
  16. package/dist/app/bin/extract-scenarios.js +1348 -0
  17. package/dist/app/bin/generate.js +353 -0
  18. package/dist/app/bin/judge-reconciliation.js +649 -0
  19. package/dist/app/bin/reconcile.js +247 -0
  20. package/dist/app/bin/report.js +291 -0
  21. package/dist/app/bin/verify-roundtrip.js +941 -0
  22. package/dist/app/bin/verify-stability.js +429 -0
  23. package/dist/app/bin/write-workbook.js +106 -0
  24. package/dist/app/data/filing/ct-computation-v1.1.toml +1033 -0
  25. package/dist/app/data/filing/ct600-v3.toml +2329 -0
  26. package/dist/app/data/filing/frs105-formats.toml +244 -0
  27. package/dist/app/data/fixture-master-gaps.json +247 -0
  28. package/dist/app/data/hmrc/SOURCE.md +14 -0
  29. package/dist/app/data/hmrc/form-layouts/bst.json +116 -0
  30. package/dist/app/data/hmrc/form-layouts/ltd.json +452 -0
  31. package/dist/app/data/hmrc/form-layouts/se.json +485 -0
  32. package/dist/app/data/hmrc/form-layouts/taxi.json +117 -0
  33. package/dist/app/data/hmrc/sa103-mtd-mapping.json +1078 -0
  34. package/dist/app/data/hmrc/sa103f_mapping_v3.csv +111 -0
  35. package/dist/app/data/judge-rubric.md +52 -0
  36. package/dist/app/data/ltd-2020.toml +49 -0
  37. package/dist/app/data/ltd-2021.toml +49 -0
  38. package/dist/app/data/ltd-2022.toml +49 -0
  39. package/dist/app/data/ltd-2023.toml +49 -0
  40. package/dist/app/data/ltd-2024.toml +49 -0
  41. package/dist/app/data/ltd-2025.toml +49 -0
  42. package/dist/app/data/ltd-2026.toml +53 -0
  43. package/dist/app/data/ltd-2027.toml +51 -0
  44. package/dist/app/data/render-unrepresentable/bst.json +24 -0
  45. package/dist/app/data/render-unrepresentable/ltd.json +863 -0
  46. package/dist/app/data/render-unrepresentable/se.json +455 -0
  47. package/dist/app/data/render-unrepresentable/taxi.json +16 -0
  48. package/dist/app/data/roundtrip-budget.json +38 -0
  49. package/dist/app/data/roundtrip-matrix-budget.json +26 -0
  50. package/dist/app/data/roundtrip-unrepresentable.json +401 -0
  51. package/dist/app/data/se-2020-2021.toml +52 -0
  52. package/dist/app/data/se-2021-2022.toml +52 -0
  53. package/dist/app/data/se-2022-2023.toml +55 -0
  54. package/dist/app/data/se-2023-2024.toml +54 -0
  55. package/dist/app/data/se-2024-2025.toml +51 -0
  56. package/dist/app/data/se-2025-2026.toml +51 -0
  57. package/dist/app/data/se-2026-2027.toml +51 -0
  58. package/dist/app/data/volatile-cells.json +16 -0
  59. package/dist/app/lib/anchors/bst.js +79 -0
  60. package/dist/app/lib/anchors/ltd.js +626 -0
  61. package/dist/app/lib/anchors/run.js +100 -0
  62. package/dist/app/lib/anchors/se.js +456 -0
  63. package/dist/app/lib/anchors/taxi.js +164 -0
  64. package/dist/app/lib/app-resources.js +80 -0
  65. package/dist/app/lib/book-checks/ltd.js +408 -0
  66. package/dist/app/lib/book-checks/se.js +687 -0
  67. package/dist/app/lib/book-checks/taxi.js +215 -0
  68. package/dist/app/lib/book-checks.js +872 -0
  69. package/dist/app/lib/books-engine.js +197 -0
  70. package/dist/app/lib/books-interchange.js +533 -0
  71. package/dist/app/lib/calculators/bst.js +381 -0
  72. package/dist/app/lib/calculators/ltd.js +1938 -0
  73. package/dist/app/lib/calculators/se.js +1239 -0
  74. package/dist/app/lib/calculators/shared.js +131 -0
  75. package/dist/app/lib/calculators/taxi.js +461 -0
  76. package/dist/app/lib/canonical-report-value.js +77 -0
  77. package/dist/app/lib/compliance-report.js +341 -0
  78. package/dist/app/lib/diya-gl-calculator.js +52 -0
  79. package/dist/app/lib/diya-gl-canonical.js +355 -0
  80. package/dist/app/lib/diya-gl-edits-ltd.js +144 -0
  81. package/dist/app/lib/diya-gl-edits.js +361 -0
  82. package/dist/app/lib/diya-gl-loader.js +774 -0
  83. package/dist/app/lib/diya-gl-schema.js +212 -0
  84. package/dist/app/lib/generator.js +1912 -0
  85. package/dist/app/lib/guide.js +33 -0
  86. package/dist/app/lib/headlines.js +293 -0
  87. package/dist/app/lib/link-caches.js +421 -0
  88. package/dist/app/lib/ltd-layout.js +139 -0
  89. package/dist/app/lib/mcp/diya-gl-tools.js +330 -0
  90. package/dist/app/lib/mcp/jsonrpc-stdio.js +66 -0
  91. package/dist/app/lib/mcp/server.js +65 -0
  92. package/dist/app/lib/overtype-sidecar.js +180 -0
  93. package/dist/app/lib/package-builder.js +202 -0
  94. package/dist/app/lib/payslips-date-chain.js +481 -0
  95. package/dist/app/lib/payslips-layout.js +235 -0
  96. package/dist/app/lib/period-shift.js +111 -0
  97. package/dist/app/lib/product-workbook.js +317 -0
  98. package/dist/app/lib/products.js +27 -0
  99. package/dist/app/lib/provenance-data.js +36 -0
  100. package/dist/app/lib/provenance.js +92 -0
  101. package/dist/app/lib/report-generator.js +374 -0
  102. package/dist/app/lib/report-indicators.js +468 -0
  103. package/dist/app/lib/report-serializer.js +392 -0
  104. package/dist/app/lib/scenario-extractor.js +1403 -0
  105. package/dist/app/lib/scenario-loader.js +84 -0
  106. package/dist/app/lib/sitemap-builder.js +59 -0
  107. package/dist/app/lib/spreadsheet-runner.js +566 -0
  108. package/dist/app/lib/tax/capital-allowances.js +77 -0
  109. package/dist/app/lib/tax/corporation-tax.js +144 -0
  110. package/dist/app/lib/tax/income-tax.js +122 -0
  111. package/dist/app/lib/tax/mileage.js +69 -0
  112. package/dist/app/lib/tax/national-insurance.js +31 -0
  113. package/dist/app/lib/tax/vat.js +188 -0
  114. package/dist/app/lib/tax-year.js +31 -0
  115. package/dist/app/lib/template-formula-map.js +253 -0
  116. package/dist/app/lib/workbook-set.js +153 -0
  117. package/dist/app/lib/xlsx-exporter.js +2815 -0
  118. package/dist/app/lib/xlsx-parts.js +111 -0
  119. package/dist/app/lib/xlsx-reader.js +84 -0
  120. package/dist/app/products/bst.js +727 -0
  121. package/dist/app/products/ltd.js +4270 -0
  122. package/dist/app/products/se.js +3403 -0
  123. package/dist/app/products/taxi.js +912 -0
  124. package/dist/app/templates/bst/bst-excel.xlsx +0 -0
  125. package/dist/app/templates/bst/meta.toml +27 -0
  126. package/dist/app/templates/ltd/Cashaccount.xlsx +0 -0
  127. package/dist/app/templates/ltd/Companysecretary.xlsx +0 -0
  128. package/dist/app/templates/ltd/Creditcardaccount.xlsx +0 -0
  129. package/dist/app/templates/ltd/Currentaccount.xlsx +0 -0
  130. package/dist/app/templates/ltd/Dividend Voucher.docx +0 -0
  131. package/dist/app/templates/ltd/Financialaccounts.xlsx +0 -0
  132. package/dist/app/templates/ltd/Fixedassets.xlsx +0 -0
  133. package/dist/app/templates/ltd/Payslips.xlsx +0 -0
  134. package/dist/app/templates/ltd/Purchases.xlsx +0 -0
  135. package/dist/app/templates/ltd/Sales.xlsx +0 -0
  136. package/dist/app/templates/ltd/Salesinvoice.xlsx +0 -0
  137. package/dist/app/templates/ltd/Savingaccount.xlsx +0 -0
  138. package/dist/app/templates/ltd/Vatreturns.xlsx +0 -0
  139. package/dist/app/templates/ltd/expensesform.xlsx +0 -0
  140. package/dist/app/templates/ltd/meta.toml +54 -0
  141. package/dist/app/templates/meta.toml +12 -0
  142. package/dist/app/templates/se/Bank.xlsx +0 -0
  143. package/dist/app/templates/se/Cash.xlsx +0 -0
  144. package/dist/app/templates/se/Financialaccounts.xlsx +0 -0
  145. package/dist/app/templates/se/Fixedassets.xlsx +0 -0
  146. package/dist/app/templates/se/Payslips.xlsx +0 -0
  147. package/dist/app/templates/se/Purchases.xlsx +0 -0
  148. package/dist/app/templates/se/Sales.xlsx +0 -0
  149. package/dist/app/templates/se/Salesinvoice.xlsx +0 -0
  150. package/dist/app/templates/se/Vat.xlsx +0 -0
  151. package/dist/app/templates/se/meta.toml +43 -0
  152. package/dist/app/templates/taxi/meta.toml +43 -0
  153. package/dist/app/templates/taxi/taxi-excel.xlsx +0 -0
  154. package/dist/web/spreadsheets.diyaccounting.co.uk/public/schema/diya-gl-book-v2.schema.json +713 -0
  155. package/dist/web/spreadsheets.diyaccounting.co.uk/public/schema/diya-gl-docs.md +930 -0
  156. package/dist/web/spreadsheets.diyaccounting.co.uk/public/schema/diya-gl-lines-v2.schema.json +220 -0
  157. package/package.json +37 -0
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env node
2
+ // SPDX-License-Identifier: AGPL-3.0-only
3
+ // Copyright (C) 2025-2026 DIY Accounting Ltd
4
+ //
5
+ // build-packages.js — Scan packages/ directories, create zip files, generate catalogue.toml
6
+ //
7
+ // Usage:
8
+ // node app/bin/build-packages.js # Build all packages
9
+ // node app/bin/build-packages.js --years 2 # Build only packages from last 2 years
10
+ //
11
+ // Reads: packages/ (product directories with Excel workbooks and PDFs)
12
+ // Writes: target/zips/ (zip files for S3 upload)
13
+ // web/spreadsheets.diyaccounting.co.uk/public/catalogue.toml
14
+
15
+ import { existsSync, readdirSync, mkdirSync, rmSync, unlinkSync, writeFileSync } from "fs";
16
+ import { join, dirname, resolve } from "path";
17
+ import { execSync } from "child_process";
18
+ import { fileURLToPath } from "url";
19
+ import { PRODUCTS, parsePackageDir, parseCompanyAnyDir, generateCompanyVariantNames, generateCatalogue } from "../lib/package-builder.js";
20
+
21
+ const __dirname = dirname(fileURLToPath(import.meta.url));
22
+ const ROOT = resolve(__dirname, "..", "..");
23
+ const PACKAGES_DIR = join(ROOT, "packages");
24
+ const ZIPS_DIR = join(ROOT, "target", "zips");
25
+ const CATALOGUE_PATH = join(ROOT, "web", "spreadsheets.diyaccounting.co.uk", "public", "catalogue.toml");
26
+
27
+ // Parse --years N argument (default: no filter, build all)
28
+ const yearsArg = process.argv.indexOf("--years");
29
+ const YEARS_LIMIT = yearsArg !== -1 && process.argv[yearsArg + 1] ? parseInt(process.argv[yearsArg + 1], 10) : null;
30
+ const CUTOFF_DATE = YEARS_LIMIT ? new Date(Date.now() - YEARS_LIMIT * 365.25 * 24 * 60 * 60 * 1000) : null;
31
+
32
+ function zipDirectory(sourceDir, zipPath) {
33
+ const zipDir = dirname(zipPath);
34
+ mkdirSync(zipDir, { recursive: true });
35
+ if (existsSync(zipPath)) unlinkSync(zipPath);
36
+ execSync(`zip -r "${zipPath}" . -q -X -x "*/.git/*" "*.sh"`, {
37
+ cwd: sourceDir,
38
+ stdio: "pipe",
39
+ });
40
+ }
41
+
42
+ function scanAndBuild() {
43
+ if (existsSync(ZIPS_DIR)) rmSync(ZIPS_DIR, { recursive: true });
44
+ mkdirSync(ZIPS_DIR, { recursive: true });
45
+
46
+ if (!existsSync(PACKAGES_DIR)) {
47
+ console.error(`packages/ directory not found at ${PACKAGES_DIR}`);
48
+ process.exit(1);
49
+ }
50
+
51
+ const entries = readdirSync(PACKAGES_DIR, { withFileTypes: true })
52
+ .filter((e) => e.isDirectory())
53
+ .map((e) => e.name)
54
+ .sort();
55
+
56
+ const allPackages = [];
57
+ const now = new Date();
58
+
59
+ for (const dirName of entries) {
60
+ const dirPath = join(PACKAGES_DIR, dirName);
61
+
62
+ // Skip work-in-progress
63
+ if (existsSync(join(dirPath, "DO NOT USE - WORK IN PROGRESS.txt"))) {
64
+ console.log(`Skipping (WIP): ${dirName}`);
65
+ continue;
66
+ }
67
+
68
+ // Try Company (Any) pattern first
69
+ const anyParsed = parseCompanyAnyDir(dirName);
70
+ if (anyParsed) {
71
+ const { startYear, endYear, format } = anyParsed;
72
+
73
+ if (CUTOFF_DATE && new Date(`${endYear + 1}-04-01`) < CUTOFF_DATE) {
74
+ console.log(`Skipping (older than ${YEARS_LIMIT}y): ${dirName}`);
75
+ continue;
76
+ }
77
+
78
+ console.log(`Company (Any): ${dirName} → generating monthly variants`);
79
+ const { variants, skipped } = generateCompanyVariantNames(startYear, endYear, format, now);
80
+
81
+ for (const label of skipped) {
82
+ console.log(` Skipping Company variant (FY not started): ${label}`);
83
+ }
84
+
85
+ for (const v of variants) {
86
+ const zipPath = join(ZIPS_DIR, `${v.zipName}.zip`);
87
+ console.log(` Zipping Company variant: ${v.zipName}`);
88
+ zipDirectory(dirPath, zipPath);
89
+ allPackages.push({
90
+ product: "Company",
91
+ date: v.date,
92
+ shortLabel: v.shortLabel,
93
+ format: v.format,
94
+ filename: `${v.zipName}.zip`,
95
+ });
96
+ }
97
+ continue;
98
+ }
99
+
100
+ // Standard package pattern
101
+ const parsed = parsePackageDir(dirName);
102
+ if (!parsed) {
103
+ console.log(`Skipping (unrecognised): ${dirName}`);
104
+ continue;
105
+ }
106
+
107
+ const { productName, date, shortLabel, format } = parsed;
108
+
109
+ if (CUTOFF_DATE && new Date(date) < CUTOFF_DATE) {
110
+ console.log(`Skipping (older than ${YEARS_LIMIT}y): ${dirName}`);
111
+ continue;
112
+ }
113
+
114
+ if (!PRODUCTS[productName]) {
115
+ console.log(`Skipping (filtered): ${dirName}`);
116
+ continue;
117
+ }
118
+
119
+ const zipName = `${dirName}.zip`;
120
+ const zipPath = join(ZIPS_DIR, zipName);
121
+
122
+ console.log(`Zipping: ${dirName}`);
123
+ zipDirectory(dirPath, zipPath);
124
+
125
+ allPackages.push({ product: productName, date, shortLabel, format, filename: zipName });
126
+ }
127
+
128
+ return allPackages;
129
+ }
130
+
131
+ // Main
132
+ console.log("=== build-packages ===");
133
+ console.log(`Packages dir: ${PACKAGES_DIR}`);
134
+ console.log(`Output zips: ${ZIPS_DIR}`);
135
+ if (YEARS_LIMIT) {
136
+ console.log(`Year filter: last ${YEARS_LIMIT} year(s) (cutoff: ${CUTOFF_DATE.toISOString().split("T")[0]})`);
137
+ }
138
+ console.log("");
139
+
140
+ const packages = scanAndBuild();
141
+ const generatedDate = new Date().toISOString().split("T")[0];
142
+ const toml = generateCatalogue(packages, generatedDate);
143
+ mkdirSync(dirname(CATALOGUE_PATH), { recursive: true });
144
+ writeFileSync(CATALOGUE_PATH, toml, "utf8");
145
+ console.log(`\nCatalogue written to ${CATALOGUE_PATH}`);
146
+ console.log(`Total packages: ${packages.length}`);
147
+
148
+ const zipFiles = readdirSync(ZIPS_DIR).filter((f) => f.endsWith(".zip"));
149
+ console.log(`\nGenerated ${zipFiles.length} zip files in target/zips/`);