Ergänzt Auftragserfassung und -bearbeitung, Unternehmerbelege, Stornos, Lagerkorrekturen, Stammdaten, Abrechnung, CRM, Formulare, Berichte und Preisverwaltung auf Basis der aktuellen PHP-Anwendung. Enthält Integrations- und Oberflächentests sowie dokumentierte Abgleiche und Prüfstände.
32 KiB
Native Auftragserfassung
Aktualisierung 13. Oktober 2026: Foto-Workflow-Sets einschließlich Freigaben, Stationsregeln und wiederaufnehmbarer Übertragung sind ergänzt. Verbindliche PHP-Quelle ist ausschließlich der aktuelle SSH-Serverstand unter /data/0/votian-test/html; Details im Menüabgleich und Prüfstatus.
Stand: 13. Oktober 2026. Die neue Erfassung schreibt über den zentralen DatabaseService in das unveränderte Bestandsschema. Die PHP-Dateien wurden nicht geändert. Diese Umsetzung ersetzt die unten beschriebenen Erfassungsabläufe, nicht sämtliche Sonderfunktionen der PHP-Auftragsmaske.
Fachlicher Umfang
| Ablauf | Verhalten |
|---|---|
| Sofortauftrag | Aktuelle Berliner Uhrzeit, Status aus HQ-Arbeitsmodus und Fahrzeugzuweisung |
| Vorbestellung | Zukünftiger Abholtermin, Reservierungsflag, optionale Warnzeit |
| Dauerauftrag | Alle 11 bestehenden Rhythmuscodes, Wochentagsmaske, optionales einschließliches Enddatum; wahlweise sofortige Anlage bis zum Serienende mit Vorschau aller Termine und Preise; sonst erzeugt der bestehende Dauerauftragsdienst die Folgen |
| Barzahlung | Technischer Systembarzahler und tatsächlicher Zahler getrennt, wählbare Kassierstation, Netto/Steuer/Brutto und Bestandsmarker im Stationshinweis |
| Fahrzeugzuweisung | Suche über SID, Kuriername oder Kennzeichen; bestehende Fahrzeug-/Kurier-ID und Vorbelegung werden gespeichert; Status gemäß PHP-Eingangspfad |
| Nacherfassung | Ausführendes Fahrzeug erforderlich, Datum in der Vergangenheit; Auftrag erledigt und Stationen abgeschlossen, separate Buchungszeit |
| Stationen | Kostenstellen- und Adresssuche, freie Adressen, beliebig umordnen, 1–100 Stationen, Abholung/Zustellung/beides, Kontakt, Telefon, Referenz und Hinweis |
| Preis | PLZ-/Gebietsmatrix oder Festpreis; historische Gültigkeiten, Grundpreis, Kundensonderkonditionen, Rabatt, Kraftstoffzuschlag, Servicepreis, Frachtvergütungsabschlag, Steuer, Dezimalrundung |
| Foto-Workflow-Sets | Freigegebene Sets des zahlenden Kunden, globale Rückfallebene, Standards nach Stationsposition/-art, abweichende Auswahl je Station einschließlich Nummer 0, gesicherte Übertragung mit Wiederholung |
| Fernverkehr | Automatische Kilometer-/PZM-Kalkulation, Mindestpreise, An-/Abfahrt, Fernverkehrsgrenze pro Streckenabschnitt, BWV-Sonderkonditionen und bewusste ASAP-Auswahl |
| Auslandsabholung | Vergleich der gesamten Rundfahrt für die jeweils drei nächsten Niederlassungen an Start und Ziel; günstigste Fahrstrecke bestimmt die Disposition |
| Disposition | HQ-Zuordnung, Vermittlungsbereiche einschließlich wählbarer Rechnungs-PLZ, Kunden-/Pflichtfilter und zusätzliche Kurierfilter, Wunschkurierregel, manuelle Disposition, Annahmefrist und Storno bei Nichtverfügbarkeit |
| Alle Kuriere / Börsenmodus | Bestands-Ausschlussliste aus Länderfreigaben und EG-/Gewichtsprüfung wird vor der Freigabe in derselben Transaktion gespeichert; Fotoübertragung hält den Auftrag gegebenenfalls zunächst zurück |
| Kopieren / Tourvorlagen | HQ-begrenzte Suche, Übernahme als neuer Auftrag, Tourname und ausdrücklich bestätigtes Überschreiben; keine Übernahme von Status, Zuweisung, Anhängen oder Versicherung |
| Mehrfachaufträge | 1–10 gleiche Aufträge in einer Transaktion; Wiederholung liefert dieselbe Gruppe |
| Herkunft / Angebot | Telefon, Mail oder Sonstiges; Angebot in manueller Disposition und zur Nachbearbeitung |
| Rechnung | Kunden-Steuerschlüssel, erforderlicher Besteller und kundenabhängige Referenz, getrennte Rechnungstexte, Maut/Auslagen einschließlich Steuer und Barbetrag, Rechnungsmail anzeigen/mit ausdrücklicher Auswahl aktualisieren |
| Leistungskalkulation | Kundenspezifische oder globale Leistungs-/Typkombinationen, Mengen und historische Preise; Pflichtkalkulation; PHP-Kalkulationsformat in jb_freetext_2 und eine zusammengefasste Preisbuchung |
| Höherversicherung | Bestands-Prämienberechnung mit Mindestbetrag/Aufrundung, separater verknüpfter Versicherungsauftrag und technischer Kurier; Sonderfall offen |
| Adressen / Dateien | Abhol-/Lieferadresse der Kostenstelle (adt_id=4), Suche in bisherigen Aufträgen, eingebettete Kartenauswahl mit Rückübernahme, Prüfung neuer Adressen mit ausdrücklicher Übersteuerung, Upload-Dienst je Station |
| Kostensplit | Gleiche, centgenaue Verteilung auf unterschiedliche interne Stationskostenstellen und den gewählten Zahler; Vorschau je Empfänger |
| Kurier-Unteraufträge | Unternehmerverrechnung bei Nacherfassungen im Inland, bis zu 20 Unternehmer, positive Unteraufträge und Gegenbuchungen |
| Artikel / Lager | Artikel je Station, Mengen, Gewicht, Packstücke und Seriennummer; ausdrücklich ausgewählte Ein-, Aus- und Umlagerung mit Bestandsprüfung und Journal |
| Freie Artikelpositionen | Freie Bezeichnung, Menge, Gesamtgewicht, Packstücke, Artikelwert, Seriennummer und Hinweis ohne Artikelstamm; keine Lagerbewegung |
| Tastenkürzel | Alt + Buchstabe nach PHP-Belegung, Hilfe im Formular, Schutz bei Unterdialogen und laufenden/unklaren Speicheranfragen |
| Nachhaltigkeitsdaten | Bei Nacherfassung automatische CO₂e-Berechnung oder geprüfte manuelle Kilometer-/CO₂e-Werte; Vorschau und Bestandsspeicherung |
| Niederlassungsübergreifende Erfassung | Auswahl freigegebener Niederlassungen desselben Mandanten; Erfassungsdaten/Preisprüfung/Speicherung im Zielbereich, unveränderte Sitzung |
| Eingabeschutz | Bestätigung beim Schließen/Ersetzen ungespeicherter Eingaben; Browser-Neuladeschutz; keine dauerhafte Speicherung der Entwürfe im Browser |
Preisbedingungen können gemäß cs_jbcond von der Abholkostenstelle stammen. Der Rechnungszahler bleibt separat. Fehlende Tarife werden als Fehler ausgewiesen. Servicezuschläge nach Straße, kundenspezifische Unvollständigkeits-/Referenzregeln und die rückwirkende Kurierprovision werden berücksichtigt. Historische, im PHP-Code fest hinterlegte Kundenzuschläge wurden in legacy-markup-history.json übernommen; Änderungen dieser PHP-Liste müssen auch hier nachvollzogen werden.
Quellen: aktuelle Dateien unter /data/0/votian-test/html auf 172.16.0.158, insbesondere jobs/job_options.php, jobs/get_saved_tour.php, jobs/job_edit.68.20.js, include/services_func.inc.php, include/ajaxReqKmPrice.php, include/ajaxReqJob.php, locating/xServer.inc.php, include/pnpoly.inc.php, include/caglobal.inc.php, include/global.inc.php und admin/cs_csc_list.php. Der alte lokale PHP-Ordner ist keine Referenz mehr.
Die Richtungsbits sind gemäß aktivem PHP-Speicher- und Ladepfad 2=Abholung, 1=Zustellung, 3=beides. Der alte Rechnungstext-Helfer beschriftet 1/2 umgekehrt. Der neue Leseadapter und die Erfassung verwenden konsistent den Speicherpfad; PHP selbst wurde nicht korrigiert.
API und Berechtigungen
GET /api/orders/entry/options, /cost-centers?q=, /cost-centers/{id}/addresses, /cost-centers/{id}/photo-workflows und /vehicles?q= liefern Erfassungsdaten. Alle benötigen Recht 7 und begrenzen Kostenstellen/Fahrzeuge auf die gewählte Erfassungsniederlassung. Stammdaten-Leserechte 0/1 sind dafür nicht erforderlich. Die Suchergebnisse sind auf 50 beschränkt.
POST /api/orders/quote validiert Eingaben und berechnet den Preis ausschließlich lesend. POST /api/orders ermittelt externe Routendaten und Fotooptionen vor der Schreibtransaktion und rechnet Tarife innerhalb der Schreibtransaktion erneut und verlangt denselben quoteFingerprint. Abweichungen liefern 409. Das Formular verwirft die Vorschau bei jeder Eingabeänderung.
GET /api/orders/entry/articles?q= sucht freigegebene Artikel der eigenen Niederlassung; /stocks?payerId=…&articleId=…&q= liefert zugängliche Lagerorte samt Artikelbestand und benötigt zusätzlich Recht 14. /features liefert den konfigurierten Kartenendpunkt und die Lagerberechtigung. Die nur lesenden POSTs /map/locate und /map/address zentrieren die Karte beziehungsweise lösen einen gewählten Punkt auf.
Alle POSTs benötigen Sitzung und CSRF-Token. Manuelle Frachtvergütung und Kurier-Unteraufträge benötigen Recht 38, eine ausdrücklich bestätigte Überschreitung von JB_CR_PRICE_BLOCK Recht 39. HQ, Bearbeiter, Status und berechnete Summen kommen ausschließlich vom Server. Unbekannte JSON-Felder werden abgewiesen. createOrders ist unabhängig von dem weiterhin deaktivierten writeOrders für Bestandsänderungen.
Speicherung und Betrieb
Job, Stationen, Adressen, tourservice, jobprice, Bestandssemaphoren und Audit-Outbox werden gemeinsam gespeichert. Vor dem Schreiben werden die beteiligten Tabellen auf InnoDB geprüft. Ein Fehler rollt die fachliche Transaktion zurück. Keine DDL-Anweisungen, Schemaänderungen, Seed-Daten oder separaten Datenbanken.
Eine UUID pro Erfassungsdialog wird unter ng_order_request in der bestehenden Semaphortabelle abgelegt. Eine Sperre auf dem Benutzer serialisiert parallele Wiederholungen. Identische Wiederholung liefert denselben Auftrag (200 statt 201); andere Nutzdaten mit derselben UUID liefern 409. Bei unklarer Netzwerkantwort hält die Oberfläche die ursprüngliche Anfrage fest und bietet „Speicherstatus prüfen“ an.
phoenix_log.log ist im geprüften Bestand MyISAM. Deshalb wird das Protokoll erst nach erfolgreichem Commit veröffentlicht. Eine transaktionale Outbox in genericdatacontainer hält ausstehende Ereignisse fest. Ein Hintergrundlauf versucht sie nach einer Minute und anschließend alle 30 Sekunden erneut; eine stabile Ereigniskennung verhindert doppelte Logeinträge auch nach Teilfehlern. Die Bestands-Protokolltabelle muss INSERT erlauben. Die Erfassung benötigt zusätzlich INSERT in die genannten Tabellen und UPDATE auf Kurierbelegung/Outbox; bei ausdrücklich ausgewählter Rechnungsmailänderung werden user.usr_inv_email und der Exportmarker company.cmp_modify_status aktualisiert. Dafür muss auch company InnoDB verwenden.
Die bestehende PHP-Verarbeitung bleibt erforderlich für Dauerauftragskopien/Feiertage, automatische Disposition und Fahrergeräte, Automailer sowie die endgültige Rechnungstextaufbereitung. Die Erfassung initialisiert die vorhandenen Semaphoren und jb_invtext_dirty. Es gibt keinen zweiten Java-Dauerauftragsscheduler. Bei der ausdrücklich ausgewählten sofortigen Serienanlage werden die gepflegten Feiertage aus publicholiday und die elf PHP-Rhythmen verwendet. Die Vorschau bindet alle Termine und Einzelpreise; beim Speichern entstehen getrennte Vorgänger-/Nachfolgerketten pro Mehrfachserie (jb_id_copy, jb_id_copy_permanent). Die sofortige Anlage ist auf zwei Jahre, 500 Aufträge und 10.000 Stationen pro Anfrage begrenzt. Ohne diese Auswahl bleibt die Fortführung beim bestehenden Dienst. Aufträge können durch diese Bestandsdienste nach dem Speichern weiterverarbeitet werden.
Kostensplit, Unternehmerverrechnung und Lager
Der Kostensplit ist bei direkt abgerechneten Rechnungsaufträgen verfügbar. Teilnehmer sind die unterschiedlichen internen Stationskostenstellen und der ausgewählte Rechnungszahler; mindestens zwei sind erforderlich. Die Preisgrundlage bleibt der ausgewählte Zahler beziehungsweise die bestehende Abholkondition. Jede rabattierte Preiskomponente und Maut werden gleich verteilt; Restcents gehen in stabiler Kostenstellenreihenfolge an die ersten Empfänger. Die Vorschau weist Netto, Maut, Steuer und Brutto je Empfänger aus. Die Speicherung setzt jb_payment=1, schreibt die verteilten Nettokomponenten in tourservice mit Rabatt 0 (bereits eingerechnet) und den Beleg unter ng_cost_split.
Kurier-Unteraufträge folgen saveJobChildren aus caglobal.inc.php: nur Nacherfassungen im Inland mit ausführendem Fahrzeug, keine Sammelabrechnung oder Fernverkehr. Die Verrechnungsbeträge werden mit Kundenzuschlag, optionalem INV_CHILDREN_DISCOUNT, Servicepreis je Unternehmer und gegebenenfalls MASK_CHILDREN_TAX_HARDCODED berechnet. Die Summe darf den Kundenpreis vor Zuschlag ohne Servicepreis nicht überschreiten. Je Unternehmer entstehen ein positiver Unterauftrag und eine Gegenbuchung beim ausführenden Kurier; Maut wird beim ersten Paar berücksichtigt. Der Hauptauftrag erhält jb_id_parent=-1 und die summierte Frachtvergütung. Der technische Zahler kommt ausschließlich aus CSC_ID_PAYER_CALCULATOR der eigenen Niederlassung. Nur für diese serverseitig bestimmte Kostenstelle sind die im Bestand üblichen versteckten oder nicht authentifizierten Verrechnungskonten zulässig; HQ-Grenze, Sperr- und Archivprüfung gelten weiter. Manuelle Einzelvergütungen können nicht gleichzeitig verwendet werden.
Artikel werden als tourarticle mit stabiler Stationszuordnung gespeichert. Sie ändern den Transportpreis nicht. Kopien und geladene Vorlagen übernehmen Artikel und Mengen, aber keine Seriennummern oder Lagerbewegungen; diese müssen neu gewählt werden. Freie Artikelpositionen verwenden articleId=0 und freeArticle mit Bezeichnung (max. 30 Zeichen), Gesamtgewicht (3 Nachkommastellen), Packstückzahl und Artikelwert (2 Nachkommastellen). Sie werden ohne Artikelstammsatz als tourarticle.at_id=0 gespeichert und lassen keine Lagerbuchung zu. Mengen vervielfachen das eingegebene Gesamtgewicht nicht. Artikelstamm-/Lagerstammdaten werden hier nicht neu angelegt.
Lagerbewegungen benötigen Recht 14 und eine ausdrückliche Auswahl von Quelle und Ziel. Ein- und Auslagerung verwenden 0 für außerhalb des Lagers. Sichtbarkeit, Schreibschutz, Kundenbezug, Lagerhierarchie und MASK_STK_SUBSTOCK_ACCESS werden serverseitig geprüft. Mengen werden über alle Positionen und Mehrfachkopien summiert; Seriennummern, vorhandener Bestand, Lagerplatzumrechnung und aktivierte Kapazitätsplanung werden geprüft. Vor dem Speichern werden die Lager- und Artikelzeilen gesperrt und die aktuellen Bestände erneut gelesen. stockarticle, articleitem und stockmove werden zusammen mit dem Auftrag in derselben Transaktion geändert; Seriennummern-Umlagerungen erhalten vorhandene Artikelmetadaten. Die Bewegung erfolgt sofort beim Speichern, auch bei Vorbestellungen. Angebote, Daueraufträge und die gleichzeitige Speicherung als Tourvorlage lassen keine Lagerbewegung zu. Artikelpositionen ohne Bewegung bleiben dort möglich.
Die Tabellen article, tourarticle, stock, stockarticle, stockmove und articleitem wurden im Bestand ausschließlich lesend auf Spalten und InnoDB geprüft. Nicht transaktionsfähige Tabellen führen vor dem Schreiben zum Abbruch. Es wurden keine echten Lagerbewegungen oder Verrechnungsaufträge zur Prüfung angelegt.
Foto-, Routen- und Fernverkehrsdienste
Die Fotooptionen kommen wie im aktuellen PHP über URL_CS_PHOTO_WORKFLOW/sets/kunde/{cs_id}. Freigaben werden gefiltert; ohne freigegebenes Kundenset wird /sets/kunde/0 gelesen. Der Server prüft Set und Stationsauswahl erneut vor dem Speichern. Bei Barzahlung gehört die Fotoauswahl zum tatsächlichen Kunden, auch wenn die Preisberechnung den technischen Systembarzahler verwendet. Ohne explizite Setauswahl gilt der Kundenstandard, sonst das erste Set. Innerhalb des Sets bestimmen Stationsposition und Stationsart den Standard; eine einzelne Station zählt wie in PHP als LAST. Nummer 0 ist eine gültige Workflow-Auswahl. Min-/Max-Fotoanzahl wird angezeigt; die Bildprüfung bleibt beim Fotodienst. Ein ausgefallener konfigurierter Fotodienst wird als Fehler gemeldet und nicht als „keine Fotos“ behandelt. Fehlt der Parameter vollständig, stehen keine Fotoworkflows zur Verfügung. Die abweichende PHP-Bedeutung der Stationsrichtungskennzeichen für Foto-Scope-Regeln ist im Menüabgleich dokumentiert und wird übernommen.
Nach dem Commit erfolgt zuerst POST /selection/set mit jbId, setNumber, danach das Lesen bestehender Stationsauswahlen und gegebenenfalls je Tourstation POST /selection mit jbId, trId, number. Set und Stationsauswahl stehen vorher atomar unter ng_photo_selection in genericdatacontainer. Ein Wiederholungsversuch setzt dasselbe Set erneut und liest anschließend GET /selection?jbId=..., um bestätigte Kombinationen aus tr_id und number zu überspringen beziehungsweise vom Set zurückgesetzte Abweichungen wiederherzustellen. Bis zur Übertragung werden neu zu disponierende Aufträge in Status 9 gehalten; die vorgesehene Fahrzeugfreigabe erfolgt erst nach Erfolg. Nachträgliche Bearbeiteränderungen, Storno und Statusänderungen werden dabei nicht überschrieben. Nacherfassungen bleiben erledigt. photoSyncPending in der Speicherantwort und der Hinweis in der Oberfläche kennzeichnen eine noch ausstehende Übertragung. Kurze, erneuerbare Datenbank-Leases verhindern parallele Übertragungen; während HTTP-Aufrufen werden keine Datenbanktransaktionen oder Auftragssperren gehalten. Verwaiste Leases laufen nach 45 Sekunden aus. Wiederholung erfolgt nach einer Minute und anschließend alle 30 Sekunden. Der Fotodienst bleibt für Bildanzahl, Aufnahme und Verarbeitung der eigentlichen Fotos zuständig.
Für Routing muss PZM_URL den vollständigen vorhandenen /api/pzm-Endpunkt enthalten; alternativ wird der globale Parameter URL_PZM gelesen. PZM_FALLBACK_URL kann einen zweiten Dienst angeben. GOOGLE_MAPS_API_KEY kommt aus der Umgebung oder dem gleichnamigen globalen Bestandsparameter. Im PHP-Code gespeicherte Zugangsdaten und Schlüssel werden nicht übernommen. Geokoordinaten werden zunächst aus einem zugänglichen, ausreichend aktuellen address_geo-Bestand gelesen; ansonsten dient Google-Geokodierung als Rückfall. Mehrdeutige, nur ortsgenaue oder teilweise passende Adressen werden abgewiesen. Der Geobestand wird nicht verändert. HTTP-Aufrufe haben Verbindungs-/Anfragezeitlimits, begrenzte Antwortgrößen und folgen keinen Weiterleitungen. Routen und Geokodierungen werden maximal fünf Minuten in einem begrenzten Speicher zwischengespeichert.
Die Kilometerkalkulation übernimmt km-Preis, Grundpreis, weitere Adressen, Mindestpreis und globale Frachtvergütungsabschläge. Der Kundenbasispreis wird wie in PHP auf volle Euro aufgerundet; die Vergütung bleibt centgenau. PZM verwendet PZM_MASK_ZONES, zonenweise Kilometer-/Fixpreise und An-/Abfahrt einschließlich der Rundfahrtsonderregel. Die Rundung richtet sich nach PZM_MASK_ROUND und PZM_MASK_DONT_ROUND_<cs_id>. Zuschläge und Festpreisrabatt werden anschließend auf den kalkulierten Basispreis angewendet. Die berechnete Basis wird als Bestands-Fixpreis gespeichert; der nachvollziehbare Rechenbeleg liegt unter ng_route_calculation. PHP-kompatible Kilometerparameter sowie preisneutrale tourservice-Zonendetails mit Typ z bleiben für das spätere Öffnen in der Altmaske erhalten. Eine manuell eingegebene Entfernung ersetzt keine automatische Berechnung.
Bei aktivierter Fernverkehrserkennung (LONGHAUL_ACTIVE, für automatische Kilometer-/PZM- und Auslandsrouten zusätzlich streckenbezogen) gilt LONGHAUL_KM als Grenze der mittleren Abschnittslänge. Für PZM wird zunächst die kürzeste Strecke einschließlich An-/Abfahrt bewertet. Im Fernverkehr werden weitere Niederlassungen entlang der alle zwei Kilometer betrachteten Routenpunkte anhand der vorhandenen PLZ-Polygone aus phoenix_special verglichen. BWV_ACTIVE, BWV_AUSSERHALB_TSZ, fahrzeugbezogene BWV_*-Tarife und PZM_ROUNDTRIPKM werden berücksichtigt. Ein gewählter Fernauftrag erhält jb_longhaul=1, optionalen Filter BWV, manuelle Disposition und bei Neuanlage zunächst keine Frachtvergütung. Die weitere Fernverkehrsbearbeitung bleibt beim bestehenden Dienst. ASAP speichert bei erreichter Grenze den PHP-Marker longhaul_deselected.
Bei Auslandsabholung entscheidet die kürzeste vollständige Rundfahrt (Niederlassung → alle Stationen → Niederlassung) über hq_id_dispo. Ein Fehler bei einem Kandidaten bricht den Vergleich ab, statt unvollständige Ergebnisse zu übernehmen. Auftragsinhaber und Zugriffsrechte bleiben bei der angemeldeten Niederlassung. Preisniederlassung und Dispositionsniederlassung werden separat geführt. Vorschau, Fingerprint und Rechenbeleg enthalten die Route, Fotoauswahlen und den Niederlassungsvergleich.
Die lesende Bestandsprüfung vom 12.10.2026 bestätigte PLZ-Polygone, Niederlassungskoordinaten, Foto-URL-Parameter und Fernverkehrs-/Zonenparameter. address_geo, ein lokaler Parameter URL_PZM und ein lokaler Parameter GOOGLE_MAPS_API_KEY waren dort nicht verfügbar. Daher müssen PZM-Endpunkt und Google-Schlüssel für diese Installation über die Umgebung konfiguriert werden. Ein produktiver Auftrags-/Foto-POST wurde nicht ausgeführt.
Abgleich mit der geöffneten Altmaske am 12.10.2026
Die Oberfläche unter test.sb.assecutor.de/jobs/job_edit.php wurde samt Frames gelesen und mit dem lokalen PHP verglichen. Korrigiert wurden insbesondere der falsche Adresstyp (zuvor 1/3 statt 4), der starre Steuerschlüssel, der fehlende Pflichtbesteller, der Zwei-Stationen-Zwang und der Verlust ungespeicherter Eingaben beim Schließen. Die oben ergänzten Abläufe verwenden die vorhandenen Tabellen und Parameter; echte Aufträge wurden bei dieser Prüfung nicht angelegt.
Am 13.10.2026 aufgelöst: Der aktuelle SSH-Serverstand belegt den Vertrag von tr_photo_set / photoSetChanged(). Die Set-Auswahl einschließlich Stationsregeln und Übertragung ist inzwischen umgesetzt (siehe oben). Der lokale PHP-Stand wird nicht mehr verwendet.
Dateianhänge verwenden URL_DOC_UPLOAD mit /upload?ref=…&readonly=… und den bestehenden upload-success-/delete-success-Ereignissen. Die Oberfläche prüft Absenderfenster, Origin und Session; der Server akzeptiert Dateilinks nur vom konfigurierten Upload-Origin und ordnet die Metadaten erst beim Speichern den neuen Tourstationen zu. Ein Upload gegen den echten Dienst wurde nicht ausgeführt.
Die eingebettete Karte verwendet den vorhandenen globalen Parameter URL_GEOCORDS und dessen PHP-Vertrag (lat/lng, geocords-confirmed, geocords-closed). Ereignisse werden auf Karten-Origin, Absenderfenster und gültige Koordinaten geprüft. Ein gewählter Punkt wird vor der ausdrücklichen Übernahme angezeigt; eine Änderung verwirft die Preisvorschau. Solange die Karte geöffnet ist, bleibt Speichern gesperrt. Google-Rückwärtsgeokodierung benötigt GOOGLE_MAPS_API_KEY. Ohne Schlüssel bleibt die Punktübernahme mit dem PHP-kompatiblen GPS (lat,lng)-Straßenmarker möglich; die Oberfläche weist auf manuell zu prüfende Adressfelder hin. Koordinatenmarker werden bei der weiteren Routenberechnung direkt ausgewertet. Die aktive Belegung aus job_accesskeys.inc.php ist als Alt + Buchstabe im Formular verfügbar; die auskommentierten PHP-Kürzel B/T wurden nicht als aktive Bestandsfunktionen übernommen.
Grenzen dieser Umsetzung
- Änderungen an Bestandsaufträgen, Storno einschließlich seiner Gegenbuchungen und Rechnungserzeugung bleiben PHP-Funktionen. Die hier beschriebenen Verrechnungsunteraufträge sind Teil der Neuanlage. Lagerstammdatenpflege, Scanner- und nachträgliche Lagerprozesse bleiben im Bestand.
- Kundenspezifische Zusatzprozesse außerhalb der Fotoworkflows bleiben PHP-Funktionen. PLZ-/Gebietsmatrizen bleiben auf deutsche Strecken begrenzt; Auslandsstrecken verwenden Kilometer, PZM oder Festpreis.
- Niederlassungsübergreifende Erfassung ist umgesetzt; die allgemeinen Listen bleiben auf den ursprünglichen Bereich begrenzt. Kunden-/Kurierportale bleiben außerhalb dieser Erfassung. Die weitere Vermittlung und die Zustellung an Fahrergeräte übernehmen weiterhin die Bestandsdienste.
- Eine Nacherfassung setzt Annahme und Abschluss auf den angegebenen Ausführungszeitpunkt. Ohne gewählte Nachhaltigkeitsberechnung bleiben die späteren CO₂e-/Kilometerberechnungen beim Bestandsdienst; wenn der Kunde Werte benötigt, wird der Auftrag ohne Werte weiterhin unvollständig markiert.
Nachhaltigkeit, Niederlassungen und Tastatur
Nacherfassungen können sustainability.mode=AUTO oder MANUAL enthalten. Manuell werden gefahrene Kilometer und Gesamt-CO₂e in kg gemeinsam verlangt. Automatisch hat die eingegebene Entfernung Vorrang; andernfalls werden Routendaten verwendet. Gewicht und Fahrzeug-/Umweltklassen folgen tools/co2e_sendReq.php (ohne Sendungsgewicht: halbe Fahrzeugnutzlast). Die vorhandene HTTPS-API erhält den PHP-Datenvertrag mit einer numerischen Berechnungsreferenz. Referenz, Anzahl und positive Emissionswerte werden geprüft; Fehler liefern keine erfundenen Werte. Externe Aufrufe erfolgen vor der Schreibtransaktion, Quote/Speichern teilen einen begrenzten fünfminütigen Ergebnis-Cache. Geänderte Fahrzeug-/Berechnungsdaten erfordern eine neue Vorschau. Gespeichert werden jobprice.mt_sort=11/12 samt Berechnungsbeleg und wie im PHP die historische Partnerprovision unter 14. Es werden keine Nachhaltigkeits-E-Mails durch den neuen Code versendet.
GET /api/orders/entry/headquarters liefert die erlaubte Auswahl. X-Order-Headquarters gilt ausschließlich für Erfassungsendpunkte und die Neuanlage. Die Freigabe wird je Anfrage aus Mandantenzuordnung, emp_headquarters, employeerights (Recht 8, einsbasiert), Root-Administrator und eingeschränkten Callcenterrechten geprüft. Lager benötigt zusätzlich die passende Freigabe. Der Filter stellt den ursprünglichen SecurityContext nach jeder Anfrage wieder her. Beim Wechsel werden nach Rückfrage alle Entwurfsdaten und der Preis verworfen. Die Vorschau ist an die Erfassungsniederlassung gebunden; der Schreibpfad sperrt das ursprüngliche Benutzerkonto und schreibt in die gewählte Niederlassung. Andere Tabs und Listen ändern ihren Bereich nicht.
Die Tastenkürzelhilfe listet die PHP-Belegung im Erfassungsdialog. Alt+S berechnet zunächst den Preis und speichert erst mit gültiger Vorschau; Pflichtfeldprüfung gilt weiterhin. Alt+L/R fragen vor dem Leeren der Stationsdaten nach. Alt+X/Y wechseln die fokussierte Station, Alt+Z vertauscht die aktuelle mit der nächsten Station unter Erhalt der Artikel- und Kassierzuordnung. AltGr, gedrückte Wiederholung, IME, Unterdialoge und gesperrte Speicherung lösen keine Kürzel aus.
Lokale Dienstzugänge
Der Launcher liest .env über scripts/env_config.py ohne Shellauswertung; Prozessvariablen haben Vorrang. application.yml liest CO2_URL, CO2_USERNAME, CO2_PASSWORD, PZM_URL, PZM_FALLBACK_URL und GOOGLE_MAPS_API_KEY. Auf ausdrücklichen Auftrag wurden die aktiven CO₂e-Zugangsdaten und der PZM-Endpunkt aus dem PHP in die ignorierte lokale .env übernommen; vorhandene befüllte Werte blieben erhalten, Dateimodus 0600. Die alternative PZM-Konstante ist im PHP leer.
Der aktive Google-Schlüssel wird aus der separaten PHP-Parameterdatenbank geladen. Mit den am 13. Oktober bereitgestellten Zugangsdaten für 172.16.0.111:3711/phoenix wurde er erfolgreich gelesen und als GOOGLE_MAPS_API_KEY in der lokalen .env gespeichert. Der Zugang zur Parameterquelle liegt getrennt unter PARAM_DB_URL, PARAM_DB_USER und PARAM_DB_PASSWORD; die Hauptdatenbankverbindung bleibt eigenständig. Der einmalige Import verwendete wegen mysql_old_password einen isolierten kompatiblen JDBC-Treiber. Die alte Parameterquelle unterstützt keine serverseitigen READ-ONLY-Transaktionen; im Import wurde ausschließlich der feste, durch DatabaseService geprüfte SELECT ausgeführt. Treiber und erzwungene Lesetransaktionen der laufenden Anwendung wurden nicht verändert. Der laufende Server liest den übernommenen Schlüssel direkt aus der Umgebung.
Ein HTTPS-Geokodierungsaufruf für die öffentliche Beispieladresse Brandenburger Tor, Berlin, lieferte OK mit einem Ergebnis. Das bestätigt Schlüssel und Geocoding-Freigabe; ein vollständiger Auftrags-/PZM-Durchlauf ist damit weiterhin nicht abgenommen. Keine Zugangsdaten gehören in Git oder Logausgaben.
Verifikation
Aktueller Erweiterungslauf: 208 Backend-Tests, davon 205 bestanden und 3 optionale Live-Tests übersprungen, keine Fehler. Frontend-Build erfolgreich. Neue Tests prüfen freie Artikel/Vorlagen, Eingabegrenzen, Kilometer/CO₂e/Partnerprovision, API-Vertrag/Cache/Fehler, Niederlassungsrechte, Kontextwiederherstellung, ursprüngliche Kontosperre und an die Niederlassung gebundene Vorschau. Im Browser mit isolierten Antworten geprüft: freie Artikel, manuelle Nachhaltigkeitsvorschau, Alt+E/G/S/L, Schutz im Unterdialog und Niederlassungswechsel mit verworfenem Entwurf. Sieben benötigte Rechte-/Fahrzeugspalten und die Freigaben des Zentralenkontos wurden mit echten SELECTs bestätigt; keine Auftrags- oder Lagerbuchung erzeugt. Kein erfolgreicher Live-CO₂e-/PZM-Durchlauf behauptet.
Vorheriger Stand:
Erweiterungslauf 12.10.2026: Frontend-Produktionsbuild erfolgreich; Maven-Testlauf mit 193 Tests, davon 190 erfolgreich und 3 vorhandene Integrationstests übersprungen, keine Fehler. Die übersprungenen Tests erfordern einen gesonderten Bestandsdatenbank-Zugang. git diff --check ohne Befund.
Zusätzliche Tests prüfen die centgenaue Kostenverteilung, Unteraufträge/Gegenbuchungen samt wiederholbarer Neuanlage, den eng begrenzten technischen Verrechnungszahler, Mengen-/Kapazitätsprüfung über mehrere Positionen und Kopien, aktuelle Lagerbestände nach Sperren, Seriennummernerhalt, Lagerrechte, Rollback sowie Kartenkoordinaten, Rückwärtsgeokodierung und API-Rechte.
Automatisierte Backend-Prüfungen decken Foto-Standard-/Stationsauswahl, wiederholbare Übertragung und Dispositionssperre, Auslands-Rundfahrten, Kilometer-/Zonentarife, Fernverkehrs-/ASAP-Grenzen, externe Fehlerfälle und HTTP-Verträge sowie Preis-/Rabattregeln, Statuszweige, Reservierungen, Daueraufträge, Barzahler, Nacherfassung, Pflichtfilter, Preisänderungen, Rechte/CSRF, Idempotenz, Transaktionsrollback und MyISAM-Protokollwiederholung ab. Diese Tests verwenden gemockte Datenzugriffe und erzeugen keine Testdatenbank.
Die vorhandene Playwright-Suite wurde an Pflichtbesteller und neue Lookup-Endpunkte angepasst; sie wurde bei diesem Erweiterungslauf nicht über die CLI ausgeführt. Die ergänzte Oberfläche wurde stattdessen über die Browsersteuerung im Codex-In-App-Browser mit isolierten lokalen API-Antworten geprüft (Steuervorbelegung, Pflichtreferenz, Einzelstation, mehrzeilige Hinweise, Rechnungs-PLZ, Leistungspositionen, Mehrfachvorschau und Abbruchschutz). Im aktuellen Lauf zusätzlich geprüft: Kostensplit, Unternehmerauswahl, Seriennummernartikel mit Umlagerung, die drei Vorschautabellen, stabile Artikelzuordnung nach Stationswechsel sowie gültige/ungültige Kartenpunkte und die Übernahme in die Station. Speichern war am lokalen Fixture-Server gesperrt. Backend-Tests prüfen zusätzlich die tatsächliche Berechnungs- und Speicherlogik mit gemocktem DatabaseService. Der gestartete Backend-Testprozess erhält ausdrücklich eine nicht erreichbare Datenbankadresse. Echte Schema- und Lookup-Abfragen wurden separat ausschließlich lesend geprüft. Eine reale Neuanlage samt Verarbeitung durch PHP, Fahrergerät und Abrechnung wurde nicht gegen den produktiven Bestand ausgeführt. Diese fachliche Abnahme ist noch erforderlich; erfolgreiche Unit-/Browserprüfungen ersetzen sie nicht.
Bestehende Aufträge neu kalkulieren – 13. Oktober 2026
Unter „Bearbeiten / Aktionen“ ist eine Preisvorschau mit anschließender Übernahme verfügbar. Berechnet werden die gespeicherten Stationen zur vorhandenen Auftragszeit; angeboten werden Tarif-, Kilometer-/PZM-, Fest- und Leistungspreise sowie Kostensplit. Aufträge mit bereits verbundenen Unternehmeraufträgen oder vorhandenen Einnahmen sind noch nicht für diese Nachkalkulation freigegeben. Die Vorschau enthält Alt-/Neupreise, Bestandteile und gegebenenfalls Verteilung. Rechte, Versionen und Frachtvergütungsgrenzen werden beim Speichern erneut geprüft; ein wiederholter Speicheraufruf erzeugt keine zusätzliche Buchung. Lagerbewegungen, Fahrerstatus, Fotos und Quittungen werden nicht wiederholt. Unabhängige Unfertig-Gründe werden durch die Neukalkulation nicht aufgehoben.
Neue Aufträge erhalten den Wert und Text der Zahlungsbedingung als separaten Snapshot in genericdatacontainer; jobprice.mt_sort=16 bleibt für vorhandene Kilometerpositionen unangetastet. Abrechnung und CSV lesen vorrangig diesen Snapshot, bei Altaufträgen die vorhandene PHP-Zahlungsbedingung. Fehlt ein historischer Wert, wird keiner aus dem aktuellen Kundenstamm erfunden.