Warenwirtschaft: AP-51 — Lagerplatz-Felder für Produkte & Verpackung
Lagerplatz-Zuordnung (Raum/Regal/Fach) gab es bisher nur bei Rohstoffen. Jetzt dieselbe Storage-Hierarchie (StorageRoom/Shelf/Slot) auch für Produkte und Verpackungsartikel, inkl. Anzeige an den passenden Stellen. - Migration: storage_room_id/shelf/slot an products + packaging_items (nullable, FK constrained, nullOnDelete). - Models Product + PackagingItem: fillable + storageRoom/Shelf/Slot-Relationen + storageLabel() („Raum 1 | Regal 3 | A"). - Produktformular (Inventar-Abschnitt) + Verpackungsformular: Auswahl-Zeile Raum/Regal/Fach; Optionen kommen aktiv/sortiert aus den zentral pflegbaren Bausteinen (Einstellungen → Allgemein). - Speichern: ProductRepository normalisiert leere Auswahl -> null (FK); PackagingItem-Requests + Repository um die drei Felder erweitert. - Anzeige: Produktbestand (Sub-Zeile mit Marker), Produktverpackung-Übersicht (neue Spalte „Lagerplatz"). - DeletionGuard: Lagerbaustein ist nicht löschbar, solange Produkte/Verpackung darauf verweisen (analog Rohstoffe). Tests: 4 neue (Produkt speichern + leer->null, Verpackung speichern + Anzeige, Löschsperre, freier Baustein löschbar). Migration auf Dev-/Live-DB gelaufen. Suite 331 grün. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
eb47c8a82d
commit
30d4e28696
16 changed files with 363 additions and 5 deletions
|
|
@ -26,6 +26,9 @@ class StorePackagingItemRequest extends FormRequest
|
|||
'min_stock_alert' => ['nullable', 'integer', 'min:0'],
|
||||
'url' => ['nullable', 'string', 'url:http,https', 'max:2048'],
|
||||
'product_id' => ['nullable', 'integer', 'exists:products,id'],
|
||||
'storage_room_id' => ['nullable', 'integer', 'exists:storage_rooms,id'],
|
||||
'storage_shelf_id' => ['nullable', 'integer', 'exists:storage_shelves,id'],
|
||||
'storage_slot_id' => ['nullable', 'integer', 'exists:storage_slots,id'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
|
@ -38,7 +41,7 @@ class StorePackagingItemRequest extends FormRequest
|
|||
'weight_grams' => $this->filled('weight_grams') ? reFormatWawiNumber($this->input('weight_grams')) : null,
|
||||
]);
|
||||
|
||||
foreach (['supplier_id', 'product_id', 'min_stock_alert'] as $key) {
|
||||
foreach (['supplier_id', 'product_id', 'min_stock_alert', 'storage_room_id', 'storage_shelf_id', 'storage_slot_id'] as $key) {
|
||||
if ($this->input($key) === '' || $this->input($key) === null) {
|
||||
$this->merge([$key => null]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ class UpdatePackagingItemRequest extends FormRequest
|
|||
'min_stock_alert' => ['nullable', 'integer', 'min:0'],
|
||||
'url' => ['nullable', 'string', 'url:http,https', 'max:2048'],
|
||||
'product_id' => ['nullable', 'integer', 'exists:products,id'],
|
||||
'storage_room_id' => ['nullable', 'integer', 'exists:storage_rooms,id'],
|
||||
'storage_shelf_id' => ['nullable', 'integer', 'exists:storage_shelves,id'],
|
||||
'storage_slot_id' => ['nullable', 'integer', 'exists:storage_slots,id'],
|
||||
'active' => ['sometimes', 'boolean'],
|
||||
];
|
||||
}
|
||||
|
|
@ -38,7 +41,7 @@ class UpdatePackagingItemRequest extends FormRequest
|
|||
'weight_grams' => $this->filled('weight_grams') ? reFormatWawiNumber($this->input('weight_grams')) : null,
|
||||
]);
|
||||
|
||||
foreach (['supplier_id', 'product_id', 'min_stock_alert'] as $key) {
|
||||
foreach (['supplier_id', 'product_id', 'min_stock_alert', 'storage_room_id', 'storage_shelf_id', 'storage_slot_id'] as $key) {
|
||||
if ($this->input($key) === '' || $this->input($key) === null) {
|
||||
$this->merge([$key => null]);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue