lambda-erp 0.2.2__tar.gz → 0.2.3__tar.gz

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 (82) hide show
  1. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/PKG-INFO +4 -4
  2. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/README.md +3 -3
  3. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/chat.py +9 -5
  4. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/packs/__init__.py +4 -4
  5. lambda_erp-0.2.3/lambda_erp/accounting/setup/packs/de_common.py +67 -0
  6. lambda_erp-0.2.3/lambda_erp/accounting/setup/packs/de_skr03.py +222 -0
  7. lambda_erp-0.2.3/lambda_erp/accounting/setup/packs/de_skr04.py +220 -0
  8. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/pyproject.toml +1 -1
  9. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/.gitignore +0 -0
  10. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/LICENSE +0 -0
  11. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/__init__.py +0 -0
  12. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/attachments.py +0 -0
  13. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/auth.py +0 -0
  14. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/bootstrap.py +0 -0
  15. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/demo_limits.py +0 -0
  16. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/deps.py +0 -0
  17. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/errors.py +0 -0
  18. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/main.py +0 -0
  19. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/oauth.py +0 -0
  20. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/pdf.py +0 -0
  21. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/providers.py +0 -0
  22. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/remarks_md.py +0 -0
  23. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/__init__.py +0 -0
  24. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/accounting.py +0 -0
  25. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/admin.py +0 -0
  26. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/analytics.py +0 -0
  27. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/bank_reconciliation.py +0 -0
  28. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/chat_api.py +0 -0
  29. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/documents.py +0 -0
  30. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/masters.py +0 -0
  31. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/proposals.py +0 -0
  32. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/reports.py +0 -0
  33. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/routers/setup.py +0 -0
  34. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/services.py +0 -0
  35. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/templates/document.html +0 -0
  36. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/api/templates/proposal.html +0 -0
  37. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/docs/agents/README.md +0 -0
  38. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/frontend/README.md +0 -0
  39. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/frontend/src/api/client.ts +0 -0
  40. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/__init__.py +0 -0
  41. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/__init__.py +0 -0
  42. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/bank_transaction.py +0 -0
  43. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/budget.py +0 -0
  44. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/chart_of_accounts.py +0 -0
  45. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/general_ledger.py +0 -0
  46. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/journal_entry.py +0 -0
  47. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/payment_entry.py +0 -0
  48. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/pos_invoice.py +0 -0
  49. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/purchase_invoice.py +0 -0
  50. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/revaluation.py +0 -0
  51. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/sales_invoice.py +0 -0
  52. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/__init__.py +0 -0
  53. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/engine.py +0 -0
  54. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/pack.py +0 -0
  55. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/packs/ch.py +0 -0
  56. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/packs/generic.py +0 -0
  57. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/profiles.py +0 -0
  58. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/setup/spine.py +0 -0
  59. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/accounting/subscription.py +0 -0
  60. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/buying/__init__.py +0 -0
  61. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/buying/purchase_order.py +0 -0
  62. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/controllers/__init__.py +0 -0
  63. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/controllers/currency.py +0 -0
  64. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/controllers/defaults.py +0 -0
  65. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/controllers/pricing_rule.py +0 -0
  66. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/controllers/taxes_and_totals.py +0 -0
  67. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/database.py +0 -0
  68. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/exceptions.py +0 -0
  69. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/hooks.py +0 -0
  70. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/model.py +0 -0
  71. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/selling/__init__.py +0 -0
  72. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/selling/proposal.py +0 -0
  73. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/selling/quotation.py +0 -0
  74. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/selling/sales_order.py +0 -0
  75. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/simulation.py +0 -0
  76. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/stock/__init__.py +0 -0
  77. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/stock/delivery_note.py +0 -0
  78. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/stock/purchase_receipt.py +0 -0
  79. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/stock/stock_entry.py +0 -0
  80. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/stock/stock_ledger.py +0 -0
  81. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/lambda_erp/utils.py +0 -0
  82. {lambda_erp-0.2.2 → lambda_erp-0.2.3}/terraform/README.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lambda-erp
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Core ERP logic - accounting, sales, purchasing, inventory
5
5
  Author: TORUS INVESTMENTS AG
6
6
  License-Expression: MIT
@@ -141,7 +141,7 @@ Standing up a new company usually means an accountant hand-building a chart of a
141
141
 
142
142
  Two dimensions shape the chart, and they compose:
143
143
 
144
- - **Localization packs** bring a country's real chart and tax setup. Today: a **generic / international** chart (also the permanent fallback for anywhere not yet localized) and **Switzerland** — the *Kontenrahmen KMU*, in German, in CHF, with MWST tax templates at the current rates. Each country is a self-contained pack, so more can land without disturbing the ones already there — that's the roadmap, one jurisdiction at a time.
144
+ - **Localization packs** bring a country's real chart and tax setup. Today: a **generic / international** chart (also the permanent fallback for anywhere not yet localized); **Switzerland** — the *Kontenrahmen KMU*, in German, in CHF, with MWST tax templates at the current rates; and **Germany** — the DATEV standard in both common variants, **SKR03** and **SKR04**, in German, in EUR, with Umsatzsteuer/Vorsteuer templates at 19 % and 7 %. Where a country ships more than one standard chart (Germany's SKR03 vs SKR04), you pick the variant; a bare "Germany" defaults to the more widely used SKR03. Each country is a self-contained pack, so more can land without disturbing the ones already there — that's the roadmap, one jurisdiction at a time.
145
145
  - **Sector profiles** tailor the chart to how you operate — **services, retail / POS, hospitality, wholesale / distribution, import / export, manufacturing, construction** — adding the accounts that model actually needs (work-in-progress and retention for construction, food-vs-beverage cost lines for hospitality, landed-cost accounts for import/export, and so on). Profiles are country-independent: the same seven apply on top of every localization.
146
146
 
