@diy-accounting-uk/diya-gl 1.2.52 → 1.2.54
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.
|
@@ -1585,6 +1585,58 @@
|
|
|
1585
1585
|
"scorecard": "101608 passed, 0 warnings, 0 failed"
|
|
1586
1586
|
}
|
|
1587
1587
|
}
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
"tag": "diya-gl-v1.2.52",
|
|
1591
|
+
"date": "2026-10-10",
|
|
1592
|
+
"formatVersion": "diya-gl/1",
|
|
1593
|
+
"engineVersion": "1.2.52+f18282c3",
|
|
1594
|
+
"taxDataHash": "51bdff60e993",
|
|
1595
|
+
"reconciledCommit": "54e8731a91279975e61b1a232fbb67fda89515f0",
|
|
1596
|
+
"templates": {
|
|
1597
|
+
"bst": {
|
|
1598
|
+
"hash": "0d003e10e00c",
|
|
1599
|
+
"scorecard": "812 passed, 0 warnings, 0 failed"
|
|
1600
|
+
},
|
|
1601
|
+
"taxi": {
|
|
1602
|
+
"hash": "1ff69654d64d",
|
|
1603
|
+
"scorecard": "700 passed, 0 warnings, 0 failed"
|
|
1604
|
+
},
|
|
1605
|
+
"se": {
|
|
1606
|
+
"hash": "064605ae76ed",
|
|
1607
|
+
"scorecard": "8015 passed, 0 warnings, 0 failed"
|
|
1608
|
+
},
|
|
1609
|
+
"ltd": {
|
|
1610
|
+
"hash": "a65ab09cf35c",
|
|
1611
|
+
"scorecard": "101608 passed, 0 warnings, 0 failed"
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
},
|
|
1615
|
+
{
|
|
1616
|
+
"tag": "diya-gl-v1.2.53",
|
|
1617
|
+
"date": "2026-10-20",
|
|
1618
|
+
"formatVersion": "diya-gl/1",
|
|
1619
|
+
"engineVersion": "1.2.53+f18282c3",
|
|
1620
|
+
"taxDataHash": "51bdff60e993",
|
|
1621
|
+
"reconciledCommit": "54e8731a91279975e61b1a232fbb67fda89515f0",
|
|
1622
|
+
"templates": {
|
|
1623
|
+
"bst": {
|
|
1624
|
+
"hash": "0d003e10e00c",
|
|
1625
|
+
"scorecard": "812 passed, 0 warnings, 0 failed"
|
|
1626
|
+
},
|
|
1627
|
+
"taxi": {
|
|
1628
|
+
"hash": "1ff69654d64d",
|
|
1629
|
+
"scorecard": "700 passed, 0 warnings, 0 failed"
|
|
1630
|
+
},
|
|
1631
|
+
"se": {
|
|
1632
|
+
"hash": "064605ae76ed",
|
|
1633
|
+
"scorecard": "8015 passed, 0 warnings, 0 failed"
|
|
1634
|
+
},
|
|
1635
|
+
"ltd": {
|
|
1636
|
+
"hash": "a65ab09cf35c",
|
|
1637
|
+
"scorecard": "101608 passed, 0 warnings, 0 failed"
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1588
1640
|
}
|
|
1589
1641
|
]
|
|
1590
1642
|
}
|
|
@@ -73,6 +73,20 @@ const REVERSE_SALES = buildReverseCodeMap(LTD_SALES_CODE_MAP);
|
|
|
73
73
|
/**
|
|
74
74
|
* Check if a cell contains a formula (has <f> tag).
|
|
75
75
|
*/
|
|
76
|
+
// The rows between first and last, inclusive, on which the column holds a cell with content:
|
|
77
|
+
// a typed value or a formula. A bank book's receipt and payment lists sit side by side and each
|
|
78
|
+
// has gaps where the other side has a row, so a reader walks the rows its own column fills
|
|
79
|
+
// rather than stopping at the first gap or testing every row of the sheet.
|
|
80
|
+
function rowsWithContent(xml, column, first, last) {
|
|
81
|
+
const rows = new Set();
|
|
82
|
+
const cellPattern = new RegExp(`<c\\s+r="${column}(\\d+)"[^>]*>`, "g");
|
|
83
|
+
for (const match of xml.matchAll(cellPattern)) {
|
|
84
|
+
const row = Number(match[1]);
|
|
85
|
+
if (row >= first && row <= last && !match[0].endsWith("/>")) rows.add(row);
|
|
86
|
+
}
|
|
87
|
+
return [...rows].sort((a, b) => a - b);
|
|
88
|
+
}
|
|
89
|
+
|
|
76
90
|
function hasCellFormula(xml, cellRef) {
|
|
77
91
|
const cellPattern = new RegExp(`<c\\s+r="${cellRef}"[^>]*(?:/>|>([\\s\\S]*?)</c>)`, "s");
|
|
78
92
|
const match = xml.match(cellPattern);
|
|
@@ -952,12 +966,14 @@ export async function extractBankTransactions(set, product, period, extractionMa
|
|
|
952
966
|
obEmitted = true;
|
|
953
967
|
}
|
|
954
968
|
|
|
955
|
-
// Receipts: rows 6+, A=date, B=source, E=code, F=amount
|
|
956
|
-
|
|
969
|
+
// Receipts: rows 6+, A=date, B=source, E=code, F=amount. A bank book lists receipts and
|
|
970
|
+
// payments side by side in statement order, so a row with a payment and no receipt is a
|
|
971
|
+
// gap on this side, not the end of the list; only the totals formula ends it.
|
|
972
|
+
for (const row of rowsWithContent(xml, "F", 6, 200)) {
|
|
973
|
+
if (hasCellFormula(xml, `F${row}`)) break;
|
|
957
974
|
const dateVal = readCellValue(xml, `A${row}`, sharedStrings);
|
|
958
975
|
const amount = readCellValue(xml, `F${row}`, sharedStrings);
|
|
959
|
-
if (dateVal === null || amount === null || typeof amount !== "number")
|
|
960
|
-
if (hasCellFormula(xml, `F${row}`)) break;
|
|
976
|
+
if (dateVal === null || amount === null || typeof amount !== "number") continue;
|
|
961
977
|
|
|
962
978
|
const source = readCellValue(xml, `B${row}`, sharedStrings) || "";
|
|
963
979
|
const code = readCellValue(xml, `E${row}`, sharedStrings) || "";
|
|
@@ -984,11 +1000,11 @@ export async function extractBankTransactions(set, product, period, extractionMa
|
|
|
984
1000
|
}
|
|
985
1001
|
|
|
986
1002
|
// Payments: rows 6+, columns per the file's payment layout
|
|
987
|
-
for (
|
|
1003
|
+
for (const row of rowsWithContent(xml, payment.amount, 6, 200)) {
|
|
1004
|
+
if (hasCellFormula(xml, `${payment.amount}${row}`)) break;
|
|
988
1005
|
const dateVal = readCellValue(xml, `${payment.date}${row}`, sharedStrings);
|
|
989
1006
|
const amount = readCellValue(xml, `${payment.amount}${row}`, sharedStrings);
|
|
990
|
-
if (dateVal === null || amount === null || typeof amount !== "number")
|
|
991
|
-
if (hasCellFormula(xml, `${payment.amount}${row}`)) break;
|
|
1007
|
+
if (dateVal === null || amount === null || typeof amount !== "number") continue;
|
|
992
1008
|
|
|
993
1009
|
const supplier = readCellValue(xml, `${payment.supplier}${row}`, sharedStrings) || "";
|
|
994
1010
|
const code = readCellValue(xml, `${payment.code}${row}`, sharedStrings) || "";
|