From c9cc74ec487ab97ea828a12587b735b54e983e04 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Mon, 16 Jun 2025 10:49:04 +0330 Subject: [PATCH] separate operator from supervisor in road item --- .../Dashboard/RoadItem/DetailController.php | 29 ++++ .../OperatorController.php} | 151 +++++------------- .../RoadItem/SupervisorController.php | 117 ++++++++++++++ .../StoreRequest.php | 2 +- .../V3/RoadItem/Supervisor/ConfirmRequest.php | 30 ++++ .../V3/RoadItem/Supervisor/RejectRequest.php | 30 ++++ .../UpdateRequest.php | 2 +- .../VerifyBySupervisorRequest.php | 2 +- .../Cartables/RoadItem/OperatorService.php | 30 ++++ .../Cartables/RoadItem/SupervisorService.php | 46 ++++++ ...2407_add_column_to_road_items_projects.php | 28 ++++ routes/v3.php | 71 ++++---- 12 files changed, 384 insertions(+), 154 deletions(-) create mode 100644 app/Http/Controllers/V3/Dashboard/RoadItem/DetailController.php rename app/Http/Controllers/V3/Dashboard/{RoadItemsProjectController.php => RoadItem/OperatorController.php} (60%) create mode 100644 app/Http/Controllers/V3/Dashboard/RoadItem/SupervisorController.php rename app/Http/Requests/V3/{RoadItemsProject => RoadItem}/StoreRequest.php (98%) create mode 100644 app/Http/Requests/V3/RoadItem/Supervisor/ConfirmRequest.php create mode 100644 app/Http/Requests/V3/RoadItem/Supervisor/RejectRequest.php rename app/Http/Requests/V3/{RoadItemsProject => RoadItem}/UpdateRequest.php (96%) rename app/Http/Requests/V3/{RoadItemsProject => RoadItem}/VerifyBySupervisorRequest.php (94%) create mode 100644 app/Services/Cartables/RoadItem/OperatorService.php create mode 100644 app/Services/Cartables/RoadItem/SupervisorService.php create mode 100644 database/migrations/2025_06_16_092407_add_column_to_road_items_projects.php diff --git a/app/Http/Controllers/V3/Dashboard/RoadItem/DetailController.php b/app/Http/Controllers/V3/Dashboard/RoadItem/DetailController.php new file mode 100644 index 00000000..dc6d3efd --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/RoadItem/DetailController.php @@ -0,0 +1,29 @@ +successResponse($roadItemsProject->cmmsMachines()->get(['cmms_machines.id', 'cmms_machines.machine_code', 'cmms_machines.car_name', 'cmms_machines.plak_number'])); + } + + public function rahdaran(RoadItemsProject $roadItemsProject): JsonResponse + { + return $this->successResponse($roadItemsProject->rahdaran()->get(['rahdaran.id', 'rahdaran.name', 'rahdaran.code'])); + } + + public function files(RoadItemsProject $roadItemsProject): JsonResponse + { + return $this->successResponse($roadItemsProject->files()->get(['path'])); + } +} diff --git a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadItem/OperatorController.php similarity index 60% rename from app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php rename to app/Http/Controllers/V3/Dashboard/RoadItem/OperatorController.php index bcb9e6fb..d3a0a9ab 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadItem/OperatorController.php @@ -1,130 +1,51 @@ supervisorCartableReport($request); - - foreach ($data['data'] as $road_item) { - if (Gate::allows('gate-supervise-road-item', $road_item)) { - $road_item['can_supervise'] = 1; - } else { - $road_item['can_supervise'] = 0; - } - } - + $data = $operatorService->dataTable($request); return response()->json($data); } - public function verifyBySupervisor(VerifyBySupervisorRequest $request, RoadItemsProject $roadItemsProject): JsonResponse + public function excel(Request $request, OperatorService $operatorService): BinaryFileResponse { - $status_fa = $request->verify == 1 ? 'تایید شده' : 'عدم تایید'; - $user = auth()->user(); - - $roadItemsProject->update([ - 'status' => $request->verify, - 'status_fa' => $status_fa, - 'supervisor_id' => $user->id, - 'supervisor_name' => $user->name, - 'supervisor_description' => $request->description, - 'supervising_time' => now(), - ]); - - $user->addActivityComplete(1149); - - return $this->successResponse(); - } - - public function restore(RoadItemsProject $roadItemsProject): JsonResponse - { - if ($roadItemsProject->status == 0) { - return $this->errorResponse('امکان بازگردانی وضعیت این فعالیت وجود ندارد!'); - } - - $roadItemsProject->update([ - 'status' => 0, - 'status_fa' => 'در حال بررسی', - 'supervisor_id' => null, - 'supervisor_description' => null, - 'supervising_time' => null, - 'supervisor_name' => null, - ]); - auth()->user()->addActivityComplete(1150); - - return $this->successResponse(); - } - - public function delete(RoadItemsProject $roadItemsProject): JsonResponse - { - if ($roadItemsProject->files()->exists()) { - Storage::delete('public/'. $roadItemsProject->files[0]->path); - Storage::delete('public/'. $roadItemsProject->files[1]->path); - $roadItemsProject->files()->delete(); - } - auth()->user()->addActivityComplete(1151); - - $roadItemsProject->delete(); - - return $this->successResponse(); - } - - - public function supervisorCartableReport(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse - { - $name = 'گزارش از کارتابل ارزیابی فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadItemTableService->supervisorCartableReport($request, true); - return Excel::download(new SupervisorCartableReport($data['data']), $name); - } - - public function operatorIndex(Request $request, RoadItemTableService $roadItemTableService): JsonResponse - { - $data = $roadItemTableService->operatorCartableReport($request); - return response()->json($data); + $name = 'گزارش از کارتابل عملیات فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; + $data = $operatorService->dataTable($request, true); + return Excel::download(new OperatorCartableReport($data['data']), $name); } /** * Store a newly created resource in storage. - * @throws ValidationException + * @throws \Throwable */ - public function store(StoreRequest $request, NominatimService $nominatimService): JsonResponse + public function store(Request $request, NominatimService $nominatimService): JsonResponse { $user = auth()->user(); - if ($user->edarate_ostani_id || is_null($user->city_id)) { - return $this->errorResponse('امکان ثبت فعالیت برای ادارات استانی و ستادی وجود ندارد!'); - } - - if (is_null($user->edarate_shahri_id)) { - return $this->errorResponse('اداره شهری برای شما در سامانه ثبت نشده است!'); - } - $info_item = InfoItem::query()->where('item', $request->item_id) ->where('sub_item', $request->sub_item_id) ->firstOrFail(); @@ -184,9 +105,7 @@ class RoadItemsProjectController extends Controller $road_item = RoadItemsProject::store($user, $attributes, $before_image, $after_image, $request->observed_item_id); - if ($road_item === -1) { - return $this->errorResponse('اقدام مربوطه قبلا رسیدگی شده است.'); - } + throw_if($road_item === -1, new ProhibitedAction('اقدام مربوطه قبلا رسیدگی شده است.')); $road_item->rahdaran()->attach($request->rahdaran_id); $road_item->cmmsMachines()->attach($request->machines_id); @@ -197,10 +116,17 @@ class RoadItemsProjectController extends Controller } /** - * Update the specified resource in storage. - * @throws ValidationException + * Display the specified resource. */ - public function update(UpdateRequest $request, RoadItemsProject $roadItemsProject): JsonResponse + public function show(RoadItemsProject $roadItemsProject): JsonResponse + { + return $this->successResponse($roadItemsProject); + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, RoadItemsProject $roadItemsProject): JsonResponse { $info_item = InfoItem::query()->where('item', $roadItemsProject->item) ->where('sub_item', $roadItemsProject->sub_item) @@ -264,25 +190,20 @@ class RoadItemsProjectController extends Controller return $this->successResponse(); } - public function operatorCartableReport(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse + /** + * Remove the specified resource from storage. + */ + public function destroy(RoadItemsProject $roadItemsProject): JsonResponse { - $name = 'گزارش از کارتابل عملیات فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadItemTableService->operatorCartableReport($request, true); - return Excel::download(new OperatorCartableReport($data['data']), $name); - } + if ($roadItemsProject->files()->exists()) { + Storage::delete('public/'. $roadItemsProject->files[0]->path); + Storage::delete('public/'. $roadItemsProject->files[1]->path); + $roadItemsProject->files()->delete(); + } + auth()->user()->addActivityComplete(1151); - public function roadItemMachine(RoadItemsProject $roadItemsProject): JsonResponse - { - return $this->successResponse($roadItemsProject->cmmsMachines()->get(['cmms_machines.id', 'cmms_machines.machine_code', 'cmms_machines.car_name', 'cmms_machines.plak_number'])); - } + $roadItemsProject->delete(); - public function roadItemRahdar(RoadItemsProject $roadItemsProject): JsonResponse - { - return $this->successResponse($roadItemsProject->rahdaran()->get(['rahdaran.id', 'rahdaran.name', 'rahdaran.code'])); - } - - public function roadItemFile(RoadItemsProject $roadItemsProject): JsonResponse - { - return $this->successResponse($roadItemsProject->files()->get(['path'])); + return $this->successResponse(); } } diff --git a/app/Http/Controllers/V3/Dashboard/RoadItem/SupervisorController.php b/app/Http/Controllers/V3/Dashboard/RoadItem/SupervisorController.php new file mode 100644 index 00000000..42cdb28c --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/RoadItem/SupervisorController.php @@ -0,0 +1,117 @@ +dataTable($request); + + foreach ($data['data'] as $road_item) { + if (Gate::allows('gate-supervise-road-item', $road_item)) { + $road_item['can_supervise'] = 1; + } else { + $road_item['can_supervise'] = 0; + } + } + + return response()->json($data); + } + + /** + * @throws Throwable + */ + public function excel(Request $request, SupervisorService $supervisorService): BinaryFileResponse + { + $name = 'گزارش از کارتابل ارزیابی فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; + $data = $supervisorService->dataTable($request, true); + return Excel::download(new SupervisorCartableReport($data['data']), $name); + } + + public function confirm(ConfirmRequest $request, RoadItemsProject $roadItemsProject): JsonResponse + { + $user = auth()->user(); + + DB::transaction(function () use ($request, $roadItemsProject, $user) { + $roadItemsProject->update([ + 'status' => 1, + 'status_fa' => 'تایید شده', + 'supervisor_id' => $user->id, + 'supervisor_name' => $user->name, + 'supervisor_description' => $request->description, + 'supervising_time' => now(), + ]); + + $user->addActivityComplete(1149); + }); + + return $this->successResponse(); + } + + public function reject(RejectRequest $request, RoadItemsProject $roadItemsProject): JsonResponse + { + $user = auth()->user(); + + DB::transaction(function () use ($request, $roadItemsProject, $user) { + $roadItemsProject->update([ + 'status' => 2, + 'status_fa' => 'عدم تایید', + 'supervisor_id' => $user->id, + 'supervisor_name' => $user->name, + 'supervisor_description' => $request->description, + 'supervising_time' => now(), + ]); + + $user->addActivityComplete(1149); + }); + + return $this->successResponse(); + } + + /** + * @throws Throwable + */ + public function restore(RoadItemsProject $roadItemsProject): JsonResponse + { + + throw_if($roadItemsProject->status == 0, new ProhibitedAction('امکان بازگردانی وضعیت این فعالیت وجود ندارد!')); + + DB::transaction(function () use ($roadItemsProject) { + $roadItemsProject->update([ + 'status' => 0, + 'status_fa' => 'در حال بررسی', + 'supervisor_id' => null, + 'supervisor_description' => null, + 'supervising_time' => null, + 'supervisor_name' => null, + ]); + auth()->user()->addActivityComplete(1150); + }); + + return $this->successResponse(); + } +} diff --git a/app/Http/Requests/V3/RoadItemsProject/StoreRequest.php b/app/Http/Requests/V3/RoadItem/StoreRequest.php similarity index 98% rename from app/Http/Requests/V3/RoadItemsProject/StoreRequest.php rename to app/Http/Requests/V3/RoadItem/StoreRequest.php index 03b3fb46..612026ec 100644 --- a/app/Http/Requests/V3/RoadItemsProject/StoreRequest.php +++ b/app/Http/Requests/V3/RoadItem/StoreRequest.php @@ -1,6 +1,6 @@ roadItemsProject); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + return [ + 'description' => 'string', + ]; + } +} diff --git a/app/Http/Requests/V3/RoadItem/Supervisor/RejectRequest.php b/app/Http/Requests/V3/RoadItem/Supervisor/RejectRequest.php new file mode 100644 index 00000000..d6af0596 --- /dev/null +++ b/app/Http/Requests/V3/RoadItem/Supervisor/RejectRequest.php @@ -0,0 +1,30 @@ +roadItemsProject); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + return [ + 'description' => 'string', + ]; + } +} diff --git a/app/Http/Requests/V3/RoadItemsProject/UpdateRequest.php b/app/Http/Requests/V3/RoadItem/UpdateRequest.php similarity index 96% rename from app/Http/Requests/V3/RoadItemsProject/UpdateRequest.php rename to app/Http/Requests/V3/RoadItem/UpdateRequest.php index 6f80951f..865c9101 100644 --- a/app/Http/Requests/V3/RoadItemsProject/UpdateRequest.php +++ b/app/Http/Requests/V3/RoadItem/UpdateRequest.php @@ -1,6 +1,6 @@ where('is_new', '=', 1) + ->where('user_id', '=', auth()->user()->id) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); + + return DataTableFacade::run( + $query, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: [ + 'id', 'province_fa', 'edarat_name', 'supervisor_description', 'item', 'item_fa', + 'sub_item', 'sub_item_fa', 'sub_item_data', 'unit_fa', 'start_lat', 'start_lng', + 'end_lat', 'end_lng', 'activity_date_time', 'created_at', 'status_fa', 'status' + ], + ); + } +} \ No newline at end of file diff --git a/app/Services/Cartables/RoadItem/SupervisorService.php b/app/Services/Cartables/RoadItem/SupervisorService.php new file mode 100644 index 00000000..ee7510fb --- /dev/null +++ b/app/Services/Cartables/RoadItem/SupervisorService.php @@ -0,0 +1,46 @@ +user(); + $query = null; + + if ($user->hasPermissionTo('show-road-item-supervise-cartable')) { + $query = RoadItemsProject::query() + ->where('is_new', 1) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); + } + elseif ($user->hasPermissionTo('show-road-item-supervise-cartable-province')) { + throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); + $query = RoadItemsProject::query() + ->where('is_new', 1) + ->where('province_id', auth()->user()->province_id) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); + } + + return DataTableFacade::run( + $query, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: [ + 'id', 'province_fa', 'edarat_name', 'item', 'item_fa', 'sub_item', + 'sub_item_fa', 'sub_item_data', 'unit_fa', 'start_lat', 'start_lng', + 'end_lat', 'end_lng', 'activity_date_time', 'created_at', 'status_fa', 'status' + ] + ); + } +} \ No newline at end of file diff --git a/database/migrations/2025_06_16_092407_add_column_to_road_items_projects.php b/database/migrations/2025_06_16_092407_add_column_to_road_items_projects.php new file mode 100644 index 00000000..3630d6f9 --- /dev/null +++ b/database/migrations/2025_06_16_092407_add_column_to_road_items_projects.php @@ -0,0 +1,28 @@ +foreignId('mission_id')->constrained('missions'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('road_items_projects', function (Blueprint $table) { + $table->dropColumn('mission_id'); + }); + } +}; diff --git a/routes/v3.php b/routes/v3.php index 59e0647a..9dce4324 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -17,9 +17,7 @@ use App\Http\Controllers\V3\Dashboard\ObservedItemController; use App\Http\Controllers\V3\Dashboard\OtpManagementController; use App\Http\Controllers\V3\Dashboard\Reports\RoadItemsReportController; use App\Http\Controllers\V3\Dashboard\Reports\RoadPatrolReportController; -use App\Http\Controllers\V3\Dashboard\RoadItemsProjectController; use App\Http\Controllers\V3\Dashboard\RoadMaintenanceStationController; -use App\Http\Controllers\V3\Dashboard\RoadObservation\RoadObservationController; use App\Http\Controllers\V3\Dashboard\RoadPatrolProjectController; use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacy\OperatorController; use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacy\OperatorReportController; @@ -116,40 +114,41 @@ Route::prefix('road_items') ->controller(RoadItemsProjectController::class) ->group(function () { - Route::get('/supervisor_index', 'supervisorIndex') + Route::prefix('operator') + ->name('operator.') + ->controller(\App\Http\Controllers\V3\Dashboard\RoadItem\OperatorController::class) + ->group(function () { + Route::get('/', 'index')->middleware('permission:create-road-item')->name('index'); + Route::get('/excel', 'excel')->name('excel'); + Route::post('/', 'store') + ->middleware(['permission:create-road-item', 'validate-store-access']) + ->name('store'); + Route::get('/{roadItemsProject}', 'show')->name('show'); + Route::get('/{roadItemsProject}', 'show')->name('show'); + Route::post('/{roadItemsProject}', 'update')->name('update'); + Route::delete('/{roadItemsProject}', 'destroy')->middleware('permission:delete-road-item')->name('destroy'); + }); + + Route::prefix('supervisor') + ->name('supervisor.') + ->controller(\App\Http\Controllers\V3\Dashboard\RoadItem\SupervisorController::class) ->middleware(['permission:show-road-item-supervise-cartable|show-road-item-supervise-cartable-province']) - ->name('supervisorIndex'); + ->group(function () { + Route::get('/', 'index')->name('index'); + Route::get('/excel', 'excel')->name('excel'); + Route::post('/confirm/{roadItemsProject}', 'confirm')->name('confirm'); + Route::post('/reject/{roadItemsProject}', 'reject')->name('reject'); + Route::post('/restore/{roadItemsProject}', 'restore')->middleware('permission:restore-road-item')->name('restore'); + }); - Route::post('/verify_by_supervisor/{roadItemsProject}', 'VerifyBySupervisor') - ->name('VerifyBySupervisor'); - - Route::post('/restore/{roadItemsProject}', 'restore') - ->middleware('permission:restore-road-item') - ->name('restore'); - - Route::post('/delete/{roadItemsProject}', 'delete') - ->middleware('permission:delete-road-item') - ->name('delete'); - - Route::get('/supervisor_report', 'supervisorCartableReport') - ->name('supervisorCartableReport'); - - Route::get('/operator_index', 'operatorIndex') - ->middleware('permission:create-road-item') - ->name('operatorIndex'); - - Route::post('/store', 'store') - ->middleware('permission:create-road-item') - ->name('store'); - - Route::post('/update/{roadItemsProject}', 'update')->name('update'); - - Route::get('/operator_report', 'operatorCartableReport') - ->name('operatorCartableReport'); - - Route::get('/machines/{roadItemsProject}', 'roadItemMachine')->name('roadItemMachine'); - Route::get('/rahdaran/{roadItemsProject}', 'roadItemRahdar')->name('roadItemRahdar'); - Route::get('/files/{roadItemsProject}', 'roadItemFile')->name('roadItemFile'); + Route::prefix('details') + ->name('details.') + ->controller(\App\Http\Controllers\V3\Dashboard\RoadItem\DetailController::class) + ->group(function () { + Route::get('/machines/{roadItemsProject}', 'machines')->name('machines'); + Route::get('/rahdaran/{roadItemsProject}', 'rahdaran')->name('rahdaran'); + Route::get('/files/{roadItemsProject}', 'files')->name('files'); + }); }); Route::prefix('road_patrols') @@ -470,8 +469,8 @@ Route::prefix('missions') ->controller(ControlUnitController::class) ->group(function () { Route::get('/', 'index')->name('index'); - Route::get('/start', 'start')->name('start'); - Route::get('/finish', 'finish')->name('finish'); + Route::post('/start/{mission}', 'start')->name('start'); + Route::post('/finish/{mission}', 'finish')->name('finish'); }); Route::prefix('details') ->name('details.')