Add endpoint to check insurance coverage amount while insert/update act in health care sheet

This commit is contained in:
Djery-Tom 2022-02-21 08:56:25 +01:00
parent 092f5a6d09
commit 3797577f9a
4 changed files with 287 additions and 51 deletions

View File

@ -699,6 +699,8 @@ class HealthCareSheetController extends Controller
$this->calculateInsuranceAmounts($healthCareSheet); $this->calculateInsuranceAmounts($healthCareSheet);
// Verification de la limite de couverture // Verification de la limite de couverture
$this->verifyInsuranceCoverageAmount($nhConfig, $insurance, $healthCareSheet, $beneficiary ?? null); $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) { foreach ($request->input('prescriptions', []) as $p) {
$prescription = NhMedicalPrescription::create($p); $prescription = NhMedicalPrescription::create($p);
@ -761,19 +763,20 @@ class HealthCareSheetController extends Controller
* @throws AppException * @throws AppException
*/ */
// Verification de la limite de couverture // 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_coverage_amount = isset($beneficiary) ? $beneficiary->insurance_coverage_amount : $insurance->insurance_coverage_amount;
$insurance_amount = $sheet->insurance_amount; $insurance_amount = $sheet->insurance_amount;
if (!$nhConfig->family_coverage_sharing) { 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) { if ($total_insurance_amount > $nhConfig->coverage_limit_per_insured_per_year) {
DB::rollBack(); DB::rollBack();
throw new AppException("La limite de couverture a été atteinte pour cet assuré"); throw new AppException("La limite de couverture a été atteinte pour cet assuré");
} }
} else { } 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) { foreach ($insurance->beneficiaries as $b) {
$total_insurance_amount += $b->insurance_coverage_amount; $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( * @OA\Post(
* path="/health-care-sheets/execution", * path="/health-care-sheets/execution",
@ -1030,6 +1047,8 @@ class HealthCareSheetController extends Controller
$this->calculateInsuranceAmounts($healthCareSheet); $this->calculateInsuranceAmounts($healthCareSheet);
// Verification de la limite de couverture // Verification de la limite de couverture
$this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $healthCareSheet, $sheet->beneficiary); $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 #Clone pivots
@ -1433,24 +1452,8 @@ class HealthCareSheetController extends Controller
try { try {
DB::beginTransaction(); DB::beginTransaction();
if ($action == 'ACCEPT') { 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; $sheet->state = InsuranceSubscriptionState::ACCEPTED;
$message = trans('messages.care_sheet_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') { } else if ($action == 'REJECT') {
$sheet->state = InsuranceSubscriptionState::REJECTED; $sheet->state = InsuranceSubscriptionState::REJECTED;
$message = trans('messages.care_sheet_rejected'); $message = trans('messages.care_sheet_rejected');
@ -1464,8 +1467,6 @@ class HealthCareSheetController extends Controller
DB::commit(); DB::commit();
return $this->successResponse($message); return $this->successResponse($message);
} catch (AppException $e) {
return $this->errorResponse($e->getMessage(), $e->getCode());
} catch (Throwable $e) { } catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString()); Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack(); DB::rollBack();
@ -1712,7 +1713,7 @@ class HealthCareSheetController extends Controller
$this->validate($request, [ $this->validate($request, [
'network_agent_id' => 'required|integer|exists:networks_agents,id', 'network_agent_id' => 'required|integer|exists:networks_agents,id',
'password' => 'required|string', '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_lastname' => 'nullable|string',
'practitioner_firstname' => 'nullable|string', 'practitioner_firstname' => 'nullable|string',
'practitioner_provider_class_id' => 'nullable|integer', 'practitioner_provider_class_id' => 'nullable|integer',
@ -1753,14 +1754,14 @@ class HealthCareSheetController extends Controller
$this->agentCredentialsVerification($request->input('network_agent_id'), $request->input('password')); $this->agentCredentialsVerification($request->input('network_agent_id'), $request->input('password'));
$beneficiary_id = $request->input('beneficiary_id'); // $beneficiary_id = $request->input('beneficiary_id');
if (!empty($beneficiary_id)) { // if (!empty($beneficiary_id)) {
$beneficiary = $sheet->insurance->beneficiaries()->where('nh_having_rights.id', $beneficiary_id)->first(); // $beneficiary = $sheet->insurance->beneficiaries()->where('nh_having_rights.id', $beneficiary_id)->first();
if (!isset($beneficiary)) { // if (!isset($beneficiary)) {
return $this->errorResponse(trans('errors.beneficiary_not_found')); // return $this->errorResponse(trans('errors.beneficiary_not_found'));
} // }
$sheet->beneficiary_id = $beneficiary_id; // $sheet->beneficiary_id = $beneficiary_id;
} // }
$nhConfig = NhNetworksConfig::where('network_id', $sheet->insurance->network_id)->first(); $nhConfig = NhNetworksConfig::where('network_id', $sheet->insurance->network_id)->first();
if (!isset($nhConfig)) { if (!isset($nhConfig)) {
@ -1801,11 +1802,11 @@ class HealthCareSheetController extends Controller
$sheet->accident_date = !empty($accident_date) ? $accident_date : null; $sheet->accident_date = !empty($accident_date) ? $accident_date : null;
$sheet->pregnancy_start_at = !empty($pregnancy_start_at) ? $pregnancy_start_at : 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; $sheet->pregnancy_end_at = !empty($pregnancy_end_at) ? $pregnancy_end_at : null;
if (isset($beneficiary)) { // if (isset($beneficiary)) {
$sheet->patient_lastname = $beneficiary->lastname; // $sheet->patient_lastname = $beneficiary->lastname;
$sheet->patient_firstname = $beneficiary->firstname; // $sheet->patient_firstname = $beneficiary->firstname;
$sheet->patient_situation = 'HAVING_RIGHT'; // $sheet->patient_situation = 'HAVING_RIGHT';
} // }
foreach ($request->input('performances', []) as $p) { foreach ($request->input('performances', []) as $p) {
if (!empty($p['to_delete'])) { 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) { foreach ($request->input('prescriptions', []) as $p) {
if (!empty($p['to_delete'])) { if (!empty($p['to_delete'])) {
NhMedicalPrescription::find($p['id'])->delete(); NhMedicalPrescription::find($p['id'])->delete();
@ -1884,7 +1878,6 @@ class HealthCareSheetController extends Controller
} }
$prescription->updated_at = $datetime; $prescription->updated_at = $datetime;
$prescription->save(); $prescription->save();
$_prescriptions[] = $prescription;
if (empty($p['id'])) { if (empty($p['id'])) {
NhHealthCareSheetsPrescription::create([ NhHealthCareSheetsPrescription::create([
@ -1936,12 +1929,13 @@ class HealthCareSheetController extends Controller
} }
} }
if ($sheet->type == HealthCareSheetType::EXECUTION) { $currentInsuranceAmount = $sheet->insurance_amount;
// Calculer les parts de l'assurance et l'assuré pour cette feuille de soins // Calculer les parts de l'assurance et l'assuré pour cette feuille de soins
$this->calculateInsuranceAmounts($sheet); $this->calculateInsuranceAmounts($sheet);
// Verification de la limite de couverture // Verification de la limite de couverture
$this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $sheet, $sheet->beneficiary); $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(); $sheet->save();
@ -1992,4 +1986,243 @@ class HealthCareSheetController extends Controller
$this->formatExamAndPrescriptionAmounts($p, $sheet); $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");
}
} }

View File

@ -50,5 +50,6 @@ return [
'cannot_renew_insurance' => "Your insurance is not stopped, you cannot renew it", 'cannot_renew_insurance' => "Your insurance is not stopped, you cannot renew it",
'already_insured' => "Vous avez deja souscrit à cette assurance", 'already_insured' => "Vous avez deja souscrit à cette assurance",
'no_sheet_accepted' => "No care sheet accepted", '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"
]; ];

View File

@ -50,5 +50,6 @@ return [
'cannot_renew_insurance' => "Votre assurance n'est pas en arrêt , vous ne pouvez pas la renouveler", '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", 'already_insured' => "Vous avez deja souscrit à cette assurance",
'no_sheet_accepted' => "Aucune feuille de soins acceptée", '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"
]; ];

View File

@ -49,6 +49,7 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route
$router->get('acts', 'HealthCareSheetController@getNetworkActs'); $router->get('acts', 'HealthCareSheetController@getNetworkActs');
$router->get('health-care-sheets', 'HealthCareSheetController@getHealthCareSheets'); $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->put('health-care-sheets', 'HealthCareSheetController@treatHealthCareSheet');
$router->post('health-care-sheets/performances-amount', 'HealthCareSheetController@calculateConsultationPerformancesAmount'); $router->post('health-care-sheets/performances-amount', 'HealthCareSheetController@calculateConsultationPerformancesAmount');
$router->post('health-care-sheets/consultation', 'HealthCareSheetController@storeHealthCareSheetConsultation'); $router->post('health-care-sheets/consultation', 'HealthCareSheetController@storeHealthCareSheetConsultation');