Skip to content

Manueller Produktionsauftrag Modul

Das Modul bildet den EDBS-Prozess „Produktion manuell" auf dem Scanner und im Web ab. Der Anwender wählt einen Produktionsauftrag aus dem EDBS und passt die produzierten Mengen an. Bisher war das nur direkt im EDBS möglich.

Das Modul läuft neben dem älteren Modul manualProduction. Beide teilen keinen Code und keine Tabelle. manualProduction erfasst Eingangsmaterial je Auftrag. manualProductionV2 pflegt die Ausgangsmengen eines EDVA-Auftrags.

Architektur

Modulstruktur

src/modules/manualProductionV2/
├── assets/
│   └── ManualProductionV2Asset.php         # Asset-Bundle für booking-form.js
├── controllers/
│   └── OrderController.php                 # Web: Liste, Auftragsansicht, Buchung
├── messages/
│   └── de/
│       └── manualproductionv2.php          # Übersetzungen
├── migrations/                             # Namespace: app\modules\manualProductionV2\migrations
│   ├── M260818080000AddManualProductionV2License.php
│   ├── M260818081000CreateProductionTable.php
│   └── M260818082000AddProdOrderDtoTemplateSetting.php
├── models/
│   ├── db/
│   │   ├── ProductionBase.php              # Schema-Abbild der Tabelle production
│   │   └── Production.php                  # Domänenlogik: Deltas, Merge, Guard
│   └── search/
│       └── ProdOrderSearch.php             # Filtermodell der Weboberfläche
├── modules/
│   └── rest/
│       ├── Module.php                      # REST-Submodul
│       ├── controllers/v1/
│       │   ├── OrderController.php         # Lesen
│       │   └── BookingController.php       # Schreiben
│       └── models/dto/
│           ├── ProdOrderDto.php            # Antwort inklusive htmlLabel
│           └── BookingDto.php              # Anfrage
├── views/order/
│   ├── index.php                           # GridView der Aufträge
│   └── detail.php                          # Auftragsansicht mit Eingabefeldern
├── web/js/
│   └── booking-form.js                     # Zugang und Gesamtmenge synchron halten
└── Module.php                              # Modul-Bootstrap, Sidebar, i18n

Das EDBS-Lesemodell liegt nach Konvention außerhalb des Moduls in src/models/edbs/ProdOrder.php.

Datenfluss

  • Lesen. ProdOrder liest die View EDBSOn.EDBSOnManProdAuftrag über Yii::$app->edbs_db. Der Zugriff ist read-only.
  • Schreiben. Scanner und Web erzeugen Zeilen in der lokalen Tabelle production mit edbs_fetched_date = NULL.
  • Abholen. Der EDBS-Worker liest die nicht abgeholten Zeilen, addiert die Deltas im ERP und stempelt edbs_fetched_date.
  • Anzeigen. Der aktuelle Wert eines Feldes ist der EDBS-Live-Wert plus die Summe der nicht abgeholten Deltas. Der Anwender sieht seine Eingabe damit sofort, auch vor dem nächsten Worker-Lauf.

EDBS-View

Die View EDBSOn.EDBSOnManProdAuftrag entsteht über php yii migrate-edbs. Sie liefert alle sao.EDVA-Datensätze mit I_EDVA > 0 und DT_DELETED IS NULL, verbunden mit TYPELOOKUP_M und TYPEDETAIL_M für den lesbaren Statustext.

Spalte der ViewEDVA-FeldBeschreibung
edva_idI_EDVAPrimärschlüssel, Buchungsschlüssel
statusN_STATUS5 ist „Produktion manuell"
status_descLookupStatustext für die Anzeige
trvp_countN_TRVPQUANTKoli, beschreibbar
abfall_gewichtN_ABFALLAbfallgewicht, beschreibbar
ausschuss_gewichtN_AUSSCHUSSAusschussgewicht, beschreibbar
zweitware_gewichtN_ZWEITEWAREZweite Ware Gewicht, beschreibbar
chargennummerS_INTERNVANRSchlüssel der RV und der Weboberfläche
artikel_descS_FRUITDESCFrucht
auftragsbezeichnungS_VADESCBezeichnung
gebinde_descS_PACKDESCVerpackung
auftragsdatumD_VADATEFertigungsdatum
erstelldatumDT_INSERTEDSortierung der Liste

