@fin.cx/tax 2.5.0 → 2.6.1

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/tax',
6
- version: '2.5.0',
6
+ version: '2.6.1',
7
7
  description: 'German tax computation engine: UStVA Kennzahl aggregation from ledger balances with form rounding, Zahllast and reconciliation checks — exact cents'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxhQUFhO0lBQ25CLE9BQU8sRUFBRSxPQUFPO0lBQ2hCLFdBQVcsRUFBRSxxSkFBcUo7Q0FDbkssQ0FBQSJ9
@@ -30,14 +30,29 @@
30
30
  * tax) and did not exempt the supplies but levied no tax on them; a year
31
31
  * before 2025 answers `before_2025` and is not told.
32
32
  *
33
- * Not read: the BMF-Schreiben of 18 March 2025 (UStAE Abschn. 19.1 ff.),
34
- * which the BMF site did not serve. Two questions it answers stay open here:
35
- * the limit in the year the business starts, which the statute does not name
36
- * (`business_started_this_year` answers `unknown`), and whether the supply by
37
- * which the running year exceeds 100 000 € is itself taxed. The statute's
38
- * wording (the running year's Gesamtumsatz "nicht überschreitet") is read so
39
- * that it is: `endsWith` names the receipt at which the sum first exceeds the
40
- * limit, and every receipt from it on is taxed.
33
+ * The year the business starts: the statute names no limit of its own for it
34
+ * (there is no previous year). The reasoning of the Jahressteuergesetz 2024
35
+ * (BT-Drs. 20/12780, read on dserver.bundestag.de 2026-09-30, p. 183 f., zu
36
+ * § 19 Abs. 1) does: "Nimmt der Unternehmer seine gewerbliche oder berufliche
37
+ * Tätigkeit auf, ist § 19 Absatz 1 Satz 1 UStG mit der Maßgabe anzuwenden,
38
+ * dass der Gesamtumsatz im laufenden Kalenderjahr den Betrag von 25 000 Euro
39
+ * nicht überschreitet. Bereits der Umsatz, mit dem die Grenze überschritten
40
+ * wird, unterliegt der Regelbesteuerung." (Art. 288a Abs. 1 UAbs. 3 RL
41
+ * 2006/112 EG); "Die bis zum Zeitpunkt der Überschreitung bewirkten Umsätze
42
+ * sind steuerfrei." And zu Abs. 2: "Übt der Unternehmer seine gewerbliche
43
+ * oder berufliche Tätigkeit nur für einen Teil des Kalenderjahres aus,
44
+ * entfällt die bisherige Umrechnung in einen Jahresgesamtumsatz": a part of a
45
+ * year counts as it is, in the year the business starts and as the next
46
+ * year's previous year. The Anleitung zur Umsatzsteuer-Voranmeldung 2026
47
+ * (p. 8, Zeile 12) reads the founding year the same way.
48
+ *
49
+ * The supply by which the running year exceeds 100 000 €: the reasoning says
50
+ * the scheme no longer applies "ab diesem Zeitpunkt", and the statute exempts
51
+ * a supply while the running year's Gesamtumsatz "nicht überschreitet"; both
52
+ * are read so that it is taxed: `endsWith` names the receipt at which the sum
53
+ * first exceeds the limit, and every receipt from it on is taxed. Not read:
54
+ * the BMF-Schreiben of 18 March 2025 (UStAE Abschn. 19.1 ff.), which the BMF
55
+ * site did not serve.
41
56
  */
42
57
  import type { TCents } from '@fin.cx/calculation';
43
58
  /** The first calendar year of the version of § 19 UStG this module applies (Jahressteuergesetz 2024, from 1 January 2025). */
@@ -46,6 +61,8 @@ export declare const SMALL_BUSINESS_FIRST_YEAR = 2025;
46
61
  export declare const SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS: TCents;
47
62
  /** 100 000 €: the running calendar year's limit (§ 19 Abs. 1 Satz 1 UStG) */
48
63
  export declare const SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS: TCents;
