Merge lane/import in feature/craftvia-mvp

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 12:22:07 +02:00
co-authored by Claude Opus 5
38 changed files with 4204 additions and 4 deletions
+209
View File
@@ -0,0 +1,209 @@
{
"crumb": "Aufträge",
"title": "Auftragsimport",
"sub": "Auftragsbestätigung hochladen, erkannte Daten prüfen und den Auftrag anlegen. Ohne Bestätigung entsteht kein Auftrag.",
"noPermission": "Für den Auftragsimport fehlt die Berechtigung.",
"upload": {
"title": "Dokument hochladen",
"drop": "PDF, JPG oder PNG hierher ziehen",
"or": "oder",
"choose": "Datei auswählen",
"limits": "PDF bis 25 MB, Bilder bis 15 MB. Das Original bleibt am Auftrag gespeichert.",
"uploading": "Wird hochgeladen … {percent} %",
"done": "Hochgeladen. Daten werden erkannt.",
"errors": {
"file_type_not_allowed": "Dateityp nicht erlaubt. Erlaubt sind PDF, JPG und PNG.",
"file_too_large": "Datei ist zu groß.",
"file_type_mismatch": "Dateiinhalt passt nicht zum Dateityp.",
"file_empty": "Datei ist leer.",
"file_missing": "Keine Datei ausgewählt.",
"forbidden": "Keine Berechtigung.",
"unauthorized": "Sitzung abgelaufen. Bitte neu anmelden.",
"network": "Hochladen fehlgeschlagen. Verbindung prüfen.",
"error": "Hochladen fehlgeschlagen."
}
},
"list": {
"title": "Importe",
"empty": "Noch keine Importe. Laden Sie eine Auftragsbestätigung hoch.",
"file": "Datei",
"uploadedAt": "Hochgeladen",
"uploadedBy": "Von",
"status": "Status",
"action": "Aktion",
"review": "Prüfen",
"open": "Ansehen",
"workOrder": "Auftrag {number}"
},
"status": {
"uploaded": "Hochgeladen",
"processing": "Verarbeitung",
"review_required": "Prüfung erforderlich",
"confirmed": "Bestätigt",
"failed": "Fehlgeschlagen",
"discarded": "Verworfen"
},
"actions": {
"retry": "Neu verarbeiten",
"retrying": "Wird gestartet …",
"discard": "Verwerfen",
"discardConfirm": "Import verwerfen? Es wird kein Auftrag angelegt. Das Originaldokument bleibt gespeichert.",
"confirm": "Bestätigen und Auftrag anlegen",
"confirming": "Auftrag wird angelegt …"
},
"detail": {
"back": "Zurück zu den Importen",
"meta": "{file} · hochgeladen am {date} von {user}",
"model": "Erkannt mit {model}",
"preview": "Originaldokument",
"previewTitle": "Vorschau des Originaldokuments",
"openNewTab": "In neuem Tab öffnen",
"download": "Herunterladen",
"processing": "Das Dokument wird verarbeitet. Die Seite aktualisiert sich automatisch.",
"failed": "Die Verarbeitung ist fehlgeschlagen.",
"failedDetail": "Technischer Hinweis: {message}",
"confirmed": "Import bestätigt. Auftrag {number} wurde angelegt.",
"openWorkOrder": "Auftrag öffnen",
"corrections": "{count, plural, =0 {Keine Korrekturen} one {1 Feld korrigiert} other {# Felder korrigiert}}",
"discarded": "Import verworfen. Es wurde kein Auftrag angelegt.",
"extractedText": "Erkannter Text",
"noText": "Kein Text erkannt."
},
"review": {
"title": "Erkannte Daten prüfen",
"intro": "Unsichere Felder sind markiert. Bitte prüfen und bei Bedarf korrigieren.",
"manualEntry": "Keine automatische Erkennung verfügbar. Bitte Daten manuell erfassen.",
"hintsTitle": "Hinweise zur Plausibilität",
"uncertain": "unsicher",
"confidence": "Sicherheit {percent} %",
"source": "Quelle: {text}",
"required": "Pflichtfeld",
"sections": {
"customer": "Kunde",
"site": "Objekt",
"contact": "Ansprechpartner",
"order": "Auftrag",
"positions": "Positionen und Material"
},
"customer": {
"existing": "Bestehenden Kunden verwenden",
"new": "Neuen Kunden anlegen",
"candidates": "Mögliche Treffer im Kundenstamm",
"noCandidates": "Keine passenden Kunden gefunden.",
"match": "Übereinstimmung {percent} %",
"merge": "Dubletten im Kundenstamm zusammenführen",
"search": "Kunden suchen",
"searchPlaceholder": "Name, Kundennummer oder Ort",
"searchButton": "Suchen",
"searchEmpty": "Keine Kunden gefunden.",
"select": "Auswählen"
},
"site": {
"none": "Kein Objekt zuordnen",
"existing": "Bestehendes Objekt verwenden",
"new": "Neues Objekt anlegen",
"noSites": "Für den gewählten Kunden sind keine Objekte angelegt.",
"chooseCustomer": "Zuerst einen bestehenden Kunden auswählen.",
"suggested": "Gleiche Adresse"
},
"reasons": {
"customer_number": "Kundennummer",
"company_name": "Firmenname",
"company_name_similar": "ähnlicher Firmenname",
"person_name": "Name",
"email": "E-Mail",
"phone": "Telefon",
"address": "Adresse",
"house_number": "Hausnummer",
"site_name": "Objektname"
},
"fields": {
"customerNumber": "Kundennummer",
"companyName": "Firmenname",
"firstName": "Vorname",
"lastName": "Nachname",
"street": "Straße",
"houseNumber": "Hausnummer",
"postalCode": "PLZ",
"city": "Ort",
"country": "Land",
"phone": "Telefon",
"email": "E-Mail",
"name": "Name",
"siteName": "Objektbezeichnung",
"title": "Auftragstitel",
"externalOrderNumber": "Auftragsnummer (Dokument)",
"offerNumber": "Angebotsnummer",
"description": "Leistungsbeschreibung",
"plannedStart": "Geplanter Beginn",
"plannedEnd": "Geplantes Ende",
"notes": "Besondere Hinweise"
},
"extractionFields": {
"orderNumber": "Auftragsnummer",
"offerNumber": "Angebotsnummer",
"customerNumber": "Kundennummer",
"companyName": "Firmenname",
"customerFirstName": "Vorname",
"customerLastName": "Nachname",
"customerAddress": "Kundenadresse",
"siteName": "Objekt",
"siteAddress": "Objektadresse",
"contactName": "Ansprechpartner",
"phone": "Telefon",
"email": "E-Mail",
"orderDate": "Auftragsdatum",
"documentDate": "Dokumentdatum",
"plannedStart": "Geplanter Beginn",
"plannedEnd": "Geplantes Ende",
"title": "Titel",
"description": "Leistungsbeschreibung",
"positions": "Positionen",
"notes": "Hinweise",
"totalAmount": "Gesamtbetrag",
"references": "Referenzen"
},
"hints": {
"date_invalid": "{field}: Datum nicht lesbar.",
"date_implausible": "{field}: Datum liegt ungewöhnlich weit in Vergangenheit oder Zukunft.",
"postal_code_invalid": "{field}: Postleitzahl ist nicht 5-stellig.",
"email_invalid": "{field}: E-Mail-Adresse hat kein gültiges Format.",
"phone_invalid": "{field}: Telefonnummer hat kein gültiges Format.",
"end_before_start": "{field}: Ende liegt vor dem Beginn.",
"manual_entry": "Keine automatische Erkennung verfügbar. Bitte manuell erfassen."
},
"positions": {
"name": "Bezeichnung",
"articleNumber": "Artikelnr.",
"quantity": "Menge",
"unit": "Einheit",
"asMaterial": "als Materialvorgabe übernehmen",
"remove": "Position entfernen",
"add": "Position hinzufügen",
"empty": "Keine Positionen erkannt."
}
},
"errors": {
"form_invalid": "Bitte die markierten Felder prüfen.",
"title_required": "Auftragstitel fehlt.",
"customer_required": "Bitte einen Kunden auswählen.",
"customer_name_required": "Firmenname oder Nachname angeben.",
"site_required": "Bitte ein Objekt auswählen.",
"site_name_required": "Objektbezeichnung oder Straße angeben.",
"site_requires_existing_customer": "Ein bestehendes Objekt setzt einen bestehenden Kunden voraus.",
"email_invalid": "E-Mail-Adresse hat kein gültiges Format.",
"postal_code_invalid": "Postleitzahl muss 5-stellig sein.",
"end_before_start": "Ende liegt vor dem Beginn.",
"date_invalid": "Datum nicht lesbar.",
"quantity_invalid": "Menge muss eine Zahl sein.",
"customer_number_taken": "Diese Kundennummer ist bereits vergeben. Bestehenden Kunden verwenden oder Nummer leeren.",
"import_not_reviewable": "Dieser Import wurde bereits bearbeitet.",
"import_not_discardable": "Dieser Import kann nicht mehr verworfen werden.",
"import_not_retryable": "Nur fehlgeschlagene Importe können neu verarbeitet werden.",
"not_found": "Datensatz nicht gefunden.",
"forbidden": "Keine Berechtigung für diese Aktion.",
"file_unavailable": "Originaldatei ist nicht verfügbar.",
"dispatch_failed": "Verarbeitung konnte nicht gestartet werden.",
"error": "Vorgang nicht möglich."
}
}
+209
View File
@@ -0,0 +1,209 @@
{
"crumb": "Work orders",
"title": "Order import",
"sub": "Upload an order confirmation, check the recognised data and create the work order. Nothing is created without confirmation.",
"noPermission": "You are not allowed to import orders.",
"upload": {
"title": "Upload document",
"drop": "Drop a PDF, JPG or PNG here",
"or": "or",
"choose": "Choose file",
"limits": "PDF up to 25 MB, images up to 15 MB. The original stays attached to the work order.",
"uploading": "Uploading … {percent} %",
"done": "Uploaded. Recognising data.",
"errors": {
"file_type_not_allowed": "File type not allowed. Allowed: PDF, JPG and PNG.",
"file_too_large": "File is too large.",
"file_type_mismatch": "File content does not match its type.",
"file_empty": "File is empty.",
"file_missing": "No file selected.",
"forbidden": "Not allowed.",
"unauthorized": "Session expired. Please sign in again.",
"network": "Upload failed. Check the connection.",
"error": "Upload failed."
}
},
"list": {
"title": "Imports",
"empty": "No imports yet. Upload an order confirmation.",
"file": "File",
"uploadedAt": "Uploaded",
"uploadedBy": "By",
"status": "Status",
"action": "Action",
"review": "Review",
"open": "View",
"workOrder": "Work order {number}"
},
"status": {
"uploaded": "Uploaded",
"processing": "Processing",
"review_required": "Review required",
"confirmed": "Confirmed",
"failed": "Failed",
"discarded": "Discarded"
},
"actions": {
"retry": "Process again",
"retrying": "Starting …",
"discard": "Discard",
"discardConfirm": "Discard this import? No work order will be created. The original document is kept.",
"confirm": "Confirm and create work order",
"confirming": "Creating work order …"
},
"detail": {
"back": "Back to imports",
"meta": "{file} · uploaded on {date} by {user}",
"model": "Recognised with {model}",
"preview": "Original document",
"previewTitle": "Preview of the original document",
"openNewTab": "Open in new tab",
"download": "Download",
"processing": "The document is being processed. This page refreshes automatically.",
"failed": "Processing failed.",
"failedDetail": "Technical detail: {message}",
"confirmed": "Import confirmed. Work order {number} was created.",
"openWorkOrder": "Open work order",
"corrections": "{count, plural, =0 {No corrections} one {1 field corrected} other {# fields corrected}}",
"discarded": "Import discarded. No work order was created.",
"extractedText": "Recognised text",
"noText": "No text recognised."
},
"review": {
"title": "Check recognised data",
"intro": "Uncertain fields are marked. Please check and correct them if needed.",
"manualEntry": "Automatic recognition is not available. Please enter the data manually.",
"hintsTitle": "Plausibility notes",
"uncertain": "uncertain",
"confidence": "Confidence {percent} %",
"source": "Source: {text}",
"required": "Required",
"sections": {
"customer": "Customer",
"site": "Site",
"contact": "Contact person",
"order": "Work order",
"positions": "Line items and material"
},
"customer": {
"existing": "Use existing customer",
"new": "Create new customer",
"candidates": "Possible matches",
"noCandidates": "No matching customers found.",
"match": "Match {percent} %",
"merge": "Merge duplicates in customer records",
"search": "Search customers",
"searchPlaceholder": "Name, customer number or city",
"searchButton": "Search",
"searchEmpty": "No customers found.",
"select": "Select"
},
"site": {
"none": "No site",
"existing": "Use existing site",
"new": "Create new site",
"noSites": "The selected customer has no sites.",
"chooseCustomer": "Select an existing customer first.",
"suggested": "Same address"
},
"reasons": {
"customer_number": "customer number",
"company_name": "company name",
"company_name_similar": "similar company name",
"person_name": "name",
"email": "e-mail",
"phone": "phone",
"address": "address",
"house_number": "house number",
"site_name": "site name"
},
"fields": {
"customerNumber": "Customer number",
"companyName": "Company name",
"firstName": "First name",
"lastName": "Last name",
"street": "Street",
"houseNumber": "House number",
"postalCode": "Postal code",
"city": "City",
"country": "Country",
"phone": "Phone",
"email": "E-mail",
"name": "Name",
"siteName": "Site name",
"title": "Work order title",
"externalOrderNumber": "Order number (document)",
"offerNumber": "Offer number",
"description": "Description of services",
"plannedStart": "Planned start",
"plannedEnd": "Planned end",
"notes": "Special notes"
},
"extractionFields": {
"orderNumber": "Order number",
"offerNumber": "Offer number",
"customerNumber": "Customer number",
"companyName": "Company name",
"customerFirstName": "First name",
"customerLastName": "Last name",
"customerAddress": "Customer address",
"siteName": "Site",
"siteAddress": "Site address",
"contactName": "Contact person",
"phone": "Phone",
"email": "E-mail",
"orderDate": "Order date",
"documentDate": "Document date",
"plannedStart": "Planned start",
"plannedEnd": "Planned end",
"title": "Title",
"description": "Description",
"positions": "Line items",
"notes": "Notes",
"totalAmount": "Total amount",
"references": "References"
},
"hints": {
"date_invalid": "{field}: date not readable.",
"date_implausible": "{field}: date is unusually far in the past or future.",
"postal_code_invalid": "{field}: postal code does not have 5 digits.",
"email_invalid": "{field}: e-mail address format is invalid.",
"phone_invalid": "{field}: phone number format is invalid.",
"end_before_start": "{field}: end is before start.",
"manual_entry": "Automatic recognition is not available. Please enter manually."
},
"positions": {
"name": "Description",
"articleNumber": "Article no.",
"quantity": "Quantity",
"unit": "Unit",
"asMaterial": "use as planned material",
"remove": "Remove line item",
"add": "Add line item",
"empty": "No line items recognised."
}
},
"errors": {
"form_invalid": "Please check the marked fields.",
"title_required": "Work order title is missing.",
"customer_required": "Please select a customer.",
"customer_name_required": "Enter a company name or last name.",
"site_required": "Please select a site.",
"site_name_required": "Enter a site name or street.",
"site_requires_existing_customer": "An existing site requires an existing customer.",
"email_invalid": "E-mail address format is invalid.",
"postal_code_invalid": "Postal code must have 5 digits.",
"end_before_start": "End is before start.",
"date_invalid": "Date not readable.",
"quantity_invalid": "Quantity must be a number.",
"customer_number_taken": "This customer number is already taken. Use the existing customer or clear the number.",
"import_not_reviewable": "This import has already been handled.",
"import_not_discardable": "This import can no longer be discarded.",
"import_not_retryable": "Only failed imports can be processed again.",
"not_found": "Record not found.",
"forbidden": "Not allowed.",
"file_unavailable": "The original file is not available.",
"dispatch_failed": "Processing could not be started.",
"error": "Action not possible."
}
}