#!/usr/bin/env python3
"""PGS15 Audit Procedure v2.0 — DOCX Generator"""
from docx import Document
from docx.shared import Pt, Cm, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn, nsdecls
from docx.oxml import parse_xml

doc = Document()

style = doc.styles['Normal']
font = style.font
font.name = 'Calibri'
font.size = Pt(11)
style.paragraph_format.space_after = Pt(6)
style.paragraph_format.line_spacing = 1.15

for level in range(1, 4):
    hs = doc.styles[f'Heading {level}']
    hs.font.name = 'Calibri'
    hs.font.color.rgb = RGBColor(0, 51, 102)
    sizes = {1: 16, 2: 13, 3: 11}
    hs.font.size = Pt(sizes[level])
    hs.font.bold = True
    hs.paragraph_format.space_before = Pt([18, 12, 8][level-1])

for section in doc.sections:
    section.top_margin = Cm(2.5)
    section.bottom_margin = Cm(2.5)
    section.left_margin = Cm(2.5)
    section.right_margin = Cm(2.5)

def add_table(headers, rows):
    table = doc.add_table(rows=1+len(rows), cols=len(headers))
    table.style = 'Table Grid'
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    for i, h in enumerate(headers):
        cell = table.rows[0].cells[i]
        cell.text = h
        shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="003366"/>')
        cell.paragraphs[0].runs[0].font.color.rgb = RGBColor(255, 255, 255)
        cell.paragraphs[0].runs[0].font.bold = True
        cell.paragraphs[0].runs[0].font.size = Pt(10)
        cell._tc.get_or_add_tcPr().append(shading)
    for r_idx, row in enumerate(rows):
        for c_idx, val in enumerate(row):
            cell = table.rows[r_idx+1].cells[c_idx]
            cell.text = str(val)
            for p in cell.paragraphs:
                for run in p.runs:
                    run.font.size = Pt(10)
            if r_idx % 2 == 1:
                shading = parse_xml(f'<w:shd {nsdecls("w")} w:fill="F2F2F2"/>')
                cell._tc.get_or_add_tcPr().append(shading)
    return table

def add_para(text, bold=False, italic=False):
    p = doc.add_paragraph()
    run = p.add_run(text)
    run.font.size = Pt(11)
    run.font.bold = bold
    run.font.italic = italic
    return p

# ===== TITLE PAGE =====
for _ in range(6):
    doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('PGS-15 Audit Procedure')
run.font.size = Pt(28)
run.font.bold = True
run.font.color.rgb = RGBColor(0, 51, 102)
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Stap-voor-Stap Handleiding voor Auditors')
run.font.size = Pt(18)
run.font.color.rgb = RGBColor(0, 51, 102)
doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Versie 2.0 — April 2026\nBron: PGS 15:2025 versie 1.0 (januari 2025)')
run.font.size = Pt(14)
for _ in range(6):
    doc.add_paragraph()
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run('Doelgroep: HSEQ-auditors, veiligheidsadviseurs')
run.font.size = Pt(11)
doc.add_page_break()

# ===== FASE 0 =====
doc.add_heading('Fase 0: Voorbereiding', level=1)
add_para('Een adequate voorbereiding is de basis van een effectieve PGS-15 audit. De auditor verzamelt vooraf alle relevante documentatie om de scope te bepalen. [PGS 15:2025 — §1, §7]')

