From 3797577f9af449fd5630e736c1a2bbe8216b0522 Mon Sep 17 00:00:00 2001 From: Djery-Tom Date: Mon, 21 Feb 2022 08:56:25 +0100 Subject: [PATCH] Add endpoint to check insurance coverage amount while insert/update act in health care sheet --- .../Controllers/HealthCareSheetController.php | 331 +++++++++++++++--- resources/lang/en/errors.php | 3 +- resources/lang/fr/errors.php | 3 +- routes/web.php | 1 + 4 files changed, 287 insertions(+), 51 deletions(-) diff --git a/app/Http/Controllers/HealthCareSheetController.php b/app/Http/Controllers/HealthCareSheetController.php index f609d06..6252114 100755 --- a/app/Http/Controllers/HealthCareSheetController.php +++ b/app/Http/Controllers/HealthCareSheetController.php @@ -699,6 +699,8 @@ class HealthCareSheetController extends Controller $this->calculateInsuranceAmounts($healthCareSheet); // Verification de la limite de couverture $this->verifyInsuranceCoverageAmount($nhConfig, $insurance, $healthCareSheet, $beneficiary ?? null); + // Mettre à jour la couverture d'assurance de l'assuré + $this->updateInsuranceCoverageAmount($healthCareSheet, $insurance, $beneficiary ?? null, $datetime); foreach ($request->input('prescriptions', []) as $p) { $prescription = NhMedicalPrescription::create($p); @@ -761,19 +763,20 @@ class HealthCareSheetController extends Controller * @throws AppException */ // Verification de la limite de couverture - private function verifyInsuranceCoverageAmount(NhNetworksConfig $nhConfig, NhInsurance $insurance, NhHealthCareSheet $sheet, NhHavingRight $beneficiary = null) + private function verifyInsuranceCoverageAmount(NhNetworksConfig $nhConfig, NhInsurance $insurance, NhHealthCareSheet $sheet, NhHavingRight $beneficiary = null + , $currentInsuranceAmount = 0) // Current Insurance Amount en cas de mise à jour de la feuille de soins pour ne pas prendre en compte la couverture deja affecté { $insurance_coverage_amount = isset($beneficiary) ? $beneficiary->insurance_coverage_amount : $insurance->insurance_coverage_amount; $insurance_amount = $sheet->insurance_amount; if (!$nhConfig->family_coverage_sharing) { - $total_insurance_amount = $insurance_coverage_amount + $insurance_amount; + $total_insurance_amount = $insurance_coverage_amount + $insurance_amount - $currentInsuranceAmount; if ($total_insurance_amount > $nhConfig->coverage_limit_per_insured_per_year) { DB::rollBack(); throw new AppException("La limite de couverture a été atteinte pour cet assuré"); } } else { - $total_insurance_amount = $insurance_amount + $insurance->insurance_coverage_amount; + $total_insurance_amount = $insurance_amount + $insurance->insurance_coverage_amount - $currentInsuranceAmount; foreach ($insurance->beneficiaries as $b) { $total_insurance_amount += $b->insurance_coverage_amount; } @@ -799,6 +802,20 @@ class HealthCareSheetController extends Controller ]); } + private function updateInsuranceCoverageAmount(NhHealthCareSheet $sheet, NhInsurance $insurance, NhHavingRight $beneficiary, + $datetime, $currentInsuranceAmount = 0): void + { // Current Insurance Amount en cas de mise à jour de la feuille de soins pour ne pas prendre en compte la couverture deja affecté) + $sheet->insurance_consumed_at = $datetime; + if (!empty($beneficiary)) { + $beneficiary->insurance_coverage_amount += ($sheet->insurance_amount - $currentInsuranceAmount); + $beneficiary->save(); + } else { + $insurance->insurance_coverage_amount += ($sheet->insurance_amount - $currentInsuranceAmount); + $insurance->save(); + } + $sheet->save(); + } + /** * @OA\Post( * path="/health-care-sheets/execution", @@ -1030,6 +1047,8 @@ class HealthCareSheetController extends Controller $this->calculateInsuranceAmounts($healthCareSheet); // Verification de la limite de couverture $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $healthCareSheet, $sheet->beneficiary); + // Mettre à jour la couverture d'assurance de l'assuré + $this->updateInsuranceCoverageAmount($healthCareSheet, $sheet->insurance, $sheet->beneficiary, $datetime); #Clone pivots @@ -1433,24 +1452,8 @@ class HealthCareSheetController extends Controller try { DB::beginTransaction(); if ($action == 'ACCEPT') { - $nhConfig = NhNetworksConfig::where('network_id', $sheet->insurance->network_id)->first(); - if (!isset($nhConfig)) { - return $this->errorResponse(trans('errors.nano_health_not_activated')); - } - // Verification de la limite de couverture - $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $sheet, $sheet->beneficiary); - $sheet->state = InsuranceSubscriptionState::ACCEPTED; $message = trans('messages.care_sheet_accepted'); - // Mettre à jour la couverture d'assurance de chaque assuré - $sheet->insurance_consumed_at = $datetime; - if (!empty($sheet->beneficiary)) { - $sheet->beneficiary->insurance_coverage_amount += $sheet->insurance_amount; - $sheet->beneficiary->save(); - } else { - $sheet->insurance->insurance_coverage_amount += $sheet->insurance_amount; - $sheet->insurance->save(); - } } else if ($action == 'REJECT') { $sheet->state = InsuranceSubscriptionState::REJECTED; $message = trans('messages.care_sheet_rejected'); @@ -1464,8 +1467,6 @@ class HealthCareSheetController extends Controller DB::commit(); return $this->successResponse($message); - } catch (AppException $e) { - return $this->errorResponse($e->getMessage(), $e->getCode()); } catch (Throwable $e) { Log::error($e->getMessage() . '\n' . $e->getTraceAsString()); DB::rollBack(); @@ -1712,7 +1713,7 @@ class HealthCareSheetController extends Controller $this->validate($request, [ 'network_agent_id' => 'required|integer|exists:networks_agents,id', 'password' => 'required|string', - 'beneficiary_id' => 'nullable|int|exists:nh_having_rights,id', +// 'beneficiary_id' => 'nullable|int|exists:nh_having_rights,id', 'practitioner_lastname' => 'nullable|string', 'practitioner_firstname' => 'nullable|string', 'practitioner_provider_class_id' => 'nullable|integer', @@ -1753,14 +1754,14 @@ class HealthCareSheetController extends Controller $this->agentCredentialsVerification($request->input('network_agent_id'), $request->input('password')); - $beneficiary_id = $request->input('beneficiary_id'); - if (!empty($beneficiary_id)) { - $beneficiary = $sheet->insurance->beneficiaries()->where('nh_having_rights.id', $beneficiary_id)->first(); - if (!isset($beneficiary)) { - return $this->errorResponse(trans('errors.beneficiary_not_found')); - } - $sheet->beneficiary_id = $beneficiary_id; - } +// $beneficiary_id = $request->input('beneficiary_id'); +// if (!empty($beneficiary_id)) { +// $beneficiary = $sheet->insurance->beneficiaries()->where('nh_having_rights.id', $beneficiary_id)->first(); +// if (!isset($beneficiary)) { +// return $this->errorResponse(trans('errors.beneficiary_not_found')); +// } +// $sheet->beneficiary_id = $beneficiary_id; +// } $nhConfig = NhNetworksConfig::where('network_id', $sheet->insurance->network_id)->first(); if (!isset($nhConfig)) { @@ -1801,11 +1802,11 @@ class HealthCareSheetController extends Controller $sheet->accident_date = !empty($accident_date) ? $accident_date : null; $sheet->pregnancy_start_at = !empty($pregnancy_start_at) ? $pregnancy_start_at : null; $sheet->pregnancy_end_at = !empty($pregnancy_end_at) ? $pregnancy_end_at : null; - if (isset($beneficiary)) { - $sheet->patient_lastname = $beneficiary->lastname; - $sheet->patient_firstname = $beneficiary->firstname; - $sheet->patient_situation = 'HAVING_RIGHT'; - } +// if (isset($beneficiary)) { +// $sheet->patient_lastname = $beneficiary->lastname; +// $sheet->patient_firstname = $beneficiary->firstname; +// $sheet->patient_situation = 'HAVING_RIGHT'; +// } foreach ($request->input('performances', []) as $p) { if (!empty($p['to_delete'])) { @@ -1844,15 +1845,8 @@ class HealthCareSheetController extends Controller ]); } } - - // Calculer les parts de l'assurance et l'assuré pour cette feuille de soins - $this->calculateInsuranceAmounts($sheet); - // Verification de la limite de couverture - $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $sheet, $beneficiary ?? null); - } - $_prescriptions = []; foreach ($request->input('prescriptions', []) as $p) { if (!empty($p['to_delete'])) { NhMedicalPrescription::find($p['id'])->delete(); @@ -1884,7 +1878,6 @@ class HealthCareSheetController extends Controller } $prescription->updated_at = $datetime; $prescription->save(); - $_prescriptions[] = $prescription; if (empty($p['id'])) { NhHealthCareSheetsPrescription::create([ @@ -1936,12 +1929,13 @@ class HealthCareSheetController extends Controller } } - if ($sheet->type == HealthCareSheetType::EXECUTION) { - // Calculer les parts de l'assurance et l'assuré pour cette feuille de soins - $this->calculateInsuranceAmounts($sheet); - // Verification de la limite de couverture - $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $sheet, $sheet->beneficiary); - } + $currentInsuranceAmount = $sheet->insurance_amount; + // Calculer les parts de l'assurance et l'assuré pour cette feuille de soins + $this->calculateInsuranceAmounts($sheet); + // Verification de la limite de couverture + $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $sheet, $sheet->beneficiary, $currentInsuranceAmount); + // Mettre à jour la couverture d'assurance de l'assuré + $this->updateInsuranceCoverageAmount($sheet, $sheet->insurance, $sheet->beneficiary, $datetime, $currentInsuranceAmount); $sheet->save(); @@ -1992,4 +1986,243 @@ class HealthCareSheetController extends Controller $this->formatExamAndPrescriptionAmounts($p, $sheet); } } + + /** + * @OA\Post( + * path="/health-care-sheets/check-insurance-coverage-amount", + * summary="Verifier si une ligne de la feuille est applicable", + * tags={"Feuilles de soins"}, + * security={{"api_key":{}}}, + * @OA\RequestBody( + * description="Corps de la requete", + * required=true, + * @OA\MediaType( + * mediaType="application/json", + * @OA\Schema( + * schema="check_insurance_coverage_amount", + * title = "Verifier si une ligne de la feuille est applicable", + * required={"insured_id", "network_agent_id", "password", "practitioner_lastname", "practitioner_provider_class_id"}, + * @OA\Property( + * property="network_id", + * description = "ID du reseau", + * type="integer", + * example= 250 + * ), + * @OA\Property( + * property="insurance_id", + * description = "ID de l'assurance", + * type="integer", + * example= 4 + * ), + * @OA\Property( + * property="beneficiary_id", + * description = "ID du beneficiaire , s'il s'agit d'une feuille de soins pour beneficiaire", + * type="integer", + * example= 4 + * ), + * @OA\Property( + * property="care_condition", + * description = "Condition de prise en charge", + * type="string", + * enum={"CURRENT_AFFECTION","LONG_TERM_AFFECTION","EXONERATION"}, + * example= "CURRENT_AFFECTION" + * ), + * @OA\Property( + * property="act_action", + * description = "Action effectuéé sur la feuille de soins", + * type="string", + * enum={"INSERT","UPDATE"}, + * example= "INSERT" + * ), + * @OA\Property( + * property="act_type", + * description = "Type d'acte qui correspond au type de la ligne dans la feuille de soins", + * type="string", + * enum={"PRESCRIPTION","EXAM","PRESCRIPTION"}, + * example= "PRESCRIPTION" + * ), + * @OA\Property( + * property="act_id", + * description = "Id de l'acte", + * type="integer", + * example= 10 + * ), + * @OA\Property(property="performances", + * type="array", + * description="Listes des prestations", + * @OA\Items(ref="#/components/schemas/check_insurance_performances") + * ), + * @OA\Property(property="prescriptions", + * type="array", + * description="Listes des prescriptions medicales", + * @OA\Items(ref="#/components/schemas/check_insurance_prescriptions") + * ), + * @OA\Property(property="exams", + * type="array", + * description="Listes des examens", + * @OA\Items(ref="#/components/schemas/check_insurance_exams") + * ) + * ), + * ), + * ), + * @OA\Response( + * response=200, + * description="OK", + * @OA\JsonContent( + * ref="#/components/schemas/ApiResponse", + * example = { + * "status" : 200, + * "response" : "Acceptable", + * "error":null + * } + * ) + * ) + * ) + * @throws \App\Exceptions\AppException + */ + // Ce route sera appélé à chaque insertion/modification de prestations, examens ou prescriptions dans une feuille de soins + public function checkInsuranceCoverageAmount(Request $request) + { + /** + * @OA\Schema( + * schema="check_insurance_performances", + * @OA\Property(property="amount", + * type="number", + * example=30000, + * description="Montant de la prestation" + * ), + * @OA\Property(property="home_visit_fees", + * type="number", + * example=5000, + * description="Frais de deplacement pour visiste à domicile " + * ), + * ) + * + * @OA\Schema( + * schema="check_insurance_prescriptions", + * @OA\Property(property="quantity", + * type="int", + * example=5, + * description="Quantité" + * ), + * @OA\Property(property="unit_price", + * type="number", + * example=3000, + * description="Prix unitaire" + * ) + * ) + * + * @OA\Schema( + * schema="check_insurance_exams", + * @OA\Property(property="quantity", + * type="int", + * example=5, + * description="Quantité" + * ), + * @OA\Property(property="unit_price", + * type="number", + * example=5000, + * description="Prix unitaire" + * ) + * ) + */ + $this->validate($request, [ + 'network_id' => 'required|exists:networks,id', + 'insurance_id' => 'required|exists:nh_insurances,id', + 'beneficiary_id' => 'nullable|exists:nh_having_rights,id', + 'care_condition' => 'required|in:CURRENT_AFFECTION,LONG_TERM_AFFECTION,EXONERATION', + 'act_action' => 'required|in:INSERT,UPDATE', // Insertion ou modification de l'acte ( Create ou modification de la feuille de soins) + 'act_type' => 'required|in:PERFORMANCE,EXAM,PRESCRIPTION', + 'act_id' => 'required_if:act_action,UPDATE|integer', // Requis lors de la modification de la feuille de soins (UPDATE) + 'performances' => 'required_if:act_type,PERFORMANCE|array', + 'performances.*.amount' => 'required_if:act_type,PERFORMANCE|numeric', + 'performances.*.home_visit_fees' => 'nullable|numeric', + 'prescriptions' => 'required_if:act_type,PRESCRIPTION|array', + 'prescriptions.*.quantity' => 'required|integer|min:1', + 'prescriptions.*.unit_price' => 'required|numeric', + 'exams' => 'required_if:act_type,EXAM|array', + 'exams.*.quantity' => 'required|integer|min:1', + 'exams.*.unit_price' => 'required|numeric', + ]); + + $beneficiary = NhHavingRight::find($request->input('beneficiary_id')); + $insurance = NhInsurance::find($request->input('insurance_id')); + $act_id = $request->input('act_id'); + $act_action = $request->input('act_action'); + $act_type = $request->input('act_type'); + $performances = $request->input('performances', []); + $exams = $request->input('exams', []); + $prescriptions = $request->input('prescriptions', []); + + if (sizeof($performances) > 1 || sizeof($exams) > 1 || sizeof($prescriptions) > 1) { + return $this->errorResponse("La verification se fait sur une seule ligne à la fois"); + } + + $nhConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first(); + if (!isset($nhConfig)) { + return $this->errorResponse(trans('errors.nano_health_not_activated')); + } + + $parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition')); + + $insurance_amount = 0; + switch ($act_type) { + case 'PERFORMANCE': + foreach ($performances as $p) { + $fees = !empty($p['home_visit_fees']) ? $p['home_visit_fees'] : 0; + $insurance_amount += ($parts->insurer_part * ($p['amount'] + $fees)); + } + $act = NhPerformance::find($act_id); + break; + case 'EXAM': + foreach ($exams as $e) { + $insurance_amount += ($parts->insurer_part * $e['unit_price'] * $e['quantity']); + } + $act = NhExam::find($act_id); + break; + case 'PRESCRIPTION': + foreach ($prescriptions as $p) { + $insurance_amount += ($parts->insurer_part * $p['unit_price'] * $p['quantity']); + } + $act = NhMedicalPrescription::find($act_id); + break; + default: + return $this->errorResponse(trans('errors.unexpected_error')); + } + + $insurance_coverage_amount = isset($beneficiary) ? $beneficiary->insurance_coverage_amount : $insurance->insurance_coverage_amount; + $current_insurance_amount = 0; + if ($act_action == 'UPDATE') { + if (!isset($act)) { + return $this->errorResponse(trans('errors.act_not_found')); + } + // En cas de modification d'une feuille de soins , considéré le montant de couverture actuel de l'acte deja pris en compte + switch ($act_type) { + case 'PERFORMANCE': + $current_insurance_amount = $act->insurance_amount; + break; + case 'EXAM': + case 'PRESCRIPTION': + $current_insurance_amount = $act->insurer_paid_amount; + break; + } + } + + if (!$nhConfig->family_coverage_sharing) { + $total_insurance_amount = $insurance_coverage_amount + $insurance_amount - $current_insurance_amount; + if ($total_insurance_amount > $nhConfig->coverage_limit_per_insured_per_year) { + return $this->errorResponse("La limite de couverture a été atteinte pour cet assuré"); + } + } else { + $total_insurance_amount = $insurance_amount + $insurance->insurance_coverage_amount - $current_insurance_amount; + foreach ($insurance->beneficiaries as $b) { + $total_insurance_amount += $b->insurance_coverage_amount; + } + if ($total_insurance_amount > ($nhConfig->coverage_limit_per_insured_per_year * ($insurance->number_of_beneficiaries + 1))) { + return $this->errorResponse("La mutualisation familiale a été atteinte pour cet assuré"); + } + } + + return $this->successResponse("Can be applied"); + } } diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php index 805d727..3e6b664 100755 --- a/resources/lang/en/errors.php +++ b/resources/lang/en/errors.php @@ -50,5 +50,6 @@ return [ 'cannot_renew_insurance' => "Your insurance is not stopped, you cannot renew it", 'already_insured' => "Vous avez deja souscrit à cette assurance", 'no_sheet_accepted' => "No care sheet accepted", - 'no_sheet_available' => "No care sheet available" + 'no_sheet_available' => "No care sheet available", + "act_not_found" => "Act not found" ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index f7d74a8..fa7c514 100755 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -50,5 +50,6 @@ return [ 'cannot_renew_insurance' => "Votre assurance n'est pas en arrêt , vous ne pouvez pas la renouveler", 'already_insured' => "Vous avez deja souscrit à cette assurance", 'no_sheet_accepted' => "Aucune feuille de soins acceptée", - 'no_sheet_available' => "Aucune feuille de soins disponible" + 'no_sheet_available' => "Aucune feuille de soins disponible", + "act_not_found" => "Acte introuvable" ]; diff --git a/routes/web.php b/routes/web.php index b8730e6..40b27cd 100644 --- a/routes/web.php +++ b/routes/web.php @@ -49,6 +49,7 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route $router->get('acts', 'HealthCareSheetController@getNetworkActs'); $router->get('health-care-sheets', 'HealthCareSheetController@getHealthCareSheets'); + $router->post('health-care-sheets/check-insurance-coverage-amount', 'HealthCareSheetController@checkInsuranceCoverageAmount'); $router->put('health-care-sheets', 'HealthCareSheetController@treatHealthCareSheet'); $router->post('health-care-sheets/performances-amount', 'HealthCareSheetController@calculateConsultationPerformancesAmount'); $router->post('health-care-sheets/consultation', 'HealthCareSheetController@storeHealthCareSheetConsultation');