@fin.cx/skr 1.3.1 → 2.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 (90) hide show
  1. package/.smartconfig.json +33 -6
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/core/core.accountpolicy.d.ts +67 -0
  4. package/dist_ts/core/core.accountpolicy.js +91 -0
  5. package/dist_ts/core/core.bukeys.d.ts +38 -0
  6. package/dist_ts/core/core.bukeys.js +117 -0
  7. package/dist_ts/core/core.datev.captions.d.ts +7 -0
  8. package/dist_ts/core/core.datev.captions.js +134 -0
  9. package/dist_ts/core/core.datev.d.ts +47 -0
  10. package/dist_ts/core/core.datev.js +129 -0
  11. package/dist_ts/core/core.hash.d.ts +27 -0
  12. package/dist_ts/core/core.hash.js +72 -0
  13. package/dist_ts/core/core.plugins.d.ts +3 -0
  14. package/dist_ts/core/core.plugins.js +9 -0
  15. package/dist_ts/core/core.recipes.d.ts +118 -0
  16. package/dist_ts/core/core.recipes.js +504 -0
  17. package/dist_ts/core/core.taxscenario.d.ts +27 -0
  18. package/dist_ts/core/core.taxscenario.js +85 -0
  19. package/dist_ts/core/core.types.d.ts +48 -0
  20. package/dist_ts/core/core.types.js +2 -0
  21. package/dist_ts/core/core.validate.d.ts +17 -0
  22. package/dist_ts/core/core.validate.js +89 -0
  23. package/dist_ts/core/index.d.ts +15 -0
  24. package/dist_ts/core/index.js +16 -0
  25. package/dist_ts/index.d.ts +15 -0
  26. package/dist_ts/index.js +10 -1
  27. package/dist_ts/plugins.d.ts +2 -1
  28. package/dist_ts/plugins.js +4 -2
  29. package/dist_ts/skr.api.d.ts +91 -22
  30. package/dist_ts/skr.api.js +357 -42
  31. package/dist_ts/skr.balances.d.ts +28 -0
  32. package/dist_ts/skr.balances.js +96 -0
  33. package/dist_ts/skr.classes.journalentry.d.ts +19 -3
  34. package/dist_ts/skr.classes.journalentry.js +67 -4
  35. package/dist_ts/skr.classes.reports.js +49 -102
  36. package/dist_ts/skr.database.d.ts +2 -0
  37. package/dist_ts/skr.database.js +1 -1
  38. package/dist_ts/skr.errors.d.ts +18 -0
  39. package/dist_ts/skr.errors.js +34 -0
  40. package/dist_ts/skr.export.js +4 -7
  41. package/dist_ts/skr.invoice.booking.js +14 -28
  42. package/dist_ts/skr.migrate.d.ts +20 -0
  43. package/dist_ts/skr.migrate.js +223 -0
  44. package/dist_ts/skr.period.d.ts +47 -0
  45. package/dist_ts/skr.period.js +95 -0
  46. package/dist_ts/skr.posting.d.ts +74 -0
  47. package/dist_ts/skr.posting.js +209 -0
  48. package/dist_ts/skr.security.d.ts +6 -9
  49. package/dist_ts/skr.security.js +16 -89
  50. package/dist_ts/skr.sequence.d.ts +32 -0
  51. package/dist_ts/skr.sequence.js +51 -0
  52. package/dist_ts/skr.txview.d.ts +46 -0
  53. package/dist_ts/skr.txview.js +235 -0
  54. package/dist_ts/skr.types.d.ts +35 -1
  55. package/dist_ts/skr.verify.d.ts +13 -0
  56. package/dist_ts/skr.verify.js +84 -0
  57. package/package.json +5 -4
  58. package/readme.hints.md +37 -0
  59. package/readme.md +69 -1
  60. package/readme.plan.md +180 -243
  61. package/ts/00_commitinfo_data.ts +1 -1
  62. package/ts/core/core.accountpolicy.ts +154 -0
  63. package/ts/core/core.bukeys.ts +146 -0
  64. package/ts/core/core.datev.captions.ts +133 -0
  65. package/ts/core/core.datev.ts +174 -0
  66. package/ts/core/core.hash.ts +76 -0
  67. package/ts/core/core.plugins.ts +9 -0
  68. package/ts/core/core.recipes.ts +659 -0
  69. package/ts/core/core.taxscenario.ts +156 -0
  70. package/ts/core/core.types.ts +74 -0
  71. package/ts/core/core.validate.ts +119 -0
  72. package/ts/core/index.ts +15 -0
  73. package/ts/index.ts +31 -0
  74. package/ts/plugins.ts +4 -0
  75. package/ts/skr.api.ts +432 -46
  76. package/ts/skr.balances.ts +127 -0
  77. package/ts/skr.classes.journalentry.ts +54 -5
  78. package/ts/skr.classes.reports.ts +54 -126
  79. package/ts/skr.database.ts +3 -0
  80. package/ts/skr.errors.ts +44 -0
  81. package/ts/skr.export.ts +3 -6
  82. package/ts/skr.invoice.booking.ts +22 -34
  83. package/ts/skr.migrate.ts +268 -0
  84. package/ts/skr.period.ts +139 -0
  85. package/ts/skr.posting.ts +273 -0
  86. package/ts/skr.security.ts +18 -93
  87. package/ts/skr.sequence.ts +89 -0
  88. package/ts/skr.txview.ts +268 -0
  89. package/ts/skr.types.ts +37 -1
  90. package/ts/skr.verify.ts +99 -0
package/.smartconfig.json CHANGED
@@ -10,12 +10,39 @@
10
10
  "license": "MIT"
11
11
  },
12
12
  "release": {
13
- "registries": [
14
- "https://verdaccio.lossless.digital",
15
- "https://registry.npmjs.org"
16
- ],
17
- "accessLevel": "public"
18
- }
13
+ "confirmation": "prompt",
14
+ "preflight": {
15
+ "requireCleanTree": true,
16
+ "test": false,
17
+ "build": true
18
+ },
19
+ "targets": {
20
+ "git": {
21
+ "enabled": true,
22
+ "remote": "origin",
23
+ "pushBranch": true,
24
+ "pushTags": true
25
+ },
26
+ "npm": {
27
+ "enabled": true,
28
+ "registries": [
29
+ "https://verdaccio.lossless.digital",
30
+ "https://registry.npmjs.org"
31
+ ],
32
+ "accessLevel": "public",
33
+ "alreadyPublished": "success"
34
+ },
35
+ "docker": {
36
+ "enabled": false,
37
+ "engine": "tsdocker",
38
+ "patterns": []
39
+ }
40
+ }
41
+ },
42
+ "services": [
43
+ "mongodb",
44
+ "minio"
45
+ ]
19
46
  },
20
47
  "@ship.zone/szci": {
21
48
  "npmGlobalTools": []
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@fin.cx/skr',
6
- version: '1.3.1',
6
+ version: '2.0.0',
7
7
  description: 'SKR03 and SKR04 German accounting standards for double-entry bookkeeping'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxhQUFhO0lBQ25CLE9BQU8sRUFBRSxPQUFPO0lBQ2hCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Account policy: which accounts a booking recipe uses for a given SKR chart.
3
+ * Defaults reflect the DATEV standard charts; entries marked PROVISIONAL are
4
+ * pattern-derived and get verified against the full chart data in M-A
5
+ * (@fin.cx/chartdata). Everything is overridable per call.
6
+ */
7
+ import type { TSKRType } from './core.types.js';
8
+ export interface IAccountPolicy {
9
+ skrType: TSKRType;
10
+ bank: string;
11
+ cash: string;
12
+ /** Sammelkonten — direct postings are blocked; use personal accounts. */
13
+ debtorsControl: string;
14
+ creditorsControl: string;
15
+ /** Suspense for unclear payments (Durchlaufende Posten). */
16
+ clearing: string;
17
+ /** Interim account for bank-to-bank transfers. */
18
+ geldtransit: string;
19
+ vat: {
20
+ outputStandard: string;
21
+ outputReduced: string;
22
+ inputStandard: string;
23
+ inputReduced: string;
24
+ intraEuAcqInput: string;
25
+ intraEuAcqOutput: string;
26
+ reverseChargeInput: string;
27
+ reverseChargeOutput: string;
28
+ };
29
+ revenue: {
30
+ domesticStandard: string;
31
+ domesticReduced: string;
32
+ intraEuSupply: string;
33
+ export: string;
34
+ reverseCharge: string;
35
+ };
36
+ expenseDefault: string;
37
+ skonto: {
38
+ /** erhaltene Skonti (purchases) — Automatikkonten with VSt correction */
39
+ receivedStandard: string;
40
+ receivedReduced: string;
41
+ /** gewährte Skonti (sales) — Automatikkonten with USt correction */
42
+ grantedStandard: string;
43
+ grantedReduced: string;
44
+ };
45
+ fx: {
46
+ gain: string;
47
+ loss: string;
48
+ };
49
+ /** Small payment-difference write-offs (PROVISIONAL: generic sonstige Erträge/Aufwendungen). */
50
+ roundingDiff: {
51
+ gain: string;
52
+ loss: string;
53
+ };
54
+ debtorRange: [number, number];
55
+ creditorRange: [number, number];
56
+ /**
57
+ * Accounts with built-in DATEV tax automatism. Lines on these accounts must
58
+ * carry no BU key ('' — automatism applies) or key 40 (automatism cancelled).
59
+ */
60
+ automatikkonten: string[];
61
+ }
62
+ export declare const SKR03_DEFAULT_POLICY: IAccountPolicy;
63
+ export declare const SKR04_DEFAULT_POLICY: IAccountPolicy;
64
+ export declare function getDefaultPolicy(skrType: TSKRType): IAccountPolicy;
65
+ export declare function isAutomatikAccount(policy: IAccountPolicy, accountNumber: string): boolean;
66
+ export declare function isDebtorAccount(policy: IAccountPolicy, accountNumber: string): boolean;
67
+ export declare function isCreditorAccount(policy: IAccountPolicy, accountNumber: string): boolean;
@@ -0,0 +1,91 @@
1
+ export const SKR03_DEFAULT_POLICY = {
2
+ skrType: 'SKR03',
3
+ bank: '1200',
4
+ cash: '1000',
5
+ debtorsControl: '1400',
6
+ creditorsControl: '1600',
7
+ clearing: '1590',
8
+ geldtransit: '1360',
9
+ vat: {
10
+ outputStandard: '1776',
11
+ outputReduced: '1771',
12
+ inputStandard: '1576',
13
+ inputReduced: '1571',
14
+ intraEuAcqInput: '1574',
15
+ intraEuAcqOutput: '1784',
16
+ reverseChargeInput: '1577',
17
+ reverseChargeOutput: '1787',
18
+ },
19
+ revenue: {
20
+ domesticStandard: '8400',
21
+ domesticReduced: '8300',
22
+ intraEuSupply: '8125',
23
+ export: '8120',
24
+ reverseCharge: '8337',
25
+ },
26
+ expenseDefault: '4980',
27
+ skonto: {
28
+ receivedStandard: '3736',
29
+ receivedReduced: '3731', // PROVISIONAL
30
+ grantedStandard: '8736',
31
+ grantedReduced: '8731', // PROVISIONAL
32
+ },
33
+ fx: { gain: '2660', loss: '2150' },
34
+ roundingDiff: { gain: '2700', loss: '2300' }, // PROVISIONAL
35
+ debtorRange: [10000, 69999],
36
+ creditorRange: [70000, 99999],
37
+ automatikkonten: ['8400', '8300', '8125', '8120', '3400', '3300', '3736', '3731', '8736', '8731'],
38
+ };
39
+ export const SKR04_DEFAULT_POLICY = {
40
+ skrType: 'SKR04',
41
+ bank: '1800',
42
+ cash: '1600',
43
+ debtorsControl: '1200',
44
+ creditorsControl: '3300',
45
+ clearing: '3290',
46
+ geldtransit: '1460',
47
+ vat: {
48
+ outputStandard: '3806',
49
+ outputReduced: '3801',
50
+ inputStandard: '1406',
51
+ inputReduced: '1401',
52
+ intraEuAcqInput: '1404',
53
+ intraEuAcqOutput: '3804',
54
+ reverseChargeInput: '1407',
55
+ reverseChargeOutput: '3837',
56
+ },
57
+ revenue: {
58
+ domesticStandard: '4400',
59
+ domesticReduced: '4300',
60
+ intraEuSupply: '4125',
61
+ export: '4120',
62
+ reverseCharge: '4337',
63
+ },
64
+ expenseDefault: '6980',
65
+ skonto: {
66
+ receivedStandard: '5736',
67
+ receivedReduced: '5731', // PROVISIONAL
68
+ grantedStandard: '4736',
69
+ grantedReduced: '4731', // PROVISIONAL
70
+ },
71
+ fx: { gain: '4840', loss: '6880' },
72
+ roundingDiff: { gain: '4830', loss: '6300' }, // PROVISIONAL
73
+ debtorRange: [10000, 69999],
74
+ creditorRange: [70000, 99999],
75
+ automatikkonten: ['4400', '4300', '4125', '4120', '5400', '5300', '5736', '5731', '4736', '4731'],
76
+ };
77
+ export function getDefaultPolicy(skrType) {
78
+ return skrType === 'SKR03' ? SKR03_DEFAULT_POLICY : SKR04_DEFAULT_POLICY;
79
+ }
80
+ export function isAutomatikAccount(policy, accountNumber) {
81
+ return policy.automatikkonten.includes(accountNumber);
82
+ }
83
+ export function isDebtorAccount(policy, accountNumber) {
84
+ const parsed = Number.parseInt(accountNumber, 10);
85
+ return Number.isInteger(parsed) && parsed >= policy.debtorRange[0] && parsed <= policy.debtorRange[1];
86
+ }
87
+ export function isCreditorAccount(policy, accountNumber) {
88
+ const parsed = Number.parseInt(accountNumber, 10);
89
+ return (Number.isInteger(parsed) && parsed >= policy.creditorRange[0] && parsed <= policy.creditorRange[1]);
90
+ }
91
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5hY2NvdW50cG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvY29yZS9jb3JlLmFjY291bnRwb2xpY3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBeURBLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFtQjtJQUNsRCxPQUFPLEVBQUUsT0FBTztJQUNoQixJQUFJLEVBQUUsTUFBTTtJQUNaLElBQUksRUFBRSxNQUFNO0lBQ1osY0FBYyxFQUFFLE1BQU07SUFDdEIsZ0JBQWdCLEVBQUUsTUFBTTtJQUN4QixRQUFRLEVBQUUsTUFBTTtJQUNoQixXQUFXLEVBQUUsTUFBTTtJQUNuQixHQUFHLEVBQUU7UUFDSCxjQUFjLEVBQUUsTUFBTTtRQUN0QixhQUFhLEVBQUUsTUFBTTtRQUNyQixhQUFhLEVBQUUsTUFBTTtRQUNyQixZQUFZLEVBQUUsTUFBTTtRQUNwQixlQUFlLEVBQUUsTUFBTTtRQUN2QixnQkFBZ0IsRUFBRSxNQUFNO1FBQ3hCLGtCQUFrQixFQUFFLE1BQU07UUFDMUIsbUJBQW1CLEVBQUUsTUFBTTtLQUM1QjtJQUNELE9BQU8sRUFBRTtRQUNQLGdCQUFnQixFQUFFLE1BQU07UUFDeEIsZUFBZSxFQUFFLE1BQU07UUFDdkIsYUFBYSxFQUFFLE1BQU07UUFDckIsTUFBTSxFQUFFLE1BQU07UUFDZCxhQUFhLEVBQUUsTUFBTTtLQUN0QjtJQUNELGNBQWMsRUFBRSxNQUFNO0lBQ3RCLE1BQU0sRUFBRTtRQUNOLGdCQUFnQixFQUFFLE1BQU07UUFDeEIsZUFBZSxFQUFFLE1BQU0sRUFBRSxjQUFjO1FBQ3ZDLGVBQWUsRUFBRSxNQUFNO1FBQ3ZCLGNBQWMsRUFBRSxNQUFNLEVBQUUsY0FBYztLQUN2QztJQUNELEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRTtJQUNsQyxZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEVB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
@@ -0,0 +1,38 @@
1
+ /**
2
+ * DATEV BU-Schlüssel (Steuerschlüssel) — single source of truth.
3
+ *
4
+ * Provenance (2026-07-09): cross-checked against multiple independent German
5
+ * bookkeeping sources. Key semantics that v1 (skr.postingkeys.ts) and the
6
+ * finance.plus reference implementation got wrong are corrected here:
7
+ * - 18/19 are steuerpflichtiger innergemeinschaftlicher Erwerb (§1a UStG)
8
+ * at 7%/19% — NOT generic "Vorsteuer ig Lieferungen".
9
+ * - 91/94 are Leistungsempfänger schuldet die Steuer (§13b UStG) at 7%/19%.
10
+ * The official DATEV Steuerschlüssel-Tabelle (Hilfe-Center Dokument 0904313)
11
+ * is portal-gated; verification against it plus one manual DATEV import per
12
+ * release candidate is the final gate (see readme.plan.md, M0 Phase 0).
13
+ */
14
+ import type { TBuKey, TTaxScenario } from './core.types.js';
15
+ export interface IBuKeyRule {
16
+ key: TBuKey;
17
+ description: string;
18
+ taxType: 'none' | 'ust' | 'vst' | 'vst_ust' | 'automatik_aufhebung';
19
+ ratePercent: number | null;
20
+ scenarios: TTaxScenario[];
21
+ }
22
+ export declare const BU_KEY_RULES: Record<Exclude<TBuKey, ''>, IBuKeyRule>;
23
+ export declare function isKnownBuKey(value: string): value is TBuKey;
24
+ export declare function getBuKeyRule(key: TBuKey): IBuKeyRule | null;
25
+ /**
26
+ * Suggest the BU key for the expense/revenue line of a booking.
27
+ *
28
+ * targetIsAutomatik: Automatikkonten compute tax themselves on DATEV import.
29
+ * When the entry carries explicit VAT lines, the automatism must be cancelled
30
+ * with key 40; a plain automatik line without explicit VAT gets no key.
31
+ */
32
+ export declare function suggestBuKey(params: {
33
+ direction: 'inbound' | 'outbound';
34
+ scenario: TTaxScenario;
35
+ ratePercent: number;
36
+ targetIsAutomatik: boolean;
37
+ hasExplicitVatLines: boolean;
38
+ }): TBuKey;
@@ -0,0 +1,117 @@
1
+ export const BU_KEY_RULES = {
2
+ '1': {
3
+ key: '1',
4
+ description: 'Umsatzsteuerfrei (§4 UStG)',
5
+ taxType: 'ust',
6
+ ratePercent: 0,
7
+ scenarios: ['domestic_tax_free', 'intra_eu_supply', 'export_third_country'],
8
+ },
9
+ '2': {
10
+ key: '2',
11
+ description: 'Umsatzsteuer 7 %',
12
+ taxType: 'ust',
13
+ ratePercent: 7,
14
+ scenarios: ['domestic_reduced'],
15
+ },
16
+ '3': {
17
+ key: '3',
18
+ description: 'Umsatzsteuer 19 %',
19
+ taxType: 'ust',
20
+ ratePercent: 19,
21
+ scenarios: ['domestic_standard'],
22
+ },
23
+ '8': {
24
+ key: '8',
25
+ description: 'Vorsteuer 7 %',
26
+ taxType: 'vst',
27
+ ratePercent: 7,
28
+ scenarios: ['domestic_reduced'],
29
+ },
30
+ '9': {
31
+ key: '9',
32
+ description: 'Vorsteuer 19 %',
33
+ taxType: 'vst',
34
+ ratePercent: 19,
35
+ scenarios: ['domestic_standard'],
36
+ },
37
+ '18': {
38
+ key: '18',
39
+ description: 'Steuerpflichtiger innergemeinschaftlicher Erwerb 7 % (§1a UStG)',
40
+ taxType: 'vst_ust',
41
+ ratePercent: 7,
42
+ scenarios: ['intra_eu_acquisition'],
43
+ },
44
+ '19': {
45
+ key: '19',
46
+ description: 'Steuerpflichtiger innergemeinschaftlicher Erwerb 19 % (§1a UStG)',
47
+ taxType: 'vst_ust',
48
+ ratePercent: 19,
49
+ scenarios: ['intra_eu_acquisition'],
50
+ },
51
+ '40': {
52
+ key: '40',
53
+ description: 'Aufhebung der Automatik',
54
+ taxType: 'automatik_aufhebung',
55
+ ratePercent: null,
56
+ scenarios: [
57
+ 'domestic_standard',
58
+ 'domestic_reduced',
59
+ 'domestic_tax_free',
60
+ 'intra_eu_supply',
61
+ 'intra_eu_acquisition',
62
+ 'reverse_charge_13b',
63
+ 'export_third_country',
64
+ ],
65
+ },
66
+ '91': {
67
+ key: '91',
68
+ description: 'Leistungsempfänger schuldet die Steuer 7 % (§13b UStG)',
69
+ taxType: 'vst_ust',
70
+ ratePercent: 7,
71
+ scenarios: ['reverse_charge_13b'],
72
+ },
73
+ '94': {
74
+ key: '94',
75
+ description: 'Leistungsempfänger schuldet die Steuer 19 % (§13b UStG)',
76
+ taxType: 'vst_ust',
77
+ ratePercent: 19,
78
+ scenarios: ['reverse_charge_13b'],
79
+ },
80
+ };
81
+ export function isKnownBuKey(value) {
82
+ return value === '' || Object.prototype.hasOwnProperty.call(BU_KEY_RULES, value);
83
+ }
84
+ export function getBuKeyRule(key) {
85
+ if (key === '')
86
+ return null;
87
+ return BU_KEY_RULES[key];
88
+ }
89
+ /**
90
+ * Suggest the BU key for the expense/revenue line of a booking.
91
+ *
92
+ * targetIsAutomatik: Automatikkonten compute tax themselves on DATEV import.
93
+ * When the entry carries explicit VAT lines, the automatism must be cancelled
94
+ * with key 40; a plain automatik line without explicit VAT gets no key.
95
+ */
96
+ export function suggestBuKey(params) {
97
+ if (params.targetIsAutomatik) {
98
+ return params.hasExplicitVatLines ? '40' : '';
99
+ }
100
+ const reduced = params.ratePercent === 7;
101
+ switch (params.scenario) {
102
+ case 'domestic_standard':
103
+ case 'domestic_reduced':
104
+ if (params.direction === 'inbound')
105
+ return reduced ? '8' : '9';
106
+ return reduced ? '2' : '3';
107
+ case 'intra_eu_acquisition':
108
+ return reduced ? '18' : '19';
109
+ case 'reverse_charge_13b':
110
+ return params.direction === 'inbound' ? (reduced ? '91' : '94') : '1';
111
+ case 'domestic_tax_free':
112
+ case 'intra_eu_supply':
113
+ case 'export_third_country':
114
+ return params.direction === 'outbound' ? '1' : '';
115
+ }
116
+ }
117
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5idWtleXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jb3JlL2NvcmUuYnVrZXlzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVCQSxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQTRDO0lBQ25FLEdBQUcsRUFBRTtRQUNILEdBQUcsRUFBRSxHQUFHO1FBQ1IsV0FBVyxFQUFFLDRCQUE0QjtRQUN6QyxPQUFPLEVBQUUsS0FBSztRQUNkLFdBQVcsRUFBRSxDQUFDO1FBQ2QsU0FBUyxFQUFFLENBQUMsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLENBQUM7S0FDNUU7SUFDRCxHQUFHLEVBQUU7UUFDSCxHQUFHLEVBQUUsR0FBRztRQUNSLFdBQVcsRUFBRSxrQkFBa0I7UUFDL0IsT0FBTyxFQUFFLEtBQUs7UUFDZCxXQUFXLEVBQUUsQ0FBQztRQUNkLFNBQVMsRUFBRSxDQUFDLGtCQUFrQixDQUFDO0tBQ2hDO0lBQ0QsR0FBRyxFQUFFO1FBQ0gsR0FBRyxFQUFFLEdBQUc7UUFDUixXQUFXLEVBQUUsbUJBQW1CO1FBQ2hDLE9BQU8sRUFBRSxLQUFLO1FBQ2QsV0FBVyxFQUFFLEVBQUU7UUFDZixTQUFTLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztLQUNqQztJQUNELEdBQUcsRUFBRTtRQUNILEdBQUcsRUFBRSxHQUFHO1FBQ1IsV0FBVyxFQUFFLGVBQWU7UUFDNUIsT0FBTyxFQUFFLEtBQUs7UUFDZCxXQUFXLEVBQUUsQ0FBQztRQUNkLFNBQVMsRUFBRSxDQUFDLGtCQUFrQixDQUFDO0tBQ2hDO0lBQ0QsR0FBRyxFQUFFO1FBQ0gsR0FBRyxFQUFFLEdBQUc7UUFDUixXQUFXLEVBQUUsZ0JBQWdCO1FBQzdCLE9BQU8sRUFBRSxLQUFLO1FBQ2QsV0FBVyxFQUFFLEVBQUU7UUFDZixTQUFTLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztLQUNqQztJQUNELElBQUksRUFBRTtRQUNKLEdBQUcsRUFBRSxJQUFJO1FBQ1QsV0FBVyxF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
@@ -0,0 +1,7 @@
1
+ /**
2
+ * DATEV Buchungsstapel (EXTF 700, Formatversion 13) column captions — 125 fields.
3
+ * Extracted 1:1 from a DATEV-importable reference file; do not edit by hand.
4
+ * Field 114 (index 113) is Festschreibung. The physical file must be written
5
+ * as CP1252 with CRLF line endings (IO-layer concern, not core's).
6
+ */
7
+ export declare const DATEV_COLUMN_CAPTIONS: string[];
@@ -0,0 +1,134 @@
1
+ /**
2
+ * DATEV Buchungsstapel (EXTF 700, Formatversion 13) column captions — 125 fields.
3
+ * Extracted 1:1 from a DATEV-importable reference file; do not edit by hand.
4
+ * Field 114 (index 113) is Festschreibung. The physical file must be written
5
+ * as CP1252 with CRLF line endings (IO-layer concern, not core's).
6
+ */
7
+ export const DATEV_COLUMN_CAPTIONS = [
8
+ "Umsatz (ohne Soll/Haben-Kz)",
9
+ "Soll/Haben-Kennzeichen",
10
+ "WKZ Umsatz",
11
+ "Kurs",
12
+ "Basisumsatz",
13
+ "WKZ Basisumsatz",
14
+ "Konto",
15
+ "Gegenkonto (ohne BU-Schlüssel)",
16
+ "BU-Schlüssel",
17
+ "Belegdatum",
18
+ "Belegfeld 1",
19
+ "Belegfeld 2",
20
+ "Skonto",
21
+ "Buchungstext",
22
+ "Postensperre",
23
+ "Diverse Adressnummer",
24
+ "Geschäftspartnerbank",
25
+ "Sachverhalt",
26
+ "Zinssperre",
27
+ "Beleglink",
28
+ "Beleginfo – Art 1",
29
+ "Beleginfo – Inhalt 1",
30
+ "Beleginfo – Art 2",
31
+ "Beleginfo – Inhalt 2",
32
+ "Beleginfo – Art 3",
33
+ "Beleginfo – Inhalt 3",
34
+ "Beleginfo – Art 4",
35
+ "Beleginfo – Inhalt 4",
36
+ "Beleginfo – Art 5",
37
+ "Beleginfo – Inhalt 5",
38
+ "Beleginfo – Art 6",
39
+ "Beleginfo – Inhalt 6",
40
+ "Beleginfo – Art 7",
41
+ "Beleginfo – Inhalt 7",
42
+ "Beleginfo – Art 8",
43
+ "Beleginfo – Inhalt 8",
44
+ "KOST1 – Kostenstelle",
45
+ "KOST2 – Kostenstelle",
46
+ "Kost Menge",
47
+ "EU-Land u. USt-IdNr.",
48
+ "EU-Steuersatz",
49
+ "Abw. Versteuerungsart",
50
+ "Sachverhalt L+L",
51
+ "Funktionsergänzung L+L",
52
+ "BU 49 Hauptfunktionstyp",
53
+ "BU 49 Hauptfunktionsnummer",
54
+ "BU 49 Funktionsergänzung",
55
+ "Zusatzinformation – Art 1",
56
+ "Zusatzinformation – Inhalt 1",
57
+ "Zusatzinformation – Art 2",
58
+ "Zusatzinformation – Inhalt 2",
59
+ "Zusatzinformation – Art 3",
60
+ "Zusatzinformation – Inhalt 3",
61
+ "Zusatzinformation – Art 4",
62
+ "Zusatzinformation – Inhalt 4",
63
+ "Zusatzinformation – Art 5",
64
+ "Zusatzinformation – Inhalt 5",
65
+ "Zusatzinformation – Art 6",
66
+ "Zusatzinformation – Inhalt 6",
67
+ "Zusatzinformation – Art 7",
68
+ "Zusatzinformation – Inhalt 7",
69
+ "Zusatzinformation – Art 8",
70
+ "Zusatzinformation – Inhalt 8",
71
+ "Zusatzinformation – Art 9",
72
+ "Zusatzinformation – Inhalt 9",
73
+ "Zusatzinformation – Art 10",
74
+ "Zusatzinformation – Inhalt 10",
75
+ "Zusatzinformation – Art 11",
76
+ "Zusatzinformation – Inhalt 11",
77
+ "Zusatzinformation – Art 12",
78
+ "Zusatzinformation – Inhalt 12",
79
+ "Zusatzinformation – Art 13",
80
+ "Zusatzinformation – Inhalt 13",
81
+ "Zusatzinformation – Art 14",
82
+ "Zusatzinformation – Inhalt 14",
83
+ "Zusatzinformation – Art 15",
84
+ "Zusatzinformation – Inhalt 15",
85
+ "Zusatzinformation – Art 16",
86
+ "Zusatzinformation – Inhalt 16",
87
+ "Zusatzinformation – Art 17",
88
+ "Zusatzinformation – Inhalt 17",
89
+ "Zusatzinformation – Art 18",
90
+ "Zusatzinformation – Inhalt 18",
91
+ "Zusatzinformation – Art 19",
92
+ "Zusatzinformation – Inhalt 19",
93
+ "Zusatzinformation – Art 20",
94
+ "Zusatzinformation – Inhalt 20",
95
+ "Stück",
96
+ "Gewicht",
97
+ "Zahlweise",
98
+ "Forderungsart",
99
+ "Veranlagungsjahr",
100
+ "Zugeordnete Fälligkeit",
101
+ "Skontotyp",
102
+ "Auftragsnummer",
103
+ "Buchungstyp",
104
+ "USt-Schlüssel (Anzahlungen)",
105
+ "EU-Mitgliedstaat (Anzahlungen)",
106
+ "Sachverhalt L+L (Anzahlungen)",
107
+ "EU-Steuersatz (Anzahlungen)",
108
+ "Erlöskonto (Anzahlungen)",
109
+ "Herkunft-Kz",
110
+ "Leerfeld",
111
+ "KOST-Datum",
112
+ "SEPA-Mandatsreferenz",
113
+ "Skontosperre",
114
+ "Gesellschaftername",
115
+ "Beteiligtennummer",
116
+ "Identifikationsnummer",
117
+ "Zeichnernummer",
118
+ "Postensperre bis",
119
+ "Bezeichnung",
120
+ "Kennzeichen",
121
+ "Festschreibung",
122
+ "Leistungsdatum",
123
+ "Datum Zuord.",
124
+ "Fälligkeit",
125
+ "Generalumkehr",
126
+ "Steuersatz",
127
+ "Land",
128
+ "Abrechnungsreferent",
129
+ "BVV-Position",
130
+ "EU-Mitgliedstaat u. UStID (Ursprung)",
131
+ "EU-Steuersatz (Ursprung)",
132
+ "Abw. Skontokonto",
133
+ ];
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5kYXRldi5jYXB0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NvcmUvY29yZS5kYXRldi5jYXB0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFhO0lBQzdDLDZCQUE2QjtJQUM3Qix3QkFBd0I7SUFDeEIsWUFBWTtJQUNaLE1BQU07SUFDTixhQUFhO0lBQ2IsaUJBQWlCO0lBQ2pCLE9BQU87SUFDUCxnQ0FBZ0M7SUFDaEMsY0FBYztJQUNkLFlBQVk7SUFDWixhQUFhO0lBQ2IsYUFBYTtJQUNiLFFBQVE7SUFDUixjQUFjO0lBQ2QsY0FBYztJQUNkLHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsYUFBYTtJQUNiLFlBQVk7SUFDWixXQUFXO0lBQ1gsbUJBQW1CO0lBQ25CLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsc0JBQXNCO0lBQ3RCLG1CQUFtQjtJQUNuQixzQkFBc0I7SUFDdEIsbUJBQW1CO0lBQ25CLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsc0JBQXNCO0lBQ3RCLG1CQUFtQjtJQUNuQixzQkFBc0I7SUFDdEIsbUJBQW1CO0lBQ25CLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsc0JBQXNCO0lBQ3RCLHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsWUFBWTtJQUNaLHNCQUFzQjtJQUN0QixlQUFlO0lBQ2YsdUJBQXVCO0lBQ3ZCLGlCQUFpQjtJQUNqQix3QkFBd0I7SUFDeEIseUJBQXlCO0lBQ3pCLDRCQUE0QjtJQUM1QiwwQkFBMEI7SUFDMUIsMkJBQTJCO0lBQzNCLDhCQUE4QjtJQUM5QiwyQkFBMkI7SUFDM0IsOEJBQThCO0lBQzlCLDJCQUEyQjtJQUMzQiw4QkFBOEI7SUFDOUIsMkJBQTJCO0lBQzNCLDhCQUE4QjtJQUM5QiwyQkFBMkI7SUFDM0IsOEJBQThCO0lBQzlCLDJCQUEyQjtJQUMzQiw4QkFBOEI7SUFDOUIsMkJBQTJCO0lBQzNCLDhCQUE4QjtJQUM5QiwyQkFBMkI7SUFDM0IsOEJBQThCO0lBQzlCLDJCQUEyQjtJQUMzQiw4QkFBOEI7SUFDOUIsNEJBQTRCO0lBQzVCLCtCQUErQjtJQUMvQiw0QkFBNEI7SUFDNUIsK0JBQStCO0lBQy9CLDRCQUE0QjtJQUM1QiwrQkFBK0I7SUFDL0IsNEJBQTRCO0lBQzVCLCtCQUErQjtJQUMvQiw0QkFBNEI7SUFDNUIsK0JBQStCO0lBQy9CLDRCQUE0QjtJQUM1QiwrQkFBK0I7SUFDL0IsNEJBQTRCO0lBQzVCLCtCQUErQjtJQUMvQiw0QkFBNEI7SUFDNUIsK0JBQStCO0lBQy9CLDRCQUE0QjtJQUM1QiwrQkFBK0I7SUFDL0IsNEJBQTRCO0lBQzVCLCtCQUErQjtJQUMvQiw0QkFBNEI7SUFDNUIsK0JBQStCO0lBQy9CLE9BQU87SUFDUCxTQUFTO0lBQ1QsV0FBVztJQUNYLGVBQWU7SUFDZixrQkFBa0I7SUFDbEIsd0JBQXdCO0lBQ3hCLFdBQVc7SUFDWCxnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLDZCQUE2QjtJQUM3QixnQ0FBZ0M7SUFDaEMsK0JBQStCO0lBQy9CLDZCQUE2QjtJQUM3QiwwQkFBMEI7SUFDMUIsYUFBYTtJQUNiLFVBQVU7SUFDVixZQUFZO0lBQ1osc0JBQXNCO0lBQ3RCLGNBQWM7SUFDZCxvQkFBb0I7SUFDcEIsbUJBQW1CO0lBQ25CLHVCQUF1QjtJQUN2QixnQkFBZ0I7SUFDaEIsa0JBQWtCO0lBQ2xCLGFBQWE7SUFDYixhQUFhO0lBQ2IsZ0JBQWdCO0lBQ2hCLGdCQUFnQjtJQUNoQixjQUFjO0lBQ2QsWUFBWTtJQUNaLGVBQWU7SUFDZixZQUFZO0lBQ1osTUFBTTtJQUNOLHFCQUFxQjtJQUNyQixjQUFjO0lBQ2Qsc0NBQXNDO0lBQ3RDLDBCQUEwQjtJQUMxQixrQkFBa0I7Q0FDbkIsQ0FBQyJ9
@@ -0,0 +1,47 @@
1
+ import type { IJournalDraft, TBuKey, TCents } from './core.types.js';
2
+ export declare const DATEV_COLUMN_COUNT = 125;
3
+ export declare const DATEV_HEADER_FIELD_COUNT = 31;
4
+ export interface IDatevBuchungsstapelRow {
5
+ umsatzCents: TCents;
6
+ sollHaben: 'S' | 'H';
7
+ konto: string;
8
+ gegenKonto: string;
9
+ buSchluessel: TBuKey;
10
+ belegDatum: Date;
11
+ belegfeld1?: string;
12
+ belegfeld2?: string;
13
+ buchungstext: string;
14
+ belegLink?: string;
15
+ kost1?: string;
16
+ kost2?: string;
17
+ festschreibung?: boolean;
18
+ }
19
+ export interface IDatevExtfHeaderOptions {
20
+ /** deterministic input — core never reads the clock */
21
+ createdAt: Date;
22
+ consultantNumber: number;
23
+ clientNumber: number;
24
+ fiscalYearStart: Date;
25
+ dateFrom: Date;
26
+ dateTo: Date;
27
+ label: string;
28
+ festschreibung: boolean;
29
+ accountLength?: number;
30
+ /** 2-char producer id in the header */
31
+ origin?: string;
32
+ exportedBy?: string;
33
+ }
34
+ /**
35
+ * Flatten journal drafts into DATEV rows — one row per line, with the line's
36
+ * explicit counterAccount as Gegenkonto (no pair reconstruction).
37
+ */
38
+ export declare function journalDraftsToDatevRows(drafts: IJournalDraft[], options?: {
39
+ festschreibung?: boolean;
40
+ }): IDatevBuchungsstapelRow[];
41
+ /**
42
+ * Produce the complete EXTF file content (header, caption row, data rows).
43
+ */
44
+ export declare function writeExtfBuchungsstapel(rows: IDatevBuchungsstapelRow[], header: IDatevExtfHeaderOptions): {
45
+ csv: string;
46
+ filename: string;
47
+ };