Re-Add Number / Key

This commit is contained in:
Frederik Beimgraben 2025-08-31 18:02:28 +02:00
parent 34589826e5
commit f63fbeeffd
2 changed files with 48 additions and 13 deletions

View File

@ -9,7 +9,19 @@ _PLACEHOLDER_VALUES: set = {None, "", "-", "JJJJ-MM", "/\\Fld@default "}
# --- COMMON fields (shared across variants) --- # --- COMMON fields (shared across variants) ---
TEXT_MAPPING_COMMON: dict = { TEXT_MAPPING_COMMON: dict = {
# Applicant # --- Meta ---
'pa-id': {
'required': True,
'target-key': 'pa.meta.id',
'type': str,
},
'pa-key': {
'required': True,
'target-key': 'pa.meta.key',
'type': str,
},
# --- Applicant ---
'pa-applicant-type': { 'pa-applicant-type': {
'required': True, 'required': True,
'target-key': 'pa.applicant.type', 'target-key': 'pa.applicant.type',
@ -56,14 +68,14 @@ TEXT_MAPPING_COMMON: dict = {
] ]
}, },
# Project core # --- Project core ---
'pa-project-name': {'required': True, 'target-key': 'pa.project.name', 'type': str}, 'pa-project-name': {'required': True, 'target-key': 'pa.project.name', 'type': str},
'pa-start-date': {'required': True, 'target-key': 'pa.project.dates.start', 'type': str}, 'pa-start-date': {'required': True, 'target-key': 'pa.project.dates.start', 'type': str},
'pa-end-date': {'required': False, 'target-key': 'pa.project.dates.end', 'type': str}, 'pa-end-date': {'required': False, 'target-key': 'pa.project.dates.end', 'type': str},
'pa-participants': {'required': False, 'target-key': 'pa.project.participants', 'type': int}, 'pa-participants': {'required': False, 'target-key': 'pa.project.participants', 'type': int},
'pa-project-description': {'required': True, 'target-key': 'pa.project.description', 'type': str}, 'pa-project-description': {'required': True, 'target-key': 'pa.project.description', 'type': str},
# Participation (checkboxes) # --- Participation (checkboxes) ---
'pa-participating-faculties-inf': {'required': False, 'target-key': 'pa.project.participation.faculties.inf', 'type': bool}, 'pa-participating-faculties-inf': {'required': False, 'target-key': 'pa.project.participation.faculties.inf', 'type': bool},
'pa-participating-faculties-esb': {'required': False, 'target-key': 'pa.project.participation.faculties.esb', 'type': bool}, 'pa-participating-faculties-esb': {'required': False, 'target-key': 'pa.project.participation.faculties.esb', 'type': bool},
'pa-participating-faculties-ls': {'required': False, 'target-key': 'pa.project.participation.faculties.ls', 'type': bool}, 'pa-participating-faculties-ls': {'required': False, 'target-key': 'pa.project.participation.faculties.ls', 'type': bool},
@ -72,15 +84,15 @@ TEXT_MAPPING_COMMON: dict = {
'pa-participating-faculties-nxt': {'required': False, 'target-key': 'pa.project.participation.faculties.nxt', 'type': bool}, 'pa-participating-faculties-nxt': {'required': False, 'target-key': 'pa.project.participation.faculties.nxt', 'type': bool},
'pa-participating-faculties-open': {'required': False, 'target-key': 'pa.project.participation.faculties.open', 'type': bool}, 'pa-participating-faculties-open': {'required': False, 'target-key': 'pa.project.participation.faculties.open', 'type': bool},
# Costs & totals # --- Costs & totals ---
'pa-cost-{a;1:24}-name': {'required': True, 'target-key': 'pa.project.costs[{a}].name', 'type': str}, 'pa-cost-{a;1:24}-name': {'required': True, 'target-key': 'pa.project.costs[{a}].name', 'type': str},
'pa-cost-{a;1:24}-amount-euro': {'required': True, 'target-key': 'pa.project.costs[{a}].amountEur', 'type': float}, 'pa-cost-{a;1:24}-amount-euro': {'required': True, 'target-key': 'pa.project.costs[{a}].amountEur', 'type': float},
'pa-requested-amount-euro-sum': {'required': True, 'target-key': 'pa.project.totals.requestedAmountEur', 'type': float}, 'pa-requested-amount-euro-sum': {'required': True, 'target-key': 'pa.project.totals.requestedAmountEur', 'type': float},
# Attachments common # --- Attachments common ---
'pa-anh-vergleichsangebote': {'required': False, 'target-key': 'pa.attachments.comparativeOffers', 'type': bool}, 'pa-anh-vergleichsangebote': {'required': False, 'target-key': 'pa.attachments.comparativeOffers', 'type': bool},
# Misc # --- Misc ---
'warning-not-supported': {'required': False, 'target-key': 'warning.notSupported', 'type': str}, 'warning-not-supported': {'required': False, 'target-key': 'warning.notSupported', 'type': str},
} }

