Fix AUTO detection

This commit is contained in:
Frederik Beimgraben 2025-09-01 02:21:09 +02:00
parent c40198c906
commit 6772e3d8f6
7 changed files with 121 additions and 82 deletions

View File

@ -776,25 +776,7 @@ const ApplicationForm: React.FC<ApplicationFormProps> = ({
}
/>
}
label="Es handelt sich um Stellenfinanzierungen"
required
/>
<FormControlLabel
control={
<Checkbox
checked={formData.qsmFlags?.studierende || false}
onChange={(e) =>
setFormData((prev: any) => ({
...prev,
qsmFlags: {
...prev.qsmFlags,
studierende: e.target.checked,
},
}))
}
/>
}
label="Die Studierenden werden an der Planung und Durchführung der Maßnahme beteiligt"
label="Es sind keine unbefristeten Stellenfinanzierungen enthalten"
required
/>
<FormControlLabel
@ -830,7 +812,7 @@ const ApplicationForm: React.FC<ApplicationFormProps> = ({
}
/>
}
label="Die beantragte Exkursion wurde von den zuständigen Stellen genehmigt"
label="Die Exkursion wurde von der Fakultät genehmigt (*)"
/>
<FormControlLabel
control={
@ -847,50 +829,12 @@ const ApplicationForm: React.FC<ApplicationFormProps> = ({
}
/>
}
label="Die Exkursion wird bereits aus anderen Mitteln bezuschusst"
label="Die Exkursion wird bereits aus anderen Mitteln bezuschusst (*)"
/>
</FormGroup>
</Paper>
)}
{/* Anhänge Section */}
<Paper variant="outlined" sx={{ p: 3, mb: 3 }}>
<Typography
variant="h6"
gutterBottom
sx={{ borderBottom: 1, borderColor: "divider", pb: 1, mb: 2 }}
>
Anhänge
</Typography>
<FormGroup>
<FormControlLabel
control={
<Checkbox
checked={formData.comparativeOffers || false}
onChange={(e) =>
handleChange("comparativeOffers", e.target.checked)
}
/>
}
label="Vergleichsangebote liegen bei"
/>
{variant === "QSM" && (
<FormControlLabel
control={
<Checkbox
checked={formData.fakultaet || false}
onChange={(e) =>
handleChange("fakultaet", e.target.checked)
}
/>
}
label="Die Fakultät ist über den Antrag informiert"
required
/>
)}
</FormGroup>
</Paper>
{/* Kostenpositionen Section */}
<Paper variant="outlined" sx={{ p: 3, mb: 3 }}>
<Typography

View File

