Warenwirtschaft: AP-33a Bestell-Abwicklung — Nav „Bestellungen" + Fulfillment-Board

Neuer Nav-Punkt „Bestellungen" (Abwicklung + API-Bestellungen als Unterpunkte).
Board für Versand-Mitarbeiter (copyreader): 4 Filter-Kacheln (heute eingegangen /
zu konfektionieren / versandfertig / heute versendet), Packliste je Bestellung
(Sets mit Komponenten), Dokumente (Rechnung/Lieferschein/Kombi-Download über
eigene copyreader-Route, Erstellen ohne Mailversand; API-Bestellungen verlinken
die externe Rechnung), Aktionen Konfektioniert/Versendet (nur vorwärts, Storno
bleibt Verkäufe/admin). Versandfertig-Regel per Kundenentscheid: Rechnung sofort,
Vorkasse nach Zahlungseingang, API immer (ShoppingOrder::isReadyToShip()).
Statuswechsel-Logik in OrderStatusService extrahiert (Verkäufe-Modal + Board
teilen Transaktion/Lock/Margin-Folgen/AP-13-Abzug). Kundenentscheid Punkt 3:
Board-Statuswechsel setzt shipped_status_locked — die Bestell-Detailseiten
ändern den Status dann nicht mehr automatisch (offen → in Bearbeitung).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-16 11:30:57 +00:00
parent f1eb5fbc7f
commit a367d851f6
9 changed files with 818 additions and 71 deletions

View file

@ -196,6 +196,7 @@ class ShoppingOrder extends Model
'delivery' => 'array',
'shipped_at' => 'datetime',
'user_white_label' => 'boolean',
'shipped_status_locked' => 'boolean',
];
public static $shippedTypes = [
@ -358,6 +359,32 @@ class ShoppingOrder extends Model
return '';
}
/**
* AP-33a (Kundenentscheid 16.07.2026): „versandfertig" = bezahlte Bestellung.
* Zahlart Rechnung (fnc) gilt sofort als bezahlt (Versand vor Zahlungseingang),
* Vorkasse erst bei Geldeingang, API-Bestellungen (txaction=extern) immer.
*/
public function isReadyToShip(): bool
{
if (in_array($this->txaction, ['non', 'failed'], true)) {
return false;
}
if ($this->paid || in_array($this->txaction, ['paid', 'extern'], true)) {
return true;
}
return $this->shopping_payment_last?->clearingtype === 'fnc';
}
/**
* Über die Partnercenter-API (WooCommerce) übertragene Bestellung — Rechnung
* existiert im externen Shop (wp_invoice_path), im System wird keine erstellt.
*/
public function isApiOrder(): bool
{
return $this->txaction === 'extern' || $this->wp_invoice_path !== null;
}
public function getShippedType()
{
return isset(self::$shippedTypes[$this->shipped]) ? self::$shippedTypes[$this->shipped] : '';