doc.add_heading('0.1 Te verzamelen documenten', level=2)
add_para('Verzamel de volgende documenten vóór het locatiebezoek:')
add_table(
    ['Nr.', 'Document', 'Bronverwijzing PGS 15:2025'],
    [
        ['1', 'Omgevingsvergunning (indien vergunningplichtig)', '§1.3, §5.2'],
        ['2', 'Stoffenlijst / Informatievoorziening hulpdiensten (M116)', 'M116, M117'],
        ['3', 'Plattegrond conform NEN 1414-1', 'M116'],
        ['4', 'Uitgangspuntendocument (UPD) — indien Veiligheidsniveau A', 'M99'],
        ['5', 'Intern noodplan (M113)', 'M113'],
        ['6', 'Inspectierapporten brandbeveiliging (indien Veiligheidsniveau A)', 'M99'],
        ['7', 'Certificaten vakbekwaamheid', '§7.4.3, M104'],
        ['8', 'Veiligheidsinformatiebladen (SDS)', 'M42–M44, Bijlage E'],
        ['9', 'Onderhouds- en keuringsrapporten', '§7.4.1, M45'],
        ['10', 'Eerdere auditrapporten en opvolging', '—'],
        ['11', 'Wijze van beschikbaar stellen informatie (M118)', 'M118'],
    ]
)
doc.add_paragraph()

doc.add_heading('0.2 Op te vragen informatie bij het bedrijf', level=2)
add_para('• Actuele stoffenlijst met totale opgeslagen hoeveelheden per ADR-klasse\n• Veranderingen sinds laatste audit (nieuwe stoffen, gewijzigde hoeveelheden, bouwkundige wijzigingen)\n• Aanwezigheid veiligheidsadviseur gevaarlijke stoffen\n• BRZO-status\n• Type opslagvoorzieningen: binnenopslag, buitenopslag, brandveiligheidsopslagkasten, (tank)containers\n• Aanwezige blus- en detectiesystemen\n• Aanwezigheid bedrijfsbrandweer (M97)\n• PV-installatie op opslagdak (M21) — toestemming bevoegd gezag?')

doc.add_heading('0.3 Checklist Voorbereiding', level=2)
add_table(
    ['Nr.', 'Controlepunt', 'Ja/Nee'],
    [
        ['1', 'Omgevingsvergunning ontvangen en bestudeerd', ''],
        ['2', 'Stoffenlijst / M116-informatie ontvangen en geanalyseerd', ''],
        ['3', 'Plattegrond conform NEN 1414-1 ontvangen', ''],
        ['4', 'UPD ontvangen (indien Veiligheidsniveau A van toepassing)', ''],
        ['5', 'Intern noodplan ontvangen (M113)', ''],
        ['6', 'Inspectierapporten brandbeveiliging ontvangen', ''],
        ['7', 'Certificaten vakbekwaamheid opgevraagd', ''],
        ['8', 'SDS van kritische stoffen ontvangen', ''],
        ['9', 'Eerdere auditrapporten opgevraagd', ''],
        ['10', 'BRZO-status nagegaan', ''],
        ['11', 'Totale opslaghoeveelheid per klasse berekend', ''],
        ['12', 'ADR-klassen en verpakkingsgroepen geïnventariseerd', ''],
        ['13', 'Veiligheidsniveau bepaald (Tabel 6 in M3)', ''],
        ['14', 'Toepasselijke maatregelen geïdentificeerd (§7 filtering)', ''],
        ['15', 'Auditdatum en contactpersoon bevestigd', ''],
    ]
)
doc.add_paragraph()
doc.add_page_break()

# ===== FASE 1 =====
doc.add_heading('Fase 1: Inventarisatie', level=1)
add_para('De inventarisatiefase bepaalt of PGS 15 van toepassing is en welke voorschriften gelden. [PGS 15:2025 — §1.2]')

doc.add_heading('1.1 Bepaal de werkingssfeer', level=2)
add_para('Stap 1: Inventariseer alle aanwezige gevaarlijke stoffen.')
add_para('• Raadpleeg de stoffenlijst / M116-informatie\n• Noteer per stof: ADR-klasse, UN-nummer, verpakkingsgroep, hoeveelheid\n• Identificeer CMR-/CLP-stoffen buiten het ADR [PGS 15:2025 — §1.2, Tabel 1]')
add_para('Stap 2: Controleer of stoffen onder de werkingssfeer vallen.')
add_para('• Raadpleeg Tabel 1: alle ADR-klassen, CMR/CLP, afvalstoffen, gewasbeschermingsmiddelen ≥400 kg\n• Sluit uit: klasse 1, 7, 5.2 (overige), lithiumhoudende energiedragers (PGS 37-2), meststoffen (PGS 7)')

