diff --git a/app/Http/Controllers/HealthCareSheetController.php b/app/Http/Controllers/HealthCareSheetController.php index 1f05541..0e77115 100755 --- a/app/Http/Controllers/HealthCareSheetController.php +++ b/app/Http/Controllers/HealthCareSheetController.php @@ -25,6 +25,7 @@ use App\Models\NhMedicalPrescription; use App\Models\NhNetworksConfig; use App\Models\NhPerformance; use App\Models\NhProviderClass; +use App\Models\NhTmpHealthCareSheet; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; @@ -644,6 +645,8 @@ class HealthCareSheetController extends Controller } $parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition')); + $currency_code = $this->getNetworkCurrency($insurance->network_id); + try { DB::beginTransaction(); @@ -698,7 +701,7 @@ class HealthCareSheetController extends Controller // Calculer les parts de l'assurance et l'assuré pour cette feuille de soins $this->calculateInsuranceAmounts($healthCareSheet); // Verification de la limite de couverture - $this->verifyInsuranceCoverageAmount($nhConfig, $insurance, $healthCareSheet, $beneficiary ?? null); + $this->verifyInsuranceCoverageAmount($nhConfig, $insurance, $healthCareSheet, $beneficiary ?? null, $currency_code); // Mettre à jour la couverture d'assurance de l'assuré $this->updateInsuranceCoverageAmount($healthCareSheet, $insurance, $datetime, $beneficiary ?? null); @@ -763,26 +766,40 @@ class HealthCareSheetController extends Controller * @throws AppException */ // Verification de la limite de couverture - 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é + private function verifyInsuranceCoverageAmount(NhNetworksConfig $nhConfig, NhInsurance $insurance, NhHealthCareSheet $sheet, NhHavingRight $beneficiary = null, + $currency_code = 'XAF', $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; + $monthPrice = $nhConfig->monthsPricesGrid()->where('nh_network_config_id', $nhConfig->id) + ->where('number_of_months', $insurance->number_of_months)->first(); + + if (!isset($monthPrice)) + throw new AppException(trans('errors.month_price_grid_not_found')); if (!$nhConfig->family_coverage_sharing) { $total_insurance_amount = $insurance_coverage_amount + $insurance_amount - $currentInsuranceAmount; - if ($total_insurance_amount > $nhConfig->coverage_limit_per_insured_per_year) { + if ($total_insurance_amount > $monthPrice->max_insurance_coverage_amount) { DB::rollBack(); - throw new AppException("La limite de couverture a été atteinte pour cet assuré"); + throw new AppException(trans('errors.insurance_coverage_amount_exceeded', [ + 'consumption' => $this->toMoneyWithCurrencyCode($insurance_coverage_amount, $currency_code), + 'remaining' => $this->toMoneyWithCurrencyCode($monthPrice->max_insurance_coverage_amount - $insurance_coverage_amount, $currency_code), + ])); } } else { - $total_insurance_amount = $insurance_amount + $insurance->insurance_coverage_amount - $currentInsuranceAmount; + // Montant de l'assurance deja consomé à date + $family_consumed_amount = $insurance->insurance_coverage_amount; foreach ($insurance->beneficiaries as $b) { - $total_insurance_amount += $b->insurance_coverage_amount; + $family_consumed_amount += $b->insurance_coverage_amount; } - if ($total_insurance_amount > ($nhConfig->coverage_limit_per_insured_per_year * ($insurance->number_of_beneficiaries + 1))) { + $total_insurance_amount = $family_consumed_amount + $insurance_amount - $currentInsuranceAmount; + $family_limit_amount = $monthPrice->max_insurance_coverage_amount * ($insurance->number_of_beneficiaries + 1); + if ($total_insurance_amount > $family_limit_amount) { DB::rollBack(); - throw new AppException("La mutualisation familiale a été atteinte pour cet assuré"); + throw new AppException(trans('errors.insurance_coverage_amount_exceeded', [ + 'consumption' => $this->toMoneyWithCurrencyCode($family_consumed_amount, $currency_code), + 'remaining' => $this->toMoneyWithCurrencyCode($family_limit_amount - $family_consumed_amount, $currency_code), + ])); } } } @@ -950,6 +967,7 @@ class HealthCareSheetController extends Controller } $parts = $this->getConfigInsuranceParts($nhConfig, $sheet->care_condition); + $currency_code = $this->getNetworkCurrency($sheet->insurance->network_id); $prescriptionsIds = array_map(function ($r) { return $r['id']; @@ -1046,7 +1064,7 @@ class HealthCareSheetController extends Controller // Calculer les parts de l'assurance et l'assuré pour cette feuille de soins $this->calculateInsuranceAmounts($healthCareSheet); // Verification de la limite de couverture - $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $healthCareSheet, $sheet->beneficiary); + $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $healthCareSheet, $sheet->beneficiary, $currency_code); // Mettre à jour la couverture d'assurance de l'assuré $this->updateInsuranceCoverageAmount($healthCareSheet, $sheet->insurance, $datetime, $sheet->beneficiary,); @@ -1769,6 +1787,7 @@ class HealthCareSheetController extends Controller } $parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition', $sheet->care_condition)); + $currency_code = $this->getNetworkCurrency($sheet->insurance->network_id); $performances = $request->input('performances', []); $prescriptions = $request->input('prescriptions', []); @@ -1933,7 +1952,7 @@ 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, $sheet->beneficiary, $currentInsuranceAmount); + $this->verifyInsuranceCoverageAmount($nhConfig, $sheet->insurance, $sheet, $sheet->beneficiary, $currency_code, $currentInsuranceAmount); // Mettre à jour la couverture d'assurance de l'assuré $this->updateInsuranceCoverageAmount($sheet, $sheet->insurance, $datetime, $sheet->beneficiary, $currentInsuranceAmount); @@ -2001,6 +2020,12 @@ class HealthCareSheetController extends Controller * @OA\Schema( * schema="check_insurance_coverage_amount", * title = "Verifier si une ligne de la feuille est applicable", + * @OA\Property( + * property="tmp_sheet_id", + * description = "ID de temporaire de le feuille de soins generrée par le frontend", + * type="string", + * example= "XXXXXXXXXXXXXXXXXXX" + * ), * @OA\Property( * property="insurance_id", * description = "ID de l'assurance", @@ -2120,6 +2145,7 @@ class HealthCareSheetController extends Controller * ) */ $this->validate($request, [ + 'tmp_sheet_id' => 'required|string',// Temporal sheet ID generate by frontend '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', @@ -2155,7 +2181,14 @@ class HealthCareSheetController extends Controller return $this->errorResponse(trans('errors.nano_health_not_activated')); } + $monthPrice = $nhConfig->monthsPricesGrid()->where('nh_network_config_id', $nhConfig->id) + ->where('number_of_months', $insurance->number_of_months)->first(); + + if (!isset($monthPrice)) + return $this->errorResponse(trans('errors.month_price_grid_not_found')); + $parts = $this->getConfigInsuranceParts($nhConfig, $request->input('care_condition')); + $currency_code = $this->getNetworkCurrency($insurance->network_id); $insurance_amount = 0; switch ($act_type) { @@ -2182,13 +2215,15 @@ class HealthCareSheetController extends Controller return $this->errorResponse(trans('errors.unexpected_error')); } + // Montant temporaire de la feuille de soins + $tmp_sheet_amount = NhTmpHealthCareSheet::where('sheet_id', $request->input('tmp_sheet_id'))->sum('insurance_amount'); $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 + // 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; @@ -2201,20 +2236,36 @@ class HealthCareSheetController extends Controller } 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é"); + // Montant de l'assurance deja consomé à date + $insurance_consumed_amount = $insurance_coverage_amount + $tmp_sheet_amount; + $total_insurance_amount = $insurance_consumed_amount + $insurance_amount - $current_insurance_amount; + if ($total_insurance_amount > $monthPrice->max_insurance_coverage_amount) { + return $this->errorResponse(trans('errors.insurance_coverage_amount_exceeded', [ + 'consumption' => $this->toMoneyWithCurrencyCode($insurance_consumed_amount, $currency_code), + 'remaining' => $this->toMoneyWithCurrencyCode($monthPrice->max_insurance_coverage_amount - $insurance_consumed_amount, $currency_code), + ])); } } else { - $total_insurance_amount = $insurance_amount + $insurance->insurance_coverage_amount - $current_insurance_amount; + // Montant de l'assurance deja consomé à date + $insurance_consumed_amount = $insurance->insurance_coverage_amount + $tmp_sheet_amount; foreach ($insurance->beneficiaries as $b) { - $total_insurance_amount += $b->insurance_coverage_amount; + $insurance_consumed_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é"); + $total_insurance_amount = $insurance_consumed_amount + $insurance_amount - $current_insurance_amount; + $family_limit_amount = $monthPrice->max_insurance_coverage_amount * ($insurance->number_of_beneficiaries + 1); + if ($total_insurance_amount > $family_limit_amount) { + return $this->errorResponse(trans('errors.insurance_coverage_amount_exceeded', [ + 'consumption' => $this->toMoneyWithCurrencyCode($insurance_consumed_amount, $currency_code), + 'remaining' => $this->toMoneyWithCurrencyCode($family_limit_amount - $insurance_consumed_amount, $currency_code), + ])); } } + NhTmpHealthCareSheet::create([ + 'sheet_id' => $request->input('tmp_sheet_id'), + 'insurance_amount' => $insurance_amount + ]); + return $this->successResponse("Can be applied"); } } diff --git a/app/Http/Controllers/InsuranceController.php b/app/Http/Controllers/InsuranceController.php index 8b6b4c2..d58c9b1 100644 --- a/app/Http/Controllers/InsuranceController.php +++ b/app/Http/Controllers/InsuranceController.php @@ -204,7 +204,7 @@ class InsuranceController extends Controller $type = $request->input('type'); $pagination = $request->input('pagination'); - $query = NhInsurance::with(['network:id,name', 'beneficiaries'])->where('user_id', $userId); + $query = NhInsurance::with(['network:id,name', 'beneficiaries', 'nhNetworkConfig'])->where('user_id', $userId); if (!empty($state)) { $query = $query->where('state', $state); @@ -228,6 +228,8 @@ class InsuranceController extends Controller $array = $pagination ? $insurances->items() : $insurances; foreach ($array as $insurance) { + $monthPrice = $insurance->nhNetworkConfig->monthsPricesGrid()->where('number_of_months', $insurance->number_of_months)->first(); + $insurance->state = trans('states.' . $insurance->state); if ($type == 'EDITABLE') { @@ -242,11 +244,15 @@ class InsuranceController extends Controller $insurance->state = trans($insurance->state); $insurance->bonus_amount = $this->toMoneyWithCurrencyCode($insurance->bonus_amount, $currency_code); $insurance->total_bonus_amount = $this->toMoneyWithCurrencyCode($insurance->total_bonus_amount, $currency_code); - $insurance->insurance_coverage_amount = $this->toMoneyWithCurrencyCode($insurance->insurance_coverage_amount, $currency_code); + $insurance->insurance_consumed_amount = $this->toMoneyWithCurrencyCode($insurance->insurance_coverage_amount, $currency_code); + $insurance->insurance_remaining_amount = $this->toMoneyWithCurrencyCode(($monthPrice->max_insurance_coverage_amount ?? 0) - $insurance->insurance_coverage_amount, $currency_code); foreach ($insurance->beneficiaries as $b) { $b->bonus_amount = $this->toMoneyWithCurrencyCode($b->bonus_amount, $currency_code); - $b->insurance_coverage_amount = $this->toMoneyWithCurrencyCode($b->insurance_coverage_amount, $currency_code); + $b->insurance_consumed_amount = $this->toMoneyWithCurrencyCode($b->insurance_coverage_amount, $currency_code); + $b->insurance_remaining_amount = $this->toMoneyWithCurrencyCode(($monthPrice->max_insurance_coverage_amount ?? 0) - $b->insurance_coverage_amount, $currency_code); } + + unset($insurance->nhNetworkConfig); } return $this->successResponse($insurances); diff --git a/app/Http/Controllers/InsuredController.php b/app/Http/Controllers/InsuredController.php index 05ce1a1..5819376 100755 --- a/app/Http/Controllers/InsuredController.php +++ b/app/Http/Controllers/InsuredController.php @@ -87,8 +87,9 @@ class InsuredController extends Controller $name = $request->input('name'); $phone = $request->input('phone'); $network_id = $request->input('network_id'); + $currency_code = $this->getNetworkCurrency($network_id); - $q = NhInsurance::with(['user:id,firstname,lastname,phone,email', 'network:id,name', 'beneficiaries'])->where('network_id', $network_id); + $q = NhInsurance::with(['user:id,firstname,lastname,phone,email', 'network:id,name', 'beneficiaries', 'nhNetworkConfig'])->where('network_id', $network_id); if (!empty($insured_id)) { $q = $q->where('insured_id', $insured_id); @@ -107,6 +108,17 @@ class InsuredController extends Controller } $insured = $q->get(); + foreach ($insured as $i) { + $monthPrice = $i->nhNetworkConfig->monthsPricesGrid()->where('number_of_months', $i->number_of_months)->first(); + $i->insurance_consumed_amount = $this->toMoneyWithCurrencyCode($i->insurance_coverage_amount, $currency_code); + $i->insurance_remaining_amount = $this->toMoneyWithCurrencyCode(($monthPrice->max_insurance_coverage_amount ?? 0) - $i->insurance_coverage_amount, $currency_code); + foreach ($i->beneficiaries as $b) { + $b->insurance_consumed_amount = $this->toMoneyWithCurrencyCode($b->insurance_coverage_amount, $currency_code); + $b->insurance_remaining_amount = $this->toMoneyWithCurrencyCode(($monthPrice->max_insurance_coverage_amount ?? 0) - $b->insurance_coverage_amount, $currency_code); + } + + unset($i->nhNetworkConfig); + } return $this->successResponse($insured); } } diff --git a/app/Models/NhNetworksConfig.php b/app/Models/NhNetworksConfig.php index 015ceff..4c8e625 100644 --- a/app/Models/NhNetworksConfig.php +++ b/app/Models/NhNetworksConfig.php @@ -40,7 +40,7 @@ class NhNetworksConfig extends Model 'max_number_of_beneficiaries' => 'int', 'age_limit_of_insured_and_spouse' => 'int', 'age_limit_of_child_beneficiary' => 'int', - 'coverage_limit_per_insured_per_year' => 'float', +// 'coverage_limit_per_insured_per_year' => 'float', 'family_coverage_sharing' => 'boolean', 'current_affection_percentage_insurer' => 'float', 'current_affection_percentage_insured' => 'float', @@ -56,7 +56,7 @@ class NhNetworksConfig extends Model 'max_number_of_beneficiaries', 'age_limit_of_insured_and_spouse', 'age_limit_of_child_beneficiary', - 'coverage_limit_per_insured_per_year', +// 'coverage_limit_per_insured_per_year', 'family_coverage_sharing', 'current_affection_percentage_insurer', 'current_affection_percentage_insured', diff --git a/app/Models/NhTmpHealthCareSheet.php b/app/Models/NhTmpHealthCareSheet.php new file mode 100644 index 0000000..1f97562 --- /dev/null +++ b/app/Models/NhTmpHealthCareSheet.php @@ -0,0 +1,31 @@ +enum('provider_billing_period', ['WEEKLY', 'BIMONTHLY', 'MONTHLY'])->default('WEEKLY')->comment('Période de facturation des prestataires : hebdomadaire ou bimensuel ,mensuel '); $table->decimal('max_number_of_beneficiaries', 1, 0)->default(0)->comment('Nombre d’ayant droit maximum : un nombre à un chiffre'); $table->decimal('age_limit_of_child_beneficiary', 2, 0)->default(0)->comment('Age limite de l’ayant droit enfant : un nombre à 2 chiffres'); - $table->decimal('coverage_limit_per_insured_per_year', 10, 2)->default(0)->comment("Limite de la couverture par assuré par an"); +// $table->decimal('coverage_limit_per_insured_per_year', 10, 2)->default(0)->comment("Limite de la couverture par assuré par an"); $table->decimal('current_affection_percentage_insurer', 3, 0)->default(0)->comment("Affection courante: % part assureur"); $table->decimal('current_affection_percentage_insured', 3, 0)->default(0)->comment("Affection courante: % part assuré"); $table->decimal('long_term_affection_percentage_insurer', 3, 0)->default(0)->comment("Affection longue durée: % part assureur"); diff --git a/database/migrations/2022_02_16_153852_add_family_coverage_sharing_to_nh_networks_configs.php b/database/migrations/2022_02_16_153852_add_family_coverage_sharing_to_nh_networks_configs.php index b66ffc8..3e16e17 100644 --- a/database/migrations/2022_02_16_153852_add_family_coverage_sharing_to_nh_networks_configs.php +++ b/database/migrations/2022_02_16_153852_add_family_coverage_sharing_to_nh_networks_configs.php @@ -14,7 +14,7 @@ class AddFamilyCoverageSharingToNhNetworksConfigs extends Migration public function up() { Schema::table('nh_networks_configs', function (Blueprint $table) { - $table->boolean('family_coverage_sharing')->default(0)->after('coverage_limit_per_insured_per_year') + $table->boolean('family_coverage_sharing')->default(0)->after('age_limit_of_child_beneficiary') ->comment("Mutualisation ou partage de couverture familiale"); }); } diff --git a/database/migrations/2022_02_25_120207_add_max_coverage_amount_to_nh_months_prices_grid.php b/database/migrations/2022_02_25_120207_add_max_coverage_amount_to_nh_months_prices_grid.php new file mode 100644 index 0000000..48e87ea --- /dev/null +++ b/database/migrations/2022_02_25_120207_add_max_coverage_amount_to_nh_months_prices_grid.php @@ -0,0 +1,33 @@ +decimal('max_insurance_coverage_amount', 10)->default(0) + ->after('min_amount')->comment("Montant limite de couverture"); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('nh_months_prices_grid', function (Blueprint $table) { + // + }); + } +} diff --git a/database/migrations/2022_02_25_120459_create_nh_tmp_health_care_sheets.php b/database/migrations/2022_02_25_120459_create_nh_tmp_health_care_sheets.php new file mode 100644 index 0000000..a688e09 --- /dev/null +++ b/database/migrations/2022_02_25_120459_create_nh_tmp_health_care_sheets.php @@ -0,0 +1,33 @@ +id(); + $table->string('sheet_id'); + $table->decimal('insurance_amount', 10); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('nh_tmp_health_care_sheets'); + } +} diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php index 3e6b664..9f313a9 100755 --- a/resources/lang/en/errors.php +++ b/resources/lang/en/errors.php @@ -51,5 +51,9 @@ return [ 'already_insured' => "Vous avez deja souscrit à cette assurance", 'no_sheet_accepted' => "No care sheet accepted", 'no_sheet_available' => "No care sheet available", - "act_not_found" => "Act not found" + "act_not_found" => "Act not found", + 'month_price_grid_not_found' => "La grille tarifaire de ce mois n'existe pas", + "insurance_coverage_amount_exceeded" => "La limite autorisée est dépassée. + Consommation : :consommation + Reste : :remaining" ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index fa7c514..8b45dba 100755 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -51,5 +51,9 @@ return [ '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", - "act_not_found" => "Acte introuvable" + "act_not_found" => "Acte introuvable", + 'month_price_grid_not_found' => "La grille tarifaire de ce mois n'existe pas", + "insurance_coverage_amount_exceeded" => "La limite autorisée est dépassée. + Consommation : :consumption + Reste : :remaining" ];