|
- <?php
-
- namespace App\Http\Controllers\Items;
-
- use App\Models\Item;
- use App\Models\Location;
- use App\Models\Stock;
- use App\Models\StockMovement;
- use Framework\Routing\Router;
-
- class WithdrawStockController
- {
- public function handle(Router $router)
- {
- if (!session()->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'],
- 'quantity' => ['required', 'positive_integer'],
- 'notes' => [],
- ], 'withdraw_errors');
-
- $location = Location::find((int) $data['location_id']);
-
- if (!$location) {
- return redirect($router->route('show-withdraw-stock-form', ['item' => $item->id]));
- }
-
- $stock = Stock::forItemAtLocation($item->id, $location->id);
- $quantity = (int) $data['quantity'];
-
- if ($quantity > $stock->quantity) {
- session()->put('withdraw_errors', [
- 'quantity' => ['Not enough stock at this location to withdraw that much'],
- ]);
-
- return redirect($router->route('show-withdraw-stock-form', ['item' => $item->id]));
- }
-
- $stock->quantity = $stock->quantity - $quantity;
- $stock->save();
-
- $movement = new StockMovement();
- $movement->item_id = $item->id;
- $movement->location_id = $location->id;
- $movement->type = 'withdraw';
- $movement->quantity_change = -$quantity;
- $movement->quantity_after = $stock->quantity;
- $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);
- }
- }
|