From 529ac30cdbd501eaa1661d2c08da16d8d358dc8a Mon Sep 17 00:00:00 2001 From: fegger Date: Sat, 12 Sep 2026 12:59:00 +0200 Subject: [PATCH] [IMP] odoo-at-payroll: GP6-Bau, KFS/BW-6-Abgleich und Odoo-19-Mechanik-Funde dokumentiert CHANGELOG-GP6-Eintrag; Plan-Abschnitt-10-Update (Buchungsmatrix nach KFS/BW 6, Nutzer-Klaerungen 5.1-5.3 inkl. aufgeklaerter Vertauschung Loehne/Gehaelter, Option-A-minimal-Split, NET-Umbenennung mit Default-Regel-Kopie-Fund); MEMORY-Handoff (88/88 auf Wegwerf-DB, GP7 als naechster Bauabschnitt, offene Referenzbuchhaltungs-Reste, Odoo-19-Mechanik-Funde: function-Record-ID-Semantik, Journal-Default-Constraint, Scaffold-Konto-Falle). --- .agents/MEMORY.md | 124 ++++++++++++++++-- docs/CHANGELOG.md | 56 ++++++++ .../IMPLEMENTIERUNGSPLAN-Privat.md | 38 ++++++ 3 files changed, 209 insertions(+), 9 deletions(-) diff --git a/.agents/MEMORY.md b/.agents/MEMORY.md index fb297c6..9310f12 100644 --- a/.agents/MEMORY.md +++ b/.agents/MEMORY.md @@ -2,9 +2,47 @@ ## Current focus -**GP5 Abfertigung Neu (BMSVG) umgesetzt und grün (84/84 Tests) — -nächster Bauabschnitt GP6 FI-Buchung UGB bzw. GP7 Meldewesen -(Priorität mit Nutzer klären)** (2026-09-11): Kern 19.0.3.1.0 +**GP6 FI-Buchung UGB umgesetzt und grün (88/88 Tests) — nächster +Bauabschnitt GP7 Meldewesen/Belege (Kern-Bau AP5/AP6)** (2026-09-12): +privat 19.0.6.0.0 — Buchungsmatrix nach **KFS/BW 6** (Nutzer- +Referenz-Exemplar `.additional_docs/KFSBW6_13072017_RF.pdf`, extrah. +`/tmp/kfsbw6/` ad hoc): Hook `_configure_payroll_account_at` +(`models/account_chart_private.py`; BE-Muster; Chart-Load-Pfad +`_post_load_data` + ``-Datendatei für Bestands-Companies — +der ERSTE `` einer function ist die Record-ID-Liste, +convert.py!) ordnet Regelkonten (Matrix als Python-Dict), Journal +SLR (Default 6200, BE-Muster — Odoo-Constraint verbietet +Receivable/Payable als Journal-Default!) und NET-Konto **3850** +(Nutzer 5.1; Anlage+reconcile, l10n_at-Chart hat es nicht). +**EKR-Debit-Split:** `l10n_at_personalgruppe` am Vertrag + +`l10n_at_account_debit_arbeiter` je Regel, Option A minimal (Nutzer +5.2: 6000/6500/6600/6601/6602; Rest Fallback auf Angestellten- +Konten bis Referenzbuchhaltungs-Fixierung); `_prepare_slip_lines`- +Gesamtüberschreibung `models/account_posting_private.py` (Odoo hat +keinen Override-Punkt; Upstream-Kopie Odoo-Pin mit 1 Substitution, +testgepinnt). Nutzer-Vertauschung aufgeklärt: „6000 Gehälter/6200 +Löhne“ → KFS/BW 6 sagt 600–619 Löhne, 620–639 Gehälten. **NET- +Umbenennung NETTO→NET** (Odoo filtert code 'NET' für Payment/ +net_wage/Negativ-Netto) + **Odoo-19-Fund:** Structure-Anlegen kopiert +die default_structure-Regeln (BASIC/GROSS/NET/…) via Feld-Default +in rule_ids — kopierte NET-Regel kollidiert im result_rules-Dict +(Netto=0); Fix: `` archiviert die Kopie (active=False; +KEIN Unlink — struct_id NOT NULL + historische Linien behalten +Regel-Ref; One2many blendet Archivierte aus). Konto-Suche exakt +vor Präfix-Fallback (Präfix max. +1 Stelle) — sonst matcht +'6000%' Odoo-Scaffold 600000 „Expenses“ chartloser Firmen! +BVG 6440 (EKR 644) vor 6400 (Odoo-Chart), Credit 3600 (Nutzer 5.3); +depends + l10n_at + hr_payroll_account_iso20022. Tests +`test_account_private` (4, Kontenplan-Mock ohne Chart-Install; +NET-Rundungscents = Odoo-„Adjustment Entry“ auf Journal-Default, +delta=0.02) + NETTO→NET in 4 Suiten — **88/88 grün** (frischer +`-i`-Lauf, Wegwerf-DB, aufgeräumt). Offen: Arbeiter-Sub-Konten-End- +codes mit Referenzbuchhaltung (GP0-Rest), Payment-/SEPA-Registrierung +nur strukturell getestet, `odoo_dev` Update nachholen (läuft auf +GP4-Stand). + +**GP5 Abfertigung Neu (BMSVG) umgesetzt und grün (84/84 Tests)** +(2026-09-11): Kern 19.0.3.1.0 (`at_sv_bv_dg` 1,53 % in `rule_parameters_sv_2026.xml`); privat 19.0.5.0.0 — Regel `BVG` (ATP_DG, ohne Nettoeffekt) auf **EIGENER ungecappter BV-Grundlage** (§ 6 Abs 5 iVm § 49 ASVG: kein HBG-/ @@ -154,6 +192,46 @@ B17-Inhalt/B18; Kleinverifikationen s. KB-KONFLIKTE „Nächste Schritte“). ## Completed +- **GP6 FI-Buchung UGB umgesetzt (88/88 grün)** (2026-09-12): + `l10n_at_hr_payroll_private` 19.0.6.0.0 — Buchungsmatrix KFS/BW 6: + `models/account_chart_private.py` (Matrix-Dict + Hook + `_configure_payroll_account_at`: exakte Konto-Suche mit + Längen-gebundenem Präfix-Fallback gegen Odoo-Scaffold-Konten + 600000 „Expenses“; NET-Konto 3850 Anlage+reconcile; Journal SLR + Default 6200 — Odoo-Constraint gegen Receivable/Payable als + Journal-Default) + `data/hr_payroll_account_private.xml` + (``-Trigger; erster value = Record-IDs) + + `models/account_posting_private.py` (`_prepare_slip_lines`- + Upstream-Kopie mit Arbeiter-Debit-Substitution) + + `l10n_at_personalgruppe` (hr.version) / + `l10n_at_account_debit_arbeiter` (hr.salary.rule). NETTO→NET + (`action_register_payment`/net_wage/Negativ-Netto filtern + code 'NET') + ``-Archivierung der automatisch + kopierten default_structure-NET-Regel (Kollision im + result_rules-Dict; active=False statt Unlink — struct_id NOT + NULL, historische Linien). Tests `test_account_private` (4: + Matrix+Move-Balance, Arbeiter-Split 6000/6500/660x, Gering- + führig, Fallback/Warnung) auf Kontenplan-Mock ohne Chart- + Install; NET-Rundungscents toleriert (Odoo bucht „Adjustment + Entry“ aufs Journal-Default). **88/88 grün** (frischer `-i`- + Lauf, Wegwerf-DB aufgeräumt); README/CHANGELOG/PLAN-10/MEMORY + nachgezogen; Rechenfälle `docs/rechenfaelle/buchhaltung.md`. + KFS/BW-6-Extraktion via opendataloader-pdf (Skill-Disziplin; + Output /tmp, unversioniert). + +- **Zed-Threads Auto-Sync Workstation↔Laptop installiert** (2026-09-12): + beide DBs jetzt 831/831 identisch; systemd-User-Timer `zed-threads-sync.timer` + (10 min) + `~/.local/bin/zed-threads-sync.sh` via ssh-Alias `framework` + (Seed-Push 117 WS-Threads, danach idempotente Delta-Zyklen, End-to-End- + Test inkl. Timer-Pfad grün). Details siehe Entscheidung „Zed-Threads + maschinenlokal“. + +- **Zed-Threads-DBs Workstation↔Laptop konsolidiert** (2026-09-12): 714 + Laptop-Threads in die WS-`threads.db` gemerged (117→831, 0 ID-Kollisionen, + Integrity ok; Laptop-Remote-Sessions schreiben clientseitig, WS-Zed war + geschlossen; Backup `/tmp/threads.db.workstation-backup`). Verfahren + + Finale-Sync siehe Entscheidung „Zed-Threads maschinenlokal“. + - **Skill `opendataloader-pdf` erstellt und in den Agent-Workflow integriert** (2026-09-12): Neues Skill `.agents/skills/opendataloader-pdf/` (SKILL.md + vendored `scripts/verify-json.py`, `scripts/hybrid-health.sh` aus dem @@ -1035,6 +1113,33 @@ B17-Inhalt/B18; Kleinverifikationen s. KB-KONFLIKTE „Nächste Schritte“). XML-Well-formedness-Check. - `.firecrawl/` bleibt lokal unversioniert (Rechts-Rohquellen); bei Fehlen neu beschaffen — niemals aus Trainingswerten arbeiten. +- **Zed-Threads maschinenlokal** (2026-09-12): Threads liegen je Maschine in + `~/.local/share/zed/threads/threads.db` (SQLite, journal=delete, + `data_type='zstd'`); Remote-Sessions (Laptop→WS) schreiben nur clientseitig + (verifiziert: Remote-Server hält DB nicht offen, laufender Laptop-Thread + fehlt in WS-DB); kein Zed-Sync, kein `threads_path`-Setting in Zed 1.20. + Laptop-Schema hat zusätzlich `worktree_branch` — Merge nutzt Spalten- + Schnittmenge, der Wert wird auf WS-Seite verworfen. Konsolidierung = + Stich-Sync, driftet sofort wieder. Merge Laptop→WS: scp der Laptop-DB → + `/tmp/laptop-threads.db`, Backup `cp -a` der WS-DB, dann + `sqlite3 ~/.local/share/zed/threads/threads.db "ATTACH '/tmp/laptop-threads.db' AS lp;" "INSERT OR REPLACE INTO main.threads (id, summary, updated_at, data_type, data, parent_id, folder_paths, folder_paths_order, created_at) SELECT l.id, l.summary, l.updated_at, l.data_type, l.data, l.parent_id, l.folder_paths, l.folder_paths_order, l.created_at FROM lp.threads l WHERE NOT EXISTS (SELECT 1 FROM main.threads t WHERE t.id = l.id AND t.updated_at > l.updated_at);" "DETACH lp;"` + — WS-Zeile bleibt, wenn strikt neuer. Rückübertrag zur Laptop-DB per scp + nur bei geschlossenem Laptop-Zed und vorherigem Re-Merge des finalen + Laptop-Stands (sonst Verlust der Session-Enden). Neue Threads erscheinen + im Agent-Panel erst nach Zed-Restart. + **Auto-Sync installiert** (2026-09-12, Workstation-koordiniert): systemd- + User-Timer `zed-threads-sync.timer` (10 min) → + `~/.local/bin/zed-threads-sync.sh` (ssh-Alias `framework`): Wasserzeichen- + Deltas je Richtung (1-h-Sicherheitsfenster), Guard `>=` (Zeile ersetzt nur + bei strikt neuerem `updated_at` — idempotent, schont Laptop- + `worktree_branch`), `busy_timeout=5000`, Integritätscheck je Delta, + State/Log `~/.local/state/zed-threads-sync/`. Wartungshinweis: + `strftime('%s', updated_at)` liefert TEXT — CAST AS INTEGER nötig, sonst + matcht der Delta-Filter alle Zeilen (in Zyklus 1 passiert, harmlos dank + Guard, behoben). Grenzen: Löschungen propagieren nicht, fremde Threads + erst nach Zed-Restart sichtbar, Sync läuft nur bei bestehender WS-User- + Session (Linger optional), Laptop offline = harmloser Skip. Die manuelle + Finale-Sync-Checkliste ist damit obsolet. ## Files that matter right now @@ -1099,12 +1204,13 @@ B17-Inhalt/B18; Kleinverifikationen s. KB-KONFLIKTE „Nächste Schritte“). unversioniert); Dev-DB `odoo_dev` (PostgreSQL lokal) - `addons/l10n_at_hr_payroll_private/` — General-AT (GP1 KV-Framework + Seed D2; GP2 Entgelt-Engine; GP3 LSt-Anbindung; GP4 SV/DB; - **GP5 Abfertigung Neu umgesetzt 2026-09-11** — `test_kv_katalog` 8 + - `test_entgelt_private` 21 + `test_lst_private` 6 + `test_sv_private` - 8 + `test_bv_private` 10 grün auf Wegwerf-DB `gp5_test` (**84/84**, - frischer `-i`-Lauf — `odoo_dev` noch auf GP4-Stand, Update - nachholen); Rechenfall-Fixtures unter `docs/rechenfaelle/` inkl. - abfertigung.md; GP6 FI-Buchung / GP7 Meldewesen als Nächstes) + GP5 Abfertigung Neu; **GP6 FI-Buchung UGB umgesetzt 2026-09-12** — + `test_kv_katalog` 8 + `test_entgelt_private` 21 + `test_lst_private` + 6 + `test_sv_private` 8 + `test_bv_private` 10 + `test_account_private` + 4 grün auf Wegwerf-DB (**88/88**, frischer `-i`-Lauf — `odoo_dev` + noch auf GP4-Stand, Update nachholen); Rechenfall-Fixtures unter + `docs/rechenfaelle/` inkl. buchhaltung.md (KFS/BW-6-Matrix); + GP7 Meldewesen/Belege als Nächstes) - `addons/l10n_at_hr_payroll/` — Bundes-Kern (SV/TASY + GP3 Lohnsteuer `models/lohnsteuer.py` + **GP4 SV/DB `models/sozialversicherung.py`** (DG/Geringfügigkeit/§ 49/Altersstichtage/§ 2a-Staffel/WF-Vektor/ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 111069d..dae786f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,61 @@ # CHANGELOG — odoo-at-payroll +## 2026-09-12 — General-AT GP6: FI-Buchung UGB nach KFS/BW 6 umgesetzt (M6) + +- `addons/l10n_at_hr_payroll_private` (19.0.6.0.0): **GP6 FI-Buchung + UGB** auf dem Österreichischen Einheitskontenrahmen (KFS/BW 6, + Nutzer-Referenz-Exemplar `.additional_docs/KFSBW6_13072017_RF.pdf`): + - `models/account_chart_private.py`: Buchungsmatrix + Hook + `_configure_payroll_account_at` (BE-Muster `l10n_be_hr_payroll_ + account`): Chart-Load (`_post_load_data`) **und** ``- + Datendatei für Bestands-Companies (erster `` = Record-IDs, + convert.py-Semantik), idempotent. Konto-Suche **exakt zuerst**, + Präfix-Fallback nur bis eine Stelle länger — blockiert Odoo- + Scaffold-Konten chartloser Firmen (6000 darf nicht 600000 + „Expenses" matchen). NET-Konto **3850 „Verbindlichkeiten aus + Lohn und Gehalt"** (Nutzer-Entscheidung 5.1) wird angelegt und + auf reconcile gesetzt (l10n_at-Standardchart hat es nicht); + Journal **SLR** mit Default = Gehälterkonto 6200 (BE-Muster; Odoo- + Constraint verbietet Receivable/Payable als Journal-Default). + - **EKR-Debit-Split Arbeiter/Angestellte** (Nutzer-Klärung: 600–619 + Löhne, 620–639 Gehälter — die Angabe „6000 Gehälter/6200 Löhne" + war gegenüber der eigenen KFS/BW-6-Referenz vertauscht): + `l10n_at_personalgruppe` am Vertrag + + `l10n_at_account_debit_arbeiter` je Regel; **Option A minimal** + (Nutzer-Entscheidung 5.2): Overrides nur Grundentgelt 6000, + Sozialaufwand 6500, Abgaben 6600/6601/6602 — Zuschläge (6225), + ÜStd (6310), Prämien (6230), SZ (6240), BV (6440, EKR 644 ohne + Split) buchen für Arbeiter bis zur Referenzbuchhaltungs- + Fixierung auf die Angestellten-Konten (fehlende Konten → Warnung, + keine Erfindung). `models/account_posting_private.py`: + Gesamtüberschreibung von `_prepare_slip_lines` (Odoo bietet + keinen Override-Punkt; Upstream-Kopie Odoo-Pin 19.0+e.20260910 + mit einzeiliger Kontosubstitution, testgepinnt). + - **NET-Umbenennung** (NETTO → NET, Odoo-Konvention): + Zahlungsregistrierung (`action_register_payment`), net_wage und + Negativ-Netto-Erkennung filtern `code == 'NET'`. **Odoo-19-Fund:** + das Anlegen einer Structure kopiert die Regeln des + `hr_payroll.default_structure` (BASIC/GROSS/NET/…) via Feld-Default + in `rule_ids` — die kopierte Default-NET-Regel kollidiert im + `result_rules`-Dict (Netto fiel auf 0). Fix: `` in + `salary_rules_private.xml` archiviert die Kopie (`active=False`; + One2many blendet Archivierte aus; KEIN Unlink — historische + Lohnkontolinien behalten die Regel-Referenz; `struct_id` ist + NOT NULL). + - Matrix: KVGEO/URL_UE 6200/6000 · Zuschläge 6225 · ÜStd 6310 · + Prämien 6230 · B13/B14 6240 · DN-SV/LSt auf 3600/3540 · NET 3850 · + SVDG-Block 6560/6500 auf 3600 · **BVG 6440 (EKR 644) mit Fallback + 6400** auf Credit **3600** (Abfuhr via KV-Träger; 5.3) · FLAFDB + 6661/6601 auf 3541 · KOMMST 6660/6600 auf 3550 · DZ 6662/6602 + auf 3542. depends: + `l10n_at`, `hr_payroll_account_iso20022` + (SEPA-Auszahlung, Plan 4.5). +- Tests: `test_account_private` (4: RF-BUCH-1..4 — Kontenplan-Mock + ohne Chart-Install; Move-Balance, Kontenzeilen, Arbeiter-Split, + Fallback/Warnung; NET-Rundungscents als Odoo-„Adjustment Entry" + auf Journal-Default mit delta=0.02 toleriert). NETTO→NET in 4 + Bestands-Suiten nachgezogen. **88/88 grün** (frischer `-i`-Lauf, + Wegwerf-DB). Rechenfälle `docs/rechenfaelle/buchhaltung.md`. + ## 2026-09-11 — General-AT GP5: Abfertigung Neu (BMSVG) umgesetzt (M6, Teil 1) - `addons/l10n_at_hr_payroll` (19.0.3.1.0): Kern-Parameter diff --git a/personalverrechnung/IMPLEMENTIERUNGSPLAN-Privat.md b/personalverrechnung/IMPLEMENTIERUNGSPLAN-Privat.md index 25e3a25..0687820 100644 --- a/personalverrechnung/IMPLEMENTIERUNGSPLAN-Privat.md +++ b/personalverrechnung/IMPLEMENTIERUNGSPLAN-Privat.md @@ -783,6 +783,44 @@ Budget: die Kandidaten 8.13, der DZ (8.11) und die Regel-Optionen (NSchAB, DAG) laufen über die GP0-/Pilotmandant-Entscheidung bzw. Change-Requests. +**Update 2026-09-12 (GP6 umgesetzt):** FI-Buchung UGB nach dem +Österreichischen Einheitskontenrahmen (KFS/BW 6 — Nutzer-Referenz- +Exemplar `.additional_docs/KFSBW6_13072017_RF.pdf`) umgesetzt und +grün (19.0.6.0.0): Hook `_configure_payroll_account_at` +(`models/account_chart_private.py`; BE-Muster, Chart-Load + +``-Datendatei, idempotent; Konto-Suche exakt mit +Längen-gebundenem Präfix-Fallback gegen Odoo-Scaffold-Konten) +ordnet Regelkonten, Journal SLR (Default 6200, BE-Muster) und NET- +Konto **3850** (Anlage + reconcile). **EKR-Debit-Split Arbeiter/ +Angestellte:** `l10n_at_personalgruppe` am Vertrag + +`l10n_at_account_debit_arbeiter` je Regel, **Option A minimal** +(Nutzer-Entscheidung 5.2: 6000/6500/6600/6601/6602; Zuschläge/ÜStd/ +Prämien/SZ/BV fallback auf Angestellten-Konten bis Referenz- +buchhaltungs-Fixierung — fehlende Konten warnen, keine Erfindung); +`_prepare_slip_lines`-Gesamtüberschreibung +(`models/account_posting_private.py` — Odoo bietet keinen Override- +Punkt, Upstream-Kopie Odoo-Pin 19.0+e.20260910 mit einzeiliger +Kontosubstitution, testgepinnt). Nutzer-Klärungen: „6000 Gehälter/ +6200 Löhne" war gegenüber KFS/BW 6 vertauscht (600–619 Löhne, +620–639 Gehälter); NET-Konto 3850 (5.1); BV-Verbindlichkeit 3600 +(5.3); BV-Aufwand 6440 (EKR 644) mit Fallback 6400. **NET- +Umbenennung** NETTO→NET (Odoo-Konvention: action_register_payment/ +net_wage/Negativ-Netto-Erkennung filtern code 'NET') + **Odoo-19- +Fund:** das Structure-Anlegen kopiert die Default-Regeln +(BASIC/GROSS/NET/…) des `hr_payroll.default_structure` via Feld- +Default in rule_ids — die kopierte NET-Regel kollidiert im +result_rules-Dict (Netto = 0); Fix: ``-Archivierung der +Kopie (active=False; kein Unlink — struct_id NOT NULL, historische +Linien). Auszahlung `hr_payroll_account_iso20022` (depends +). +Tests: `test_account_private` (4, Kontenplan-Mock ohne Chart- +Install) + NETTO→NET in 4 Bestands-Suiten — **88/88 grün** +(frischer `-i`-Lauf, Wegwerf-DB; Odoo bucht NET-Rundungscents als +„Adjustment Entry" auf das Journal-Default). Rechenfälle +`docs/rechenfaelle/buchhaltung.md`. Offen: Arbeiter-Sub-Konten-End- +fixierung mit der Referenzbuchhaltung (Option A-Rest, GP0), Payment- +Registrierung/SEPA nur strukturell getestet; GP7 Meldewesen als +Nächstes. + **Update 2026-09-11 (GP5 umgesetzt):** Abfertigung Neu (BMSVG) umgesetzt und grün: Kern-Parameter `at_sv_bv_dg` (1,53 %, 19.0.3.1.0); privat (19.0.5.0.0) Regel `BVG` (ATP_DG, ohne