Warenwirtschaft: AP-09 bis AP-13 (Produktbestand, Set-Produkte, Ausschuss, Konzepte)

- AP-09 Produktbestand inkl. Bewegungshistorie (product_stock_movements, ProductStockService)
- AP-10 Rohstoffbestand-Ansicht je Lager (RawMaterialStockController)
- AP-11 Bestandsschwellen / Out-of-Stock-Handling fuer Produkte und Shop
- AP-12 Ausgang/Ausschuss (stock_disposals, StockDisposalController, InventoryService)
- Set-Produkte (product_set_items) inkl. Aufloesung
- Produktentwicklung & Hinweise-Verwaltung (Notices)
- AP-13 Entwicklungskonzept Shop-Bestandsabzug im Plan dokumentiert
- Feature-Tests fuer neue Module + aktualisierter Entwicklungsplan

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin Adametz 2026-06-03 11:04:22 +00:00
parent 78679e0c55
commit 3ee2d756e9
63 changed files with 5968 additions and 901 deletions

View file

@ -2,6 +2,7 @@
namespace App\Http\Requests\Inventory;
use App\Models\Product;
use Illuminate\Foundation\Http\FormRequest;
class StoreProductionRequest extends FormRequest
@ -16,19 +17,28 @@ class StoreProductionRequest extends FormRequest
*/
public function rules(): array
{
$recipeRequired = $this->recipeRequired();
return [
'product_id' => ['required', 'integer', 'exists:products,id'],
'location_id' => ['required', 'integer', 'exists:locations,id'],
'produced_at' => ['required', 'date'],
'quantity' => ['required', 'integer', 'min:1'],
'notes' => ['nullable', 'string', 'max:2000'],
'ingredient_lines' => ['required', 'array', 'min:1'],
'ingredient_lines' => [$recipeRequired ? 'required' : 'nullable', 'array', $recipeRequired ? 'min:1' : 'min:0'],
'ingredient_lines.*.ingredient_id' => ['required', 'integer', 'exists:ingredients,id'],
'ingredient_lines.*.stock_entry_id' => ['required', 'integer', 'exists:stock_entries,id'],
'ingredient_lines.*.quantity_used' => ['required', 'string'],
];
}
private function recipeRequired(): bool
{
$product = Product::query()->find($this->input('product_id'));
return $product === null ? true : ! (bool) $product->no_recipe_required;
}
/**
* @return array<string, mixed>
*/
@ -48,7 +58,7 @@ class StoreProductionRequest extends FormRequest
'stock_entry_id' => (int) $line['stock_entry_id'],
'quantity_used' => $line['quantity_used'],
];
}, $data['ingredient_lines']),
}, $data['ingredient_lines'] ?? []),
];
}
}