mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 17:13:42 +00:00
feat: auto-update fall_id when KVNR is entered on a case
When a KVNR is entered on a case that has a random-suffix or legacy Nachname-based fall_id, the fall_id is automatically rebuilt using the new KVNR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7bbe501bfa
commit
c302a91411
3 changed files with 55 additions and 2 deletions
|
|
@ -24,6 +24,7 @@ from app.schemas.case import (
|
||||||
from app.schemas.disclosure import DisclosureRequestCreate, DisclosureRequestResponse
|
from app.schemas.disclosure import DisclosureRequestCreate, DisclosureRequestResponse
|
||||||
from app.config import get_settings
|
from app.config import get_settings
|
||||||
from app.services.audit_service import log_action
|
from app.services.audit_service import log_action
|
||||||
|
from app.services.import_service import has_random_suffix
|
||||||
from app.services.disclosure_service import (
|
from app.services.disclosure_service import (
|
||||||
create_disclosure_request, has_active_disclosure, has_pending_request,
|
create_disclosure_request, has_active_disclosure, has_pending_request,
|
||||||
)
|
)
|
||||||
|
|
@ -433,6 +434,12 @@ def set_case_kvnr(
|
||||||
old_kvnr = case.kvnr
|
old_kvnr = case.kvnr
|
||||||
new_kvnr = payload.get("kvnr")
|
new_kvnr = payload.get("kvnr")
|
||||||
case.kvnr = new_kvnr
|
case.kvnr = new_kvnr
|
||||||
|
|
||||||
|
# Auto-update fall_id if it currently has a non-KVNR suffix
|
||||||
|
old_fall_id = case.fall_id
|
||||||
|
if new_kvnr and case.fall_id and has_random_suffix(case.fall_id):
|
||||||
|
case.fall_id = f"{case.jahr}-{case.kw:02d}-{case.fallgruppe}-{new_kvnr}"
|
||||||
|
|
||||||
case.updated_by = user.id
|
case.updated_by = user.id
|
||||||
db.commit()
|
db.commit()
|
||||||
db.refresh(case)
|
db.refresh(case)
|
||||||
|
|
@ -443,8 +450,8 @@ def set_case_kvnr(
|
||||||
action="kvnr_updated",
|
action="kvnr_updated",
|
||||||
entity_type="case",
|
entity_type="case",
|
||||||
entity_id=case.id,
|
entity_id=case.id,
|
||||||
old_values={"kvnr": old_kvnr},
|
old_values={"kvnr": old_kvnr, "fall_id": old_fall_id},
|
||||||
new_values={"kvnr": new_kvnr},
|
new_values={"kvnr": new_kvnr, "fall_id": case.fall_id},
|
||||||
ip_address=request.client.host if request.client else None,
|
ip_address=request.client.host if request.client else None,
|
||||||
user_agent=request.headers.get("user-agent"),
|
user_agent=request.headers.get("user-agent"),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ Handles:
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import random
|
import random
|
||||||
|
import re
|
||||||
import string
|
import string
|
||||||
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
@ -41,6 +42,28 @@ def generate_fall_id(parsed: ParsedCase) -> str:
|
||||||
return f"{parsed.jahr}-{parsed.kw:02d}-{parsed.fallgruppe}-{suffix}"
|
return f"{parsed.jahr}-{parsed.kw:02d}-{parsed.fallgruppe}-{suffix}"
|
||||||
|
|
||||||
|
|
||||||
|
# KVNR format: letter followed by 9 digits (e.g. A123456789)
|
||||||
|
KVNR_PATTERN = re.compile(r'^[A-Z]\d{9}$')
|
||||||
|
|
||||||
|
|
||||||
|
def has_random_suffix(fall_id: str | None) -> bool:
|
||||||
|
"""Check if a fall_id ends with a non-KVNR suffix.
|
||||||
|
|
||||||
|
Returns True for random suffixes (6-char alphanumeric) and legacy
|
||||||
|
Nachname-based suffixes. Returns False for KVNR suffixes.
|
||||||
|
"""
|
||||||
|
if not fall_id:
|
||||||
|
return False
|
||||||
|
parts = fall_id.rsplit("-", 1)
|
||||||
|
if len(parts) < 2:
|
||||||
|
return False
|
||||||
|
suffix = parts[1]
|
||||||
|
# If it matches KVNR pattern, it's NOT a random suffix
|
||||||
|
if KVNR_PATTERN.match(suffix):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_duplicate(db: Session, parsed: ParsedCase) -> bool:
|
def check_duplicate(db: Session, parsed: ParsedCase) -> bool:
|
||||||
"""Check if a case already exists in the database.
|
"""Check if a case already exists in the database.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ from app.services.import_service import (
|
||||||
confirm_import,
|
confirm_import,
|
||||||
generate_fall_id,
|
generate_fall_id,
|
||||||
generate_random_suffix,
|
generate_random_suffix,
|
||||||
|
has_random_suffix,
|
||||||
preview_import,
|
preview_import,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -354,3 +355,25 @@ class TestPreviewImportMocked:
|
||||||
assert result.rows[0].row_number == 1
|
assert result.rows[0].row_number == 1
|
||||||
assert result.rows[1].row_number == 2
|
assert result.rows[1].row_number == 2
|
||||||
assert result.rows[2].row_number == 3
|
assert result.rows[2].row_number == 3
|
||||||
|
|
||||||
|
|
||||||
|
# ── has_random_suffix tests ───────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
class TestHasRandomSuffix:
|
||||||
|
def test_kvnr_suffix(self):
|
||||||
|
"""Fall_id with KVNR is NOT random."""
|
||||||
|
assert has_random_suffix("2026-06-onko-A123456789") is False
|
||||||
|
|
||||||
|
def test_random_suffix(self):
|
||||||
|
"""Fall_id with 6-char random suffix IS random."""
|
||||||
|
assert has_random_suffix("2026-06-onko-X7K9M2") is True
|
||||||
|
|
||||||
|
def test_legacy_nachname_suffix(self):
|
||||||
|
"""Fall_id with legacy Nachname suffix IS treated as non-KVNR."""
|
||||||
|
assert has_random_suffix("2020-32-onko-Bartl-Zimmermann") is True
|
||||||
|
assert has_random_suffix("2026-06-kardio-Tonn") is True
|
||||||
|
|
||||||
|
def test_empty_fall_id(self):
|
||||||
|
assert has_random_suffix("") is False
|
||||||
|
assert has_random_suffix(None) is False
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue