From 6e3fa39d984304b8107dadd20f9dcb0511b002a4 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Mon, 17 Feb 2025 15:36:12 +0330 Subject: [PATCH 1/9] create permission --- routes/v3.php | 3 ++- storage/sql-files/permissions.sql | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/routes/v3.php b/routes/v3.php index b21aeb26..8455ac0f 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -219,10 +219,11 @@ Route::prefix('road_patrol_reports') Route::prefix('damages') ->name('damages.') + ->middleware('permission:manage-damage') ->controller(DamageManagementController::class) ->group(function () { Route::get('/', 'index')->name('index'); - Route::get('/list', 'list')->name('list'); + Route::get('/list', 'list')->name('list')->withoutMiddleware('permission:manage-damage'); Route::post('/', 'store')->name('store'); Route::get('/{damage}', 'show')->name('show'); Route::post('/{damage}', 'update')->name('update'); diff --git a/storage/sql-files/permissions.sql b/storage/sql-files/permissions.sql index d6515554..cfba0d08 100644 --- a/storage/sql-files/permissions.sql +++ b/storage/sql-files/permissions.sql @@ -134,4 +134,5 @@ INSERT INTO permissions (name,guard_name,name_fa,description,created_at,updated_ ('show-receipt-province','web','نمایش خسارت (استانی)','نمایش خسارات استانی',NULL,NULL,NULL,NULL,'receipt','خسارات وارد بر ابنیه فنی راه',1,0), ('supervise-road-item-by-edareostani','web','نظارت بر ثبت فعالیت روزانه و جاری(ادارات استانی)',NULL,'2023-07-09 09:48:35','2023-07-09 09:48:37',NULL,NULL,'road-item','فعالیت روزانه',0,0), ('azmayesh-management','web','مدیریت آزمایشات',NULL,'2024-11-18 09:48:35','2024-11-18 09:48:35',NULL,NULL,'azmayesh','آزمایشات',0,0), - ('azmayesh-type-management','web','مدیریت نوع آزمایشات',NULL,'2024-11-18 09:48:35','2024-11-18 09:48:35',NULL,NULL,'azmayesh','آزمایشات',0,0); + ('azmayesh-type-management','web','مدیریت نوع آزمایشات',NULL,'2024-11-18 09:48:35','2024-11-18 09:48:35',NULL,NULL,'azmayesh','آزمایشات',0,0), + ('manage-damage','web','مدیریت خسارات',NULL,'2025-02-17 15:20:35','2025-02-17 15:20:35',NULL,NULL,'damage','خسارات',0,0), From 8a863fa61d6789ecd993df0be5418444b1c75053 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Mon, 17 Feb 2025 16:53:57 +0330 Subject: [PATCH 2/9] fix permission --- storage/sql-files/permissions.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/sql-files/permissions.sql b/storage/sql-files/permissions.sql index cfba0d08..d9aa8baa 100644 --- a/storage/sql-files/permissions.sql +++ b/storage/sql-files/permissions.sql @@ -135,4 +135,4 @@ INSERT INTO permissions (name,guard_name,name_fa,description,created_at,updated_ ('supervise-road-item-by-edareostani','web','نظارت بر ثبت فعالیت روزانه و جاری(ادارات استانی)',NULL,'2023-07-09 09:48:35','2023-07-09 09:48:37',NULL,NULL,'road-item','فعالیت روزانه',0,0), ('azmayesh-management','web','مدیریت آزمایشات',NULL,'2024-11-18 09:48:35','2024-11-18 09:48:35',NULL,NULL,'azmayesh','آزمایشات',0,0), ('azmayesh-type-management','web','مدیریت نوع آزمایشات',NULL,'2024-11-18 09:48:35','2024-11-18 09:48:35',NULL,NULL,'azmayesh','آزمایشات',0,0), - ('manage-damage','web','مدیریت خسارات',NULL,'2025-02-17 15:20:35','2025-02-17 15:20:35',NULL,NULL,'damage','خسارات',0,0), + ('manage-damage','web','مدیریت خسارات',NULL,'2025-02-17 15:20:35','2025-02-17 15:20:35',NULL,NULL,'damage','خسارات',0,0); From 2dc007c4cbbc0a2e6b6403dfc595f788394beaab Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Tue, 18 Feb 2025 16:06:00 +0330 Subject: [PATCH 3/9] seperate the relation loading --- .../V3/Dashboard/ReceiptController.php | 151 ++++++++++++++++-- .../Dashboard/RoadItemsProjectController.php | 19 ++- .../Dashboard/RoadPatrolProjectController.php | 14 +- .../Reports/RoadItemReportService.php | 49 +++--- .../Reports/RoadPatrolReportService.php | 39 ++--- routes/v3.php | 7 + 6 files changed, 209 insertions(+), 70 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/ReceiptController.php b/app/Http/Controllers/V3/Dashboard/ReceiptController.php index 0e9ad4dd..dcf59a49 100644 --- a/app/Http/Controllers/V3/Dashboard/ReceiptController.php +++ b/app/Http/Controllers/V3/Dashboard/ReceiptController.php @@ -21,30 +21,22 @@ class ReceiptController extends Controller { use ApiResponse; - public function show(Request $request): JsonResponse + public function index(Request $request): JsonResponse { - $columns = array('id', 'province_fa','city_fa', 'axis_name', 'accident_type_fa', 'accident_date', 'id', - 'damage_picture1', 'damage_picture2', 'plaque', 'created_at', 'sum', 'deposit_date', 'status', - 'police_file_date','deposit_insurance_image','deposit_daghi_image','deposit_insurance_amount', - 'deposit_daghi_amount','status_fa','final_amount','province_id','accident_time','accident_type', - 'city_id','driver_name','driver_national_code','driver_phone_number','police_file','lat','lng', - 'police_serial','report_base' - ); - - $allowedFilters = $columns; - $allowedSortings = $columns; + $allowedFilters = ['*']; + $allowedSortings = ['*']; $user = auth()->user(); $query = null; if ($user->hasPermissionTo('show-receipt')) { - $query = Accident::with('damages'); + $query = Accident::query(); } else { if (is_null($user->province_id)) { return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); } - $query = Accident::with('damages')->where('province_id', '=', $user->province_id); + $query = Accident::query()->where('province_id', '=', $user->province_id); } $data = DataTableFacade::run( @@ -83,8 +75,10 @@ class ReceiptController extends Controller 'accident_type' => $request->accident_type, 'accident_date' => $request->accident_date, 'accident_time' => $request->accident_time, - 'accident_type_fa' => DailyAccidentSettings::where('type', 'accident_type')->where('name', $request->accident_type)->first()->value, + 'accident_type_fa' => DailyAccidentSettings::query()->where('type', 'accident_type')->where('name', $request->accident_type)->first()->value, 'way_id' => $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng), + 'report_base' => $request->report_base != null ? 1 : null, + 'police_file' => '', ]; if ($request->report_base) { @@ -128,4 +122,133 @@ class ReceiptController extends Controller auth()->user()->addActivityComplete(1123); }); } + + public function show(Accident $accident): JsonResponse + { + return $this->successResponse($accident->load('damages')); + } + + public function update(Accident $accident, Request $request, NominatimService $nominatimService) + { + DB::transaction(function () use ($request, $accident, $nominatimService) { + $accident->province_fa = Province::where('id', $request->province_id)->first()->name_fa; + $accident->province_id = $request->province_id; + + $accident->city_fa = City::where('id', $request->city_id)->first()->name_fa; + $accident->city_id = $request->city_id; + + $accident->axis_name = $request->axis_name; + $accident->driver_name = $request->driver_name; + $accident->plaque = $request->plaque; + $accident->driver_national_code = $request->national_code; + $accident->driver_phone_number = $request->phone_number; + + $accident->lat = $request->lat; + $accident->lng = $request->lng; + + $accident->accident_type = $request->accident_type; + $accident->accident_type_fa = DailyAccidentSettings::where('type', 'accident_type')->where('name', $request->accident_type)->first()->value; + $accident->accident_date = $request->accident_date; + $accident->accident_time = $request->accident_time; + + $accident->way_id = $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng); + + $accident->save(); + + if ($request->report_base) { + \File::delete('storage/'.$accident->police_file); + $accident->police_file = null; + $accident->police_serial = null; + $accident->report_base = 1; + } else { + if ($accident->report_base) { + if ($request->has('police_file')) { + \File::delete('storage/'.$accident->police_file); + $accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public'); + } else { + abort(401, 'please send the file'); + } + } else { + if ($request->has('police_file')) { + \File::delete('storage/'.$accident->police_file); + $accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public'); + } + } + + $accident->police_file_date = $request->police_file_date; + $accident->police_serial = $request->police_serial; + $accident->report_base = 0; + } + + $accident->save(); + + if ($request->has('damage_picture1')) { + \File::delete('storage/'.$accident->damage_picture1); + $accident->damage_picture1 = $request->file('damage_picture1')->storeAs('receipts_files/'.$accident->id, 'damage_picture1_'.$accident->id.'_'.time().'.'.$request->file('damage_picture1')->extension(), 'public'); + } elseif ($request->has('damage_picture1_is_delete')) { + \File::delete('storage/'.$accident->damage_picture1); + $accident->damage_picture1 = null; + } + + if ($request->has('damage_picture2')) { + \File::delete('storage/'.$accident->damage_picture2); + $accident->damage_picture2 = $request->file('damage_picture2')->storeAs('receipts_files/'.$accident->id, 'damage_picture2_'.$accident->id.'_'.time().'.'.$request->file('damage_picture2')->extension(), 'public'); + } elseif ($request->has('damage_picture2_is_delete')) { + \File::delete('storage/'.$accident->damage_picture2); + $accident->damage_picture2 = null; + } + + $accident->save(); + $sum = 0; + $accident->damages()->detach(); + foreach (json_decode($request->items_damge) as $key => $item) { + $damage = Damage::find($item->id); + $accident->damages()->attach($item->id, [ + 'value' => $item->value, + 'unit' => $damage->unit, + 'amount' => $item->amount, + ]); + $sum += $item->amount; + } + + + $ojrate_nasb = $sum/100*20; + $accident->ojrate_nasb = $ojrate_nasb; + + $sum += $ojrate_nasb; + $accident->sum = $sum; + + $accident->save(); + + auth()->user()->addActivityComplete(1124); + }); + } + + public function delete(Accident $accident) + { + \File::delete('storage/receipts_files/'.$accident->id); + + $accident->damages()->detach(); + $accident->delete(); + auth()->user()->addActivityComplete(1125); + + return $this->successResponse(); + } + + public function sendToInsurance(Request $request, Accident $accident) + { + DB::transaction(function () use ($request, $accident) { + $accident->sendToInsurance(); + $accident->save(); + + auth()->user()->addActivityComplete(1126); + }); + + $account_data = Province::query()->where('id', $accident->province_id)->first(); + + return $this->successResponse([ + $account_data, + $accident->load('damages') + ]); + } } diff --git a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php index 00295fb7..f2ee6e08 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php @@ -99,7 +99,7 @@ class RoadItemsProjectController extends Controller public function supervisorCartableReport(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse { $name = 'گزارش از کارتابل ارزیابی فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadItemReportService->supervisorCartableReport($request); + $data = $roadItemReportService->supervisorCartableReport($request, true); return Excel::download(new SupervisorCartableReport($data['data']), $name); } @@ -267,7 +267,22 @@ class RoadItemsProjectController extends Controller public function operatorCartableReport(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse { $name = 'گزارش از کارتابل عملیات فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadItemReportService->operatorCartableReport($request); + $data = $roadItemReportService->operatorCartableReport($request, true); return Excel::download(new OperatorCartableReport($data['data']), $name); } + + public function roadItemMachine(RoadItemsProject $roadItemsProject): JsonResponse + { + return $this->successResponse($roadItemsProject->load('cmmsMachines:id,machine_code,car_name,plak_number')); + } + + public function roadItemRahdar(RoadItemsProject $roadItemsProject): JsonResponse + { + return $this->successResponse($roadItemsProject->load('rahdaran:id,name,code')); + } + + public function roadItemFile(RoadItemsProject $roadItemsProject): JsonResponse + { + return $this->successResponse($roadItemsProject->load('files')); + } } diff --git a/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php index 6056a563..7493b980 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php @@ -83,7 +83,7 @@ class RoadPatrolProjectController extends Controller public function supervisorCartableReport(Request $request, RoadPatrolReportService $roadPatrolReportService): BinaryFileResponse { $name = 'گزارش از کارتابل ارزیابی گشت راهداری ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadPatrolReportService->supervisorCartableReport($request); + $data = $roadPatrolReportService->supervisorCartableReport($request, true); return Excel::download(new SupervisorCartableReport($data['data']), $name); } @@ -325,7 +325,17 @@ class RoadPatrolProjectController extends Controller public function operatorCartableReport(Request $request, RoadPatrolReportService $roadPatrolReportService): BinaryFileResponse { $name = 'گزارش از کارتابل عملیات گشت راهداری ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadPatrolReportService->operatorCartableReport($request); + $data = $roadPatrolReportService->operatorCartableReport($request, true); return Excel::download(new OperatorCartableReport($data['data']), $name); } + + public function roadPatrolMachine(RoadPatrol $roadPatrol): JsonResponse + { + return $this->successResponse($roadPatrol->load('cmmsMachines:id,machine_code,car_name,plak_number')); + } + + public function roadPatrolRahdar(RoadPatrol $roadPatrol): JsonResponse + { + return $this->successResponse($roadPatrol->load('rahdaran:id,name,code')); + } } diff --git a/app/Services/Reports/RoadItemReportService.php b/app/Services/Reports/RoadItemReportService.php index 4751cda3..6f8551ed 100644 --- a/app/Services/Reports/RoadItemReportService.php +++ b/app/Services/Reports/RoadItemReportService.php @@ -11,31 +11,31 @@ use Illuminate\Support\Facades\DB; class RoadItemReportService { - public function supervisorCartableReport(Request $request) + public function supervisorCartableReport(Request $request, $loadRelations = false) { - $columns = array( - 'id', 'user_id', 'start_lat', 'start_lng', 'end_lat', - 'end_lng', 'project_distance', 'item', 'item_fa', 'sub_item_fa', 'sub_item', - 'sub_item_data', 'created_at', 'updated_at', 'province_id', 'province_fa', - 'unit_fa', 'status', 'status_fa', 'supervisor_description', 'supervising_time', - 'supervisor_name', 'edarat_id', 'edarat_name', 'activity_date_time','cmmsMachines.machine_code', 'rahdaran.code', - ); - - $allowedFilters = $columns; - $allowedSortings = $columns; + $allowedFilters = ['*']; + $allowedSortings = ['*']; $user = auth()->user(); $query = null; if ($user->hasPermissionTo('show-road-item-supervise-cartable')) { - $query = RoadItemsProject::query()->where('is_new', 1)->with(['files', 'rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number']); + $query = RoadItemsProject::query() + ->select(['id', 'province_fa', 'edarat_name', 'item_fa', '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) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); } elseif ($user->hasPermissionTo('show-road-item-supervise-cartable-province')) { if (is_null($user->province_id)) { return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); } - $query = RoadItemsProject::query()->where('is_new', 1) - ->with(['files', 'rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])->where('province_id', auth()->user()->province_id); + $query = RoadItemsProject::query() + ->select(['id', 'province_fa', 'edarat_name', 'item_fa', '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('province_id', auth()->user()->province_id) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); } $data = DataTableFacade::run( @@ -47,22 +47,17 @@ class RoadItemReportService return $data; } - public function operatorCartableReport(Request $request) + public function operatorCartableReport(Request $request, $loadRelations = false) { - $columns = array( - 'id', 'user_id', 'start_lat', 'start_lng', 'end_lat', - 'end_lng', 'project_distance', 'item', 'item_fa', 'sub_item_fa', 'sub_item', - 'sub_item_data', 'created_at', 'updated_at', 'province_id', 'province_fa', - 'unit_fa', 'status', 'status_fa', 'supervisor_description', 'supervising_time', - 'supervisor_name', 'edarat_id', 'edarat_name', 'activity_date_time', 'cmmsMachines.machine_code', 'rahdaran.code', - ); + $allowedFilters = ['*']; + $allowedSortings = ['*']; - $allowedFilters = $columns; - $allowedSortings = $columns; - - $query = RoadItemsProject::with(['files', 'rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number']) + $query = RoadItemsProject::query() + ->select(['id', 'supervisor_description', 'item_fa', '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); + ->where('user_id', auth()->user()->id) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number']));; $data = DataTableFacade::run( $query, diff --git a/app/Services/Reports/RoadPatrolReportService.php b/app/Services/Reports/RoadPatrolReportService.php index 38559505..8f0964d8 100644 --- a/app/Services/Reports/RoadPatrolReportService.php +++ b/app/Services/Reports/RoadPatrolReportService.php @@ -9,33 +9,27 @@ use Illuminate\Support\Facades\DB; class RoadPatrolReportService { - public function supervisorCartableReport(Request $request) + public function supervisorCartableReport(Request $request, $loadRelations = false) { - $columns = array( - 'id', 'start_lat', 'start_lon', 'end_lat', 'end_lon', 'operator_id', 'created_at', - 'operator_name', 'officer_plaque', 'officer_phone_number', 'officer_name', - 'supervisor_description', 'supervising_time', 'supervisor_name', 'status', - 'status_fa', 'distance', 'province_id', 'province_fa', 'edare_id', 'edare_name', - 'start_time', 'end_time','description', 'cmmsMachines.machine_code', 'rahdaran.code', - ); - - $allowedFilters = $columns; - $allowedSortings = $columns; + $allowedFilters = ['*']; + $allowedSortings = ['*']; $user = auth()->user(); $query = null; if ($user->hasPermissionTo('show-road-patrol-supervise-cartable')) { $query = RoadPatrol::query() - ->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number']); + ->select([]) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); } elseif ($user->hasPermissionTo('show-road-patrol-supervise-cartable-province')) { if (is_null($user->province_id)) { return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); } $query = RoadPatrol::query() - ->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number']) - ->where('province_id', '=', $user->province_id); + ->select([]) + ->where('province_id', '=', $user->province_id) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); } $data = DataTableFacade::run( @@ -47,20 +41,15 @@ class RoadPatrolReportService return $data; } - public function operatorCartableReport(Request $request) + public function operatorCartableReport(Request $request, $loadRelations = false) { - $columns = array( - 'id', 'start_lat', 'start_lon', 'end_lat', 'end_lon', 'officer_plaque', 'created_at', - 'officer_phone_number', 'officer_name', 'supervisor_description', 'supervising_time', - 'supervisor_name', 'status', 'status_fa', 'distance', 'start_time', 'end_time', 'cmmsMachines.machine_code', 'rahdaran.code', - ); - - $allowedFilters = $columns; - $allowedSortings = $columns; + $allowedFilters = ['*']; + $allowedSortings = ['*']; $query = RoadPatrol::query() - ->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number']) - ->where('operator_id', '=', auth()->user()->id); + ->select([]) + ->where('operator_id', '=', auth()->user()->id) + ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); $data = DataTableFacade::run( $query, diff --git a/routes/v3.php b/routes/v3.php index b21aeb26..8d91a9cc 100644 --- a/routes/v3.php +++ b/routes/v3.php @@ -121,6 +121,10 @@ Route::prefix('road_items') Route::get('/operator_report', 'operatorCartableReport') ->name('operatorCartableReport'); + + Route::get('/machines/{roadItemsProject}', 'roadItemMachine')->name('roadItemMachine'); + Route::get('/rahdaran/{roadItemsProject}', 'roadItemRahdar')->name('roadItemRahdar'); + Route::get('/files/{roadItemsProject}', 'roadItemFile')->name('roadItemFile'); }); Route::prefix('road_patrols') @@ -155,6 +159,9 @@ Route::prefix('road_patrols') Route::get('/detail/{roadPatrol}', 'show') ->name('show'); + + Route::get('/machines/{roadPatrol}', 'roadPatrolMachine')->name('roadPatrolMachine'); + Route::get('/rahdaran/{roadPatrol}', 'roadPatrolRahdar')->name('roadPatrolRahdar'); }); Route::prefix('cmms_machines') From 5634827103ad38f87031751a4363227fbe17a335 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Wed, 19 Feb 2025 09:26:18 +0330 Subject: [PATCH 4/9] seperate relation for road patrol cartable --- .../Controllers/V3/Dashboard/RoadItemsProjectController.php | 6 +++--- .../V3/Dashboard/RoadPatrolProjectController.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php index f2ee6e08..0cf834d3 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php @@ -273,16 +273,16 @@ class RoadItemsProjectController extends Controller public function roadItemMachine(RoadItemsProject $roadItemsProject): JsonResponse { - return $this->successResponse($roadItemsProject->load('cmmsMachines:id,machine_code,car_name,plak_number')); + return $this->successResponse($roadItemsProject->cmmsMachines()->get(['cmms_machines.id', 'cmms_machines.machine_code', 'cmms_machines.car_name', 'cmms_machines.plak_number'])); } public function roadItemRahdar(RoadItemsProject $roadItemsProject): JsonResponse { - return $this->successResponse($roadItemsProject->load('rahdaran:id,name,code')); + return $this->successResponse($roadItemsProject->rahdaran()->get(['rahdaran.id', 'rahdaran.name', 'rahdaran.code'])); } public function roadItemFile(RoadItemsProject $roadItemsProject): JsonResponse { - return $this->successResponse($roadItemsProject->load('files')); + return $this->successResponse($roadItemsProject->files()->get(['path'])); } } diff --git a/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php index 7493b980..dd1f9f32 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php @@ -331,11 +331,11 @@ class RoadPatrolProjectController extends Controller public function roadPatrolMachine(RoadPatrol $roadPatrol): JsonResponse { - return $this->successResponse($roadPatrol->load('cmmsMachines:id,machine_code,car_name,plak_number')); + return $this->successResponse($roadPatrol->cmmsMachines()->get(['cmms_machines.id', 'cmms_machines.machine_code', 'cmms_machines.car_name', 'cmms_machines.plak_number'])); } public function roadPatrolRahdar(RoadPatrol $roadPatrol): JsonResponse { - return $this->successResponse($roadPatrol->load('rahdaran:id,name,code')); + return $this->successResponse($roadPatrol->rahdaran()->get(['rahdaran.id', 'rahdaran.name', 'rahdaran.code'])); } } From aded4f876cf04034930f5291fec804e250a4876a Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 22 Feb 2025 13:15:17 +0330 Subject: [PATCH 5/9] create receipt logic api --- app/Enums/AccidentStates.php | 28 ++ .../Dashboard/AccidentReceiptController.php | 373 ++++++++++++++++++ .../V3/Dashboard/ReceiptController.php | 254 ------------ .../ConfirmPaymentInfoRequest.php | 31 ++ app/Models/Accident.php | 5 + app/Models/File.php | 19 + database/factories/FileFactory.php | 23 ++ .../2025_02_22_101703_create_files_table.php | 30 ++ database/seeders/FileSeeder.php | 17 + routes/v3.php | 17 + 10 files changed, 543 insertions(+), 254 deletions(-) create mode 100644 app/Enums/AccidentStates.php create mode 100644 app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php delete mode 100644 app/Http/Controllers/V3/Dashboard/ReceiptController.php create mode 100644 app/Http/Requests/V3/AccidentReceipt/ConfirmPaymentInfoRequest.php create mode 100644 app/Models/File.php create mode 100644 database/factories/FileFactory.php create mode 100644 database/migrations/2025_02_22_101703_create_files_table.php create mode 100644 database/seeders/FileSeeder.php diff --git a/app/Enums/AccidentStates.php b/app/Enums/AccidentStates.php new file mode 100644 index 00000000..b6494271 --- /dev/null +++ b/app/Enums/AccidentStates.php @@ -0,0 +1,28 @@ + "بدون اقدام", + 1 => "صدور نامه بیمه و کارشناسی داغی", + 2 => "فیش ها ثبت شده است.", + 3 => "فاکتور صادر شده است.", + 4 => "فاکتور پرداخت شده است", + 5 => "نامه پلیس راه صادر شده است (اتمام فرایند)", + ]; + + return $mapArray[$state]; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php new file mode 100644 index 00000000..518d2816 --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php @@ -0,0 +1,373 @@ +user(); + $query = null; + + if ($user->hasPermissionTo('show-receipt')) { + $query = Accident::query(); + } + else { + if (is_null($user->province_id)) { + return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); + } + + $query = Accident::query()->where('province_id', '=', $user->province_id); + } + + $data = DataTableFacade::run( + $query, + $request, + allowedFilters: $allowedFilters, + allowedSortings: $allowedSortings + ); + + + $user->addActivityComplete(1122); + + return response()->json($data); + } + + public function accidentDamage(Accident $accident): JsonResponse + { + return $this->successResponse($accident->damages()->get(['unit', 'amount', 'value'])); + } + + public function store(Request $request, NominatimService $nominatimService): JsonResponse + { + DB::transaction(function () use ($request, $nominatimService) { + + $province = Province::query()->where('id', '=', $request->province_id)->first(); + $city = City::query()->where('id', '=', $request->city_id)->first(); + + $accidentData = [ + 'province_id' => $province->id, + 'province_fa' => $province->name_fa, + 'city_id' => $city->id, + 'city_fa' => $city->name_fa, + 'axis_name' => $request->axis_name, + 'driver_name' => $request->driver_name, + 'plaque' => $request->plaque, + 'driver_national_code' => $request->driver_national_code, + 'driver_phone_number' => $request->driver_phone_number, + 'user_id' => auth()->user()->id, + 'lat' => $request->lat, + 'lng' => $request->lng, + 'accident_type' => $request->accident_type, + 'accident_date' => $request->accident_date, + 'accident_time' => $request->accident_time, + 'accident_type_fa' => DailyAccidentSettings::query()->where('type', 'accident_type')->where('name', $request->accident_type)->first()->value, + 'way_id' => $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng), + 'report_base' => $request->report_base, +// 'police_file' => $request->report_base ? null : FileFacade::save($request->file('police_file'), 'receipts_files/'), + 'police_serial' => $request->police_serial ?? null, + 'police_file_date' => $request->police_file_date ?? null, +// 'damage_picture1' => $request->has('damage_picture1') ? FileFacade::save($request->file('damage_picture1'), 'receipts_files/') : null, +// 'damage_picture2' => $request->has('damage_picture2') ? FileFacade::save($request->file('damage_picture2'), 'receipts_files/') : null, + 'status' => AccidentStates::BEDON_EGHDAM->value, + 'status_fa' => AccidentStates::name(AccidentStates::BEDON_EGHDAM->value), + ]; + + $sum = 0; + $damageData = []; + + foreach ($request->items_damge as $key => $damage) { + $damage = Damage::query()->find($damage->id); + $damageData[$damage->id] = [ + 'value' => $damage->value, + 'unit' => $damage->unit, + 'amount' => $damage->amount, + ]; + $sum += $damage->amount; + } + + $ojrate_nasb = $sum/100*20; + $sum += $ojrate_nasb; + + $accidentData['ojrate_nasb'] = $ojrate_nasb; + $accidentData['sum'] = $sum; + + $accident = Accident::query()->create($accidentData); + + $filesData = [ + [ + 'name' => 'damage_picture1', + 'path' => FileFacade::save($request->file('damage_picture1'), "receipts_files/{$accident->id}/"), + ], + [ + 'name' => 'damage_picture2', + 'path' => FileFacade::save($request->file('damage_picture2'), "receipts_files/{$accident->id}/") + ] + ]; + + if (!$request->report_base) { + $filesData[] = [ + 'name' => 'police_file', + 'path' => FileFacade::save($request->file('police_file'), "receipts_files/{$accident->id}/") + ]; + } + + $accident->damages()->attach($damageData); + $accident->files()->createMany($filesData); + + auth()->user()->addActivityComplete(1123); + }); + + return $this->successResponse(); + } + + public function show(Accident $accident): JsonResponse + { + return $this->successResponse($accident->load('damages')); + } + + public function update(Accident $accident, Request $request, NominatimService $nominatimService): JsonResponse + { + DB::transaction(function () use ($request, $accident, $nominatimService) { + + $province = Province::query()->where('id', '=', $request->province_id)->first(); + $city = City::query()->where('id', '=', $request->city_id)->first(); + + if ($request->report_base && $accident->police_file) { + FileFacade::delete($accident->police_file, true); + } + + if (!$request->report_base && $request->filled('police_file')) { + FileFacade::delete($accident->police_file, true); + } + + if ($request->has('damage_picture1')) { + FileFacade::delete($accident->damage_picture1, true); + $damage_picture1 = FileFacade::save($request->file('damage_picture1'), 'receipts_files/'); + } + if ($request->has('damage_picture2')) { + FileFacade::delete($accident->damage_picture2, true); + $damage_picture2 = FileFacade::save($request->file('damage_picture2'), 'receipts_files/'); + } + + $accidentData = [ + 'province_id' => $province->id, + 'province_fa' => $province->name_fa, + 'city_id' => $city->id, + 'city_fa' => $city->name_fa, + 'axis_name' => $request->axis_name, + 'driver_name' => $request->driver_name, + 'plaque' => $request->plaque, + 'driver_national_code' => $request->driver_national_code, + 'driver_phone_number' => $request->driver_phone_number, + 'user_id' => auth()->user()->id, + 'lat' => $request->lat, + 'lng' => $request->lng, + 'accident_type' => $request->accident_type, + 'accident_date' => $request->accident_date, + 'accident_time' => $request->accident_time, + 'accident_type_fa' => DailyAccidentSettings::query()->where('type', 'accident_type')->where('name', $request->accident_type)->first()->value, + 'way_id' => $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng), + 'report_base' => $request->report_base, + 'police_file' => $request->report_base == 0 ? FileFacade::save($request->file('police_file'), 'receipts_files/') : null, + 'police_serial' => $request->police_serial ?? null, + 'police_file_date' => $request->police_file_date ?? null, + 'damage_picture1' => $damage_picture1, + 'damage_picture2' => $damage_picture2, + ]; + + $sum = 0; + $damageData = []; + + foreach ($request->items_damge as $key => $item) { + $damage = Damage::query()->find($item->id); + $damageData[$damage->id] = [ + 'value' => $damage->value, + 'unit' => $damage->unit, + 'amount' => $damage->amount, + ]; + $sum += $item->amount; + } + + + $ojrate_nasb = $sum/100*20; + $sum += $ojrate_nasb; + + $accidentData['ojrate_nasb'] = $ojrate_nasb; + $accidentData['sum'] = $sum; + + $accident->update($accidentData); + + $accident->damages()->sync($damageData); + + auth()->user()->addActivityComplete(1124); + }); + + return $this->successResponse(); + } + + public function destroy(Accident $accident): JsonResponse + { + FileFacade::delete('storage/receipts_files/'.$accident->id); + + $accident->damages()->detach(); + + $accident->delete(); + + auth()->user()->addActivityComplete(1125); + + return $this->successResponse(); + } + + public function generateInsuranceLetter(Accident $accident): JsonResponse + { + DB::transaction(function () use ($accident) { + $accident->update([ + 'status' => AccidentStates::SODOR_NAME_BIME_VA_DAGHI->value, + 'status_fa' => AccidentStates::name(AccidentStates::SODOR_NAME_BIME_VA_DAGHI->value), + ]); + + auth()->user()->addActivityComplete(1126); + }); + + $account_data = Province::query()->where('id', $accident->province_id)->first(); + + return $this->successResponse([ + $account_data, + $accident->load('damages') + ]); + } + + public function confirmPaymentInfo(ConfirmPaymentInfoRequest $request, Accident $accident): JsonResponse + { + DB::transaction(function () use ($request, $accident) { + if ($request->has('deposit_insurance_status')) { + if ($request->has('deposit_insurance_image')) { + $accident->deposit_insurance_image = $request->file('deposit_insurance_image')->storeAs('receipts_files/'.$accident->id, 'deposit_insurance_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_insurance_image')->extension(), 'public'); + } + + $accident->deposit_insurance_amount = $request->deposit_insurance_amount; + } else { + $accident->deposit_insurance_image = null; + $accident->deposit_insurance_amount = null; + } + + if ($request->has('deposit_daghi_status')) { + if ($request->has('deposit_daghi_image')) { + $accident->deposit_daghi_image = $request->file('deposit_daghi_image')->storeAs('receipts_files/'.$accident->id, 'deposit_daghi_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_daghi_image')->extension(), 'public'); + } + + $accident->deposit_daghi_amount = $request->deposit_daghi_amount; + } else { + $accident->deposit_daghi_image = null; + $accident->deposit_daghi_amount = null; + } + + $accident->update([ + 'status' => AccidentStates::SABT_FISH->value, + 'status_fa' => AccidentStates::name(AccidentStates::SABT_FISH->value), + ]); + + auth()->user()->addActivityComplete(1132); + + return $this->successResponse(); + }); + } + + public function submitInvoice(Accident $accident, PaymentService $paymentService): JsonResponse + { + DB::transaction(function () use ($accident, $paymentService) { + + $final_amount = $accident->sum - ($accident->deposit_insurance_amount + $accident->deposit_daghi_amount); + + if ($final_amount < 0) { + return $this->errorResponse('error'); + } + + $accident->final_amount = $final_amount; + + $accident->bill_code = $paymentService->invoiceBillApi($accident->driver_national_code, $final_amount); + + $accident->update([ + 'status' => AccidentStates::SODOR_FACTOR->value, + 'status_fa' => AccidentStates::name(AccidentStates::SODOR_FACTOR->value), + ]); + + $msg = "فاکتور با شناسه پرداخت \n" . explode("/", $accident->bill_code)[0]. "\n در سامانه سازمان راهداری ثبت شد. برای پرداخت از لینک زیر اقدام نمایید.\n\n".env("PAYMENT_LINK")."/#/pay/".explode("/", $accident->bill_code)[0]."/$final_amount"; + + Sms::sendSms($accident->driver_phone_number, $msg); + + auth()->user()->addActivityComplete(1129); + + return $this->successResponse(); + }); + } + + public function checkPaymentStatus(Accident $accident, PaymentService $paymentService): JsonResponse + { + DB::transaction(function () use ($accident, $paymentService) { + if ($accident->final_amount > 0) { + + $response = json_decode($paymentService->callPaymentStatusBillApi(explode("/", $accident->bill_code)[0])); + + if ($response->isPayed) { + $accident->update([ + 'status' => AccidentStates::PARDAKHT_FACTOR->value, + 'status_fa' => AccidentStates::name(AccidentStates::PARDAKHT_FACTOR->value), + ]); + } + } + else + { + $accident->update([ + 'status' => AccidentStates::PARDAKHT_FACTOR->value, + 'status_fa' => AccidentStates::name(AccidentStates::PARDAKHT_FACTOR->value), + ]); + } + + auth()->user()->addActivityComplete(1130); + + return $this->successResponse(); + }); + } + + public function generatePoliceDocument(Request $request, Accident $accident): JsonResponse + { + DB::transaction(function () use ($request, $accident) { + + $accident->update([ + 'status' => AccidentStates::SODOR_NAME_POLICE_RAH->value, + 'status_fa' => AccidentStates::name(AccidentStates::SODOR_NAME_POLICE_RAH->value), + ]); + + auth()->user()->addActivityComplete(1131); + }); + + + return $this->successResponse(); + } +} diff --git a/app/Http/Controllers/V3/Dashboard/ReceiptController.php b/app/Http/Controllers/V3/Dashboard/ReceiptController.php deleted file mode 100644 index dcf59a49..00000000 --- a/app/Http/Controllers/V3/Dashboard/ReceiptController.php +++ /dev/null @@ -1,254 +0,0 @@ -user(); - $query = null; - - if ($user->hasPermissionTo('show-receipt')) { - $query = Accident::query(); - } else { - if (is_null($user->province_id)) { - return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); - } - - $query = Accident::query()->where('province_id', '=', $user->province_id); - } - - $data = DataTableFacade::run( - $query, - $request, - allowedFilters: $allowedFilters, - allowedSortings: $allowedSortings - ); - - - $user->addActivityComplete(1122); - - return $this->successResponse($data); - } - - public function store(Request $request, NominatimService $nominatimService) - { - DB::transaction(function () use ($request, $nominatimService) { - - $province = Province::query()->where('id', '=', $request->province_id)->first(); - $city = City::query()->where('id', '=', $request->city_id)->first(); - - $accident = [ - 'province_id' => $province->id, - 'province_fa' => $province->name_fa, - 'city_id' => $city->id, - 'city_fa' => $city->name_fa, - 'axis_name' => $request->axis_name, - 'driver_name' => $request->driver_name, - 'plaque' => $request->plaque, - 'driver_national_code' => $request->driver_national_code, - 'driver_phone_number' => $request->driver_phone_number, - 'user_id' => auth()->user()->id, - 'lat' => $request->lat, - 'lng' => $request->lng, - 'accident_type' => $request->accident_type, - 'accident_date' => $request->accident_date, - 'accident_time' => $request->accident_time, - 'accident_type_fa' => DailyAccidentSettings::query()->where('type', 'accident_type')->where('name', $request->accident_type)->first()->value, - 'way_id' => $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng), - 'report_base' => $request->report_base != null ? 1 : null, - 'police_file' => '', - ]; - - if ($request->report_base) { - $accident['report_base'] = 1; - } else { - $accident['police_file'] = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public'); - $accident['police_serial'] = $request->police_serial; - $accident['police_file_date'] = $request->police_file_date; - $accident['report_base'] = 0; - } - - if ($request->has('damage_picture1')) { - $new_accident->damage_picture1 = $request->file('damage_picture1')->storeAs('receipts_files/'.$new_accident->id, 'damage_picture1_'.$new_accident->id.'_'.time().'.'.$request->file('damage_picture1')->extension(), 'public'); - } - - if ($request->has('damage_picture2')) { - $new_accident->damage_picture2 = $request->file('damage_picture2')->storeAs('receipts_files/'.$new_accident->id, 'damage_picture2_'.$new_accident->id.'_'.time().'.'.$request->file('damage_picture2')->extension(), 'public'); - } - - $new_accident->save(); - $sum = 0; - foreach (json_decode($request->items_damge) as $key => $item) { - $damage = Damage::find($item->id); - $new_accident->damages()->attach($item->id, [ - 'value' => $item->value, - 'unit' => $damage->unit, - 'amount' => $item->amount, - ]); - $sum += $item->amount; - } - - $ojrate_nasb = $sum/100*20; - $new_accident->ojrate_nasb = $ojrate_nasb; - - $sum += $ojrate_nasb; - $new_accident->sum = $sum; - $new_accident->withoutAction(); - $new_accident->save(); - $msg = "درخواست شما بابت پرداخت خسارت وارده به ابنیه فنی و تاسیسات راه با کد یکتا ".$new_accident->id." ثبت شد.\n".verta()->now()->format('Y/m/d H:i') ; - Sms::sendSms($request->phone_number, $msg); - auth()->user()->addActivityComplete(1123); - }); - } - - public function show(Accident $accident): JsonResponse - { - return $this->successResponse($accident->load('damages')); - } - - public function update(Accident $accident, Request $request, NominatimService $nominatimService) - { - DB::transaction(function () use ($request, $accident, $nominatimService) { - $accident->province_fa = Province::where('id', $request->province_id)->first()->name_fa; - $accident->province_id = $request->province_id; - - $accident->city_fa = City::where('id', $request->city_id)->first()->name_fa; - $accident->city_id = $request->city_id; - - $accident->axis_name = $request->axis_name; - $accident->driver_name = $request->driver_name; - $accident->plaque = $request->plaque; - $accident->driver_national_code = $request->national_code; - $accident->driver_phone_number = $request->phone_number; - - $accident->lat = $request->lat; - $accident->lng = $request->lng; - - $accident->accident_type = $request->accident_type; - $accident->accident_type_fa = DailyAccidentSettings::where('type', 'accident_type')->where('name', $request->accident_type)->first()->value; - $accident->accident_date = $request->accident_date; - $accident->accident_time = $request->accident_time; - - $accident->way_id = $nominatimService->get_way_id_from_nominatim($request->lat, $request->lng); - - $accident->save(); - - if ($request->report_base) { - \File::delete('storage/'.$accident->police_file); - $accident->police_file = null; - $accident->police_serial = null; - $accident->report_base = 1; - } else { - if ($accident->report_base) { - if ($request->has('police_file')) { - \File::delete('storage/'.$accident->police_file); - $accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public'); - } else { - abort(401, 'please send the file'); - } - } else { - if ($request->has('police_file')) { - \File::delete('storage/'.$accident->police_file); - $accident->police_file = $request->file('police_file')->storeAs('receipts_files/'.$accident->id, 'police_file_'.$accident->id.'_'.time().'.'.$request->file('police_file')->extension(), 'public'); - } - } - - $accident->police_file_date = $request->police_file_date; - $accident->police_serial = $request->police_serial; - $accident->report_base = 0; - } - - $accident->save(); - - if ($request->has('damage_picture1')) { - \File::delete('storage/'.$accident->damage_picture1); - $accident->damage_picture1 = $request->file('damage_picture1')->storeAs('receipts_files/'.$accident->id, 'damage_picture1_'.$accident->id.'_'.time().'.'.$request->file('damage_picture1')->extension(), 'public'); - } elseif ($request->has('damage_picture1_is_delete')) { - \File::delete('storage/'.$accident->damage_picture1); - $accident->damage_picture1 = null; - } - - if ($request->has('damage_picture2')) { - \File::delete('storage/'.$accident->damage_picture2); - $accident->damage_picture2 = $request->file('damage_picture2')->storeAs('receipts_files/'.$accident->id, 'damage_picture2_'.$accident->id.'_'.time().'.'.$request->file('damage_picture2')->extension(), 'public'); - } elseif ($request->has('damage_picture2_is_delete')) { - \File::delete('storage/'.$accident->damage_picture2); - $accident->damage_picture2 = null; - } - - $accident->save(); - $sum = 0; - $accident->damages()->detach(); - foreach (json_decode($request->items_damge) as $key => $item) { - $damage = Damage::find($item->id); - $accident->damages()->attach($item->id, [ - 'value' => $item->value, - 'unit' => $damage->unit, - 'amount' => $item->amount, - ]); - $sum += $item->amount; - } - - - $ojrate_nasb = $sum/100*20; - $accident->ojrate_nasb = $ojrate_nasb; - - $sum += $ojrate_nasb; - $accident->sum = $sum; - - $accident->save(); - - auth()->user()->addActivityComplete(1124); - }); - } - - public function delete(Accident $accident) - { - \File::delete('storage/receipts_files/'.$accident->id); - - $accident->damages()->detach(); - $accident->delete(); - auth()->user()->addActivityComplete(1125); - - return $this->successResponse(); - } - - public function sendToInsurance(Request $request, Accident $accident) - { - DB::transaction(function () use ($request, $accident) { - $accident->sendToInsurance(); - $accident->save(); - - auth()->user()->addActivityComplete(1126); - }); - - $account_data = Province::query()->where('id', $accident->province_id)->first(); - - return $this->successResponse([ - $account_data, - $accident->load('damages') - ]); - } -} diff --git a/app/Http/Requests/V3/AccidentReceipt/ConfirmPaymentInfoRequest.php b/app/Http/Requests/V3/AccidentReceipt/ConfirmPaymentInfoRequest.php new file mode 100644 index 00000000..3b079953 --- /dev/null +++ b/app/Http/Requests/V3/AccidentReceipt/ConfirmPaymentInfoRequest.php @@ -0,0 +1,31 @@ +|string> + */ + public function rules(): array + { + return [ + 'deposit_insurance_image' => 'file', + 'deposit_insurance_amount' => 'required_with:deposit_insurance_image', + 'deposit_daghi_image' => 'file', + 'deposit_daghi_amount' => 'required_with:deposit_daghi_image', + ]; + } +} diff --git a/app/Models/Accident.php b/app/Models/Accident.php index 8221365b..62ef308f 100644 --- a/app/Models/Accident.php +++ b/app/Models/Accident.php @@ -5,6 +5,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use App\Traits\ReceiptReportAble; +use Illuminate\Database\Eloquent\Relations\MorphMany; class Accident extends Model { @@ -87,4 +88,8 @@ class Accident extends Model } } + public function files(): MorphMany + { + return $this->morphMany(File::class, 'fileable'); + } } diff --git a/app/Models/File.php b/app/Models/File.php new file mode 100644 index 00000000..cfafa7e9 --- /dev/null +++ b/app/Models/File.php @@ -0,0 +1,19 @@ +morphTo(); + } +} diff --git a/database/factories/FileFactory.php b/database/factories/FileFactory.php new file mode 100644 index 00000000..80144e1f --- /dev/null +++ b/database/factories/FileFactory.php @@ -0,0 +1,23 @@ + + */ +class FileFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // + ]; + } +} diff --git a/database/migrations/2025_02_22_101703_create_files_table.php b/database/migrations/2025_02_22_101703_create_files_table.php new file mode 100644 index 00000000..6af3da40 --- /dev/null +++ b/database/migrations/2025_02_22_101703_create_files_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('name')->nullable(); + $table->text('path'); + $table->morphs('fileable'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('files'); + } +}; diff --git a/database/seeders/FileSeeder.php b/database/seeders/FileSeeder.php new file mode 100644 index 00000000..67df9646 --- /dev/null +++ b/database/seeders/FileSeeder.php @@ -0,0 +1,17 @@ +name('update'); Route::post('/activate/{damage}', 'activate')->name('activate'); }); + +Route::prefix('receipts') + ->name('receipts.') + ->controller(AccidentReceiptController::class) + ->group(function () { + Route::get('/', 'index')->name('index'); + Route::post('/', 'store')->name('store'); + Route::get('/{accident}', 'show')->name('show'); + Route::post('/{accident}', 'update')->name('update'); + Route::delete('/{accident}', 'destroy')->name('destroy'); + Route::get('/generate_insurance_letter/{accident}', 'generateInsuranceLetter')->name('generateInsuranceLetter'); + Route::post('/confirm_payment_info/{accident}', 'confirmPaymentInfo')->name('confirmPaymentInfo'); + Route::get('/submit_invoice/{accident}', 'submitInvoice')->name('submitInvoice'); + Route::get('/check_payment_status/{accident}', 'checkPaymentStatus')->name('checkPaymentStatus'); + Route::get('/generate_police_document/{accident}', 'generatePoliceDocument')->name('generatePoliceDocument'); + }); From e6930f2dfec70a46290eb461fab75dbd5e66dbed Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 22 Feb 2025 15:31:12 +0330 Subject: [PATCH 6/9] create receipt report logic --- app/Exports/V3/AccidentReceipt/CityReport.php | 79 +++++++++++++ .../V3/AccidentReceipt/DataTableReport.php | 75 +++++++++++++ .../V3/AccidentReceipt/ProvinceReport.php | 78 +++++++++++++ .../Dashboard/AccidentReceiptController.php | 67 +++++------ .../AccidentReceiptReportController.php | 44 ++++++++ .../Reports/RoadItemsReportController.php | 34 +++--- .../Reports/RoadPatrolReportController.php | 18 +-- .../Dashboard/RoadItemsProjectController.php | 18 +-- .../Dashboard/RoadPatrolProjectController.php | 18 +-- .../V3/AccidentReceipt/StoreRequest.php | 47 ++++++++ .../V3/AccidentReceipt/UpdateRequest.php | 45 ++++++++ .../Cartables/AccidentReceiptTableService.php | 106 ++++++++++++++++++ .../RoadItemTableService.php} | 4 +- .../RoadPatrolTableService.php} | 4 +- routes/v3.php | 14 ++- 15 files changed, 565 insertions(+), 86 deletions(-) create mode 100644 app/Exports/V3/AccidentReceipt/CityReport.php create mode 100644 app/Exports/V3/AccidentReceipt/DataTableReport.php create mode 100644 app/Exports/V3/AccidentReceipt/ProvinceReport.php create mode 100644 app/Http/Controllers/V3/Dashboard/Reports/AccidentReceiptReportController.php create mode 100644 app/Http/Requests/V3/AccidentReceipt/StoreRequest.php create mode 100644 app/Http/Requests/V3/AccidentReceipt/UpdateRequest.php create mode 100644 app/Services/Cartables/AccidentReceiptTableService.php rename app/Services/{Reports/RoadItemReportService.php => Cartables/RoadItemTableService.php} (99%) rename app/Services/{Reports/RoadPatrolReportService.php => Cartables/RoadPatrolTableService.php} (99%) diff --git a/app/Exports/V3/AccidentReceipt/CityReport.php b/app/Exports/V3/AccidentReceipt/CityReport.php new file mode 100644 index 00000000..db40c177 --- /dev/null +++ b/app/Exports/V3/AccidentReceipt/CityReport.php @@ -0,0 +1,79 @@ +data; + + return view('v3.AccidentReceipt.CityReport', [ + 'data' => $data['data'], + 'fromDate' => $data['fromDate'], + 'ToDate' => $data['ToDate'], + ]); + } + + /** + * @return array + */ + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + }, + ]; + } + + public function drawings() + { + $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) + { + return [ + // Style the first row as bold text. + 'A:BA' => [ + 'font' => [ + 'name' => 'B Nazanin' + ] + ], + ]; + } +} diff --git a/app/Exports/V3/AccidentReceipt/DataTableReport.php b/app/Exports/V3/AccidentReceipt/DataTableReport.php new file mode 100644 index 00000000..ba9bed37 --- /dev/null +++ b/app/Exports/V3/AccidentReceipt/DataTableReport.php @@ -0,0 +1,75 @@ + $this->data, + ]); + } + + /** + * @return array + */ + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + }, + ]; + } + + public function drawings() + { + $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) + { + return [ + // Style the first row as bold text. + 'A:BA' => [ + 'font' => [ + 'name' => 'B Nazanin' + ] + ], + ]; + } +} diff --git a/app/Exports/V3/AccidentReceipt/ProvinceReport.php b/app/Exports/V3/AccidentReceipt/ProvinceReport.php new file mode 100644 index 00000000..9eee4900 --- /dev/null +++ b/app/Exports/V3/AccidentReceipt/ProvinceReport.php @@ -0,0 +1,78 @@ +data; + return view('v3.AccidentReceipt.ProvinceReport', [ + 'data' => $data['data'], + 'fromDate' => $data['fromDate'], + 'ToDate' => $data['ToDate'], + ]); + } + + /** + * @return array + */ + public function registerEvents(): array + { + return [ + AfterSheet::class => function (AfterSheet $event) { + $event->sheet->getDelegate()->setRightToLeft(true); + }, + ]; + } + + public function drawings() + { + $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) + { + return [ + // Style the first row as bold text. + 'A:BA' => [ + 'font' => [ + 'name' => 'B Nazanin' + ] + ], + ]; + } +} diff --git a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php index 518d2816..6bbe9280 100644 --- a/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php +++ b/app/Http/Controllers/V3/Dashboard/AccidentReceiptController.php @@ -3,66 +3,57 @@ namespace App\Http\Controllers\V3\Dashboard; use App\Enums\AccidentStates; +use App\Exports\V3\AccidentReceipt\DataTableReport; use App\Facades\DataTable\DataTableFacade; use App\Facades\File\FileFacade; use App\Facades\Sms\Sms; use App\Http\Controllers\Controller; use App\Http\Requests\V3\AccidentReceipt\ConfirmPaymentInfoRequest; +use App\Http\Requests\V3\AccidentReceipt\StoreRequest; +use App\Http\Requests\V3\AccidentReceipt\UpdateRequest; use App\Http\Traits\ApiResponse; use App\Models\Accident; use App\Models\City; use App\Models\DailyAccidentSettings; use App\Models\Damage; use App\Models\Province; +use App\Services\Cartables\AccidentReceiptTableService; use App\Services\NominatimService; use App\Services\PaymentService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; +use Maatwebsite\Excel\Facades\Excel; +use Symfony\Component\HttpFoundation\BinaryFileResponse; class AccidentReceiptController extends Controller { use ApiResponse; - public function index(Request $request): JsonResponse + public function index(Request $request, AccidentReceiptTableService $accidentReceiptTableService): JsonResponse { - $allowedFilters = ['*']; - $allowedSortings = ['*']; + $data = $accidentReceiptTableService->dataTable($request); - $user = auth()->user(); - $query = null; - - if ($user->hasPermissionTo('show-receipt')) { - $query = Accident::query(); - } - else { - if (is_null($user->province_id)) { - return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); - } - - $query = Accident::query()->where('province_id', '=', $user->province_id); - } - - $data = DataTableFacade::run( - $query, - $request, - allowedFilters: $allowedFilters, - allowedSortings: $allowedSortings - ); - - - $user->addActivityComplete(1122); + auth()->user()->addActivityComplete(1122); return response()->json($data); } + public function excelReport(Request $request, AccidentReceiptTableService $accidentReceiptTableService): BinaryFileResponse + { + auth()->user()->addActivityComplete(1126); + $name = 'گزارش از خسارات وارده به ابنیه فنی و تاسیسات راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + $data = $accidentReceiptTableService->dataTable($request); + return Excel::download(new DataTableReport($data), $name); + } + public function accidentDamage(Accident $accident): JsonResponse { return $this->successResponse($accident->damages()->get(['unit', 'amount', 'value'])); } - public function store(Request $request, NominatimService $nominatimService): JsonResponse + public function store(StoreRequest $request, NominatimService $nominatimService): JsonResponse { DB::transaction(function () use ($request, $nominatimService) { @@ -150,7 +141,7 @@ class AccidentReceiptController extends Controller return $this->successResponse($accident->load('damages')); } - public function update(Accident $accident, Request $request, NominatimService $nominatimService): JsonResponse + public function update(Accident $accident, UpdateRequest $request, NominatimService $nominatimService): JsonResponse { DB::transaction(function () use ($request, $accident, $nominatimService) { @@ -213,7 +204,6 @@ class AccidentReceiptController extends Controller $sum += $item->amount; } - $ojrate_nasb = $sum/100*20; $sum += $ojrate_nasb; @@ -267,10 +257,10 @@ class AccidentReceiptController extends Controller DB::transaction(function () use ($request, $accident) { if ($request->has('deposit_insurance_status')) { if ($request->has('deposit_insurance_image')) { - $accident->deposit_insurance_image = $request->file('deposit_insurance_image')->storeAs('receipts_files/'.$accident->id, 'deposit_insurance_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_insurance_image')->extension(), 'public'); + $deposit_insurance_image = $request->file('deposit_insurance_image')->storeAs('receipts_files/'.$accident->id, 'deposit_insurance_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_insurance_image')->extension(), 'public'); } - $accident->deposit_insurance_amount = $request->deposit_insurance_amount; + $deposit_insurance_amount = $request->deposit_insurance_amount; } else { $accident->deposit_insurance_image = null; $accident->deposit_insurance_amount = null; @@ -278,16 +268,20 @@ class AccidentReceiptController extends Controller if ($request->has('deposit_daghi_status')) { if ($request->has('deposit_daghi_image')) { - $accident->deposit_daghi_image = $request->file('deposit_daghi_image')->storeAs('receipts_files/'.$accident->id, 'deposit_daghi_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_daghi_image')->extension(), 'public'); + $deposit_daghi_image = $request->file('deposit_daghi_image')->storeAs('receipts_files/'.$accident->id, 'deposit_daghi_image_'.$accident->id.'_'.time().'.'.$request->file('deposit_daghi_image')->extension(), 'public'); } - $accident->deposit_daghi_amount = $request->deposit_daghi_amount; + $deposit_daghi_amount = $request->deposit_daghi_amount; } else { $accident->deposit_daghi_image = null; $accident->deposit_daghi_amount = null; } $accident->update([ + 'deposit_insurance_image' => $deposit_insurance_image, + 'deposit_insurance_amount' => $deposit_insurance_amount, + 'deposit_daghi_image' => $deposit_daghi_image, + 'deposit_daghi_amount' => $deposit_daghi_amount, 'status' => AccidentStates::SABT_FISH->value, 'status_fa' => AccidentStates::name(AccidentStates::SABT_FISH->value), ]); @@ -308,11 +302,11 @@ class AccidentReceiptController extends Controller return $this->errorResponse('error'); } - $accident->final_amount = $final_amount; - - $accident->bill_code = $paymentService->invoiceBillApi($accident->driver_national_code, $final_amount); + $bill_code = $paymentService->invoiceBillApi($accident->driver_national_code, $final_amount); $accident->update([ + 'final_amount' => $final_amount, + 'bill_code' => $bill_code, 'status' => AccidentStates::SODOR_FACTOR->value, 'status_fa' => AccidentStates::name(AccidentStates::SODOR_FACTOR->value), ]); @@ -367,7 +361,6 @@ class AccidentReceiptController extends Controller auth()->user()->addActivityComplete(1131); }); - return $this->successResponse(); } } diff --git a/app/Http/Controllers/V3/Dashboard/Reports/AccidentReceiptReportController.php b/app/Http/Controllers/V3/Dashboard/Reports/AccidentReceiptReportController.php new file mode 100644 index 00000000..3f07d6f9 --- /dev/null +++ b/app/Http/Controllers/V3/Dashboard/Reports/AccidentReceiptReportController.php @@ -0,0 +1,44 @@ +provinceReport($request); + return $this->successResponse($data['data']); + } + + public function cityReport(Request $request, AccidentReceiptTableService $accidentReceiptTableService): JsonResponse + { + $data = $accidentReceiptTableService->cityReport($request); + return $this->successResponse($data['data']); + } + + public function provinceExcelReport(Request $request, AccidentReceiptTableService $accidentReceiptTableService): BinaryFileResponse + { + $data = $accidentReceiptTableService->provinceReport($request); + $name = 'گزارش از خسارات وارده به ابنیه فنی و تاسیسات راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + return Excel::download(new ProvinceReport($data), $name); + } + + public function cityExcelReport(Request $request, AccidentReceiptTableService $accidentReceiptTableService): BinaryFileResponse + { + $data = $accidentReceiptTableService->cityReport($request); + $name = 'گزارش از خسارات وارده به ابنیه فنی و تاسیسات راه ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; + return Excel::download(new CityReport($data), $name); + } +} diff --git a/app/Http/Controllers/V3/Dashboard/Reports/RoadItemsReportController.php b/app/Http/Controllers/V3/Dashboard/Reports/RoadItemsReportController.php index 70d15be0..46b47699 100644 --- a/app/Http/Controllers/V3/Dashboard/Reports/RoadItemsReportController.php +++ b/app/Http/Controllers/V3/Dashboard/Reports/RoadItemsReportController.php @@ -12,7 +12,7 @@ use App\Models\EdarateShahri; use App\Models\InfoItem; use App\Models\Province; use App\Models\RoadItemsProject; -use App\Services\Reports\RoadItemReportService; +use App\Services\Cartables\RoadItemTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Maatwebsite\Excel\Facades\Excel; @@ -32,9 +32,9 @@ class RoadItemsReportController extends Controller ]); } - public function countryActivityPerSubItem(Request $request, RoadItemReportService $roadItemReportService): JsonResponse + public function countryActivityPerSubItem(Request $request, RoadItemTableService $roadItemTableService): JsonResponse { - $activities = $roadItemReportService->countryActivityPerSubItem($request); + $activities = $roadItemTableService->countryActivityPerSubItem($request); $provinces = Province::all(['id', 'name_fa']); $subItems = InfoItem::query() ->where('item', $request->item) @@ -47,9 +47,9 @@ class RoadItemsReportController extends Controller ]); } - public function provinceActivityPerSubItem(Request $request, RoadItemReportService $roadItemReportService): JsonResponse + public function provinceActivityPerSubItem(Request $request, RoadItemTableService $roadItemTableService): JsonResponse { - $activities = $roadItemReportService->provinceActivityPerSubItem($request); + $activities = $roadItemTableService->provinceActivityPerSubItem($request); $edarateShahri = EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']); @@ -64,13 +64,13 @@ class RoadItemsReportController extends Controller ]); } - public function countryActivityPerItem(Request $request, RoadItemReportService $roadItemReportService): JsonResponse + public function countryActivityPerItem(Request $request, RoadItemTableService $roadItemTableService): JsonResponse { if (auth()->check()) { auth()->user()->addActivityComplete(1033); } - $activities = $roadItemReportService->countryActivityPerItem($request); + $activities = $roadItemTableService->countryActivityPerItem($request); $provinces = Province::all(['id', 'name_fa']); return $this->successResponse([ @@ -79,9 +79,9 @@ class RoadItemsReportController extends Controller ]); } - public function provinceActivityPerItem(Request $request, RoadItemReportService $roadItemReportService): JsonResponse + public function provinceActivityPerItem(Request $request, RoadItemTableService $roadItemTableService): JsonResponse { - $activities = $roadItemReportService->provinceActivityPerItem($request); + $activities = $roadItemTableService->provinceActivityPerItem($request); $edarateShahri = EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']); return $this->successResponse([ @@ -90,11 +90,11 @@ class RoadItemsReportController extends Controller ]); } - public function countryActivityExcelPerItem(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse + public function countryActivityExcelPerItem(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse { auth()->user()->addActivityComplete(1034); $name = 'گزارش کشوری از فعالیت روزانه و جاری - جدول 1 ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; - $activities = $roadItemReportService->countryActivityPerItem($request); + $activities = $roadItemTableService->countryActivityPerItem($request); return Excel::download(new CountryActivityPerItemReport([ 'activities' => $activities, 'provinces' => Province::all(['id', 'name_fa']), @@ -102,11 +102,11 @@ class RoadItemsReportController extends Controller ]), $name); } - public function provinceActivityExcelPerItem(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse + public function provinceActivityExcelPerItem(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse { auth()->user()->addActivityComplete(1034); $name = 'گزارش استانی از فعالیت روزانه و جاری - جدول 1 ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; - $activities = $roadItemReportService->provinceActivityPerItem($request); + $activities = $roadItemTableService->provinceActivityPerItem($request); return Excel::download(new ProvinceActivityPerItemReport([ 'activities' => $activities, 'edarateShahri' => EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']), @@ -114,11 +114,11 @@ class RoadItemsReportController extends Controller ]), $name); } - public function countryActivityExcelPerSubItem(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse + public function countryActivityExcelPerSubItem(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse { auth()->user()->addActivityComplete(1034); $name = "گزارش کشوری از فعالیت روزانه و جاری - جدول 2 " . verta()->now()->format('Y-m-d H-i') . '.xlsx'; - $activities = $roadItemReportService->countryActivityPerSubItem($request); + $activities = $roadItemTableService->countryActivityPerSubItem($request); $subItems = InfoItem::query() ->where('item', $request->item) ->get(['id', 'item', 'item_str', 'sub_item_str', 'sub_item_unit', 'sub_item']); @@ -130,10 +130,10 @@ class RoadItemsReportController extends Controller ]), $name); } - public function provinceActivityExcelPerSubItem(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse + public function provinceActivityExcelPerSubItem(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse { auth()->user()->addActivityComplete(1034); - $activities = $roadItemReportService->provinceActivityPerSubItem($request); + $activities = $roadItemTableService->provinceActivityPerSubItem($request); $name = "گزارش استانی از فعالیت روزانه و جاری - جدول 2 " . verta()->now()->format('Y-m-d H-i') . '.xlsx'; $subItems = InfoItem::query() ->where('item', $request->item) diff --git a/app/Http/Controllers/V3/Dashboard/Reports/RoadPatrolReportController.php b/app/Http/Controllers/V3/Dashboard/Reports/RoadPatrolReportController.php index 9f485e05..d4382427 100644 --- a/app/Http/Controllers/V3/Dashboard/Reports/RoadPatrolReportController.php +++ b/app/Http/Controllers/V3/Dashboard/Reports/RoadPatrolReportController.php @@ -10,7 +10,7 @@ use App\Models\EdarateShahri; use App\Models\Province; use App\Models\RoadObserved; use App\Models\RoadPatrol; -use App\Services\Reports\RoadPatrolReportService; +use App\Services\Cartables\RoadPatrolTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Maatwebsite\Excel\Facades\Excel; @@ -19,9 +19,9 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse; class RoadPatrolReportController extends Controller { use ApiResponse; - public function countryPatrolActivity(Request $request, RoadPatrolReportService $roadPatrolReportService): JsonResponse + public function countryPatrolActivity(Request $request, RoadPatrolTableService $roadPatrolTableService): JsonResponse { - $activities = $roadPatrolReportService->countryActivity($request); + $activities = $roadPatrolTableService->countryActivity($request); $provinces = Province::all(['id', 'name_fa']); @@ -31,11 +31,11 @@ class RoadPatrolReportController extends Controller ]); } - public function provincePatrolActivity(Request $request, RoadPatrolReportService $roadPatrolReportService): JsonResponse + public function provincePatrolActivity(Request $request, RoadPatrolTableService $roadPatrolTableService): JsonResponse { $request->validate(["province_id" => "required",]); - $activities = $roadPatrolReportService->provinceActivity($request); + $activities = $roadPatrolTableService->provinceActivity($request); $edarateShahri = EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']); @@ -45,9 +45,9 @@ class RoadPatrolReportController extends Controller ]); } - public function countryActivityExcel(Request $request, RoadPatrolReportService $roadPatrolReportService): BinaryFileResponse + public function countryActivityExcel(Request $request, RoadPatrolTableService $roadPatrolTableService): BinaryFileResponse { - $activities = $roadPatrolReportService->countryActivity($request); + $activities = $roadPatrolTableService->countryActivity($request); $provinces = Province::all(['id', 'name_fa']); $name = 'گزارش از گشت راهداری و ترابری ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; @@ -58,9 +58,9 @@ class RoadPatrolReportController extends Controller ]), $name); } - public function provinceActivityExcel(Request $request, RoadPatrolReportService $roadPatrolReportService): BinaryFileResponse + public function provinceActivityExcel(Request $request, RoadPatrolTableService $roadPatrolTableService): BinaryFileResponse { - $activities = $roadPatrolReportService->provinceActivity($request); + $activities = $roadPatrolTableService->provinceActivity($request); $edarateShahri = EdarateShahri::query()->where('province_id', '=', $request->province_id)->get(['id', 'name_fa']); $name = 'گزارش از گشت راهداری و ترابری ' . verta()->now()->format('Y-m-d H-i') . '.xlsx'; diff --git a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php index 0cf834d3..bcb9e6fb 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadItemsProjectController.php @@ -13,7 +13,7 @@ use App\Models\EdarateShahri; use App\Models\InfoItem; use App\Models\RoadItemsProject; use App\Services\NominatimService; -use App\Services\Reports\RoadItemReportService; +use App\Services\Cartables\RoadItemTableService; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Gate; @@ -28,9 +28,9 @@ class RoadItemsProjectController extends Controller /** * Display a listing of the resource. */ - public function supervisorIndex(Request $request, RoadItemReportService $roadItemReportService): JsonResponse + public function supervisorIndex(Request $request, RoadItemTableService $roadItemTableService): JsonResponse { - $data = $roadItemReportService->supervisorCartableReport($request); + $data = $roadItemTableService->supervisorCartableReport($request); foreach ($data['data'] as $road_item) { if (Gate::allows('gate-supervise-road-item', $road_item)) { @@ -96,16 +96,16 @@ class RoadItemsProjectController extends Controller } - public function supervisorCartableReport(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse + public function supervisorCartableReport(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse { $name = 'گزارش از کارتابل ارزیابی فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadItemReportService->supervisorCartableReport($request, true); + $data = $roadItemTableService->supervisorCartableReport($request, true); return Excel::download(new SupervisorCartableReport($data['data']), $name); } - public function operatorIndex(Request $request, RoadItemReportService $roadItemReportService): JsonResponse + public function operatorIndex(Request $request, RoadItemTableService $roadItemTableService): JsonResponse { - $data = $roadItemReportService->operatorCartableReport($request); + $data = $roadItemTableService->operatorCartableReport($request); return response()->json($data); } @@ -264,10 +264,10 @@ class RoadItemsProjectController extends Controller return $this->successResponse(); } - public function operatorCartableReport(Request $request, RoadItemReportService $roadItemReportService): BinaryFileResponse + public function operatorCartableReport(Request $request, RoadItemTableService $roadItemTableService): BinaryFileResponse { $name = 'گزارش از کارتابل عملیات فعالیت روزانه ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadItemReportService->operatorCartableReport($request, true); + $data = $roadItemTableService->operatorCartableReport($request, true); return Excel::download(new OperatorCartableReport($data['data']), $name); } diff --git a/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php b/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php index dd1f9f32..98550c02 100644 --- a/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php +++ b/app/Http/Controllers/V3/Dashboard/RoadPatrolProjectController.php @@ -15,7 +15,7 @@ use App\Models\RoadItemsProject; use App\Models\RoadObserved; use App\Models\RoadPatrol; use App\Services\NominatimService; -use App\Services\Reports\RoadPatrolReportService; +use App\Services\Cartables\RoadPatrolTableService; use Carbon\Carbon; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -30,9 +30,9 @@ class RoadPatrolProjectController extends Controller { use ApiResponse; - public function supervisorIndex(Request $request, RoadPatrolReportService $roadPatrolReportService): JsonResponse + public function supervisorIndex(Request $request, RoadPatrolTableService $roadPatrolTableService): JsonResponse { - $data = $roadPatrolReportService->supervisorCartableReport($request); + $data = $roadPatrolTableService->supervisorCartableReport($request); foreach ($data['data'] as $road_patrol) { if (Gate::allows('gate-supervise-road-item', $road_patrol)) { @@ -80,16 +80,16 @@ class RoadPatrolProjectController extends Controller return $this->successResponse(); } - public function supervisorCartableReport(Request $request, RoadPatrolReportService $roadPatrolReportService): BinaryFileResponse + public function supervisorCartableReport(Request $request, RoadPatrolTableService $roadPatrolTableService): BinaryFileResponse { $name = 'گزارش از کارتابل ارزیابی گشت راهداری ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadPatrolReportService->supervisorCartableReport($request, true); + $data = $roadPatrolTableService->supervisorCartableReport($request, true); return Excel::download(new SupervisorCartableReport($data['data']), $name); } - public function operatorIndex(Request $request, RoadPatrolReportService $roadPatrolReportService): JsonResponse + public function operatorIndex(Request $request, RoadPatrolTableService $roadPatrolTableService): JsonResponse { - $data = $roadPatrolReportService->operatorCartableReport($request); + $data = $roadPatrolTableService->operatorCartableReport($request); return response()->json($data); } @@ -322,10 +322,10 @@ class RoadPatrolProjectController extends Controller return $this->successResponse($roadPatrol); } - public function operatorCartableReport(Request $request, RoadPatrolReportService $roadPatrolReportService): BinaryFileResponse + public function operatorCartableReport(Request $request, RoadPatrolTableService $roadPatrolTableService): BinaryFileResponse { $name = 'گزارش از کارتابل عملیات گشت راهداری ' . verta()->now()->format('Y-m-d H:i') . '.xlsx'; - $data = $roadPatrolReportService->operatorCartableReport($request, true); + $data = $roadPatrolTableService->operatorCartableReport($request, true); return Excel::download(new OperatorCartableReport($data['data']), $name); } diff --git a/app/Http/Requests/V3/AccidentReceipt/StoreRequest.php b/app/Http/Requests/V3/AccidentReceipt/StoreRequest.php new file mode 100644 index 00000000..b5b5627f --- /dev/null +++ b/app/Http/Requests/V3/AccidentReceipt/StoreRequest.php @@ -0,0 +1,47 @@ +|string> + */ + public function rules(): array + { + return [ + 'province_id' => 'required|integer|exists:provinces,id', + 'city_id' => 'required|integer|exists:cities,id', + 'axis_name' => 'required|string', + 'driver_name' => 'required|string', + 'plaque' => 'required|string', + 'driver_national_code' => 'required|string', + 'driver_phone_number' => 'required|string', + 'lat' => 'required|numeric', + 'lng' => 'required|numeric', + 'accident_type' => 'required|integer', + 'accident_date' => 'required|date', + 'accident_time' => 'required|string', + 'report_base' => 'required|in:0,1', + 'police_file' => 'required_if:report_base,0|file|mimes:pdf,jpg,jpeg,png', + 'police_serial' => 'required_if:report_base,0|string', + 'police_file_date' => 'required_if:report_base,0|date', + 'damage_picture1' => 'required|file|mimes:pdf,jpg,jpeg,png', + 'damage_picture2' => 'required|file|mimes:pdf,jpg,jpeg,png', + ]; + } +} diff --git a/app/Http/Requests/V3/AccidentReceipt/UpdateRequest.php b/app/Http/Requests/V3/AccidentReceipt/UpdateRequest.php new file mode 100644 index 00000000..c5219237 --- /dev/null +++ b/app/Http/Requests/V3/AccidentReceipt/UpdateRequest.php @@ -0,0 +1,45 @@ +|string> + */ + public function rules(): array + { + return [ + 'province_id' => 'required|integer|exists:provinces,id', + 'city_id' => 'required|integer|exists:cities,id', + 'axis_name' => 'required|string', + 'driver_name' => 'required|string', + 'plaque' => 'required|string', + 'driver_national_code' => 'required|string', + 'driver_phone_number' => 'required|string', + 'lat' => 'required|numeric', + 'lng' => 'required|numeric', + 'accident_type' => 'required|integer', + 'accident_date' => 'required|date', + 'accident_time' => 'required|string', + 'report_base' => 'required|in:0,1', + 'police_file' => 'required_if:report_base,0|file|mimes:pdf,jpg,jpeg,png', + 'police_serial' => 'required_if:report_base,0|string', + 'police_file_date' => 'required_if:report_base,0|date', + 'damage_picture1' => 'required|file|mimes:pdf,jpg,jpeg,png', + 'damage_picture2' => 'required|file|mimes:pdf,jpg,jpeg,png', + ]; + } +} diff --git a/app/Services/Cartables/AccidentReceiptTableService.php b/app/Services/Cartables/AccidentReceiptTableService.php new file mode 100644 index 00000000..6831f918 --- /dev/null +++ b/app/Services/Cartables/AccidentReceiptTableService.php @@ -0,0 +1,106 @@ +user(); + $query = null; + + if ($user->hasPermissionTo('show-receipt')) { + $query = Accident::query(); + } + else { + if (is_null($user->province_id)) { + return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); + } + + $query = Accident::query()->where('province_id', '=', $user->province_id); + } + + return DataTableFacade::run( + $query, + $request, + allowedFilters: ['*'], + allowedSortings: ['*'] + ); + } + + public function provinceReport(Request $request): array + { + $data = DB::select( + 'SELECT + "کشوری" as province_fa, + -1 as province_id, + COUNT(id) AS tedade, + COUNT(CASE WHEN report_base = 0 THEN 1 END) AS police_rah, + COUNT(CASE WHEN report_base = 1 THEN 1 END) AS gozaresh_gasht, + SUM(`sum`) AS kol_sabt_shode, + SUM(CASE WHEN STATUS > 3 THEN `sum` END) AS vasel_shode, + SUM(CASE WHEN STATUS > 3 THEN `deposit_insurance_amount` END) AS vasel_shode_bimeh, + SUM(CASE WHEN STATUS > 3 THEN `deposit_daghi_amount` END) AS vasel_shode_daghi, + SUM(CASE WHEN STATUS > 3 THEN `final_amount` END) AS vasel_shode_final + FROM `accidents` + where created_at BETWEEN "'.$request->from_date.'" AND "'.$request->date_to.'" + union + SELECT + province_fa, + province_id, + COUNT(id) AS tedade, + COUNT(CASE WHEN report_base = 0 THEN 1 END) AS police_rah, + COUNT(CASE WHEN report_base = 1 THEN 1 END) AS gozaresh_gasht, + SUM(`sum`) AS kol_sabt_shode, + SUM(CASE WHEN STATUS > 3 THEN `sum` END) AS vasel_shode, + SUM(CASE WHEN STATUS > 3 THEN `deposit_insurance_amount` END) AS vasel_shode_bimeh, + SUM(CASE WHEN STATUS > 3 THEN `deposit_daghi_amount` END) AS vasel_shode_daghi, + SUM(CASE WHEN STATUS > 3 THEN `final_amount` END) AS vasel_shode_final + FROM `accidents` + where created_at BETWEEN "'.$request->from_date.'" AND "'.$request->date_to.'" + GROUP BY province_id + ' + ); + + return [ + 'data' => collect($data), + 'fromDate' => $request->from_date, + 'toDate' => $request->date_to, + ]; + } + + public function cityReport(Request $request): array + { + $data = DB::select( + 'SELECT + city_fa, + city_id, + COUNT(id) AS tedade, + COUNT(CASE WHEN report_base = 0 THEN 1 END) AS police_rah, + COUNT(CASE WHEN report_base = 1 THEN 1 END) AS gozaresh_gasht, + SUM(`sum`) AS kol_sabt_shode, + SUM(CASE WHEN STATUS > 3 THEN `sum` END) AS vasel_shode, + SUM(CASE WHEN STATUS > 3 THEN `deposit_insurance_amount` END) AS vasel_shode_bimeh, + SUM(CASE WHEN STATUS > 3 THEN `deposit_daghi_amount` END) AS vasel_shode_daghi, + SUM(CASE WHEN STATUS > 3 THEN `final_amount` END) AS vasel_shode_final + FROM `accidents` + where created_at BETWEEN "'.$request->from_date.'" AND "'.$request->date_to.'" AND province_id ='.$request->province_id.' + GROUP BY city_id + ' + ); + + return [ + 'data' => collect($data), + 'fromDate' => $request->from_date, + 'toDate' => $request->date_to, + ]; + } +} diff --git a/app/Services/Reports/RoadItemReportService.php b/app/Services/Cartables/RoadItemTableService.php similarity index 99% rename from app/Services/Reports/RoadItemReportService.php rename to app/Services/Cartables/RoadItemTableService.php index 6f8551ed..c0a929fd 100644 --- a/app/Services/Reports/RoadItemReportService.php +++ b/app/Services/Cartables/RoadItemTableService.php @@ -1,6 +1,6 @@ name('receipts.') ->controller(AccidentReceiptController::class) ->group(function () { - Route::get('/', 'index')->name('index'); + Route::get('/', 'index')->name('index'); + Route::get('/excel_report', 'excelReport')->name('excelReport'); Route::post('/', 'store')->name('store'); Route::get('/{accident}', 'show')->name('show'); Route::post('/{accident}', 'update')->name('update'); @@ -252,3 +254,13 @@ Route::prefix('receipts') Route::get('/check_payment_status/{accident}', 'checkPaymentStatus')->name('checkPaymentStatus'); Route::get('/generate_police_document/{accident}', 'generatePoliceDocument')->name('generatePoliceDocument'); }); + +Route::prefix('receipt_reports') + ->name('receiptReports.') + ->controller(ReceiptReportController::class) + ->group(function () { + Route::get('/province_report', 'provinceReport')->name('provinceReport'); + Route::get('/city_report', 'cityReport')->name('cityReport'); + Route::get('/province_excel_report', 'provinceExcelReport')->name('provinceExcelReport'); + Route::get('/city_excel_report', 'cityExcelReport')->name('cityExcelReport'); + }); From 0b8b0cef02be4bf20e771c97985041c850cfe0c4 Mon Sep 17 00:00:00 2001 From: amirghasempoor Date: Sat, 22 Feb 2025 16:02:19 +0330 Subject: [PATCH 7/9] select required columns --- app/Services/Cartables/RoadPatrolTableService.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/Services/Cartables/RoadPatrolTableService.php b/app/Services/Cartables/RoadPatrolTableService.php index 76f2b6dd..c6f38395 100644 --- a/app/Services/Cartables/RoadPatrolTableService.php +++ b/app/Services/Cartables/RoadPatrolTableService.php @@ -19,7 +19,10 @@ class RoadPatrolTableService if ($user->hasPermissionTo('show-road-patrol-supervise-cartable')) { $query = RoadPatrol::query() - ->select([]) + ->select([ + 'province_fa', 'province_id', 'id', 'edare_id', 'edare_name', 'start_time', 'end_time', 'created_at', 'description', + 'distance', 'vehicle_runtime', 'fuel_consumption', 'stop_points,' + ]) ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); } elseif ($user->hasPermissionTo('show-road-patrol-supervise-cartable-province')) { @@ -27,7 +30,10 @@ class RoadPatrolTableService return $this->errorResponse('استانی برای شما در سامانه ثبت نشده است!'); } $query = RoadPatrol::query() - ->select([]) + ->select([ + 'province_fa', 'province_id', 'id', 'edare_id', 'edare_name', 'start_time', 'end_time', 'created_at', 'description', + 'distance', 'vehicle_runtime', 'fuel_consumption', 'stop_points,' + ]) ->where('province_id', '=', $user->province_id) ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); } @@ -47,7 +53,10 @@ class RoadPatrolTableService $allowedSortings = ['*']; $query = RoadPatrol::query() - ->select([]) + ->select([ + 'province_fa', 'province_id', 'id', 'edare_id', 'edare_name', 'start_time', 'end_time', 'created_at', 'description', + 'distance', 'vehicle_runtime', 'fuel_consumption', 'stop_points,' + ]) ->where('operator_id', '=', auth()->user()->id) ->when($loadRelations, fn ($query) => $query->with(['rahdaran:id,name,code', 'cmmsMachines:id,machine_code,car_name,plak_number'])); From 32630f64006a2776d3634f054139268c972ebf23 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Sat, 22 Feb 2025 17:10:14 +0330 Subject: [PATCH 8/9] crate file test for damage and fix update request and add 2 option in validation --- app/Http/Requests/V3/Damage/UpdateRequest.php | 2 +- resources/lang/fa/validation.php | 2 + tests/Feature/V3/Damage/ActivateTest.php | 12 ++ tests/Feature/V3/Damage/IndexTest.php | 66 +++++++ tests/Feature/V3/Damage/ListTest.php | 43 +++++ tests/Feature/V3/Damage/ShowTest.php | 59 ++++++ tests/Feature/V3/Damage/StoreTest.php | 156 +++++++++++++++ tests/Feature/V3/Damage/UpdateTest.php | 180 ++++++++++++++++++ 8 files changed, 519 insertions(+), 1 deletion(-) create mode 100644 tests/Feature/V3/Damage/ActivateTest.php create mode 100644 tests/Feature/V3/Damage/IndexTest.php create mode 100644 tests/Feature/V3/Damage/ListTest.php create mode 100644 tests/Feature/V3/Damage/ShowTest.php create mode 100644 tests/Feature/V3/Damage/StoreTest.php create mode 100644 tests/Feature/V3/Damage/UpdateTest.php diff --git a/app/Http/Requests/V3/Damage/UpdateRequest.php b/app/Http/Requests/V3/Damage/UpdateRequest.php index 70b0833a..8021f716 100644 --- a/app/Http/Requests/V3/Damage/UpdateRequest.php +++ b/app/Http/Requests/V3/Damage/UpdateRequest.php @@ -25,7 +25,7 @@ class UpdateRequest extends FormRequest return [ 'title' =>['required', 'string', 'max:255',Rule::unique('damages','title')->ignore($this->damage->id)], 'unit' =>'required|string', - 'base_price' =>'required|numeric', + 'base_price' =>'required|integer', ]; } } diff --git a/resources/lang/fa/validation.php b/resources/lang/fa/validation.php index 0f2de9dc..7f8bc492 100644 --- a/resources/lang/fa/validation.php +++ b/resources/lang/fa/validation.php @@ -202,5 +202,7 @@ return [ 'fields.*.option' => 'گزینه های فیلد', 'cmms_machine_id' => 'کد یکتا ماشین', 'contract_subitem_id' => 'کد یکتای پروژه', + 'base_price' => 'قیمت پایه', + 'unit' => 'واحد' ], ]; diff --git a/tests/Feature/V3/Damage/ActivateTest.php b/tests/Feature/V3/Damage/ActivateTest.php new file mode 100644 index 00000000..97678b63 --- /dev/null +++ b/tests/Feature/V3/Damage/ActivateTest.php @@ -0,0 +1,12 @@ +create(); + $response = $this->actingAs($user)->getJson(route('v3.damages.index')); + $response->assertForbidden(); + } + + public function test_user_cannot_access_authentication(): void + { + $response = $this->getJson(route('v3.damages.index')); + $response->assertStatus(401); + } + + public function test_all_damages_returned_successfully_for_index(): void + { + + $user = User::factory() + ->has(factory: Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + + Damage::factory()->count(5)->create(); + + $response = $this->actingAs($user)->getJson(route('v3.damages.index', [ + 'start' => 0, + 'size' => 10, + 'filters' => json_encode([]), + 'sorting' => json_encode([]), + ])); + $response->assertOk(); + $response->assertJsonStructure([ + 'data' => [ + '*' => [ + 'id', + 'title', + 'unit', + 'base_price', + 'status', + ], + ], + 'meta' => [ + 'totalRowCount', + ], + ]); + } +} diff --git a/tests/Feature/V3/Damage/ListTest.php b/tests/Feature/V3/Damage/ListTest.php new file mode 100644 index 00000000..ba71e7d6 --- /dev/null +++ b/tests/Feature/V3/Damage/ListTest.php @@ -0,0 +1,43 @@ +getJson(route('v3.damages.list')); + $response->assertStatus(401); + } + public function test_all_damages_returned_successfully_for_list(): void + { + $user = User::factory()->create(); + Damage::factory()->count(5)->create(); + $response = $this->actingAs($user)->getJson(route('v3.damages.list')); + $response->assertOk(); + $response->assertJsonStructure([ + 'data' => [ + '*' => [ + 'id', + 'title', + 'unit', + 'base_price', + 'status', + ], + ], + ]); + + } +} + + diff --git a/tests/Feature/V3/Damage/ShowTest.php b/tests/Feature/V3/Damage/ShowTest.php new file mode 100644 index 00000000..9256c488 --- /dev/null +++ b/tests/Feature/V3/Damage/ShowTest.php @@ -0,0 +1,59 @@ +create();; + $response = $this->getJson(route('v3.damages.show', [$damage->id])); + + $response->assertStatus(401); + } + + public function test_user_without_permission_cannot_view_damage(): void + { + $user = User::factory()->create(); + $damage = Damage::factory()->create();; + + $response = $this->actingAs($user)->getJson(route('v3.damages.show', [$damage->id])); + + $response->assertForbidden(); + } + + public function test_user_with_permission_can_view_damage(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $damage = Damage::factory()->create(); + + $response = $this->actingAs($user)->getJson(route('v3.damages.show', [$damage->id])); + + $response->assertOk() + ->assertJson([ + 'data' => [ + 'id' => $damage->id, + 'title' => $damage->title, + 'unit' => $damage->unit, + 'base_price' => $damage->base_price, + 'status' => $damage->status, + ] + ]); + } + +} diff --git a/tests/Feature/V3/Damage/StoreTest.php b/tests/Feature/V3/Damage/StoreTest.php new file mode 100644 index 00000000..607815ad --- /dev/null +++ b/tests/Feature/V3/Damage/StoreTest.php @@ -0,0 +1,156 @@ +postJson(route('v3.damages.store')); + $response->assertStatus(401); + } + + public function test_user_without_permission_cannot_store_damage(): void + { + $user = User::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store')); + $response->assertForbidden(); + } + + public function test_validation_fails_when_required_fields_are_missing(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store')); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.required', ['attribute' => "عنوان"]), + 'unit' => __('validation.required', ['attribute' => 'واحد']), + 'base_price' => __('validation.required', ['attribute' => 'قیمت پایه']), + ]); + } + + public function test_title_must_be_unique(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + $damage = Damage::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store'), [ + 'title' => $damage->title, + 'unit' => 'kg', + 'base_price' => 5000, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.unique', ['attribute' => "عنوان"]), + ]); + } + + public function test_store_title_and_unit_must_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store'), [ + 'title' => 12345, + 'unit' => 67890, + 'base_price' => 10000, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.string', ['attribute' => "عنوان"]), + 'unit' => __('validation.string', ['attribute' => 'واحد']), + ]); + } + + public function test_store_title_must_not_exceed_255_characters(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $longTitle = $this->faker->text(500); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store'), [ + 'title' => $longTitle, + 'unit' => 'kg', + 'base_price' => 10000, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.max.string',['attribute' => 'عنوان', 'max' => 255]), + ]); + } + + public function test_store_base_price_must_be_intger(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store'), [ + 'title' => 'Valid Title', + 'unit' => 'm', + 'base_price' => 'valid intger', + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'base_price' => __('validation.integer', ['attribute' => 'قیمت پایه']), + ]); + } + + + public function test_user_with_permission_can_store_damage(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $data = [ + 'title' => 'New Damage', + 'unit' => 'm', + 'base_price' => 10000, + ]; + + $response = $this->actingAs($user)->postJson(route('v3.damages.store'), $data); + + $response->assertOk() + ->assertJson([ + 'message' => __('messages.successful'), + ]); + + $this->assertDatabaseHas('damages', $data); + } + +} diff --git a/tests/Feature/V3/Damage/UpdateTest.php b/tests/Feature/V3/Damage/UpdateTest.php new file mode 100644 index 00000000..850ecedf --- /dev/null +++ b/tests/Feature/V3/Damage/UpdateTest.php @@ -0,0 +1,180 @@ +create();; + $response = $this->getJson(route('v3.damages.update', [$damage->id])); + + $response->assertStatus(401); + } + + public function test_user_without_permission_cannot_update_damage(): void + { + $user = User::factory()->create(); + $damage = Damage::factory()->create();; + + $response = $this->actingAs($user)->getJson(route('v3.damages.update', [$damage->id])); + + $response->assertForbidden(); + } + + public function test_validation_fails_when_required_fields_are_missing(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + + $damage = Damage::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.update', [$damage->id])); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.required', ['attribute' => "عنوان"]), + 'unit' => __('validation.required', ['attribute' => 'واحد']), + 'base_price' => __('validation.required', ['attribute' => 'قیمت پایه']), + ]); + } + + public function test_title_must_be_unique(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $existingDamage = Damage::factory()->create([ + 'title' => 'Existing Title' + ]); + + $damage = Damage::factory()->create(); + $response = $this->actingAs($user)->postJson(route('v3.damages.update', [$damage->id]),[ + 'title' => $existingDamage->title, + 'unit' => 'm', + 'base_price' => 5000, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.unique', ['attribute' => "عنوان"]), + ]); + } + + public function test_title_and_unit_must_be_string(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $damage = Damage::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.update', [$damage->id]), [ + 'title' => 12345, + 'unit' => 67890, + 'base_price' => 10000, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.string', ['attribute' => "عنوان"]), + 'unit' => __('validation.string', ['attribute' => 'واحد']), + ]); + } + + public function test_title_must_not_exceed_255_characters(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $damage = Damage::factory()->create(); + $longTitle = $this->faker->text(500); + + $response = $this->actingAs($user)->postJson(route('v3.damages.update', [$damage->id]), [ + 'title' => $longTitle, + 'unit' => 'kg', + 'base_price' => 10000, + ]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'title' => __('validation.max.string',['attribute' => 'عنوان', 'max' => 255]), + ]); + } + + public function test_base_price_must_be_integer(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $damage = Damage::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.update', [$damage->id]), [ + 'title' => 'Valid Title', + 'unit' => 'kg', + 'base_price' => 'invalid_price',]); + + $response->assertUnprocessable() + ->assertInvalid([ + 'base_price' => __('validation.integer', ['attribute' => 'قیمت پایه']), + ]); + } + + + public function test_user_with_permission_can_update_damage(): void + { + $user = User::factory() + ->has(Permission::factory([ + 'name' => 'manage-damage' + ])) + ->create(); + + $damage = Damage::factory()->create(); + + $updateData = [ + 'title' => 'Updated Damage', + 'unit' => 'litre', + 'base_price' => 20000, + ]; + + $response = $this->actingAs($user)->postJson(route('v3.damages.update', [$damage->id]), $updateData); + + $response->assertStatus(200) + ->assertJson([ + 'message' => __('messages.successful'), + ]); + + $this->assertDatabaseHas('damages', [ + 'id' => $damage->id, + 'title' => $updateData['title'], + 'unit' => $updateData['unit'], + 'base_price' => $updateData['base_price'], + ]); + } + + +} From b61a3e6452804eb9e0fc2c04db8cf120e73edf12 Mon Sep 17 00:00:00 2001 From: joddyabott Date: Sat, 22 Feb 2025 17:16:05 +0330 Subject: [PATCH 9/9] crate file test for damage and fix update request and add 2 option in validation --- tests/Feature/V3/Damage/ActivateTest.php | 61 ++++++++++++++++++++++++ tests/Feature/V3/Damage/IndexTest.php | 6 +-- tests/Feature/V3/Damage/ListTest.php | 4 +- tests/Feature/V3/Damage/ShowTest.php | 6 +-- 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/tests/Feature/V3/Damage/ActivateTest.php b/tests/Feature/V3/Damage/ActivateTest.php index 97678b63..b1ea5bb2 100644 --- a/tests/Feature/V3/Damage/ActivateTest.php +++ b/tests/Feature/V3/Damage/ActivateTest.php @@ -2,11 +2,72 @@ namespace Tests\Feature\V3\Damage; +use App\Models\Damage; +use App\Models\Permission; +use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Tests\TestCase; class ActivateTest extends TestCase { + use RefreshDatabase, WithFaker; + + public function test_unauthenticated_user_cannot_activate_damage(): void + { + $response = $this->postJson(route('v3.damages.store')); + $response->assertStatus(401); + } + + public function test_user_without_permission_cannot_activate_damage(): void + { + $user = User::factory()->create(); + + $response = $this->actingAs($user)->postJson(route('v3.damages.store')); + $response->assertForbidden(); + } + + + public function test_user_with_permission_can_activate_damage(): void + { + $user = User::factory() + ->has(Permission::factory()->state(['name' => 'manage-damage'])) + ->create(); + + $damage = Damage::factory()->create(['status' => 0]); + + $response = $this->actingAs($user)->postJson(route('v3.damages.activate', [$damage->id])); + + $response->assertOk() + ->assertJson([ + 'message' => __('messages.successful') + ]); + + $this->assertDatabaseHas('damages', [ + 'id' => $damage->id, + 'status' => 1, + ]); + } + + public function test_user_with_permission_can_deactivate_damage(): void + { + $user = User::factory() + ->has(Permission::factory()->state(['name' => 'manage-damage'])) + ->create(); + + $damage = Damage::factory()->create(['status' => 1]); + + $response = $this->actingAs($user)->postJson(route('v3.damages.activate', [$damage->id])); + + $response->assertOk() + ->assertJson([ + 'message' => __('messages.successful') + ]); + + $this->assertDatabaseHas('damages', [ + 'id' => $damage->id, + 'status' => 0, + ]); + } } diff --git a/tests/Feature/V3/Damage/IndexTest.php b/tests/Feature/V3/Damage/IndexTest.php index cc1de931..2a97e718 100644 --- a/tests/Feature/V3/Damage/IndexTest.php +++ b/tests/Feature/V3/Damage/IndexTest.php @@ -16,20 +16,20 @@ class IndexTest extends TestCase * A basic feature test example. */ - public function test_user_should_have_manage_damage_permission_index(): void + public function test_user_should_have_manage_damage_permission_index_damage(): void { $user = User::factory()->create(); $response = $this->actingAs($user)->getJson(route('v3.damages.index')); $response->assertForbidden(); } - public function test_user_cannot_access_authentication(): void + public function test_user_cannot_access_authentication_to_index_damage(): void { $response = $this->getJson(route('v3.damages.index')); $response->assertStatus(401); } - public function test_all_damages_returned_successfully_for_index(): void + public function test_all_damages_returned_successfully_for_index_damage(): void { $user = User::factory() diff --git a/tests/Feature/V3/Damage/ListTest.php b/tests/Feature/V3/Damage/ListTest.php index ba71e7d6..b582d845 100644 --- a/tests/Feature/V3/Damage/ListTest.php +++ b/tests/Feature/V3/Damage/ListTest.php @@ -13,13 +13,13 @@ class ListTest extends TestCase { use RefreshDatabase, WithFaker; - public function test_user_cannot_access_authentication(): void + public function test_user_cannot_access_authentication_list_damage(): void { $response = $this->getJson(route('v3.damages.list')); $response->assertStatus(401); } - public function test_all_damages_returned_successfully_for_list(): void + public function test_all_damages_returned_successfully_for_list_damage(): void { $user = User::factory()->create(); Damage::factory()->count(5)->create(); diff --git a/tests/Feature/V3/Damage/ShowTest.php b/tests/Feature/V3/Damage/ShowTest.php index 9256c488..34ba0eb5 100644 --- a/tests/Feature/V3/Damage/ShowTest.php +++ b/tests/Feature/V3/Damage/ShowTest.php @@ -13,7 +13,7 @@ class ShowTest extends TestCase { use RefreshDatabase , WithFaker; - public function test_unauthenticated_user_cannot_view_damage(): void + public function test_unauthenticated_user_cannot_view_show_damage(): void { $damage = Damage::factory()->create();; @@ -22,7 +22,7 @@ class ShowTest extends TestCase $response->assertStatus(401); } - public function test_user_without_permission_cannot_view_damage(): void + public function test_user_without_permission_cannot_view_damage_show_damage(): void { $user = User::factory()->create(); $damage = Damage::factory()->create();; @@ -32,7 +32,7 @@ class ShowTest extends TestCase $response->assertForbidden(); } - public function test_user_with_permission_can_view_damage(): void + public function test_user_with_permission_can_view_damage_to_show_damage(): void { $user = User::factory() ->has(Permission::factory([