doc.add_heading('1.2 Ondergrenzen toets', level=2)
add_para('• Raadpleeg Tabel 2 van PGS 15:2025 (§1.2.1) voor de ondergrens per klasse/verpakkingsgroep\n• Bij meerdere stoffen: bereken de som van (hoeveelheid/ondergrens). Indien ≥1: PGS 15 van toepassing\n• LQ/EQ-vrijstelling: dubbele ondergrens, mits in transportverpakking (uitzondering: klasse 5.2)\n• Stoffen met bijkomend gevaar: laagste ondergrens is bepalend')

doc.add_heading('1.3 Bepaal het Veiligheidsniveau', level=2)
add_para('Elke opslagvoorziening heeft een basisveiligheidsniveau. Afhankelijk van stof + hoeveelheid geldt een hoger niveau:')
add_para('Stap 1: Bepaal ADR-klasse, verpakkingsgroep en vlampunt per stof')
add_para('Stap 2: Bepaal de totale opgeslagen hoeveelheid')
add_para('Stap 3: Raadpleeg Tabel 6 in M3 → lees het vereiste Veiligheidsniveau en WBDBO')
add_para('Stap 4: Bepaal type opslag (binnen/buiten/kast/container/tijdelijk)')
add_para('Stap 5: Filter de maatregelen uit §7 op veiligheidsniveau + type opslag + stofgroep [PGS 15:2025 — §7.1.1, Tabel 5]')

add_table(
    ['Niveau', 'Wanneer van toepassing', 'Belangrijkste extra eisen'],
    [
        ['Basis', 'Elke opslagvoorziening', 'MW1, M2, M21, M35, M116/M117'],
        ['A', 'Brandescalatie-scenario\'s (Tabel 6)', 'UPD (M99), VBB (M96), WBDBO 60/90 min, jaarlijkse inspectie'],
        ['B', 'Middelste scenario\'s (Tabel 6)', 'Brandwerendheid en/of afstanden'],
        ['C', 'Niet-ontstoken escalatie (Tabel 6)', 'Verspreidingspreventie'],
    ]
)
doc.add_paragraph()

doc.add_heading('1.4 Documenteer ADR-klassen en verpakkingsgroepen', level=2)
add_para('Maak een tabel met: stofnaam, UN-nummer, ADR-klasse(n), verpakkingsgroep, hoeveelheid, opslaglocatie, veiligheidsniveau. Dit overzicht vormt de basis voor de toetsing in fase 3.')
doc.add_page_break()

# ===== FASE 2 =====
doc.add_heading('Fase 2: Locatiebezoek', level=1)

doc.add_heading('2.1 Opkomst en opening meeting', level=2)
add_para('• Introductie en doel van de audit communiceren\n• Scope en aanpak bespreken\n• Veiligheidsinstructies ontvangen (PBM\'s, noodsituaties, evacuatieroute)\n• Begeleiding regelen\n• Tijdsplanning afspreken')

doc.add_heading('2.2 Systematische doorloop van de locatie', level=2)
add_para('Route: Buitenzijde → algemene inrichting → binnenopslag → specifieke opslagvoorzieningen', bold=True)

doc.add_heading('A. Buitenzijde van de inrichting', level=3)
add_para('Controleer:')
add_para('• Veiligheidssignalering aan buitenzijde: gevaarsidentificatiesymbolen conform ADR (art. 5.2) zichtbaar en correct [M135]\n• Buitenopslagvoorzieningen: staat, constructie, afstanden. WBDBO visueel beoordelen [M21]\n• Afstanden: ≥5 m = 30 min WBDBO-reductie; ≥15 m = 60 min reductie (was 10 m) [M90]\n• PV-installatie op opslagdak: toestemming bevoegd gezag aanwezig? [M21]\n• Bereikbaarheid hulpdiensten: toegangswegen breed, vrijgehouden [M103]\n• Bluswatervoorziening: aanwezig, bereikbaar, voldoende capaciteit [M103]\n• Gasflessen buiten: opslag conform M7/M8/M54/M56, afstand min. 15 m tot gebouwen [M91]')

