Schnittstellen

Manueller Adressimport (CSV)

Einfuehrung

Dieses Dokument beschreibt die manuelle Adressimportschnittstelle. Im Gegensatz zu den kVASy Varianten ist sie nicht auf eine spezifische Quellsystem-Spaltenbelegung festgelegt: die Anwender:innen entscheiden selbst, welche Adressattribute sie pflegen wollen, und liefern eine CSV-Datei deren Spaltenkoepfe zu den unterstuetzten Adressattributen passen.

Die Schnittstelle aktualisiert vorhandene Adressen oder legt neue Adressen an. Die Auswahl wird ueber einen strikt priorisierten Update-Schluessel gesteuert; ein Boolescher Hilfsschluessel _create entscheidet, ob bei nicht gefundenem Update-Schluessel eine neue Adresse erzeugt wird.

Zugriff

Die Import Job Definition wird beim Setup automatisch angelegt:

  1. Navigieren Sie zu Schnittstellen → Import-Job-Definition.
  2. Waehlen Sie den Eintrag "Manueller Adressimport".
  3. Laden Sie eine CSV-Datei hoch und nutzen Sie wahlweise Probelauf (Dry-Run) oder Importieren.

Update-Schluessel

Pro Zeile wird genau einer der folgenden Schluessel verwendet, in dieser Reihenfolge:

  1. id
  2. pit_number
  3. hostsystem_reference
  4. pit_number2

Der erste nicht leere Schluessel der Zeile gewinnt — auch wenn weitere Schluesselspalten gefuellt sind.

Verhalten bei nicht gefundenem Update-Schluessel

_createVerhalten
nicht gesetzt oder falseDie Zeile schlaegt mit dem passenden Fehler fehl: ID_UNKNOWN, PIT_NUMBER_UNKNOWN, HOSTSYSTEM_REFERENCE_UNKNOWN oder PIT_NUMBER2_UNKNOWN.
true und Schluessel ist idDie Zeile schlaegt mit ID_UNKNOWN fehl — eine bestehende Datenbank-id darf vom Import nicht erzwungen werden.
true und Schluessel ist pit_number / hostsystem_reference / pit_number2Eine neue Adresse wird angelegt; der Update-Schlusselwert wird auf das gleichnamige Adressattribut geschrieben.

Fehlt jeder Update-Schluessel in einer Zeile, wird der Fehler NO_UPDATE_KEY gemeldet.

Treffen mehrere Adressen auf den Update-Schluessel zu, wird der Fehler UPDATE_KEY_NOT_UNIQUE gemeldet.

Spaltenliste

Der Spaltenkopf der CSV-Datei steuert die Zuordnung der Werte zu Adressattributen. Spaltenkoepfe ausserhalb der folgenden Allowlist fuehren zu unknown_column und dem Abbruch des gesamten Imports — bevor irgendwelche Aenderungen wirksam werden.

Update-Schluessel und Hilfsfelder

SpalteTypBeschreibung
idIntegerUpdate-Schluessel (hoechste Prioritaet). Niemals als Wert ins Adressattribut geschrieben.
pit_numberTextUpdate-Schluessel und Adressattribut.
hostsystem_referenceTextUpdate-Schluessel und Adressattribut.
pit_number2TextUpdate-Schluessel und Adressattribut.
_createBooleanSteuert das Anlegen bei fehlender Adresse (siehe oben). Wird nicht in die Datenbank geschrieben.

Direkte Adressattribute

SpalteTyp
name, name2, firstname, lastnameText
street, street2, zip, postbox, city, districtText
email, phone, mobilephone, fax, webpageText
comment, identText
archivedTimestamp mit Zeitzone (ISO-8601, z. B. 2026-04-28T10:00:00+02:00)
last_drainage_date, drainage_clearance_valid_untilDatum (locale-abhaengig oder ISO yyyy-MM-dd)
socket_availableBoolean
correspondence_typeAufzaehlung: post, email, sms
tagsQuoted, kommagetrennte Liste, z. B. "foo,bar"
number_of_inhabitants, pit_volume, last_drainage_volume, volume_factor, effective_hose_length, max_drainage_volume, max_cross_vehicle_weight, max_axle_loadDezimalzahl (locale-abhaengig)

Fremdschluessel-Spalten

