From 7c1afca80b4059f0c666f5f1fafd167bca6aae01 Mon Sep 17 00:00:00 2001 From: StyxX65 <150797939+StyxX65@users.noreply.github.com> Date: Tue, 21 Apr 2026 13:12:54 +0200 Subject: [PATCH] Bugfixes fix: select mode onclick exports, multi-source progress counter, OCR page-by-page --- CHANGELOG.md | 8 +- CLAUDE.md | 4 + README.md | 22 +++ VERSION | 2 +- static/js/results.js | 4 + static/js/scan.js | 25 ++- .../local_files/01_cpr_with_context_label.txt | 19 +++ .../local_files/02_cpr_mod11_valid_bare.txt | 15 ++ .../03_cpr_post2007_with_context.txt | 24 +++ .../fixtures/local_files/04_multiple_cprs.txt | 31 ++++ .../local_files/05_student_register.csv | 9 + .../fixtures/local_files/06_employee_list.csv | 6 + .../local_files/07_protected_number.txt | 16 ++ tests/fixtures/local_files/08_mixed_pii.txt | 21 +++ .../fixtures/local_files/09_cpr_in_docx.docx | Bin 0 -> 37143 bytes .../fixtures/local_files/10_clean_no_pii.txt | 25 +++ .../local_files/11_false_positive_invoice.txt | 31 ++++ .../local_files/12_post2007_no_context.txt | 20 +++ .../fixtures/local_files/13_cpr_in_xlsx.xlsx | Bin 0 -> 6281 bytes .../fixtures/local_files/generate_fixtures.py | 154 ++++++++++++++++++ 20 files changed, 425 insertions(+), 11 deletions(-) create mode 100644 tests/fixtures/local_files/01_cpr_with_context_label.txt create mode 100644 tests/fixtures/local_files/02_cpr_mod11_valid_bare.txt create mode 100644 tests/fixtures/local_files/03_cpr_post2007_with_context.txt create mode 100644 tests/fixtures/local_files/04_multiple_cprs.txt create mode 100644 tests/fixtures/local_files/05_student_register.csv create mode 100644 tests/fixtures/local_files/06_employee_list.csv create mode 100644 tests/fixtures/local_files/07_protected_number.txt create mode 100644 tests/fixtures/local_files/08_mixed_pii.txt create mode 100644 tests/fixtures/local_files/09_cpr_in_docx.docx create mode 100644 tests/fixtures/local_files/10_clean_no_pii.txt create mode 100644 tests/fixtures/local_files/11_false_positive_invoice.txt create mode 100644 tests/fixtures/local_files/12_post2007_no_context.txt create mode 100644 tests/fixtures/local_files/13_cpr_in_xlsx.xlsx create mode 100644 tests/fixtures/local_files/generate_fixtures.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d77bbe..9058451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,20 @@ Version numbers follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html --- -## [Unreleased] +## [1.6.21] — 2026-04-20 ### Added +- **Local-file scan test fixtures** — `tests/fixtures/local_files/` contains 13 ready-made files (`.txt`, `.csv`, `.docx`, `.xlsx`) covering every detection scenario: CPR with explicit label, mod-11–valid CPR without label, post-2007 CPR with/without context keyword, protected number (day+40), multiple CPRs in one file, mixed PII (CPR + email + Art. 9 health data), and three true-negative cases (clean content, invoice false-positive, post-2007 serial number without context). All CPR numbers are mathematically valid; false-positive fixtures are verified to produce zero hits. Run `generate_fixtures.py` to regenerate the binary files. + - **Interface PIN** — optional session-level authentication gate for the main scanner interface. Set a 4–8 digit PIN in **Settings → Security → Interface PIN**; anyone reaching `http://host:5100` is redirected to `/login` and must enter the PIN before accessing scan controls, settings, or results. Viewer tokens and the `/view` route are completely unaffected — reviewers continue to use their own auth chain. The PIN is stored as a salted SHA-256 hash in `config.json`. Brute-force protection: 5 failed attempts per IP locks out for 5 minutes. A `POST /api/interface/logout` endpoint clears the session. PIN management via `GET/POST/DELETE /api/interface/pin`. ### Fixed +- **"Vælg" (select mode) button did nothing** — `toggleSelectMode`, `toggleCardSelect`, `selectAllVisible`, and `applyBulkDisposition` were defined inside an ES module but never assigned to `window`, so all `onclick` attributes calling them silently failed. Added the four missing `window.*` exports at the bottom of `results.js`. + +- **Progress counter frozen at M365 total during Google/file scan** — the `scan_progress` handler in `scan.js` only updated `progressStats` and `progressEta` for `source === "m365"`. When M365 finished first, the counter stayed at its final value (e.g. "15083 / 15083 ETA 0s") for the entire duration of the Google and file scans. Fixed in two places: `scan_done` now clears the stats/ETA elements immediately when another scan is still running; `scan_progress` for Google/file sources now shows a running `"X scanned"` count (using the `scanned` field those engines already send) and clears ETA, but only while M365 is not running — M365 stats continue to dominate during concurrent scans. + - **PDF OCR kills process on large files** — `document_scanner` previously called `convert_from_path()` once for the entire PDF before the processing loop, allocating all page images in memory simultaneously. A 50-page A4 PDF at 300 DPI required ~1.3 GB in a single allocation, triggering the OS OOM killer. Fixed by rendering one page at a time with `convert_from_path(first_page=N, last_page=N)` inside the loop across `scan_pdf`, `redact_fitz_pdf`, and `redact_pdf`. Peak OCR memory is now bounded to roughly one page (~26 MB at 300 DPI) regardless of document length. - **No bulk disposition tagging** — each result card had to be opened individually to set a disposition. Added a Select mode (filter bar "Vælg" button) that reveals per-card checkboxes. Selecting one or more items shows a bulk tag bar at the bottom of the grid with a disposition dropdown and Apply button. Calls `POST /api/db/disposition/bulk`; updates all selected items in-memory and clears the selection. "Select all visible" / "Deselect all" toggle available in the bar. Hidden in viewer mode. diff --git a/CLAUDE.md b/CLAUDE.md index 61df833..1ad10d0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -44,6 +44,10 @@ python -m pytest tests/ -q 128 tests in `tests/`. No integration tests for Flask routes or live M365/Google connections. +**Local-file scan fixtures** — `tests/fixtures/local_files/` holds 13 documents for manual/UI-level testing of the file scanner. 10 should be flagged; 3 are true negatives. All CPR numbers verified against `is_valid_cpr`. `generate_fixtures.py` (requires `python-docx` + `openpyxl`, already in venv) regenerates the binary `.docx`/`.xlsx` files. + +**`_CPR_PREFIX_NOISE` in `.docx` fixtures** — `scan_docx` builds a single string by concatenating all run texts with no separators between paragraphs. If a CPR value run is immediately followed by text from the next paragraph without a word boundary, `\b` in `CPR_PATTERN` fails and the number is silently missed. The fixture generator appends a trailing `" "` to every value run so CPRs are always surrounded by word boundaries after concatenation. Do not remove this trailing space — the detection will silently regress. + ## Viewer mode (#33) — routes/viewer.py + static/js/viewer.js Read-only access for DPOs and reviewers. Key invariants: diff --git a/README.md b/README.md index dffa78f..e430e46 100644 --- a/README.md +++ b/README.md @@ -609,6 +609,28 @@ Each new module (`cpr_detector.py`, `app_config.py`, `checkpoint.py`, `gdpr_db.p The test suite should be run before every release and after any change to `document_scanner.py`, `cpr_detector.py`, or `gdpr_db.py`. CPR detection is the legal core of the tool — a false negative means a real GDPR violation goes undetected. +#### Local-file scan fixtures + +`tests/fixtures/local_files/` provides 13 hand-crafted documents for end-to-end testing of the file scanner via the UI or `file_scanner.py`. Drop the folder as a local source and run a scan — all 10 PII-bearing files should be flagged and all 3 negative-case files should produce zero hits. + +| File | Format | Expected | Scenario | +|---|---|---|---| +| `01_cpr_with_context_label.txt` | TXT | Flag | CPR with explicit `CPR-nummer:` label | +| `02_cpr_mod11_valid_bare.txt` | TXT | Flag | mod-11–valid CPR without any context keyword | +| `03_cpr_post2007_with_context.txt` | TXT | Flag | Post-2007 birth (fails mod-11), detected via `Personnummer:` keyword | +| `04_multiple_cprs.txt` | TXT | Flag | 3 distinct CPR numbers in one staff-records file | +| `05_student_register.csv` | CSV | Flag | 8 students incl. one protected-address (day+40) CPR | +| `06_employee_list.csv` | CSV | Flag | 5 employees with CPRs | +| `07_protected_number.txt` | TXT | Flag | Protected CPR (`410172-1200`, day+40 encoding) | +| `08_mixed_pii.txt` | TXT | Flag | CPR + email + phone + GDPR Art. 9 health category | +| `09_cpr_in_docx.docx` | DOCX | Flag | 2 CPRs in a Word document (paragraph format) | +| `10_clean_no_pii.txt` | TXT | **No flag** | Meeting minutes — no personal data | +| `11_false_positive_invoice.txt` | TXT | **No flag** | Invoice: CPR-shaped numbers suppressed by `faktura`/`varenr` context | +| `12_post2007_no_context.txt` | TXT | **No flag** | Equipment serial that looks like a post-2007 CPR but has no context keyword | +| `13_cpr_in_xlsx.xlsx` | XLSX | Flag | Excel workbook with two sheets: students + employees | + +All CPR numbers are mathematically valid (verified against `is_valid_cpr`). Run `generate_fixtures.py` inside the venv to regenerate the `.docx` and `.xlsx` binary files after any changes. + ### Roadmap See [SUGGESTIONS.md](SUGGESTIONS.md) for the full feature roadmap with implementation status. diff --git a/VERSION b/VERSION index c45801e..49e1fe3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.6.20 +1.6.21 diff --git a/static/js/results.js b/static/js/results.js index 17c63c7..11e9dc9 100644 --- a/static/js/results.js +++ b/static/js/results.js @@ -1016,6 +1016,10 @@ window._autoConnectSSEIfRunning = _autoConnectSSEIfRunning; window._loadViewerResults = _loadViewerResults; window.executeBulkDelete = executeBulkDelete; window.applyFilters = applyFilters; +window.toggleSelectMode = toggleSelectMode; +window.toggleCardSelect = toggleCardSelect; +window.selectAllVisible = selectAllVisible; +window.applyBulkDisposition = applyBulkDisposition; window.exportExcel = exportExcel; window.exportArticle30 = exportArticle30; window.clearFilters = clearFilters; diff --git a/static/js/scan.js b/static/js/scan.js index 8831095..deb0411 100644 --- a/static/js/scan.js +++ b/static/js/scan.js @@ -320,16 +320,16 @@ function _attachScanListeners(source) { var fill = document.getElementById('progressFill_' + src); if (fill) fill.style.width = pct + '%'; document.getElementById('progressFile').textContent = d.file || ''; - // Only update stats/ETA from M365 (has meaningful totals and ETA) + var statsEl = document.getElementById('progressStats'); + var etaEl = document.getElementById('progressEta'); if (src === 'm365') { - var statsEl = document.getElementById('progressStats'); - if (statsEl && d.total) { - statsEl.textContent = (d.index || 0) + ' / ' + d.total; - } - var etaEl = document.getElementById('progressEta'); - if (etaEl && d.eta !== undefined) { - etaEl.textContent = d.eta ? ('ETA ' + d.eta) : ''; - } + // M365 sends index + total + ETA — show exact counter + if (statsEl && d.total) statsEl.textContent = (d.index || 0) + ' / ' + d.total; + if (etaEl && d.eta !== undefined) etaEl.textContent = d.eta ? ('ETA ' + d.eta) : ''; + } else if (!S._m365ScanRunning) { + // Google / file: no total known upfront — show running count once M365 is done + if (statsEl && d.scanned !== undefined) statsEl.textContent = d.scanned + ' scanned'; + if (etaEl) etaEl.textContent = ''; } }); source.addEventListener('scan_file', function(e) { @@ -369,6 +369,13 @@ function _attachScanListeners(source) { S._m365ScanRunning = false; _renderProgressSegments(); var _anyRunning = S._googleScanRunning || S._fileScanRunning; + // Clear M365 counter/ETA so Google/file progress can take over the display + if (_anyRunning) { + var _se = document.getElementById('progressStats'); + var _ee = document.getElementById('progressEta'); + if (_se) _se.textContent = ''; + if (_ee) _ee.textContent = ''; + } // Only close SSE once all concurrent scans have finished. // Closing early would drop google_scan_done / file_scan_done events and // leave the UI stuck in scanning state. diff --git a/tests/fixtures/local_files/01_cpr_with_context_label.txt b/tests/fixtures/local_files/01_cpr_with_context_label.txt new file mode 100644 index 0000000..23fb9da --- /dev/null +++ b/tests/fixtures/local_files/01_cpr_with_context_label.txt @@ -0,0 +1,19 @@ +Personoplysninger — Elevakt +=========================== + +Elevens navn: Lars Bjerregaard Nielsen +Klasse: 8B +Skole: Gudenaaskolen + +CPR-nummer: 010172-1019 +Fødselsdato: 1. januar 1972 +Adresse: Skolevej 14, 8680 Ry +Telefon: +45 86 89 12 34 +E-mail: lars.nielsen@privat.dk + +Notater: +Eleven har haft fravær i uge 12 og 14. Forældrene er kontaktet. +Der er afholdt møde den 3. marts 2024 med klasselærer og skoleleder. + +Underskrift: _______________________ +Dato: ___________________ diff --git a/tests/fixtures/local_files/02_cpr_mod11_valid_bare.txt b/tests/fixtures/local_files/02_cpr_mod11_valid_bare.txt new file mode 100644 index 0000000..7f24f9e --- /dev/null +++ b/tests/fixtures/local_files/02_cpr_mod11_valid_bare.txt @@ -0,0 +1,15 @@ +Besøgslog — Sundhedscenter Skanderborg +======================================= + +Dato: 28. april 2024 +Sagsbehandler: M. Andersen + +Borger: Hanne Kirstine Pedersen +Registreringsnummer: 280490-0120 +Henvendelse vedrørende: Sygedagpenge, paragraf 7 opfølgning + +Samtalen fandt sted kl. 10:15 og varede 45 minutter. +Borger mødte op til tiden og var forberedt. + +Aftale om næste møde: 26. maj 2024 kl. 10:00 +Sted: Mødelokale 3, Adelgade 44, 8660 Skanderborg diff --git a/tests/fixtures/local_files/03_cpr_post2007_with_context.txt b/tests/fixtures/local_files/03_cpr_post2007_with_context.txt new file mode 100644 index 0000000..448d4a0 --- /dev/null +++ b/tests/fixtures/local_files/03_cpr_post2007_with_context.txt @@ -0,0 +1,24 @@ +Tilmelding til SFO — Gudenaaskolen +=================================== + +Barnets navn: Emma Sofie Christensen +Personnummer: 150315-4321 +Klasse: 1A (skolestart august 2022) + +Forældrenes oplysninger +----------------------- +Forældrenes navn: Søren og Pia Christensen +Adresse: Birkevej 7, 8680 Ry +Telefon: +45 23 45 67 89 +E-mail: soeren.christensen@familie.dk + +Fremmødetider valgt: + Morgen-SFO: 07:00–08:00 + Eftermiddag: 13:00–17:00 + +Særlige oplysninger til pædagoger: +Emma har en lettere nøddeallergi (jordnødder og cashewnødder). +Kontaktperson ved allergi: Pia Christensen, tlf. 23 45 67 89 + +Dato for tilmelding: 15. marts 2022 +Underskrift: _______________________ diff --git a/tests/fixtures/local_files/04_multiple_cprs.txt b/tests/fixtures/local_files/04_multiple_cprs.txt new file mode 100644 index 0000000..eca88ec --- /dev/null +++ b/tests/fixtures/local_files/04_multiple_cprs.txt @@ -0,0 +1,31 @@ +Personalemappe — Fortroligt +============================ +Afdeling: Administrationen, Skanderborg Kommune + +Medarbejder 1 +------------- +Navn: Christian Bøgh Hansen +CPR: 150365-1102 +Stilling: Skoleleder +Ansættelsesdato: 1. august 2005 +Løngruppe: L4 + +Medarbejder 2 +------------- +Navn: Lise Ravn Johansen +CPR: 020898-0203 +Stilling: Pædagog, fuldtid +Ansættelsesdato: 15. september 2021 +Løngruppe: L2 + +Medarbejder 3 +------------- +Navn: Anders Munk Mortensen +CPR: 010172-1019 +Stilling: Administrativ medarbejder +Ansættelsesdato: 1. marts 2010 +Løngruppe: L3 + +Dokument oprettet: 20. april 2026 +Sidst opdateret: 20. april 2026 +Udarbejdet af: HR-afdelingen diff --git a/tests/fixtures/local_files/05_student_register.csv b/tests/fixtures/local_files/05_student_register.csv new file mode 100644 index 0000000..8913ce6 --- /dev/null +++ b/tests/fixtures/local_files/05_student_register.csv @@ -0,0 +1,9 @@ +Klasse,Navn,CPR-nummer,Adresse,Forælder tlf,Bemærkninger +7A,Magnus Lund Eriksen,010172-1019,Egevej 3 8680 Ry,+45 40 12 34 56, +7A,Nora Bjerrum Nielsen,280490-0120,Møllevej 11 8680 Ry,+45 50 23 45 67,Brillebærer +7A,Oliver Skov Madsen,250372-0100,Kirkegade 2 8660 Skanderborg,+45 60 34 56 78, +7A,Ida Holst Andersen,020898-0203,Skovbrynet 19 8680 Ry,+45 70 45 67 89,Kontaktperson: Far +7B,Rasmus Dal Kristensen,150365-1102,Rosenvej 5 8680 Ry,+45 21 56 78 90, +7B,Sofie Holm Thomsen,111111-1010,Birkevej 22 8660 Skanderborg,+45 31 67 89 01,Allergi: nødder +7B,Emil Sand Jensen,010107-4102,Hybenvej 7 8680 Ry,+45 41 78 90 12, +7B,Laura Bak Møller,410172-1200,Pilevej 4 8660 Skanderborg,+45 51 89 01 23,Beskyttet adresse diff --git a/tests/fixtures/local_files/06_employee_list.csv b/tests/fixtures/local_files/06_employee_list.csv new file mode 100644 index 0000000..ab1d9b5 --- /dev/null +++ b/tests/fixtures/local_files/06_employee_list.csv @@ -0,0 +1,6 @@ +Medarbejder-ID,Navn,Personnummer,Afdeling,Stilling,E-mail,Telefon,Ansættelses-dato +EMP-001,Christian Bøgh Hansen,150365-1102,Ledelse,Skoleleder,c.hansen@gudenaaskolen.dk,+45 86 89 10 01,2005-08-01 +EMP-002,Mette Dahl Andersen,280490-0120,Administration,Sekretær,m.andersen@gudenaaskolen.dk,+45 86 89 10 02,2012-01-15 +EMP-003,Søren Lykke Jakobsen,010172-1019,Pædagogik,Lærer,s.jakobsen@gudenaaskolen.dk,+45 86 89 10 03,2009-08-01 +EMP-004,Hanne Frost Pedersen,250372-0100,Pædagogik,Lærer,h.pedersen@gudenaaskolen.dk,+45 86 89 10 04,2015-08-01 +EMP-005,Lise Ravn Johansen,020898-0203,SFO,Pædagog,l.johansen@gudenaaskolen.dk,+45 86 89 10 05,2021-09-15 diff --git a/tests/fixtures/local_files/07_protected_number.txt b/tests/fixtures/local_files/07_protected_number.txt new file mode 100644 index 0000000..b001c80 --- /dev/null +++ b/tests/fixtures/local_files/07_protected_number.txt @@ -0,0 +1,16 @@ +Fortrolig personoplysning — Navne- og adressebeskyttelse +========================================================== + +VIGTIGT: Denne person har navne- og adressebeskyttelse i CPR-registeret. +Oplysningerne må ikke videregives uden samtykke. + +Navn: Laura Bak Møller +CPR-nummer: 410172-1200 + (Dag + 40 angiver beskyttet adresse) + +Kontaktoplysninger administreres af kommunen. +Henvendelse via: Borgerservice, Skanderborg Kommune +Telefon: 86 52 10 00 + +Dokumentet er klassificeret FORTROLIGT. +Opbevares i aflåst arkiv — ikke i fællesnetværk. diff --git a/tests/fixtures/local_files/08_mixed_pii.txt b/tests/fixtures/local_files/08_mixed_pii.txt new file mode 100644 index 0000000..aa1b9f8 --- /dev/null +++ b/tests/fixtures/local_files/08_mixed_pii.txt @@ -0,0 +1,21 @@ +Lægeerklæring — Helbredsattest +================================ +Udstedt af: Skanderborg Lægepraksis, Adelgade 10, 8660 Skanderborg +Praktiserende læge: Dr. P. Holm + +Patient: Søren Lykke Jakobsen +Fødselsdato / CPR: 010172-1019 +Adresse: Skolevej 22, 8680 Ry +Telefon: +45 22 33 44 55 +E-mail: soeren.jakobsen@privat.dk + +Diagnose (ICD-10): F41.1 — Generaliseret angst +Behandling: Psykoterapi + medicinsk behandling (SSRI) +Særlig kategori: Psykisk lidelse — GDPR Art. 9 + +Erklæringens formål: Sygedagpenge, §7-opfølgning +Periode: 1. april 2026 – 30. juni 2026 + +Lægens underskrift: _______________________ +Dato: 20. april 2026 +Stempel: [Skanderborg Lægepraksis] diff --git a/tests/fixtures/local_files/09_cpr_in_docx.docx b/tests/fixtures/local_files/09_cpr_in_docx.docx new file mode 100644 index 0000000000000000000000000000000000000000..43c66cf7dfb2c2431441f708dd97e1499fe5a873 GIT binary patch literal 37143 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 BO-cX& literal 0 HcmV?d00001 diff --git a/tests/fixtures/local_files/10_clean_no_pii.txt b/tests/fixtures/local_files/10_clean_no_pii.txt new file mode 100644 index 0000000..9990fc0 --- /dev/null +++ b/tests/fixtures/local_files/10_clean_no_pii.txt @@ -0,0 +1,25 @@ +Mødereferat — Pædagogisk råd +============================== +Dato: 20. april 2026 +Sted: Personalerummet, Gudenaaskolen +Ordstyrer: Skolelederen +Referent: Administrationen + +Dagsorden: +1. Godkendelse af referat fra seneste møde +2. Orientering om skoleårets planlægning 2026/2027 +3. Status på inklusion og trivselsundersøgelse +4. Eventuelt + +Ad 1: Referatet fra mødet den 15. marts 2026 blev godkendt uden bemærkninger. + +Ad 2: Skolelederen orienterede om planlægningen for det kommende skoleår. +Skemaerne for 0.-9. klasse offentliggøres i Aula senest 1. juni 2026. +Der er planlagt en fælles pædagogisk dag den 10. august 2026. + +Ad 3: Trivselsundersøgelsen viste generelt gode resultater. +Inklusionsvejlederen præsenterer en handlingsplan på næste møde. + +Ad 4: Intet til eventuelt. + +Næste møde: Tirsdag den 19. maj 2026 kl. 14:00 i personalerummet. diff --git a/tests/fixtures/local_files/11_false_positive_invoice.txt b/tests/fixtures/local_files/11_false_positive_invoice.txt new file mode 100644 index 0000000..93a8d4d --- /dev/null +++ b/tests/fixtures/local_files/11_false_positive_invoice.txt @@ -0,0 +1,31 @@ +FAKTURA +======= +Leverandør: Kontor & Papir A/S + Industriparken 22, 8600 Silkeborg + CVR: 12345678 + +Kunde: Gudenaaskolen + Skolevej 1, 8680 Ry + EAN: 5790001234567 + +Fakturanr: 250372-0100 +Fakturadato: 20. april 2026 +Forfaldsdato: 20. maj 2026 + +Ordrenr: 020898-0203 +Varenr: 150365-1102 + +Linjer: +--------------------------------------------------------------------------- +Beskrivelse Antal Enhedspris Moms Total +--------------------------------------------------------------------------- +Kopipapir A4 80g, pk/500 20 89,00 kr 20% 2.136,00 kr +Blækpatroner HP 305, sort 5 149,00 kr 20% 894,00 kr +Whiteboardmarker, ass. farver 3 49,95 kr 20% 179,82 kr +--------------------------------------------------------------------------- +Subtotal ekskl. moms: 2.561,95 kr +Moms 25%: 640,49 kr +I alt inkl. moms: 3.202,44 kr + +Betalingsbetingelser: Netto 30 dage +Bank: Jyske Bank, Reg. 7600, Konto 1234567 diff --git a/tests/fixtures/local_files/12_post2007_no_context.txt b/tests/fixtures/local_files/12_post2007_no_context.txt new file mode 100644 index 0000000..6b1c79e --- /dev/null +++ b/tests/fixtures/local_files/12_post2007_no_context.txt @@ -0,0 +1,20 @@ +Inventarliste — Klasselokale 7A +================================ +Opdateret: 20. april 2026 +Af: Teknisk servicepersonale + +Rum-ID: 7A-GS-2026 +Lokale: Bygning C, 1. sal + +Inventar: +--------- +Elevborde 32 stk (serienr. påtegnet under bordet) +Elevstole 32 stk (standard, justerbar højde) +Lærerbord 1 stk (inkl. skuff, lås medfølger) +Whiteboard 2 stk (160×120 cm) +Projektor 1 stk (Epson EB-W51, serienr. 150315-4321) +Projektordug 1 stk (180 cm, motor-betjent) +Gardinmotor 2 stk (fjernstyret) + +Næste serviceeftersyn: Oktober 2026 +Ansvarlig: Teknisk afdeling, Skanderborg Kommune diff --git a/tests/fixtures/local_files/13_cpr_in_xlsx.xlsx b/tests/fixtures/local_files/13_cpr_in_xlsx.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7f572163059eb7dc27e3826eba7ec53e8b1cd6cf GIT binary patch literal 6281 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