Files

296 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 ~135190 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 24 PT; nach AP3/AP5 wären es 1525+ 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, ~125175 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 69 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 `<deploy>/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) | 23 |
| M3 | History-Import (Option B; inkl. pip install / alternativ A + Aufräum) | 12 |
| M4 | Modul-Split Kern/Gemeinde, depends, Manifest-Text | 24 |
| — | Model-Rename TASY (D5, falls ja) | +1 |
| M5 | Skills/AGENTS/Memory im neuen Repo | 12 |
| M6 | gem360-Seite (Stub, MEMORY, Branch-Ruhestand, Scope-Pointer) | 12 |
| M7 | Validierung beider Seiten | 12 |
| **Σ** | | **917 PT ≈ 1,52,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: ~125175 PT.
## 6. Versions-/Kompatibilitätsvertrag (Bridge)
- Das Payroll-Repo taggt Releases (Vorschlag: `payroll-<modulversion>` 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 &amp; 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 D1D6 sind dabei je explizit zu
bestätigen; Abweichungen vom Plan (z. B. doch Option A beim Import)
erfolgen als Change-Request.