doc.add_heading('B. Algemene inrichting', level=3)
add_para('• Nooddouche bereikbaar en functioneel\n• Vluchtroutes vrij en gemarkeerd\n• Opslag niet in vluchtroutes [M4]\n• Algemene ventilatie doelmatig [M11]\n• Good housekeeping (MW1)')

doc.add_heading('C. Binnenopslagvoorzieningen', level=3)
add_para('Controleer per opslagvoorziening:')
add_para('• WBDBO: minimaal 60 min (wanden, vloer, dak). Bij Veiligheidsniveau A >10 ton: 90 min [M21, M24]\n• Deuren zelfsluitend in brandwerende constructie [M21]\n• Brandveiligheidsopslagkasten: min. 30 min (gasflessen: min. 60 min) [Bijlage F]\n• Productopvang: capaciteit 110% grootste verpakking of 10% totaal [M35, M36]\n• Compartimentering: onverenigbare combinaties gescheiden conform Bijlage E [M42–M44]\n• Etikettering: ADR/CLP correct, ook omgepakte kleinere verpakkingen [M48]\n• Manoeuvreerruimte tussen opslagvakken voldoende [M76]\n• Stellingen en aanrijdbeveiliging [M75, M78]')

doc.add_heading('D. Specifieke opslagvoorzieningen', level=3)
add_para('Gasflessen:', bold=True)
add_para('• Binnenopslag ≤250 l: in brandveiligheidsopslagkast (≥60 min BW) [M7]\n• Binnenopslag >250 l: zoveel mogelijk voorkomen; dedicated indien noodzakelijk [M8]\n• Kelderopslag gasflessen: VERBODEN [M8]\n• Max 2 brandveiligheidsopslagkasten gasflessen per brandcompartiment op verdieping [M8]\n• Staand opgeslagen, niet gestapeld (tenzij voorziening) [M54]\n• Bescherming tegen omvallen [M56]\n• Gasflessen tegen gevel: Wbdbo ≥60 min tot 4 m hoogte + overstekend dak [M91]')

add_para('Verdiepingsopslag:', bold=True)
add_para('• Eerste verdieping: max 1 opslagruimte, max 2.500 kg/l [M8]\n• Kelder en hogere verdiepingen: max 500 kg/l (uitzondering: onbrandbare ADR 8 VG II/III en ADR 9) [M8]\n• Brandveiligheidsopslagkasten op verdieping: max 2.500 kg/l per brandcompartiment [M8]')

add_para('Spuitbussen en canisters (UN 3500–3505):', bold=True)
add_para('• Maatregelen voor categorie spuitbussen van toepassing [M2]\n• Stapelhoogte max. 3,60 m zonder stellingen; bij Veiligheidsniveau A: stapelhoogte via UPD [M55]')

add_para('Organische peroxiden:', bold=True)
add_para('• Max. 1.000 kg in LQ-verpakkingen [M19]\n• Type G: als aanverwante stoffen, PGS 15-maatregelen niet van toepassing')

add_para('Acuut toxische stoffen (H300-H331, ADR 6.1 VG I/II):', bold=True)
add_para('• Uitsluitend in UN-gekeurde verpakkingen [M49]\n• Opslaghoogte max. 1,80 m [M49]\n• Apart brandcompartiment of 5 m vrije zone [M49]\n• Lekbak met monsternamepunt [M59]')

add_para('Tijdelijke opslag (§7.6.2):', bold=True)
add_para('• Drie categorieën: max. 10.000 kg; max. 10.000 kg met deskundig toezicht; max. 30.000 kg met deskundig toezicht [M109–M115]\n• Alleen deel basisveiligheidsniveau-maatregelen van toepassing')

add_para('(Tank)containers:', bold=True)
add_para('• Neerleggen tijdens transport en opslag lege ongereinigd: M47 (ingangscontrole), M52 (weerbestendige verpakking)\n• Stationaire opslag in (tank)container: eisen reguliere opslagvoorziening')

