where('is_active', true) ->orderBy('sort_order') ->orderBy('created_at', 'desc') ->get() ->map(fn ($form) => [ 'id' => $form->id, 'title' => $form->title, 'description' => $form->description, 'file_url' => $form->file_url, 'file_type' => strtoupper(pathinfo($form->file_path, PATHINFO_EXTENSION)), 'direction' => $form->direction, ]); return response()->json([ 'success' => true, 'data' => $forms, ]); } /** * دریافت تعهدنامه‌ها بر اساس جهت ارسال * GET /api/v1/commitment-forms/{direction} */ public function byDirection(string $direction): JsonResponse { $forms = CommitmentForm::query() ->where('is_active', true) ->where(function ($query) use ($direction) { $query->where('direction', 'both') ->orWhere('direction', $direction); }) ->orderBy('sort_order') ->orderBy('created_at', 'desc') ->get() ->map(fn ($form) => [ 'id' => $form->id, 'title' => $form->title, 'description' => $form->description, 'file_url' => $form->file_url, 'file_type' => strtoupper(pathinfo($form->file_path, PATHINFO_EXTENSION)), 'direction' => $form->direction, ]); return response()->json([ 'success' => true, 'data' => $forms, ]); } /** * دریافت لیست تعهدنامه‌های مربوط به سفارش خاص * GET /api/v1/customer/orders/{shipment}/commitment-forms */ public function shipmentForms(Shipment $shipment): JsonResponse { $user = auth()->user(); // بررسی مالکیت if ($shipment->user_id !== $user->id) { return response()->json([ 'success' => false, 'message' => 'شما به این سفارش دسترسی ندارید.', ], 403); } $forms = CommitmentForm::query() ->where('is_active', true) ->where(function ($query) use ($shipment) { $query->where('direction', 'both') ->orWhere('direction', $shipment->direction); }) ->orderBy('sort_order') ->orderBy('created_at', 'desc') ->get(); $rows = ShipmentCommitmentForm::where('shipment_id', $shipment->id) ->whereIn('commitment_form_id', $forms->pluck('id')) ->get() ->keyBy('commitment_form_id'); // ساخت ردیف pending برای فرم‌هایی که هنوز رکورد ندارند — // تا بخش تعهدنامه‌ها در پنل ادمین همه فرم‌ها را همراه وضعیت نمایش دهد foreach ($forms as $form) { if (!isset($rows[$form->id])) { $rows[$form->id] = ShipmentCommitmentForm::create([ 'shipment_id' => $shipment->id, 'commitment_form_id' => $form->id, 'status' => 'pending', ]); } } $data = $forms->map(function ($form) use ($shipment, $rows) { $upload = $rows[$form->id]; return [ 'id' => $form->id, 'title' => $form->title, 'description' => $form->description, // 🛡️ URL دانلود قالب از طریق route محافظت‌شده (نه asset عمومی) 'file_url' => route('customer.commitment-forms.template', [ 'shipment' => $shipment->id, 'form' => $form->id, ]), 'file_type' => strtoupper(pathinfo($form->file_path, PATHINFO_EXTENSION)), 'direction' => $form->direction, 'upload_status' => $upload->status, 'uploaded_file_url' => $upload->uploaded_file_path ? route('customer.commitment-forms.download', ['shipment' => $shipment->id, 'form' => $form->id]) : null, 'uploaded_at' => $upload->created_at, 'notes' => $upload->notes, ]; }); return response()->json([ 'success' => true, 'data' => $data, ]); } /** * دانلود قالب خام تعهدنامه (محافظت‌شده با بررسی مالکیت سفارش). * GET /api/v1/customer/orders/{shipment}/commitment-forms/{form}/template */ public function downloadTemplate(Shipment $shipment, CommitmentForm $form) { $user = auth()->user(); if ($shipment->user_id !== $user->id) { return response()->json([ 'success' => false, 'message' => 'شما به این سفارش دسترسی ندارید.', ], 403); } if (!$form->file_path || !Storage::disk('public')->exists($form->file_path)) { return response()->json([ 'success' => false, 'message' => 'فایل قالب یافت نشد.', ], 404); } $ext = pathinfo($form->file_path, PATHINFO_EXTENSION); $filename = 'template-' . $form->id . '-' . $shipment->awb_no . '.' . $ext; return Storage::disk('public')->download($form->file_path, $filename); } /** * آپلود فرم تعهدنامه امضاشده * POST /api/v1/customer/orders/{shipment}/commitment-forms/{form}/upload */ public function uploadSigned(Request $request, Shipment $shipment, CommitmentForm $form): JsonResponse { $user = auth()->user(); // بررسی مالکیت if ($shipment->user_id !== $user->id) { return response()->json([ 'success' => false, 'message' => 'شما به این سفارش دسترسی ندارید.', ], 403); } $request->validate([ 'file' => 'required|file|mimes:pdf,jpg,jpeg,png|max:5120', // حداکثر 5MB 'notes' => 'nullable|string|max:1000', ]); try { $file = $request->file('file'); // 🛡️ ذخیره در دیسک امن (غیرعمومی) — فقط از طریق route محافظت‌شده قابل دانلود $path = $file->store("commitment-forms/{$shipment->id}", 'secure'); $upload = ShipmentCommitmentForm::updateOrCreate( [ 'shipment_id' => $shipment->id, 'commitment_form_id' => $form->id, ], [ 'uploaded_file_path' => $path, 'uploaded_file_type' => $file->getClientOriginalExtension(), 'uploaded_file_size' => $file->getSize(), 'status' => 'uploaded', 'notes' => $request->input('notes'), 'uploaded_by' => $user->id, ] ); return response()->json([ 'success' => true, 'message' => 'فایل با موفقیت آپلود شد.', 'data' => [ 'id' => $upload->id, 'file_url' => route('customer.commitment-forms.download', [ 'shipment' => $shipment->id, 'form' => $form->id, ]), 'file_type' => $upload->uploaded_file_type, 'status' => $upload->status, 'uploaded_at' => $upload->created_at, ], ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'خطا در آپلود فایل: ' . $e->getMessage(), ], 500); } } /** * دانلود فرم تعهدنامه امزاشده (محافظت‌شده با بررسی مالکیت). * GET /api/v1/customer/orders/{shipment}/commitment-forms/{form}/download */ public function downloadSigned(Shipment $shipment, CommitmentForm $form) { $user = auth()->user(); if ($shipment->user_id !== $user->id) { return response()->json([ 'success' => false, 'message' => 'شما به این سفارش دسترسی ندارید.', ], 403); } $upload = ShipmentCommitmentForm::where('shipment_id', $shipment->id) ->where('commitment_form_id', $form->id) ->firstOrFail(); if (!$upload->uploaded_file_path) { return response()->json([ 'success' => false, 'message' => 'فایلی برای این تعهدنامه آپلود نشده است.', ], 404); } return Storage::disk('secure')->download( $upload->uploaded_file_path, 'commitment-' . $form->id . '-' . $shipment->awb_no . '.' . $upload->uploaded_file_type ); } }