64
+ /** 25 000 €: the running calendar year's limit in the year the business starts (BT-Drs. 20/12780, p. 183 f., zu § 19 Abs. 1 UStG) */
65
+ export declare const SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS: TCents;
49
66
  /**
50
67
  * What a receipt is to the Gesamtumsatz (§ 19 Abs. 2 UStG):
51
68
  * - `counted`: an Entgelt for a steuerbarer Umsatz (§ 1 Abs. 1 Nr. 1), taxed or
@@ -76,7 +93,12 @@ export interface IGesamtumsatzOfYear {
76
93
  totalCents: TCents;
77
94
  leftOutCents: Record<Exclude<TGesamtumsatzPart, 'counted'>, TCents>;
78
95
  }
79
- /** Why a year starts with the exemption or without it. */
96
+ /**
97
+ * Why a year starts with the exemption or without it. `within_limits` and
98
+ * `business_started_this_year` start it exempt: the one by the previous
99
+ * year's Gesamtumsatz, the other as the year the business starts, which has
100
+ * none (its running limit is 25 000 €).
101
+ */
80
102
  export type TSmallBusinessReason = 'within_limits' | 'previous_year_over' | 'waived' | 'previous_year_unknown' | 'business_started_this_year'
81
103
  /** a year before 2025, under the version with other limits (`SMALL_BUSINESS_FIRST_YEAR`): not told */
82
104
  | 'before_2025';