147
147
  The result is booked in one step — chart of accounts, sensible default accounts, tax templates, and a cost center — ready for opening balances. New here? The in-app **Tutorial** has a one-click **Get started** that opens the wizard in chat.
@@ -150,7 +150,7 @@ The result is booked in one step — chart of accounts, sensible default account
150
150
 
151
151
  ## What works today
152
152
 
153
- - **Guided company setup through chat** — pick a country (generic or Switzerland, more coming) and business type, preview the exact chart of accounts, confirm, and it's booked
153
+ - **Guided company setup through chat** — pick a country (generic, Switzerland, or Germany SKR03/SKR04, more coming) and business type, preview the exact chart of accounts, confirm, and it's booked
154
154
  - Full sales and purchase cycles (Quotation → Sales Order → Delivery Note → Sales Invoice → Payment Entry, and the buying equivalents)
155
155
  - Returns / credit notes / debit notes with proper GL and stock reversal
156
156
  - Moving-average stock ledger with negative-stock protection
@@ -190,7 +190,7 @@ Four things had to be true for this to work, and they all became true in the las
190
190
 
191
191
  Every company configuring an ERP runs into the same problems: local tax rules, common workflow patterns, industry-specific accounting quirks. Most of that knowledge isn't a competitive advantage — it's the same ground being re-covered separately at every implementation, by every team, in slightly different ways.
192
192
 
193
- We want Lambda ERP to be where that knowledge lives in public. The base system is MIT-licensed, and the repo has real seams for that knowledge to slot into: a new country's chart of accounts and tax rules is a self-contained **localization pack**, and an industry's way of operating is a **sector profile** — both live in `lambda_erp/accounting/setup/` and are documented for contributors in [`docs/agents/company_setup.md`](docs/agents/company_setup.md). A German VAT pack, a U.S. sales-tax-by-state module, a template for professional services — each is an additive contribution that every deployment picks up. The goal is a true community where running an ERP gets cheaper, faster, and more flexible for everyone, not just the implementer.
193
+ We want Lambda ERP to be where that knowledge lives in public. The base system is MIT-licensed, and the repo has real seams for that knowledge to slot into: a new country's chart of accounts and tax rules is a self-contained **localization pack**, and an industry's way of operating is a **sector profile** — both live in `lambda_erp/accounting/setup/` and are documented for contributors in [`docs/agents/company_setup.md`](docs/agents/company_setup.md). An Austrian or French chart, a U.S. sales-tax-by-state module, a template for professional services — each is an additive contribution that every deployment picks up (the Swiss KMU and German DATEV packs already in the tree are the worked examples). The goal is a true community where running an ERP gets cheaper, faster, and more flexible for everyone, not just the implementer.
194
194
 
195
195
  ---
196
196
 
@@ -114,7 +114,7 @@ Standing up a new company usually means an accountant hand-building a chart of a
114
114
 
115
115
  Two dimensions shape the chart, and they compose:
116
116
 
117
- - **Localization packs** bring a country's real chart and tax setup. Today: a **generic / international** chart (also the permanent fallback for anywhere not yet localized) and **Switzerland** — the *Kontenrahmen KMU*, in German, in CHF, with MWST tax templates at the current rates. Each country is a self-contained pack, so more can land without disturbing the ones already there — that's the roadmap, one jurisdiction at a time.
117
+ - **Localization packs** bring a country's real chart and tax setup. Today: a **generic / international** chart (also the permanent fallback for anywhere not yet localized); **Switzerland** — the *Kontenrahmen KMU*, in German, in CHF, with MWST tax templates at the current rates; and **Germany** — the DATEV standard in both common variants, **SKR03** and **SKR04**, in German, in EUR, with Umsatzsteuer/Vorsteuer templates at 19 % and 7 %. Where a country ships more than one standard chart (Germany's SKR03 vs SKR04), you pick the variant; a bare "Germany" defaults to the more widely used SKR03. Each country is a self-contained pack, so more can land without disturbing the ones already there — that's the roadmap, one jurisdiction at a time.
118
118
  - **Sector profiles** tailor the chart to how you operate — **services, retail / POS, hospitality, wholesale / distribution, import / export, manufacturing, construction** — adding the accounts that model actually needs (work-in-progress and retention for construction, food-vs-beverage cost lines for hospitality, landed-cost accounts for import/export, and so on). Profiles are country-independent: the same seven apply on top of every localization.
119
119
 
120
120
  The result is booked in one step — chart of accounts, sensible default accounts, tax templates, and a cost center — ready for opening balances. New here? The in-app **Tutorial** has a one-click **Get started** that opens the wizard in chat.
@@ -123,7 +123,7 @@ The result is booked in one step — chart of accounts, sensible default account
123
123
 
124
124
  ## What works today
125
125
 
126
- - **Guided company setup through chat** — pick a country (generic or Switzerland, more coming) and business type, preview the exact chart of accounts, confirm, and it's booked
126
+ - **Guided company setup through chat** — pick a country (generic, Switzerland, or Germany SKR03/SKR04, more coming) and business type, preview the exact chart of accounts, confirm, and it's booked
127
127
  - Full sales and purchase cycles (Quotation → Sales Order → Delivery Note → Sales Invoice → Payment Entry, and the buying equivalents)
128
128
  - Returns / credit notes / debit notes with proper GL and stock reversal
129
129
  - Moving-average stock ledger with negative-stock protection
@@ -163,7 +163,7 @@ Four things had to be true for this to work, and they all became true in the las
163
163
 
164
164
  Every company configuring an ERP runs into the same problems: local tax rules, common workflow patterns, industry-specific accounting quirks. Most of that knowledge isn't a competitive advantage — it's the same ground being re-covered separately at every implementation, by every team, in slightly different ways.
165
165
 