Fremdschluessel werden ueber den natuerlichen Identifikator des Zielobjekts referenziert. Trifft der Wert keine bzw. mehrere Datensaetze, schlaegt die Zeile mit FK_REFERENCE_UNKNOWN bzw. FK_REFERENCE_NOT_UNIQUE fehl.

SpalteAufgeloest gegenAdressattribut
country_id/alpha2country.alpha_2country_id
country_id/alpha3country.alpha_3country_id
country_id/identcountry.identcountry_id
address_segment/identaddress_segment.identaddress_segment_id
type_of_pit/identtype_of_pit.identtype_of_pit_id
owner_client_id/identclient.identowner_client_id
tour_id/identtour.identtour_id
correspondence_address_id/idaddress.idcorrespondence_address_id
correspondence_address_id/hostsystem_referenceaddress.hostsystem_referencecorrespondence_address_id
billing_address_id/idaddress.idbilling_address_id

Liefern mehrere Spalten der gleichen Gruppe einen Wert (z. B. sowohl country_id/alpha2 als auch country_id/ident), gewinnt die Spalte mit der hoeheren Prioritaet, also die in der Tabelle weiter oben stehende.

Wertinterpretation

Die Interpretation richtet sich nach dem Feld locale der Import-Job-Definition (Default de-DE).

  • Wahrheitswerte sind unabhaengig von Gross-/Kleinschreibung. Akzeptiert werden true/false, yes/no, ja/nein, wahr/falsch, sowie 1 (wahr) und 0 (falsch).
  • Zahlen verwenden das locale-typische Dezimaltrennzeichen — z. B. Komma fuer de-DE. Fuer en-US wird der Punkt erwartet.
  • Datumswerte koennen im locale-typischen Format mit vierstelligem Jahr (z. B. 28.04.2026 fuer de-DE), im locale-typischen Kurzformat mit zweistelligem Jahr (28.04.26 fuer de-DE) oder als ISO yyyy-MM-dd geliefert werden.
  • Zeitstempel mit Zeitzone sind als ISO 8601 mit Offset zu liefern, z. B. 2026-04-28T10:00:00+02:00.
  • Tags kommen als ein einziger CSV-Wert: gewuenschte Eintraege werden mit Komma getrennt, das gesamte Feld wird in Anfuehrungszeichen eingeschlossen, also "foo,bar". Leere Eintraege werden ignoriert.

Leere Zellen bedeuten „nicht gesetzt": Beim Update wird das vorhandene Datenbankattribut nicht veraendert; beim Anlegen wird das Attribut nicht gesetzt.

Zwei-Phasen-Verarbeitung

Der Import laeuft in zwei Phasen, um Datenbank-Effekte erst bei vollstaendig gueltiger Eingabe wirksam werden zu lassen:

  1. Pruefung (check-data): Es werden alle Zellen aller Zeilen typgerecht geparst und Fremdschluessel aufgeloest. Schon eine einzige fehlerhafte Zelle laesst den Import scheitern.
  2. Verarbeitung (process-data): Erst nachdem Phase 1 vollstaendig erfolgreich war, werden die Update-/Insert-Operationen auf der Datenbank ausgefuehrt.

Der Probelauf ueber /v1/import_job/dry-run/<id> liefert die gleiche normalisierte Datenstruktur, die anschliessend bei einem echten Import verarbeitet werden wuerde — inklusive aufgeloester Fremdschluessel, geparster Datums- und Dezimalwerte sowie der gewaehlten Update-Schluessel pro Zeile. Damit lassen sich Probleme zuverlaessig vor dem eigentlichen Import erkennen.

Fehlercodes

Alle Fehlercodes sind im I18n-Katalog hinterlegt und werden mit Platzhaltern fuer Werte ausgegeben:

CodeBedeutung
unknown_columnSpaltenkopf liegt nicht in der Allowlist (siehe Spaltenliste).
NO_UPDATE_KEYZeile enthaelt keinen Update-Schluessel.
UPDATE_KEY_NOT_UNIQUEUpdate-Schluessel verweist auf mehrere Adressen.
ID_UNKNOWNAdresse mit der angegebenen id existiert nicht.
PIT_NUMBER_UNKNOWNAdresse mit dem angegebenen pit_number existiert nicht und _create ist false.
HOSTSYSTEM_REFERENCE_UNKNOWNAdresse mit dem angegebenen hostsystem_reference existiert nicht und _create ist false.
PIT_NUMBER2_UNKNOWNAdresse mit dem angegebenen pit_number2 existiert nicht und _create ist false.
FK_REFERENCE_UNKNOWNFremdschluesselwert konnte nicht aufgeloest werden.
FK_REFERENCE_NOT_UNIQUEFremdschluesselwert ist nicht eindeutig (mehrere Treffer).
CELL_PARSE_FAILEDWert konnte nicht in den erwarteten Datentyp umgewandelt werden.