doc.add_heading('2.3 Informatievoorziening hulpdiensten (M116, M117)', level=2)
add_para('Bij opslag >2.500 kg: controleer de informatievoorziening:')
add_para('• M116: Plattegrond conform NEN 1414-1 + stoffenlijst bij aankomst beschikbaar?\n• M117: Binnen 30 min na aankomst hulpdienst beschikbaar: vervoersnaam, chemische naam, ADR-klasse, UN-nummer, GEVI-nummer, actuele hoeveelheid, VG, CMR/CLP, MSDS?\n• M118: Wijze van beschikbaarstellen vastgelegd?\n• Deskundig persoon beschikbaar (telefonisch toegestaan bij niet-continubedrijven)?\n• Niet van toepassing op brandveiligheidsopslagkasten')
add_para('Opmerking: De oude "journaalverplichting" is in PGS 15:2025 vervangen door gegevensbeschikbaarheid (M116/M117).', italic=True)

doc.add_heading('2.4 Foto\'s maken', level=2)
add_para('• Buitenzijde opslagvoorzieningen (overzicht + details signalering)\n• Binnenzijde (overzicht + vakindeling)\n• Productopvang (detail)\n• Compartimentering\n• Etikettering (correct + afwijkend)\n• Brandbeveiligingsinstallaties\n• PV-installatie op dak (indien aanwezig)\n• Afwijkingen (altijd met contextfoto)\n• Minimaal 30 foto\'s per auditlocatie')

doc.add_heading('2.5 Documenten inzien op locatie', level=2)
add_para('• Informatievoorziening hulpdiensten (M116/M117): actualiteit, volledigheid, toegankelijkheid\n• Intern noodplan (M113): actualiteit, beproefd, telefoonnummerslijst\n• Vakbekwaamheidscertificaten: geldigheid\n• Inspectierapporten brandbeveiliging (M99): datum, bevindingen opgevolgd?\n• Onderhoudslogboeken (M45)')
doc.add_page_break()

# ===== FASE 3 =====
doc.add_heading('Fase 3: Toetsing', level=1)

doc.add_heading('3.1 Hoe de checklist te gebruiken', level=2)
add_para('Gebruik de PGS-15 Audit Checklist (document 3) als leidraad. Per controlepunt:\n• Lees de toetsvraag\n• Raadpleeg de maatregelverwijzing in PGS 15:2025 (§7)\n• Bepaal het antwoord: Conform / Afwijking / Kritieke afwijking / Niet van toepassing\n• Documenteer bevindingen\n• Verwijs naar foto\'s')

doc.add_heading('3.2 Per sectie: waar specifiek op letten', level=2)

secties = [
    ('Sectie 1 — Werkingssfeer (§1.2)', 'Klopt de inventarisatie? Alle ADR-klassen en CMR/CLP-stoffen meegenomen? Uitsluitingen correct?'),
    ('Sectie 2 — Ondergrenzen (§1.2.1, Tabel 2)', 'Ondergrens correct berekend? LQ/EQ-vrijstelling correct? Bijkomende gevaren meegewogen?'),
    ('Sectie 3 — Werkvoorraad (M14)', 'Enkel voor bedrijfsvoering noodzakelijke stoffen? Of "verkapte opslag"?'),
    ('Sectie 4 — Opslagvoorzieningen (M2, M3, M21)', 'Binnen- vs buitenopslag correct? WBDBO conform (60/90 min)? Afstanden conform (15 m)? PV-installatie toestemming?'),
    ('Sectie 5 — Productopvang (M35, M36)', 'Opvangvoorziening aanwezig, intact, capaciteit correct (110%/10%)? Monsternamepunt bij acuut toxische stoffen (M59)?'),
    ('Sectie 6 — Compartimentering (Bijlage E)', 'Onverenigbare combinaties gescheiden? Vakscheiding fysiek aanwezig? Acuut toxische stoffen apart (M49)?'),
    ('Sectie 7 — Veiligheidsniveaus (M3, Tabel 6)', 'Veiligheidsniveau correct bepaald? Maatregelen correct gefilterd op categorie?'),
    ('Sectie 8 — Brandbeveiliging (M96, M97, M99)', 'VBB aanwezig bij Veiligheidsniveau A? UPD goedgekeurd? Jaarlijkse inspectie? Bedrijfsbrandweer (M97)?'),
    ('Sectie 9 — Informatievoorziening (M116, M117)', 'Plattegrond conform NEN 1414-1? Stoffenlijst bij aankomst beschikbaar? 30-min eis haalbaar? Deskundig persoon bereikbaar?'),
    ('Sectie 10 — Noodplan (M113)', 'Noodplan aanwezig en actueel? Beproefd? Telefoonnummerslijst actueel?'),
    ('Sectie 11 — Veiligheidssignalering (M135)', 'Gevaarsidentificatiesymbolen conform ADR art. 5.2 aanwezig aan buitenzijde?'),
    ('Sectie 12 — Gasflessen (M7, M8, M54–M56)', 'Binnenopslag correct (≤250 l kast, >250 l dedicated)? Kelder VERBODEN? Max 2 kasten/BC? Afstand 15 m?'),
    ('Sectie 13 — Verdiepingsopslag (M8)', 'Max 2.500 kg/l 1e verdieping? Max 500 kg/l kelder/hoger? Gasflessen kelder VERBODEN?'),
    ('Sectie 14 — Tijdelijke opslag (§7.6.2)', 'Categorie correct? Alleen basisniveau-maatregelen? Max. hoeveelheden gerespecteerd?'),
    ('Sectie 15 — Onderhoud & keuring (M45, M46)', 'Onderhoudsprocedure aanwezig? Periodieke keuringen uitgevoerd? Ingangscontrole (M45)?'),
    ('Sectie 16 — Gelijkwaardigheid (§8)', 'Alternatieve maatregelen schriftelijk onderbouwd en goedgekeurd?'),
]
for title, content in secties:
    add_para(title, bold=True)
    add_para(content)
doc.add_paragraph()

doc.add_heading('3.3 Veelvoorkomende afwijkingen', level=2)
add_table(
    ['Nr.', 'Afwijking', 'Hoe te herkennen', 'Maatregel'],
    [
        ['1', 'Ontbrekende etikettering', 'Verpakkingen zonder ADR/CLP-etiket, vooral omgepakte kleinverpakkingen', 'M48'],
        ['2', 'Onvoldoende productopvang', 'Opvangbak ontbreekt, volgelopen, of capaciteit onvoldoende', 'M35, M36'],
        ['3', 'Verkeerde compartimentering', 'Onverenigbare stoffen inzelfde vak (bijv. klasse 3 + 5.1)', 'Bijlage E, M42'],
        ['4', 'Werkvoorraad als verkapte opslag', 'Meerdere ongeopende verpakkingen op werkvloer', 'M14'],
        ['5', 'Informatievoorziening onvolledig', 'Stoffenlijst niet actueel, ontbrekende UN-nummers, geen 30-min capaciteit', 'M116, M117'],
        ['6', 'Vakbekwaamheid niet aangetoond', 'Geen certificaten beschikbaar', 'M104'],
        ['7', 'Veiligheidssignalering ontbreekt', 'Geen gevaarsymbolen aan buitenzijde', 'M135'],
        ['8', 'Noodplan verouderd', 'Niet geëvalueerd of niet aangepast na wijzigingen', 'M113'],
        ['9', 'Opslag in vluchtroute', 'Gevaarlijke stoffen in gangen, trappenhuizen', 'M4'],
        ['10', 'Gasflessen in kelder', 'Verboden opslag', 'M8'],
        ['11', 'PV-installatie zonder toestemming', 'Zonnepanelen op opslagdak zonder goedkeuring', 'M21'],
        ['12', 'WBDBO onvoldoende', 'Brandwerendheid <60 min bij opslag >ondergrens', 'M21, M24'],
    ]
)
doc.add_paragraph()

