25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

94 lines
2.7KB

  1. <?php
  2. namespace App\Http\Controllers\Items;
  3. use App\Models\Item;
  4. use App\Models\Location;
  5. use App\Models\Stock;
  6. use App\Models\StockMovement;
  7. use Framework\Routing\Router;
  8. class WithdrawStockController
  9. {
  10. public function handle(Router $router)
  11. {
  12. if (!session()->has('user_id')) {
  13. return redirect($router->route('show-register-form'));
  14. }
  15. secure();
  16. $parameters = $router->current()->parameters();
  17. $item = Item::find((int) $parameters['item']);
  18. if (!$item) {
  19. return redirect($router->route('show-items'));
  20. }
  21. $data = validate($_POST, [
  22. 'location_id' => ['required'],
  23. 'quantity' => ['required', 'positive_integer'],
  24. 'notes' => [],
  25. ], 'withdraw_errors');
  26. $location = Location::find((int) $data['location_id']);
  27. if (!$location) {
  28. return redirect($router->route('show-withdraw-stock-form', ['item' => $item->id]));
  29. }
  30. $stock = Stock::forItemAtLocation($item->id, $location->id);
  31. $quantity = (int) $data['quantity'];
  32. if ($quantity > $stock->quantity) {
  33. session()->put('withdraw_errors', [
  34. 'quantity' => ['Not enough stock at this location to withdraw that much'],
  35. ]);
  36. return redirect($router->route('show-withdraw-stock-form', ['item' => $item->id]));
  37. }
  38. $stock->quantity = $stock->quantity - $quantity;
  39. $stock->save();
  40. $movement = new StockMovement();
  41. $movement->item_id = $item->id;
  42. $movement->location_id = $location->id;
  43. $movement->type = 'withdraw';
  44. $movement->quantity_change = -$quantity;
  45. $movement->quantity_after = $stock->quantity;
  46. $movement->notes = $data['notes'] ?? '';
  47. $movement->user_id = session('user_id');
  48. $movement->save();
  49. $this->alertIfLowStock($item);
  50. return redirect($router->route('view-item', ['item' => $item->id]));
  51. }
  52. private function alertIfLowStock(Item $item): void
  53. {
  54. if ($item->reorder_level <= 0) {
  55. return;
  56. }
  57. $total = array_sum(array_map(
  58. fn($row) => $row->quantity,
  59. Stock::where('item_id', $item->id)->all(),
  60. ));
  61. if ($total > $item->reorder_level) {
  62. return;
  63. }
  64. app('queue')->push(function ($itemName, $total, $reorderLevel) {
  65. app('email')
  66. ->to(config('warehouse.alert_email'))
  67. ->subject("Low stock: {$itemName}")
  68. ->text("{$itemName} is at {$total} units, at or below its reorder level of {$reorderLevel}.")
  69. ->send();
  70. }, $item->name, $total, $item->reorder_level);
  71. }
  72. }

Powered by TurnKey Linux.