diff --git a/app/Exports/V3/RoadObservation/CountryCartableReport.php b/app/Exports/V3/RoadObservation/CountryCartableReport.php
new file mode 100644
index 00000000..e46a48ac
--- /dev/null
+++ b/app/Exports/V3/RoadObservation/CountryCartableReport.php
@@ -0,0 +1,70 @@
+ $this->data,
+ ]);
+ }
+
+ public function registerEvents(): array
+ {
+ return [
+ AfterSheet::class => function (AfterSheet $event) {
+ $event->sheet->getDelegate()->setRightToLeft(true);
+ $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial');
+ $event->sheet->getDelegate()->getStyle('A:U')
+ ->getAlignment()
+ ->setHorizontal(Alignment::HORIZONTAL_CENTER);
+
+ $event->sheet->getDelegate()->getStyle('A:U')
+ ->getAlignment()
+ ->setVertical(Alignment::VERTICAL_CENTER);
+ }
+ ];
+ }
+
+ 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('j1');
+ return [$drawing, $drawing2];
+ }
+
+}
diff --git a/app/Exports/V3/RoadObservation/ProvinceCartableReport.php b/app/Exports/V3/RoadObservation/ProvinceCartableReport.php
new file mode 100644
index 00000000..57daad87
--- /dev/null
+++ b/app/Exports/V3/RoadObservation/ProvinceCartableReport.php
@@ -0,0 +1,70 @@
+ $this->data,
+ ]);
+ }
+
+ public function registerEvents(): array
+ {
+ return [
+ AfterSheet::class => function (AfterSheet $event) {
+ $event->sheet->getDelegate()->setRightToLeft(true);
+ $event->sheet->getDelegate()->getStyle('A:U')->getFont()->setName('Arial');
+ $event->sheet->getDelegate()->getStyle('A:U')
+ ->getAlignment()
+ ->setHorizontal(Alignment::HORIZONTAL_CENTER);
+
+ $event->sheet->getDelegate()->getStyle('A:U')
+ ->getAlignment()
+ ->setVertical(Alignment::VERTICAL_CENTER);
+ }
+ ];
+ }
+
+ 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('j1');
+ return [$drawing, $drawing2];
+ }
+
+}
diff --git a/app/Http/Controllers/V3/Dashboard/RoadObservation/ReportController.php b/app/Http/Controllers/V3/Dashboard/RoadObservation/ReportController.php
index db11136c..3f6b42ce 100644
--- a/app/Http/Controllers/V3/Dashboard/RoadObservation/ReportController.php
+++ b/app/Http/Controllers/V3/Dashboard/RoadObservation/ReportController.php
@@ -3,13 +3,18 @@
namespace App\Http\Controllers\V3\Dashboard\RoadObservation;
use App\Exports\V2\RoadObservation\ReportComplaintsExport;
+use App\Exports\V3\SafetyAndPrivacy\Country\AccessRoadReport as ExcelReport;
+use App\Exports\V3\SafetyAndPrivacy\Province\AccessRoadReport;
use App\Facades\DataTable\DataTableFacade;
use App\Http\Traits\ApiResponse;
+use App\Models\EdarateShahri;
use App\Models\RoadObserved;
use App\Services\Cartables\RoadObservation\ReportService;
+use App\Services\Cartables\SafetyAndPrivacy\OperatorService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
+use PhpOffice\PhpSpreadsheet\Exception;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class ReportController
@@ -39,4 +44,39 @@ class ReportController
allowedSelects: ['id', 'lat', 'lng', 'status']
));
}
-}
\ No newline at end of file
+
+ public function countryActivity(Request $request, ReportService $reportService): JsonResponse
+ {
+
+ $data = $reportService->countryActivity($request);
+ return response()->json($data['data']);
+ }
+
+ public function provinceActivity(Request $request, ReportService $reportService): JsonResponse
+ {
+
+ $data = $reportService->provinceActivity(
+ province_id: $request->input('province_id')
+ );
+
+ return $this->successResponse([
+ 'activities' => $data,
+ 'edarateShahri' => EdarateShahri::where('province_id', $request->province_id)->get(['id', 'name_fa']),
+ ]);
+ }
+ public function countryActivityExcel(Request $request, OperatorService $operatorService): BinaryFileResponse
+ {
+ $data = $operatorService->countryActivity();
+ $name = 'گزارش رسیدگی به شکایات واکنش سریع' . verta()->now()->format('Y-m-d H-i') . '.xlsx';
+ return Excel::download(new ReportComplaintsExport($data), $name);
+ }
+
+ public function provinceActivityExcel(Request $request, OperatorService $operatorService): BinaryFileResponse
+ {
+ $data = $operatorService->provinceActivity(
+ province_id: $request->input('province_id')
+ );
+ $name = 'گزارش رسیدگی به شکایات واکنش سریع' . verta()->now()->format('Y-m-d H-i') . '.xlsx';
+ return Excel::download(new AccessRoadReport($data, $request), $name);
+ }
+}
diff --git a/app/Services/Cartables/RoadObservation/ReportService.php b/app/Services/Cartables/RoadObservation/ReportService.php
index 71d0cd03..73a78a08 100644
--- a/app/Services/Cartables/RoadObservation/ReportService.php
+++ b/app/Services/Cartables/RoadObservation/ReportService.php
@@ -5,6 +5,7 @@ namespace App\Services\Cartables\RoadObservation;
use App\Facades\DataTable\DataTableFacade;
use App\Models\RoadObserved;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\DB;
class ReportService
{
@@ -50,4 +51,94 @@ class ReportService
'toDate' => $toDate,
];
}
+ public function countryActivity(Request $request): array
+ {
+ return DB::select("
+ SELECT
+ p.id AS province_id,
+ p.name_fa AS province_name,
+ SUM(t.rms_status = 0 ) AS residegiShode,
+ SUM(t.rms_status = 1 ) AS egdamshode,
+ SUM(t.rms_status = 2) AS egdamnashodeh,
+ SUM(t.status = 0 ) AS darhalbarasi,
+ SUM(t.status = 1 ) AS taayidshode,
+ SUM(t.status = 2 ) AS adamtaayid,
+ SUM(t.rms_status = 0 ) + SUM(t.rms_status = 1) + SUM(t.rms_status = 2) AS total
+ FROM
+ provinces p
+ LEFT JOIN
+
+ road_observeds t ON t.province_id = p.id
+ GROUP BY
+ p.id, p.name_fa
+
+ UNION ALL
+
+ SELECT
+ -1 AS province_id,
+ 'کل کشور' AS province_name,
+ SUM(t.rms_status = 0 ) AS residegiShode,
+ SUM(t.rms_status = 1 ) AS egdamshode,
+ SUM(t.rms_status = 2) AS egdamnashodeh,
+ SUM(t.status = 0 ) AS darhalbarasi,
+ SUM(t.status = 1 ) AS taayidshode,
+ SUM(t.status = 2 ) AS adamtaayid,
+ SUM(t.rms_status = 0 ) + SUM(t.rms_status = 1) + SUM(t.rms_status = 2) AS total
+ FROM
+ provinces p
+ LEFT JOIN
+
+ road_observeds t ON t.province_id = p.id
+ ORDER BY
+ province_id
+ ");
+ }
+
+ public function provinceActivity(int $province_id): array
+ {
+ return DB::select("
+ SELECT
+ e.id AS edare_id,
+ e.name_fa AS edare_name,
+ COALESCE(SUM(t.rms_status = 0 ),0) AS residegiShode,
+ COALESCE(SUM(t.rms_status = 1),0) AS egdamshode,
+ COALESCE(SUM(t.rms_status = 2),0) AS egdamnashodeh,
+ COALESCE(SUM(t.status = 0 ),0) AS darhalbarasi,
+ COALESCE(SUM(t.status = 1 ),0) AS taayidshode,
+ COALESCE(SUM(t.status = 2 ),0) AS adamtaayid,
+ COALESCE(SUM(t.rms_status = 0 ) + SUM(t.rms_status = 1) + SUM(t.rms_status = 2),0)AS total
+ FROM
+ edarate_shahri e
+ LEFT JOIN
+ road_observeds t ON t.edarate_shahri_id = e.id AND t.province_id = e.province_id
+ WHERE
+ e.province_id = :provinceId
+ GROUP BY
+ e.id, e.name_fa
+
+ UNION ALL
+
+ SELECT
+ -1 AS edare_id,
+ 'کل استان' AS edare_name,
+ COALESCE(SUM(t.rms_status = 0 ),0) AS residegiShode,
+ COALESCE(SUM(t.rms_status = 1),0) AS egdamshode,
+ COALESCE(SUM(t.rms_status = 2),0) AS egdamnashodeh,
+ COALESCE(SUM(t.status = 0 ),0) AS darhalbarasi,
+ COALESCE(SUM(t.status = 1 ),0) AS taayidshode,
+ COALESCE(SUM(t.status = 2 ),0) AS adamtaayid,
+ COALESCE(SUM(t.rms_status = 0 ) + SUM(t.rms_status = 1) + SUM(t.rms_status = 2),0)AS total
+ FROM
+ edarate_shahri e
+ LEFT JOIN
+ road_observeds t ON t.edarate_shahri_id = e.id AND t.province_id = e.province_id
+ WHERE
+ e.province_id = :provinceId
+ ORDER BY
+ edare_id
+ ", [
+ 'provinceId' => $province_id,
+ ]);
+ }
+
}
\ No newline at end of file
diff --git a/database/migrations/2025_09_08_104123_add_mission_id_to_road_items_projects_table.php b/database/migrations/2025_09_08_104123_add_mission_id_to_road_items_projects_table.php
index 62d511c4..e874b73e 100644
--- a/database/migrations/2025_09_08_104123_add_mission_id_to_road_items_projects_table.php
+++ b/database/migrations/2025_09_08_104123_add_mission_id_to_road_items_projects_table.php
@@ -12,7 +12,7 @@ return new class extends Migration
public function up(): void
{
Schema::table('road_items_projects', function (Blueprint $table) {
- $table->foreignId('mission_id')->nullable()->constrained('missions');
+ $table->unsignedBigInteger('mission_id')->nullable();
});
}
@@ -22,7 +22,6 @@ return new class extends Migration
public function down(): void
{
Schema::table('road_items_projects', function (Blueprint $table) {
- $table->dropForeign('road_items_projects_mission_id_foreign');
$table->dropColumn('mission_id');
});
}
diff --git a/resources/views/v3/Reports/RoadObservation/CountryReport.blade.php b/resources/views/v3/Reports/RoadObservation/CountryReport.blade.php
new file mode 100644
index 00000000..d2aa8270
--- /dev/null
+++ b/resources/views/v3/Reports/RoadObservation/CountryReport.blade.php
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+ گزارش واکنش سریع
+
+
+
+
+
+
+
+
+
+ |
+ تاریخ دریافت گزارش: {{ verta()->now()->format('Y/m/d H:i') }}
+ |
+
+
+ |
+ |
+
+
+ |
+ گزارش رسیدگی به شکایات واکنش سریع
+ |
+
+
+ | کد یکتا |
+ رسیدگی نشده |
+ اقدام شده |
+ اقدام نشده |
+ درحال بررسی |
+ تائید شده |
+ عدم تائید |
+
+
+
+
+
+
+ @foreach ($data as $item)
+
+ | {{ $item['id'] ?? '-' }} |
+ {{ $item['rms_status'] ?? '0' }} |
+ {{ $item['rms_status'] ?? '1' }} |
+ {{ $item['rms_status'] ?? '2' }} |
+ {{ $item['status'] ?? '0' }} |
+ {{ $item['status'] ?? '1' }} |
+ {{ $item['status'] ?? '2' }} |
+
+ @endforeach
+
+
+
+
diff --git a/resources/views/v3/Reports/RoadObservation/ProvinceReport.blade.php b/resources/views/v3/Reports/RoadObservation/ProvinceReport.blade.php
new file mode 100644
index 00000000..fb9c6b08
--- /dev/null
+++ b/resources/views/v3/Reports/RoadObservation/ProvinceReport.blade.php
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+ گزارش واکنش سریع
+
+
+
+
+
+
+
+
+
+ |
+ تاریخ دریافت گزارش: {{ verta()->now()->format('Y/m/d H:i') }}
+ |
+
+
+ |
+ |
+
+
+ |
+ گزارش رسیدگی به شکایات واکنش سریع
+ |
+
+
+ | کد یکتا |
+ کد سوانح |
+ استان |
+ اداره |
+ موضوع گزارش |
+ نوع گزارش |
+ توضیح گزارش |
+ موقعیت مکانی |
+ شماره تماس گیرنده |
+ تاریخ ثبت |
+
+
+
+
+
+ @foreach ($data as $item)
+
+ | {{ $item['id'] ?? '-' }} |
+ {{ $item['fk_RegisteredEventMessage'] ?? '-' }} |
+ {{ $item['province_fa'] ?? '-' }} |
+ {{ $item['edarate_shahri_name_fa'] ?? '-' }} |
+ {{ $item['Title'] ?? '-' }} |
+ {{ $item['FeatureTypeTitle'] ?? '-' }} |
+ {{ $item['Description'] ?? '-' }} |
+ {{ isset($item['lat']) && isset($item['lng']) ? $item['lat'] . ' ' . $item['lng'] : '-' }} |
+ {{ $item['MobileForSendEventSms'] ?? '-' }} |
+ {{ $item['created_at'] ? verta($item['created_at'])->format('Y/n/j H:i:s') : '-' }} |
+
+ @endforeach
+
+
+
+
diff --git a/routes/v3.php b/routes/v3.php
index 23eec06b..9e753f83 100644
--- a/routes/v3.php
+++ b/routes/v3.php
@@ -351,6 +351,10 @@ Route::prefix('road_observations')
Route::get('/index', 'index')->name('index')->middleware('permission:show-fast-react-province|show-fast-react');
Route::get('/excel', 'excel')->name('excel')->middleware('permission:show-fast-react-province|show-fast-react');
Route::get('/map', 'map')->name('map');
+ Route::get('/country_activity', 'countryActivity')->name('countryActivity');
+ Route::get('/province_activity', 'provinceActivity')->name('provinceActivity');
+ Route::get('/country_activity_excels', 'countryActivityExcel')->name('countryExcelActivity');
+ Route::get('/province_activity_excel', 'provinceActivityExcel')->name('provinceExcelActivity');
});
});