doc.add_heading('3.4 Grijze gebieden', level=2)
add_para('• Gelijkwaardigheidsbeginsel (§8): Eis schriftelijke onderbouwing en goedkeuring door bevoegd gezag\n• Werkvoorraad vs opslag (M14): Documenteer hoeveelheden, gebruikspatroon, opslagduur\n• Stoffen zonder duidelijke ADR-classificatie: Raadpleeg SDS, documenteer als open punt\n• Interpretatieverschillen: Verwijs naar exacte tekst PGS 15:2025, markeer als "Ter beoordeling bevoegd gezag"')
doc.add_page_break()

# ===== FASE 4 =====
doc.add_heading('Fase 4: Rapportage', level=1)

doc.add_heading('4.1 Bevindingen formuleren (STAR-principe)', level=2)
add_para('• Situatie: Wat is de aangetroffen situatie?\n• Toetsing: Welke maatregel uit PGS 15:2025 is van toepassing? (M-nummer verplicht)\n• Afwijking: Waarin wijkt de situatie af?\n• Risico: Welk risico vormt de afwijking?')
add_para('Voorbeeld:', bold=True)
add_para('"De opslagvoorziening aan de noordzijde bevat 3.200 kg brandbare vloeistoffen (ADR-klasse 3, VG II). Volgens Tabel 6 in M3 geldt Veiligheidsniveau A met WBDBO 60 min. De wanden bestaan uit gipsplaat zonder brandwerende bekleding, wat naar schatting <15 min weerstand biedt. Risico: bij brand is snelle branduitbreking naar aangrenzende ruimten waarschijnlijk."', italic=True)

doc.add_heading('4.2 Classificatie', level=2)
add_table(
    ['Classificatie', 'Omschrijving', 'Actie'],
    [
        ['CONFORM', 'Voldoet aan de maatregel', 'Geen actie vereist'],
        ['AFWIJKING', 'Wijkt af, geen direct gevaar', 'Herstel binnen 3-6 maanden'],
        ['KRITIEK', 'Wijkt af, direct/potentieel gevaar', 'Direct mitigerende maatregelen; herstel 2-4 weken'],
        ['N.v.t.', 'Maatregel niet van toepassing', 'Geen actie'],
    ]
)
doc.add_paragraph()

doc.add_heading('4.3 Aanbevelingen formuleren', level=2)
add_para('• Specifiek: Wat moet er gebeuren?\n• Toegespitst: Wie is verantwoordelijk?\n• Tijdgebonden: Binnen welke termijn?\n• Verwijzend: Naar welk PGS 15:2025-maatregelnummer?')

doc.add_heading('4.4 Opvolging en termijnen', level=2)
add_para('• Kritieke afwijkingen: direct (24-48 uur) mitigerende maatregelen; definitief herstel 2-4 weken\n• Afwijkingen: herstel 3-6 maanden\n• Aanbevelingen: opvolging bij volgende periodieke audit\n• Follow-up audit plannen')

doc.add_page_break()

# ===== COLOFON =====
add_para('COLOFON', bold=True, italic=True)
add_para('Bronvermelding: PGS 15:2025 versie 1.0 (januari 2025), Publicatiereeks Gevaarlijke Stoffen.')
add_para('Vastgesteld door: Bestuurlijk Omgevingsberaar (BOb), 16 januari 2025.')
add_para('URL: https://publicatiereeksgevaarlijkestoffen.nl/publicaties/online/pgs-15/2025/1-0-januari-2025')
add_para('Versie: 2.0 | Samengesteld april 2026.')
add_para('Dit document is bedoeld als werkinstructie voor auditors en vervangt niet de originele PGS 15:2025-publicatie.', italic=True)

output_path = '/root/projects/jg/2026-pgs15-audit-toolkit/deliverables/docx/PGS15_Audit_Procedure_v2.0.docx'
doc.save(output_path)
print(f"DOCX saved to: {output_path}")