View File

@ -17,7 +17,7 @@ import json
import re import re
from argparse import ArgumentParser from argparse import ArgumentParser
from dataclasses import dataclass, asdict, field from dataclasses import dataclass, asdict, field
from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple, Union from typing import Any, Dict, Iterable, List, Mapping, Optional, Tuple
import PyPDF2 import PyPDF2
from pdf_field_mapping import ( from pdf_field_mapping import (
@ -31,6 +31,11 @@ from pdf_field_mapping import (
# Types / Data Model # Types / Data Model
# ========================= # =========================
@dataclass
class Meta:
id: Optional[str] = None
key: Optional[str] = None
@dataclass @dataclass
class Name: class Name:
first: Optional[str] = None first: Optional[str] = None
@ -133,7 +138,11 @@ class WarningInfo:
@dataclass @dataclass
class RootPayload: class RootPayload:
pa: Any = field(default_factory=dict) # will hold applicant + project + attachments pa: Dict[str, Any] = field(default_factory=dict) # kompatibel für Dump
applicant: Applicant = field(default_factory=Applicant)
project: Project = field(default_factory=Project)
attachments: Attachments = field(default_factory=Attachments)
meta: Meta = field(default_factory=Meta)
warning: WarningInfo = field(default_factory=WarningInfo) warning: WarningInfo = field(default_factory=WarningInfo)
_validation: Dict[str, Any] = field(default_factory=dict) _validation: Dict[str, Any] = field(default_factory=dict)
@ -338,6 +347,13 @@ def _get(d: Mapping[str, Any], path: str, default=None):
return curr return curr
def payload_to_model(payload: Dict[str, Any]) -> RootPayload: def payload_to_model(payload: Dict[str, Any]) -> RootPayload:
# Meta
meta_dict = _get(payload, "pa.meta", {}) or {}
meta = Meta(
id=meta_dict.get("id"),
key=meta_dict.get("key"),
)
# Build Applicant # Build Applicant
applicant_dict = _get(payload, "pa.applicant", {}) or {} applicant_dict = _get(payload, "pa.applicant", {}) or {}
applicant = Applicant( applicant = Applicant(
@ -427,14 +443,21 @@ def payload_to_model(payload: Dict[str, Any]) -> RootPayload:
warning = WarningInfo(notSupported=warning_dict.get("notSupported")) warning = WarningInfo(notSupported=warning_dict.get("notSupported"))
root = RootPayload( root = RootPayload(
pa={ applicant=applicant,
"applicant": asdict(applicant), project=project,
"project": asdict(project), attachments=attachments,
"attachments": asdict(attachments), meta=meta,
},
warning=warning, warning=warning,
_validation=payload.get("_validation", {}), _validation=payload.get("_validation", {}),
) )
# Für JSON-Kompatibilität auch pa zusammenbauen
root.pa = {
"meta": asdict(meta),
"applicant": asdict(applicant),
"project": asdict(project),
"attachments": asdict(attachments),
}
return root return root