SparePartReservationController.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Models\Reservation;
  4. use App\Models\Shortage;
  5. use App\Services\SparePartIssueService;
  6. use App\Services\SparePartReservationService;
  7. use Illuminate\Http\JsonResponse;
  8. use Illuminate\Http\RedirectResponse;
  9. use Illuminate\Http\Request;
  10. /**
  11. * Контроллер управления резервами запчастей
  12. */
  13. class SparePartReservationController extends Controller
  14. {
  15. public function __construct(
  16. protected SparePartReservationService $reservationService,
  17. protected SparePartIssueService $issueService
  18. ) {}
  19. /**
  20. * Список резервов для рекламации (API)
  21. */
  22. public function forReclamation(int $reclamationId): JsonResponse
  23. {
  24. $reservations = $this->reservationService->getReservationsForReclamation($reclamationId);
  25. return response()->json([
  26. 'reservations' => $reservations->map(fn($r) => [
  27. 'id' => $r->id,
  28. 'spare_part_id' => $r->spare_part_id,
  29. 'article' => $r->sparePart->article,
  30. 'used_in_maf' => $r->sparePart->used_in_maf,
  31. 'reserved_qty' => $r->reserved_qty,
  32. 'with_documents' => $r->with_documents,
  33. 'status' => $r->status,
  34. 'order_id' => $r->spare_part_order_id,
  35. 'created_at' => $r->created_at->format('d.m.Y H:i'),
  36. ]),
  37. ]);
  38. }
  39. /**
  40. * Дефициты для рекламации (API)
  41. */
  42. public function shortagesForReclamation(int $reclamationId): JsonResponse
  43. {
  44. $shortages = Shortage::query()
  45. ->where('reclamation_id', $reclamationId)
  46. ->with('sparePart')
  47. ->get();
  48. return response()->json([
  49. 'shortages' => $shortages->map(fn($s) => [
  50. 'id' => $s->id,
  51. 'spare_part_id' => $s->spare_part_id,
  52. 'article' => $s->sparePart->article,
  53. 'used_in_maf' => $s->sparePart->used_in_maf,
  54. 'required_qty' => $s->required_qty,
  55. 'reserved_qty' => $s->reserved_qty,
  56. 'missing_qty' => $s->missing_qty,
  57. 'with_documents' => $s->with_documents,
  58. 'status' => $s->status,
  59. 'coverage_percent' => $s->coverage_percent,
  60. 'created_at' => $s->created_at->format('d.m.Y H:i'),
  61. ]),
  62. ]);
  63. }
  64. /**
  65. * Отменить резерв
  66. */
  67. public function cancel(Request $request, Reservation $reservation): RedirectResponse
  68. {
  69. $reason = $request->input('reason', 'Отмена пользователем');
  70. if (!$reservation->isActive()) {
  71. return back()->with(['error' => 'Резерв не активен!']);
  72. }
  73. $this->reservationService->cancelReservation($reservation, $reason);
  74. return back()->with(['success' => 'Резерв отменён!']);
  75. }
  76. /**
  77. * Списать резерв (выполнить отгрузку)
  78. */
  79. public function issue(Request $request, Reservation $reservation): RedirectResponse
  80. {
  81. $note = $request->input('note', '');
  82. if (!$reservation->isActive()) {
  83. return back()->with(['error' => 'Резерв не активен!']);
  84. }
  85. try {
  86. $this->issueService->issueReservation($reservation, $note);
  87. return back()->with(['success' => 'Списание выполнено!']);
  88. } catch (\Exception $e) {
  89. return back()->with(['error' => $e->getMessage()]);
  90. }
  91. }
  92. /**
  93. * Списать все резервы для рекламации
  94. */
  95. public function issueAllForReclamation(Request $request, int $reclamationId): RedirectResponse
  96. {
  97. $results = $this->issueService->issueForReclamation($reclamationId);
  98. $totalIssued = array_sum(array_map(fn($r) => $r->issued, $results));
  99. return back()->with([
  100. 'success' => "Списано запчастей: {$totalIssued} шт."
  101. ]);
  102. }
  103. /**
  104. * Отменить все резервы для рекламации
  105. */
  106. public function cancelAllForReclamation(Request $request, int $reclamationId): RedirectResponse
  107. {
  108. $reason = $request->input('reason', 'Массовая отмена');
  109. $totalCancelled = $this->reservationService->cancelForReclamation($reclamationId);
  110. return back()->with([
  111. 'success' => "Отменено резервов на {$totalCancelled} шт."
  112. ]);
  113. }
  114. }