@ -319,14 +319,36 @@ const AdminApplicationView: React.FC = () => {
<Typography variant="subtitle2" color="text.secondary">
E-Mail
</Typography>
<Typography variant="body1">{formData.email}</Typography>
<Typography variant="body1">
{formData.email ? (
<a
href={`mailto:${formData.email}`}
style={{ color: "inherit" }}
>
{formData.email}
</a>
) : (
"-"
)}
</Typography>
</Grid>
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="text.secondary">
Telefon
</Typography>
<Typography variant="body1">{formData.phone || "-"}</Typography>
<Typography variant="body1">
{formData.phone ? (
<a
href={`tel:${formData.phone}`}
style={{ color: "inherit" }}
>
{formData.phone}
</a>
) : (
"-"
)}
</Typography>
</Grid>
<Grid item xs={12} sm={6}>
@ -428,12 +450,21 @@ const AdminApplicationView: React.FC = () => {
: "Erfüllte Aufgabe der VS nach §65 des Landeshochschulgesetzes"}
</Typography>
<Typography variant="body1">
{currentApplication.variant === "QSM" && formData.qsmFinancing
? QSM_FINANCING_LABELS[formData.qsmFinancing] ||
{currentApplication.variant === "QSM" &&
(formData.financingCode || formData.qsmFinancing)
? QSM_FINANCING_LABELS[
(formData.financingCode ||
formData.qsmFinancing) as keyof typeof QSM_FINANCING_LABELS
] ||
formData.financingCode ||
formData.qsmFinancing
: currentApplication.variant === "VSM" &&
formData.vsmFinancing
? VSM_FINANCING_LABELS[formData.vsmFinancing] ||
(formData.financingCode || formData.vsmFinancing)
? VSM_FINANCING_LABELS[
(formData.financingCode ||
formData.vsmFinancing) as keyof typeof VSM_FINANCING_LABELS
] ||
formData.financingCode ||
formData.vsmFinancing
: "-"}
</Typography>

View File

@ -282,6 +282,24 @@ const ViewApplicationPage: React.FC = () => {
</Typography>
</Grid>
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="text.secondary">
Telefon
</Typography>
<Typography variant="body1">
{formData.phone ? (
<a
href={`tel:${formData.phone}`}
style={{ color: "inherit" }}
>
{formData.phone}
</a>
) : (
"-"
)}
</Typography>
</Grid>
<Grid item xs={12} sm={6}>
<Typography variant="subtitle2" color="text.secondary">
Institution
@ -370,16 +388,25 @@ const ViewApplicationPage: React.FC = () => {
<Paper sx={{ p: 3, mb: 3 }}>
<Typography variant="h6" gutterBottom>
{currentApplication.variant === "QSM"
? "Erfüllte Aufgabe der QSM"
? "Erfüllte Aufgabe nach VWV zur Verwendung von QS-Mitteln"
: "Erfüllte Aufgabe der VS nach §65 des Landeshochschulgesetzes"}
</Typography>
<Typography variant="body1">
{currentApplication.variant === "QSM" && formData.qsmFinancing
? QSM_FINANCING_LABELS[formData.qsmFinancing] ||
{currentApplication.variant === "QSM" &&
(formData.financingCode || formData.qsmFinancing)
? QSM_FINANCING_LABELS[
(formData.financingCode ||
formData.qsmFinancing) as keyof typeof QSM_FINANCING_LABELS
] ||
formData.financingCode ||
formData.qsmFinancing
: currentApplication.variant === "VSM" &&
formData.vsmFinancing
? VSM_FINANCING_LABELS[formData.vsmFinancing] ||
(formData.financingCode || formData.vsmFinancing)
? VSM_FINANCING_LABELS[
(formData.financingCode ||
formData.vsmFinancing) as keyof typeof VSM_FINANCING_LABELS
] ||
formData.financingCode ||
formData.vsmFinancing
: "-"}
</Typography>

View File

@ -1198,8 +1198,12 @@ function createFormJsonFromData(formData: Partial<FormData>): string {
}
// Add variant-specific fields
if (formData.variant === "QSM" && formData.qsmFinancing) {
formJson["pa-qsm-financing"] = { "/V": formData.qsmFinancing };
if (formData.variant === "QSM") {
if (formData.financingCode || formData.qsmFinancing) {
formJson["pa-qsm-financing"] = {
"/V": formData.financingCode || formData.qsmFinancing,
};
}
if (formData.qsmFlags) {
formJson["pa-qsm-stellenfinanzierungen"] = {
"/V": formData.qsmFlags.stellenfinanzierungen,
@ -1213,14 +1217,28 @@ function createFormJsonFromData(formData: Partial<FormData>): string {
"/V": formData.qsmFlags.exkursionBezuschusst,
};
}
} else if (formData.variant === "VSM" && formData.vsmFinancing) {
formJson["pa-vsm-financing"] = { "/V": formData.vsmFinancing };
} else if (formData.variant === "VSM") {
if (formData.financingCode || formData.vsmFinancing) {
formJson["pa-vsm-financing"] = {
"/V": formData.financingCode || formData.vsmFinancing,
};
}
if (formData.vsmFlags) {
formJson["pa-vsm-aufgaben"] = { "/V": formData.vsmFlags.aufgaben };
formJson["pa-vsm-individuell"] = { "/V": formData.vsmFlags.individuell };
}
}
// Add attachments
if (formData.comparativeOffers !== undefined) {
formJson["pa-anh-vergleichsangebote"] = {
"/V": formData.comparativeOffers,
};
}
if (formData.fakultaet !== undefined) {
formJson["pa-anh-fakultaet"] = { "/V": formData.fakultaet };
}
const jsonString = JSON.stringify(formJson);
return btoa(unescape(encodeURIComponent(jsonString))); // Base64 encode with UTF-8 support
}
@ -1258,11 +1276,13 @@ function convertPayloadToFormData(payload: RootPayload): Partial<FormData> {
name: cost.name || "",
amountEur: cost.amountEur || 0,
})),
variant: (pa.project.financing.qsm
? "QSM"
: pa.project.financing.vsm
variant: (pa.project.financing.vsm?.code
? "VSM"
: pa.project.financing.qsm?.code
? "QSM"
: "COMMON") as Variant,
financingCode:
pa.project.financing.qsm?.code || pa.project.financing.vsm?.code || "",
qsmFinancing: pa.project.financing.qsm?.code as any,
qsmFlags: pa.project.financing.qsm?.flags
? {

View File

@ -284,6 +284,7 @@ export interface FormData {
// Financing
variant: Variant;
financingCode?: string;
qsmFinancing?: QSMFinancingCode;
qsmFlags?: {
stellenfinanzierungen: boolean;

View File

@ -155,7 +155,7 @@ def fill_pdf(payload: Dict[str, Any], variant: str, out_path: Optional[str] = No
writer.add_page(p)
# Flatten payload first
mapping = core._merge_mapping(variant)
mapping = core._merge_mapping(variant, {})
flat = _flatten(payload)
# Calculate total amount from costs

View File

@ -239,8 +239,23 @@ def _set_nested(root: Dict[str, Any], dotted: str, value: Any) -> None:
curr[part] = {}
curr = curr[part]
def _merge_mapping(variant: str) -> Dict[str, Dict[str, Any]]:
def _detect_best_mapping(form_fields: Mapping[str, Any]) -> str:
# Implement logic to detect best mapping based on form fields
# Example: Check for specific field names or patterns
# Return "QSM", "VSM", or "COMMON" based on the detection
if "pa-qsm-financing" in form_fields:
return "QSM"
if "pa-vsm-financing" in form_fields:
return "VSM"
return "COMMON"
def _merge_mapping(variant: str, form_fields: Mapping[str, Any]) -> Dict[str, Dict[str, Any]]:
v = (variant or "").strip().upper()
if v == "AUTO":
# Find best mapping based on form fields
return _merge_mapping(_detect_best_mapping(form_fields), form_fields)
if v == "QSM":
return {**TEXT_MAPPING_COMMON, **TEXT_MAPPING_QSM}
if v == "VSM":
@ -259,13 +274,14 @@ def detect_variant(form_fields: Mapping[str, Any]) -> str:
return "VSM"
return "COMMON"
def map_form_to_payload(form_json: Dict[str, Dict[str, Any]], variant: str) -> Dict[str, Any]:
"""
Map PDF-like form JSON (fieldName -> dict with '/V', etc.) to nested payload
using TEXT_MAPPING_* dicts. Unknown/empty fields are skipped.
"""
mapping = _merge_mapping(variant)
form_fields = form_json.keys()
mapping = _merge_mapping(variant, form_fields)
out: Dict[str, Any] = {}
# Pre-collect costs