ProductionOrderDocumentController.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Http\Controllers;
  4. use App\Jobs\GenerateProductionOrderFileJob;
  5. use App\Models\File;
  6. use App\Models\ProductionOrder;
  7. use App\Models\ProductionOrderDelivery;
  8. use App\Models\ProductionOrderInstallation;
  9. use App\Models\Role;
  10. use App\Services\ProductionOrderDocumentService;
  11. use Illuminate\Http\RedirectResponse;
  12. use Illuminate\Http\Request;
  13. use Illuminate\Support\Facades\Storage;
  14. use Illuminate\Support\Str;
  15. use Symfony\Component\HttpFoundation\StreamedResponse;
  16. class ProductionOrderDocumentController extends Controller
  17. {
  18. public function exportItems(Request $request, ProductionOrder $productionOrder): RedirectResponse
  19. {
  20. $this->dispatch($request, $productionOrder, ProductionOrderDocumentService::TYPE_ITEMS);
  21. return back()->with('success', 'Задача экспорта МАФ создана.');
  22. }
  23. public function deliveryRequest(
  24. Request $request,
  25. ProductionOrder $productionOrder,
  26. ProductionOrderDelivery $delivery,
  27. ): RedirectResponse {
  28. $this->assertDeliveryBelongsToOrder($productionOrder, $delivery);
  29. $this->dispatch(
  30. $request,
  31. $productionOrder,
  32. ProductionOrderDocumentService::TYPE_DELIVERY,
  33. $delivery->id,
  34. );
  35. return back()->with('success', 'Задача формирования заявки на доставку создана.');
  36. }
  37. public function installationPack(
  38. Request $request,
  39. ProductionOrder $productionOrder,
  40. ProductionOrderInstallation $installation,
  41. ): RedirectResponse {
  42. $this->assertInstallationBelongsToOrder($productionOrder, $installation);
  43. $this->dispatch(
  44. $request,
  45. $productionOrder,
  46. ProductionOrderDocumentService::TYPE_INSTALLATION,
  47. $installation->id,
  48. );
  49. return back()->with('success', 'Задача формирования монтажного пакета создана.');
  50. }
  51. public function technicalDocuments(Request $request, ProductionOrder $productionOrder): RedirectResponse
  52. {
  53. $validated = $request->validate([
  54. 'item_ids' => ['required', 'array', 'min:1'],
  55. 'item_ids.*' => ['required', 'integer', 'distinct'],
  56. ]);
  57. $itemIds = collect($validated['item_ids'])->map(static fn ($id): int => (int) $id)->values();
  58. abort_unless(
  59. $productionOrder->items()->whereKey($itemIds)->count() === $itemIds->count(),
  60. 404,
  61. );
  62. $this->dispatch(
  63. $request,
  64. $productionOrder,
  65. ProductionOrderDocumentService::TYPE_TECHNICAL_DOCUMENTS,
  66. itemIds: $itemIds->all(),
  67. );
  68. return back()->with('success', 'Задача архивации техдокументации создана.');
  69. }
  70. public function download(Request $request, File $file): StreamedResponse
  71. {
  72. abort_unless($file->is_generated, 404);
  73. abort_unless(Str::startsWith((string) $file->path, 'generated/production-orders/'), 404);
  74. abort_unless(
  75. (int) $file->user_id === (int) $request->user()->id
  76. || $request->user()->hasRole(Role::ADMIN),
  77. 403,
  78. );
  79. abort_unless(Storage::disk('local')->exists((string) $file->path), 404);
  80. return Storage::disk('local')->download((string) $file->path, (string) $file->original_name);
  81. }
  82. /** @param list<int> $itemIds */
  83. private function dispatch(
  84. Request $request,
  85. ProductionOrder $order,
  86. string $type,
  87. ?int $relatedId = null,
  88. array $itemIds = [],
  89. ): void {
  90. GenerateProductionOrderFileJob::dispatch(
  91. $type,
  92. $order->id,
  93. (int) $request->user()->id,
  94. $relatedId,
  95. $itemIds,
  96. );
  97. }
  98. private function assertDeliveryBelongsToOrder(
  99. ProductionOrder $order,
  100. ProductionOrderDelivery $delivery,
  101. ): void {
  102. abort_unless((int) $delivery->production_order_id === (int) $order->id, 404);
  103. }
  104. private function assertInstallationBelongsToOrder(
  105. ProductionOrder $order,
  106. ProductionOrderInstallation $installation,
  107. ): void {
  108. abort_unless((int) $installation->production_order_id === (int) $order->id, 404);
  109. }
  110. }