ProdOrder ist ein yii\db\ActiveRecord auf dieser View. Die View trägt keinen Primärschlüssel, deshalb gibt primaryKey() die Spalte edva_id zurück. Die Finder heißen findAllActiveEdbs(), findEdbs($chargeNr) und findByIdEdbs($edbsVaId). Alle laufen über findActive(), das nach erstelldatum absteigend sortiert.

Datenmodell

production

Buchungsjournal des Moduls. Jede Buchung schreibt eine neue Zeile mit vorzeichenbehafteten Deltas. Zeilen werden nie geändert und nie gelöscht. Eine Korrektur ist eine neue Zeile mit umgekehrtem Vorzeichen.

SpalteTypBeschreibung
idintPrimary Key
edbs_va_idintEDVA.I_EDVA, Gruppierungsschlüssel
intern_va_nrstring(45)EDVA.S_INTERNVANR, Chargennummer
TRVP_countintDelta Koli, EDBS N_TRVPQUANT
abfall_gewichtdecimal(10,3)Delta Abfallgewicht in kg, EDBS N_ABFALL
zweite_ware_gewichtdecimal(10,3)Delta Zweite Ware in kg, EDBS N_ZWEITEWARE
ausschussgewichtdecimal(10,3)Delta Ausschuss in kg, EDBS N_AUSSCHUSS
fk_user_idintFK auf user, Verursacher der Buchung
createddatetimeAutomatischer Timestamp
modifieddatetimeAutomatischer Timestamp bei Änderung
edbs_fetched_datedatetimeVom EDBS-Worker gesetzt, NULL heißt offen
madtinyintSoft-Delete

Die Spaltennamen der vier Mengenfelder sind Teil des Vertrags mit dem EDBS-Worker.

Domänenlogik

Production::book(ProdOrder $order, array $values) ist der einzige Einstieg für REST und Web.

  1. normalizeDeltas() prüft die Feldnamen gegen Production::VALUE_COLUMNS, rundet auf die Genauigkeit der Spalte und verwirft leere Felder sowie Deltas, die auf null runden.
  2. Bleibt nichts übrig, endet die Buchung mit BadRequestHttpException.
  3. getCurrentValues() liest den EDBS-Live-Wert und addiert die nicht abgeholten Deltas.
  4. guardCumulated() lehnt jedes Feld ab, dessen kumulierter Wert unter null fiele.
  5. Alle Deltas landen in einer Zeile. Eine Buchung ist damit ohne Transaktion vollständig oder gar nicht.

VALUE_COLUMNS verbindet Journalspalte und View-Spalte. Die Namen unterscheiden sich, weil das Journal dem Ticket folgt und die View dem EDBS:

JournalspalteSpalte der View
TRVP_counttrvp_count
abfall_gewichtabfall_gewicht
zweite_ware_gewichtzweitware_gewicht
ausschussgewichtausschuss_gewicht

REST API

Basis /manualProductionV2/rest/v1/. Authentifizierung über Bearer Token oder die Web-Session. Rollen admin und storeman.

MethodeEndpunktBeschreibung
GET/order/activeAlle Aufträge im Status 5 mit aktuellen Werten
GET/order/info?chargeNr=Auftragsdetail zu einer Chargennummer inklusive htmlLabel
POST/booking/createMengenänderung buchen

order/active und order/info

Je Auftrag steht unter values ein Eintrag pro beschreibbarem Feld:

json
"values": {
  "TRVP_count": { "edbs": 480, "unfetched": 20, "current": 500 }
}

current ist der Bezugswert für eine Gesamtmengen-Eingabe im Client. order/active holt die nicht abgeholten Summen für die ganze Liste mit einer Abfrage.

booking/create

json
{
  "edbsVaId": 41287,
  "values": { "TRVP_count": 8, "abfall_gewicht": 2.5 }
}

