has('user_id')) { return redirect($router->route('show-register-form')); } secure(); $parameters = $router->current()->parameters(); $item = Item::find((int) $parameters['item']); if (!$item) { return redirect($router->route('show-items')); } $data = validate($_POST, [ 'location_id' => ['required'], // not ['required'] - PHP's empty("0") is true, which would reject // a legitimate "set this to zero" adjustment before it reaches // the ctype_digit check below (which does allow zero). 'quantity' => [], 'notes' => [], ], 'adjust_errors'); if (!isset($data['quantity']) || !ctype_digit((string) $data['quantity'])) { session()->put('adjust_errors', [ 'quantity' => ['quantity must be a whole number, 0 or greater'], ]); return redirect($router->route('show-adjust-stock-form', ['item' => $item->id])); } $location = Location::find((int) $data['location_id']); if (!$location) { return redirect($router->route('show-adjust-stock-form', ['item' => $item->id])); } $stock = Stock::forItemAtLocation($item->id, $location->id); $newQuantity = (int) $data['quantity']; $change = $newQuantity - $stock->quantity; $stock->quantity = $newQuantity; $stock->save(); $movement = new StockMovement(); $movement->item_id = $item->id; $movement->location_id = $location->id; $movement->type = 'adjustment'; $movement->quantity_change = $change; $movement->quantity_after = $newQuantity; $movement->notes = $data['notes'] ?? ''; $movement->user_id = session('user_id'); $movement->save(); $this->alertIfLowStock($item); return redirect($router->route('view-item', ['item' => $item->id])); } private function alertIfLowStock(Item $item): void { if ($item->reorder_level <= 0) { return; } $total = array_sum(array_map( fn($row) => $row->quantity, Stock::where('item_id', $item->id)->all(), )); if ($total > $item->reorder_level) { return; } app('queue')->push(function ($itemName, $total, $reorderLevel) { app('email') ->to(config('warehouse.alert_email')) ->subject("Low stock: {$itemName}") ->text("{$itemName} is at {$total} units, at or below its reorder level of {$reorderLevel}.") ->send(); }, $item->name, $total, $item->reorder_level); } }