diff --git a/app/Enums/SafetyAndPrivacyStatus.php b/app/Enums/SafetyAndPrivacyStatus.php new file mode 100644 index 00000000..34358e24 --- /dev/null +++ b/app/Enums/SafetyAndPrivacyStatus.php @@ -0,0 +1,21 @@ + 'تایید', + 2 => 'عدم تایید', + 3 => 'در حال بررسی' + ]; + + return $mapArray[$state]; + } +} \ No newline at end of file diff --git a/app/Enums/SafetyAndPrivacySteps.php b/app/Enums/SafetyAndPrivacySteps.php new file mode 100644 index 00000000..b0e30776 --- /dev/null +++ b/app/Enums/SafetyAndPrivacySteps.php @@ -0,0 +1,21 @@ + 'گام اول (شناسایی)', + 2 => 'گام دوم (مستندات قضایی)', + 3 => 'گام سوم (برخورد)', + ]; + + return $mapArray[$step]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 693a1864..3124cce8 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -3,6 +3,8 @@ namespace App\Http\Controllers\V3\Dashboard; use App\Enums\AxisTypes; +use App\Enums\SafetyAndPrivacyStatus; +use App\Enums\SafetyAndPrivacySteps; use App\Exports\V3\SafetyAndPrivacy\CartableReport; use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; @@ -18,10 +20,8 @@ use App\Services\Cartables\SafetyAndPrivacyTableService; use App\Services\NominatimService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; -use Illuminate\Support\Facades\Validator; use Maatwebsite\Excel\Facades\Excel; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Throwable; @@ -33,9 +33,9 @@ class SafetyAndPrivacyController extends Controller /** * @throws Throwable */ - public function index(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse + public function operatorIndex(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse { - return response()->json($safetyAndPrivacyTableService->datatable($request)); + return response()->json($safetyAndPrivacyTableService->operatorDatatable($request)); } /** @@ -44,7 +44,7 @@ class SafetyAndPrivacyController extends Controller public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse { $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; - $data = $safetyAndPrivacyTableService->datatable($request); + $data = $safetyAndPrivacyTableService->operatorDatatable($request); return Excel::download(new CartableReport($data['data']), $name); } @@ -52,14 +52,6 @@ class SafetyAndPrivacyController extends Controller { $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('اداره شهری برای شما در سامانه ثبت نشده است!'); - } - $coordinates = explode(',', $request->point); $item = InfoItem::query() ->where('id', $request->info_id) @@ -85,8 +77,9 @@ class SafetyAndPrivacyController extends Controller 'way_id' => $nominatimService->get_way_id_from_nominatim($coordinates[0], $coordinates[1]), 'axis_type_id' => $request->axis_type_id, 'axis_type_name' => AxisTypes::name($request->axis_type_id), - 'step' => 1, - 'step_fa' => 'گام اول (شناسایی)' + 'step' => SafetyAndPrivacySteps::SHENASAEI->value, + 'step_fa' => SafetyAndPrivacySteps::name(1), + 'is_finished' => false ]); $safety_and_privacy->recognize_picture = $request->has('recognize_picture') ? @@ -104,14 +97,6 @@ class SafetyAndPrivacyController extends Controller { $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('اداره شهری برای شما در سامانه ثبت نشده است!'); - } - DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { $judiciary_document = []; @@ -121,8 +106,8 @@ class SafetyAndPrivacyController extends Controller $safetyAndPrivacy->update([ 'judiciary_document' => serialize($judiciary_document), 'judiciary_document_upload_date' => now(), - 'step' => 2, - 'step_fa' => 'گام دوم (مستندات قضایی)' + 'step' => SafetyAndPrivacySteps::MOSTANADAT_GAZAEI->value, + 'step_fa' => SafetyAndPrivacySteps::name(2), ]); $user->addActivityComplete(1135); @@ -135,21 +120,14 @@ class SafetyAndPrivacyController extends Controller { $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('اداره شهری برای شما در سامانه ثبت نشده است!'); - } - DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { $safetyAndPrivacy->update([ - 'step' => 3, - 'step_fa' => 'گام سوم (برخورد)', + 'step' => SafetyAndPrivacySteps::BARKHORD->value, + 'step_fa' => SafetyAndPrivacySteps::name(3), 'action_picture' => FileFacade::save($request->action_picture, "safety_and_privacy/{$safetyAndPrivacy->id}/action_picture"), 'action_picture_document_upload_date' => now(), 'action_date' => $request->action_date, + 'is_finished' => true ]); $user->addActivityComplete(1136); @@ -179,7 +157,7 @@ class SafetyAndPrivacyController extends Controller public function destroy(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { - Storage::deleteDirectory("public/safety_and_privacy/{$safetyAndPrivacy->id}"); + FileFacade::deleteDirectory("safety_and_privacy/{$safetyAndPrivacy->id}"); DB::transaction(function () use ($safetyAndPrivacy) { @@ -221,4 +199,40 @@ class SafetyAndPrivacyController extends Controller allowedSelects: ['id', 'lat', 'lon', 'step'] )); } + + public function confirm(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $safetyAndPrivacy->update([ + 'status' => SafetyAndPrivacyStatus::CONFIRM->value, + 'supervisor_description' => $request->supervisor_description + ]); + + return $this->successResponse(); + } + + public function reject(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $safetyAndPrivacy->update([ + 'status' => SafetyAndPrivacyStatus::REJECT->value, + 'supervisor_description' => $request->supervisor_description + ]); + + return $this->successResponse(); + } + + public function finish(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $safetyAndPrivacy->update([ + 'is_finished' => $request->is_finished, + 'final_description' => $request->final_description, + 'status' => SafetyAndPrivacyStatus::PENDING->value, + ]); + + return $this->successResponse(); + } + + public function supervisorIndex(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse + { + return response()->json($safetyAndPrivacyTableService->supervisorDataTable($request)); + } } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index bc9e3c68..04705bf0 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -77,6 +77,7 @@ class Kernel extends HttpKernel 'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class, 'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class, 'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class, + 'validate-store-access' => \App\Http\Middleware\ValidateStoreAccess::class, ]; /** diff --git a/app/Http/Middleware/ValidateStoreAccess.php b/app/Http/Middleware/ValidateStoreAccess.php new file mode 100644 index 00000000..ec57469f --- /dev/null +++ b/app/Http/Middleware/ValidateStoreAccess.php @@ -0,0 +1,32 @@ +edarate_ostani_id || is_null($user->city_id), + new ProhibitedAction('امکان ثبت این مورد برای ادارات استانی و ستادی وجود ندارد!')); + + throw_if(is_null($user->edarate_shahri_id), + new ProhibitedAction('اداره شهری برای شما در سامانه ثبت نشده است!')); + + return $next($request); + } +} diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index ac347063..d1c6cc3f 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -36,7 +36,11 @@ class SafetyAndPrivacy extends Model 'action_picture_document_upload_date', 'axis_type_id', 'axis_type_name', - 'action_date' + 'action_date', + 'status', + 'final_description', + 'is_finished', + 'supervisor_description' ]; public $table = "safety_and_privacy"; diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index afe8c30a..8aca0a54 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -18,7 +18,7 @@ class SafetyAndPrivacyTableService /** * @throws Throwable */ - public function dataTable(Request $request, $loadRelations = false) + public function operatorDataTable(Request $request) { $user = auth()->user(); @@ -50,6 +50,30 @@ class SafetyAndPrivacyTableService ); } + public function supervisorDataTable(Request $request) + { + $user = auth()->user(); + + $fields = ['id','lat','lon','province_id','province_fa','city_id','city_fa','edare_shahri_id','edare_shahri_name', + 'recognize_picture','action_picture','operator_id','operator_name','way_id','created_at','updated_at','step', + 'info_id','info_fa','activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', + 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date' + ]; + + $query = SafetyAndPrivacy::query()->where([ + ['province_id', '=', $user->province_id], + ['is_finished', '=', 1] + ]); + + return DataTableFacade::run( + $query, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: $fields + ); + } + public function countryActivity(Request $request): array { $activities = []; diff --git a/database/migrations/2025_04_22_100327_add_column_to_safety_and_privacy_table.php b/database/migrations/2025_04_22_100327_add_column_to_safety_and_privacy_table.php new file mode 100644 index 00000000..49d997a7 --- /dev/null +++ b/database/migrations/2025_04_22_100327_add_column_to_safety_and_privacy_table.php @@ -0,0 +1,31 @@ +boolean('is_finished')->nullable(); + $table->integer('status')->nullable(); + $table->string('supervisor_description')->nullable(); + $table->string('final_description')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('safety_and_privacy', function (Blueprint $table) { + $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description']); + }); + } +}; diff --git a/routes/v3.php b/routes/v3.php index a71859a2..d0924334 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -337,13 +337,15 @@ Route::prefix('safety_and_privacy') ->name('SafetyAndPrivacy.') ->controller(SafetyAndPrivacyController::class) ->group(function () { - Route::get('/', 'index')->name('index')->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province|show-safety-and-privacy-operator-cartable-edarate-shahri'); + Route::get('/', 'operatorIndex')->name('operatorIndex')->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province|show-safety-and-privacy-operator-cartable-edarate-shahri'); Route::get('/excel_report', 'excelReport')->name('excelReport')->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province|show-safety-and-privacy-operator-cartable-edarate-shahri'); - Route::post('/first_step_store', 'firstStepStore')->name('firstStepStore')->middleware('permission:add-safety-and-privacy'); + Route::post('/first_step_store', 'firstStepStore')->name('firstStepStore') + ->middleware(['validate-store-access', 'permission:add-safety-and-privacy']); + Route::get('/sub_items', 'subItems')->name('subItems'); Route::get('/map', 'map')->name('map'); - Route::post('/second_step_store/{safetyAndPrivacy}', 'secondStepStore')->name('secondStepStore')->middleware('permission:add-safety-and-privacy'); - Route::post('/third_step_store/{safetyAndPrivacy}', 'thirdStepStore')->name('thirdStepStore')->middleware('permission:add-safety-and-privacy'); + Route::post('/second_step_store/{safetyAndPrivacy}', 'secondStepStore')->name('secondStepStore')->middleware(['validate-store-access','permission:add-safety-and-privacy']); + Route::post('/third_step_store/{safetyAndPrivacy}', 'thirdStepStore')->name('thirdStepStore')->middleware(['validate-store-access','permission:add-safety-and-privacy']); Route::post('/{safetyAndPrivacy}', 'update')->name('update')->middleware('permission:update-safety-and-privacy'); Route::get('/{safetyAndPrivacy}', 'show')->name('show'); Route::delete('/{safetyAndPrivacy}', 'destroy')->name('destroy')->middleware('permission:delete-safety-and-privacy');