@@ -100,9 +122,17 @@ export interface ISmallBusinessStatus {
100
122
  atStart: 'exempt' | 'taxable' | 'unknown';
101
123
  reason: TSmallBusinessReason;
102
124
  /**
103
- * Where the year starts exempt and its Gesamtumsatz exceeds 100 000 €: the
104
- * receipt by which it first does (its day, its place in the receipts as
105
- * given, the sum with it). It and every later receipt are taxed.
125
+ * Where the year starts exempt: the running year's Gesamtumsatz up to which
126
+ * it stays exempt, 100 000 € (`SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS`), or
127
+ * 25 000 € in the year the business starts
128
+ * (`SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS`)
129
+ */
130
+ runningLimitCents?: TCents;
131
+ /**
132
+ * Where the year starts exempt and its Gesamtumsatz exceeds
133
+ * `runningLimitCents`: the receipt by which it first does (its day, its
134
+ * place in the receipts as given, the sum with it). It and every later
135
+ * receipt are taxed.
106
136
  */
107
137
  endsWith?: {
108
138
  receivedOn: string;
@@ -118,7 +148,9 @@ export declare function gesamtumsatzOf(receiptsArg: readonly IGesamtumsatzReceip
118
148
  * Whether a calendar year's supplies are exempt under § 19 Abs. 1 UStG: from
119
149
  * its start where the previous year's Gesamtumsatz did not exceed 25 000 € and
120
150
  * no waiver is in force, until the receipt by which the running year's
121
- * Gesamtumsatz exceeds 100 000 € (`endsWith`).
151
+ * Gesamtumsatz exceeds 100 000 € (`endsWith`). In the year the business
152
+ * starts (`previousYearCents: 'business_started'`) from its start, until the
153
+ * receipt by which it exceeds 25 000 €, counted as it is, not as a whole year.
122
154
  */
123
155
  export declare function smallBusinessStatusOf(inputArg: ISmallBusinessYearInput): ISmallBusinessStatus;
124
156
  /** The last calendar year a waiver effective for `yearArg` binds (§ 19 Abs. 3 Satz 3 UStG: at least five calendar years). */
@@ -4,6 +4,8 @@ export const SMALL_BUSINESS_FIRST_YEAR = 2025;
4
4
  export const SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS = 2_500_000;
5
5
  /** 100 000 €: the running calendar year's limit (§ 19 Abs. 1 Satz 1 UStG) */
6
6
  export const SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS = 10_000_000;
7
+ /** 25 000 €: the running calendar year's limit in the year the business starts (BT-Drs. 20/12780, p. 183 f., zu § 19 Abs. 1 UStG) */
8
+ export const SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS = 2_500_000;
7
9
  export const GESAMTUMSATZ_PARTS = ['counted', 'exempt_section_4_listed', 'exempt_ancillary', 'fixed_assets', 'not_taxable_here'];
8
10
  const isCalendarDay = (valueArg) => {
9
11
  if (typeof valueArg !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(valueArg)) {
@@ -52,7 +54,9 @@ export function gesamtumsatzOf(receiptsArg, yearArg) {
52
54
  * Whether a calendar year's supplies are exempt under § 19 Abs. 1 UStG: from
53
55
  * its start where the previous year's Gesamtumsatz did not exceed 25 000 € and
54
56
  * no waiver is in force, until the receipt by which the running year's
55
- * Gesamtumsatz exceeds 100 000 € (`endsWith`).
57
+ * Gesamtumsatz exceeds 100 000 € (`endsWith`). In the year the business
58
+ * starts (`previousYearCents: 'business_started'`) from its start, until the
59
+ * receipt by which it exceeds 25 000 €, counted as it is, not as a whole year.
56
60
  */
57
61
  export function smallBusinessStatusOf(inputArg) {
58
62
  assertYear(inputArg.year);
@@ -76,23 +80,23 @@ export function smallBusinessStatusOf(inputArg) {
76
80
  if (inputArg.waived === true) {
77
81
  return { ...base, atStart: 'taxable', reason: 'waived' };
78
82
  }
79
- if (previous === 'business_started') {
80
- return { ...base, atStart: 'unknown', reason: 'business_started_this_year' };
81
- }
82
83
  if (previous === undefined) {
83
84
  return { ...base, atStart: 'unknown', reason: 'previous_year_unknown' };
84
85
  }
85
- if (previous > SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS) {
86
+ if (previous !== 'business_started' && previous > SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS) {
86
87
  return { ...base, atStart: 'taxable', reason: 'previous_year_over' };
87
88
  }
89
+ const reason = previous === 'business_started' ? 'business_started_this_year' : 'within_limits';
90
+ const runningLimitCents = previous === 'business_started' ? SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS : SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS;
91
+ const exempt = { ...base, atStart: 'exempt', reason, runningLimitCents };
88
92
  let sum = 0;
89
93
  for (const { receipt, index } of counted) {
90
94
  sum += receipt.entgeltCents;
91
- if (sum > SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS) {
92
- return { ...base, atStart: 'exempt', reason: 'within_limits', endsWith: { receivedOn: receipt.receivedOn, index, runningCents: sum } };
95
+ if (sum > runningLimitCents) {
96
+ return { ...exempt, endsWith: { receivedOn: receipt.receivedOn, index, runningCents: sum } };
93
97
  }
94
98
  }
95
- return { ...base, atStart: 'exempt', reason: 'within_limits' };
99
+ return exempt;
96
100
  }
97
101
  /** The last calendar year a waiver effective for `yearArg` binds (§ 19 Abs. 3 Satz 3 UStG: at least five calendar years). */
98
102
  export function smallBusinessWaiverBindsUntil(yearArg) {
@@ -110,4 +114,4 @@ export function smallBusinessWaiverDeadline(yearArg) {
110
114
  const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
111
115
  return `${year}-02-${leap ? '29' : '28'}`;
112
116
  }
113
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hbGxidXNpbmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYWxsYnVzaW5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBMkNBLDhIQUE4SDtBQUM5SCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLENBQUM7QUFFOUMsNkVBQTZFO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLHdDQUF3QyxHQUFXLFNBQVMsQ0FBQztBQUMxRSw2RUFBNkU7QUFDN0UsTUFBTSxDQUFDLE1BQU0sdUNBQXVDLEdBQVcsVUFBVSxDQUFDO0FBa0IxRSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBaUMsQ0FBQyxTQUFTLEVBQUUseUJBQXlCLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixDQUFDLENBQUM7QUEwRC9KLE1BQU0sYUFBYSxHQUFHLENBQUMsUUFBaUIsRUFBc0IsRUFBRTtJQUM5RCxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQzFFLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNELE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN0RCxPQUFPLElBQUksQ0FBQyxjQUFjLEVBQUUsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLEtBQUssR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxLQUFLLEdBQUcsQ0FBQztBQUN6RyxDQUFDLENBQUM7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
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hbGxidXNpbmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYWxsYnVzaW5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBMERBLDhIQUE4SDtBQUM5SCxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLENBQUM7QUFFOUMsNkVBQTZFO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLHdDQUF3QyxHQUFXLFNBQVMsQ0FBQztBQUMxRSw2RUFBNkU7QUFDN0UsTUFBTSxDQUFDLE1BQU0sdUNBQXVDLEdBQVcsVUFBVSxDQUFDO0FBQzFFLHFJQUFxSTtBQUNySSxNQUFNLENBQUMsTUFBTSx3Q0FBd0MsR0FBVyxTQUFTLENBQUM7QUFrQjFFLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFpQyxDQUFDLFNBQVMsRUFBRSx5QkFBeUIsRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztBQXVFL0osTUFBTSxhQUFhLEdBQUcsQ0FBQyxRQUFpQixFQUFzQixFQUFFO0lBQzlELElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDMUUsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDM0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE9BQU8sSUFBSSxDQUFDLGNBQWMsRUFBRSxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLEtBQUssS0FBSyxHQUFHLENBQUMs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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fin.cx/tax",
3
- "version": "2.5.0",
3
+ "version": "2.6.1",
4
4
  "private": false,
5
5
  "description": "German tax computation engine: UStVA Kennzahl aggregation from ledger balances with form rounding, Zahllast and reconciliation checks — exact cents",
6
6
  "main": "dist_ts/index.js",
@@ -29,13 +29,13 @@
29
29
  "homepage": "https://code.foss.global/fin.cx/tax#readme",
30
30
  "dependencies": {
31
31
  "@fin.cx/calculation": "^1.1.1",
32
- "@fin.cx/chartdata": "^2.12.1"
32
+ "@fin.cx/chartdata": "^3.1.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@git.zone/tsbuild": "^5.0.0",
35
+ "@git.zone/tsbuild": "^5.1.2",
36
36
  "@git.zone/tsrun": "^3.0.2",
37
- "@git.zone/tstest": "^6.3.2",
38
- "@types/node": "^26.6.2"
37
+ "@git.zone/tstest": "^7.2.0",
38
+ "@types/node": "^26.6.3"
39
39
  },
40
40
  "files": [
41
41
  "ts/**/*",
package/readme.md CHANGED
@@ -89,16 +89,26 @@ const status = tax.smallBusinessStatusOf({
89
89
  previousYearCents: tax.gesamtumsatzOf(receipts, 2025).totalCents,
90
90
  receipts, // [{ receivedOn: '2026-03-01', entgeltCents: 120000, part: 'counted' }, …]
91
91
  });
92
- // { atStart: 'exempt', reason: 'within_limits', endsWith?: { receivedOn, index, runningCents }, runningCents }
92
+ // { atStart: 'exempt', reason: 'within_limits', runningLimitCents: 10000000, endsWith?: { receivedOn, index, runningCents }, runningCents }
93
93
  ```
94
94
 
95
95
  `endsWith` names the receipt by which the running year first exceeds
96
- 100 000 €; it and every later one are taxed. A waiver (§ 19 Abs. 3) makes the
97
- year `taxable`; `smallBusinessWaiverDeadline`, `…BindsUntil` and
98
- `…RevocableFrom` give its dates. The year the business starts answers
99
- `unknown`: the statute names no limit for it. So does a year before 2025
100
- (`before_2025`), under the version with other limits (22 000 € / 50 000 €,
101
- with the tax). The rules cover businesses resident in Germany or the areas of
96
+ `runningLimitCents` (100 000 €); it and every later one are taxed. A waiver
97
+ (§ 19 Abs. 3) makes the year `taxable`; `smallBusinessWaiverDeadline`,
98
+ `…BindsUntil` and `…RevocableFrom` give its dates.
99
+
100
+ The year the business starts (`previousYearCents: 'business_started'`) has no
101
+ previous year, and the statute names no limit of its own for it. The reasoning
102
+ of the Jahressteuergesetz 2024 (BT-Drs. 20/12780, p. 183 f.) does: the running
103
+ year's Gesamtumsatz must not exceed 25 000 €, and the supply by which it does is
104
+ taxed already. So that year starts `exempt` (`business_started_this_year`) with
105
+ `runningLimitCents` 25 000 € (`SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS`), and
106
+ `endsWith` names the receipt above it. A part of a year is not converted to a
107
+ whole year any longer (same source, zu Abs. 2): three months with 24 000 € are
108
+ 24 000 €, in the year the business starts and as the next year's previous year.
109
+
110
+ A year before 2025 answers `unknown` (`before_2025`), under the version with
111
+ other limits (22 000 € / 50 000 €, with the tax). The rules cover businesses resident in Germany or the areas of
102
112
  § 1 Abs. 3 UStG; the new vehicles of § 19 Abs. 6 are not modelled.
103
113
 
104
114
  ## German VAT rates, dated
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/tax',
6
- version: '2.5.0',
6
+ version: '2.6.1',
7
7
  description: 'German tax computation engine: UStVA Kennzahl aggregation from ledger balances with form rounding, Zahllast and reconciliation checks — exact cents'
8
8
  }
@@ -30,14 +30,29 @@
30
30
  * tax) and did not exempt the supplies but levied no tax on them; a year
31
31
  * before 2025 answers `before_2025` and is not told.
32
32
  *
33
- * Not read: the BMF-Schreiben of 18 March 2025 (UStAE Abschn. 19.1 ff.),
34
- * which the BMF site did not serve. Two questions it answers stay open here:
35
- * the limit in the year the business starts, which the statute does not name
36
- * (`business_started_this_year` answers `unknown`), and whether the supply by
37
- * which the running year exceeds 100 000 € is itself taxed. The statute's
38
- * wording (the running year's Gesamtumsatz "nicht überschreitet") is read so
39
- * that it is: `endsWith` names the receipt at which the sum first exceeds the
40
- * limit, and every receipt from it on is taxed.
33
+ * The year the business starts: the statute names no limit of its own for it
34
+ * (there is no previous year). The reasoning of the Jahressteuergesetz 2024
35
+ * (BT-Drs. 20/12780, read on dserver.bundestag.de 2026-09-30, p. 183 f., zu
36
+ * § 19 Abs. 1) does: "Nimmt der Unternehmer seine gewerbliche oder berufliche
37
+ * Tätigkeit auf, ist § 19 Absatz 1 Satz 1 UStG mit der Maßgabe anzuwenden,
38
+ * dass der Gesamtumsatz im laufenden Kalenderjahr den Betrag von 25 000 Euro
39
+ * nicht überschreitet. Bereits der Umsatz, mit dem die Grenze überschritten
40
+ * wird, unterliegt der Regelbesteuerung." (Art. 288a Abs. 1 UAbs. 3 RL
41
+ * 2006/112 EG); "Die bis zum Zeitpunkt der Überschreitung bewirkten Umsätze
42
+ * sind steuerfrei." And zu Abs. 2: "Übt der Unternehmer seine gewerbliche
43
+ * oder berufliche Tätigkeit nur für einen Teil des Kalenderjahres aus,
44
+ * entfällt die bisherige Umrechnung in einen Jahresgesamtumsatz": a part of a
45
+ * year counts as it is, in the year the business starts and as the next
46
+ * year's previous year. The Anleitung zur Umsatzsteuer-Voranmeldung 2026
47
+ * (p. 8, Zeile 12) reads the founding year the same way.
48
+ *
49
+ * The supply by which the running year exceeds 100 000 €: the reasoning says
50
+ * the scheme no longer applies "ab diesem Zeitpunkt", and the statute exempts
51
+ * a supply while the running year's Gesamtumsatz "nicht überschreitet"; both
52
+ * are read so that it is taxed: `endsWith` names the receipt at which the sum
53
+ * first exceeds the limit, and every receipt from it on is taxed. Not read:
54
+ * the BMF-Schreiben of 18 March 2025 (UStAE Abschn. 19.1 ff.), which the BMF
55
+ * site did not serve.
41
56
  */
42
57
  import type { TCents } from '@fin.cx/calculation';
43
58
 
@@ -48,6 +63,8 @@ export const SMALL_BUSINESS_FIRST_YEAR = 2025;
48
63
  export const SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS: TCents = 2_500_000;
49
64
  /** 100 000 €: the running calendar year's limit (§ 19 Abs. 1 Satz 1 UStG) */
50
65
  export const SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS: TCents = 10_000_000;
66
+ /** 25 000 €: the running calendar year's limit in the year the business starts (BT-Drs. 20/12780, p. 183 f., zu § 19 Abs. 1 UStG) */
67
+ export const SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS: TCents = 2_500_000;
51
68
 
52
69
  /**
53
70
  * What a receipt is to the Gesamtumsatz (§ 19 Abs. 2 UStG):
@@ -83,7 +100,12 @@ export interface IGesamtumsatzOfYear {
83
100
  leftOutCents: Record<Exclude<TGesamtumsatzPart, 'counted'>, TCents>;
84
101
  }
85
102
 
86
- /** Why a year starts with the exemption or without it. */
103
+ /**
104
+ * Why a year starts with the exemption or without it. `within_limits` and
105
+ * `business_started_this_year` start it exempt: the one by the previous
106
+ * year's Gesamtumsatz, the other as the year the business starts, which has
107
+ * none (its running limit is 25 000 €).
108
+ */
87
109
  export type TSmallBusinessReason =
88
110
  | 'within_limits'
89
111
  | 'previous_year_over'
@@ -114,9 +136,17 @@ export interface ISmallBusinessStatus {
114
136
  atStart: 'exempt' | 'taxable' | 'unknown';
115
137
  reason: TSmallBusinessReason;
116
138
  /**
117
- * Where the year starts exempt and its Gesamtumsatz exceeds 100 000 €: the
118
- * receipt by which it first does (its day, its place in the receipts as
119
- * given, the sum with it). It and every later receipt are taxed.
139
+ * Where the year starts exempt: the running year's Gesamtumsatz up to which
140
+ * it stays exempt, 100 000 € (`SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS`), or
141
+ * 25 000 € in the year the business starts
142
+ * (`SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS`)
143
+ */
144
+ runningLimitCents?: TCents;
145
+ /**
146
+ * Where the year starts exempt and its Gesamtumsatz exceeds
147
+ * `runningLimitCents`: the receipt by which it first does (its day, its
148
+ * place in the receipts as given, the sum with it). It and every later
149
+ * receipt are taxed.
120
150
  */
121
151
  endsWith?: { receivedOn: string; index: number; runningCents: TCents };
122
152
  /** the year's Gesamtumsatz over all its receipts */
@@ -173,7 +203,9 @@ export function gesamtumsatzOf(receiptsArg: readonly IGesamtumsatzReceipt[], yea
173
203
  * Whether a calendar year's supplies are exempt under § 19 Abs. 1 UStG: from
174
204
  * its start where the previous year's Gesamtumsatz did not exceed 25 000 € and
175
205
  * no waiver is in force, until the receipt by which the running year's
176
- * Gesamtumsatz exceeds 100 000 € (`endsWith`).
206
+ * Gesamtumsatz exceeds 100 000 € (`endsWith`). In the year the business
207
+ * starts (`previousYearCents: 'business_started'`) from its start, until the
208
+ * receipt by which it exceeds 25 000 €, counted as it is, not as a whole year.
177
209
  */
178
210
  export function smallBusinessStatusOf(inputArg: ISmallBusinessYearInput): ISmallBusinessStatus {
179
211
  assertYear(inputArg.year);
@@ -197,23 +229,23 @@ export function smallBusinessStatusOf(inputArg: ISmallBusinessYearInput): ISmall
197
229
  if (inputArg.waived === true) {
198
230
  return { ...base, atStart: 'taxable', reason: 'waived' };
199
231
  }
200
- if (previous === 'business_started') {
201
- return { ...base, atStart: 'unknown', reason: 'business_started_this_year' };
202
- }
203
232
  if (previous === undefined) {
204
233
  return { ...base, atStart: 'unknown', reason: 'previous_year_unknown' };
205
234
  }
206
- if (previous > SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS) {
235
+ if (previous !== 'business_started' && previous > SMALL_BUSINESS_PREVIOUS_YEAR_LIMIT_CENTS) {
207
236
  return { ...base, atStart: 'taxable', reason: 'previous_year_over' };
208
237
  }
238
+ const reason: TSmallBusinessReason = previous === 'business_started' ? 'business_started_this_year' : 'within_limits';
239
+ const runningLimitCents = previous === 'business_started' ? SMALL_BUSINESS_FOUNDING_YEAR_LIMIT_CENTS : SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS;
240
+ const exempt = { ...base, atStart: 'exempt' as const, reason, runningLimitCents };
209
241
  let sum = 0;
210
242
  for (const { receipt, index } of counted) {
211
243
  sum += receipt.entgeltCents;
212
- if (sum > SMALL_BUSINESS_RUNNING_YEAR_LIMIT_CENTS) {
213
- return { ...base, atStart: 'exempt', reason: 'within_limits', endsWith: { receivedOn: receipt.receivedOn, index, runningCents: sum } };
244
+ if (sum > runningLimitCents) {
245
+ return { ...exempt, endsWith: { receivedOn: receipt.receivedOn, index, runningCents: sum } };
214
246
  }
215
247
  }
216
- return { ...base, atStart: 'exempt', reason: 'within_limits' };
248
+ return exempt;
217
249
  }
218
250
 
219
251
  /** The last calendar year a waiver effective for `yearArg` binds (§ 19 Abs. 3 Satz 3 UStG: at least five calendar years). */