[ADD] personalverrechnung: machine-readable KV library (all current collective agreements)

Cross-checked catalogue of all currently valid Austrian collective
agreements, per the source policy: main source = the responsible
employer-side chamber, kollektivvertrag.at (OEGB-Verlag) as complete
cross-check baseline.

- oegb/: 593 variants from kollektivvertrag.at with full consolidated
  texts (JSON primary format, Markdown for review/diff) plus
  catalog.json/.csv; fetched via the portal's JSON servlets
  (dashboard/structure/slices/topics), resumable
- wko/: 614 current documents from the WKO KV database (1,820 branch
  overviews across 10 regions) with texts and catalog; match-report
  against the baseline: 407 pairs, 30 date disagreements flagged
- chambers/chambers.json: curated registry of chamber-side sources and
  publication gaps (GOeD member-only, RA/Notariat not public, OCR-less
  scan PDFs, missing hospital-doctors KV)
- kv-catalog.json/.csv: merged catalogue, 768 entries, chamber
  classification, main_source, cross_check status, manual_review lists
- tools/fetch_kv_portal.py / fetch_wko_kv.py / build_kv_catalog.py:
  stdlib-only fetchers and merge step, each with a --refresh diff mode
- RUNBOOK.md: update cycle for keeping the library current (annual,
  tied to the Wartung rhythm and KV rounds)

