ProductionOrderDeliveryController.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Http\Controllers;
  4. use App\Enums\ProductionOrderNotificationEvent;
  5. use App\Http\Requests\SaveProductionOrderDeliveryRequest;
  6. use App\Models\ProductionOrder;
  7. use App\Models\ProductionOrderDelivery;
  8. use App\Services\ProductionOrderPlanningService;
  9. use App\Services\NotificationService;
  10. use Carbon\CarbonImmutable;
  11. use Carbon\CarbonInterface;
  12. use Illuminate\Contracts\View\View;
  13. use Illuminate\Http\RedirectResponse;
  14. use Illuminate\Http\Request;
  15. class ProductionOrderDeliveryController extends Controller
  16. {
  17. public function index(Request $request): View
  18. {
  19. $validated = $request->validate([
  20. 'week' => ['nullable', 'date'],
  21. ]);
  22. $weekStart = CarbonImmutable::parse($validated['week'] ?? now())
  23. ->startOfWeek(CarbonInterface::MONDAY);
  24. $weekEnd = $weekStart->endOfWeek(CarbonInterface::SUNDAY);
  25. $days = collect(range(0, 6))->mapWithKeys(static function (int $offset) use ($weekStart): array {
  26. $date = $weekStart->addDays($offset);
  27. return [$date->toDateString() => $date];
  28. });
  29. $deliveries = ProductionOrderDelivery::query()
  30. ->whereBetween('delivery_date', [$weekStart->toDateString(), $weekEnd->toDateString()])
  31. ->with(['productionOrder', 'driver'])
  32. ->orderBy('delivery_date')
  33. ->orderBy('delivery_time')
  34. ->orderBy('id')
  35. ->get()
  36. ->groupBy(fn (ProductionOrderDelivery $delivery): string => $delivery->delivery_date->toDateString());
  37. $nav = $this->startNavigationContext($request);
  38. return view('production_order_deliveries.index', [
  39. 'active' => 'schedule_deliveries',
  40. 'title' => 'График доставок',
  41. 'days' => $days,
  42. 'deliveries' => $deliveries,
  43. 'weekStart' => $weekStart,
  44. 'weekEnd' => $weekEnd,
  45. 'previousWeek' => $weekStart->subWeek()->toDateString(),
  46. 'nextWeek' => $weekStart->addWeek()->toDateString(),
  47. 'nav' => $nav,
  48. ]);
  49. }
  50. public function store(
  51. SaveProductionOrderDeliveryRequest $request,
  52. ProductionOrder $productionOrder,
  53. ProductionOrderPlanningService $service,
  54. NotificationService $notificationService,
  55. ): RedirectResponse {
  56. $delivery = $service->createDelivery($productionOrder, $request->validated(), $request->user());
  57. $notificationService->notifyProductionOrderEvent(
  58. $productionOrder,
  59. ProductionOrderNotificationEvent::DeliveryAdded,
  60. $request->user(),
  61. delivery: $delivery->load('driver'),
  62. );
  63. return $this->redirectToOrder($request, $productionOrder)
  64. ->with('success', 'Доставка добавлена.');
  65. }
  66. public function update(
  67. SaveProductionOrderDeliveryRequest $request,
  68. ProductionOrder $productionOrder,
  69. ProductionOrderDelivery $delivery,
  70. ProductionOrderPlanningService $service,
  71. ): RedirectResponse {
  72. $this->assertBelongsToOrder($productionOrder, $delivery);
  73. $service->updateDelivery($delivery, $request->validated(), $request->user());
  74. return $this->redirectToOrder($request, $productionOrder)
  75. ->with('success', 'Доставка обновлена.');
  76. }
  77. public function destroy(
  78. Request $request,
  79. ProductionOrder $productionOrder,
  80. ProductionOrderDelivery $delivery,
  81. ProductionOrderPlanningService $service,
  82. ): RedirectResponse {
  83. $this->assertBelongsToOrder($productionOrder, $delivery);
  84. $service->deleteDelivery($delivery);
  85. return $this->redirectToOrder($request, $productionOrder)
  86. ->with('success', 'Доставка удалена.');
  87. }
  88. private function assertBelongsToOrder(
  89. ProductionOrder $order,
  90. ProductionOrderDelivery $delivery,
  91. ): void {
  92. abort_unless($delivery->production_order_id === $order->id, 404);
  93. }
  94. private function redirectToOrder(Request $request, ProductionOrder $order): RedirectResponse
  95. {
  96. return redirect()->route('schedule.orders.show', $this->withNav(
  97. ['productionOrder' => $order],
  98. $this->resolveNavToken($request),
  99. ));
  100. }
  101. }