@diy-accounting-uk/diya-gl 1.2.11 → 1.2.13
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.
- package/dist/app/data/releases.json +52 -0
- package/dist/app/data/render-unrepresentable/bst.json +1 -1
- package/dist/app/data/render-unrepresentable/se.json +2 -1
- package/dist/app/lib/calculators/se-derivations.js +0 -8
- package/dist/app/lib/calculators/se.js +9 -4
- package/dist/app/lib/provenance-data.js +3 -3
- package/dist/app/products/se.js +45 -23
- package/package.json +1 -1
|
@@ -519,6 +519,58 @@
|
|
|
519
519
|
"scorecard": "101565 passed, 0 warnings, 0 failed"
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
"tag": "diya-gl-v1.2.11",
|
|
525
|
+
"date": "2026-09-13",
|
|
526
|
+
"formatVersion": "diya-gl/1",
|
|
527
|
+
"engineVersion": "1.2.11+32b8b8c8",
|
|
528
|
+
"taxDataHash": "4ecdbe985d22",
|
|
529
|
+
"reconciledCommit": "c910fdeefbe4f2f71ae9ec5f5d4a713783a1c0c7",
|
|
530
|
+
"templates": {
|
|
531
|
+
"bst": {
|
|
532
|
+
"hash": "0d003e10e00c",
|
|
533
|
+
"scorecard": "812 passed, 0 warnings, 0 failed"
|
|
534
|
+
},
|
|
535
|
+
"taxi": {
|
|
536
|
+
"hash": "1ff69654d64d",
|
|
537
|
+
"scorecard": "686 passed, 0 warnings, 0 failed"
|
|
538
|
+
},
|
|
539
|
+
"se": {
|
|
540
|
+
"hash": "2d5629384e82",
|
|
541
|
+
"scorecard": "7952 passed, 0 warnings, 0 failed"
|
|
542
|
+
},
|
|
543
|
+
"ltd": {
|
|
544
|
+
"hash": "caa14632083b",
|
|
545
|
+
"scorecard": "101605 passed, 0 warnings, 0 failed"
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"tag": "diya-gl-v1.2.12",
|
|
551
|
+
"date": "2026-09-14",
|
|
552
|
+
"formatVersion": "diya-gl/1",
|
|
553
|
+
"engineVersion": "1.2.12+8ad4ddf1",
|
|
554
|
+
"taxDataHash": "4ecdbe985d22",
|
|
555
|
+
"reconciledCommit": "c910fdeefbe4f2f71ae9ec5f5d4a713783a1c0c7",
|
|
556
|
+
"templates": {
|
|
557
|
+
"bst": {
|
|
558
|
+
"hash": "0d003e10e00c",
|
|
559
|
+
"scorecard": "812 passed, 0 warnings, 0 failed"
|
|
560
|
+
},
|
|
561
|
+
"taxi": {
|
|
562
|
+
"hash": "1ff69654d64d",
|
|
563
|
+
"scorecard": "686 passed, 0 warnings, 0 failed"
|
|
564
|
+
},
|
|
565
|
+
"se": {
|
|
566
|
+
"hash": "4decdcb12664",
|
|
567
|
+
"scorecard": "7952 passed, 0 warnings, 0 failed"
|
|
568
|
+
},
|
|
569
|
+
"ltd": {
|
|
570
|
+
"hash": "caa14632083b",
|
|
571
|
+
"scorecard": "101605 passed, 0 warnings, 0 failed"
|
|
572
|
+
}
|
|
573
|
+
}
|
|
522
574
|
}
|
|
523
575
|
]
|
|
524
576
|
}
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
"cell/SE Short!D94": "The SA103S view's box table (sa103s, books/products/bst.js) does not print this box.",
|
|
21
21
|
"section/self-assessment-sa103s/other-tax-adjustments": "The SA103S view's box table (sa103s, books/products/bst.js) does not print this box.",
|
|
22
22
|
"cell/SE Short!D106": "The SA103S view's box table (sa103s, books/products/bst.js) does not print this box.",
|
|
23
|
-
"section/self-assessment-sa103s/net-profit-for-tax-calc": "The SA103S view's box table (sa103s, books/products/bst.js) does not print this box."
|
|
23
|
+
"section/self-assessment-sa103s/net-profit-for-tax-calc-box-31": "The SA103S view's box table (sa103s, books/products/bst.js) does not print this box."
|
|
24
24
|
}
|
|
@@ -461,5 +461,6 @@
|
|
|
461
461
|
"section/journal-category-vat-netting/business-entertainment-memo-purchases-e/net": "The journal-category-vat-netting report is a reconciliation table (categoryNettingLines, products/se.js) explaining how a gross journal figure nets into a statement cell; no page view is this table.",
|
|
462
462
|
"section/journal-category-vat-netting/business-entertainment-memo-purchases-e/residue": "The journal-category-vat-netting report is a reconciliation table (categoryNettingLines, products/se.js) explaining how a gross journal figure nets into a statement cell; no page view is this table.",
|
|
463
463
|
"section/journal-category-vat-netting/business-entertainment-memo-purchases-e/vat": "The journal-category-vat-netting report is a reconciliation table (categoryNettingLines, products/se.js) explaining how a gross journal figure nets into a statement cell; no page view is this table.",
|
|
464
|
-
"section/accounting-profit-to-tax-profit-bridge/add-disallowable-expenses-added-back-box-46": "The page has no profit-bridge view; the bridge from accounting profit to tax profit is not printed anywhere on the books page."
|
|
464
|
+
"section/accounting-profit-to-tax-profit-bridge/add-disallowable-expenses-added-back-box-46": "The page has no profit-bridge view; the bridge from accounting profit to tax profit is not printed anywhere on the books page.",
|
|
465
|
+
"section/accounting-profit-to-tax-profit-bridge/add-the-full-return-s-own-box-71-adjustment-for-change-of-accounting-practice": "The page has no profit-bridge view; the bridge from accounting profit to tax profit is not printed anywhere on the books page."
|
|
465
466
|
}
|
|
@@ -605,14 +605,6 @@ export function buildSelfEmploymentAnnualSubmission(book, lines, taxData, option
|
|
|
605
605
|
"SA103F box 54 has no formula behind it and the book states no tax.selfEmployment.allowances.electricChargePointAllowance; the box stays blank.",
|
|
606
606
|
});
|
|
607
607
|
}
|
|
608
|
-
if (cellNumber("D210") !== 0) {
|
|
609
|
-
warnings.push({
|
|
610
|
-
field: primaryField(boxes, "71"),
|
|
611
|
-
reason:
|
|
612
|
-
"SE Full carries box 71 into box 77 (D219 = O179+E197+D210+P190) and not into box 73 (O194 = O174); HMRC computes the adjusted profit from the filed field, so the sheet's printed box 73 and its Income Tax sheet leave it out.",
|
|
613
|
-
handComputed: round2(seFull.O174 + cellNumber("D210")),
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
608
|
for (const { box: boxNumber, pick } of NO_SOURCE_ANNUAL_BOXES) {
|
|
617
609
|
const entry = boxEntry(boxes, boxNumber);
|
|
618
610
|
const field = fieldsOf(entry)[pick];
|
|
@@ -1175,13 +1175,18 @@ export function calculateSeCells(book, lines, taxData, scenario = {}) {
|
|
|
1175
1175
|
const fromNetLoss = -seFull.O129 + seFull.D174 - seFull.O169;
|
|
1176
1176
|
return fromNetLoss < 0 ? -fromNetLoss : 0;
|
|
1177
1177
|
});
|
|
1178
|
-
|
|
1178
|
+
// HMRC's SA103F working sheet for boxes 73 and 77 takes one figure, box
|
|
1179
|
+
// 64 less box 65 plus boxes 68, 71 and 72: box 73 is that figure when it
|
|
1180
|
+
// is positive and box 77 is its negation when it is not. The sheet reads
|
|
1181
|
+
// O174-O179+N(D197)+D210+N(O190); boxes 68 and 72 have no input cell on
|
|
1182
|
+
// this template, so their printed dash cells (D197, O190) contribute nil
|
|
1183
|
+
// and box 71 (D210) is the only adjustment that moves either figure.
|
|
1184
|
+
const adjustedProfitBeforeFloor = carry([seFull.O174, seFull.O179], () => seFull.O174 - seFull.O179 + sheetNumber(seFull.D210));
|
|
1185
|
+
seFull.O194 = carry([adjustedProfitBeforeFloor], () => Math.max(0, adjustedProfitBeforeFloor));
|
|
1179
1186
|
seFull.O204 = pl.B11;
|
|
1180
1187
|
seFull.O199 = carry([seFull.O194], () => (sheetNumber(seFull.D179) > 0 ? 0 : Math.min(seFull.O194 + seFull.O204, lossesBroughtForward)));
|
|
1181
1188
|
seFull.O210 = carry([seFull.O194, seFull.O199], () => seFull.O194 - seFull.O199 + seFull.O204);
|
|
1182
|
-
|
|
1183
|
-
// cell beside each printed dash, so only box 71 joins the loss.
|
|
1184
|
-
seFull.D219 = carry([seFull.O179], () => seFull.O179 + sheetNumber(seFull.D210));
|
|
1189
|
+
seFull.D219 = carry([adjustedProfitBeforeFloor], () => Math.max(0, -adjustedProfitBeforeFloor));
|
|
1185
1190
|
seFull.O224 = seFull.D219;
|
|
1186
1191
|
seFull.D231 = contractorDeductions;
|
|
1187
1192
|
seFull.J280 = admin.N20;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
export const PROVENANCE_DATA = {
|
|
14
14
|
formatVersion: "diya-gl/1",
|
|
15
|
-
engineVersion: "1.2.
|
|
15
|
+
engineVersion: "1.2.13+f5b44cdf",
|
|
16
16
|
taxDataHash: "4ecdbe985d22",
|
|
17
17
|
reconciledCommit: "c910fdeefbe4f2f71ae9ec5f5d4a713783a1c0c7",
|
|
18
18
|
templates: {
|
|
@@ -25,8 +25,8 @@ export const PROVENANCE_DATA = {
|
|
|
25
25
|
scorecard: "686 passed, 0 warnings, 0 failed",
|
|
26
26
|
},
|
|
27
27
|
se: {
|
|
28
|
-
hash: "
|
|
29
|
-
scorecard: "
|
|
28
|
+
hash: "15d3b753f7a4",
|
|
29
|
+
scorecard: "7956 passed, 0 warnings, 0 failed",
|
|
30
30
|
},
|
|
31
31
|
ltd: {
|
|
32
32
|
hash: "caa14632083b",
|
package/dist/app/products/se.js
CHANGED
|
@@ -230,10 +230,12 @@ export const DISALLOWABLE_PERCENT_CELLS = {
|
|
|
230
230
|
// The SA103F boxes the trader states by hand, keyed by HMRC's own API field
|
|
231
231
|
// names. Verified against the template: SE Full!O154 (box 57) reads
|
|
232
232
|
// D139+D144+D147+D152+D156+D160+O139+O144+O149, so every allowance cell here
|
|
233
|
-
// is a term of the total; O169 (box 63) reads O154+D179;
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
233
|
+
// is a term of the total; O169 (box 63) reads O154+D179; O194 (box 73) and
|
|
234
|
+
// D219 (box 77) each floor the working sheet's one figure,
|
|
235
|
+
// O174-O179+N(D197)+D210+N(O190), at nil from its own side. Box 54's caption
|
|
236
|
+
// at N136 is "Electric charge-point allowance" (L136 = 54); box 55's cell
|
|
237
|
+
// O144 is the small pools formula, so the enhanced-allowance figure has no
|
|
238
|
+
// input cell of its own.
|
|
237
239
|
export const ANNUAL_ALLOWANCE_CELLS = {
|
|
238
240
|
zeroEmissionsGoodsVehicleAllowance: "D152",
|
|
239
241
|
zeroEmissionsCarAllowance: "D156",
|
|
@@ -1842,6 +1844,11 @@ export function profitBridge(results) {
|
|
|
1842
1844
|
{ label: "Less the full return's own Structures and Buildings Allowance (box 53)", cell: "SE Full!D160", value: -num(seFull?.D160) },
|
|
1843
1845
|
{ label: "Less the full return's own electric charge-point allowance (box 54)", cell: "SE Full!O139", value: -num(seFull?.O139) },
|
|
1844
1846
|
{ label: "Less the full return's own box 62 adjustment", cell: "SE Full!D179", value: -num(seFull?.D179) },
|
|
1847
|
+
{
|
|
1848
|
+
label: "Add the full return's own box 71 adjustment for change of accounting practice",
|
|
1849
|
+
cell: "SE Full!D210",
|
|
1850
|
+
value: num(seFull?.D210),
|
|
1851
|
+
},
|
|
1845
1852
|
{
|
|
1846
1853
|
label: "Add back the year's loss, carried forward rather than reducing tax below nil",
|
|
1847
1854
|
cell: "SE Full!O179",
|
|
@@ -2278,13 +2285,14 @@ export function checkCompliance(results, expected, taxData, calculateExpectedTax
|
|
|
2278
2285
|
);
|
|
2279
2286
|
// Income Tax!E5 reads 'SE Full'!O210, so the short return's box 31
|
|
2280
2287
|
// reaches it only through the full return: the two agree exactly when
|
|
2281
|
-
// no box the trader states on SE Full alone (52, 52.1, 53, 54, 62
|
|
2282
|
-
// carries a figure, and stand apart by those figures otherwise.
|
|
2288
|
+
// no box the trader states on SE Full alone (52, 52.1, 53, 54, 62 and
|
|
2289
|
+
// 71) carries a figure, and stand apart by those figures otherwise.
|
|
2283
2290
|
const fullOnly = results["SE Full"] || {};
|
|
2284
|
-
const fullReturnOnlyBoxes =
|
|
2291
|
+
const fullReturnOnlyBoxes =
|
|
2292
|
+
num(fullOnly.D152) + num(fullOnly.D156) + num(fullOnly.D160) + num(fullOnly.O139) + num(fullOnly.D179) - num(fullOnly.D210);
|
|
2285
2293
|
if (seShort.D106) {
|
|
2286
2294
|
check(
|
|
2287
|
-
"SA103S: Profit for tax (D106) less the SE Full-only boxes 52, 52.1, 53, 54 and 62 = Income Tax E5",
|
|
2295
|
+
"SA103S: Profit for tax (D106) less the SE Full-only boxes 52, 52.1, 53, 54 and 62 plus box 71 = Income Tax E5",
|
|
2288
2296
|
Math.max(0, num(seShort.D106) - fullReturnOnlyBoxes),
|
|
2289
2297
|
tax.E5,
|
|
2290
2298
|
);
|
|
@@ -2507,7 +2515,21 @@ export function checkCompliance(results, expected, taxData, calculateExpectedTax
|
|
|
2507
2515
|
num(seFull.O174),
|
|
2508
2516
|
taxProfitFromNetProfit > 0 ? taxProfitFromNetProfit : Math.max(0, taxProfitFromNetLoss),
|
|
2509
2517
|
);
|
|
2510
|
-
|
|
2518
|
+
// HMRC's working sheet for boxes 73 and 77 takes one figure, box 64 less
|
|
2519
|
+
// box 65 plus boxes 68, 71 and 72; box 73 is it when positive, box 77 its
|
|
2520
|
+
// negation when not. Boxes 68 (D197) and 72 (O190) print a dash on this
|
|
2521
|
+
// template and contribute nil, so box 71 is the only adjustment here.
|
|
2522
|
+
const adjustedProfitBeforeFloor = num(seFull.O174) - num(seFull.O179) + num(seFull.D210);
|
|
2523
|
+
check(
|
|
2524
|
+
"SA103F box 73 adjusted profit (O194) = box 64 less box 65 plus box 71, floored at nil",
|
|
2525
|
+
num(seFull.O194),
|
|
2526
|
+
Math.max(0, adjustedProfitBeforeFloor),
|
|
2527
|
+
);
|
|
2528
|
+
check(
|
|
2529
|
+
"SA103F box 77 adjusted loss (D219) = box 65 less box 64 and box 71, floored at nil",
|
|
2530
|
+
num(seFull.D219),
|
|
2531
|
+
Math.max(0, -adjustedProfitBeforeFloor),
|
|
2532
|
+
);
|
|
2511
2533
|
check(
|
|
2512
2534
|
"SA103F box 76 total taxable profits (O210) = box 73 less box 74 plus box 75",
|
|
2513
2535
|
num(seFull.O210),
|
|
@@ -2604,21 +2626,19 @@ export function checkCompliance(results, expected, taxData, calculateExpectedTax
|
|
|
2604
2626
|
num(seFull.D174) - num(seFull.O122) - num(seFull.O160),
|
|
2605
2627
|
ownUseStated,
|
|
2606
2628
|
);
|
|
2607
|
-
//
|
|
2608
|
-
// box
|
|
2629
|
+
// The same two boxes anchored on the figure the book states, so a sheet
|
|
2630
|
+
// whose box 71 cell and adjusted figures agree with each other but not
|
|
2631
|
+
// with the book fails here.
|
|
2632
|
+
const statedAccountingAdjustment = statedAdjustments.accountingAdjustment || 0;
|
|
2609
2633
|
check(
|
|
2610
|
-
"SA103F box
|
|
2611
|
-
num(seFull.
|
|
2612
|
-
num(seFull.
|
|
2634
|
+
"SA103F box 73 adjusted profit (O194) = box 64 less box 65 plus the box 71 figure the book states, floored at nil",
|
|
2635
|
+
num(seFull.O194),
|
|
2636
|
+
Math.max(0, num(seFull.O174) - num(seFull.O179) + statedAccountingAdjustment),
|
|
2613
2637
|
);
|
|
2614
|
-
// Box 73 reads box 64 alone (O194 = O174). HMRC's working sheet adds box
|
|
2615
|
-
// 71 to the adjusted profit; the sheet carries box 71 into box 77 only.
|
|
2616
2638
|
check(
|
|
2617
|
-
"SA103F box
|
|
2618
|
-
num(seFull.
|
|
2619
|
-
num(seFull.
|
|
2620
|
-
0.01,
|
|
2621
|
-
"warning",
|
|
2639
|
+
"SA103F box 77 adjusted loss (D219) = box 65 less box 64 and the box 71 figure the book states, floored at nil",
|
|
2640
|
+
num(seFull.D219),
|
|
2641
|
+
Math.max(0, num(seFull.O179) - num(seFull.O174) - statedAccountingAdjustment),
|
|
2622
2642
|
);
|
|
2623
2643
|
|
|
2624
2644
|
if (sa103s) {
|
|
@@ -2646,10 +2666,12 @@ export function checkCompliance(results, expected, taxData, calculateExpectedTax
|
|
|
2646
2666
|
num(seFull.O174),
|
|
2647
2667
|
Math.max(0, num(sa103s.D99) - fullReturnOnlyDeductions),
|
|
2648
2668
|
);
|
|
2669
|
+
// Box 71 is the one SE Full-only figure that adds to the taxable
|
|
2670
|
+
// profit; the short return has no box for it either.
|
|
2649
2671
|
check(
|
|
2650
|
-
"SA103F box 76 total taxable profits: full return (O210) = short return (D106) less the SE Full-only boxes 52, 52.1, 53, 54 and 62, with each return's own loss set-off",
|
|
2672
|
+
"SA103F box 76 total taxable profits: full return (O210) = short return (D106) less the SE Full-only boxes 52, 52.1, 53, 54 and 62 plus box 71, with each return's own loss set-off",
|
|
2651
2673
|
num(seFull.O210),
|
|
2652
|
-
Math.max(0, num(sa103s.D106) - fullReturnOnlyDeductions + num(sa103s.O94) - num(seFull.O199)),
|
|
2674
|
+
Math.max(0, num(sa103s.D106) - fullReturnOnlyDeductions + num(seFull.D210) + num(sa103s.O94) - num(seFull.O199)),
|
|
2653
2675
|
);
|
|
2654
2676
|
check(
|
|
2655
2677
|
"SA103S box 28 net business profit for tax purposes (D99) leaves out the allowances and box 62 adjustment the trader states on SE Full alone",
|