Jeder Wert ist ein Delta. Der Server kennt keine Gesamtmenge. Ein Client, der eine Gesamtmenge eingeben lässt, rechnet vorher um: Delta = neue Gesamtmenge - current. Die Antwort ist der Auftrag nach der Buchung.

Fehlercodes: 400 bei unbekanntem Feld, nicht numerischem Wert, leerer Buchung oder verletztem Guard. 404 bei unbekanntem Auftrag. 405 bei falscher Methode.

Die Rückverfolgbarkeit braucht keinen eigenen Endpunkt. Der Scanner ruft dafür GET /tracing/rest/v1/production/info?scancode=<Chargennummer> auf.

Web-Controller

OrderController

ActionMethodeBeschreibung
actionIndexGETGridView der Aufträge, gefiltert und sortiert über ProdOrderSearch
actionDetailGETAuftragsansicht zu chargeNr aus dem URL-Parameter
actionBookPOSTBuchung schreiben, danach Redirect auf actionDetail

actionDetail nimmt denselben Parameter wie tracing/trace/detail. Beide Ansichten verlinken sich gegenseitig. Die Liste bietet je Zeile zwei Schaltflächen, eine in die Rückverfolgbarkeit und eine in die Auftragsansicht.

Die Auftragsansicht zeigt je Feld den EDBS-Wert, die nicht abgeholte Summe und den aktuellen Wert. Daneben stehen zwei Eingabefelder, „Zugang" und „Neue Gesamtmenge". web/js/booking-form.js hält beide synchron. Abgeschickt wird nur der Zugang.

Gewichte erscheinen mit drei Nachkommastellen und der Einheit kg. Koli erscheint ohne Einheit als ganze Zahl. Die Formatierung läuft über den formatter mit Locale de-DE.

Settings

KeyModulTypBeschreibung
ProdOrderDto_templatereststringHTML-Template des Auftragskopfs für den Scanner

Das Template wird von ProdOrderDto::getHtmlLabel() über den StringTemplateParser gerendert. ProdOrderDto ist im Template-Editor unter src/controllers/admin/TemplateEditorController.php registriert.

Module::initSideBar() fügt den Eintrag „Manuelle Produktion" mit dem Gewicht 900 hinzu. Ziel ist /manualProductionV2/order/index. Der Eintrag erscheint nur bei aktiver Lizenz.

Internationalisierung

Übersetzungskategorie: manualproductionv2 Basispfad: @app/modules/manualProductionV2/messages Konfiguriert in Module::initConfig(). Fehlertexte laufen über die globale Kategorie error.

Lizenzierung

Das Modul ist lizenzbasiert. Die Lizenz manualProductionV2 muss in der Tabelle licenses aktiviert sein. Das Modul ist als Scanner-Modul markiert.

Tests

DateiUmfang
tests/codeception/unit/ManualProductionBookingTest.phpDeltas, Merge, Guards, nicht abgeholte Summen
tests/codeception/functional/rest/manualProductionV2/…Cest.phpAuthentifizierung, Methoden, Validierung der REST-API
tests/codeception/functional/web/manualProductionV2/…WebCest.phpZugriffsschutz und Methoden der Weboberfläche

Alles hinter der Validierung liest live aus dem EDBS. Dieser Teil ist bewusst nicht getestet. Die Rechenlogik ist EDBS-frei über Unit-Tests abgedeckt.

Offene Punkte

  • Der Statusfilter in ProdOrder::findActive() ist derzeit auskommentiert. Liste und Finder liefern damit alle Produktionsaufträge, nicht nur Status 5.
  • Ein Fetch-HealthCheck für die Tabelle production fehlt noch. Vorlage ist src/checks/fetch_checks/EdbsFetchCheck_Base.php.
  • Der EDBS-Worker muss die Deltas addieren, nicht setzen. Das ist mit dem EDBS-Team zu bestätigen.

ITeas iScan Applikation Dokumentation

Version: dev-develop Version: dev-develop
Commit: 4d5bbe3c
Deployed at: 2026-09-07T14:12:35Z