Lohntafel PDFs are linked but not downloaded; wage tables contained in
the KV texts are converted. No Odoo module changes.
This commit is contained in:
2026-09-09 19:10:07 +02:00
parent 99728c1f23
commit 5b629a5916
2427 changed files with 2744543 additions and 8 deletions
@@ -0,0 +1,132 @@
{
"variant_id": "SI-2948_de",
"variant_group_id": "bayerische-saalforste-salzburg",
"title": "Bayerische Saalforste Salzburg",
"employment_types": [
"arb"
],
"employment_types_names": [
"Arbeiter:innen"
],
"provinces": [
"s"
],
"provinces_names": [
"Salzburg"
],
"unions": [
"pro-ge"
],
"unions_names": [
"PRO-GE"
],
"validity": {
"valid_from": "2026-06-25",
"last_content_update": "2026-06-25"
},
"fetched_at": "2026-09-09",
"source_urls": {
"dashboard": "https://www.kollektivvertrag.at/kv?variant-group-id=bayerische-saalforste-salzburg&variant-id=SI-2948_de&topic-id=1",
"volltext": "https://www.kollektivvertrag.at/volltext?doc-set-id=SI-2948_de",
"portal": "https://www.kollektivvertrag.at"
},
"chamber": null,
"slices": [
{
"slice_id": "914709_20260401",
"name": "Lohn-/Gehaltsordnung",
"valid_from": "2026-03-31",
"version": "20260401"
}
],
"slice_history": [],
"topics": [
{
"id": "1ac39e3b-0d06-4838-98d9-cfaf854a9c31",
"title": "Löhne, Zulagen, Urlaub und Fahrtkosten"
}
],
"chamber_heuristic": "unclassified",
"content": {
"slices": {
"914709_20260401": {
"id": "914709_20260401",
"title": "Bayerische Saalforste Salzburg / Lohn-/Gehaltsordnung",
"children": [
{
"id": "pr914713_5234847",
"element": "para",
"titleHtml": "<div class=\"titelbereich h1\"><div class=\"titel\"><h1 class=\"titel\">Lohns&auml;tze ab der Lohnerh&ouml;hung per 1.4.2026</h1></div></div>",
"contentHtml": "<div class=\"para\" id=\"pr914713_5234847\"><div class=\"textinhalt\"> <table border=\"1\" frame=\"box\" rules=\"all\" width=\"100%\"> <colgroup> <col width=\"12*\"> <col width=\"12*\"> <col width=\"12*\"> <col width=\"12*\"> <col width=\"12*\"> <col width=\"12*\"> <col width=\"12*\"> <col width=\"12*\"></colgroup> <tbody> <tr> <td>garantierter DV 2025</td> <td align=\"right\">23,86&nbsp;&euro;</td> <td>Erh&ouml;hung in%</td> <td align=\"right\">3,30&nbsp;%</td> <td align=\"right\">0,7874&nbsp;&euro;</td> <td>in EURO/h</td> <td>Garantierter DV 2026</td> <td align=\"right\">24,65&nbsp;&euro;</td> </tr> </tbody> </table> <table border=\"1\" frame=\"box\" rules=\"all\" width=\"100%\"> <div class=\"annotationen\"> <div class=\"lohn\" name=\"Lohntabelle Bayerische Saalforste Salzburg\"></div></div> <colgroup> <col width=\"20*\"> <col width=\"10*\"> <col width=\"10*\"> <col width=\"10*\"> <col width=\"10*\"> <col width=\"10*\"> <col width=\"10*\"> <col width=\"10*\"> <col width=\"10*\"></colgroup> <thead> <tr> <th>Gruppe</th> <th>Zeitlohn</th> <th>Akkordrichtsatz</th> <th>Pr&auml;mienlohn 2</th> <th>Pr&auml;mienlohn 3</th> <th>Pr&auml;mienlohn 4</th> <th>Stundensatz <br>Holzernte <br>normal</th> <th>Stundensatz <br>Holzernte <br>Gebirgsharvester</th> <th>Stundensatz <br>Inventur</th> </tr> </thead> <tbody> <tr bedingungen=\"Besch&auml;ftigungsgruppe = 'Forstfacharbeiter m.P.'\"> <td align=\"left\"><div class=\"annotationen\"> <div class=\"beschaeftigungsgruppe\" name=\"Forstfacharbeiter m.P.\"></div></div>Forstfacharbeiter m.P.</td> <td align=\"center\" bedingungen=\"Zeitlohn\" class=\"Stundenlohn\">19,17</td> <td align=\"center\" bedingungen=\"Akkordrichtsatz\" class=\"Stundenlohn\">21,36</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-2\" class=\"Stundenlohn\">23,33</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-3\" class=\"Stundenlohn\">25,24</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-4\" class=\"Stundenlohn\">26,19</td> <td align=\"center\" bedingungen=\"Holzernte\" class=\"Stundenlohn\">25,29</td> <td align=\"center\" bedingungen=\"Holzernte; Gebirgsharvester\" class=\"Stundenlohn\">26,44</td> <td align=\"center\" bedingungen=\"Inventur\" class=\"Stundenlohn\">24,79</td> </tr> <tr bedingungen=\"Besch&auml;ftigungsgruppe = 'Forstarbeiter o.P.'\"> <td align=\"left\"><div class=\"annotationen\"> <div class=\"beschaeftigungsgruppe\" name=\"Forstarbeiter o.P.\"></div></div>Forstarbeiter o. P.</td> <td align=\"center\" bedingungen=\"Zeitlohn\" class=\"Stundenlohn\">18,17</td> <td align=\"center\" bedingungen=\"Akkordrichtsatz\" class=\"Stundenlohn\">20,36</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-2\" class=\"Stundenlohn\">22,33</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-3\" class=\"Stundenlohn\">24,24</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-4\" class=\"Stundenlohn\">25,19</td> <td align=\"center\" bedingungen=\"Holzernte\" class=\"Stundenlohn\">24,29</td> <td align=\"center\" bedingungen=\"Holzernte; Gebirgsharvester\" class=\"Stundenlohn\">25,44</td> <td align=\"center\" bedingungen=\"Inventur\" class=\"Stundenlohn\">23,79</td> </tr> <tr bedingungen=\"Besch&auml;ftigungsgruppe = Maschinist\"> <td align=\"left\"><div class=\"annotationen\"> <div class=\"beschaeftigungsgruppe\" name=\"Maschinist\"></div></div>Maschinist</td> <td align=\"center\" bedingungen=\"Besch&auml;ftigungsgruppe = Zeitlohn\" class=\"Stundenlohn\">19,17</td> <td align=\"center\" bedingungen=\"Akkordrichtsatz\" class=\"Stundenlohn\">21,36</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-2\" class=\"Stundenlohn\">23,33</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-3\" class=\"Stundenlohn\">25,24</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-4\" class=\"Stundenlohn\">26,19</td> <td align=\"center\" bedingungen=\"Holzernte\" class=\"Stundenlohn\">25,29</td> <td align=\"center\" bedingungen=\"Holzernte; Gebirgsharvester\" class=\"Stundenlohn\">26,44</td> <td align=\"center\" bedingungen=\"Inventur\" class=\"Stundenlohn\">24,79</td> </tr> <tr bedingungen=\"Besch&auml;ftigungsgruppe = Hilfsarbeiter\"> <td align=\"left\"><div class=\"annotationen\"> <div class=\"beschaeftigungsgruppe\" name=\"Hilfsarbeiter\"></div></div>Hilfsarbeiter</td> <td align=\"center\" bedingungen=\"Zeitlohn\" class=\"Stundenlohn\" mindestlohn=\"true\">18,01</td> <td align=\"center\" bedingungen=\"Akkordrichtsatz\" class=\"Stundenlohn\">19,91</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-2\" class=\"Stundenlohn\">21,47</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-3\" class=\"Stundenlohn\">23,27</td> <td align=\"center\" bedingungen=\"Pr&auml;mienlohn-4\" class=\"Stundenlohn\">24,10</td> <td align=\"center\">&mdash;</td> <td align=\"center\">&mdash;</td> <td align=\"center\">&mdash;</td> </tr> </tbody> </table> </div></div>",
"title": "Lohnsätze ab der Lohnerhöhung per 1.4.2026",
"type": null,
"subType": null,
"number": null,
"footNoteIds": null,
"children": [
{
"id": "pr914714_5234848",
"element": "para",
"titleHtml": null,
"contentHtml": "<div class=\"para\" id=\"pr914714_5234848\"><div class=\"textinhalt\"> <ul class=\"nummerierung-none liste\"> <li class=\"listeel\" style=\"list-style-type:&bull;\"><span class=\"listenel_num\">&bull;</span> <p class=\"text\">Der garantierte Durchschnittslohn wird um <span class=\"fett hervor\">3,3&nbsp;% erh&ouml;ht</span>.</p> </li> <li class=\"listeel\" style=\"list-style-type:&bull;\"><span class=\"listenel_num\">&bull;</span> <p class=\"text\">Die Errichtung der Arbeitsgruppen betrifft &bdquo;Wege- und Fahrzeugentsch&auml;digung&ldquo; und 6. Urlaubswoche. </p> </li> <li class=\"listeel\" style=\"list-style-type:&bull;\"><span class=\"listenel_num\">&bull;</span> <p class=\"text\">Der neue Mindestlohn betr&auml;gt <span class=\"fett hervor\">3.119,33&nbsp;Euro</span>.</p> </li> </ul> </div></div>",
"title": null,
"type": null,
"subType": null,
"number": null,
"footNoteIds": null,
"children": null
}
]
}
],
"footNotes": null,
"errorMessage": null
}
},
"topics": {
"1ac39e3b-0d06-4838-98d9-cfaf854a9c31": {
"id": "1ac39e3b-0d06-4838-98d9-cfaf854a9c31",
"title": "Löhne, Zulagen, Urlaub und Fahrtkosten",
"variantId": "SI-2948_de",
"variantGroupId": "bayerische-saalforste-salzburg",
"items": [
{
"id": "d40d05a2-700b-46a6-8564-67fb15cf9710",
"htmlContent": "<div class='titelbereich h1'><div class='titel'><h1 class='titel'>Lohnsätze ab der Lohnerhöhung per 1.4.2026</h1></div></div><div class='para' id='pr914713_5234847'><div class='textinhalt'> <table border='1' frame='box' rules='all' width='100%'> <colgroup> <col width='12*'/> <col width='12*'/> <col width='12*'/> <col width='12*'/> <col width='12*'/> <col width='12*'/> <col width='12*'/> <col width='12*'/></colgroup> <tbody> <tr> <td>garantierter DV 2025</td> <td align='right'>23,86 €</td> <td>Erhöhung in%</td> <td align='right'>3,30 %</td> <td align='right'>0,7874 €</td> <td>in EURO/h</td> <td>Garantierter DV 2026</td> <td align='right'>24,65 €</td> </tr> </tbody> </table> <table border='1' frame='box' rules='all' width='100%'> <div class='annotationen'> <div class='lohn' name='Lohntabelle Bayerische Saalforste Salzburg'></div></div> <colgroup> <col width='20*'/> <col width='10*'/> <col width='10*'/> <col width='10*'/> <col width='10*'/> <col width='10*'/> <col width='10*'/> <col width='10*'/> <col width='10*'/></colgroup> <thead> <tr> <th>Gruppe</th> <th>Zeitlohn</th> <th>Akkordrichtsatz</th> <th>Prämienlohn 2</th> <th>Prämienlohn 3</th> <th>Prämienlohn 4</th> <th>Stundensatz <br/>Holzernte <br/>normal</th> <th>Stundensatz <br/>Holzernte <br/>Gebirgsharvester</th> <th>Stundensatz <br/>Inventur</th> </tr> </thead> <tbody> <tr bedingungen='Beschäftigungsgruppe = 'Forstfacharbeiter m.P.''> <td align='left'><div class='annotationen'> <div class='beschaeftigungsgruppe' name='Forstfacharbeiter m.P.'></div></div>Forstfacharbeiter m.P.</td> <td align='center' bedingungen='Zeitlohn' class='Stundenlohn'>19,17</td> <td align='center' bedingungen='Akkordrichtsatz' class='Stundenlohn'>21,36</td> <td align='center' bedingungen='Prämienlohn-2' class='Stundenlohn'>23,33</td> <td align='center' bedingungen='Prämienlohn-3' class='Stundenlohn'>25,24</td> <td align='center' bedingungen='Prämienlohn-4' class='Stundenlohn'>26,19</td> <td align='center' bedingungen='Holzernte' class='Stundenlohn'>25,29</td> <td align='center' bedingungen='Holzernte; Gebirgsharvester' class='Stundenlohn'>26,44</td> <td align='center' bedingungen='Inventur' class='Stundenlohn'>24,79</td> </tr> <tr bedingungen='Beschäftigungsgruppe = 'Forstarbeiter o.P.''> <td align='left'><div class='annotationen'> <div class='beschaeftigungsgruppe' name='Forstarbeiter o.P.'></div></div>Forstarbeiter o. P.</td> <td align='center' bedingungen='Zeitlohn' class='Stundenlohn'>18,17</td> <td align='center' bedingungen='Akkordrichtsatz' class='Stundenlohn'>20,36</td> <td align='center' bedingungen='Prämienlohn-2' class='Stundenlohn'>22,33</td> <td align='center' bedingungen='Prämienlohn-3' class='Stundenlohn'>24,24</td> <td align='center' bedingungen='Prämienlohn-4' class='Stundenlohn'>25,19</td> <td align='center' bedingungen='Holzernte' class='Stundenlohn'>24,29</td> <td align='center' bedingungen='Holzernte; Gebirgsharvester' class='Stundenlohn'>25,44</td> <td align='center' bedingungen='Inventur' class='Stundenlohn'>23,79</td> </tr> <tr bedingungen='Beschäftigungsgruppe = Maschinist'> <td align='left'><div class='annotationen'> <div class='beschaeftigungsgruppe' name='Maschinist'></div></div>Maschinist</td> <td align='center' bedingungen='Beschäftigungsgruppe = Zeitlohn' class='Stundenlohn'>19,17</td> <td align='center' bedingungen='Akkordrichtsatz' class='Stundenlohn'>21,36</td> <td align='center' bedingungen='Prämienlohn-2' class='Stundenlohn'>23,33</td> <td align='center' bedingungen='Prämienlohn-3' class='Stundenlohn'>25,24</td> <td align='center' bedingungen='Prämienlohn-4' class='Stundenlohn'>26,19</td> <td align='center' bedingungen='Holzernte' class='Stundenlohn'>25,29</td> <td align='center' bedingungen='Holzernte; Gebirgsharvester' class='Stundenlohn'>26,44</td> <td align='center' bedingungen='Inventur' class='Stundenlohn'>24,79</td> </tr> <tr bedingungen='Beschäftigungsgruppe = Hilfsarbeiter'> <td align='left'><div class='annotationen'> <div class='beschaeftigungsgruppe' name='Hilfsarbeiter'></div></div>Hilfsarbeiter</td> <td align='center' bedingungen='Zeitlohn' class='Stundenlohn' mindestlohn='true'>18,01</td> <td align='center' bedingungen='Akkordrichtsatz' class='Stundenlohn'>19,91</td> <td align='center' bedingungen='Prämienlohn-2' class='Stundenlohn'>21,47</td> <td align='center' bedingungen='Prämienlohn-3' class='Stundenlohn'>23,27</td> <td align='center' bedingungen='Prämienlohn-4' class='Stundenlohn'>24,10</td> <td align='center'>—</td> <td align='center'>—</td> <td align='center'>—</td> </tr> </tbody> </table> </div></div>",
"variantId": "SI-2948_de",
"sliceId": "914709_20260401",
"source": "variant",
"anchor": "pr914713_5234847",
"structuralContext": [
{
"title": "Lohn-/Gehaltsordnung",
"anchor": "914709_20260401",
"level": 0
}
]
},
{
"id": "4a563418-e612-4b33-9c95-6bfd321fd2ac",
"htmlContent": "<div class='para' id='pr914714_5234848'><div class='textinhalt'> <ul class='nummerierung-none liste'> <li class='listeel' style='list-style-type:•'><span class='listenel_num'>•</span> <p class='text'>Der garantierte Durchschnittslohn wird um <span class='fett hervor'>3,3 % erhöht</span>.</p> </li> <li class='listeel' style='list-style-type:•'><span class='listenel_num'>•</span> <p class='text'>Die Errichtung der Arbeitsgruppen betrifft „Wege- und Fahrzeugentschädigung“ und 6. Urlaubswoche. </p> </li> <li class='listeel' style='list-style-type:•'><span class='listenel_num'>•</span> <p class='text'>Der neue Mindestlohn beträgt <span class='fett hervor'>3.119,33 Euro</span>.</p> </li> </ul> </div></div>",
"variantId": "SI-2948_de",
"sliceId": "914709_20260401",
"source": "variant",
"anchor": "pr914714_5234848",
"structuralContext": [
{
"title": "Lohnsätze ab der Lohnerhöhung per 1.4.2026",
"anchor": "pr914713_5234847",
"level": 1
},
{
"title": "Lohn-/Gehaltsordnung",
"anchor": "914709_20260401",
"level": 0
}
]
}
]
}
}
}
}