166
- We want Lambda ERP to be where that knowledge lives in public. The base system is MIT-licensed, and the repo has real seams for that knowledge to slot into: a new country's chart of accounts and tax rules is a self-contained **localization pack**, and an industry's way of operating is a **sector profile** — both live in `lambda_erp/accounting/setup/` and are documented for contributors in [`docs/agents/company_setup.md`](docs/agents/company_setup.md). A German VAT pack, a U.S. sales-tax-by-state module, a template for professional services — each is an additive contribution that every deployment picks up. The goal is a true community where running an ERP gets cheaper, faster, and more flexible for everyone, not just the implementer.
166
+ We want Lambda ERP to be where that knowledge lives in public. The base system is MIT-licensed, and the repo has real seams for that knowledge to slot into: a new country's chart of accounts and tax rules is a self-contained **localization pack**, and an industry's way of operating is a **sector profile** — both live in `lambda_erp/accounting/setup/` and are documented for contributors in [`docs/agents/company_setup.md`](docs/agents/company_setup.md). An Austrian or French chart, a U.S. sales-tax-by-state module, a template for professional services — each is an additive contribution that every deployment picks up (the Swiss KMU and German DATEV packs already in the tree are the worked examples). The goal is a true community where running an ERP gets cheaper, faster, and more flexible for everyone, not just the implementer.
167
167
 
168
168
  ---
169
169
 
@@ -1089,10 +1089,14 @@ TOOLS = [
1089
1089
  "`sector` is one of: services, retail_pos, hospitality, distribution, "
1090
1090
  "import_export, manufacturing, construction. If you're unsure which fits, "
1091
1091
  "ASK the user about their business rather than guessing. `country` selects "
1092
- "the jurisdiction chart. Available: 'generic' (international, USD) and 'CH' "
1092
+ "the jurisdiction chart. Available: 'generic' (international, USD); 'CH' "
1093
1093
  "(Switzerland — Kontenrahmen KMU, German account names, CHF, with MWST tax "
1094
- "templates). Any other country falls back to the generic chart tell the "
1095
- "user when `jurisdiction.is_fallback` is true."
1094
+ "templates); and 'DE' (Germany DATEV chart, German account names, EUR, with "
1095
+ "Umsatzsteuer/Vorsteuer tax templates at 19 %/7 %). Germany has two chart "
1096
+ "`variant`s: 'skr03' (process-ordered, the most common — the default for a bare "
1097
+ "'DE') and 'skr04' (balance-sheet-ordered, DATEV's recommendation for newly "
1098
+ "founded companies); ask which they use if it matters. Any other country falls "
1099
+ "back to the generic chart — tell the user when `jurisdiction.is_fallback` is true."
1096
1100
  ),
1097
1101
  "parameters": {
1098
1102
  "type": "object",
@@ -1104,8 +1108,8 @@ TOOLS = [
1104
1108
  "import_export", "manufacturing", "construction"],
1105
1109
  "description": "Operating-mode profile. Omit if the business is generic/unknown.",
1106
1110
  },
1107
- "country": {"type": "string", "description": "Jurisdiction code, e.g. 'CH'. Defaults to generic."},
1108
- "variant": {"type": "string", "description": "Sub-chart variant, e.g. 'skr03' (rarely needed)."},
1111
+ "country": {"type": "string", "description": "Jurisdiction code, e.g. 'CH' or 'DE'. Defaults to generic."},
1112
+ "variant": {"type": "string", "description": "Sub-chart variant. For 'DE': 'skr03' (default) or 'skr04'. Omit otherwise."},
1109
1113
  "currency": {"type": "string", "description": "Base currency, e.g. 'USD', 'CHF'. Defaults to the pack currency."},
1110
1114
  },
1111
1115
  "required": ["name"],
@@ -6,11 +6,11 @@ imported. Adding a jurisdiction = drop a module here and import it below.
6
6
 
7
7
  generic the jurisdiction-neutral / international pack (and fallback)
8
8
  ch Switzerland (Kontenrahmen KMU)