Beispiele

Die folgenden Beispiele entstammen dem ausfuehrbaren Beispielsatz im Repo werner unter integration-tests/userdata/address/. Die dortige README.md katalogisiert alle Faelle inklusive Fehlerpfaden und schlaegt eine manuelle Testreihenfolge vor.

Minimaler Insert

Kleinste sinnvolle Eingabe: zwei neue Adressen, identifiziert ueber pit_number. Spalten, die nicht im Header stehen, werden bei einem spaeteren Update nicht angefasst -- sie bleiben in der Datenbank erhalten.

Quelle: integration-tests/userdata/address/01_minimal_create.csv.

_create,pit_number,name,city
true,DEMO-MIN-001,Mustermann GmbH,Berlin
true,DEMO-MIN-002,Musterfrau OHG,Hamburg

Vollstaendiger Insert mit deutscher Locale

Demonstriert das volle Spektrum der Wertinterpretation: Dezimalzahlen mit Komma muessen wegen des CSV-Trenners in Anfuehrungszeichen stehen ("12,5"), tags werden als ein in Anfuehrungszeichen eingeschlossener Wert mit kommagetrennten Eintraegen geliefert ("vip,abrechnung-q2"), socket_available akzeptiert 1/0, correspondence_type ist eine Aufzaehlung, und country_id/alpha2 loest gegen country.alpha_2 auf.

Quelle: integration-tests/userdata/address/02_full_create_de_locale.csv.

_create,pit_number,name,name2,firstname,lastname,street,zip,city,email,phone,number_of_inhabitants,pit_volume,volume_factor,socket_available,last_drainage_date,correspondence_type,tags,country_id/alpha2
true,DEMO-FULL-001,Beispiel KG,Zentrale,Erika,Mustermann,Musterstraße 12,10115,Berlin,[email protected],+49 30 1234567,4,"12,5","2,5",1,2026-04-15,email,"vip,abrechnung-q2",DE
true,DEMO-FULL-002,Beispiel AG,,Max,Mustermann,Hauptstraße 7,20095,Hamburg,[email protected],+49 40 7654321,2,"8,1","1,0",0,2026-03-30,post,"intern",DE

Reines Update ueber pit_number

_create=false zwingt den Import in den Aktualisierungspfad: Treffer per pit_number werden aktualisiert, fehlt der Eintrag in der Datenbank, faellt die Zeile mit PIT_NUMBER_UNKNOWN durch.

Quelle: integration-tests/userdata/address/03_update_by_pit_number.csv.

_create,pit_number,phone,email
false,DEMO-MIN-001,+49 30 9999999,[email protected]
false,DEMO-MIN-002,+49 40 8888888,[email protected]

Fehlerpfad: unbekannter Update-Schluessel ohne _create

Kanonischer Fall fuer das Fehler-Detail-Reporting: _create=false und ein pit_number, den es in der Datenbank nicht gibt. Der Import erzeugt fuer diese Zeile einen Eintrag in error_details mit error-code = PIT_NUMBER_UNKNOWN; alle anderen, gueltigen Zeilen des selben Imports werden trotzdem ausgefuehrt.

Quelle: integration-tests/userdata/address/06_unknown_pit_no_create.csv.

_create,pit_number,name
false,DEMO-NICHT-VORHANDEN-001,Sollte PIT_NUMBER_UNKNOWN ausloesen

Vollstaendiger Beispielsatz

Der vollstaendige, ausfuehrbare Beispielsatz inklusive der weiteren Faelle -- unknown_column, FK_REFERENCE_UNKNOWN, NO_UPDATE_KEY, locale-Varianten fuer Booleans und Dezimalzahlen, partielles Update und Update-Schluessel-Prioritaet (id vor hostsystem_reference) -- liegt zusammen mit einer ausfuehrlichen README.md unter integration-tests/userdata/address/ im Repo werner.

Previous
Import Adressen aus kVASy Tourenplanung V2