From 6ec1f6c2b471d5a2ae744992c9674a7ab0c7996e Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 11 Mar 2025 11:47:43 +0330 Subject: [PATCH 01/48] write test for permission controller --- .../SendRoadObservationToNikarayanCommand.php | 10 +- app/Jobs/SendRoadObservationToNikarayan.php | 8 +- app/Services/NikarayanService.php | 2 +- ...33823_create_road_items_projects_table.php | 2 +- ...133823_create_user_activity_logs_table.php | 8 +- phpunit.xml | 4 +- routes/v3.php | 2 + tests/Feature/V3/Permission/IndexTest.php | 59 ++++ tests/Feature/V3/Permission/StoreTest.php | 297 ++++++++++++++++++ 9 files changed, 375 insertions(+), 17 deletions(-) create mode 100644 tests/Feature/V3/Permission/IndexTest.php create mode 100644 tests/Feature/V3/Permission/StoreTest.php diff --git a/app/Console/Commands/SendRoadObservationToNikarayanCommand.php b/app/Console/Commands/SendRoadObservationToNikarayanCommand.php index e04568bd..5202e148 100644 --- a/app/Console/Commands/SendRoadObservationToNikarayanCommand.php +++ b/app/Console/Commands/SendRoadObservationToNikarayanCommand.php @@ -33,16 +33,14 @@ class SendRoadObservationToNikarayanCommand extends Command $this->info("Dispatching jobs with a delay between each..."); DB::transaction(function () use (&$count) { - $delay = 0; RoadObserved::query() ->whereBetween('StartTime_DateTime_fa', ['1403-01-01 00:00:00', '1403-07-13 23:59:59']) - ->chunkById(50, function ($roads) use (&$delay, &$count) { + ->chunkById(50, function ($roads) use (&$count) { foreach ($roads as $road) { $road->update(['status' => 1]); - SendRoadObservationToNikarayan::dispatch($road)->delay(now()->addSeconds($delay)); - Log::channel('road_observation_problem')->info("Job for Road Observed ID {$road->id} scheduled with a {$delay} seconds delay."); - $this->info("Scheduled job for Road ID: {$road->id} {$delay}s"); - $delay += 3; + SendRoadObservationToNikarayan::dispatch($road); + Log::channel('road_observation_problem')->info("Job for Road Observed ID {$road->id} scheduled."); + $this->info("Scheduled job for Road ID: {$road->id}"); $count +=1; } }); diff --git a/app/Jobs/SendRoadObservationToNikarayan.php b/app/Jobs/SendRoadObservationToNikarayan.php index 87cdeb0c..6b7abb26 100644 --- a/app/Jobs/SendRoadObservationToNikarayan.php +++ b/app/Jobs/SendRoadObservationToNikarayan.php @@ -45,12 +45,14 @@ class SendRoadObservationToNikarayan implements ShouldQueue ); $soapClient = new SoapClient($url); - - $soapClient->UpdateInfo_RoadObservedProblems($array); + $result = $soapClient->UpdateInfo_RoadObservedProblems($array); + Log::channel('road_observation_problem')->info(json_encode($result), [$this->roadObserved->id]); } catch (\Exception $exception){ Log::channel('road_observation_problem')->error($exception->getMessage(), [ - 'roadObserved' => $this->roadObserved, + 'roadObserved' => $this->roadObserved->id, + 'line' => $exception->getLine(), + 'file' => $exception->getFile(), ]); } } diff --git a/app/Services/NikarayanService.php b/app/Services/NikarayanService.php index 19f4945e..2d229668 100644 --- a/app/Services/NikarayanService.php +++ b/app/Services/NikarayanService.php @@ -33,7 +33,7 @@ class NikarayanService $soapClient = new SoapClient($url); $result = $soapClient->UpdateInfo_RoadObservedProblems($array); - Log::channel('nikarayan')->info($result); + Log::channel('nikarayan')->info(json_encode($result)); return $result; } diff --git a/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php b/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php index d3257d2d..dc96c4ed 100644 --- a/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php +++ b/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php @@ -21,7 +21,7 @@ return new class extends Migration $table->decimal('end_lat', 12, 10)->nullable(); $table->decimal('end_lng', 12, 10)->nullable(); $table->string('project_distance')->nullable(); - $table->unsignedTinyInteger('item')->index('item'); + $table->unsignedTinyInteger('item');//->index('item'); $table->string('item_fa')->nullable(); $table->integer('sub_item')->nullable(); $table->string('sub_item_fa')->nullable(); diff --git a/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php b/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php index 4a0b14cc..e72b82b5 100644 --- a/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php +++ b/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php @@ -36,10 +36,10 @@ return new class extends Migration $table->string('action_type', 100)->nullable(); $table->text('model')->nullable(); $table->timestamps(); - $table->integer('mm')->nullable()->storedAs('month(`created_at`)'); - $table->integer('yy')->nullable()->storedAs('year(`created_at`)'); - $table->integer('dd')->nullable()->storedAs('dayofmonth(`created_at`)'); - $table->integer('hh')->nullable()->storedAs('hour(`created_at`)'); + $table->integer('mm')->nullable();//->storedAs('month(`created_at`)'); + $table->integer('yy')->nullable();//->storedAs('year(`created_at`)'); + $table->integer('dd')->nullable();//->storedAs('dayofmonth(`created_at`)'); + $table->integer('hh')->nullable();//->storedAs('hour(`created_at`)'); }); } diff --git a/phpunit.xml b/phpunit.xml index cf1d8ca1..ff19ac12 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -21,8 +21,8 @@ - - + + diff --git a/routes/v3.php b/routes/v3.php index 380dd3c9..f87debdc 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -321,6 +321,7 @@ Route::prefix('road_observations') Route::prefix('log_list') ->name('logList.') + ->middleware('permission:manage-log-list') ->controller(LogListManagementController::class) ->group(function () { Route::get('/', 'index')->name('index'); @@ -372,6 +373,7 @@ Route::name('items.') Route::prefix('permissions') ->name('permissions.') + ->middleware('permission:manage-permissions') ->controller(PermissionManagementController::class) ->group(function () { Route::get('/', 'index')->name('index'); diff --git a/tests/Feature/V3/Permission/IndexTest.php b/tests/Feature/V3/Permission/IndexTest.php new file mode 100644 index 00000000..e53c1cd6 --- /dev/null +++ b/tests/Feature/V3/Permission/IndexTest.php @@ -0,0 +1,59 @@ +create(); + + $response = $this->actingAs($user)->getJson(route('v3.permissions.index')); + + $response->assertForbidden(); + } + + public function test_all_permissions_returned_successfully(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->getJson(route('v3.permissions.index', [ + 'start' => 0, + 'size' => 10, + 'filters' => json_encode([]), + 'sorting' => json_encode([]), + ])); + + $response->assertOk(); + + $response->assertJsonStructure([ + 'data' => [ + '*' => [ + 'id', + 'name', + 'name_fa', + 'type', + 'type_fa', + 'description', + ], + ], + "meta" => [ + "totalRowCount" + ] + ]); + } +} diff --git a/tests/Feature/V3/Permission/StoreTest.php b/tests/Feature/V3/Permission/StoreTest.php new file mode 100644 index 00000000..37df8b84 --- /dev/null +++ b/tests/Feature/V3/Permission/StoreTest.php @@ -0,0 +1,297 @@ +create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertForbidden(); + } + + public function test_name_attribute_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'name' => __('validation.required', ['attribute' => 'نام']) + ]); + } + + public function test_name_attribute_should_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'name' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'name' => __('validation.string', ['attribute' => 'نام']) + ]); + } + + public function test_name_attribute_should_be_unique(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $permission = Permission::factory()->create([ + 'name' => $this->faker->name() + ]); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'name' => $permission->name, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'name' => __('validation.unique', ['attribute' => 'نام']) + ]); + } + + public function test_name_fa_attribute_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'name_fa' => __('validation.required', ['attribute' => 'name fa']) + ]); + } + + public function test_name_fa_attribute_should_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'name_fa' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'name_fa' => __('validation.string', ['attribute' => 'name fa']) + ]); + } + + public function test_description_attribute_should_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'description' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'description' => __('validation.string', ['attribute' => 'توضیحات']) + ]); + } + + public function test_type_attribute_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'type' => __('validation.required', ['attribute' => 'type']) + ]); + } + + public function test_type_attribute_should_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'type' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'type' => __('validation.string', ['attribute' => 'type']) + ]); + } + + public function test_type_fa_attribute_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'type_fa' => __('validation.required', ['attribute' => 'type fa']) + ]); + } + + public function test_type_fa_attribute_should_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'type_fa' => $this->faker->numberBetween(1, 10) + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'type_fa' => __('validation.string', ['attribute' => 'type fa']) + ]); + } + + public function test_need_province_attribute_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'need_province' => __('validation.required', ['attribute' => 'need province']) + ]); + } + + public function test_need_province_attribute_should_be_1_or_0(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'need_province' => $this->faker->numberBetween(3, 9), + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'need_province' => __('validation.in', ['attribute' => 'need province']) + ]); + } + + public function test_need_edare_shahri_attribute_is_required(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'need_edare_shahri' => __('validation.required', ['attribute' => 'need edare shahri']) + ]); + } + + public function test_need_edare_shahri_attribute_should_be_1_or_0(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), [ + 'need_edare_shahri' => $this->faker->numberBetween(3, 9), + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'need_edare_shahri' => __('validation.in', ['attribute' => 'need edare shahri']) + ]); + } + + public function test_user_can_create_a_permission() + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-permissions' + ])) + ->create(); + + $inputData = [ + 'name' => $this->faker->name(), + 'name_fa' => $this->faker->name(), + 'description' => $this->faker->lexify(), + 'type' => $this->faker->name(), + 'type_fa' => $this->faker->name(), + 'need_province' => $this->faker->numberBetween(0, 1), + 'need_edare_shahri' => $this->faker->numberBetween(0, 1), + ]; + + $response = $this->actingAs($user)->postJson(route('v3.permissions.store'), $inputData); + + $response->assertOk() + ->assertExactJson([ + 'message' => __('messages.successful'), + ]); + + $this->assertDatabaseHas('permissions', $inputData); + } +} From 44f604e4e6bd52cb7a9e568c3fd59745c5eac435 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 11 Mar 2025 13:31:46 +0330 Subject: [PATCH 02/48] add update api for safetyAndPrivacy --- .../Dashboard/SafetyAndPrivacyController.php | 15 ++++++++++ .../V3/SafetyAndPrivacy/UpdateRequest.php | 28 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 app/Http/Requests/V3/SafetyAndPrivacy/UpdateRequest.php diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index a36842d3..33c23e27 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -9,6 +9,7 @@ use App\Http\Controllers\Controller; use App\Http\Requests\V3\SafetyAndPrivacy\FirstStepStoreRequest; use App\Http\Requests\V3\SafetyAndPrivacy\SecondStepStoreRequest; use App\Http\Requests\V3\SafetyAndPrivacy\ThirdStepStoreRequest; +use App\Http\Requests\V3\SafetyAndPrivacy\UpdateRequest; use App\Http\Traits\ApiResponse; use App\Models\InfoItem; use App\Models\SafetyAndPrivacy; @@ -148,6 +149,20 @@ class SafetyAndPrivacyController extends Controller return $this->successResponse(); } + public function update(SafetyAndPrivacy $safetyAndPrivacy, UpdateRequest $request): JsonResponse + { + DB::transaction(function () use ($request, $safetyAndPrivacy) { + $safetyAndPrivacy->update([ + 'axis_type_id' => $request->axis_type_id, + 'axis_type_name' => AxisTypes::name($request->axis_type_id), + ]); + + auth()->user()->addActivityComplete(); + }); + + return $this->successResponse(); + } + public function show(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { return $this->successResponse($safetyAndPrivacy); diff --git a/app/Http/Requests/V3/SafetyAndPrivacy/UpdateRequest.php b/app/Http/Requests/V3/SafetyAndPrivacy/UpdateRequest.php new file mode 100644 index 00000000..c0dab333 --- /dev/null +++ b/app/Http/Requests/V3/SafetyAndPrivacy/UpdateRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + 'axis_type_id' => 'required|integer|exists:axis_types,id', + ]; + } +} From 2375cd8b8812900f48eaa9ff1e4a968bd4cd743d Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 11 Mar 2025 15:38:26 +0330 Subject: [PATCH 03/48] add update api --- .../Controllers/V3/Dashboard/SafetyAndPrivacyController.php | 2 +- routes/v3.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 33c23e27..463a2900 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -157,7 +157,7 @@ class SafetyAndPrivacyController extends Controller 'axis_type_name' => AxisTypes::name($request->axis_type_id), ]); - auth()->user()->addActivityComplete(); + auth()->user()->addActivityComplete(1168); }); return $this->successResponse(); diff --git a/routes/v3.php b/routes/v3.php index f87debdc..bef397bb 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -342,6 +342,7 @@ Route::prefix('safety_and_privacy') Route::get('/sub_items', 'subItems')->name('subItems'); 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('/{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'); Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); From 30ff1b022aa8c01bab1bcf7af41036382ecc937f Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 12 Mar 2025 11:53:49 +0330 Subject: [PATCH 04/48] roll back the wrong commit --- ...2024_03_05_133823_create_road_items_projects_table.php | 2 +- .../2024_03_05_133823_create_user_activity_logs_table.php | 8 ++++---- phpunit.xml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php b/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php index dc96c4ed..d3257d2d 100644 --- a/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php +++ b/database/old_migrations/2024_03_05_133823_create_road_items_projects_table.php @@ -21,7 +21,7 @@ return new class extends Migration $table->decimal('end_lat', 12, 10)->nullable(); $table->decimal('end_lng', 12, 10)->nullable(); $table->string('project_distance')->nullable(); - $table->unsignedTinyInteger('item');//->index('item'); + $table->unsignedTinyInteger('item')->index('item'); $table->string('item_fa')->nullable(); $table->integer('sub_item')->nullable(); $table->string('sub_item_fa')->nullable(); diff --git a/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php b/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php index e72b82b5..4a0b14cc 100644 --- a/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php +++ b/database/old_migrations/2024_03_05_133823_create_user_activity_logs_table.php @@ -36,10 +36,10 @@ return new class extends Migration $table->string('action_type', 100)->nullable(); $table->text('model')->nullable(); $table->timestamps(); - $table->integer('mm')->nullable();//->storedAs('month(`created_at`)'); - $table->integer('yy')->nullable();//->storedAs('year(`created_at`)'); - $table->integer('dd')->nullable();//->storedAs('dayofmonth(`created_at`)'); - $table->integer('hh')->nullable();//->storedAs('hour(`created_at`)'); + $table->integer('mm')->nullable()->storedAs('month(`created_at`)'); + $table->integer('yy')->nullable()->storedAs('year(`created_at`)'); + $table->integer('dd')->nullable()->storedAs('dayofmonth(`created_at`)'); + $table->integer('hh')->nullable()->storedAs('hour(`created_at`)'); }); } diff --git a/phpunit.xml b/phpunit.xml index ff19ac12..cf1d8ca1 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -21,8 +21,8 @@ - - + + From 1c0ebdb9ab66680fd323f9c5b0305dcf515994c3 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Wed, 12 Mar 2025 17:01:14 +0330 Subject: [PATCH 05/48] wrote test for restore,supervisorIndex,verify --- .../factories/RoadItemsProjectFactory.php | 14 +- .../V3/RoadItemsProject/RestoreTest.php | 72 ++++++++++ .../RoadItemsProject/SupervisorIndexTest.php | 35 +---- .../RoadItemsProject/VerifyBySupervisor.php | 133 ++++++++++++++++++ 4 files changed, 224 insertions(+), 30 deletions(-) create mode 100644 tests/Feature/V3/RoadItemsProject/RestoreTest.php create mode 100644 tests/Feature/V3/RoadItemsProject/VerifyBySupervisor.php diff --git a/database/factories/RoadItemsProjectFactory.php b/database/factories/RoadItemsProjectFactory.php index b6543430..174d68a8 100644 --- a/database/factories/RoadItemsProjectFactory.php +++ b/database/factories/RoadItemsProjectFactory.php @@ -3,6 +3,7 @@ namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Facades\Schema; /** * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User> @@ -18,7 +19,16 @@ class RoadItemsProjectFactory extends Factory { return [ 'item' => $this->faker->numberBetween(1, 10), - 'sub_item' => $this->faker->numberBetween(1, 10), - ]; + 'sub_items' => $this->faker->title(), + 'start_lat' =>$this->faker->latitude(), + 'start_lng' =>$this->faker->longitude(), + 'is_new' => $this->faker->boolean(), + 'status' => $this->faker->randomElement([0, 1, 2]), + 'activity_date_time' =>$this->faker->dateTimeBetween('-1 year', 'now'), + 'province_id' => $this->faker->numberBetween(1, 10), + 'city_id' => $this->faker->numberBetween(1, 10), + 'user_id' =>$this->faker->numberBetween(1, 10), + 'user_name' => $this->faker->name(), + ]; } } diff --git a/tests/Feature/V3/RoadItemsProject/RestoreTest.php b/tests/Feature/V3/RoadItemsProject/RestoreTest.php new file mode 100644 index 00000000..a0688df5 --- /dev/null +++ b/tests/Feature/V3/RoadItemsProject/RestoreTest.php @@ -0,0 +1,72 @@ +create(); + $roadItem = RoadItemsProject::factory()->create(); + $response = $this->actingAs($user)->postJson(route('v3.road_items.restore', [$roadItem->id])); + $response->assertForbidden(); + } + public function test_user_cannot_access_authentication_restore(): void + { + $roadItem = RoadItemsProject::factory()->create(); + $response =$this->postJson(route('v3.road_items.restore', [$roadItem->id])); + $response->assertStatus(401); + + } + public function test_user_can_restore_road_item(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'restore-road-item' + ])) + ->create(); + + $logList = LogList::factory()->create([ + 'log_unique_code' => 1150, + ]); + UserActivityLog::factory()->create(); + + $roadItem = RoadItemsProject::factory()->create([ + 'status' => 1, + 'status_fa' => 'تایید شده', + 'supervisor_id' => $user->id, + 'supervisor_name' => $user->name, + 'supervisor_description' => 'تایید شده توسط تست', + ]); + + $response = $this->actingAs($user)->postJson(route('v3.road_items.restore', [$roadItem->id])); + + $response->assertOk() + ->assertJson([ + 'message' => __('messages.successful'), + ]); + + $this->assertDatabaseHas('road_items_projects', [ + 'id' => $roadItem->id, + 'status' => 0, + 'status_fa' => 'در حال بررسی', + 'supervisor_id' => null, + 'supervisor_name' => null, + 'supervisor_description' => null, + 'supervising_time' => null, + ]); + } + +} diff --git a/tests/Feature/V3/RoadItemsProject/SupervisorIndexTest.php b/tests/Feature/V3/RoadItemsProject/SupervisorIndexTest.php index 13a080d4..602f4bdb 100644 --- a/tests/Feature/V3/RoadItemsProject/SupervisorIndexTest.php +++ b/tests/Feature/V3/RoadItemsProject/SupervisorIndexTest.php @@ -23,6 +23,13 @@ class SupervisorIndexTest extends TestCase $response->assertForbidden(); } + public function test_user_cannot_access_authentication_to_supervisor_index(): void + { + $response = $this->getJson(route('v3.road_items.supervisorIndex')); + + $response->assertStatus(401); + } + public function test_supervisor_can_see_the_data_table(): void { @@ -47,49 +54,21 @@ class SupervisorIndexTest extends TestCase 'data' => [ '*' => [ "id", - "user_id", "start_lat", "start_lng", "end_lat", "end_lng", - "project_distance", "item", "item_fa", - "sub_item", "sub_item_fa", "sub_item_data", - "sub_items", - "sub_items_data", "created_at", - "updated_at", - "province_id", "province_fa", - "city_id", - "city_fa", - "is_new", - "parent_id", - "start_way_id", - "end_way_id", "unit_fa", - "user_name", - "created_at_fa", - "info_id", "status", "status_fa", - "edarat_id", "edarat_name", - "edarat_type", - "activity_date", - "activity_time", "activity_date_time", - "supervisor_id", - "supervisor_name", - "supervisor_description", - "supervising_time", - "cmms_machine_id", - "cmms_machine_code", - "rahdar_id", - "rahdar_code", "can_supervise", ], ] diff --git a/tests/Feature/V3/RoadItemsProject/VerifyBySupervisor.php b/tests/Feature/V3/RoadItemsProject/VerifyBySupervisor.php new file mode 100644 index 00000000..24c14c43 --- /dev/null +++ b/tests/Feature/V3/RoadItemsProject/VerifyBySupervisor.php @@ -0,0 +1,133 @@ +create(); + + $response = $this->postJson(route('v3.road_items.VerifyBySupervisor', [$roadItem->id])); + + $response->assertStatus(401); + } + + public function test_supervisor_without_permission_cannot_verify_road_item(): void + { + $user = User::factory()->create(); + + Gate::shouldReceive('allows') + ->andReturn(false); + + $roadItem = RoadItemsProject::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.road_items.VerifyBySupervisor', [$roadItem->id,])); + + $response->assertForbidden(); + } + public function test_validation_fails_when_required_fields_are_missing(): void + { + $user = User::factory()->create(); + $roadItem = RoadItemsProject::factory()->create(); + + Gate::shouldReceive('allows') + ->andReturn(true); + + $response = $this->actingAs($user)->postJson(route('v3.road_items.VerifyBySupervisor', [$roadItem->id])); + + $response->assertUnprocessable() + ->assertInvalid([ + 'verify' => __('validation.required', ['attribute' => 'verify']), + ]); + } + + public function test_validation_fails_when_verify_field_is_invalid(): void + { + $user = User::factory()->create(); + $roadItem = RoadItemsProject::factory()->create(); + + Gate::shouldReceive('allows') + ->andReturn(true); + + $response = $this->actingAs($user)->postJson(route('v3.road_items.VerifyBySupervisor', [$roadItem->id]), [ + 'verify' => 5, + 'description' => $this->faker()->sentence(), + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'verify' => __('validation.in', ['attribute' => 'verify']), + ]); + } + + public function test_verify_description_must_be_string(): void + { + $user = User::factory()->create(); + $roadItem = RoadItemsProject::factory()->create(); + + Gate::shouldReceive('allows') + ->andReturn(true); + + $response = $this->actingAs($user)->postJson(route('v3.road_items.VerifyBySupervisor', [$roadItem->id]), [ + 'description' => 12345, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'description' => __('validation.string', ['attribute' =>"توضیحات"]), + ]); + } + + + + public function test_supervisor_can_view_road_item_data(): void + { + $user = User::factory()->create(); + + LogList::factory()->create([ + 'log_unique_code' => 1149, + ]); + UserActivityLog::factory()->create(); + + $roadItem = RoadItemsProject::factory()->create(); + + Gate::shouldReceive('allows') + ->andReturn(true); + + $description = fake()->sentence(); + $response = $this->actingAs($user)->postJson(route('v3.road_items.VerifyBySupervisor', [$roadItem->id,]), [ + 'verify' => 1, + 'description' =>$description, + ]); + + $response->assertOk() + ->assertJson([ + 'message' => __('messages.successful'), + ]); + $this->assertDatabaseHas('road_items_projects', [ + 'id' => $roadItem->id, + 'status' => 1, + 'status_fa' => 'تایید شده', + 'supervisor_id' => $user->id, + 'supervisor_name' => $user->name, + 'supervisor_description' =>$description, + ]); + } +} From f295034f4f6967b33e9888dc4503409749eeba88 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Sun, 30 Mar 2025 13:47:39 +0330 Subject: [PATCH 06/48] create test for three item in roaditem project --- .../V3/RoadItemsProject/DeleteTest.php | 57 ++ .../V3/RoadItemsProject/OperatorIndexTest.php | 8 + .../Feature/V3/RoadItemsProject/StoreTest.php | 878 +++++++----------- 3 files changed, 401 insertions(+), 542 deletions(-) create mode 100644 tests/Feature/V3/RoadItemsProject/DeleteTest.php diff --git a/tests/Feature/V3/RoadItemsProject/DeleteTest.php b/tests/Feature/V3/RoadItemsProject/DeleteTest.php new file mode 100644 index 00000000..09fb4ae8 --- /dev/null +++ b/tests/Feature/V3/RoadItemsProject/DeleteTest.php @@ -0,0 +1,57 @@ +create(); + $roadItem = RoadItemsProject::factory()->create(); + $response = $this->actingAs($user)->postJson(route('v3.road_items.delete', [$roadItem->id])); + $response->assertForbidden(); + } + + public function test_user_cannot_access_authentication_delete(): void + { + $roadItem = RoadItemsProject::factory()->create(); + $response =$this->postJson(route('v3.road_items.delete', [$roadItem->id])); + $response->assertStatus(401); + + } + + public function test_user_can_delete_road_item(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'delete-road-item' + ])) + ->create(); + + $logList = LogList::factory()->create([ + 'log_unique_code' => 1151, + ]); + UserActivityLog::factory()->create(); + $roadItem = RoadItemsProject::factory()->create(); + $response = $this->actingAs($user)->postJson(route('v3.road_items.delete', [$roadItem->id])); + + $response->assertOk() + ->assertJson([ + 'message' => __('messages.successful'), + ]); + $this->assertDatabaseMissing('road_items_projects', [ + 'id' => $roadItem->id, + ]); + } +} diff --git a/tests/Feature/V3/RoadItemsProject/OperatorIndexTest.php b/tests/Feature/V3/RoadItemsProject/OperatorIndexTest.php index b7e9a765..27888ae7 100644 --- a/tests/Feature/V3/RoadItemsProject/OperatorIndexTest.php +++ b/tests/Feature/V3/RoadItemsProject/OperatorIndexTest.php @@ -24,6 +24,14 @@ class OperatorIndexTest extends TestCase $response->assertForbidden(); } + public function test_user_cannot_access_authentication_to_operator_index(): void + { + $response = $this->getJson(route('v3.road_items.operatorIndex')); + + $response->assertStatus(401); + } + + public function test_operator_can_see_the_data_table(): void { $user = User::factory() diff --git a/tests/Feature/V3/RoadItemsProject/StoreTest.php b/tests/Feature/V3/RoadItemsProject/StoreTest.php index ee141ece..7a44821a 100644 --- a/tests/Feature/V3/RoadItemsProject/StoreTest.php +++ b/tests/Feature/V3/RoadItemsProject/StoreTest.php @@ -12,6 +12,7 @@ use App\Models\ObservedItem; use App\Models\Permission; use App\Models\Province; use App\Models\Rahdaran; +use App\Models\RoadItemsProject; use App\Models\User; use App\Models\UserActivityLog; use App\Services\NominatimService; @@ -22,6 +23,8 @@ use Illuminate\Support\Facades\Storage; use Mockery\MockInterface; use Symfony\Component\Finder\Exception\AccessDeniedException; use Tests\TestCase; +use Illuminate\Support\Str; + class StoreTest extends TestCase { @@ -37,104 +40,56 @@ class StoreTest extends TestCase $response->assertForbidden(); } + public function test_user_cannot_access_authentication_store(): void + { +// $roadItem = RoadItemsProject::factory()->create(); + $response =$this->postJson(route('v3.road_items.store')); + $response->assertStatus(401); - public function test_start_point_is_required(): void + } + + public function test_required_fields(): void { $user = User::factory() ->has(Permission::factory([ 'name' => 'create-road-item' ])) ->create(); - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); $response->assertUnprocessable() ->assertInvalid([ - 'start_point' => __('validation.required', ['attribute' => 'start point']) + 'start_point' => __('validation.required', ['attribute' => 'start point']), + 'item_id' => __('validation.required', ['attribute' => 'item id']), + 'sub_item_id' => __('validation.required', ['attribute' => 'sub item id']), + 'amount' => __('validation.required', ['attribute' => 'amount']), + 'activity_date' => __('validation.required', ['attribute' => 'تاریخ فعالیت']), + 'activity_time' => __('validation.required', ['attribute' => 'ساعت فعالیت']), + 'machines_id' => __('validation.required', ['attribute' => 'machines id']), + 'rahdaran_id' => __('validation.required', ['attribute' => 'rahdaran id']), ]); } - public function test_item_id_is_required(): void + public function test_integer_fields(): void { $user = User::factory() ->has(Permission::factory([ 'name' => 'create-road-item' ])) ->create(); + $data = [ + 'item_id' => $this->faker->name, + 'sub_item_id' => $this->faker->name, + 'observed_item_id' => $this->faker->name, + ]; - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); + $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); $response->assertUnprocessable() ->assertInvalid([ - 'item_id' => __('validation.required', ['attribute' => 'item id']) - ]); - } - - public function test_item_id_should_be_integer(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'item_id' => $this->faker->name - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'item_id' => __('validation.integer', ['attribute' => 'item id']) - ]); - } - - public function test_sub_item_id_is_required(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); - - $response->assertUnprocessable() - ->assertInvalid([ - 'sub_item_id' => __('validation.required', ['attribute' => 'sub item id']) - ]); - } - - public function test_sub_item_id_should_be_integer(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'sub_item_id' => $this->faker->name - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'sub_item_id' => __('validation.integer', ['attribute' => 'sub item id']) - ]); - } - - public function test_amount_is_required(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); - - $response->assertUnprocessable() - ->assertInvalid([ - 'amount' => __('validation.required', ['attribute' => 'amount']) + 'item_id' => __('validation.integer', ['attribute' => 'item id']), + 'sub_item_id' => __('validation.integer', ['attribute' => 'sub item id']), + 'observed_item_id' => __('validation.integer', ['attribute' => 'observed item id']), ]); } @@ -156,7 +111,7 @@ class StoreTest extends TestCase ]); } - public function test_observed_item_id_should_be_integer(): void + public function test_exists_fields(): void { $user = User::factory() ->has(Permission::factory([ @@ -164,523 +119,362 @@ class StoreTest extends TestCase ])) ->create(); - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'observed_item_id' => $this->faker->name - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'observed_item_id' => __('validation.integer', ['attribute' => 'observed item id']) - ]); - } - - public function test_observed_item_id_should_be_existed_in_db(): void - { - $observedItem = ObservedItem::factory()->create(); - - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'observed_item_id' => $this->faker->numberBetween(10, 20) - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'observed_item_id' => __('validation.exists', ['attribute' => 'observed item id']) - ]); - } - - public function test_activity_date_is_required(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); - - $response->assertUnprocessable() - ->assertInvalid([ - 'activity_date' => __('validation.required', ['attribute' => 'تاریخ فعالیت']) - ]); - } - - public function test_activity_date_should_match_the_format(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'activity_date' => $this->faker->date('d-m-Y-H-i-s') - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'activity_date' => __('validation.date_format', ['attribute' => 'تاریخ فعالیت', 'format' => 'Y-m-d']) - ]); - } - - public function test_activity_time_is_required(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); - - $response->assertUnprocessable() - ->assertInvalid([ - 'activity_time' => __('validation.required', ['attribute' => 'ساعت فعالیت']) - ]); - } - - public function test_activity_time_should_match_the_format(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'activity_time' => $this->faker->date('d-m-Y-H-i-s') - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'activity_time' => __('validation.date_format', ['attribute' => 'ساعت فعالیت', 'format' => 'H:i']) - ]); - } - - public function test_before_image_should_be_image(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'before_image' => $this->faker->name - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'before_image' => __('validation.image', ['attribute' => 'before image']) - ]); - } - - public function test_before_image_should_be_less_than_4096kb(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $image = UploadedFile::fake()->create('image.jpg', 5096); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'before_image' => $image - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'before_image' => __('validation.max.file', ['attribute' => 'before image', 'max' => 4096]) - ]); - } - - public function test_after_image_should_be_image(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'after_image' => $this->faker->randomNumber() - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'after_image' => __('validation.image', ['attribute' => 'after image']) - ]); - } - - public function test_after_image_should_be_less_than_4096kb(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $image = UploadedFile::fake()->create('image.jpg', 5096); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'after_image' => $image - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'after_image' => __('validation.max.file', ['attribute' => 'after image', 'max' => 4096]) - ]); - } - - public function test_cmms_machine_id_is_required(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); - - $response->assertUnprocessable() - ->assertInvalid([ - 'cmms_machine_id' => __('validation.required', ['attribute' => 'کد یکتا ماشین']) - ]); - } - - public function test_cmms_machine_id_should_already_exists_on_the_table(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'cmms_machine_id' => $this->faker->numberBetween(10, 100) - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'cmms_machine_id' => __('validation.exists', ['attribute' => 'کد یکتا ماشین']) - ]); - } - - public function test_rahdar_id_is_required(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store')); - - $response->assertUnprocessable() - ->assertInvalid([ - 'rahdar_id' => __('validation.required', ['attribute' => 'rahdar id']) - ]); - } - - public function test_rahdar_id_should_already_exists_on_the_table(): void - { - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create(); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), [ - 'rahdar_id' => $this->faker->numberBetween(10, 100) - ]); - - $response->assertUnprocessable() - ->assertInvalid([ - 'rahdar_id' => __('validation.exists', ['attribute' => 'rahdar id']) - ]); - } - - public function test_province_user_is_prohibited_to_access(): void - { - $edarateOstani = EdarateOstani::factory()->create(); - $cmmsMachine = CMMSMachine::factory()->create(); - $rahdar = Rahdaran::factory()->create(); - - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create([ - 'edarate_ostani_id' => $edarateOstani->id - ]); - $data = [ - 'start_point' => '12,12', - 'item_id' => $this->faker->numberBetween(1, 10), - 'sub_item_id' => $this->faker->numberBetween(1, 10), - 'amount' => $this->faker->numberBetween(1, 10), - 'activity_date' => $this->faker->date(), - 'activity_time' => $this->faker->date('H:i'), - 'before_image' => UploadedFile::fake()->create('image.jpg', 10), - 'after_image' => UploadedFile::fake()->create('image.jpg', 10), - 'cmms_machine_id' => $cmmsMachine->id, - 'rahdar_id' => $rahdar->id, + 'machines_id' => [$this->faker->numberBetween(10000, 99999)], + 'rahdaran_id' => [$this->faker->numberBetween(10000, 99999)], + 'observed_item_id' => $this->faker->numberBetween(10000, 99999), ]; $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); - $response->assertStatus(400) - ->assertExactJson([ - 'message' => 'امکان ثبت فعالیت برای ادارات استانی و ستادی وجود ندارد!' + $response->assertUnprocessable() + ->assertInvalid([ + 'machines_id.0', + 'rahdaran_id.0', + 'observed_item_id', ]); } - public function test_user_should_have_edarate_shahri_id(): void + public function test_image_fields(): void { - $city = City::factory()->create(); - $cmmsMachine = CMMSMachine::factory()->create(); - $rahdar = Rahdaran::factory()->create(); - $user = User::factory() ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create([ - 'city_id' => $city->id - ]); + 'name' => 'create-road-item'])) + ->create(); $data = [ - 'start_point' => '12,12', - 'item_id' => $this->faker->numberBetween(1, 10), - 'sub_item_id' => $this->faker->numberBetween(1, 10), - 'amount' => $this->faker->numberBetween(1, 10), - 'activity_date' => $this->faker->date(), - 'activity_time' => $this->faker->date('H:i'), - 'before_image' => UploadedFile::fake()->create('image.jpg', 10), - 'after_image' => UploadedFile::fake()->create('image.jpg', 10), - 'cmms_machine_id' => $cmmsMachine->id, - 'rahdar_id' => $rahdar->id, + 'before_image' =>$this->faker->name, + 'after_image' =>$this->faker->name, ]; $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); - $response->assertStatus(400) - ->assertExactJson([ - 'message' => 'اداره شهری برای شما در سامانه ثبت نشده است!' - ]); - } - - public function test_end_point_required_when_info_item_needs_end_point(): void - { - $city = City::factory()->create(); - $edarateShari = EdarateShahri::factory()->create(); - $cmmsMachine = CMMSMachine::factory()->create(); - $rahdar = Rahdaran::factory()->create(); - - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create([ - 'city_id' => $city->id, - 'edarate_shahri_id' => $edarateShari->id - ]); - - $data = [ - 'start_point' => '12,12', - 'item_id' => $this->faker->numberBetween(1, 10), - 'sub_item_id' => $this->faker->numberBetween(1, 10), - 'amount' => $this->faker->numberBetween(1, 10), - 'activity_date' => $this->faker->date(), - 'activity_time' => $this->faker->date('H:i'), - 'before_image' => UploadedFile::fake()->create('image.jpg', 10), - 'after_image' => UploadedFile::fake()->create('image.jpg', 10), - 'cmms_machine_id' => $cmmsMachine->id, - 'rahdar_id' => $rahdar->id, - ]; - - InfoItem::factory()->create([ - 'item' => $data['item_id'], - 'sub_item' => $data['sub_item_id'], - 'needs_end_point' => 1 - ]); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); - $response->assertUnprocessable() ->assertInvalid([ - 'end_point' => __('validation.required', ['attribute' => 'end_point']) + 'before_image' => __('validation.image', ['attribute' => 'before image']), + 'after_image' => __('validation.image', ['attribute' => 'after image']), ]); } - public function test_before_image_required_when_info_item_needs_image(): void + public function test_image_should_be_less_than_4096kb(): void { - $city = City::factory()->create(); - $edarateShari = EdarateShahri::factory()->create(); - $cmmsMachine = CMMSMachine::factory()->create(); - $rahdar = Rahdaran::factory()->create(); - $user = User::factory() ->has(Permission::factory([ 'name' => 'create-road-item' ])) - ->create([ - 'city_id' => $city->id, - 'edarate_shahri_id' => $edarateShari->id - ]); + ->create(); $data = [ - 'start_point' => '12,12', - 'item_id' => $this->faker->numberBetween(1, 10), - 'sub_item_id' => $this->faker->numberBetween(1, 10), - 'amount' => $this->faker->numberBetween(1, 10), - 'activity_date' => $this->faker->date(), - 'activity_time' => $this->faker->date('H:i'), - 'cmms_machine_id' => $cmmsMachine->id, - 'rahdar_id' => $rahdar->id, + 'before_image' => UploadedFile::fake()->create('image.jpg', 5096), + 'after_image' => UploadedFile::fake()->create('image.jpg', 5096), ]; - InfoItem::factory()->create([ - 'item' => $data['item_id'], - 'sub_item' => $data['sub_item_id'], - 'needs_image' => 1 - ]); - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); $response->assertUnprocessable() ->assertInvalid([ - 'before_image' => __('validation.required', ['attribute' => 'before_image']) + 'before_image' => __('validation.max.file', ['attribute' => 'before image', 'max' => 4096]), + 'after_image' => __('validation.max.file', ['attribute' => 'after image', 'max' => 4096]), ]); } - public function test_after_image_required_when_info_item_needs_image(): void + public function test_date_format_fields(): void { - $city = City::factory()->create(); - $edarateShari = EdarateShahri::factory()->create(); - $cmmsMachine = CMMSMachine::factory()->create(); - $rahdar = Rahdaran::factory()->create(); - $user = User::factory() ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create([ - 'city_id' => $city->id, - 'edarate_shahri_id' => $edarateShari->id - ]); + 'name' => 'create-road-item'])) + ->create(); $data = [ - 'start_point' => '12,12', - 'item_id' => $this->faker->numberBetween(1, 10), - 'sub_item_id' => $this->faker->numberBetween(1, 10), - 'amount' => $this->faker->numberBetween(1, 10), - 'activity_date' => $this->faker->date(), - 'activity_time' => $this->faker->date('H:i'), - 'cmms_machine_id' => $cmmsMachine->id, - 'rahdar_id' => $rahdar->id, + 'activity_date' => $this->faker->date('d-m-Y-H-i-s'), + 'activity_time'=> $this->faker->date('d-m-Y-H-i-s'), ]; - InfoItem::factory()->create([ - 'item' => $data['item_id'], - 'sub_item' => $data['sub_item_id'], - 'needs_image' => 1 - ]); - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); $response->assertUnprocessable() ->assertInvalid([ - 'after_image' => __('validation.required', ['attribute' => 'after_image']) + 'activity_date' => __('validation.date_format', ['attribute' => 'تاریخ فعالیت', 'format' => 'Y-m-d']), + 'activity_time' => __('validation.date_format', ['attribute' => 'ساعت فعالیت', 'format' => 'H:i']), ]); } +// +// public function test_province_user_is_prohibited_to_access(): void +// { +// $edarateOstani = EdarateOstani::factory()->create(); +// $cmmsMachine = CMMSMachine::factory()->create(); +// $rahdar = Rahdaran::factory()->create(); +// +// $user = User::factory() +// ->has(Permission::factory([ +// 'name' => 'create-road-item' +// ])) +// ->create([ +// 'edarate_ostani_id' => $edarateOstani->id +// ]); +// +// $data = [ +// 'start_point' => '12,12', +// 'item_id' => $this->faker->numberBetween(1, 10), +// 'sub_item_id' => $this->faker->numberBetween(1, 10), +// 'amount' => $this->faker->numberBetween(1, 10), +// 'activity_date' => $this->faker->date(), +// 'activity_time' => $this->faker->date('H:i'), +// 'before_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'after_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'cmms_machine_id' => $cmmsMachine->id, +// 'rahdar_id' => $rahdar->id, +// ]; +// +// $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); +// +// $response->assertStatus(400) +// ->assertExactJson([ +// 'message' => 'امکان ثبت فعالیت برای ادارات استانی و ستادی وجود ندارد!' +// ]); +// } +// +// public function test_user_should_have_edarate_shahri_id(): void +// { +// $city = City::factory()->create(); +// $cmmsMachine = CMMSMachine::factory()->create(); +// $rahdar = Rahdaran::factory()->create(); +// +// $user = User::factory() +// ->has(Permission::factory([ +// 'name' => 'create-road-item' +// ])) +// ->create([ +// 'city_id' => $city->id +// ]); +// +// $data = [ +// 'start_point' => '12,12', +// 'item_id' => $this->faker->numberBetween(1, 10), +// 'sub_item_id' => $this->faker->numberBetween(1, 10), +// 'amount' => $this->faker->numberBetween(1, 10), +// 'activity_date' => $this->faker->date(), +// 'activity_time' => $this->faker->date('H:i'), +// 'before_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'after_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'cmms_machine_id' => $cmmsMachine->id, +// 'rahdar_id' => $rahdar->id, +// ]; +// +// $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); +// +// $response->assertStatus(400) +// ->assertExactJson([ +// 'message' => 'اداره شهری برای شما در سامانه ثبت نشده است!' +// ]); +// } +// +// public function test_end_point_required_when_info_item_needs_end_point(): void +// { +// $city = City::factory()->create(); +// $edarateShari = EdarateShahri::factory()->create(); +// $cmmsMachine = CMMSMachine::factory()->create(); +// $rahdar = Rahdaran::factory()->create(); +// +// $user = User::factory() +// ->has(Permission::factory([ +// 'name' => 'create-road-item' +// ])) +// ->create([ +// 'city_id' => $city->id, +// 'edarate_shahri_id' => $edarateShari->id +// ]); +// +// $data = [ +// 'start_point' => '12,12', +// 'item_id' => $this->faker->numberBetween(1, 10), +// 'sub_item_id' => $this->faker->numberBetween(1, 10), +// 'amount' => $this->faker->numberBetween(1, 10), +// 'activity_date' => $this->faker->date(), +// 'activity_time' => $this->faker->date('H:i'), +// 'before_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'after_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'cmms_machine_id' => $cmmsMachine->id, +// 'rahdar_id' => $rahdar->id, +// ]; +// +// InfoItem::factory()->create([ +// 'item' => $data['item_id'], +// 'sub_item' => $data['sub_item_id'], +// 'needs_end_point' => 1 +// ]); +// +// $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); +// +// $response->assertUnprocessable() +// ->assertInvalid([ +// 'end_point' => __('validation.required', ['attribute' => 'end_point']) +// ]); +// } +// +// public function test_before_image_required_when_info_item_needs_image(): void +// { +// $city = City::factory()->create(); +// $edarateShari = EdarateShahri::factory()->create(); +// $cmmsMachine = CMMSMachine::factory()->create(); +// $rahdar = Rahdaran::factory()->create(); +// +// $user = User::factory() +// ->has(Permission::factory([ +// 'name' => 'create-road-item' +// ])) +// ->create([ +// 'city_id' => $city->id, +// 'edarate_shahri_id' => $edarateShari->id +// ]); +// +// $data = [ +// 'start_point' => '12,12', +// 'item_id' => $this->faker->numberBetween(1, 10), +// 'sub_item_id' => $this->faker->numberBetween(1, 10), +// 'amount' => $this->faker->numberBetween(1, 10), +// 'activity_date' => $this->faker->date(), +// 'activity_time' => $this->faker->date('H:i'), +// 'cmms_machine_id' => $cmmsMachine->id, +// 'rahdar_id' => $rahdar->id, +// ]; +// +// InfoItem::factory()->create([ +// 'item' => $data['item_id'], +// 'sub_item' => $data['sub_item_id'], +// 'needs_image' => 1 +// ]); +// +// $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); +// +// $response->assertUnprocessable() +// ->assertInvalid([ +// 'before_image' => __('validation.required', ['attribute' => 'before_image']) +// ]); +// } +// +// public function test_after_image_required_when_info_item_needs_image(): void +// { +// $city = City::factory()->create(); +// $edarateShari = EdarateShahri::factory()->create(); +// $cmmsMachine = CMMSMachine::factory()->create(); +// $rahdar = Rahdaran::factory()->create(); +// +// $user = User::factory() +// ->has(Permission::factory([ +// 'name' => 'create-road-item' +// ])) +// ->create([ +// 'city_id' => $city->id, +// 'edarate_shahri_id' => $edarateShari->id +// ]); +// +// $data = [ +// 'start_point' => '12,12', +// 'item_id' => $this->faker->numberBetween(1, 10), +// 'sub_item_id' => $this->faker->numberBetween(1, 10), +// 'amount' => $this->faker->numberBetween(1, 10), +// 'activity_date' => $this->faker->date(), +// 'activity_time' => $this->faker->date('H:i'), +// 'cmms_machine_id' => $cmmsMachine->id, +// 'rahdar_id' => $rahdar->id, +// ]; +// +// InfoItem::factory()->create([ +// 'item' => $data['item_id'], +// 'sub_item' => $data['sub_item_id'], +// 'needs_image' => 1 +// ]); +// +// $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); +// +// $response->assertUnprocessable() +// ->assertInvalid([ +// 'after_image' => __('validation.required', ['attribute' => 'after_image']) +// ]); +// } +// +// public function test_can_store_a_new_road_item_project(): void +// { +// $city = City::factory()->create(); +// $province = Province::factory()->create(); +// $edarateShari = EdarateShahri::factory()->create(); +// $cmmsMachine = CMMSMachine::factory()->create(); +// $rahdar = Rahdaran::factory()->create(); +// +// LogList::factory()->create([ +// 'log_unique_code' => 1154 +// ]); +// UserActivityLog::factory()->create(); +// +// $user = User::factory() +// ->has(Permission::factory([ +// 'name' => 'create-road-item' +// ])) +// ->create([ +// 'city_id' => $city->id, +// 'province_id' => $province->id, +// 'edarate_shahri_id' => $edarateShari->id +// ]); +// +// Storage::fake('public'); +// +// $this->mock(NominatimService::class, function (MockInterface $mock) { +// $mock->shouldReceive('get_way_id_from_nominatim') +// ->once() +// ->andReturn(0); +// }); +// +// $data = [ +// 'start_point' => '12,12', +// 'item_id' => $this->faker->numberBetween(1, 10), +// 'sub_item_id' => $this->faker->numberBetween(1, 10), +// 'amount' => $this->faker->numberBetween(1, 10), +// 'activity_date' => $this->faker->date(), +// 'activity_time' => $this->faker->date('H:i'), +// 'before_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'after_image' => UploadedFile::fake()->create('image.jpg', 10), +// 'cmms_machine_id' => $cmmsMachine->id, +// 'rahdar_id' => $rahdar->id, +// ]; +// +// $infoItem = InfoItem::factory()->create([ +// 'item' => $data['item_id'], +// 'sub_item' => $data['sub_item_id'], +// 'needs_image' => 1 +// ]); +// +// $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); +// +// $response->assertOk() +// ->assertExactJson([ +// 'message' => __('messages.successful') +// ]); +// +// $this->assertDatabaseHas('road_items_projects', [ +// 'start_lat' => 12, +// 'start_lng' => 12, +// 'item' => $data['item_id'], +// 'sub_item' => $data['sub_item_id'], +// 'province_id' => $province->id, +// 'city_id' => $city->id, +// 'user_name' => $user->name, +// 'start_way_id' => 0, +// 'info_id' => $infoItem->id, +// 'status' => 0, +// 'status_fa' => 'در حال بررسی', +// 'edarat_id' => $user->edarate_shahri_id, +// 'cmms_machine_id' => $cmmsMachine->id, +// 'cmms_machine_code' => $cmmsMachine->machine_code, +// 'rahdar_id' => $rahdar->id, +// 'rahdar_code' => $rahdar->code +// ]); +// +// $this->assertDatabaseHas('user_activity_logs', [ +// 'user_id' => $user->id, +// 'username' => $user->username, +// 'log_unique_code' => 1154, +// ]); +// - public function test_can_store_a_new_road_item_project(): void - { - $city = City::factory()->create(); - $province = Province::factory()->create(); - $edarateShari = EdarateShahri::factory()->create(); - $cmmsMachine = CMMSMachine::factory()->create(); - $rahdar = Rahdaran::factory()->create(); - - LogList::factory()->create([ - 'log_unique_code' => 1154 - ]); - UserActivityLog::factory()->create(); - - $user = User::factory() - ->has(Permission::factory([ - 'name' => 'create-road-item' - ])) - ->create([ - 'city_id' => $city->id, - 'province_id' => $province->id, - 'edarate_shahri_id' => $edarateShari->id - ]); - - Storage::fake('public'); - - $this->mock(NominatimService::class, function (MockInterface $mock) { - $mock->shouldReceive('get_way_id_from_nominatim') - ->once() - ->andReturn(0); - }); - - $data = [ - 'start_point' => '12,12', - 'item_id' => $this->faker->numberBetween(1, 10), - 'sub_item_id' => $this->faker->numberBetween(1, 10), - 'amount' => $this->faker->numberBetween(1, 10), - 'activity_date' => $this->faker->date(), - 'activity_time' => $this->faker->date('H:i'), - 'before_image' => UploadedFile::fake()->create('image.jpg', 10), - 'after_image' => UploadedFile::fake()->create('image.jpg', 10), - 'cmms_machine_id' => $cmmsMachine->id, - 'rahdar_id' => $rahdar->id, - ]; - - $infoItem = InfoItem::factory()->create([ - 'item' => $data['item_id'], - 'sub_item' => $data['sub_item_id'], - 'needs_image' => 1 - ]); - - $response = $this->actingAs($user)->postJson(route('v3.road_items.store'), $data); - - $response->assertOk() - ->assertExactJson([ - 'message' => __('messages.successful') - ]); - - $this->assertDatabaseHas('road_items_projects', [ - 'start_lat' => 12, - 'start_lng' => 12, - 'item' => $data['item_id'], - 'sub_item' => $data['sub_item_id'], - 'province_id' => $province->id, - 'city_id' => $city->id, - 'user_name' => $user->name, - 'start_way_id' => 0, - 'info_id' => $infoItem->id, - 'status' => 0, - 'status_fa' => 'در حال بررسی', - 'edarat_id' => $user->edarate_shahri_id, - 'cmms_machine_id' => $cmmsMachine->id, - 'cmms_machine_code' => $cmmsMachine->machine_code, - 'rahdar_id' => $rahdar->id, - 'rahdar_code' => $rahdar->code - ]); - - $this->assertDatabaseHas('user_activity_logs', [ - 'user_id' => $user->id, - 'username' => $user->username, - 'log_unique_code' => 1154, - ]); - } } From 9e1b25d9a185524c72176c99731605e458f174d8 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Mon, 7 Apr 2025 18:13:23 +0330 Subject: [PATCH 07/48] creat index forRoadMaintenanceStationController and write routs for this --- .../RoadMaintenanceStationController.php | 138 ++++++++++++++++++ routes/v3.php | 9 ++ 2 files changed, 147 insertions(+) create mode 100644 app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php new file mode 100644 index 00000000..220ab30f --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -0,0 +1,138 @@ +user(); + auth()->user()->addActivityComplete(1019); + + $allowedFilters = ['*']; + $allowedSortings = ['*']; + + $province = $request->province ?? null; + $status = $request->status ?? null; + $type = $request->type ?? null; + + $query = RahdariPoint::with('files'); + if ($user->can('show-tollhouse')) { + $query + ->when($province, function ($query, $province) { + return $query->where('province_id', $province); + }) + ->when($status, function ($query, $status) { + return $query->where('status', $status); + }) + ->when($type, function ($query, $type) { + return $query->where('type', $type); + }); + + } elseif ($user->can('show-tollhouse-province')) { + $query + ->where('province_id', $user->province_id) + ->when($status, function ($query, $status) { + return $query->where('status', $status); + }) + ->when($type, function ($query, $type) { + return $query->where('type', $type); + }); + + } else { + return response()->json(['message' => 'Forbidden'], 403); + } + $data = DataTableFacade::run( + $query, + $request, + allowedFilters: $allowedFilters, + allowedSortings: $allowedSortings + ); + + + $processedData = []; + + foreach ($data['data'] as $key => $item) { + $processedData[$key] = $item; + + + if ($user->can('edit-tollhouse')) { + $processedData[$key]['canEdit'] = 1; + } elseif ($user->can('edit-tollhouse-province')) { + $processedData[$key]['canEdit'] = $item['province_id'] == $user->province_id ? 1 : 0; + } else { + $processedData[$key]['canEdit'] = 0; + } + + + if ($user->can('delete-tollhouse')) { + $processedData[$key]['canDelete'] = 1; + } elseif ($user->can('delete-tollhouse-province')) { + $processedData[$key]['canDelete'] = $item['province_id'] == $user->province_id ? 1 : 0; + } else { + $processedData[$key]['canDelete'] = 0; + } + } + + $data['data'] = $processedData; + + return response()->json($data); + } + /** + * Show the form for creating a new resource. + */ + public function create() + { + // + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(string $id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id) + { + // + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + // + } +} diff --git a/routes/v3.php b/routes/v3.php index bef397bb..42e8c110 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -10,6 +10,7 @@ use App\Http\Controllers\V3\Dashboard\ItemsManagementController; use App\Http\Controllers\V3\Dashboard\ObservedItemController; use App\Http\Controllers\V3\Dashboard\AccidentReceiptController; use App\Http\Controllers\V3\Dashboard\OtpManagementController; +use App\Http\Controllers\V3\Dashboard\RoadMaintenanceStationController; use App\Http\Controllers\V3\Dashboard\Reports\AccidentReceiptReportController; use App\Http\Controllers\V3\Dashboard\Reports\RoadItemsReportController; use App\Http\Controllers\V3\Dashboard\Reports\RoadPatrolReportController; @@ -385,3 +386,11 @@ Route::prefix('permissions') }); Route::get('/notifications', NotificationController::class)->name('notifications'); + +Route::prefix('Road-Maintenance-Station') + ->name('Road-Maintenance-Station.') + ->controller( RoadMaintenanceStationController::class) + ->group(function () { + Route::get('/', 'index')->name('index'); + }); + From 93d177537999b8d4b56a5c6d2442c9a034878be0 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 8 Apr 2025 11:11:26 +0330 Subject: [PATCH 08/48] add axis type to safety excel --- .../Dashboard/SafetyAndPrivacyController.php | 22 +++++++++++++++ .../ThirdStepStoreRequest.php | 1 + .../SafetyAndPrivacyTableService.php | 2 +- ...add_column_to_safety_and_privacy_table.php | 28 +++++++++++++++++++ .../SafetyAndPrivacy/CartableReport.blade.php | 21 ++++++++------ 5 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 database/migrations/2025_04_07_133638_add_column_to_safety_and_privacy_table.php diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 463a2900..df748c35 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -141,6 +141,7 @@ class SafetyAndPrivacyController extends Controller 'step_fa' => 'گام سوم (برخورد)', '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, ]); $user->addActivityComplete(1136); @@ -201,4 +202,25 @@ class SafetyAndPrivacyController extends Controller ->select('id', 'item', 'item_str', 'sub_item_str as name', 'sub_item_unit as unit', 'needs_image', 'needs_end_point', 'sub_item') ->get()); } + + public function map(Request $request): JsonResponse + { + $province = $request->province_id; + $edare_shahri = $request->edare_shahri_id; + $step = $request->step; + $info_id = $request->info_id; + $fromDate = $request->from_date ? $request->from_date . ' 00:00:00' : now()->startOfDay()->toDateTimeString(); + $toDate = $request->date_to ? $request->date_to . ' 23:59:59' : now()->endOfDay()->toDateTimeString(); + + $activities = SafetyAndPrivacy::query() + ->when($province, fn ($query) => $query->where('province_id', '=', $province)) + ->when($edare_shahri, fn($query) => $query->where('edarate_shahri_id', '=', $edare_shahri)) + ->when($step, fn($query) => $query->where('step', '=', $step)) + ->when($info_id, fn($query) => $query->where('info_id', '=', $info_id)) + ->whereBetween('created_at', [$fromDate, $toDate]) + ->select('id', 'lat', 'lon', 'step') + ->get(); + + return $this->successResponse($activities); + } } diff --git a/app/Http/Requests/V3/SafetyAndPrivacy/ThirdStepStoreRequest.php b/app/Http/Requests/V3/SafetyAndPrivacy/ThirdStepStoreRequest.php index 652ea3a4..91879ed5 100644 --- a/app/Http/Requests/V3/SafetyAndPrivacy/ThirdStepStoreRequest.php +++ b/app/Http/Requests/V3/SafetyAndPrivacy/ThirdStepStoreRequest.php @@ -23,6 +23,7 @@ class ThirdStepStoreRequest extends FormRequest { return [ 'action_picture' => 'required|image', + 'action_date' => 'required|date', ]; } } diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index e7c9a85d..891999cc 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -20,7 +20,7 @@ class SafetyAndPrivacyTableService $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' + 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date' ]; if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable')) { diff --git a/database/migrations/2025_04_07_133638_add_column_to_safety_and_privacy_table.php b/database/migrations/2025_04_07_133638_add_column_to_safety_and_privacy_table.php new file mode 100644 index 00000000..b3934b8b --- /dev/null +++ b/database/migrations/2025_04_07_133638_add_column_to_safety_and_privacy_table.php @@ -0,0 +1,28 @@ +dateTime('action_date')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('safety_and_privacy', function (Blueprint $table) { + $table->dropColumn('action_date'); + }); + } +}; diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php index 48fb08bf..1888c78a 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php @@ -52,7 +52,15 @@ - مورد + مورد مشاهده شده + + + نوع محور + + + تاریخ ثبت @@ -60,20 +68,16 @@ - تاریخ ثبت مستندات قضایی + تاریخ بارگذاری مستندات قضایی - تاریخ اقدام + تاریخ ثبت اقدام وضعیت - - تاریخ ثبت - @@ -84,6 +88,8 @@ {{ $item['province_fa'] ?? '-' }} {{ $item['edare_shahri_name'] ?? '-' }} {{ $item['info_fa'] ?? '-' }} + {{ $item['axis_type_name'] ?? '-' }} + {{ $item['created_at'] ? verta($item['created_at'])->format('Y/n/j H:i:s') : '-' }} {{ $item['activity_date_time'] ? verta($item['activity_date_time'])->format('Y/n/j H:i:s') : '-' }} @@ -95,7 +101,6 @@ {{ $item['step_fa'] ?? '-' }} - {{ $item['created_at'] ? verta($item['created_at'])->format('Y/n/j H:i:s') : '-' }} @endforeach From 107f9ff469a691ad1e2298e0ffaca3773dfd4ba7 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 8 Apr 2025 14:32:41 +0330 Subject: [PATCH 09/48] add map api to safety --- routes/v3.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/v3.php b/routes/v3.php index 42e8c110..cc2cd997 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -347,6 +347,7 @@ Route::prefix('safety_and_privacy') Route::get('/{safetyAndPrivacy}', 'show')->name('show'); Route::delete('/{safetyAndPrivacy}', 'destroy')->name('destroy')->middleware('permission:delete-safety-and-privacy'); Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); + Route::get('/map', 'map')->name('map'); }); Route::prefix('safety_and_privacy_report') @@ -393,4 +394,3 @@ Route::prefix('Road-Maintenance-Station') ->group(function () { Route::get('/', 'index')->name('index'); }); - From 21f2dd7c2fb8974f4d97426bfc35a07005a7b657 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Wed, 9 Apr 2025 16:21:58 +0330 Subject: [PATCH 10/48] create show,store,update and delete for RoadMaintenanceStationController --- app/Enums/RoadMaintenanceStationTypes.php | 21 ++ .../RoadMaintenanceStationController.php | 236 +++++++++++++----- .../RoadMaintenanceStation/StoreRequest.php | 57 +++++ .../RoadMaintenanceStation/UpdateRequest.php | 52 ++++ routes/v3.php | 12 +- 5 files changed, 312 insertions(+), 66 deletions(-) create mode 100644 app/Enums/RoadMaintenanceStationTypes.php create mode 100644 app/Http/Requests/V3/RoadMaintenanceStation/StoreRequest.php create mode 100644 app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php diff --git a/app/Enums/RoadMaintenanceStationTypes.php b/app/Enums/RoadMaintenanceStationTypes.php new file mode 100644 index 00000000..4d557675 --- /dev/null +++ b/app/Enums/RoadMaintenanceStationTypes.php @@ -0,0 +1,21 @@ + "دائمی", + 2 => "موقت", + 3 => "فصلی", + ]; + + return $mapArray[$state]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index 220ab30f..7b1069ab 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -2,12 +2,22 @@ namespace App\Http\Controllers\V3\Dashboard; +use App\Enums\RoadMaintenanceStationTypes; use App\Facades\DataTable\DataTableFacade; +use App\Facades\File\FileFacade; use App\Http\Controllers\Controller; +use App\Http\Requests\V3\RoadMaintenanceStation\StoreRequest; +use App\Http\Requests\V3\RoadMaintenanceStation\UpdateRequest; use App\Http\Traits\ApiResponse; +use App\Models\City; +use App\Models\Province; use App\Models\RahdariPoint; +use App\Models\RahdariPointHistory; +use Hekmatinasser\Verta\Facades\Verta; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; +use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; class RoadMaintenanceStationController extends Controller @@ -22,36 +32,21 @@ class RoadMaintenanceStationController extends Controller $allowedFilters = ['*']; $allowedSortings = ['*']; - $province = $request->province ?? null; - $status = $request->status ?? null; - $type = $request->type ?? null; + $province = $request->province; + $status = $request->status; + $type = $request->type; + + $query = RahdariPoint::with('files') + ->when($status, fn ($query, $status) => $query->where('status', $status)) + ->when($type, fn ($query, $type) => $query->where('type', $type)); - $query = RahdariPoint::with('files'); if ($user->can('show-tollhouse')) { - $query - ->when($province, function ($query, $province) { - return $query->where('province_id', $province); - }) - ->when($status, function ($query, $status) { - return $query->where('status', $status); - }) - ->when($type, function ($query, $type) { - return $query->where('type', $type); - }); - - } elseif ($user->can('show-tollhouse-province')) { - $query - ->where('province_id', $user->province_id) - ->when($status, function ($query, $status) { - return $query->where('status', $status); - }) - ->when($type, function ($query, $type) { - return $query->where('type', $type); - }); - - } else { - return response()->json(['message' => 'Forbidden'], 403); + $query->when($province, fn($query) => $query->where('province_id', $province)); } + elseif ($user->can('show-tollhouse-province')) { + $query->where('province_id', $user->province_id); + } + $data = DataTableFacade::run( $query, $request, @@ -60,79 +55,190 @@ class RoadMaintenanceStationController extends Controller ); - $processedData = []; - - foreach ($data['data'] as $key => $item) { - $processedData[$key] = $item; - - + foreach ($data['data'] as &$stations) { if ($user->can('edit-tollhouse')) { - $processedData[$key]['canEdit'] = 1; + $stations['canEdit'] = 1; } elseif ($user->can('edit-tollhouse-province')) { - $processedData[$key]['canEdit'] = $item['province_id'] == $user->province_id ? 1 : 0; + if ($user->province_id) { + $stations['canEdit'] = 1; + } else { + $stations['canEdit'] = 0; + } } else { - $processedData[$key]['canEdit'] = 0; + $stations['canEdit'] = 0; } - if ($user->can('delete-tollhouse')) { - $processedData[$key]['canDelete'] = 1; + $stations['canDelete'] = 1; } elseif ($user->can('delete-tollhouse-province')) { - $processedData[$key]['canDelete'] = $item['province_id'] == $user->province_id ? 1 : 0; + if ($user->province_id) { + $stations['canDelete'] = 1; + } else { + $stations['canDelete'] = 0; + } } else { - $processedData[$key]['canDelete'] = 0; + $stations['canDelete'] = 0; } } - $data['data'] = $processedData; - return response()->json($data); } - /** - * Show the form for creating a new resource. - */ - public function create() - { - // - } /** * Store a newly created resource in storage. */ - public function store(Request $request) + public function store(StoreRequest $request): JsonResponse { - // + $provinceName = Province::query()->find($request->province_id)->name_fa; + + $cityName = City::query()->find($request->city_id)->name_fa; + + $station = RahdariPoint::query()->create([ + 'province_id' => $request->province_id, + 'province_name' => $provinceName, + 'city_id' => $request->city_id, + 'city_name' => $cityName, + 'name' => $request->name, + 'status' => $request->status, + 'type' => $request->type, + 'type_fa' =>RoadMaintenanceStationTypes::name($request->type), + 'team_num' => $request->team_num, + 'staff_num' => $request->staff_num, + 'phone' => $request->phone, + 'responsible_name' => $request->responsible_name, + 'responsible_mobile' => $request->responsible_mobile, + 'successor_name' => $request->successor_name, + 'successor_mobile' => $request->successor_mobile, + 'machines_light' => $request->machines_light, + 'machines_sheavy' => $request->machines_sheavy, + 'machines_heavy' => $request->machines_heavy, + 'code' => $request->code, + 'lat' => $request->lat, + 'lng' => $request->lng, + 'updated_at_fa' => verta()->now()->format('Y/m/d H:i:s'), + ]); + + $uploadPaths = [ + 'overview_files_1' => 'road_stations', + 'overview_files_2' => 'road_stations', + 'overview_files_3' => 'road_stations', + 'overview_files_4' => 'road_stations', + 'overview_files_5' => 'road_stations', + ]; + + foreach ($uploadPaths as $field => $path) { + if ($request->hasFile($field)) { + $station->files()->create([ + 'path' => FileFacade::save($request->$field, $path) + ]); + } + } + + return $this->successResponse(); } /** * Display the specified resource. */ - public function show(string $id) + public function show(RahdariPoint $rahdariPoint): JsonResponse { - // - } - - /** - * Show the form for editing the specified resource. - */ - public function edit(string $id) - { - // + return $this->successResponse( + $rahdariPoint->load('files') + ); } /** * Update the specified resource in storage. */ - public function update(Request $request, string $id) + public function update(UpdateRequest $request, RahdariPoint $rahdariPoint): JsonResponse { - // + + RahdariPointHistory::query()->create([ + 'user_id' => $request->user()->id, + 'point_id' => $rahdariPoint->id, + 'previous_status' => $rahdariPoint->status, + 'previous_type' => $rahdariPoint->type, + 'previous_team_num' => $rahdariPoint->team_num, + 'previous_staff_num' => $rahdariPoint->staff_num, + 'previous_phone' => $rahdariPoint->phone, + 'previous_responsible_name' => $rahdariPoint->responsible_name, + 'previous_responsible_mobile' => $rahdariPoint->responsible_mobile, + 'previous_successor_name' => $rahdariPoint->successor_name, + 'previous_successor_mobile' => $rahdariPoint->successor_mobile, + 'previous_machines_light' => $rahdariPoint->machines_light, + 'previous_machines_sheavy' => $rahdariPoint->machines_sheavy, + 'previous_machines_heavy' => $rahdariPoint->machines_heavy, + 'previous_lat' => $rahdariPoint->lat, + 'previous_lng' => $rahdariPoint->lng, + 'new_files' => json_encode($rahdariPoint->files), + ]); + + $rahdariPoint->update([ + 'status' => $request->input('status', $rahdariPoint->status), + 'type' => $request->input('type', $rahdariPoint->type), + 'type_fa' => RoadMaintenanceStationTypes::name($request->type) ?? $rahdariPoint->type_fa, + 'team_num' => $request->input('team_num', $rahdariPoint->team_num), + 'staff_num' => $request->input('staff_num', $rahdariPoint->staff_num), + 'phone' => $request->input('phone', $rahdariPoint->phone), + 'responsible_name' => $request->input('responsible_name', $rahdariPoint->responsible_name), + 'responsible_mobile' => $request->input('responsible_mobile', $rahdariPoint->responsible_mobile), + 'successor_name' => $request->input('successor_name', $rahdariPoint->successor_name), + 'successor_mobile' => $request->input('successor_mobile', $rahdariPoint->successor_mobile), + 'machines_light' => $request->input('machines_light', $rahdariPoint->machines_light), + 'machines_sheavy' => $request->input('machines_sheavy', $rahdariPoint->machines_sheavy), + 'machines_heavy' => $request->input('machines_heavy', $rahdariPoint->machines_heavy), + 'lat' => $request->input('lat', $rahdariPoint->lat), + 'lng' => $request->input('lng', $rahdariPoint->lng), + 'lat_from' => $request->lat_from, + 'lng_from' => $request->lng_from, + 'geometry' => $request->geometry, + 'lat_to' => $request->lat_to, + 'lng_to' => $request->lng_to, + 'color' => $request->color, + 'updated_at_fa' => verta()->now()->format('Y/m/d H:i:s'), + ]); + + $uploadFields = [ + 'overview_files_1', + 'overview_files_2', + 'overview_files_3', + 'overview_files_4', + 'overview_files_5', + ]; + + foreach ($uploadFields as $index => $field) { + if ($request->hasFile($field)) { + $existingFile = $rahdariPoint->files->get($index); + + $newPath = FileFacade::save($request->$field, 'rahdari_points/overview'); + + if ($existingFile) { + FileFacade::delete($existingFile->path); + $existingFile->update(['path' => $newPath]); + } else { +// dd($rahdariPoint->id); + $rahdariPoint->files()->create(['path' => $newPath]); + } + } + } + + return $this->successResponse(); } /** * Remove the specified resource from storage. */ - public function destroy(string $id) + public function destroy(RahdariPoint $rahdariPoint): JsonResponse { - // + foreach ($rahdariPoint->files as $file) { + FileFacade::delete($file->path); + } + + RahdariPointHistory::query()->where('point_id', $rahdariPoint->id)->delete(); + + $rahdariPoint->files()->delete(); + $rahdariPoint->delete(); + + return $this->successResponse(); } } diff --git a/app/Http/Requests/V3/RoadMaintenanceStation/StoreRequest.php b/app/Http/Requests/V3/RoadMaintenanceStation/StoreRequest.php new file mode 100644 index 00000000..e58698ea --- /dev/null +++ b/app/Http/Requests/V3/RoadMaintenanceStation/StoreRequest.php @@ -0,0 +1,57 @@ +user(); + + return $user->hasPermissionTo('add-tollhouse') || + ($user->hasPermissionTo('add-tollhouse-province') && $this->province_id == $user->province_id); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'province_id' => 'required|exists:provinces,id', + 'city_id' => 'required|exists:cities,id', + 'name' => 'required|string|max:255', + 'status' => 'required|in:0,1', + 'type' =>'required|in:1,2,3', + 'team_num' => 'numeric', + 'staff_num' => 'numeric', + 'phone' => 'string|max:50', + 'responsible_name' => 'string|max:255', + 'responsible_mobile' => 'string|max:50', + 'successor_name' => 'string|max:255', + 'successor_mobile' => 'string|max:50', + 'machines_light' => 'numeric', + 'machines_sheavy' => 'numeric', + 'machines_heavy' => 'numeric', + 'code' => 'string|max:50', + 'lat' => 'numeric', + 'lng' => 'numeric', + 'overview_files_1' => 'file|mimes:jpg,jpeg,png,pdf|max:51200', + 'overview_files_2' => 'file|mimes:jpg,jpeg,png,pdf|max:51200', + 'overview_files_3' => 'file|mimes:jpg,jpeg,png,pdf|max:51200', + 'overview_files_4' => 'file|mimes:jpg,jpeg,png,pdf|max:51200', + 'overview_files_5' => 'file|mimes:jpg,jpeg,png,pdf|max:51200', + ]; + } +} diff --git a/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php b/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php new file mode 100644 index 00000000..892394aa --- /dev/null +++ b/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php @@ -0,0 +1,52 @@ +|string> + */ + public function rules(): array + { + return [ + 'status' => 'integer|in:0,1', + 'type' => 'integer|in:1,2,3', + 'team_num' => 'numeric', + 'staff_num' => 'numeric', + 'phone' => 'string|max:50', + 'responsible_name' => 'string|max:255', + 'responsible_mobile' => 'string|max:50', + 'successor_name' => 'string|max:255', + 'successor_mobile' => 'string|max:50', + 'machines_light' => 'numeric', + 'machines_sheavy' => 'numeric', + 'machines_heavy' => 'numeric', + 'lat' => 'numeric', + 'lng' => 'numeric', + 'lat_from' => 'numeric', + 'lng_from' => 'numeric', + 'lat_to' => 'numeric', + 'lng_to' => 'numeric', + 'color' => 'numeric', + 'geometry' => 'numeric', + 'overview_files_1' => 'file|mimes:jpg,jpeg,png,pdf|max:5120', + 'overview_files_2' => 'file|mimes:jpg,jpeg,png,pdf|max:5120', + 'overview_files_3' => 'file|mimes:jpg,jpeg,png,pdf|max:5120', + 'overview_files_4' => 'file|mimes:jpg,jpeg,png,pdf|max:5120', + 'overview_files_5' => 'file|mimes:jpg,jpeg,png,pdf|max:5120', + ]; + } +} diff --git a/routes/v3.php b/routes/v3.php index 42e8c110..45e8a384 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -391,6 +391,16 @@ Route::prefix('Road-Maintenance-Station') ->name('Road-Maintenance-Station.') ->controller( RoadMaintenanceStationController::class) ->group(function () { - Route::get('/', 'index')->name('index'); + Route::get('/', 'index')->name('index') + ->middleware('permission:show-tollhouse|show-tollhouse-province'); + Route::post('/', 'store')->name('store') + ->middleware('permission:add-tollhouse|add-tollhouse-province'); + Route::get('/{rahdariPoint}', 'show')->name('show') + ->middleware('permission:show-tollhouse|show-tollhouse-province'); + Route::post('/{rahdariPoint}', 'update')->name('update') + ->middleware('permission:edit-tollhouse|edit-tollhouse-province'); + Route::delete('/{rahdariPoint}', 'destroy')->name('destroy') + ->middleware('permission:delete-tollhouse|delete-tollhouse-province'); + }); From a1d3b86a6958f63e52d96cb3af18b12cd888885e Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 12 Apr 2025 12:55:33 +0330 Subject: [PATCH 11/48] add map report to safety --- .../Commands/RoadObservationProblems.php | 2 +- app/Http/Controllers/Api/BiController.php | 4 ++- .../Dashboard/SafetyAndPrivacyController.php | 25 ++++++------------- routes/v3.php | 2 +- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/app/Console/Commands/RoadObservationProblems.php b/app/Console/Commands/RoadObservationProblems.php index d56da6bb..c778d66c 100755 --- a/app/Console/Commands/RoadObservationProblems.php +++ b/app/Console/Commands/RoadObservationProblems.php @@ -99,7 +99,7 @@ class RoadObservationProblems extends Command 'EndTime' => $value->EndTime ?? null, 'StartDate' => $value->StartDate ?? null, 'EndDate' => $value->EndDate ?? null, - 'StartTime_DateTime' => $value->StartTime_DateTime ?? null, + 'StartTime_DateTime' => $value->StartTime_DateTime ? Carbon::createFromFormat('m/d/Y h:i:s A', $value->StartTime_DateTime)->format('Y-m-d H:i:s') : null, 'StartTime_DateTime_fa' => Verta::instance($value->StartTime_DateTime) ?? null, 'EndTime_DateTime' => $value->EndTime_DateTime ?? null, 'AutoID' => $value->AutoID ?? null, diff --git a/app/Http/Controllers/Api/BiController.php b/app/Http/Controllers/Api/BiController.php index 91272974..ecb4de03 100644 --- a/app/Http/Controllers/Api/BiController.php +++ b/app/Http/Controllers/Api/BiController.php @@ -150,6 +150,7 @@ class BiController extends Controller public function getDiagram(Request $request) { + ini_set('memory_limit', '-1'); $subjectID = $request->subject_id; $provinceID = $request->province_id; $dateFrom = $request->from_date; @@ -1021,6 +1022,7 @@ class BiController extends Controller public function separationActivityTypeRahdariActivities(Request $request) { + ini_set('memory_limit', '-1'); $dateFrom = $request->from_date; $dateTo = $request->to_date; $provinceID = $request->province_id ?? null; @@ -1198,4 +1200,4 @@ class BiController extends Controller 'data' => round($camps, 2) ]); } -} \ 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 df748c35..ef1caacf 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\V3\Dashboard; use App\Enums\AxisTypes; use App\Exports\V3\SafetyAndPrivacy\CartableReport; +use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; use App\Http\Controllers\Controller; use App\Http\Requests\V3\SafetyAndPrivacy\FirstStepStoreRequest; @@ -205,22 +206,12 @@ class SafetyAndPrivacyController extends Controller public function map(Request $request): JsonResponse { - $province = $request->province_id; - $edare_shahri = $request->edare_shahri_id; - $step = $request->step; - $info_id = $request->info_id; - $fromDate = $request->from_date ? $request->from_date . ' 00:00:00' : now()->startOfDay()->toDateTimeString(); - $toDate = $request->date_to ? $request->date_to . ' 23:59:59' : now()->endOfDay()->toDateTimeString(); - - $activities = SafetyAndPrivacy::query() - ->when($province, fn ($query) => $query->where('province_id', '=', $province)) - ->when($edare_shahri, fn($query) => $query->where('edarate_shahri_id', '=', $edare_shahri)) - ->when($step, fn($query) => $query->where('step', '=', $step)) - ->when($info_id, fn($query) => $query->where('info_id', '=', $info_id)) - ->whereBetween('created_at', [$fromDate, $toDate]) - ->select('id', 'lat', 'lon', 'step') - ->get(); - - return $this->successResponse($activities); + return DataTableFacade::run( + SafetyAndPrivacy::query(), + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: ['id', 'lat', 'lon', 'step'] + ); } } diff --git a/routes/v3.php b/routes/v3.php index cc2cd997..cd08f3cb 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -341,13 +341,13 @@ Route::prefix('safety_and_privacy') 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::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('/{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'); Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); - Route::get('/map', 'map')->name('map'); }); Route::prefix('safety_and_privacy_report') From c5894051c1f9e3dcf945c41f16cc4e5d7b765ac5 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 12 Apr 2025 14:56:43 +0330 Subject: [PATCH 12/48] return json type --- .../Controllers/V3/Dashboard/SafetyAndPrivacyController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index ef1caacf..5741f4ff 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -206,12 +206,12 @@ class SafetyAndPrivacyController extends Controller public function map(Request $request): JsonResponse { - return DataTableFacade::run( + return response()->json(DataTableFacade::run( SafetyAndPrivacy::query(), $request, allowedFilters: ['*'], allowedSortings: ['*'], allowedSelects: ['id', 'lat', 'lon', 'step'] - ); + )); } } From a643bdf626566a367e5ad352b43e0576db59edcc Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 12 Apr 2025 15:06:50 +0330 Subject: [PATCH 13/48] debug the index method --- .../RoadMaintenanceStationController.php | 36 ++++++++----------- routes/v3.php | 16 +++------ 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index 7b1069ab..28d3a078 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -38,12 +38,10 @@ class RoadMaintenanceStationController extends Controller $query = RahdariPoint::with('files') ->when($status, fn ($query, $status) => $query->where('status', $status)) - ->when($type, fn ($query, $type) => $query->where('type', $type)); + ->when($type, fn ($query, $type) => $query->where('type', $type)) + ->when($province, fn($query, $province) => $query->where('province_id', $province)); - if ($user->can('show-tollhouse')) { - $query->when($province, fn($query) => $query->where('province_id', $province)); - } - elseif ($user->can('show-tollhouse-province')) { + if ($user->hasPermissionTo('show-tollhouse-province')) { $query->where('province_id', $user->province_id); } @@ -56,27 +54,23 @@ class RoadMaintenanceStationController extends Controller foreach ($data['data'] as &$stations) { - if ($user->can('edit-tollhouse')) { + if ($user->hasPermissionTo('edit-tollhouse')) { $stations['canEdit'] = 1; - } elseif ($user->can('edit-tollhouse-province')) { - if ($user->province_id) { - $stations['canEdit'] = 1; - } else { - $stations['canEdit'] = 0; - } - } else { + } + elseif ($user->hasPermissionTo('edit-tollhouse-province') && $stations->province_id == $user->province_id) { + $stations['canEdit'] = 1; + } + else { $stations['canEdit'] = 0; } - if ($user->can('delete-tollhouse')) { + if ($user->hasPermissionTo('delete-tollhouse')) { $stations['canDelete'] = 1; - } elseif ($user->can('delete-tollhouse-province')) { - if ($user->province_id) { - $stations['canDelete'] = 1; - } else { - $stations['canDelete'] = 0; - } - } else { + } + elseif ($user->hasPermissionTo('delete-tollhouse-province') && $stations->province_id == $user->province_id) { + $stations['canDelete'] = 1; + } + else { $stations['canDelete'] = 0; } } diff --git a/routes/v3.php b/routes/v3.php index 28207829..54aa3439 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -392,15 +392,9 @@ Route::prefix('Road-Maintenance-Station') ->name('Road-Maintenance-Station.') ->controller( RoadMaintenanceStationController::class) ->group(function () { - Route::get('/', 'index')->name('index') - ->middleware('permission:show-tollhouse|show-tollhouse-province'); - Route::post('/', 'store')->name('store') - ->middleware('permission:add-tollhouse|add-tollhouse-province'); - Route::get('/{rahdariPoint}', 'show')->name('show') - ->middleware('permission:show-tollhouse|show-tollhouse-province'); - Route::post('/{rahdariPoint}', 'update')->name('update') - ->middleware('permission:edit-tollhouse|edit-tollhouse-province'); - Route::delete('/{rahdariPoint}', 'destroy')->name('destroy') - ->middleware('permission:delete-tollhouse|delete-tollhouse-province'); - + Route::get('/', 'index')->name('index')->middleware('permission:show-tollhouse|show-tollhouse-province'); + Route::post('/', 'store')->name('store')->middleware('permission:add-tollhouse|add-tollhouse-province'); + Route::get('/{rahdariPoint}', 'show')->name('show')->middleware('permission:show-tollhouse|show-tollhouse-province'); + Route::post('/{rahdariPoint}', 'update')->name('update')->middleware('permission:edit-tollhouse|edit-tollhouse-province'); + Route::delete('/{rahdariPoint}', 'destroy')->name('destroy')->middleware('permission:delete-tollhouse|delete-tollhouse-province'); }); From 52f22656e2b8322d3b47d96f187dd71b2304cb40 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 12 Apr 2025 16:13:49 +0330 Subject: [PATCH 14/48] add action date to safety --- app/Models/SafetyAndPrivacy.php | 1 + routes/v3.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index 8cb61c14..ac347063 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -36,6 +36,7 @@ class SafetyAndPrivacy extends Model 'action_picture_document_upload_date', 'axis_type_id', 'axis_type_name', + 'action_date' ]; public $table = "safety_and_privacy"; diff --git a/routes/v3.php b/routes/v3.php index 54aa3439..211b4a6d 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -388,8 +388,8 @@ Route::prefix('permissions') Route::get('/notifications', NotificationController::class)->name('notifications'); -Route::prefix('Road-Maintenance-Station') - ->name('Road-Maintenance-Station.') +Route::prefix('road_maintenance_station') + ->name('roadMaintenanceStation.') ->controller( RoadMaintenanceStationController::class) ->group(function () { Route::get('/', 'index')->name('index')->middleware('permission:show-tollhouse|show-tollhouse-province'); From 822730afb13a9a50e0eaaeecb2408c4ab472a583 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 13 Apr 2025 09:54:26 +0330 Subject: [PATCH 15/48] debug rahdari point --- .../Dashboard/RoadMaintenanceStationController.php | 14 ++++---------- app/Http/Controllers/V3/NotificationController.php | 7 +++++-- app/Models/RahdariPoint.php | 9 ++++----- routes/v3.php | 2 +- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index 28d3a078..b59790da 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -136,9 +136,7 @@ class RoadMaintenanceStationController extends Controller */ public function show(RahdariPoint $rahdariPoint): JsonResponse { - return $this->successResponse( - $rahdariPoint->load('files') - ); + return $this->successResponse($rahdariPoint->load('files')); } /** @@ -146,7 +144,6 @@ class RoadMaintenanceStationController extends Controller */ public function update(UpdateRequest $request, RahdariPoint $rahdariPoint): JsonResponse { - RahdariPointHistory::query()->create([ 'user_id' => $request->user()->id, 'point_id' => $rahdariPoint->id, @@ -204,13 +201,12 @@ class RoadMaintenanceStationController extends Controller if ($request->hasFile($field)) { $existingFile = $rahdariPoint->files->get($index); - $newPath = FileFacade::save($request->$field, 'rahdari_points/overview'); + $newPath = FileFacade::save($request->field, 'rahdari_points/overview'); if ($existingFile) { FileFacade::delete($existingFile->path); $existingFile->update(['path' => $newPath]); } else { -// dd($rahdariPoint->id); $rahdariPoint->files()->create(['path' => $newPath]); } } @@ -222,14 +218,12 @@ class RoadMaintenanceStationController extends Controller /** * Remove the specified resource from storage. */ - public function destroy(RahdariPoint $rahdariPoint): JsonResponse + public function destroy(RahdariPoint $rahdariPoint): JsonResponse { foreach ($rahdariPoint->files as $file) { FileFacade::delete($file->path); } - - RahdariPointHistory::query()->where('point_id', $rahdariPoint->id)->delete(); - + $rahdariPoint->rahdariPointHistories()->delete(); $rahdariPoint->files()->delete(); $rahdariPoint->delete(); diff --git a/app/Http/Controllers/V3/NotificationController.php b/app/Http/Controllers/V3/NotificationController.php index d322a95a..01d4ae63 100644 --- a/app/Http/Controllers/V3/NotificationController.php +++ b/app/Http/Controllers/V3/NotificationController.php @@ -122,8 +122,11 @@ class NotificationController extends Controller ->get(); } - $safety_and_privacy['step_one'] = isset($activity[0]) ? $activity[0]->cnt : 0; - $safety_and_privacy['step_two'] = isset($activity[1]) ? $activity[1]->cnt : 0; + $step_one = $activity->where('step', '=', 1)->first(); + $step_two = $activity->where('step', '=', 2)->first(); + + $safety_and_privacy['step_one'] = $step_one->cnt ?? 0; + $safety_and_privacy['step_two'] = $step_two->cnt ?? 0; return $safety_and_privacy; } diff --git a/app/Models/RahdariPoint.php b/app/Models/RahdariPoint.php index 66f9fe02..3cbbc611 100644 --- a/app/Models/RahdariPoint.php +++ b/app/Models/RahdariPoint.php @@ -3,6 +3,8 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\MorphMany; class RahdariPoint extends Model { @@ -69,15 +71,12 @@ class RahdariPoint extends Model 'updated_at_fa', ]; - /** - * Get all of the point's files. - */ - public function files() + public function files(): MorphMany { return $this->morphMany('App\Models\PointFile', 'point_fileable'); } - public function rahdariPointHistories() + public function rahdariPointHistories(): HasMany { return $this->hasMany('App\Models\RahdariPointHistory', 'point_id'); } diff --git a/routes/v3.php b/routes/v3.php index 211b4a6d..54310f34 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -393,7 +393,7 @@ Route::prefix('road_maintenance_station') ->controller( RoadMaintenanceStationController::class) ->group(function () { Route::get('/', 'index')->name('index')->middleware('permission:show-tollhouse|show-tollhouse-province'); - Route::post('/', 'store')->name('store')->middleware('permission:add-tollhouse|add-tollhouse-province'); + Route::post('/', 'store')->name('store'); Route::get('/{rahdariPoint}', 'show')->name('show')->middleware('permission:show-tollhouse|show-tollhouse-province'); Route::post('/{rahdariPoint}', 'update')->name('update')->middleware('permission:edit-tollhouse|edit-tollhouse-province'); Route::delete('/{rahdariPoint}', 'destroy')->name('destroy')->middleware('permission:delete-tollhouse|delete-tollhouse-province'); From b25ce4bfe2c268d84ee3cdd16011f67f4ce5c48f Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Mon, 14 Apr 2025 10:47:11 +0330 Subject: [PATCH 16/48] create map for rahdari point --- .../RoadMaintenanceStationController.php | 38 ++++++++++++++----- app/Models/PointFile.php | 7 +++- .../SafetyAndPrivacy/CartableReport.blade.php | 10 ++--- routes/v3.php | 2 + 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index b59790da..bef19a2b 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -36,7 +36,7 @@ class RoadMaintenanceStationController extends Controller $status = $request->status; $type = $request->type; - $query = RahdariPoint::with('files') + $query = RahdariPoint::query() ->when($status, fn ($query, $status) => $query->where('status', $status)) ->when($type, fn ($query, $type) => $query->where('type', $type)) ->when($province, fn($query, $province) => $query->where('province_id', $province)); @@ -113,11 +113,11 @@ class RoadMaintenanceStationController extends Controller ]); $uploadPaths = [ - 'overview_files_1' => 'road_stations', - 'overview_files_2' => 'road_stations', - 'overview_files_3' => 'road_stations', - 'overview_files_4' => 'road_stations', - 'overview_files_5' => 'road_stations', + 'overview_files_1' => "road_stations/{$station->id}", + 'overview_files_2' => "road_stations/{$station->id}", + 'overview_files_3' => "road_stations/{$station->id}", + 'overview_files_4' => "road_stations/{$station->id}", + 'overview_files_5' => "road_stations/{$station->id}", ]; foreach ($uploadPaths as $field => $path) { @@ -136,7 +136,7 @@ class RoadMaintenanceStationController extends Controller */ public function show(RahdariPoint $rahdariPoint): JsonResponse { - return $this->successResponse($rahdariPoint->load('files')); + return $this->successResponse($rahdariPoint); } /** @@ -201,13 +201,13 @@ class RoadMaintenanceStationController extends Controller if ($request->hasFile($field)) { $existingFile = $rahdariPoint->files->get($index); - $newPath = FileFacade::save($request->field, 'rahdari_points/overview'); + $path = FileFacade::save($request->$field, "road_stations/{$rahdariPoint->id}"); if ($existingFile) { FileFacade::delete($existingFile->path); - $existingFile->update(['path' => $newPath]); + $existingFile->update(['path' => $path]); } else { - $rahdariPoint->files()->create(['path' => $newPath]); + $rahdariPoint->files()->create(['path' => $path]); } } } @@ -229,4 +229,22 @@ class RoadMaintenanceStationController extends Controller return $this->successResponse(); } + + public function images(RahdariPoint $rahdariPoint): JsonResponse + { + return $this->successResponse($rahdariPoint->files()->get(['path'])); + } + + public function map(Request $request): JsonResponse + { + auth()->user()->addActivityComplete(1023); + + return response()->json(DataTableFacade::run( + RahdariPoint::query(), + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: ['id', 'lat', 'lng', 'status', 'type'], + )); + } } diff --git a/app/Models/PointFile.php b/app/Models/PointFile.php index 4c59eb93..67638dca 100644 --- a/app/Models/PointFile.php +++ b/app/Models/PointFile.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\MorphTo; class PointFile extends Model { @@ -25,13 +26,15 @@ class PointFile extends Model * @var array */ protected $fillable = [ - 'path' + 'path', + 'point_fileable_id', + 'point_fileable_type', ]; /** * Get the owning point_fileable model. */ - public function point_fileable() + public function point_fileable(): MorphTo { return $this->morphTo(); } diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php index 1888c78a..c1065678 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php @@ -21,18 +21,18 @@ - - - @@ -72,7 +72,7 @@ diff --git a/routes/v3.php b/routes/v3.php index 54310f34..53df4d15 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -394,6 +394,8 @@ Route::prefix('road_maintenance_station') ->group(function () { Route::get('/', 'index')->name('index')->middleware('permission:show-tollhouse|show-tollhouse-province'); Route::post('/', 'store')->name('store'); + Route::post('/map', 'map')->name('map'); + Route::post('/images/{rahdariPoint}', 'images')->name('images'); Route::get('/{rahdariPoint}', 'show')->name('show')->middleware('permission:show-tollhouse|show-tollhouse-province'); Route::post('/{rahdariPoint}', 'update')->name('update')->middleware('permission:edit-tollhouse|edit-tollhouse-province'); Route::delete('/{rahdariPoint}', 'destroy')->name('destroy')->middleware('permission:delete-tollhouse|delete-tollhouse-province'); From a3600c68faa30b0f576d457d70bd3be093e5df17 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Mon, 14 Apr 2025 11:14:06 +0330 Subject: [PATCH 17/48] add full url for pictures --- .../V3/Dashboard/RoadMaintenanceStationController.php | 2 +- app/Models/PointFile.php | 9 +++++++++ routes/v3.php | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index bef19a2b..17ae8698 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -136,7 +136,7 @@ class RoadMaintenanceStationController extends Controller */ public function show(RahdariPoint $rahdariPoint): JsonResponse { - return $this->successResponse($rahdariPoint); + return $this->successResponse($rahdariPoint->load('files')); } /** diff --git a/app/Models/PointFile.php b/app/Models/PointFile.php index 67638dca..fc437a39 100644 --- a/app/Models/PointFile.php +++ b/app/Models/PointFile.php @@ -2,8 +2,10 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphTo; +use Illuminate\Support\Facades\Storage; class PointFile extends Model { @@ -38,4 +40,11 @@ class PointFile extends Model { return $this->morphTo(); } + + protected function path(): Attribute + { + return Attribute::make( + get: fn($value) => $value == null ? null : Storage::disk('public')->url($value) + ); + } } diff --git a/routes/v3.php b/routes/v3.php index 53df4d15..a71859a2 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -394,8 +394,8 @@ Route::prefix('road_maintenance_station') ->group(function () { Route::get('/', 'index')->name('index')->middleware('permission:show-tollhouse|show-tollhouse-province'); Route::post('/', 'store')->name('store'); - Route::post('/map', 'map')->name('map'); - Route::post('/images/{rahdariPoint}', 'images')->name('images'); + Route::get('/map', 'map')->name('map'); + Route::get('/images/{rahdariPoint}', 'images')->name('images'); Route::get('/{rahdariPoint}', 'show')->name('show')->middleware('permission:show-tollhouse|show-tollhouse-province'); Route::post('/{rahdariPoint}', 'update')->name('update')->middleware('permission:edit-tollhouse|edit-tollhouse-province'); Route::delete('/{rahdariPoint}', 'destroy')->name('destroy')->middleware('permission:delete-tollhouse|delete-tollhouse-province'); From 2e0b49df45e838756584544183178e7883c2624c Mon Sep 17 00:00:00 2001 From: joddyabott Date: Mon, 14 Apr 2025 15:40:10 +0330 Subject: [PATCH 18/48] create new column for database and improve the controller --- .../RoadMaintenanceStationController.php | 78 +++++++++++-------- .../RoadMaintenanceStation/UpdateRequest.php | 3 + ...ulums_to_rahdari_point_histories_table.php | 40 ++++++++++ 3 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 database/migrations/2025_04_14_150741_add_culums_to_rahdari_point_histories_table.php diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index 17ae8698..3dd07a5a 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -13,11 +13,8 @@ use App\Models\City; use App\Models\Province; use App\Models\RahdariPoint; use App\Models\RahdariPointHistory; -use Hekmatinasser\Verta\Facades\Verta; use Illuminate\Http\Request; use Illuminate\Http\JsonResponse; -use Illuminate\Support\Facades\Auth; -use Illuminate\Support\Facades\DB; class RoadMaintenanceStationController extends Controller @@ -83,15 +80,15 @@ class RoadMaintenanceStationController extends Controller */ public function store(StoreRequest $request): JsonResponse { - $provinceName = Province::query()->find($request->province_id)->name_fa; + $province = Province::query()->find($request->province_id); - $cityName = City::query()->find($request->city_id)->name_fa; + $city = City::query()->find($request->city_id); $station = RahdariPoint::query()->create([ - 'province_id' => $request->province_id, - 'province_name' => $provinceName, - 'city_id' => $request->city_id, - 'city_name' => $cityName, + 'province_id' => $province->id, + 'province_name' => $province->name_fa, + 'city_id' => $city->id, + 'city_name' => $city->name_fa, 'name' => $request->name, 'status' => $request->status, 'type' => $request->type, @@ -144,45 +141,59 @@ class RoadMaintenanceStationController extends Controller */ public function update(UpdateRequest $request, RahdariPoint $rahdariPoint): JsonResponse { + $province = Province::query()->find($request->province_id); + + $city = City::query()->find($request->city_id); + RahdariPointHistory::query()->create([ 'user_id' => $request->user()->id, 'point_id' => $rahdariPoint->id, + 'previous_province_id' => $province->id, + 'previous_province_name' => $province->name_fa, + 'previous_city_id' => $city->id, + 'previous_city_name' => $city->name_fa, + 'previous_name' => $rahdariPoint->name, 'previous_status' => $rahdariPoint->status, 'previous_type' => $rahdariPoint->type, - 'previous_team_num' => $rahdariPoint->team_num, - 'previous_staff_num' => $rahdariPoint->staff_num, + 'previous_team_num' => $rahdariPoint->team_num, + 'previous_staff_num' => $rahdariPoint->staff_num, 'previous_phone' => $rahdariPoint->phone, - 'previous_responsible_name' => $rahdariPoint->responsible_name, - 'previous_responsible_mobile' => $rahdariPoint->responsible_mobile, - 'previous_successor_name' => $rahdariPoint->successor_name, - 'previous_successor_mobile' => $rahdariPoint->successor_mobile, - 'previous_machines_light' => $rahdariPoint->machines_light, - 'previous_machines_sheavy' => $rahdariPoint->machines_sheavy, - 'previous_machines_heavy' => $rahdariPoint->machines_heavy, + 'previous_responsible_name' => $rahdariPoint->responsible_name, + 'previous_responsible_mobile' => $rahdariPoint->responsible_mobile, + 'previous_successor_name' => $rahdariPoint->successor_name, + 'previous_successor_mobile' => $rahdariPoint->successor_mobile, + 'previous_machines_light' => $rahdariPoint->machines_light, + 'previous_machines_sheavy' => $rahdariPoint->machines_sheavy, + 'previous_machines_heavy' => $rahdariPoint->machines_heavy, 'previous_lat' => $rahdariPoint->lat, 'previous_lng' => $rahdariPoint->lng, 'new_files' => json_encode($rahdariPoint->files), ]); $rahdariPoint->update([ - 'status' => $request->input('status', $rahdariPoint->status), - 'type' => $request->input('type', $rahdariPoint->type), + 'province_id' => $province->id, + 'province_name' => $province->name_fa, + 'city_id' => $city->id, + 'city_name' => $city->name_fa, + 'name' => $request->input('name'), + 'status' => $request->input('status'), + 'type' => $request->input('type',), 'type_fa' => RoadMaintenanceStationTypes::name($request->type) ?? $rahdariPoint->type_fa, - 'team_num' => $request->input('team_num', $rahdariPoint->team_num), - 'staff_num' => $request->input('staff_num', $rahdariPoint->staff_num), - 'phone' => $request->input('phone', $rahdariPoint->phone), - 'responsible_name' => $request->input('responsible_name', $rahdariPoint->responsible_name), - 'responsible_mobile' => $request->input('responsible_mobile', $rahdariPoint->responsible_mobile), - 'successor_name' => $request->input('successor_name', $rahdariPoint->successor_name), - 'successor_mobile' => $request->input('successor_mobile', $rahdariPoint->successor_mobile), - 'machines_light' => $request->input('machines_light', $rahdariPoint->machines_light), - 'machines_sheavy' => $request->input('machines_sheavy', $rahdariPoint->machines_sheavy), - 'machines_heavy' => $request->input('machines_heavy', $rahdariPoint->machines_heavy), - 'lat' => $request->input('lat', $rahdariPoint->lat), - 'lng' => $request->input('lng', $rahdariPoint->lng), + 'team_num' => $request->input('team_num'), + 'staff_num' => $request->input('staff_num'), + 'phone' => $request->input('phone'), + 'responsible_name' => $request->input('responsible_name'), + 'responsible_mobile' => $request->input('responsible_mobile'), + 'successor_name' => $request->input('successor_name'), + 'successor_mobile' => $request->input('successor_mobile'), + 'machines_light' => $request->input('machines_light'), + 'machines_sheavy' => $request->input('machines_sheavy'), + 'machines_heavy' => $request->input('machines_heavy'), + 'lat' => $request->input('lat'), + 'lng' => $request->input('lng'), 'lat_from' => $request->lat_from, 'lng_from' => $request->lng_from, - 'geometry' => $request->geometry, + 'geometry' => $request->geometry, 'lat_to' => $request->lat_to, 'lng_to' => $request->lng_to, 'color' => $request->color, @@ -200,7 +211,6 @@ class RoadMaintenanceStationController extends Controller foreach ($uploadFields as $index => $field) { if ($request->hasFile($field)) { $existingFile = $rahdariPoint->files->get($index); - $path = FileFacade::save($request->$field, "road_stations/{$rahdariPoint->id}"); if ($existingFile) { diff --git a/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php b/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php index 892394aa..3443e3b1 100644 --- a/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php +++ b/app/Http/Requests/V3/RoadMaintenanceStation/UpdateRequest.php @@ -22,6 +22,9 @@ class UpdateRequest extends FormRequest public function rules(): array { return [ + 'province_id' => 'required|exists:provinces,id', + 'city_id' => 'required|exists:cities,id', + 'name' => 'required|string|max:255', 'status' => 'integer|in:0,1', 'type' => 'integer|in:1,2,3', 'team_num' => 'numeric', diff --git a/database/migrations/2025_04_14_150741_add_culums_to_rahdari_point_histories_table.php b/database/migrations/2025_04_14_150741_add_culums_to_rahdari_point_histories_table.php new file mode 100644 index 00000000..4743a7a3 --- /dev/null +++ b/database/migrations/2025_04_14_150741_add_culums_to_rahdari_point_histories_table.php @@ -0,0 +1,40 @@ +after('user_id', function (Blueprint $table) { + $table->unsignedSmallInteger('previous_province_id')->nullable(); + $table->string('previous_province_name')->nullable(); + $table->unsignedSmallInteger('previous_city_id')->nullable(); + $table->string('previous_city_name')->nullable(); + $table->string('previous_name')->nullable(); + }); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('rahdari_point_histories', function (Blueprint $table) { + $table->dropColumn([ + 'previous_province_id', + 'previous_province_name', + 'previous_city_id', + 'previous_city_name', + 'previous_name', + ]); + }); + } +}; From 8d138b83390d6a066862b2fcd8213f860ed7750d Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 15 Apr 2025 10:45:47 +0330 Subject: [PATCH 19/48] add group by feature to datatable --- app/Facades/DataTable/DataTable.php | 9 +- .../Dashboard/SafetyAndPrivacyController.php | 7 + app/Models/RahdariPointHistory.php | 5 + .../SafetyAndPrivacyTableService.php | 177 +++++------------- app/Services/DataTable/DataTableInput.php | 6 + app/Services/DataTable/DataTableService.php | 16 +- 6 files changed, 91 insertions(+), 129 deletions(-) diff --git a/app/Facades/DataTable/DataTable.php b/app/Facades/DataTable/DataTable.php index ae637a86..86d25fe6 100644 --- a/app/Facades/DataTable/DataTable.php +++ b/app/Facades/DataTable/DataTable.php @@ -28,7 +28,8 @@ class DataTable array $allowedFilters = [], array $allowedRelations = [], array $allowedSortings = [], - array $allowedSelects = [] + array $allowedSelects = [], + ?array $allowedGroupBy = null ): array { @@ -43,7 +44,8 @@ class DataTable $sorting, $rels, $allowedFilters, - $allowedSortings + $allowedSortings, + $allowedGroupBy ); $query = $this->makeQueryFromModel($mixed); @@ -52,7 +54,8 @@ class DataTable ->setAllowedFilters($allowedFilters) ->setAllowedRelations($allowedRelations) ->setAllowedSortings($allowedSortings) - ->setAllowedSelects($allowedSelects); + ->setAllowedSelects($allowedSelects) + ->setAllowedGroupBy($allowedGroupBy); return $dataTableService->getData(); } diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 5741f4ff..693a1864 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -24,16 +24,23 @@ use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Validator; use Maatwebsite\Excel\Facades\Excel; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Throwable; class SafetyAndPrivacyController extends Controller { use ApiResponse; + /** + * @throws Throwable + */ public function index(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse { return response()->json($safetyAndPrivacyTableService->datatable($request)); } + /** + * @throws Throwable + */ public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse { $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; diff --git a/app/Models/RahdariPointHistory.php b/app/Models/RahdariPointHistory.php index e8d2e9fd..c6d359bc 100644 --- a/app/Models/RahdariPointHistory.php +++ b/app/Models/RahdariPointHistory.php @@ -13,6 +13,11 @@ class RahdariPointHistory extends Model */ protected $fillable = [ 'user_id', + 'previous_province_id', + 'previous_province_name', + 'previous_city_id', + 'previous_city_name', + 'previous_name', 'previous_status', 'previous_type', 'previous_team_num', diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 891999cc..304c3532 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -2,17 +2,22 @@ namespace App\Services\Cartables; +use App\Exceptions\ProhibitedAction; use App\Facades\DataTable\DataTableFacade; use App\Http\Traits\ApiResponse; use App\Models\Province; use App\Models\SafetyAndPrivacy; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use Throwable; class SafetyAndPrivacyTableService { use ApiResponse; + /** + * @throws Throwable + */ public function dataTable(Request $request, $loadRelations = false) { $user = auth()->user(); @@ -27,16 +32,12 @@ class SafetyAndPrivacyTableService $query = SafetyAndPrivacy::query()->select($fields); } elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-province')) { - if (is_null($user->province_id)) { - return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); - } + throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); $query = SafetyAndPrivacy::query()->where('province_id', '=', $user->province_id)->select($fields); } elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-edarate-shahri')) { - if (is_null($user->edarate_shahri_id)) { - return $this->errorResponse('اداره ای برای شما در سامانه ثبت نشده است!'); - } + throw_if(is_null($user->edarate_shahri_id), new ProhibitedAction('اداره ای برای شما در سامانه ثبت نشده است!')); $query = SafetyAndPrivacy::query()->where('edare_shahri_id', '=', $user->edarate_shahri_id); } @@ -51,74 +52,45 @@ class SafetyAndPrivacyTableService public function countryActivity(Request $request): array { - $fromDate = $request->from_date ? $request->from_date . ' 00:00:00' : now()->startOfDay()->toDateTimeString(); - $toDate = $request->date_to ? $request->date_to . ' 23:59:59' : now()->endOfDay()->toDateTimeString(); - $axisTypeId = $request->axis_type_id; - $activities = []; + $countryQuery = SafetyAndPrivacy::query()->selectRaw('COUNT(*) as qty,info_id, step'); - $country = SafetyAndPrivacy::query() - ->selectRaw('COUNT(*) as qty,info_id, step') - ->whereBetween('created_at', [$fromDate, $toDate]) - ->when($axisTypeId, function ($query) use ($axisTypeId) { - $query->where('axis_type_id', '=', $axisTypeId); - }) - ->groupBy('info_id', 'step') - ->get(); - -// $country = DB::select( -// "SELECT COUNT(*) as qty,info_id, step -// FROM safety_and_privacy where created_at BETWEEN '".$fromDate."' and '".$toDate."' -// GROUP BY info_id,step" -// ); + $country = DataTableFacade::run( + $countryQuery, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedGroupBy: ['info_id', 'step'] + ); $countryTotalSum = 0; $countryData = [ 'name_fa' => 'کشوری', 'province_id' => -1, 'sum' => 0, - '89' => [ - '1' => 0, - '2' => 0, - '3' => 0, - ], - '90' => [ - '1' => 0, - '2' => 0, - '3' => 0, - ], - '91' => [ - '1' => 0, - '2' => 0, - '3' => 0, - ], + '89' => ['1' => 0, '2' => 0, '3' => 0,], + '90' => ['1' => 0, '2' => 0, '3' => 0,], + '91' => ['1' => 0, '2' => 0, '3' => 0,], ]; foreach ($country as $key => $value) { $countryTotalSum += $value->qty; $countryData[$value->info_id][$value->step] = $value->qty; $countryData["sum"] = $countryTotalSum; } + $activities[] = (object) $countryData; + $provinceQuery = Province::query()->selectRaw('province_id, province_fa, COUNT(*) as qty,info_id, step'); + $provinces = DataTableFacade::run( + $provinceQuery, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedGroupBy: ['info_id', 'step', 'province_id', 'province_fa'] + ); - $provinces = SafetyAndPrivacy::query() - ->selectRaw('province_id, province_fa, COUNT(*) as qty,info_id, step') - ->whereBetween('created_at', [$fromDate, $toDate]) - ->when($axisTypeId, function ($query) use ($axisTypeId) { - $query->where('axis_type_id', '=', $axisTypeId); - }) - ->groupBy('info_id', 'step', 'province_id', 'province_fa') - ->get(); - -// $provinces = DB::select( -// "SELECT province_id, province_fa, COUNT(*) as qty,info_id, step -// FROM safety_and_privacy where created_at BETWEEN '".$fromDate."' and '".$toDate."' -// GROUP BY info_id,step,province_id,province_fa" -// ); - - foreach ($provinces as $value) { + foreach ($provinces as $value) + { $provinceId = $value->province_id; - - // Check if the province already exists in the activities array if (!isset($activities[$provinceId])) { $activities[$provinceId] = (object) [ 'province_id' => $provinceId, @@ -129,64 +101,33 @@ class SafetyAndPrivacyTableService '91' => ['1' => 0, '2' => 0, '3' => 0], ]; } - $activities[$provinceId]->{$value->info_id}[$value->step] = $value->qty; $activities[$provinceId]->sum += $value->qty; } - $activities = array_values($activities); - - return [ - 'activities' => $activities, - 'fromDate' => $fromDate, - 'toDate' => $toDate, - ]; + return array_values($activities); } public function provinceActivity(Request $request): array { - $fromDate = $request->from_date ? $request->from_date . ' 00:00:00' : now()->startOfDay()->toDateTimeString(); - $toDate = $request->date_to ? $request->date_to . ' 23:59:59' : now()->endOfDay()->toDateTimeString(); - $provinceId = $request->province_id; - $axisTypeId = $request->axis_type_id; $activities = []; - - $province = SafetyAndPrivacy::query() - ->selectRaw('COUNT(*) as qty,info_id, step') - ->where('province_id', '=', $provinceId) - ->whereBetween('created_at', [$fromDate, $toDate]) - ->when($axisTypeId, function ($query) use ($axisTypeId) { - $query->where('axis_type_id', '=', $axisTypeId); - }) - ->groupBy('info_id', 'step') - ->get(); - -// $province = DB::select(' -// SELECT COUNT(*) as qty,info_id, step -// FROM safety_and_privacy where province_id ='.$provinceId.' and created_at BETWEEN "'.$fromDate.'" and "'.$toDate.'" -// GROUP BY info_id,step -// '); + $provinceQuery = Province::query()->selectRaw('COUNT(*) as qty,info_id, step'); + $province = DataTableFacade::run( + $provinceQuery, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedGroupBy: ['info_id', 'step'] + ); $provinceTotalSum = 0; $provinceData = [ 'name_fa' => 'استانی', 'edare_shahri_id' => -1, 'sum' => 0, - '89' => [ - '1' => 0, - '2' => 0, - '3' => 0, - ], - '90' => [ - '1' => 0, - '2' => 0, - '3' => 0, - ], - '91' => [ - '1' => 0, - '2' => 0, - '3' => 0, - ], + '89' => ['1' => 0, '2' => 0, '3' => 0,], + '90' => ['1' => 0, '2' => 0, '3' => 0,], + '91' => ['1' => 0, '2' => 0, '3' => 0,], ]; foreach ($province as $key => $value) { $provinceTotalSum += $value->qty; @@ -195,26 +136,18 @@ class SafetyAndPrivacyTableService } $activities[] = (object) $provinceData; - $cities = SafetyAndPrivacy::query() - ->selectRaw('edare_shahri_id, COUNT(*) as qty,info_id, step') - ->where('province_id', '=', $provinceId) - ->whereBetween('created_at', [$fromDate, $toDate]) - ->when($axisTypeId, function ($query) use ($axisTypeId) { - $query->where('axis_type_id', '=', $axisTypeId); - }) - ->groupBy('info_id', 'step', 'edare_shahri_id') - ->get(); + $citiesQuery = SafetyAndPrivacy::query()->selectRaw('edare_shahri_id, COUNT(*) as qty,info_id, step'); + $cities = DataTableFacade::run( + $citiesQuery, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedGroupBy: ['info_id', 'step', 'edare_shahri_id'] + ); -// $cities = DB::select(' -// SELECT edare_shahri_id, COUNT(*) as qty,info_id, step -// FROM safety_and_privacy where province_id ='.$provinceId.' and created_at BETWEEN "'.$fromDate.'" and "'.$toDate.'" -// GROUP BY info_id,step,edare_shahri_id -// '); - - foreach ($cities as $value) { + foreach ($cities as $value) + { $cityId = $value->edare_shahri_id; - - // Initialize data for each unique city if (!isset($activities[$cityId])) { $activities[$cityId] = (object) [ 'edare_shahri_id' => $cityId, @@ -229,12 +162,6 @@ class SafetyAndPrivacyTableService $activities[$cityId]->sum += $value->qty; } - $activities = array_values($activities); - - return [ - 'activities' => $activities, - 'fromDate' => $fromDate, - 'toDate' => $toDate, - ]; + return array_values($activities); } } diff --git a/app/Services/DataTable/DataTableInput.php b/app/Services/DataTable/DataTableInput.php index 8464e878..1bbe5200 100644 --- a/app/Services/DataTable/DataTableInput.php +++ b/app/Services/DataTable/DataTableInput.php @@ -22,6 +22,7 @@ class DataTableInput private array $rels, private array $allowedFilters, private array $allowedSortings, + private ?array $GroupBy, ) { } @@ -74,4 +75,9 @@ class DataTableInput { return $this->rels; } + + public function getGroupBy(): ?array + { + return $this->GroupBy; + } } diff --git a/app/Services/DataTable/DataTableService.php b/app/Services/DataTable/DataTableService.php index 647f6e44..442f6e48 100644 --- a/app/Services/DataTable/DataTableService.php +++ b/app/Services/DataTable/DataTableService.php @@ -13,6 +13,7 @@ class DataTableService protected array $allowedRelations; protected array $allowedSortings; protected array $allowedSelects; + protected array $allowedGroupBy; private int $totalRowCount; public function __construct( @@ -46,6 +47,12 @@ class DataTableService return $this; } + public function setAllowedGroupBy(array $allowedGroupBy): DataTableService + { + $this->allowedGroupBy = $allowedGroupBy; + return $this; + } + /** * Handle 'getData' operations * @return array @@ -88,7 +95,9 @@ class DataTableService foreach ($sorting as $sort){ $query = (new ApplySort($query, $sort))->apply(); } - + + $query = $this->applyGroupBy($query, $this->allowedGroupBy); + return $query; } @@ -101,6 +110,11 @@ class DataTableService return $query; } + protected function applyGroupBy(Builder $query, array $groupBy): Builder + { + return empty($groupBy) ? $query : $query->groupBy($groupBy); + } + protected function includeRelationsInQuery(Builder $query, array $rels): Builder { if (!empty($rels)) { From b46bd53254e14b972b8d4f26b60b577d2746ebdf Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 15 Apr 2025 11:14:38 +0330 Subject: [PATCH 20/48] return the correct data values --- .../Reports/SafetyAndPrivacyReportController.php | 4 ++-- .../Cartables/SafetyAndPrivacyTableService.php | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/Reports/SafetyAndPrivacyReportController.php b/app/Http/Controllers/V3/Dashboard/Reports/SafetyAndPrivacyReportController.php index cc3d5673..3346cdb7 100644 --- a/app/Http/Controllers/V3/Dashboard/Reports/SafetyAndPrivacyReportController.php +++ b/app/Http/Controllers/V3/Dashboard/Reports/SafetyAndPrivacyReportController.php @@ -22,7 +22,7 @@ class SafetyAndPrivacyReportController extends Controller { $data = $safetyAndPrivacyTableService->countryActivity($request); return $this->successResponse([ - 'activities' => $data['activities'], + 'activities' => $data, 'provinces' => Province::all(['id', 'name_fa']) ]); } @@ -31,7 +31,7 @@ class SafetyAndPrivacyReportController extends Controller { $data = $safetyAndPrivacyTableService->provinceActivity($request); return $this->successResponse([ - 'activities' => $data['activities'], + 'activities' => $data, 'edarateShahri' => EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']), ]); } diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 304c3532..33b8645a 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -72,14 +72,14 @@ class SafetyAndPrivacyTableService '90' => ['1' => 0, '2' => 0, '3' => 0,], '91' => ['1' => 0, '2' => 0, '3' => 0,], ]; - foreach ($country as $key => $value) { + foreach ($country['data'] as $key => $value) { $countryTotalSum += $value->qty; $countryData[$value->info_id][$value->step] = $value->qty; $countryData["sum"] = $countryTotalSum; } $activities[] = (object) $countryData; - $provinceQuery = Province::query()->selectRaw('province_id, province_fa, COUNT(*) as qty,info_id, step'); + $provinceQuery = SafetyAndPrivacy::query()->selectRaw('province_id, province_fa, COUNT(*) as qty,info_id, step'); $provinces = DataTableFacade::run( $provinceQuery, $request, @@ -88,7 +88,7 @@ class SafetyAndPrivacyTableService allowedGroupBy: ['info_id', 'step', 'province_id', 'province_fa'] ); - foreach ($provinces as $value) + foreach ($provinces['data'] as $value) { $provinceId = $value->province_id; if (!isset($activities[$provinceId])) { @@ -129,7 +129,7 @@ class SafetyAndPrivacyTableService '90' => ['1' => 0, '2' => 0, '3' => 0,], '91' => ['1' => 0, '2' => 0, '3' => 0,], ]; - foreach ($province as $key => $value) { + foreach ($province['data'] as $key => $value) { $provinceTotalSum += $value->qty; $provinceData["sum"] = $provinceTotalSum; $provinceData[$value->info_id][$value->step] = $value->qty; @@ -145,7 +145,7 @@ class SafetyAndPrivacyTableService allowedGroupBy: ['info_id', 'step', 'edare_shahri_id'] ); - foreach ($cities as $value) + foreach ($cities['data'] as $value) { $cityId = $value->edare_shahri_id; if (!isset($activities[$cityId])) { From ee933a3f917317d7e9e3901e0537128e0e5e0d44 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 15 Apr 2025 15:50:14 +0330 Subject: [PATCH 21/48] order image files --- app/Facades/DataTable/DataTable.php | 2 +- .../V3/Dashboard/RoadMaintenanceStationController.php | 2 +- app/Services/Cartables/SafetyAndPrivacyTableService.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Facades/DataTable/DataTable.php b/app/Facades/DataTable/DataTable.php index 86d25fe6..63699505 100644 --- a/app/Facades/DataTable/DataTable.php +++ b/app/Facades/DataTable/DataTable.php @@ -29,7 +29,7 @@ class DataTable array $allowedRelations = [], array $allowedSortings = [], array $allowedSelects = [], - ?array $allowedGroupBy = null + array $allowedGroupBy = [] ): array { diff --git a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php index 3dd07a5a..dc14f995 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadMaintenanceStationController.php @@ -242,7 +242,7 @@ class RoadMaintenanceStationController extends Controller public function images(RahdariPoint $rahdariPoint): JsonResponse { - return $this->successResponse($rahdariPoint->files()->get(['path'])); + return $this->successResponse($rahdariPoint->files()->orderBy('id')->get(['path'])); } public function map(Request $request): JsonResponse diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 33b8645a..afe8c30a 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -111,7 +111,7 @@ class SafetyAndPrivacyTableService public function provinceActivity(Request $request): array { $activities = []; - $provinceQuery = Province::query()->selectRaw('COUNT(*) as qty,info_id, step'); + $provinceQuery = SafetyAndPrivacy::query()->selectRaw('COUNT(*) as qty,info_id, step'); $province = DataTableFacade::run( $provinceQuery, $request, From 613a8f0bd815955141803abed62c8f5bcbe7354a Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 15 Apr 2025 16:08:16 +0330 Subject: [PATCH 22/48] refactor blade files --- app/Exports/V3/SafetyAndPrivacy/CountryActivityReport.php | 8 +++----- .../V3/SafetyAndPrivacy/ProvinceActivityReport.php | 6 +++--- .../SafetyAndPrivacy/CountryActivityReport.blade.php | 5 ----- .../SafetyAndPrivacy/ProvinceActivityReport.blade.php | 7 +------ 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/app/Exports/V3/SafetyAndPrivacy/CountryActivityReport.php b/app/Exports/V3/SafetyAndPrivacy/CountryActivityReport.php index b6e6ccb2..68e1b99a 100644 --- a/app/Exports/V3/SafetyAndPrivacy/CountryActivityReport.php +++ b/app/Exports/V3/SafetyAndPrivacy/CountryActivityReport.php @@ -19,13 +19,13 @@ class CountryActivityReport implements FromView, WithEvents, ShouldAutoSize, Wit public function view(): View { $data = $this->data; - $existedProvinces = array_keys($data['activities']); + $existedProvinces = array_keys($data); foreach (\App\Models\Province::all() as $value) { $provinceId = $value->id; if (!array_key_exists($provinceId, $existedProvinces)) { - $data['activities'][] = (object) [ + $data[] = (object) [ 'province_id' => $provinceId, 'name_fa' => $value->name_fa, 'sum' => 0, @@ -37,9 +37,7 @@ class CountryActivityReport implements FromView, WithEvents, ShouldAutoSize, Wit } return view('v3.Reports.SafetyAndPrivacy.CountryActivityReport', [ - 'data' => $data['activities'], - 'fromDate' => $data['fromDate'], - 'toDate' => $data['toDate'], + 'data' => $data, ]); } diff --git a/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php b/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php index 399b5bca..8e839d90 100644 --- a/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php +++ b/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php @@ -21,14 +21,14 @@ class ProvinceActivityReport implements FromView, WithEvents, ShouldAutoSize, Wi public function view(): View { $data = $this->data; - $existedCities = array_keys($data['activities']); + $existedCities = array_keys($data); $edarat = EdarateShahri::query()->where('province_id', '=', $this->request->province_id)->get(['id', 'name_fa']); foreach ($edarat as $value) { $edareId = $value->id; if (!array_key_exists($edareId, $existedCities)) { - $data['activities'][] = (object) [ + $data[] = (object) [ 'edare_shahri_id' => $edareId, 'name_fa' => $value->name_fa, 'sum' => 0, @@ -40,7 +40,7 @@ class ProvinceActivityReport implements FromView, WithEvents, ShouldAutoSize, Wi } return view('v3.Reports.SafetyAndPrivacy.ProvinceActivityReport', [ - 'data' => $data['activities'], + 'data' => $data, 'fromDate' => $data['fromDate'], 'toDate' => $data['toDate'], ]); diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php index f7c5bd53..72009c19 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php @@ -29,11 +29,6 @@ diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php index 7e156b78..b5db906f 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php @@ -27,13 +27,8 @@ From 79e6cc37aaf479c7d66d31bee26b43a92dcb0575 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 19 Apr 2025 14:19:45 +0330 Subject: [PATCH 23/48] debug the blades --- app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php | 2 -- .../v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php | 2 +- .../Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php b/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php index 8e839d90..17b1e853 100644 --- a/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php +++ b/app/Exports/V3/SafetyAndPrivacy/ProvinceActivityReport.php @@ -41,8 +41,6 @@ class ProvinceActivityReport implements FromView, WithEvents, ShouldAutoSize, Wi return view('v3.Reports.SafetyAndPrivacy.ProvinceActivityReport', [ 'data' => $data, - 'fromDate' => $data['fromDate'], - 'toDate' => $data['toDate'], ]); } diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php index 72009c19..ee8c6c6a 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/CountryActivityReport.blade.php @@ -28,7 +28,7 @@ diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php index b5db906f..df2f7638 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/ProvinceActivityReport.blade.php @@ -28,7 +28,7 @@ From 1cb4c4f15d63df0233fe2eac220562710ad66622 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 20 Apr 2025 11:21:03 +0330 Subject: [PATCH 24/48] debug road observed --- .../Dashboard/RoadObservationController.php | 40 +++++------ .../Controllers/V3/NotificationController.php | 66 ++++++++----------- app/Models/RoadObserved.php | 10 ++- 3 files changed, 50 insertions(+), 66 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/RoadObservationController.php b/app/Http/Controllers/V3/Dashboard/RoadObservationController.php index a3b97c4c..01291183 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadObservationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadObservationController.php @@ -24,6 +24,7 @@ use Hekmatinasser\Verta\Verta; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use App\Services\Cartables\RoadObservationTableService; +use Illuminate\Support\Facades\DB; use Maatwebsite\Excel\Facades\Excel; use SoapFault; use Symfony\Component\HttpFoundation\BinaryFileResponse; @@ -117,8 +118,8 @@ class RoadObservationController extends Controller $roadObserved->files()->where('path', 'like', '%_image_before%')->delete(); $roadObserved->files()->where('path', 'like', '%_image_after%')->delete(); - $image_before = FileFacade::save($request->image_before, "road_observeds/{$roadObserved->id}/"); - $image_after = FileFacade::save($request->image_after, "road_observeds/{$roadObserved->id}/"); + $image_before = FileFacade::save($request->image_before, "road_observeds/{$roadObserved->id}"); + $image_after = FileFacade::save($request->image_after, "road_observeds/{$roadObserved->id}"); $files_path[0]['path'] = $image_before; $files_path[1]['path'] = $image_after; @@ -135,20 +136,15 @@ class RoadObservationController extends Controller $roadObservedHistoryData['new_files'] = $files; } - $roadObserved->problemHistories()->create($roadObservedHistoryData); - $roadObserved->update($roadObservedData); + DB::transaction(function () use ($roadObserved, $roadObservedHistoryData, $roadObservedData, $request, $nikarayanService) { + $roadObserved->problemHistories()->create($roadObservedHistoryData); + $roadObserved->update($roadObservedData); - auth()->user()->addActivityComplete(1142); + auth()->user()->addActivityComplete(1142); - try { $nikarayanService->updateRoadObservedInfoByNikarayan($request, $roadObserved, json_encode($roadObservedHistoryData['new_files'])); - } - catch (SoapFault $e) { - $msg = "error in send to nikarayan at" . date("Y-m-d H:i:s") . "\n"; - $msg .= $e->getMessage(); - Sms::sendSms(env('RMS_CTO_PHONE_NUMBER'), $msg); - } + }); return $this->successResponse(); } @@ -182,7 +178,7 @@ class RoadObservationController extends Controller if ($roadObserved->image_before) { FileFacade::delete($roadObserved->image_before, true); } - $image_before = FileFacade::save($request->image_before, "road_observeds/{$roadObserved->id}/"); + $image_before = FileFacade::save($request->image_before, "road_observeds/{$roadObserved->id}"); $roadObservedData['image_before'] = $image_before; $files_path[0]['path'] = $image_before; } @@ -191,7 +187,7 @@ class RoadObservationController extends Controller if ($roadObserved->image_after) { FileFacade::delete($roadObserved->image_after, true); } - $image_after = FileFacade::save($request->image_after, "road_observeds/{$roadObserved->id}/"); + $image_after = FileFacade::save($request->image_after, "road_observeds/{$roadObserved->id}"); $roadObservedData['image_after'] = $image_after; $files_path[1]['path'] = $image_after; } @@ -206,20 +202,14 @@ class RoadObservationController extends Controller $roadObservedHistoryData['new_files'] = $files; } - $roadObserved->problemHistories()->create($roadObservedHistoryData); - $roadObserved->update($roadObservedData); + DB::transaction(function () use ($roadObserved, $roadObservedHistoryData, $roadObservedData, $request, $nikarayanService) { + $roadObserved->problemHistories()->create($roadObservedHistoryData); + $roadObserved->update($roadObservedData); - auth()->user()->addActivityComplete(1142); + auth()->user()->addActivityComplete(1142); - try { $nikarayanService->updateRoadObservedInfoByNikarayan($request, $roadObserved, json_encode($roadObservedHistoryData['new_files'])); - } - catch (SoapFault $e) { - - $msg = "error in send to nikarayan at" . date("Y-m-d H:i:s") . "\n"; - $msg .= $e->getMessage(); - Sms::sendSms(env('RMS_CTO_PHONE_NUMBER'), $msg); - } + }); return $this->successResponse(); } diff --git a/app/Http/Controllers/V3/NotificationController.php b/app/Http/Controllers/V3/NotificationController.php index 01d4ae63..833ba72c 100644 --- a/app/Http/Controllers/V3/NotificationController.php +++ b/app/Http/Controllers/V3/NotificationController.php @@ -144,56 +144,44 @@ class NotificationController extends Controller 'supervise_cnt' => 0 ]; - $conditions = []; - $complaintConditions = [ - ['rms_status', '=', 0], - ['edarate_shahri_id', '!=', null] - ]; - if ($user->hasPermissionTo('show-fast-react')) { - $conditions[] = ['status', '=', 2]; + $road_observations['supervise_cnt'] = RoadObserved::query()->where([ + ['rms_status', '<>', 0], + ['status', '=', 0] + ])->count(); + + $road_observations['complaint_cnt'] = RoadObserved::query()->where('rms_status', '=', 0)->count(); } elseif ($user->hasPermissionTo('show-fast-react-province')) { throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); - $conditions = [ - ['status', '=', 2], - ['rms_province_id', '=', $user->province_id] - ]; - $complaintConditions[] = ['province_id', '=', $user->province_id]; + + $road_observations['supervise_cnt'] = RoadObserved::query()->where([ + ['rms_status', '<>', 0], + ['status', '=', 0], + ['province_id', '=', $user->province_id] + ])->count(); + + $road_observations['complaint_cnt'] = RoadObserved::query()->where([ + ['rms_status', '=', 0], + ['province_id', '=', $user->province_id] + ])->count(); } elseif ($user->hasPermissionTo('show-fast-react-edarate-shahri')) { throw_if(is_null($user->edarate_shahri_id), new ProhibitedAction('اداره ای برای شما در سامانه ثبت نشده است!')); - $conditions = [ + + $road_observations['operation_cnt'] = RoadObserved::query()->where([ + ['rms_status', '<>', 0], ['status', '=', 2], ['edarate_shahri_id', '=', $user->edarate_shahri_id] - ]; - $complaintConditions[] = ['edarate_shahri_id', '=', $user->edarate_shahri_id]; + ])->count(); + + $road_observations['complaint_cnt'] = RoadObserved::query()->where([ + ['rms_status', '=', 0], + ['edarate_shahri_id', '=', $user->edarate_shahri_id] + ])->count(); } - if (!empty($conditions)) { - $road_observations['operation_cnt'] = RoadObserved::query()->where($conditions)->count(); - $road_observations['complaint_cnt'] = RoadObserved::query()->where($complaintConditions)->count(); - $road_observations['total'] += $road_observations['operation_cnt'] + $road_observations['complaint_cnt']; - } - - $superviseConditions = [ - ['status', '=', 0] - ]; - - if ($user->hasPermissionTo('supervise-fast-react')) { - $road_observations['supervise_cnt'] = RoadObserved::query()->where($superviseConditions)->count(); - $road_observations['complaint_cnt'] = RoadObserved::query()->where($complaintConditions)->count(); - $road_observations['total'] += $road_observations['supervise_cnt'] + $road_observations['complaint_cnt']; - } - elseif ($user->hasPermissionTo('supervise-fast-react-province')) { - throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); - $superviseConditions[] = ['province_id', '=', $user->province_id]; - $complaintConditions[] = ['province_id', '=', $user->province_id]; - - $road_observations['supervise_cnt'] = RoadObserved::query()->where($superviseConditions)->count(); - $road_observations['complaint_cnt'] = RoadObserved::query()->where($complaintConditions)->count(); - $road_observations['total'] += $road_observations['supervise_cnt'] + $road_observations['complaint_cnt']; - } + $road_observations['total'] += $road_observations['operation_cnt'] + $road_observations['complaint_cnt'] + $road_observations['supervise_cnt']; return $road_observations; } diff --git a/app/Models/RoadObserved.php b/app/Models/RoadObserved.php index 18c4c9af..ce30a7a2 100644 --- a/app/Models/RoadObserved.php +++ b/app/Models/RoadObserved.php @@ -108,14 +108,20 @@ class RoadObserved extends Model protected function imageAfter(): Attribute { return Attribute::make( - get: fn($value) => $value == null ? null : Storage::disk('public')->url($value) + get: fn($value) => $value == null ? null : + (filter_var($value, FILTER_VALIDATE_URL) + ? $value + : Storage::disk('public')->url($value)) ); } protected function imageBefore(): Attribute { return Attribute::make( - get: fn($value) => $value == null ? null : Storage::disk('public')->url($value) + get: fn($value) => $value == null ? null : + (filter_var($value, FILTER_VALIDATE_URL) + ? $value + : Storage::disk('public')->url($value)) ); } } From 940c5d917af88ba31a51be9df418f09bab39e8b3 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 20 Apr 2025 13:29:24 +0330 Subject: [PATCH 25/48] debug accident --- .../V3/Dashboard/AccidentReceiptController.php | 4 ++-- .../V3/Dashboard/RoadObservationController.php | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php index 5368e931..27620e3e 100644 --- a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php +++ b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php @@ -240,9 +240,9 @@ class AccidentReceiptController extends Controller DB::transaction(function () use ($request, $accident) { $accident->update([ - 'deposit_insurance_image' => $request->deposit_insurance_image != null ? FileFacade::save($request->deposit_insurance_image, "receipts_files/{$accident->id}/deposit_insurance/") : null, + 'deposit_insurance_image' => $request->has('deposit_insurance_image') ? FileFacade::save($request->deposit_insurance_image, "receipts_files/{$accident->id}/deposit_insurance") : null, 'deposit_insurance_amount' => $request->deposit_insurance_amount ?? 0, - 'deposit_daghi_image' => $request->deposit_insurance_image != null ? FileFacade::save($request->deposit_daghi_image, "receipts_files/{$accident->id}/deposit_daghi/") : null, + 'deposit_daghi_image' => $request->has('deposit_daghi_image') ? FileFacade::save($request->deposit_daghi_image, "receipts_files/{$accident->id}/deposit_daghi") : null, 'deposit_daghi_amount' => $request->deposit_daghi_amount ?? 0, 'status' => AccidentStates::SABT_FISH->value, 'status_fa' => AccidentStates::name(AccidentStates::SABT_FISH->value), diff --git a/app/Http/Controllers/V3/Dashboard/RoadObservationController.php b/app/Http/Controllers/V3/Dashboard/RoadObservationController.php index 01291183..8cdd32c7 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadObservationController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadObservationController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\V3\Dashboard; use App\Exports\V3\RoadObservation\ComplaintsReport; use App\Exports\V3\RoadObservation\OperatorCartableReport; use App\Exports\V3\RoadObservation\SupervisorCartableReport; +use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; use App\Facades\Sms\Sms; use App\Http\Controllers\Controller; @@ -295,4 +296,15 @@ class RoadObservationController extends Controller return $this->successResponse(); } + + public function map(Request $request): JsonResponse + { + return response()->json(DataTableFacade::run( + RoadObserved::query(), + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: ['id', 'lat', 'lng', 'status'] + )); + } } From 88bcf8e49ec11f32a33218bfad29769223eac988 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 20 Apr 2025 13:45:15 +0330 Subject: [PATCH 26/48] delete directory --- app/Facades/File/File.php | 5 +++++ .../Controllers/V3/Dashboard/AccidentReceiptController.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Facades/File/File.php b/app/Facades/File/File.php index 79155a8e..418f7664 100644 --- a/app/Facades/File/File.php +++ b/app/Facades/File/File.php @@ -104,4 +104,9 @@ class File fclose($file); return trim($output); } + + public function deleteDirectory(string $path, string $disk = 'public'): void + { + Storage::disk($disk)->deleteDirectory($path); + } } diff --git a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php index 27620e3e..3b314a2d 100644 --- a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php +++ b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php @@ -202,7 +202,7 @@ class AccidentReceiptController extends Controller public function destroy(Accident $accident): JsonResponse { - FileFacade::delete('storage/receipts_files/'.$accident->id); + FileFacade::deleteDirectory('receipts_files/'.$accident->id); DB::transaction(function () use ($accident) { From b677624d5d6f6ab0ecadd90e20ca819164c137cc Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 20 Apr 2025 15:54:34 +0330 Subject: [PATCH 27/48] debug excel blades --- app/Services/Cartables/RoadItemTableService.php | 2 +- app/Services/DataTable/DataTableService.php | 3 +-- .../v3/Reports/RoadItems/OperatorCartableReport.blade.php | 3 +-- .../v3/Reports/RoadItems/SupervisorCartableReport.blade.php | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/Services/Cartables/RoadItemTableService.php b/app/Services/Cartables/RoadItemTableService.php index 0b64e741..2638e5c5 100644 --- a/app/Services/Cartables/RoadItemTableService.php +++ b/app/Services/Cartables/RoadItemTableService.php @@ -53,7 +53,7 @@ class RoadItemTableService $allowedSortings = ['*']; $query = RoadItemsProject::query() - ->select(['id', 'supervisor_description', 'item', 'item_fa', 'sub_item', 'sub_item_fa', 'sub_item_data', 'unit_fa', 'start_lat', 'start_lng', + ->select(['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']) ->where('is_new', 1) ->where('user_id', auth()->user()->id) diff --git a/app/Services/DataTable/DataTableService.php b/app/Services/DataTable/DataTableService.php index 442f6e48..5755ad1d 100644 --- a/app/Services/DataTable/DataTableService.php +++ b/app/Services/DataTable/DataTableService.php @@ -80,6 +80,7 @@ class DataTableService $query = $this->applySelect($query, $this->allowedSelects); $query = $this->includeRelationsInQuery($query, $this->allowedRelations); + $query = $this->applyGroupBy($query, $this->allowedGroupBy); $this->totalRowCount = $query->count(); @@ -96,8 +97,6 @@ class DataTableService $query = (new ApplySort($query, $sort))->apply(); } - $query = $this->applyGroupBy($query, $this->allowedGroupBy); - return $query; } diff --git a/resources/views/v3/Reports/RoadItems/OperatorCartableReport.blade.php b/resources/views/v3/Reports/RoadItems/OperatorCartableReport.blade.php index 3894defd..76431163 100644 --- a/resources/views/v3/Reports/RoadItems/OperatorCartableReport.blade.php +++ b/resources/views/v3/Reports/RoadItems/OperatorCartableReport.blade.php @@ -97,7 +97,7 @@ - +
تاریخ دریافت گزارش: {{ verta()->now()->format('Y/m/d H:i') }}
گزارش فعالیت های نگهداری حریم راه - تاریخ ثبت اقدام + تاریخ اقدام @@ -97,7 +97,7 @@ - {{ $item['action_picture_document_upload_date'] ? verta($item['action_picture_document_upload_date'])->format('Y/n/j H:i:s') : '-' }} + {{ $item['action_picture_document_upload_date'] ? verta($item['action_date'])->format('Y/n/j H:i:s') : '-' }} {{ $item['step_fa'] ?? '-' }} گزارش نگهداری حریم راه از تاریخ - {{ verta($fromDate)->format('Y/n/j') }} - تا - تاریخ - {{ verta($toDate)->format('Y/n/j') }} -
+ style="background-color: #DAEEF3;text-align: center;border-right:1px solid black;font-weight:bolder;font-size: 13px;"> گزارش نگهداری حریم راه از تاریخ - {{ verta($fromDate)->format('Y/n/j') }} - تا - تاریخ - {{ verta($toDate)->format('Y/n/j') }} -
- گزارش نگهداری حریم راه از تاریخ + گزارش نگهداری حریم راه
- گزارش نگهداری حریم راه از تاریخ + گزارش نگهداری حریم راه
{{ $item['sub_item_data'] ? ($item['unit_fa'] ? $item['sub_item_data'] . '(' . $item['unit_fa'] . ')' : $item['sub_item_data'] . '(-)') : '-' }} {{ $item['cmms_machines'] != null ? $item['cmms_machines']->pluck('machine_code')->implode(', ') : '-' }}{{ $item['cmmsMachines'] != null ? $item['cmmsMachines']->pluck('machine_code')->implode(', ') : '-' }} {{ $item['rahdaran'] != null ? $item['rahdaran']->pluck('code')->implode(', ') : '-' }} {{ isset($item['start_lat']) && isset($item['start_lng']) ? $item['start_lat'] . ' ' . $item['start_lng'] : '-' }} @@ -114,5 +114,4 @@
- diff --git a/resources/views/v3/Reports/RoadItems/SupervisorCartableReport.blade.php b/resources/views/v3/Reports/RoadItems/SupervisorCartableReport.blade.php index 6203dbbc..d7bb9a9f 100644 --- a/resources/views/v3/Reports/RoadItems/SupervisorCartableReport.blade.php +++ b/resources/views/v3/Reports/RoadItems/SupervisorCartableReport.blade.php @@ -97,7 +97,7 @@ {{ $item['sub_item_data'] ? ($item['unit_fa'] ? $item['sub_item_data'] . '(' . $item['unit_fa'] . ')' : $item['sub_item_data'] . '(-)') : '-' }} - {{ $item['cmms_machines'] != null ? $item['cmms_machines']->pluck('machine_code')->implode(', ') : '-' }} + {{ $item['cmmsMachines'] != null ? $item['cmmsMachines']->pluck('machine_code')->implode(', ') : '-' }} {{ $item['rahdaran'] != null ? $item['rahdaran']->pluck('code')->implode(', ') : '-' }} {{ isset($item['start_lat']) && isset($item['start_lng']) ? $item['start_lat'] . ' ' . $item['start_lng'] : '-' }} From bb4904a38f0b0f9c0d63dff3814f06b2ae73701b Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 20 Apr 2025 16:32:11 +0330 Subject: [PATCH 28/48] edit excels --- .../v3/Reports/RoadPatrols/OperatorCartableReport.blade.php | 2 +- .../v3/Reports/RoadPatrols/SupervisorCartableReport.blade.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/views/v3/Reports/RoadPatrols/OperatorCartableReport.blade.php b/resources/views/v3/Reports/RoadPatrols/OperatorCartableReport.blade.php index c90cb1da..92e1f1d6 100644 --- a/resources/views/v3/Reports/RoadPatrols/OperatorCartableReport.blade.php +++ b/resources/views/v3/Reports/RoadPatrols/OperatorCartableReport.blade.php @@ -74,7 +74,7 @@ {{ $item['id'] ?? '-' }} {{ $item['province_fa'] ?? '-' }} {{ $item['edare_name'] ?? '-' }} - {{ $item['cmms_machines'] != null ? $item['cmms_machines']->pluck('machine_code')->implode(', ') : '-' }} + {{ $item['cmmsMachines'] != null ? $item['cmmsMachines']->pluck('machine_code')->implode(', ') : '-' }} {{ $item['rahdaran'] != null ? $item['rahdaran']->pluck('code')->implode(', ') : '-' }} {{ $item['start_time'] ? verta($item['start_time'])->format('Y/n/j H:i:s') : '-' }} {{ $item['end_time'] ? verta($item['end_time'])->format('Y/n/j H:i:s') : '-' }} diff --git a/resources/views/v3/Reports/RoadPatrols/SupervisorCartableReport.blade.php b/resources/views/v3/Reports/RoadPatrols/SupervisorCartableReport.blade.php index 0fb2a3d1..af572a66 100644 --- a/resources/views/v3/Reports/RoadPatrols/SupervisorCartableReport.blade.php +++ b/resources/views/v3/Reports/RoadPatrols/SupervisorCartableReport.blade.php @@ -33,7 +33,7 @@ + style="background-color: #DAEEF3;text-align: center;border-right:1px solid black;font-weight:bolder;font-size: 13px;"> گزارش کارتابل ارزیابی گشت راهداری @@ -74,7 +74,7 @@ {{ $item['id'] ?? '-' }} {{ $item['province_fa'] ?? '-' }} {{ $item['edare_name'] ?? '-' }} - {{ $item['cmms_machines'] != null ? $item['cmms_machines']->pluck('machine_code')->implode(', ') : '-' }} + {{ $item['cmmsMachines'] != null ? $item['cmmsMachines']->pluck('machine_code')->implode(', ') : '-' }} {{ $item['rahdaran'] != null ? $item['rahdaran']->pluck('code')->implode(', ') : '-' }} {{ $item['start_time'] ? verta($item['start_time'])->format('Y/n/j H:i:s') : '-' }} {{ $item['end_time'] ? verta($item['end_time'])->format('Y/n/j H:i:s') : '-' }} From aef3bfdd9465a21a37ff0b63bedfadb61c576c64 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Tue, 22 Apr 2025 13:45:04 +0330 Subject: [PATCH 29/48] create new middlware and add in route and kernel --- .../Dashboard/SafetyAndPrivacyController.php | 24 -------------- app/Http/Kernel.php | 1 + app/Http/Middleware/ValidateStoreAccess.php | 32 +++++++++++++++++++ routes/v3.php | 8 +++-- 4 files changed, 38 insertions(+), 27 deletions(-) create mode 100644 app/Http/Middleware/ValidateStoreAccess.php diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 693a1864..ce39c5e3 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -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) @@ -104,14 +96,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 = []; @@ -135,14 +119,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) { $safetyAndPrivacy->update([ 'step' => 3, 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/routes/v3.php b/routes/v3.php index a71859a2..5d58b5b5 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -339,11 +339,13 @@ Route::prefix('safety_and_privacy') ->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('/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'); From d6d9009649533fb3344b0c49c59e2760c4d641da Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 22 Apr 2025 13:48:04 +0330 Subject: [PATCH 30/48] create supervisor cartable --- app/Enums/SafetyAndPrivacyStatus.php | 19 ++++++++++++ app/Models/SafetyAndPrivacy.php | 5 +++- .../SafetyAndPrivacyTableService.php | 26 +++++++++++++++- ...add_column_to_safety_and_privacy_table.php | 30 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 app/Enums/SafetyAndPrivacyStatus.php create mode 100644 database/migrations/2025_04_22_100327_add_column_to_safety_and_privacy_table.php diff --git a/app/Enums/SafetyAndPrivacyStatus.php b/app/Enums/SafetyAndPrivacyStatus.php new file mode 100644 index 00000000..4e7c164d --- /dev/null +++ b/app/Enums/SafetyAndPrivacyStatus.php @@ -0,0 +1,19 @@ + 'تایید', + 2 => 'عدم تایید', + ]; + + return $mapArray[$state]; + } +} \ No newline at end of file diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index ac347063..77a64138 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -36,7 +36,10 @@ class SafetyAndPrivacy extends Model 'action_picture_document_upload_date', 'axis_type_id', 'axis_type_name', - 'action_date' + 'action_date', + 'status', + 'final_description', + 'is_finished' ]; 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..1a63dd23 --- /dev/null +++ b/database/migrations/2025_04_22_100327_add_column_to_safety_and_privacy_table.php @@ -0,0 +1,30 @@ +boolean('is_finished')->nullable(); + $table->integer('status')->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']); + }); + } +}; From 05060078a193ac3736da8870636e67aa0f8f480f Mon Sep 17 00:00:00 2001 From: joddyabott Date: Tue, 22 Apr 2025 14:33:03 +0330 Subject: [PATCH 31/48] create enum for safety and privacy steps --- app/Enums/SafetyAndPrivacySteps.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 app/Enums/SafetyAndPrivacySteps.php diff --git a/app/Enums/SafetyAndPrivacySteps.php b/app/Enums/SafetyAndPrivacySteps.php new file mode 100644 index 00000000..5589bdcf --- /dev/null +++ b/app/Enums/SafetyAndPrivacySteps.php @@ -0,0 +1,23 @@ + 'گام اول (شناسایی)', + 2 => 'گام دوم (مستندات قضایی)', + 3 => 'گام سوم (برخورد)', + ]; + + return $mapArray[$state]; + } +} \ No newline at end of file From ef373a9f5b8c70609aa3f34c6411fcc05e7e8a2a Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 22 Apr 2025 14:36:43 +0330 Subject: [PATCH 32/48] add confirm and reject api --- .../Dashboard/SafetyAndPrivacyController.php | 47 ++++++++++++++++--- app/Models/SafetyAndPrivacy.php | 3 +- ...add_column_to_safety_and_privacy_table.php | 3 +- routes/v3.php | 2 +- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index ce39c5e3..d5d6aa2a 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\V3\Dashboard; use App\Enums\AxisTypes; +use App\Enums\SafetyAndPrivacyStatus; use App\Exports\V3\SafetyAndPrivacy\CartableReport; use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; @@ -18,10 +19,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 +32,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 +43,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); } @@ -78,7 +77,8 @@ class SafetyAndPrivacyController extends Controller 'axis_type_id' => $request->axis_type_id, 'axis_type_name' => AxisTypes::name($request->axis_type_id), 'step' => 1, - 'step_fa' => 'گام اول (شناسایی)' + 'step_fa' => 'گام اول (شناسایی)', + 'is_finished' => false ]); $safety_and_privacy->recognize_picture = $request->has('recognize_picture') ? @@ -197,4 +197,39 @@ 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 + ]); + + return $this->successResponse(); + } + + public function supervisorIndex(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse + { + return response()->json($safetyAndPrivacyTableService->supervisorDataTable($request)); + } } diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index 77a64138..d1c6cc3f 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -39,7 +39,8 @@ class SafetyAndPrivacy extends Model 'action_date', 'status', 'final_description', - 'is_finished' + 'is_finished', + 'supervisor_description' ]; public $table = "safety_and_privacy"; 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 index 1a63dd23..49d997a7 100644 --- 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 @@ -14,6 +14,7 @@ return new class extends Migration Schema::table('safety_and_privacy', function (Blueprint $table) { $table->boolean('is_finished')->nullable(); $table->integer('status')->nullable(); + $table->string('supervisor_description')->nullable(); $table->string('final_description')->nullable(); }); } @@ -24,7 +25,7 @@ return new class extends Migration public function down(): void { Schema::table('safety_and_privacy', function (Blueprint $table) { - $table->dropColumn(['status', 'final_description', 'is_finished']); + $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description']); }); } }; diff --git a/routes/v3.php b/routes/v3.php index 5d58b5b5..d0924334 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -337,7 +337,7 @@ 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(['validate-store-access', 'permission:add-safety-and-privacy']); From 16c143fa4cc3fdb55cbd493aaa6ad7e142f3e7f8 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 22 Apr 2025 14:58:02 +0330 Subject: [PATCH 33/48] use enum for saving --- app/Enums/SafetyAndPrivacySteps.php | 6 ++---- .../V3/Dashboard/SafetyAndPrivacyController.php | 15 ++++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/Enums/SafetyAndPrivacySteps.php b/app/Enums/SafetyAndPrivacySteps.php index 5589bdcf..b0e30776 100644 --- a/app/Enums/SafetyAndPrivacySteps.php +++ b/app/Enums/SafetyAndPrivacySteps.php @@ -8,9 +8,7 @@ enum SafetyAndPrivacySteps: int case MOSTANADAT_GAZAEI = 2; case BARKHORD = 3; - - - public static function name(int $state): string + public static function name(int $step): string { $mapArray = [ 1 => 'گام اول (شناسایی)', @@ -18,6 +16,6 @@ enum SafetyAndPrivacySteps: int 3 => 'گام سوم (برخورد)', ]; - return $mapArray[$state]; + 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 d5d6aa2a..2f5ddfa5 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -4,6 +4,7 @@ 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; @@ -76,8 +77,8 @@ 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 ]); @@ -105,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); @@ -121,8 +122,8 @@ class SafetyAndPrivacyController extends Controller 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, @@ -155,7 +156,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) { From 8513ebd72822fb445c306dbeca11d94881de250c Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 09:06:50 +0330 Subject: [PATCH 34/48] add pending to status --- app/Enums/SafetyAndPrivacyStatus.php | 2 ++ .../Controllers/V3/Dashboard/SafetyAndPrivacyController.php | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Enums/SafetyAndPrivacyStatus.php b/app/Enums/SafetyAndPrivacyStatus.php index 4e7c164d..34358e24 100644 --- a/app/Enums/SafetyAndPrivacyStatus.php +++ b/app/Enums/SafetyAndPrivacyStatus.php @@ -6,12 +6,14 @@ enum SafetyAndPrivacyStatus: int { case CONFIRM = 1; case REJECT = 2; + case PENDING = 3; public static function name(int $state): string { $mapArray = [ 1 => 'تایید', 2 => 'عدم تایید', + 3 => 'در حال بررسی' ]; return $mapArray[$state]; diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 2f5ddfa5..3124cce8 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -127,6 +127,7 @@ class SafetyAndPrivacyController extends Controller '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); @@ -223,7 +224,8 @@ class SafetyAndPrivacyController extends Controller { $safetyAndPrivacy->update([ 'is_finished' => $request->is_finished, - 'final_description' => $request->final_description + 'final_description' => $request->final_description, + 'status' => SafetyAndPrivacyStatus::PENDING->value, ]); return $this->successResponse(); From 1227814dea34324226b6d8490785dcfc9c3b35dd Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 09:53:09 +0330 Subject: [PATCH 35/48] change query columns --- app/Enums/SafetyAndPrivacyStatus.php | 4 ++-- .../V3/Dashboard/SafetyAndPrivacyController.php | 13 +++++++++++-- ...00327_add_column_to_safety_and_privacy_table.php | 3 ++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/Enums/SafetyAndPrivacyStatus.php b/app/Enums/SafetyAndPrivacyStatus.php index 34358e24..78168c2a 100644 --- a/app/Enums/SafetyAndPrivacyStatus.php +++ b/app/Enums/SafetyAndPrivacyStatus.php @@ -4,16 +4,16 @@ namespace App\Enums; enum SafetyAndPrivacyStatus: int { + case PENDING = 0; case CONFIRM = 1; case REJECT = 2; - case PENDING = 3; public static function name(int $state): string { $mapArray = [ + 0 => 'در حال بررسی', 1 => 'تایید', 2 => 'عدم تایید', - 3 => 'در حال بررسی' ]; return $mapArray[$state]; diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 3124cce8..afb45a7d 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -202,8 +202,11 @@ class SafetyAndPrivacyController extends Controller public function confirm(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { + $status_id = SafetyAndPrivacyStatus::CONFIRM->value; + $safetyAndPrivacy->update([ 'status' => SafetyAndPrivacyStatus::CONFIRM->value, + 'status_fa' => SafetyAndPrivacyStatus::name($status_id), 'supervisor_description' => $request->supervisor_description ]); @@ -212,8 +215,11 @@ class SafetyAndPrivacyController extends Controller public function reject(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { + $status_id = SafetyAndPrivacyStatus::REJECT->value; + $safetyAndPrivacy->update([ - 'status' => SafetyAndPrivacyStatus::REJECT->value, + 'status' => $status_id, + 'status_fa' => SafetyAndPrivacyStatus::name($status_id), 'supervisor_description' => $request->supervisor_description ]); @@ -222,10 +228,13 @@ class SafetyAndPrivacyController extends Controller public function finish(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { + $status_id = SafetyAndPrivacyStatus::PENDING->value; + $safetyAndPrivacy->update([ - 'is_finished' => $request->is_finished, + 'is_finished' => 1, 'final_description' => $request->final_description, 'status' => SafetyAndPrivacyStatus::PENDING->value, + 'status_fa' => SafetyAndPrivacyStatus::name($status_id), ]); return $this->successResponse(); 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 index 49d997a7..d63218ce 100644 --- 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 @@ -14,6 +14,7 @@ return new class extends Migration Schema::table('safety_and_privacy', function (Blueprint $table) { $table->boolean('is_finished')->nullable(); $table->integer('status')->nullable(); + $table->string('status_fa')->nullable(); $table->string('supervisor_description')->nullable(); $table->string('final_description')->nullable(); }); @@ -25,7 +26,7 @@ return new class extends Migration public function down(): void { Schema::table('safety_and_privacy', function (Blueprint $table) { - $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description']); + $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description', 'status_fa']); }); } }; From 99ce5133b0a462f762c5e11a0da040b1a0f5aede Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 10:17:07 +0330 Subject: [PATCH 36/48] create form request for supervisor --- .../Dashboard/SafetyAndPrivacyController.php | 23 +++++++++------ .../V3/SafetyAndPrivacy/FinishRequest.php | 28 +++++++++++++++++++ .../V3/SafetyAndPrivacy/RejectRequest.php | 28 +++++++++++++++++++ .../SafetyAndPrivacyTableService.php | 8 +++--- routes/v3.php | 2 +- 5 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 app/Http/Requests/V3/SafetyAndPrivacy/FinishRequest.php create mode 100644 app/Http/Requests/V3/SafetyAndPrivacy/RejectRequest.php diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index afb45a7d..c89b5842 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -9,6 +9,8 @@ use App\Exports\V3\SafetyAndPrivacy\CartableReport; use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; use App\Http\Controllers\Controller; +use App\Http\Requests\V3\SafetyAndPrivacy\FinishRequest; +use App\Http\Requests\V3\SafetyAndPrivacy\RejectRequest; use App\Http\Requests\V3\SafetyAndPrivacy\FirstStepStoreRequest; use App\Http\Requests\V3\SafetyAndPrivacy\SecondStepStoreRequest; use App\Http\Requests\V3\SafetyAndPrivacy\ThirdStepStoreRequest; @@ -60,6 +62,7 @@ class SafetyAndPrivacyController extends Controller DB::transaction(function () use ($request, $coordinates, $item, $nominatimService, $user) { + $step = SafetyAndPrivacySteps::SHENASAEI->value; $safety_and_privacy = SafetyAndPrivacy::query()->create([ 'lat' => $coordinates[0], 'lon' => $coordinates[1], @@ -77,9 +80,10 @@ 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' => SafetyAndPrivacySteps::SHENASAEI->value, - 'step_fa' => SafetyAndPrivacySteps::name(1), - 'is_finished' => false + 'step' => $step, + 'step_fa' => SafetyAndPrivacySteps::name($step), + 'is_finished' => false, + 'final_description' => 'پیام سیستمی : این عملیات پس از طی تمامی گام ها خاتمه یافت' ]); $safety_and_privacy->recognize_picture = $request->has('recognize_picture') ? @@ -103,11 +107,12 @@ class SafetyAndPrivacyController extends Controller foreach ($request->judiciary_document as $index => $file) { $judiciary_document[] = FileFacade::save($file, "safety_and_privacy/{$safetyAndPrivacy->id}/judiciary_document"); } + $step = SafetyAndPrivacySteps::MOSTANADAT_GAZAEI->value; $safetyAndPrivacy->update([ 'judiciary_document' => serialize($judiciary_document), 'judiciary_document_upload_date' => now(), 'step' => SafetyAndPrivacySteps::MOSTANADAT_GAZAEI->value, - 'step_fa' => SafetyAndPrivacySteps::name(2), + 'step_fa' => SafetyAndPrivacySteps::name($step), ]); $user->addActivityComplete(1135); @@ -121,9 +126,10 @@ class SafetyAndPrivacyController extends Controller $user = auth()->user(); DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { + $step = SafetyAndPrivacySteps::BARKHORD->value; $safetyAndPrivacy->update([ 'step' => SafetyAndPrivacySteps::BARKHORD->value, - 'step_fa' => SafetyAndPrivacySteps::name(3), + 'step_fa' => SafetyAndPrivacySteps::name($step), '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, @@ -200,20 +206,19 @@ class SafetyAndPrivacyController extends Controller )); } - public function confirm(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + public function confirm(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { $status_id = SafetyAndPrivacyStatus::CONFIRM->value; $safetyAndPrivacy->update([ 'status' => SafetyAndPrivacyStatus::CONFIRM->value, 'status_fa' => SafetyAndPrivacyStatus::name($status_id), - 'supervisor_description' => $request->supervisor_description ]); return $this->successResponse(); } - public function reject(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + public function reject(RejectRequest $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { $status_id = SafetyAndPrivacyStatus::REJECT->value; @@ -226,7 +231,7 @@ class SafetyAndPrivacyController extends Controller return $this->successResponse(); } - public function finish(Request $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + public function finish(FinishRequest $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse { $status_id = SafetyAndPrivacyStatus::PENDING->value; diff --git a/app/Http/Requests/V3/SafetyAndPrivacy/FinishRequest.php b/app/Http/Requests/V3/SafetyAndPrivacy/FinishRequest.php new file mode 100644 index 00000000..a8cb30bc --- /dev/null +++ b/app/Http/Requests/V3/SafetyAndPrivacy/FinishRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + 'final_description' => 'required|string', + ]; + } +} diff --git a/app/Http/Requests/V3/SafetyAndPrivacy/RejectRequest.php b/app/Http/Requests/V3/SafetyAndPrivacy/RejectRequest.php new file mode 100644 index 00000000..7ddc7700 --- /dev/null +++ b/app/Http/Requests/V3/SafetyAndPrivacy/RejectRequest.php @@ -0,0 +1,28 @@ +|string> + */ + public function rules(): array + { + return [ + 'supervisor_description' => 'required|string', + ]; + } +} diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 8aca0a54..40f70cc4 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -22,10 +22,10 @@ class SafetyAndPrivacyTableService { $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' + $fields = ['id','lat','lon', 'province_fa', 'edare_shahri_name', + 'recognize_picture','action_picture','created_at','step', 'final_description', + 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', + 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description' ]; if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable')) { diff --git a/routes/v3.php b/routes/v3.php index d0924334..55ab1d3f 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -337,7 +337,7 @@ Route::prefix('safety_and_privacy') ->name('SafetyAndPrivacy.') ->controller(SafetyAndPrivacyController::class) ->group(function () { - 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('/operator_index', '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(['validate-store-access', 'permission:add-safety-and-privacy']); From c29738f96c2234141489774a06f91554c136b29a Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 10:34:05 +0330 Subject: [PATCH 37/48] create report for supervisor --- ...eReport.php => OperatorCartableReport.php} | 4 +- .../SupervisorCartableReport.php | 69 +++++++++++ .../Dashboard/SafetyAndPrivacyController.php | 18 ++- ...e.php => OperatorCartableReport.blade.php} | 0 .../SupervisorCartableReport.blade.php | 109 ++++++++++++++++++ routes/v3.php | 11 +- 6 files changed, 202 insertions(+), 9 deletions(-) rename app/Exports/V3/SafetyAndPrivacy/{CartableReport.php => OperatorCartableReport.php} (91%) create mode 100644 app/Exports/V3/SafetyAndPrivacy/SupervisorCartableReport.php rename resources/views/v3/Reports/SafetyAndPrivacy/{CartableReport.blade.php => OperatorCartableReport.blade.php} (100%) create mode 100644 resources/views/v3/Reports/SafetyAndPrivacy/SupervisorCartableReport.blade.php diff --git a/app/Exports/V3/SafetyAndPrivacy/CartableReport.php b/app/Exports/V3/SafetyAndPrivacy/OperatorCartableReport.php similarity index 91% rename from app/Exports/V3/SafetyAndPrivacy/CartableReport.php rename to app/Exports/V3/SafetyAndPrivacy/OperatorCartableReport.php index 6c066aa1..81137eea 100644 --- a/app/Exports/V3/SafetyAndPrivacy/CartableReport.php +++ b/app/Exports/V3/SafetyAndPrivacy/OperatorCartableReport.php @@ -12,13 +12,13 @@ use Maatwebsite\Excel\Events\AfterSheet; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; -class CartableReport implements FromView, WithEvents, ShouldAutoSize, WithDrawings +class OperatorCartableReport implements FromView, WithEvents, ShouldAutoSize, WithDrawings { public function __construct(private ?Collection $data){} public function view(): View { - return view('v3.Reports.SafetyAndPrivacy.CartableReport', [ + return view('v3.Reports.SafetyAndPrivacy.OperatorCartableReport', [ 'data' => $this->data, ]); } diff --git a/app/Exports/V3/SafetyAndPrivacy/SupervisorCartableReport.php b/app/Exports/V3/SafetyAndPrivacy/SupervisorCartableReport.php new file mode 100644 index 00000000..cf712aaf --- /dev/null +++ b/app/Exports/V3/SafetyAndPrivacy/SupervisorCartableReport.php @@ -0,0 +1,69 @@ + $this->data, + ]); + } + + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + }, + ]; + } + + public function drawings(): array + { + $drawing = new Drawing(); + $drawing->setName('Logo'); + $drawing->setDescription('This is my logo'); + $drawing->setPath(public_path('/dist/logo.png')); + $drawing->setWidth(50); + $drawing->setHeight(50); + $drawing->setOffsetX(5); + $drawing->setOffsetY(5); + $drawing->setCoordinates('A1'); + + $drawing2 = new Drawing(); + $drawing2->setName('Logo'); + $drawing2->setDescription('This is my logo'); + $drawing2->setPath(public_path('/dist/141icon.png')); + $drawing2->setWidth(50); + $drawing2->setHeight(50); + $drawing2->setOffsetX(5); + $drawing2->setOffsetY(5); + $drawing2->setCoordinates('B1'); + return [$drawing, $drawing2]; + } + + public function styles(Worksheet $sheet): array + { + return [ + 'A:BA' => [ + 'font' => [ + 'name' => 'B Nazanin' + ] + ], + ]; + } +} \ 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 c89b5842..89d9324c 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -5,7 +5,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\Exports\V3\SafetyAndPrivacy\OperatorCartableReport; +use App\Exports\V3\SafetyAndPrivacy\SupervisorCartableReport; use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; use App\Http\Controllers\Controller; @@ -43,11 +44,11 @@ class SafetyAndPrivacyController extends Controller /** * @throws Throwable */ - public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + public function operatorExcelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse { $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; $data = $safetyAndPrivacyTableService->operatorDatatable($request); - return Excel::download(new CartableReport($data['data']), $name); + return Excel::download(new OperatorCartableReport($data['data']), $name); } public function firstStepStore(FirstStepStoreRequest $request, NominatimService $nominatimService): JsonResponse @@ -111,7 +112,7 @@ class SafetyAndPrivacyController extends Controller $safetyAndPrivacy->update([ 'judiciary_document' => serialize($judiciary_document), 'judiciary_document_upload_date' => now(), - 'step' => SafetyAndPrivacySteps::MOSTANADAT_GAZAEI->value, + 'step' => $step, 'step_fa' => SafetyAndPrivacySteps::name($step), ]); @@ -128,7 +129,7 @@ class SafetyAndPrivacyController extends Controller DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { $step = SafetyAndPrivacySteps::BARKHORD->value; $safetyAndPrivacy->update([ - 'step' => SafetyAndPrivacySteps::BARKHORD->value, + 'step' => $step, 'step_fa' => SafetyAndPrivacySteps::name($step), 'action_picture' => FileFacade::save($request->action_picture, "safety_and_privacy/{$safetyAndPrivacy->id}/action_picture"), 'action_picture_document_upload_date' => now(), @@ -249,4 +250,11 @@ class SafetyAndPrivacyController extends Controller { return response()->json($safetyAndPrivacyTableService->supervisorDataTable($request)); } + + public function supervisorExcelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + $data = $safetyAndPrivacyTableService->supervisorDataTable($request); + return Excel::download(new SupervisorCartableReport($data['data']), $name); + } } diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/OperatorCartableReport.blade.php similarity index 100% rename from resources/views/v3/Reports/SafetyAndPrivacy/CartableReport.blade.php rename to resources/views/v3/Reports/SafetyAndPrivacy/OperatorCartableReport.blade.php diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/SupervisorCartableReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/SupervisorCartableReport.blade.php new file mode 100644 index 00000000..c1065678 --- /dev/null +++ b/resources/views/v3/Reports/SafetyAndPrivacy/SupervisorCartableReport.blade.php @@ -0,0 +1,109 @@ + + + + + + + + فعالیت های نگهداری حریم راه + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($data as $item) + + + + + + + + + + + + + + + + @endforeach + +
+ تاریخ دریافت گزارش: {{ verta()->now()->format('Y/m/d H:i') }} +
+
+ گزارش فعالیت های نگهداری حریم راه +
+ کد یکتا + + استان + + اداره + + مورد مشاهده شده + + نوع محور + + تاریخ ثبت + + تاریخ بازدید + + تاریخ بارگذاری مستندات قضایی + + تاریخ اقدام + + وضعیت +
{{ $item['id'] ?? '-' }}{{ $item['province_fa'] ?? '-' }}{{ $item['edare_shahri_name'] ?? '-' }}{{ $item['info_fa'] ?? '-' }}{{ $item['axis_type_name'] ?? '-' }}{{ $item['created_at'] ? verta($item['created_at'])->format('Y/n/j H:i:s') : '-' }}{{ $item['activity_date_time'] ? verta($item['activity_date_time'])->format('Y/n/j H:i:s') : '-' }} + {{ $item['judiciary_document_upload_date'] && $item['judiciary_document_upload_date'] != '0000-00-00 00:00:00' ? verta($item['judiciary_document_upload_date'])->format('Y/n/j H:i:s') : '-' }} + + {{ $item['action_picture_document_upload_date'] ? verta($item['action_date'])->format('Y/n/j H:i:s') : '-' }} + {{ $item['step_fa'] ?? '-' }}
+ + diff --git a/routes/v3.php b/routes/v3.php index 55ab1d3f..9bb08728 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -337,8 +337,12 @@ Route::prefix('safety_and_privacy') ->name('SafetyAndPrivacy.') ->controller(SafetyAndPrivacyController::class) ->group(function () { - Route::get('/operator_index', '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::get('/operator_index', '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('/supervisor_index', 'supervisorIndex')->name('supervisorIndex') + ->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('/operator_excel_report', 'operatorExcelReport')->name('operatorExcelReport') + ->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(['validate-store-access', 'permission:add-safety-and-privacy']); @@ -350,6 +354,9 @@ Route::prefix('safety_and_privacy') Route::get('/{safetyAndPrivacy}', 'show')->name('show'); Route::delete('/{safetyAndPrivacy}', 'destroy')->name('destroy')->middleware('permission:delete-safety-and-privacy'); Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); + Route::post('/confirm/{safetyAndPrivacy}', 'confirm')->name('confirm'); + Route::post('/reject/{safetyAndPrivacy}', 'reject')->name('reject'); + Route::post('/finish/{safetyAndPrivacy}', 'finish')->name('finish'); }); Route::prefix('safety_and_privacy_report') From 717b268f76c8c684a715dc8373902436244f3939 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 11:45:01 +0330 Subject: [PATCH 38/48] add permission --- .../V3/Dashboard/SafetyAndPrivacyController.php | 4 ++-- .../Cartables/SafetyAndPrivacyTableService.php | 4 ++-- .../SafetyAndPrivacy/OperatorCartableReport.blade.php | 10 ---------- routes/v3.php | 11 ++++++----- 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 89d9324c..06f215fd 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -212,7 +212,7 @@ class SafetyAndPrivacyController extends Controller $status_id = SafetyAndPrivacyStatus::CONFIRM->value; $safetyAndPrivacy->update([ - 'status' => SafetyAndPrivacyStatus::CONFIRM->value, + 'status' => $status_id, 'status_fa' => SafetyAndPrivacyStatus::name($status_id), ]); @@ -239,7 +239,7 @@ class SafetyAndPrivacyController extends Controller $safetyAndPrivacy->update([ 'is_finished' => 1, 'final_description' => $request->final_description, - 'status' => SafetyAndPrivacyStatus::PENDING->value, + 'status' => $status_id, 'status_fa' => SafetyAndPrivacyStatus::name($status_id), ]); diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 40f70cc4..4e651ef4 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -22,8 +22,8 @@ class SafetyAndPrivacyTableService { $user = auth()->user(); - $fields = ['id','lat','lon', 'province_fa', 'edare_shahri_name', - 'recognize_picture','action_picture','created_at','step', 'final_description', + $fields = [ + 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description' ]; diff --git a/resources/views/v3/Reports/SafetyAndPrivacy/OperatorCartableReport.blade.php b/resources/views/v3/Reports/SafetyAndPrivacy/OperatorCartableReport.blade.php index c1065678..043a3f4d 100644 --- a/resources/views/v3/Reports/SafetyAndPrivacy/OperatorCartableReport.blade.php +++ b/resources/views/v3/Reports/SafetyAndPrivacy/OperatorCartableReport.blade.php @@ -42,14 +42,6 @@ style="text-align: center;border: 1px solid black;background-color: #EBF1DE;font-weight: bold;"> کد یکتا - - استان - - - اداره - مورد مشاهده شده @@ -85,8 +77,6 @@ @foreach ($data as $item) {{ $item['id'] ?? '-' }} - {{ $item['province_fa'] ?? '-' }} - {{ $item['edare_shahri_name'] ?? '-' }} {{ $item['info_fa'] ?? '-' }} {{ $item['axis_type_name'] ?? '-' }} {{ $item['created_at'] ? verta($item['created_at'])->format('Y/n/j H:i:s') : '-' }} diff --git a/routes/v3.php b/routes/v3.php index 9bb08728..7d6b2e8f 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -338,14 +338,15 @@ Route::prefix('safety_and_privacy') ->controller(SafetyAndPrivacyController::class) ->group(function () { Route::get('/operator_index', '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'); + ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); Route::get('/supervisor_index', 'supervisorIndex')->name('supervisorIndex') - ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province|show-safety-and-privacy-operator-cartable-edarate-shahri'); + ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province'); Route::get('/operator_excel_report', 'operatorExcelReport')->name('operatorExcelReport') - ->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(['validate-store-access', 'permission:add-safety-and-privacy']); + ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); + Route::get('/supervisor_excel_report', 'supervisorExcelReport')->name('supervisorExcelReport') + ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province'); + 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(['validate-store-access','permission:add-safety-and-privacy']); From 65eea49aa49d1e1bc46f0188f38e451b1e4b03de Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 12:00:01 +0330 Subject: [PATCH 39/48] debug mass assignment --- .../Controllers/V3/Dashboard/SafetyAndPrivacyController.php | 4 ++-- app/Models/SafetyAndPrivacy.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 06f215fd..36d41115 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -84,7 +84,6 @@ class SafetyAndPrivacyController extends Controller 'step' => $step, 'step_fa' => SafetyAndPrivacySteps::name($step), 'is_finished' => false, - 'final_description' => 'پیام سیستمی : این عملیات پس از طی تمامی گام ها خاتمه یافت' ]); $safety_and_privacy->recognize_picture = $request->has('recognize_picture') ? @@ -134,7 +133,8 @@ class SafetyAndPrivacyController extends Controller '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 + 'is_finished' => true, + 'final_description' => 'پیام سیستمی : این عملیات پس از طی تمامی گام ها خاتمه یافت' ]); $user->addActivityComplete(1136); diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index d1c6cc3f..78660895 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -40,7 +40,8 @@ class SafetyAndPrivacy extends Model 'status', 'final_description', 'is_finished', - 'supervisor_description' + 'supervisor_description', + 'status_fa' ]; public $table = "safety_and_privacy"; From 89f39a1f337c8a3e5168b1b115b976c6689cfc4a Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 23 Apr 2025 13:22:38 +0330 Subject: [PATCH 40/48] update fillable fields --- app/Models/SafetyAndPrivacy.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index 78660895..55e0a239 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -41,7 +41,8 @@ class SafetyAndPrivacy extends Model 'final_description', 'is_finished', 'supervisor_description', - 'status_fa' + 'status_fa', + 'need_judiciary' ]; public $table = "safety_and_privacy"; From 5e4f6379ffea432f53d1eb8b10c5baebef62b92e Mon Sep 17 00:00:00 2001 From: joddyabott Date: Wed, 23 Apr 2025 14:01:03 +0330 Subject: [PATCH 41/48] chenge two table and improve safetyand privacy controller and request --- .../Dashboard/SafetyAndPrivacyController.php | 21 +++++++++++++------ .../SecondStepStoreRequest.php | 1 + ...add_column_to_safety_and_privacy_table.php | 7 ++++++- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php index 36d41115..06b03021 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacyController.php @@ -101,18 +101,27 @@ class SafetyAndPrivacyController extends Controller { $user = auth()->user(); - DB::transaction(function () use ($request, $safetyAndPrivacy, $user) - { + DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { + + $need_judiciary = $request->need_judiciary; + $judiciary_document = []; - foreach ($request->judiciary_document as $index => $file) { - $judiciary_document[] = FileFacade::save($file, "safety_and_privacy/{$safetyAndPrivacy->id}/judiciary_document"); + if ($need_judiciary) { + foreach ($request->judiciary_document as $index => $file) { + $judiciary_document[] = FileFacade::save( + $file, + "safety_and_privacy/{$safetyAndPrivacy->id}/judiciary_document" + ); + } } + $step = SafetyAndPrivacySteps::MOSTANADAT_GAZAEI->value; $safetyAndPrivacy->update([ - 'judiciary_document' => serialize($judiciary_document), - 'judiciary_document_upload_date' => now(), 'step' => $step, 'step_fa' => SafetyAndPrivacySteps::name($step), + 'judiciary_document' => $need_judiciary ? serialize($judiciary_document) : null, + 'judiciary_document_upload_date' => $need_judiciary ? now() : null, + 'need_judiciary' => $need_judiciary, ]); $user->addActivityComplete(1135); diff --git a/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php b/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php index 5d130d51..78e471ad 100644 --- a/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php +++ b/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php @@ -22,6 +22,7 @@ class SecondStepStoreRequest extends FormRequest public function rules(): array { return [ + 'need_judiciary' => 'required|boolean', 'judiciary_document' => 'required|array', 'judiciary_document.*' => 'file', ]; 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 index d63218ce..e78b6af7 100644 --- 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 @@ -17,6 +17,9 @@ return new class extends Migration $table->string('status_fa')->nullable(); $table->string('supervisor_description')->nullable(); $table->string('final_description')->nullable(); + $table->boolean('need_judiciary')->nullable(); + $table->text('judiciary_document')->nullable()->change(); + $table->dateTime('judiciary_document_upload_date')->nullable()->change(); }); } @@ -26,7 +29,9 @@ return new class extends Migration public function down(): void { Schema::table('safety_and_privacy', function (Blueprint $table) { - $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description', 'status_fa']); + $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description', 'status_fa', 'need_judiciary']); + $table->text('judiciary_document')->change(); + $table->dateTime('judiciary_document_upload_date')->change(); }); } }; From c754a2a7bae563f78c773e5c7de12eab5e01b708 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 27 Apr 2025 10:11:50 +0330 Subject: [PATCH 42/48] change directory --- .../SafetyAndPrivacy/OperatorController.php | 230 ++++++++++++++++++ .../OperatorReportController.php | 52 ++++ .../SafetyAndPrivacy/SupervisorController.php | 56 +++++ .../SupervisorReportController.php | 56 +++++ routes/v3.php | 77 ++++-- 5 files changed, 444 insertions(+), 27 deletions(-) create mode 100644 app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php create mode 100644 app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorReportController.php create mode 100644 app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php create mode 100644 app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorReportController.php diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php new file mode 100644 index 00000000..bce8f08e --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php @@ -0,0 +1,230 @@ +json($safetyAndPrivacyTableService->operatorDatatable($request)); + } + + /** + * @throws Throwable + */ + public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + $data = $safetyAndPrivacyTableService->operatorDatatable($request); + return Excel::download(new OperatorCartableReport($data['data']), $name); + } + + public function firstStepStore(FirstStepStoreRequest $request, NominatimService $nominatimService): JsonResponse + { + $user = auth()->user(); + + $coordinates = explode(',', $request->point); + $item = InfoItem::query() + ->where('id', $request->info_id) + ->where('item', 17) + ->firstOrFail(); + + DB::transaction(function () use ($request, $coordinates, $item, $nominatimService, $user) + { + $step = SafetyAndPrivacySteps::SHENASAEI->value; + $safety_and_privacy = SafetyAndPrivacy::query()->create([ + 'lat' => $coordinates[0], + 'lon' => $coordinates[1], + 'operator_id' => $user->id, + 'operator_name' => $user->name, + 'province_id' => $user->province_id, + 'province_fa' => $user->province_fa, + 'info_id' => $item->id, + 'info_fa' => $item->sub_item_str, + 'city_id' => $user->city_id, + 'city_fa' => $user->city_fa, + 'activity_date_time' => $request->activity_date." ".$request->activity_time, + 'edare_shahri_id' => $user->edarate_shahri_id, + 'edare_shahri_name' => $user->edarate_shahri_name, + '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' => $step, + 'step_fa' => SafetyAndPrivacySteps::name($step), + 'is_finished' => false, + ]); + + $safety_and_privacy->recognize_picture = $request->has('recognize_picture') ? + FileFacade::save($request->recognize_picture, "safety_and_privacy/{$safety_and_privacy->id}") : + null; + $safety_and_privacy->save(); + + $user->addActivityComplete(1134); + }); + + return $this->successResponse(); + } + + public function secondStepStore(SafetyAndPrivacy $safetyAndPrivacy, SecondStepStoreRequest $request): JsonResponse + { + $user = auth()->user(); + + DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { + + $need_judiciary = $request->need_judiciary; + + $judiciary_document = []; + if ($need_judiciary) { + foreach ($request->judiciary_document as $index => $file) { + $judiciary_document[] = FileFacade::save( + $file, + "safety_and_privacy/{$safetyAndPrivacy->id}/judiciary_document" + ); + } + } + + $step = SafetyAndPrivacySteps::MOSTANADAT_GAZAEI->value; + $safetyAndPrivacy->update([ + 'step' => $step, + 'step_fa' => SafetyAndPrivacySteps::name($step), + 'judiciary_document' => $need_judiciary ? serialize($judiciary_document) : null, + 'judiciary_document_upload_date' => $need_judiciary ? now() : null, + 'need_judiciary' => $need_judiciary, + ]); + + $user->addActivityComplete(1135); + }); + + return $this->successResponse(); + } + + public function thirdStepStore(SafetyAndPrivacy $safetyAndPrivacy, ThirdStepStoreRequest $request): JsonResponse + { + $user = auth()->user(); + + DB::transaction(function () use ($request, $safetyAndPrivacy, $user) { + $step = SafetyAndPrivacySteps::BARKHORD->value; + $safetyAndPrivacy->update([ + 'step' => $step, + 'step_fa' => SafetyAndPrivacySteps::name($step), + '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, + 'final_description' => 'پیام سیستمی : این عملیات پس از طی تمامی گام ها خاتمه یافت' + ]); + + $user->addActivityComplete(1136); + }); + + return $this->successResponse(); + } + + public function update(SafetyAndPrivacy $safetyAndPrivacy, UpdateRequest $request): JsonResponse + { + DB::transaction(function () use ($request, $safetyAndPrivacy) { + $safetyAndPrivacy->update([ + 'axis_type_id' => $request->axis_type_id, + 'axis_type_name' => AxisTypes::name($request->axis_type_id), + ]); + + auth()->user()->addActivityComplete(1168); + }); + + return $this->successResponse(); + } + + public function show(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + return $this->successResponse($safetyAndPrivacy); + } + + public function destroy(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + FileFacade::deleteDirectory("safety_and_privacy/{$safetyAndPrivacy->id}"); + + DB::transaction(function () use ($safetyAndPrivacy) + { + auth()->user()->addActivityComplete(1155); + $safetyAndPrivacy->delete(); + }); + + return $this->successResponse(); + } + + public function deserialize(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $judiciaries = $safetyAndPrivacy->judiciary_document ? unserialize($safetyAndPrivacy->judiciary_document) : []; + + $result = []; + + foreach ($judiciaries as $judiciary) { + $result[] = Storage::disk('public')->url($judiciary); + } + + return $this->successResponse($result); + } + + public function subItems(): JsonResponse + { + return $this->successResponse(InfoItem::query() + ->where('item', '=', 17) + ->select('id', 'item', 'item_str', 'sub_item_str as name', 'sub_item_unit as unit', 'needs_image', 'needs_end_point', 'sub_item') + ->get()); + } + + public function finish(FinishRequest $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $status_id = SafetyAndPrivacyStatus::PENDING->value; + + $safetyAndPrivacy->update([ + 'is_finished' => 1, + 'final_description' => $request->final_description, + 'status' => $status_id, + 'status_fa' => SafetyAndPrivacyStatus::name($status_id), + ]); + + return $this->successResponse(); + } + + public function map(Request $request): JsonResponse + { + return response()->json(DataTableFacade::run( + SafetyAndPrivacy::query(), + $request, + allowedFilters: ['*'], + allowedSortings: ['*'], + allowedSelects: ['id', 'lat', 'lon', 'step'] + )); + } +} diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorReportController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorReportController.php new file mode 100644 index 00000000..31b41c52 --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorReportController.php @@ -0,0 +1,52 @@ +countryActivity($request); + return $this->successResponse([ + 'activities' => $data, + 'provinces' => Province::all(['id', 'name_fa']) + ]); + } + + public function provinceActivity(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse + { + $data = $safetyAndPrivacyTableService->provinceActivity($request); + return $this->successResponse([ + 'activities' => $data, + 'edarateShahri' => EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']), + ]); + } + + public function countryExcelActivity(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $data = $safetyAndPrivacyTableService->countryActivity($request); + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + return Excel::download(new CountryActivityReport($data), $name); + } + + public function provinceExcelActivity(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $data = $safetyAndPrivacyTableService->provinceActivity($request); + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + return Excel::download(new ProvinceActivityReport($data, $request), $name); + } +} diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php new file mode 100644 index 00000000..240a7219 --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php @@ -0,0 +1,56 @@ +json($safetyAndPrivacyTableService->supervisorDataTable($request)); + } + + public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + $data = $safetyAndPrivacyTableService->supervisorDataTable($request); + return Excel::download(new SupervisorCartableReport($data['data']), $name); + } + + public function confirm(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $status_id = SafetyAndPrivacyStatus::CONFIRM->value; + + $safetyAndPrivacy->update([ + 'status' => $status_id, + 'status_fa' => SafetyAndPrivacyStatus::name($status_id), + ]); + + return $this->successResponse(); + } + + public function reject(RejectRequest $request, SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + { + $status_id = SafetyAndPrivacyStatus::REJECT->value; + + $safetyAndPrivacy->update([ + 'status' => $status_id, + 'status_fa' => SafetyAndPrivacyStatus::name($status_id), + 'supervisor_description' => $request->supervisor_description + ]); + + return $this->successResponse(); + } +} diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorReportController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorReportController.php new file mode 100644 index 00000000..60b3ab87 --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorReportController.php @@ -0,0 +1,56 @@ +countryActivity($request); + return $this->successResponse([ + 'activities' => $data, + 'provinces' => Province::all(['id', 'name_fa']) + ]); + } + + public function provinceActivity(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse + { + $data = $safetyAndPrivacyTableService->provinceActivity($request); + return $this->successResponse([ + 'activities' => $data, + 'edarateShahri' => EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']), + ]); + } + + public function countryExcelActivity(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $data = $safetyAndPrivacyTableService->countryActivity($request); + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + return Excel::download(new CountryActivityReport($data), $name); + } + + public function provinceExcelActivity(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse + { + $data = $safetyAndPrivacyTableService->provinceActivity($request); + $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + return Excel::download(new ProvinceActivityReport($data, $request), $name); + } +} diff --git a/routes/v3.php b/routes/v3.php index 7d6b2e8f..98953436 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -18,7 +18,10 @@ use App\Http\Controllers\V3\Dashboard\Reports\SafetyAndPrivacyReportController; use App\Http\Controllers\V3\Dashboard\RoadItemsProjectController; use App\Http\Controllers\V3\Dashboard\RoadObservationController; use App\Http\Controllers\V3\Dashboard\RoadPatrolProjectController; -use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacyController; +use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacy\OperatorController; +use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacy\OperatorReportController; +use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacy\SupervisorController; +use App\Http\Controllers\V3\Dashboard\SafetyAndPrivacy\SupervisorReportController; use App\Http\Controllers\V3\FMSVehicleManagementController; use App\Http\Controllers\V3\Harim\DivarkeshiController; use App\Http\Controllers\V3\LogListManagementController; @@ -335,39 +338,59 @@ Route::prefix('log_list') Route::prefix('safety_and_privacy') ->name('SafetyAndPrivacy.') - ->controller(SafetyAndPrivacyController::class) ->group(function () { - Route::get('/operator_index', 'operatorIndex')->name('operatorIndex') - ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); - Route::get('/supervisor_index', 'supervisorIndex')->name('supervisorIndex') - ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province'); - Route::get('/operator_excel_report', 'operatorExcelReport')->name('operatorExcelReport') - ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); - Route::get('/supervisor_excel_report', 'supervisorExcelReport')->name('supervisorExcelReport') - ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province'); + Route::prefix('operator') + ->name('operator.') + ->controller(OperatorController::class) + ->group(function () { + Route::get('/', 'index')->name('index') + ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); + Route::get('/excel_report', 'excelReport')->name('excelReport') + ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); + 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(['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'); + Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); + Route::post('/finish/{safetyAndPrivacy}', 'finish')->name('finish'); + }); - 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(['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'); - Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); - Route::post('/confirm/{safetyAndPrivacy}', 'confirm')->name('confirm'); - Route::post('/reject/{safetyAndPrivacy}', 'reject')->name('reject'); - Route::post('/finish/{safetyAndPrivacy}', 'finish')->name('finish'); + Route::prefix('supervisor') + ->name('supervisor.') + ->controller(SupervisorController::class) + ->group(function () { + Route::get('/', 'index')->name('index') + ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province'); + Route::get('/excel_report', 'excelReport')->name('excelReport') + ->middleware('permission:show-safety-and-privacy-operator-cartable|show-safety-and-privacy-operator-cartable-province'); + Route::post('/confirm/{safetyAndPrivacy}', 'confirm')->name('confirm'); + Route::post('/reject/{safetyAndPrivacy}', 'reject')->name('reject'); + }); }); Route::prefix('safety_and_privacy_report') ->name('SafetyAndPrivacyReport.') - ->controller(SafetyAndPrivacyReportController::class) ->group(function () { - Route::get('/country_activity', 'countryActivity')->name('countryActivity'); - Route::get('/province_activity', 'provinceActivity')->name('provinceActivity'); - Route::get('/country_excel_activity', 'countryExcelActivity')->name('countryExcelActivity'); - Route::get('/province_excel_activity', 'provinceExcelActivity')->name('provinceExcelActivity'); + Route::prefix('operator') + ->name('operator.') + ->controller(OperatorReportController::class) + ->group(function () { + Route::get('/country_activity', 'countryActivity')->name('countryActivity'); + Route::get('/province_activity', 'provinceActivity')->name('provinceActivity'); + Route::get('/country_excel_activity', 'countryExcelActivity')->name('countryExcelActivity'); + Route::get('/province_excel_activity', 'provinceExcelActivity')->name('provinceExcelActivity'); + }); + + Route::prefix('supervisor') + ->name('supervisor.') + ->controller(SupervisorReportController::class) + ->group(function () { + + }); }); Route::prefix('otp') From 65375bf399efa2d48ec2d5d428d718f3f1785382 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 27 Apr 2025 10:51:11 +0330 Subject: [PATCH 43/48] add description section to second step --- .../SafetyAndPrivacy/OperatorController.php | 1 + .../SecondStepStoreRequest.php | 3 +- .../SafetyAndPrivacyTableService.php | 40 +++++++++---------- ...add_column_to_safety_and_privacy_table.php | 1 + 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php index bce8f08e..650a6a93 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/OperatorController.php @@ -120,6 +120,7 @@ class OperatorController extends Controller 'judiciary_document' => $need_judiciary ? serialize($judiciary_document) : null, 'judiciary_document_upload_date' => $need_judiciary ? now() : null, 'need_judiciary' => $need_judiciary, + 'operator_description' => $request->operator_description, ]); $user->addActivityComplete(1135); diff --git a/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php b/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php index 78e471ad..dc88a0b6 100644 --- a/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php +++ b/app/Http/Requests/V3/SafetyAndPrivacy/SecondStepStoreRequest.php @@ -23,7 +23,8 @@ class SecondStepStoreRequest extends FormRequest { return [ 'need_judiciary' => 'required|boolean', - 'judiciary_document' => 'required|array', + 'operator_description' => 'required_if:need_judiciary,0|string', + 'judiciary_document' => 'required_if:need_judiciary,1|array', 'judiciary_document.*' => 'file', ]; } diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 4e651ef4..f5d07ad4 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -28,42 +28,40 @@ class SafetyAndPrivacyTableService 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description' ]; - if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable')) { - $query = SafetyAndPrivacy::query()->select($fields); - } - elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-province')) { - throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); + throw_if(is_null($user->edarate_shahri_id), new ProhibitedAction('اداره ای برای شما در سامانه ثبت نشده است!')); - $query = SafetyAndPrivacy::query()->where('province_id', '=', $user->province_id)->select($fields); - } - elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-edarate-shahri')) { - throw_if(is_null($user->edarate_shahri_id), new ProhibitedAction('اداره ای برای شما در سامانه ثبت نشده است!')); - - $query = SafetyAndPrivacy::query()->where('edare_shahri_id', '=', $user->edarate_shahri_id); - } + $query = SafetyAndPrivacy::query()->where('edare_shahri_id', '=', $user->edarate_shahri_id); return DataTableFacade::run( $query, $request, allowedFilters: ['*'], - allowedSortings: ['*'] + allowedSortings: ['*'], + allowedSelects: $fields ); } + /** + * @throws Throwable + */ 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' + $fields = [ + 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', + 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', + 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description' ]; - $query = SafetyAndPrivacy::query()->where([ - ['province_id', '=', $user->province_id], - ['is_finished', '=', 1] - ]); + $query = SafetyAndPrivacy::query()->where('is_finished', '=', 1); + + if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-province')) + { + throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); + + $query = $query->where('province_id', '=', $user->province_id); + } return DataTableFacade::run( $query, 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 index e78b6af7..d747836d 100644 --- 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 @@ -15,6 +15,7 @@ return new class extends Migration $table->boolean('is_finished')->nullable(); $table->integer('status')->nullable(); $table->string('status_fa')->nullable(); + $table->string('operator_description')->nullable(); $table->string('supervisor_description')->nullable(); $table->string('final_description')->nullable(); $table->boolean('need_judiciary')->nullable(); From 9a0f1522448b6ebf8982041e7eaec2a4e0008721 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 27 Apr 2025 11:20:48 +0330 Subject: [PATCH 44/48] add prefix to routes --- .../SafetyAndPrivacyTableService.php | 4 ++-- ...add_column_to_safety_and_privacy_table.php | 2 +- routes/v3.php | 21 +++++++++---------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index f5d07ad4..89e0ee0f 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -25,7 +25,7 @@ class SafetyAndPrivacyTableService $fields = [ 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', - 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description' + 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description', 'operator_description' ]; throw_if(is_null($user->edarate_shahri_id), new ProhibitedAction('اداره ای برای شما در سامانه ثبت نشده است!')); @@ -51,7 +51,7 @@ class SafetyAndPrivacyTableService $fields = [ 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', - 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description' + 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description', 'operator_description' ]; $query = SafetyAndPrivacy::query()->where('is_finished', '=', 1); 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 index d747836d..63711b72 100644 --- 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 @@ -30,7 +30,7 @@ return new class extends Migration public function down(): void { Schema::table('safety_and_privacy', function (Blueprint $table) { - $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description', 'status_fa', 'need_judiciary']); + $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description', 'status_fa', 'need_judiciary', 'operator_description']); $table->text('judiciary_document')->change(); $table->dateTime('judiciary_document_upload_date')->change(); }); diff --git a/routes/v3.php b/routes/v3.php index 98953436..01f34693 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -339,24 +339,23 @@ Route::prefix('log_list') Route::prefix('safety_and_privacy') ->name('SafetyAndPrivacy.') ->group(function () { - Route::prefix('operator') - ->name('operator.') + Route::name('operator.') ->controller(OperatorController::class) ->group(function () { - Route::get('/', 'index')->name('index') + Route::get('operator', 'index')->name('index') ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); - Route::get('/excel_report', 'excelReport')->name('excelReport') + Route::get('operator/excel_report', 'excelReport')->name('excelReport') ->middleware('permission:show-safety-and-privacy-operator-cartable-edarate-shahri'); - Route::post('/first_step_store', 'firstStepStore')->name('firstStepStore')->middleware(['validate-store-access', 'permission:add-safety-and-privacy']); + Route::post('operator/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(['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'); + Route::post('operator/second_step_store/{safetyAndPrivacy}', 'secondStepStore')->name('secondStepStore')->middleware(['validate-store-access','permission:add-safety-and-privacy']); + Route::post('operator/third_step_store/{safetyAndPrivacy}', 'thirdStepStore')->name('thirdStepStore')->middleware(['validate-store-access','permission:add-safety-and-privacy']); + Route::post('operator/{safetyAndPrivacy}', 'update')->name('update')->middleware('permission:update-safety-and-privacy'); + Route::get('operator/{safetyAndPrivacy}', 'show')->name('show'); + Route::delete('operator/{safetyAndPrivacy}', 'destroy')->name('destroy')->middleware('permission:delete-safety-and-privacy'); Route::get('/deserialize/{safetyAndPrivacy}', 'deserialize')->name('deserialize'); - Route::post('/finish/{safetyAndPrivacy}', 'finish')->name('finish'); + Route::post('operator/finish/{safetyAndPrivacy}', 'finish')->name('finish'); }); Route::prefix('supervisor') From d0b9803d8d928390c3ba8858548636687ef7b4a5 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 27 Apr 2025 13:55:29 +0330 Subject: [PATCH 45/48] add notification count for supervise --- .../SafetyAndPrivacy/SupervisorController.php | 8 +++++ .../Controllers/V3/NotificationController.php | 33 ++++++++++++------- app/Models/SafetyAndPrivacy.php | 3 +- .../SafetyAndPrivacyTableService.php | 6 ++-- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php index 240a7219..f6ddb692 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php @@ -13,15 +13,23 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Maatwebsite\Excel\Facades\Excel; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Throwable; class SupervisorController extends Controller { use ApiResponse; + + /** + * @throws Throwable + */ public function index(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): JsonResponse { return response()->json($safetyAndPrivacyTableService->supervisorDataTable($request)); } + /** + * @throws Throwable + */ public function excelReport(Request $request, SafetyAndPrivacyTableService $safetyAndPrivacyTableService): BinaryFileResponse { $name = 'گزارش از نگهداری حریم راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; diff --git a/app/Http/Controllers/V3/NotificationController.php b/app/Http/Controllers/V3/NotificationController.php index 833ba72c..b48536c5 100644 --- a/app/Http/Controllers/V3/NotificationController.php +++ b/app/Http/Controllers/V3/NotificationController.php @@ -91,23 +91,31 @@ class NotificationController extends Controller private function safetyAndPrivacyNotifications(): JsonResponse|array { $user = auth()->user(); - $safety_and_privacy = array(); + $safety_and_privacy = [ + 'supervise_cnt' => 0, + 'step_one' => 0, + 'step_two' => 0, + ]; if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable')) { - $activity = SafetyAndPrivacy::query() - ->selectRaw('count(*) as cnt, step') - ->groupby('step') - ->orderBy('step') + $supervise = SafetyAndPrivacy::query() + ->selectRaw('count(*) as cnt') + ->where([ + ['is_finished', '=', 1], + ['status', '=', 0], + ]) ->get(); } elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-province')) { throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); - $activity = SafetyAndPrivacy::query() + $supervise = SafetyAndPrivacy::query() ->where('province_id', '=', $user->province_id) - ->selectRaw('count(*) as cnt, step') - ->groupby('step') - ->orderBy('step') + ->selectRaw('count(*) as cnt') + ->where([ + ['is_finished', '=', 1], + ['status', '=', 0], + ]) ->get(); } @@ -120,13 +128,14 @@ class NotificationController extends Controller ->groupby('step') ->orderBy('step') ->get(); - } - $step_one = $activity->where('step', '=', 1)->first(); - $step_two = $activity->where('step', '=', 2)->first(); + $step_one = $activity->where('step', '=', 1)->first(); + $step_two = $activity->where('step', '=', 2)->first(); + } $safety_and_privacy['step_one'] = $step_one->cnt ?? 0; $safety_and_privacy['step_two'] = $step_two->cnt ?? 0; + $safety_and_privacy['supervise_cnt'] = $supervise->cnt ?? 0; return $safety_and_privacy; } diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index 55e0a239..5fbc1126 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -42,7 +42,8 @@ class SafetyAndPrivacy extends Model 'is_finished', 'supervisor_description', 'status_fa', - 'need_judiciary' + 'need_judiciary', + 'operator_description' ]; public $table = "safety_and_privacy"; diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index 89e0ee0f..a9ec577e 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -49,12 +49,12 @@ class SafetyAndPrivacyTableService $user = auth()->user(); $fields = [ - 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', - 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', + 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', 'province_fa', + 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', 'edare_shahri_name', 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description', 'operator_description' ]; - $query = SafetyAndPrivacy::query()->where('is_finished', '=', 1); + $query = SafetyAndPrivacy::query(); if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-province')) { From 933a5165e70af8d9da15f34c1447a23eaff10ccd Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sun, 27 Apr 2025 14:24:37 +0330 Subject: [PATCH 46/48] add new column to safety --- .../SafetyAndPrivacy/SupervisorController.php | 9 ++++- .../Controllers/V3/NotificationController.php | 39 +++++++------------ app/Models/SafetyAndPrivacy.php | 4 +- .../SafetyAndPrivacyTableService.php | 2 +- ...add_column_to_safety_and_privacy_table.php | 8 +++- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php index f6ddb692..fc026166 100644 --- a/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php +++ b/app/Http/Controllers/V3/Dashboard/SafetyAndPrivacy/SupervisorController.php @@ -37,13 +37,16 @@ class SupervisorController extends Controller return Excel::download(new SupervisorCartableReport($data['data']), $name); } - public function confirm(SafetyAndPrivacy $safetyAndPrivacy): JsonResponse + public function confirm(SafetyAndPrivacy $safetyAndPrivacy, Request $request): JsonResponse { $status_id = SafetyAndPrivacyStatus::CONFIRM->value; $safetyAndPrivacy->update([ 'status' => $status_id, 'status_fa' => SafetyAndPrivacyStatus::name($status_id), + 'supervisor_description' => $request->supervisor_description, + 'supervisor_id' => auth()->user()->id, + 'supervisor_name' => auth()->user()->name, ]); return $this->successResponse(); @@ -56,7 +59,9 @@ class SupervisorController extends Controller $safetyAndPrivacy->update([ 'status' => $status_id, 'status_fa' => SafetyAndPrivacyStatus::name($status_id), - 'supervisor_description' => $request->supervisor_description + 'supervisor_description' => $request->supervisor_description, + 'supervisor_id' => auth()->user()->id, + 'supervisor_name' => auth()->user()->name, ]); return $this->successResponse(); diff --git a/app/Http/Controllers/V3/NotificationController.php b/app/Http/Controllers/V3/NotificationController.php index b48536c5..f5d3bb82 100644 --- a/app/Http/Controllers/V3/NotificationController.php +++ b/app/Http/Controllers/V3/NotificationController.php @@ -91,33 +91,22 @@ class NotificationController extends Controller private function safetyAndPrivacyNotifications(): JsonResponse|array { $user = auth()->user(); - $safety_and_privacy = [ - 'supervise_cnt' => 0, - 'step_one' => 0, - 'step_two' => 0, - ]; - if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable')) { - $supervise = SafetyAndPrivacy::query() - ->selectRaw('count(*) as cnt') - ->where([ - ['is_finished', '=', 1], - ['status', '=', 0], - ]) - ->get(); + $safety_and_privacy = array(); + if ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable')) { + $safety_and_privacy['supervise_cnt'] = SafetyAndPrivacy::query() + ->where('is_finished', '=', 1) + ->where('status', '=', 0) + ->count(); } elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-province')) { throw_if(is_null($user->province_id), new ProhibitedAction('استانی برای شما در سامانه ثبت نشده است!')); - $supervise = SafetyAndPrivacy::query() + $safety_and_privacy['supervise_cnt'] = SafetyAndPrivacy::query() ->where('province_id', '=', $user->province_id) - ->selectRaw('count(*) as cnt') - ->where([ - ['is_finished', '=', 1], - ['status', '=', 0], - ]) - ->get(); - + ->where('is_finished', '=', 1) + ->where('status', '=', 0) + ->count(); } elseif ($user->hasPermissionTo('show-safety-and-privacy-operator-cartable-edarate-shahri')) { throw_if(is_null($user->edarate_shahri_id), new ProhibitedAction('اداره ای برای شما در سامانه ثبت نشده است!')); @@ -125,17 +114,17 @@ class NotificationController extends Controller $activity = SafetyAndPrivacy::query() ->where('edare_shahri_id', '=', $user->edarate_shahri_id) ->selectRaw('count(*) as cnt, step') + ->where('is_finished', '=', 0) ->groupby('step') ->orderBy('step') ->get(); $step_one = $activity->where('step', '=', 1)->first(); $step_two = $activity->where('step', '=', 2)->first(); - } - $safety_and_privacy['step_one'] = $step_one->cnt ?? 0; - $safety_and_privacy['step_two'] = $step_two->cnt ?? 0; - $safety_and_privacy['supervise_cnt'] = $supervise->cnt ?? 0; + $safety_and_privacy['step_one'] = $step_one->cnt ?? 0; + $safety_and_privacy['step_two'] = $step_two->cnt ?? 0; + } return $safety_and_privacy; } diff --git a/app/Models/SafetyAndPrivacy.php b/app/Models/SafetyAndPrivacy.php index 5fbc1126..0ae5ac91 100644 --- a/app/Models/SafetyAndPrivacy.php +++ b/app/Models/SafetyAndPrivacy.php @@ -43,7 +43,9 @@ class SafetyAndPrivacy extends Model 'supervisor_description', 'status_fa', 'need_judiciary', - 'operator_description' + 'operator_description', + 'supervisor_name', + 'supervisor_id' ]; public $table = "safety_and_privacy"; diff --git a/app/Services/Cartables/SafetyAndPrivacyTableService.php b/app/Services/Cartables/SafetyAndPrivacyTableService.php index a9ec577e..b6331901 100644 --- a/app/Services/Cartables/SafetyAndPrivacyTableService.php +++ b/app/Services/Cartables/SafetyAndPrivacyTableService.php @@ -49,7 +49,7 @@ class SafetyAndPrivacyTableService $user = auth()->user(); $fields = [ - 'id','lat','lon', 'recognize_picture','action_picture','created_at','step', 'final_description', 'province_fa', + 'id','lat','lon', 'recognize_picture','action_picture','created_at','status', 'final_description', 'province_fa', 'info_fa', 'activity_date_time', 'action_picture_document_upload_date', 'judiciary_document_upload_date', 'edare_shahri_name', 'step_fa', 'axis_type_id', 'axis_type_name', 'action_date', 'is_finished', 'status_fa', 'supervisor_description', 'operator_description' ]; 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 index 63711b72..ac7409c5 100644 --- 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 @@ -19,6 +19,8 @@ return new class extends Migration $table->string('supervisor_description')->nullable(); $table->string('final_description')->nullable(); $table->boolean('need_judiciary')->nullable(); + $table->integer('supervisor_id')->nullable(); + $table->string('supervisor_name')->nullable(); $table->text('judiciary_document')->nullable()->change(); $table->dateTime('judiciary_document_upload_date')->nullable()->change(); }); @@ -30,7 +32,11 @@ return new class extends Migration public function down(): void { Schema::table('safety_and_privacy', function (Blueprint $table) { - $table->dropColumn(['status', 'final_description', 'is_finished', 'supervisor_description', 'status_fa', 'need_judiciary', 'operator_description']); + $table->dropColumn([ + 'status', 'final_description', 'is_finished', + 'supervisor_description', 'status_fa', 'need_judiciary', + 'operator_description', 'supervisor_name', 'supervisor_id', + ]); $table->text('judiciary_document')->change(); $table->dateTime('judiciary_document_upload_date')->change(); }); From 439527306c6db2d2ddb24bebb133f246c6e108d7 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Mon, 12 May 2025 16:23:39 +0330 Subject: [PATCH 47/48] add daily mode to nikarayan command --- app/Console/Commands/RoadObservationProblems.php | 12 +++++++----- app/Console/Kernel.php | 5 +++-- app/Services/NikarayanService.php | 9 ++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/Console/Commands/RoadObservationProblems.php b/app/Console/Commands/RoadObservationProblems.php index c778d66c..3706103e 100755 --- a/app/Console/Commands/RoadObservationProblems.php +++ b/app/Console/Commands/RoadObservationProblems.php @@ -24,7 +24,7 @@ class RoadObservationProblems extends Command * * @var string */ - protected $signature = 'webservice:roadobserved'; + protected $signature = 'webservice:roadobserved {--daily-mode}'; /** * The console command description. @@ -63,7 +63,9 @@ class RoadObservationProblems extends Command // return 0; // } - $result = $nikarayanService->getRoadObservedProblemsByDate(); + $time = $this->option('daily-mode') ? verta()->subDay() : verta(); + + $result = $nikarayanService->getRoadObservedProblemsByDate($time); $result = serialize($result); $x = strpos($result, 'fk_FeatureType >= 1 && $value->fk_FeatureType <= 18) { + if ($value->fk_FeatureType >= 1 && $value->fk_FeatureType <= 24) { $mobile = null; if ($value->MobileForSendEventSms && (strlen($value->MobileForSendEventSms) == 11)) { @@ -89,7 +91,7 @@ class RoadObservationProblems extends Command } $city = findCityFromGeoJson($value->YGeo, $value->XGeo); - $cityModel = $city ? City::find($city['city_id']) : null; + $cityModel = $city ? City::query()->find($city['city_id']) : City::query()->find(NikarayanComplaints::mapCities((int) $value->fk_Town)); $rop = RoadObserved::query()->updateOrCreate( ['fk_RegisteredEventMessage' => $value->fk_RegisteredEventMessage], [ @@ -130,7 +132,7 @@ class RoadObservationProblems extends Command 'province_id' => $city ? $city['province_id'] : null, 'city_id' => $city ? $city['city_id'] : null, // 'handler_type' => EdarateShahri::class, - 'edarate_shahri_id' => $cityModel ? ($cityModel->edarateShahri()->where('is_primary', 1)->exists() ? $cityModel->edarateShahri()->where('is_primary', 1)->first()->id : null) : null, + 'edarate_shahri_id' => $cityModel->edarateShahri()->first()->id, 'province_fa' => (isset($city['province_id']) ? Province::find($city['province_id'])->name_fa : null), 'city_fa' => $cityModel ? $cityModel->name_fa : null, ] diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 7a38c610..6a2033c1 100755 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -26,7 +26,7 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule) { $schedule->command('webservice:roadobserved') - ->everyFiveMinutes()->appendOutputTo(storage_path('logs/roadobser.log')); + ->everyFiveMinutes()->appendOutputTo(storage_path('logs/nikarayan.log')); $schedule->command('command:sendcontractsmsnotification') // ->everyMinute()->appendOutputTo(storage_path('logs/contractSms.log')); @@ -35,7 +35,8 @@ class Kernel extends ConsoleKernel $schedule->command('reports:rms-summary') ->dailyAt('00:00')->appendOutputTo(storage_path('logs/report_summary.log')); - + $schedule->command("webservice:roadobserved --daily-mode") + ->dailyAt('00:15')->appendOutputTo(storage_path('logs/nikarayan.log')); } /** diff --git a/app/Services/NikarayanService.php b/app/Services/NikarayanService.php index 2d229668..702ab1d4 100644 --- a/app/Services/NikarayanService.php +++ b/app/Services/NikarayanService.php @@ -49,15 +49,14 @@ class NikarayanService /** * @throws SoapFault */ - public function getRoadObservedProblemsByDate() + public function getRoadObservedProblemsByDate($time) { try { $url = "https://riws.rmto.ir/WebServices/NRPTrafficStatus.asmx?wsdl"; - $v = verta(); - $month = $v->month < 10 ? '0' . $v->month : $v->month; - $day = $v->day < 10 ? '0' . $v->day : $v->day; - $date = $v->year . $month . $day; + $month = $time->month < 10 ? '0' . $time->month : $time->month; + $day = $time->day < 10 ? '0' . $time->day : $time->day; + $date = $time->year . $month . $day; $soap_client = new SoapClient($url); return $soap_client->Get_RoadObservedProblems_ByDate(array( From 2a4e8a39432cc5a0d04e68b0c7449ee5c5d115c7 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 13 May 2025 10:02:18 +0330 Subject: [PATCH 48/48] add extra city for nikarayan --- app/Enums/NikarayanComplaints.php | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/app/Enums/NikarayanComplaints.php b/app/Enums/NikarayanComplaints.php index 9d2d5feb..d8bfecd5 100644 --- a/app/Enums/NikarayanComplaints.php +++ b/app/Enums/NikarayanComplaints.php @@ -2636,7 +2636,37 @@ enum NikarayanComplaints: int "CityName" => "خرمدره", "ProvinceID" => "67", "InvarID" => 150 - ] + ], + 432 => [ + "OnvarID" => 432, + "CityName" => "جرقویه علیا", + "ProvinceID" => "21", + "InvarID" => 497 + ], + 433 => [ + "OnvarID" => 433, + "CityName" => "كوهپایه", + "ProvinceID" => "21", + "InvarID" => 793 + ], + 434 => [ + "OnvarID" => 434, + "CityName" => "ورزنه", + "ProvinceID" => "21", + "InvarID" => 805 + ], + 435 => [ + "OnvarID" => 435, + "CityName" => "هرند", + "ProvinceID" => "21", + "InvarID" => 794 + ], + 436 => [ + "OnvarID" => 436, + "CityName" => "جرقویه سفلی", + "ProvinceID" => "21", + "InvarID" => 497 + ], ]; return $nikarayanToRmsCityId[$city_id]["InvarID"]; }