9
- # de Germany (SKR03/04) later
9
+ de.skr03 Germany, DATEV SKR03 (process-ordered) default for a bare `de`
10
+ de.skr04 Germany, DATEV SKR04 (balance-sheet-ordered)
10
11
  """
11
12
 
12
13
  from lambda_erp.accounting.setup.packs import generic # noqa: F401
13
14
  from lambda_erp.accounting.setup.packs import ch # noqa: F401
14
-
15
- # Future packs register on import add them here, e.g.:
16
- # from lambda_erp.accounting.setup.packs import de_skr03 # noqa: F401
15
+ from lambda_erp.accounting.setup.packs import de_skr03 # noqa: F401
16
+ from lambda_erp.accounting.setup.packs import de_skr04 # noqa: F401
@@ -0,0 +1,67 @@
1
+ """Shared German (DATEV) helpers for the SKR03 / SKR04 packs.
2
+
3
+ The two German charts differ only in their *numbering scheme* — SKR03 is
4
+ process-ordered (Prozessgliederung), SKR04 balance-sheet-ordered
5
+ (Abschlussgliederung) — but the tax mechanics are identical: the same German
6
+ VAT (Umsatzsteuer / Vorsteuer) at the same two federal rates. Rather than copy
7
+ the ~30-line tax-template builder into both variant modules, the shared factory
8
+ lives here and each variant passes in its own tax-account leaf names.
9
+
10
+ German VAT rates (federal, unchanged since 2007; the 2020 COVID cut reverted
11
+ 2021-01-01):
12
+ * **19 %** Regelsteuersatz (standard rate)
13
+ * **7 %** ermäßigter Steuersatz (reduced rate — food, books, transit, …)
14
+
15
+ Output tax = *Umsatzsteuer* (a liability), input tax = *Vorsteuer* (recoverable).
16
+ """
17
+
18
+ from lambda_erp.utils import _dict
19
+ from lambda_erp.database import get_db
20
+ from lambda_erp.accounting.chart_of_accounts import account_abbr
21
+
22
+ # The two federal rates, shared by both charts.
23
+ STANDARD_RATE = 19.0
24
+ REDUCED_RATE = 7.0
25
+
26
+
27
+ def make_de_setup_tax(sales_taxes, purchase_taxes):
28
+ """Build a pack ``setup_tax(company, currency)`` hook for a German chart.
29
+
30
+ ``sales_taxes`` / ``purchase_taxes`` are lists of ``(title, rate,
31
+ account_leaf)`` where ``account_leaf`` is the tax account's name *within this
32
+ variant's chart* (the ``- <abbr>`` company suffix is appended here). Mirrors
33
+ ``ch.ch_setup_tax``: idempotent, does not commit (the engine owns the
34
+ transaction), returns a short human summary.
35
+ """
36
+
37
+ def de_setup_tax(company_name, currency):
38
+ db = get_db()
39
+ abbr = account_abbr(company_name)
40
+ summary = []
41
+
42
+ def _template(title, tax_type, rate, account_leaf):
43
+ name = f"{title} - {abbr}"
44
+ if db.exists("Tax Template", name):
45
+ return # idempotent: leave an existing template
46
+ db.insert("Tax Template", _dict(
47
+ name=name, title=title, company=company_name, tax_type=tax_type,
48
+ ))
49
+ db.insert("Tax Template Detail", _dict(
50
+ name=f"{name}-1",
51
+ parent=name,
52
+ charge_type="On Net Total",
53
+ account_head=f"{account_leaf} - {abbr}",
54
+ rate=rate,
55
+ description=title,
56
+ idx=1,
57
+ ))
58
+ summary.append(f"{tax_type}: {title} @ {rate}%")
59
+
60
+ for title, rate, leaf in sales_taxes:
61
+ _template(title, "Sales", rate, leaf)
62
+ for title, rate, leaf in purchase_taxes:
63
+ _template(title, "Purchase", rate, leaf)
64
+
65
+ return summary
66
+
67
+ return de_setup_tax
@@ -0,0 +1,222 @@
1
+ """Germany — SKR03 localization pack (DATEV Prozessgliederungsprinzip).
2
+
3
+ Hand-authored from the published **DATEV SKR03** standard chart — the
4
+ process-ordered Kontenrahmen (class 0 fixed assets & capital, class 1 finance,
5
+ class 3 goods inward, class 4 operating expense, class 8 revenue). SKR03 remains
6
+ the most widely used chart among German SMEs, so it is the default a bare
7
+ ``resolve_pack("de")`` lands on; its sibling ``de_skr04`` carries the *same*
8
+ accounts under the newer balance-sheet-ordered numbering.
9
+
10
+ Account numbers and their German titles are a German functional standard, not
11
+ anyone's copyrightable arrangement, so this is authored from the standard —
12
+ cross-checked against the LGPL Odoo ``l10n_de`` template data — rather than
13
+ copied from a packaged file, the same stance as the generic and Swiss packs.
14
+
15
+ A curated ~60-account core proportionate to the Swiss pack (not the full
16
+ ~1,270-account SKR03). Two German specifics:
17
+ * **EUR** base currency, German account titles carrying their SKR03 number.
18
+ * **Umsatzsteuer / Vorsteuer** — the shared ``make_de_setup_tax`` hook builds
19
+ Sales/Purchase tax templates at the two federal rates (19 % Regelsteuersatz,
20
+ 7 % ermäßigt) against the SKR03 USt / Vorsteuer accounts.
21
+
22
+ Note the process ordering: several accounts sit in a DATEV class whose leading
23
+ digit does not match their balance-sheet section (e.g. ``3980 Waren (Bestand)``
24
+ is an *asset* though it is numbered in the class-3 goods band, and ``1600
25
+ Verbindlichkeiten aLuL`` is a *liability* though numbered in the class-1 finance
26
+ band). The tree is organised by ``root_type`` — the number is only a label.
27
+ """
28
+
29
+ from lambda_erp.accounting.setup import spine
30
+ from lambda_erp.accounting.setup.pack import LocalizationPack, register_pack
31
+ from lambda_erp.accounting.setup.packs.de_common import (
32
+ make_de_setup_tax, STANDARD_RATE, REDUCED_RATE,
33
+ )
34
+
35
+
36
+ # ---------------------------------------------------------------------------
37
+ # Base chart — SKR03 (curated core). Numbers live in the account name (the
38
+ # Account doctype is name-keyed, no separate code column). root_type /
39
+ # report_type inherit from the parent; set on the five roots. Organised by
40
+ # balance-sheet section (root_type), NOT by the leading SKR03 digit.
41
+ # ---------------------------------------------------------------------------
42
+ DE_SKR03_CHART = {
43
+ "0-1 Aktiva": {
44
+ "root_type": "Asset",
45
+ "report_type": "Balance Sheet",
46
+ "children": {
47
+ "0 Anlagevermögen": {
48
+ "children": {
49
+ "0200 Technische Anlagen und Maschinen": {"account_type": "Fixed Asset"},
50
+ "0300 Andere Anlagen, Betriebs- und Geschäftsausstattung": {"account_type": "Fixed Asset"},
51
+ "0320 Pkw": {"account_type": "Fixed Asset"},
52
+ "0350 Lkw": {"account_type": "Fixed Asset"},
53
+ "0400 Betriebsausstattung": {"account_type": "Fixed Asset"},
54
+ "0420 Büroeinrichtung": {"account_type": "Fixed Asset"},
55
+ "0250 Wertberichtigungen zu Sachanlagen": {"account_type": "Accumulated Depreciation"},
56
+ },
57
+ },
58
+ "1 Finanz- und Umlaufvermögen": {
59
+ "children": {
60
+ "1000 Kasse": {"account_type": "Cash"},
61
+ "1200 Bank": {"account_type": "Bank"},
62
+ "1400 Forderungen aus Lieferungen und Leistungen": {"account_type": "Receivable"},
63
+ "1460 Geldtransit": {"account_type": ""},
64
+ "1571 Abziehbare Vorsteuer 7 %": {"account_type": ""},
65
+ "1576 Abziehbare Vorsteuer 19 %": {"account_type": ""},
66
+ "0980 Aktive Rechnungsabgrenzung": {"account_type": ""},
67
+ "3980 Waren (Bestand)": {"account_type": "Stock"},
68
+ "7000 Unfertige Erzeugnisse (Bestand)": {"account_type": "Stock"},
69
+ },
70
+ },
71
+ },
72
+ },
73
+ "08 Eigenkapital": {
74
+ "root_type": "Equity",
75
+ "report_type": "Balance Sheet",
76
+ "children": {
77
+ "0800 Gezeichnetes Kapital / Eigenkapital": {"account_type": ""},
78
+ "0840 Kapitalrücklage": {"account_type": ""},
79
+ "0860 Gewinnvortrag vor Verwendung": {"account_type": ""},
80
+ "0868 Verlustvortrag vor Verwendung": {"account_type": ""},
81
+ "9000 Saldenvorträge, Sachkonten (Eröffnungsbilanz)": {"account_type": ""},
82
+ },
83
+ },
84
+ "16-17 Verbindlichkeiten": {
85
+ "root_type": "Liability",
86
+ "report_type": "Balance Sheet",
87
+ "children": {
88
+ "16 Kurzfristige Verbindlichkeiten": {
89
+ "children": {
90
+ "1600 Verbindlichkeiten aus Lieferungen und Leistungen": {"account_type": "Payable"},
91
+ "1608 Wareneingänge ohne Rechnung": {"account_type": "Stock Received But Not Billed"},
92
+ "1740 Verbindlichkeiten aus Lohn und Gehalt": {"account_type": ""},
93
+ "1742 Verbindlichkeiten im Rahmen der sozialen Sicherheit": {"account_type": ""},
94
+ "1771 Umsatzsteuer 7 %": {"account_type": "Tax"},
95
+ "1776 Umsatzsteuer 19 %": {"account_type": "Tax"},
96
+ "0990 Passive Rechnungsabgrenzung": {"account_type": ""},
97
+ },
98
+ },
99
+ "17 Langfristige Verbindlichkeiten": {
100
+ "children": {
101
+ "0630 Verbindlichkeiten gegenüber Kreditinstituten": {"account_type": ""},
102
+ "0700 Verbindlichkeiten aus Darlehen": {"account_type": ""},
103
+ },
104
+ },
105
+ },
106
+ },
107
+ "8 Umsatzerlöse und betriebliche Erträge": {
108
+ "root_type": "Income",
109
+ "report_type": "Profit and Loss",
110
+ "children": {
111
+ "8200 Erlöse": {"account_type": "Income Account"},
112
+ "8300 Erlöse 7 % USt": {"account_type": "Income Account"},
113
+ "8400 Erlöse 19 % USt": {"account_type": "Income Account"},
114
+ "8700 Erlösschmälerungen (Skonti, Rabatte)": {"account_type": ""},
115
+ "2700 Sonstige betriebliche Erträge": {"account_type": ""},
116
+ "2660 Erträge aus Währungsumrechnung": {"account_type": ""},
117
+ },
118
+ },
119
+ "2-4 Aufwendungen": {
120
+ "root_type": "Expense",
121
+ "report_type": "Profit and Loss",
122
+ "children": {
123
+ "3 Wareneingang und Materialaufwand": {
124
+ "children": {
125
+ "3200 Wareneingang": {"account_type": "Cost of Goods Sold"},
126
+ "3300 Wareneingang 7 % Vorsteuer": {"account_type": "Cost of Goods Sold"},
127
+ "3400 Wareneingang 19 % Vorsteuer": {"account_type": "Cost of Goods Sold"},
128
+ "3030 Einkauf Roh-, Hilfs- und Betriebsstoffe": {"account_type": "Cost of Goods Sold"},
129
+ "3800 Bezugsnebenkosten": {"account_type": "Chargeable"},
130
+ "3830 Zölle und Einfuhrabgaben": {"account_type": "Chargeable"},
131
+ "3960 Bestandsveränderungen": {"account_type": "Stock Adjustment"},
132
+ },
133
+ },
134
+ "4 Betriebliche Aufwendungen": {
135
+ "children": {
136
+ "4100 Löhne und Gehälter": {"account_type": ""},
137
+ "4130 Gesetzliche soziale Aufwendungen": {"account_type": ""},
138
+ "4200 Raumkosten": {"account_type": ""},
139
+ "4210 Miete (unbewegliche Wirtschaftsgüter)": {"account_type": ""},
140
+ "4360 Versicherungen": {"account_type": ""},
141
+ "4500 Fahrzeugkosten": {"account_type": ""},
142
+ "4600 Werbekosten": {"account_type": ""},
143
+ "4660 Reisekosten": {"account_type": ""},
144
+ "4910 Porto, Telefon und Bürobedarf": {"account_type": ""},
145
+ "4830 Abschreibungen auf Sachanlagen": {"account_type": "Depreciation"},
146
+ "4840 Kursdifferenzen (Währungsumrechnung)": {"account_type": ""},
147
+ "4845 Kursdifferenzen (nicht realisiert)": {"account_type": ""},
148
+ "4970 Rundungsdifferenzen": {"account_type": "Round Off"},
149
+ },
150
+ },
151
+ "2 Neutrale Aufwendungen": {
152
+ "children": {
153
+ "2100 Zinsen und ähnliche Aufwendungen": {"account_type": ""},
154
+ "2280 Steuern vom Einkommen und Ertrag": {"account_type": ""},
155
+ },
156
+ },
157
+ },
158
+ },
159
+ }
160
+
161
+
162
+ DE_SKR03_ANCHORS = {
163
+ spine.CURRENT_ASSETS: "1 Finanz- und Umlaufvermögen",
164
+ spine.FIXED_ASSETS: "0 Anlagevermögen",
165
+ spine.CURRENT_LIABILITIES: "16 Kurzfristige Verbindlichkeiten",
166
+ spine.EQUITY: "08 Eigenkapital",
167
+ spine.INCOME: "8 Umsatzerlöse und betriebliche Erträge",
168
+ spine.DIRECT_COSTS: "3 Wareneingang und Materialaufwand",
169
+ spine.OPERATING_EXPENSES: "4 Betriebliche Aufwendungen",
170
+ }
171
+
172
+
173
+ # Every default the posting engine references must resolve to an SKR03 leaf, or
174
+ # postings that fall back to it will fail. Keys mirror STANDARD_DEFAULTS.
175
+ DE_SKR03_DEFAULTS = {
176
+ "default_receivable_account": "1400 Forderungen aus Lieferungen und Leistungen",
177
+ "default_payable_account": "1600 Verbindlichkeiten aus Lieferungen und Leistungen",
178
+ "default_income_account": "8400 Erlöse 19 % USt",
179
+ "default_expense_account": "3400 Wareneingang 19 % Vorsteuer",
180
+ "round_off_account": "4970 Rundungsdifferenzen",
181
+ "stock_in_hand_account": "3980 Waren (Bestand)",
182
+ "stock_received_but_not_billed": "1608 Wareneingänge ohne Rechnung",
183
+ "stock_adjustment_account": "3960 Bestandsveränderungen",
184
+ "default_opening_balance_equity": "9000 Saldenvorträge, Sachkonten (Eröffnungsbilanz)",
185
+ "default_freight_in_account": "3800 Bezugsnebenkosten",
186
+ "default_customs_account": "3830 Zölle und Einfuhrabgaben",
187
+ "default_exchange_gain_loss_account": "4840 Kursdifferenzen (Währungsumrechnung)",
188
+ "default_unrealized_exchange_account": "4845 Kursdifferenzen (nicht realisiert)",
189
+ }
190
+
191
+
192
+ # German VAT wiring — (title, rate, account_leaf). Output tax = Umsatzsteuer
193
+ # (liability), input tax = Vorsteuer (recoverable asset).
194
+ _SALES_TAXES = [
195
+ ("Umsatzsteuer 19 % (Regelsteuersatz)", STANDARD_RATE, "1776 Umsatzsteuer 19 %"),
196
+ ("Umsatzsteuer 7 % (ermäßigt)", REDUCED_RATE, "1771 Umsatzsteuer 7 %"),
197
+ ]
198
+ _PURCHASE_TAXES = [
199
+ ("Vorsteuer 19 %", STANDARD_RATE, "1576 Abziehbare Vorsteuer 19 %"),
200
+ ("Vorsteuer 7 %", REDUCED_RATE, "1571 Abziehbare Vorsteuer 7 %"),
201
+ ]
202
+
203
+ de_skr03_setup_tax = make_de_setup_tax(_SALES_TAXES, _PURCHASE_TAXES)
204
+
205
+
206
+ DE_SKR03_PACK = register_pack(LocalizationPack(
207
+ country="de",
208
+ variant="skr03",
209
+ label="Germany (DATEV SKR03)",
210
+ currency="EUR",
211
+ language="de",
212
+ base_chart=DE_SKR03_CHART,
213
+ anchors=DE_SKR03_ANCHORS,
214
+ defaults=DE_SKR03_DEFAULTS,
215
+ setup_tax=de_skr03_setup_tax,
216
+ notes=(
217
+ "German SME chart, DATEV SKR03 (process-ordered), German titles with "
218
+ "SKR03 numbers, EUR. Umsatzsteuer/Vorsteuer templates at 19 / 7 %. "
219
+ "Hand-authored from the published standard, cross-checked against Odoo "
220
+ "l10n_de. The most widely used German chart — the default for a bare `de`."
221
+ ),
222
+ ))
@@ -0,0 +1,220 @@
1
+ """Germany — SKR04 localization pack (DATEV Abschlussgliederungsprinzip).
2
+
3
+ Hand-authored from the published **DATEV SKR04** standard chart — the
4
+ balance-sheet-ordered Kontenrahmen (class 0 Anlagevermögen … class 7 further
5
+ income/expense), which is DATEV's recommendation for newly founded companies.
6
+ Account numbers and their German titles are a German functional standard, not
7
+ anyone's copyrightable arrangement, so this is authored from the standard —
8
+ cross-checked against the LGPL Odoo ``l10n_de`` template data — rather than
9
+ copied from a packaged file, the same stance as the generic and Swiss packs.
10
+
11
+ A curated ~60-account core proportionate to the Swiss pack (not the full
12
+ ~1,200-account SKR04); extend as needed. Two German specifics:
13
+ * **EUR** base currency, German account titles carrying their SKR04 number.
14
+ * **Umsatzsteuer / Vorsteuer** — the shared ``make_de_setup_tax`` hook builds
15
+ Sales/Purchase tax templates at the two federal rates (19 % Regelsteuersatz,
16
+ 7 % ermäßigt) against the SKR04 USt / Vorsteuer accounts.
17
+
18
+ Its sibling ``de_skr03`` carries the *same* accounts under the process-ordered
19
+ numbering; both register ``country="de"`` variants, so ``resolve_pack("de")``
20
+ falls back to the alphabetically-first variant (SKR03) when the caller does not
21
+ name one — SKR03 is still the most widely used chart among German SMEs.
22
+ """
23
+
24
+ from lambda_erp.accounting.setup import spine
25
+ from lambda_erp.accounting.setup.pack import LocalizationPack, register_pack
26
+ from lambda_erp.accounting.setup.packs.de_common import (
27
+ make_de_setup_tax, STANDARD_RATE, REDUCED_RATE,
28
+ )
29
+
30
+
31
+ # ---------------------------------------------------------------------------
32
+ # Base chart — SKR04 (curated core). Numbers live in the account name (the
33
+ # Account doctype is name-keyed, no separate code column). root_type /
34
+ # report_type inherit from the parent; set on the five roots. Group accounts
35
+ # (with children) carry no account_type; leaves carry the posting role.
36
+ # ---------------------------------------------------------------------------
37
+ DE_SKR04_CHART = {
38
+ "0-1 Aktiva": {
39
+ "root_type": "Asset",
40
+ "report_type": "Balance Sheet",
41
+ "children": {
42
+ "0 Anlagevermögen": {
43
+ "children": {
44
+ "0400 Technische Anlagen und Maschinen": {"account_type": "Fixed Asset"},
45
+ "0500 Andere Anlagen, Betriebs- und Geschäftsausstattung": {"account_type": "Fixed Asset"},
46
+ "0520 Pkw": {"account_type": "Fixed Asset"},
47
+ "0540 Lkw": {"account_type": "Fixed Asset"},
48
+ "0670 Betriebsausstattung": {"account_type": "Fixed Asset"},
49
+ "0690 Geschäftsausstattung": {"account_type": "Fixed Asset"},
50
+ "0810 Abschreibung auf Sachanlagen (Wertberichtigung)": {"account_type": "Accumulated Depreciation"},
51
+ },
52
+ },
53
+ "1 Umlaufvermögen": {
54
+ "children": {
55
+ "1000 Roh-, Hilfs- und Betriebsstoffe": {"account_type": "Stock"},
56
+ "1100 Fertige Erzeugnisse und Waren (Bestand)": {"account_type": "Stock"},
57
+ "1140 Waren (Bestand)": {"account_type": "Stock"},
58
+ "1200 Forderungen aus Lieferungen und Leistungen": {"account_type": "Receivable"},
59
+ "1210 Zweifelhafte Forderungen": {"account_type": ""},
60
+ "1401 Abziehbare Vorsteuer 7 %": {"account_type": ""},
61
+ "1406 Abziehbare Vorsteuer 19 %": {"account_type": ""},
62
+ "1460 Geldtransit": {"account_type": ""},
63
+ "1600 Kasse": {"account_type": "Cash"},
64
+ "1800 Bank": {"account_type": "Bank"},
65
+ "1900 Aktive Rechnungsabgrenzung": {"account_type": ""},
66
+ },
67
+ },
68
+ },
69
+ },
70
+ "2 Eigenkapital": {
71
+ "root_type": "Equity",
72
+ "report_type": "Balance Sheet",
73
+ "children": {
74
+ "2000 Festkapital / Gezeichnetes Kapital": {"account_type": ""},
75
+ "2100 Kapitalrücklage": {"account_type": ""},
76
+ "2970 Gewinnvortrag vor Verwendung": {"account_type": ""},
77
+ "2978 Verlustvortrag vor Verwendung": {"account_type": ""},
78
+ "9000 Saldenvorträge, Sachkonten (Eröffnungsbilanz)": {"account_type": ""},
79
+ },
80
+ },
81
+ "3 Fremdkapital": {
82
+ "root_type": "Liability",
83
+ "report_type": "Balance Sheet",
84
+ "children": {
85
+ "30 Kurzfristige Verbindlichkeiten": {
86
+ "children": {
87
+ "3300 Verbindlichkeiten aus Lieferungen und Leistungen": {"account_type": "Payable"},
88
+ "3395 Noch nicht abgerechnete Wareneingänge": {"account_type": "Stock Received But Not Billed"},
89
+ "3740 Verbindlichkeiten aus Lohn und Gehalt": {"account_type": ""},
90
+ "3790 Verbindlichkeiten im Rahmen der sozialen Sicherheit": {"account_type": ""},
91
+ "3801 Umsatzsteuer 7 %": {"account_type": "Tax"},
92
+ "3806 Umsatzsteuer 19 %": {"account_type": "Tax"},
93
+ "3900 Passive Rechnungsabgrenzung": {"account_type": ""},
94
+ },
95
+ },
96
+ "34 Langfristige Verbindlichkeiten": {
97
+ "children": {
98
+ "3150 Verbindlichkeiten gegenüber Kreditinstituten": {"account_type": ""},
99
+ "3170 Verbindlichkeiten aus Darlehen": {"account_type": ""},
100
+ },
101
+ },
102
+ },
103
+ },
104
+ "4 Umsatzerlöse und betriebliche Erträge": {
105
+ "root_type": "Income",
106
+ "report_type": "Profit and Loss",
107
+ "children": {
108
+ "4000 Umsatzerlöse": {"account_type": "Income Account"},
109
+ "4300 Erlöse 7 % USt": {"account_type": "Income Account"},
110
+ "4400 Erlöse 19 % USt": {"account_type": "Income Account"},
111
+ "4700 Erlösschmälerungen (Skonti, Rabatte)": {"account_type": ""},
112
+ "4830 Sonstige betriebliche Erträge": {"account_type": ""},
113
+ "4840 Erträge aus Währungsumrechnung": {"account_type": ""},
114
+ },
115
+ },
116
+ "5-7 Aufwendungen": {
117
+ "root_type": "Expense",
118
+ "report_type": "Profit and Loss",
119
+ "children": {
120
+ "5 Material- und Wareneinkauf": {
121
+ "children": {
122
+ "5000 Aufwendungen für Roh-, Hilfs- und Betriebsstoffe": {"account_type": "Cost of Goods Sold"},
123
+ "5200 Wareneingang": {"account_type": "Cost of Goods Sold"},
124
+ "5300 Wareneingang 7 % Vorsteuer": {"account_type": "Cost of Goods Sold"},
125
+ "5400 Wareneingang 19 % Vorsteuer": {"account_type": "Cost of Goods Sold"},
126
+ "5800 Bezugsnebenkosten": {"account_type": "Chargeable"},
127
+ "5820 Zölle und Einfuhrabgaben": {"account_type": "Chargeable"},
128
+ "5883 Bestandsveränderungen": {"account_type": "Stock Adjustment"},
129
+ },
130
+ },
131
+ "6 Sonstige betriebliche Aufwendungen": {
132
+ "children": {
133
+ "6000 Löhne und Gehälter": {"account_type": ""},
134
+ "6110 Gesetzliche soziale Aufwendungen": {"account_type": ""},
135
+ "6305 Raumkosten": {"account_type": ""},
136
+ "6310 Miete (unbewegliche Wirtschaftsgüter)": {"account_type": ""},
137
+ "6400 Versicherungen, Beiträge und Abgaben": {"account_type": ""},
138
+ "6500 Fahrzeugkosten": {"account_type": ""},
139
+ "6600 Werbekosten": {"account_type": ""},
140
+ "6650 Reisekosten": {"account_type": ""},
141
+ "6800 Porto, Telefon und Bürobedarf": {"account_type": ""},
142
+ "6220 Abschreibungen auf Sachanlagen": {"account_type": "Depreciation"},
143
+ "6880 Kursdifferenzen (Währungsumrechnung)": {"account_type": ""},
144
+ "6885 Kursdifferenzen (nicht realisiert)": {"account_type": ""},
145
+ "6969 Rundungsdifferenzen": {"account_type": "Round Off"},
146
+ },
147
+ },
148
+ "7 Weitere Aufwendungen": {
149
+ "children": {
150
+ "7300 Zinsen und ähnliche Aufwendungen": {"account_type": ""},
151
+ "7600 Steuern vom Einkommen und Ertrag": {"account_type": ""},
152
+ },
153
+ },
154
+ },
155
+ },
156
+ }
157
+
158
+
159
+ DE_SKR04_ANCHORS = {
160
+ spine.CURRENT_ASSETS: "1 Umlaufvermögen",
161
+ spine.FIXED_ASSETS: "0 Anlagevermögen",
162
+ spine.CURRENT_LIABILITIES: "30 Kurzfristige Verbindlichkeiten",
163
+ spine.EQUITY: "2 Eigenkapital",
164
+ spine.INCOME: "4 Umsatzerlöse und betriebliche Erträge",
165
+ spine.DIRECT_COSTS: "5 Material- und Wareneinkauf",
166
+ spine.OPERATING_EXPENSES: "6 Sonstige betriebliche Aufwendungen",
167
+ }
168
+
169
+
170
+ # Every default the posting engine references must resolve to an SKR04 leaf, or
171
+ # postings that fall back to it will fail. Keys mirror STANDARD_DEFAULTS.
172
+ DE_SKR04_DEFAULTS = {
173
+ "default_receivable_account": "1200 Forderungen aus Lieferungen und Leistungen",
174
+ "default_payable_account": "3300 Verbindlichkeiten aus Lieferungen und Leistungen",
175
+ "default_income_account": "4400 Erlöse 19 % USt",
176
+ "default_expense_account": "5400 Wareneingang 19 % Vorsteuer",
177
+ "round_off_account": "6969 Rundungsdifferenzen",
178
+ "stock_in_hand_account": "1140 Waren (Bestand)",
179
+ "stock_received_but_not_billed": "3395 Noch nicht abgerechnete Wareneingänge",
180
+ "stock_adjustment_account": "5883 Bestandsveränderungen",
181
+ "default_opening_balance_equity": "9000 Saldenvorträge, Sachkonten (Eröffnungsbilanz)",
182
+ "default_freight_in_account": "5800 Bezugsnebenkosten",
183
+ "default_customs_account": "5820 Zölle und Einfuhrabgaben",
184
+ "default_exchange_gain_loss_account": "6880 Kursdifferenzen (Währungsumrechnung)",
185
+ "default_unrealized_exchange_account": "6885 Kursdifferenzen (nicht realisiert)",
186
+ }
187
+
188
+
189
+ # German VAT wiring — (title, rate, account_leaf). Output tax = Umsatzsteuer
190
+ # (liability), input tax = Vorsteuer (recoverable asset).
191
+ _SALES_TAXES = [
192
+ ("Umsatzsteuer 19 % (Regelsteuersatz)", STANDARD_RATE, "3806 Umsatzsteuer 19 %"),
193
+ ("Umsatzsteuer 7 % (ermäßigt)", REDUCED_RATE, "3801 Umsatzsteuer 7 %"),
194
+ ]
195
+ _PURCHASE_TAXES = [
196
+ ("Vorsteuer 19 %", STANDARD_RATE, "1406 Abziehbare Vorsteuer 19 %"),
197
+ ("Vorsteuer 7 %", REDUCED_RATE, "1401 Abziehbare Vorsteuer 7 %"),
198
+ ]
199
+
200
+ de_skr04_setup_tax = make_de_setup_tax(_SALES_TAXES, _PURCHASE_TAXES)
201
+
202
+
203
+ DE_SKR04_PACK = register_pack(LocalizationPack(
204
+ country="de",
205
+ variant="skr04",
206
+ label="Germany (DATEV SKR04)",
207
+ currency="EUR",
208
+ language="de",
209
+ base_chart=DE_SKR04_CHART,
210
+ anchors=DE_SKR04_ANCHORS,
211
+ defaults=DE_SKR04_DEFAULTS,
212
+ setup_tax=de_skr04_setup_tax,
213
+ notes=(
214
+ "German SME chart, DATEV SKR04 (balance-sheet-ordered), German titles "
215
+ "with SKR04 numbers, EUR. Umsatzsteuer/Vorsteuer templates at 19 / 7 %. "
216
+ "Hand-authored from the published standard, cross-checked against Odoo "
217
+ "l10n_de. DATEV's recommendation for newly founded companies; the "
218
+ "process-ordered SKR03 sibling is the default for a bare `de`."
219
+ ),
220
+ ))
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lambda-erp"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "Core ERP logic - accounting, sales, purchasing, inventory"
5
5
  readme = "README.md"
6
6
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes