# PLAN — Repo-Split Personalverrechnung (gem360 → eigenes Repo) **Status:** Plan zur Freigabe (AGENTS.md-Workflow) — keine Ausführung vor ausdrücklicher Freigabe. Dieser Plan beschreibt nur die Migration; es werden bis zur Freigabe keine Dateien verschoben, umbenannt oder gelöscht. - **Datum:** 2026-09-09 - **Basis:** Branch `dev-payroll` @ `d4e6763` (lokal, unpushed) über Merge-Base `975277a` (origin/dev); 12 Commits - **Verifikationen (2026-09-09):** `git log origin/dev..dev-payroll`, Modul-Inspektion (~2.500 LOC, grep `vrv2015|budget_position_id|vrv_ansatz` → **0 Treffer**), Regelparameter-Inventar (`at_sv_*` vs. `gembg_*`), Modell-Inventar, Deployment-Layout (`../ixsol`: `odoo`, `l10n_at_vrv2015`, `l10n_at_vrv2015_glm`, `gem360` als separate Addon-Quellen) - **Kontext:** `personalverrechnung/PLAN-payroll-bgld.md` (Abschnitte 4, 7), Diskussion General-AT-Payroll 2026-09-09 (Zusatzschätzung ~135–190 PT) ## 1. Ziel & Motivation Die österreichische Personalverrechnung wird aus `gem360-git` in ein eigenes Projekt/Git-Repo überführt und dort weiterentwickelt — zunächst die Bgld. Gemeinde-Personalverrechnung (laufender Auftrag, AP3+ offen), perspektivisch ein General-AT-Payroll-Produkt (KV-basierte Privatwirtschaft) auf gemeinsamem Bundes-Kern. Begründung: - **Abhängigkeitspfeil bleibt einseitig gem360 → Payroll-Repo** (späteres Bridge-Modul); Payroll hängt niemals von gem360-Modulen ab. - **Bundes-Kern (LSt, SV, Meldewesen) entsteht als eigenes Modul** und wird von Gemeinde- UND General-Produkt konsumiert → jährliche Rechtswerte (LSt-Tarif, SV-Sätze, ELDA/FinOnl-Specs) werden einmal gepflegt, nie geforkt. - **Timing:** ~2.500 LOC, AP3 (LSt) noch nicht gebaut, keine VRV-Verflechtung (grep 0 Treffer, `l10n_at_vrv2015` steht nur als `depends`-Deklaration im Manifest) → Split heute 2–4 PT; nach AP3/AP5 wären es 15–25+ PT. - **Scope:** gem360 bleibt VRV/Gemeinde-Buchhaltung; das harte Constraint „KEINE Lohnverrechnung in Odoo" aus `50-SCOPE-module.md` bleibt für gem360 gewahrt. Payroll wird eigene Produktlinie mit eigenem Release-Takt. ## 2. Ist-Zustand (verifiziert 2026-09-09) | Element | Zustand | |---|---| | Branch `dev-payroll` | lokal, **unpushed**; 12 Commits: Plan-Docs (4), Modul (Scaffold, AP1, SV-TASY-Layer, AP2-Entgelt-Engine), Skills (2 Commits) | | Modul `l10n_at_gemeinde_payroll` | v19.0.1.3.0, ~2.500 LOC / 25 Dateien; implementiert: AP1 Katalog (35 Gruppen/433 Werte 2026), AP2 Entgelt-Engine (Structure + Regeln), SV-Wertelayer (17 `at_sv_*`-Rule-Parameter 2026 aus ÖGK TASY + Import-Wizard) | | Tests | 3 Suiten: `test_katalog`, `test_entgelt`, `test_tasy_import` | | VRV-Verflechtung | **keine** — nur `depends`-Deklaration `l10n_at_vrv2015`; kein Code/Daten-Bezug (grep 0 Treffer); `l10n_at_vrv2015` selbst referenziert Payroll nicht (grep 0) | | Regelparameter | `rule_parameters_2026.xml` = 17 sektor-neutrale `at_sv_*`-Parameter (KV/PV/UV/AV/AK/WF/BV/GfG/HBG/IESG) → Kern; `rule_parameters_entgelt.xml` = 4 `gembg_*`-Parameter (KIZU/Journaldienst/SFZU/Bereitschaft) → GemBG | | Modelle | Kern-Kandidaten: `gemeinde.payroll.tasy.mapping/.import.line/.import.wizard` (tasy.py); GemBG-seitig: `gemeinde.payroll.entlohnungsgruppe/-stufe`, `vorrueckung.wizard`, `hr.version`/`hr.employee`-Erweiterungen | | Manifest | `depends: [hr_payroll, hr_payroll_account, l10n_at_vrv2015]`; **Beschreibung veraltet** (nennt nur AP1+SV-Layer, AP2 fehlt) | | Skills | `.agents/skills/` seit `83250b8` versioniert; Commit `7f99677` tracked **alle** Skills + `IMPORT_ROLLBACK_NOTES.md` auch auf dev-payroll (inkl. vrv2015-Skill mit PDF-Assets) → beim Import beachten | | `.firecrawl/` | unversionierte Rechts-Rohquellen (GemBG-Konsolidierung, RV 0715, SV-Werte 2026) → **manuell kopieren**, sonst erzwingt der payroll-Skill Re-Fetch von RIS/sozialversicherung.at | | Werkzeuge | `git filter-repo` **nicht installiert** (pip nachinstallierbar); Workingtree von dev-payroll ist clean (nur Untracked) | ## 3. Ziel-Struktur ### 3.1 Neues Repo (Name: Entscheidung D1, Vorschlag `odoo-at-payroll`) ``` odoo-at-payroll/ AGENTS.md # angepasster Projekt-Workflow (committen!) .agents/skills/ payroll/SKILL.md # kopiert + Pfade angepasst odoo19-development/SKILL.md # kopiert (gem360-Variante ist generisch) agent-memory/SKILL.md # kopiert; eigenes .agents/MEMORY.md frisch .agents/MEMORY.md # neu aufgesetzt (Handoff für Payroll-Repo) addons/ l10n_at_hr_payroll/ # KERN: SV-Werte + TASY (heute), LSt (AP3), # Meldewesen (AP5), Belege (AP6), # Jahreswerte (AP8-LSt/SV-Teil) l10n_at_gemeinde_payroll/ # hierher migriert; Katalog + GemBG-Regeln; # depends: l10n_at_hr_payroll (statt vrv2015) l10n_at_hr_payroll_private/ # SPÄTER: General-AT (KV-Framework, AZG/UrlG, # 13./14. Bezüge, Abfertigung Neu); nur Gerüst personalverrechnung/ # komplett übernommen (Docs, tools/, quellen/) .firecrawl/ # manuell kopiert (unversioniert, lokal) docs/ # CHANGELOG, Testing-Strategie (anlegen) ``` ### 3.2 Modul-Split (Abhängigkeiten) | Modul | depends | Inhalt | |---|---|---| | `l10n_at_hr_payroll` (neu, Kern) | `hr_payroll` | `hr.rule.parameter`-Seeds `at_sv_*` (rule_parameters_2026.xml), TASY-Modelle + Mapping-Daten + Import-Wizard + Views, `test_tasy_import`; später: `lohnsteuer.py`-Utility (AP3), L16/eSV-Exporte (AP5), Belege (AP6) | | `l10n_at_gemeinde_payroll` (migriert) | `l10n_at_hr_payroll`, `hr_payroll_account` | Katalog (entlohnung.py, CSVs), `hr.version`/`hr.employee`-Felder, Vorrückungs-Wizard, Structure + Entgelt-Regeln (referenzieren `at_sv_*`-Parameter **per Code** → funktionieren unverändert, solange Kern installiert ist), `rule_parameters_entgelt.xml`, Tests `test_katalog`/`test_entgelt` | | `l10n_at_hr_payroll_private` (später) | `l10n_at_hr_payroll` | General-AT-Produkt (eigener Plan, ~125–175 PT) | | `l10n_at_gemeinde_payroll_vrv` (Bridge, **bleibt in gem360**) | `l10n_at_gemeinde_payroll`, `l10n_at_vrv2015` | AP7-Inhalt: `vrv_ansatz_id` auf `hr.salary.rule`, Posting-Hook `_prepare_line_values` (Ansatz/EHH/FHH), Abfertigungsrückstellungs-Buchung. **Jetzt nicht bauen** — nur der Vertrag (Abschnitt 6) | Regel-Parameter-Auflösung: die GemBG-Regeln lesen Parameter über `payslip._rule_parameter('at_sv_kv_dg')` (String-Code, kein XML-ID-Bezug); die Verschiebung der Parameter-Daten in den Kern erfordert **keine** Regeländerung. ## 4. Migrationsschritte (konkret) ### 4.1 M1 — Backup (Voraussetzung, zuerst) ```bash cd /home/fegger/Code/ixsol/gem360-git git push origin dev-payroll # existiert bisher nur lokal! ``` Außerdem: `.firecrawl/` sichern (unversioniert) und dieser Plan (`personalverrechnung/PLAN-repo-split.md`) wird **vor dem Export auf dev-payroll committet**, damit er mit der Historie wandert. ### 4.2 M2 — Repo-Bootstrap - Remote steht (D1 entschieden 2026-09-09, Existenz verifiziert — Repo ist leer): `http://100.103.83.12:3003/fegger/odoo-at-payroll.git`; Clone nach `/home/fegger/Code/ixsol/odoo-at-payroll`. - Odoo-19-Enterprise-Source als Geschwister-Checkout (Precedent: `/home/fegger/Code/ixsol/odoo`); Odoo-Version-Pin im README dokumentieren. - Grundgerüst: `addons/`, `personalverrechnung/`, `docs/`, `.agents/`; saubere `.gitignore` (kein Nachbau der gem360-`.git/info/exclude`-Lösung). - AGENTS.md **wirklich committen** (war in gem360 lokal excluded). ### 4.3 M3 — History-Import **Option B (empfohlen — saubere, pfad-begrenzte Historie):** ```bash pip install git-filter-repo # einmalig cd /tmp git clone /home/fegger/Code/ixsol/gem360-git gem360-payroll-export cd gem360-payroll-export git checkout dev-payroll git filter-repo --path 60-PLAN-payroll-bgld.md \ --path personalverrechnung \ --path addons/l10n_at_gemeinde_payroll # Ergebnis: die 10 Payroll-Commits (+ ggf. der Plan-Commit aus M1 = 11); # die Skill-Commits (7f99677, e4e8200) entfallen automatisch # (betreffen keine der Pfade) git branch -m dev-payroll main git remote add origin http://100.103.83.12:3003/fegger/odoo-at-payroll.git git push -u origin main ``` Provenance (RV 0715-Werte, TASY-Quellen, Plan-Historie) bleibt im Commit-Log erhalten. **Option A (Fallback, keine Zusatz-Tools):** ```bash cd /home/fegger/Code/ixsol/gem360-git git format-patch 975277a..dev-payroll -o /tmp/payroll-patches # im neuen Repo: git am /tmp/payroll-patches/*.patch # danach Aufräum-Commit: entfernen von .agents/skills/{vrv2015, # accounting-review, odoo19-accounting} und IMPORT_ROLLBACK_NOTES.md # (gem360-spezifisch, mit Option A in der Historie enthalten) ``` Nach beiden Optionen: `personalverrechnung/quellen/TASY-LSWH-Export-20260324.xml` (93k Zeilen) prüfen — wandert mit, ggf. per `.gitignore` von dauerhafter Versionierung ausnehmen (Precedent-Entscheidung im neuen Repo). ### 4.4 M4 — Modul-Split Kern/Gemeinde 1. `addons/l10n_at_hr_payroll/` anlegen (Manifest v19.0.1.0.0, `depends: [hr_payroll]`, LGPL-3, `countries: ['at']`). 2. **Verschieben** in den Kern: `models/tasy.py`, `views/tasy_views.xml`, `data/tasy_mapping.xml`, `data/rule_parameters_2026.xml`, `tests/test_tasy_import.py`, Security-Zeilen 6–9 aus `ir.model.access.csv` (eigene CSV im Kern). 3. **Verbleibend** in `l10n_at_gemeinde_payroll`: alles GemBG-seitige (Katalog, hr.version-Felder, Vorrückungs-Wizard, Structure, Entgelt- Regeln, `rule_parameters_entgelt.xml`, `test_katalog`, `test_entgelt`, restliche Security-Zeilen). 4. `depends` der Gemeinde-Moduls: `l10n_at_vrv2015` **streichen**, durch `l10n_at_hr_payroll` ersetzen (`hr_payroll_account` bleibt). 5. **Model-Rename (D5, empfohlen):** `gemeinde.payroll.tasy.mapping`, `.import.line`, `.import.wizard` → `l10n.at.payroll.tasy.mapping` usw., inkl. XML-IDs in Views/Mapping-Daten/Security/Tests. **Jetzt billiger denn je** (noch keine Datenbank mit dem Modul); später kostet ein Odoo- Modell-Rename xmlid-Migration. Alternativ: Namen belassen und im Kern dokumentieren (unschön, funktioniert). 6. Manifest-Beschreibung von `l10n_at_gemeinde_payroll` korrigieren (AP2-Entgelt-Engine ist implementiert; aktueller Text ist veraltet). 7. `l10n_at_hr_payroll_private/` nur als leeres Gerüst mit README („folgt; siehe personalverrechnung/") — kein Code. ### 4.5 M5 — Skills / AGENTS / Memory im neuen Repo - `payroll/SKILL.md` kopieren + Pfade anpassen: `personalverrechnung/`- und `addons/`-Pfade gelten unverändert; VRV-Referenzen (Buchungsabschnitt) auf die **künftige Bridge** in gem360 umlenken; YAML-Frontmatter beachten (Projektkonvention: name = Verzeichnisname, description). - `odoo19-development`, `agent-memory` kopieren; neues `.agents/MEMORY.md` aufsetzen (Fokus: Migration abgeschlossen, AP3 als nächster Schritt). - Neues `AGENTS.md`: gem360-Workflow übernehmen, VRV-Skill-Selection und 50-SCOPE-Bezüge entfernen. ### 4.6 M6 — gem360-Seite - `.agents/skills/payroll/` in gem360 auf **Stub** reduzieren (Verweis auf das Payroll-Repo; die Weiterentwicklung läuft dort) — D3. - `.agents/MEMORY.md`: Handoff-Eintrag (Split durchgeführt, dev-payroll obsolet, AP3 läuft im neuen Repo). - **Branch `dev-payroll` in gem360 vorerst behalten** (Nutzer-Entscheidung 2026-09-09: „keep dev-payroll for now“) — Stilllegung (löschen oder als `archive/dev-payroll` taggen) auf später vertagt. Bis dahin gilt: keine weitere Payroll-Implementierung auf dem gem360-Branch und **kein Merge nach dev/va_module** (sonst Dopplung mit dem Payroll-Repo). - `50-SCOPE-module.md`/Backlog: Pointer auf das Payroll-Repo ergänzen (Scope-Constraint bleibt erfüllt; Gemeinde-Payroll läuft extern weiter). - Deployment-Wiring (D4): Precedent nutzen — pro Deployment gepinntes Checkout `/odoo-at-payroll/addons` als zusätzliche addons_path- Quelle (wie `l10n_at_vrv2015` als Geschwister-Verzeichnis). Alternativen: git submodule vs. deploy-Artifact. Erst relevant, sobald die Bridge bzw. die erste Payroll-Installation auf einem gem360-Deployment liegt. ### 4.7 M7 — Validierung - `py_compile` über beide Module; XML-Well-formedness-Check (Muster wie im va_module-Workflow). - Odoo-Testlauf auf **Wegwerf-DB** (nie direkt auf `gem360_dev`): `-i l10n_at_hr_payroll,l10n_at_gemeinde_payroll --test-tags /l10n_at_hr_payroll,/l10n_at_gemeinde_payroll` — alle 3 Suiten grün (Katalog, Entgelt, TASY-Import). - Installations-Prüfung ohne `l10n_at_vrv2015` im addons_path (beweist die entkoppelte depends-Kette). - gem360-Seite: grep, dass kein gem360-Code/Daten das Payroll-Modul referenzieren (erwartet: 0 Treffer — verifiziert), und Install-Regression der VRV-Module (unverändert). ## 5. Aufwandsschätzung | M | Schritt | PT | |---|---|---| | M1 | Backup (Push, Plan-Commit, .firecrawl-Sicherung) | 0,5 | | M2 | Repo-Bootstrap (GitLab, Struktur, Odoo-Pin, AGENTS) | 2–3 | | M3 | History-Import (Option B; inkl. pip install / alternativ A + Aufräum) | 1–2 | | M4 | Modul-Split Kern/Gemeinde, depends, Manifest-Text | 2–4 | | — | Model-Rename TASY (D5, falls ja) | +1 | | M5 | Skills/AGENTS/Memory im neuen Repo | 1–2 | | M6 | gem360-Seite (Stub, MEMORY, Branch-Ruhestand, Scope-Pointer) | 1–2 | | M7 | Validierung beider Seiten | 1–2 | | **Σ** | | **9–17 PT ≈ 1,5–2,5 Wochen** | Danach unverändert weiter: AP0/AP3+ des Bgld.-Auftrags (~165 PT Rest) — aber AP3 (Lohnsteuer) **im Kern-Modul** des neuen Repos, sodass das General-Produkt ihn erbt. Zusatzschätzung General-AT dort: ~125–175 PT. ## 6. Versions-/Kompatibilitätsvertrag (Bridge) - Das Payroll-Repo taggt Releases (Vorschlag: `payroll-` je Modul-Bundle, beginnend `payroll-19.0.1.0`). - gem360-Deployments pinnen ein Tag; die Bridge `l10n_at_gemeinde_payroll_vrv` dokumentiert die getestete Kombination (Odoo hat keinen nativen Versions-Range-Mechanismus für `depends` → Vertrag per CHANGELOG + Install-Validierung im Deployment). - Regel: Payroll-Repo hängt **nie** von gem360-Modulen ab; die Bridge hängt von beiden Seiten ab und ist die einzige Nahtstelle. - Odoo-Major-Upgrades künftig in beiden Repos gegen denselben Odoo-Pin validieren. ## 7. Risiken | Risiko | Gegenmaßnahme | |---|---| | `dev-payroll` unpushed → Totalverlust bei Migration-Fehlern | M1 zuerst; erst nach erfolgreichem Import Branch stilllegen | | Commit `7f99677` zieht gem360-Skills (vrv2015-PDFs, Rollback-Notes) in die History | Option B (pfad-gefiltert) primär; bei Option A Aufräum-Commit | | `.firecrawl/` unversioniert → Provenance-Verlust | manueller Copy in M2; payroll-Skill erzwingt sonst Re-Fetch | | AGENTS.md/Skills nur lokal getrackt (gem360-Exclude-Besonderheit) | im neuen Repo bewusst committen; YAML-Frontmatter-Konvention einhalten | | Doppelte Odoo-Version-Pflege (zwei Repos) | gemeinsamer Odoo-Pin + Vertrag nach Abschnitt 6 | | Unterwart-Deployment braucht künftig zwei Addon-Quellen | D4 mit Ops klären, bevor die Bridge (AP7) gebaut wird | | TASY-Model-Rename später teuer (xmlid-Migration) | D5 jetzt entscheiden (empfohlen: ja, in M4) | | Split-Fehler bei Security-CSV/XML-IDs | M7-Validierung (Install + alle Testsuiten) | ## 8. Offene Entscheidungen (vor M2 zu treffen) | # | Entscheidung | Vorschlag | |---|---|---| | D1 | ~~Repo-Name & Hosting~~ | **Entschieden (2026-09-09):** `http://100.103.83.12:3003/fegger/odoo-at-payroll.git` (verifiziert: erreichbar, leer). Branch wird im neuen Repo zu `main` umbenannt. gem360-Branch `dev-payroll` bleibt vorerst (M6) | | D2 | Kern-Modulname | `l10n_at_hr_payroll` (Upstream-konventionsgerecht; Name ist unsere Wahl, es existiert kein gleichnamiges Odoo-Modul) | | D3 | Payroll-Skill in gem360 | Stub mit Verweis behalten (Bridge-Arbeit braucht Kontext) | | D4 | Deployment-Mechanik | gepinntes Checkout als addons_path-Quelle (Precedent vrv2015-Geschwister) | | D5 | TASY-Model-Rename jetzt? | ja (in M4; später deutlich teurer) | | D6 | Lizenz | LGPL-3 wie bisher (nötig für möglichen späteren Upstream-Beitrag) | ## 9. Reihenfolge / Milestones M0 Freigabe dieses Plans → M1 Backup → M2 Bootstrap → M3 Import → M4 Modul-Split (inkl. D5) → M5 Skills/AGENTS/Memory → M6 gem360-Seite → M7 Validierung → **AP0/AP3 (Lohnsteuer) im Kern-Modul des neuen Repos** (gemäß `IMPLEMENTIERUNGSPLAN-Bgld.md`, Abschnitt 4.2 Regel `LSTL`). ## 10. Freigabe-Antrag Mit Freigabe dieses Plans startet die Ausführung mit M1 (Backup) und M2 (Bootstrap). Optionen/Entscheidungen D1–D6 sind dabei je explizit zu bestätigen; Abweichungen vom Plan (z. B. doch Option A beim Import) erfolgen als Change-Request.