nanosanteservice/app/Http/Controllers/InsuranceController.php

833 lines
36 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Events\InsuranceEvent;
use App\InsuranceAction;
use App\InsuranceInvoiceState;
use App\InsuranceState;
use App\InsuranceSubscriptionState;
use App\Models\AgentPlus;
use App\Models\CountriesCurrency;
use App\Models\NhInsurance;
use App\Models\NhInsurancesHavingRight;
use App\Models\NhInsurancesInvoice;
use App\Models\NhInsurancesPayment;
use App\Models\NhInsurancesSubscription;
use App\Models\NhInsurancesSubscriptionsHistory;
use App\Models\NhNetworksConfig;
use App\Models\Wallet;
use App\Rules\PasswordValidation;
use App\Traits\Helper;
use DateTime;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use Throwable;
class InsuranceController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* @OA\Get(
* path="/insurances/networks",
* summary="Afficher la liste des reseaux d'assurances ( par pays )",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="country_id",
* name="country_id",
* description="ID du pays",
* in="query",
* required=false,
* @OA\Schema(
* type="integer",
* default=78
* )
* ),
* @OA\Parameter(
* parameter="user_id",
* name="user_id",
* description="ID de l'utilisateur",
* in="query",
* required=false,
* @OA\Schema(
* type="integer",
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":250,"name":"Cnamgs-pharmacies", "age_limit_of_insured_and_spouse" : 30 ,
* "age_limit_of_child_beneficiary": 25 , "max_number_of_beneficiaries":"5", "months_prices":{{"id": 1,"number_of_months":"3","min_amount":"150000 XAF"}}}},
* "error":null
* }
* )
* )
* )
*/
public function getInsurancesNetworks(Request $request)
{
$this->validate($request, [
'country_id' => 'nullable|integer|exists:countries,id',
'user_id' => 'nullable|integer|exists:users,id'
]);
$user_id = $request->input('user_id');
if (!empty($user_id)) {
$insurances = DB::select("SELECT n.id , n.name FROM networks n JOIN configWallet cw ON cw.id_network = n.id JOIN nh_networks_configs nhc
ON nhc.network_id = n.id JOIN nh_insurances nhi ON nhi.network_id = n.id WHERE nhi.user_id = :user_id AND cw.type = 'ilink_sante' AND n.status = 1", ['user_id' => $user_id]);
} else {
$insurances = DB::select("SELECT n.id , n.name , nhc.age_limit_of_insured_and_spouse, nhc.age_limit_of_child_beneficiary, nhc.max_number_of_beneficiaries, nhc.family_coverage_sharing, nhc.id as nhc_id
FROM networks n JOIN configWallet cw ON cw.id_network = n.id JOIN nh_networks_configs nhc
ON nhc.network_id = n.id WHERE n.country_id = :countryId AND cw.type = 'ilink_sante' AND n.status = 1", ['countryId' => $request->input('country_id')]);
foreach ($insurances as $network) {
$this->formatInsuranceNetwork($network);
}
}
return $this->successResponse($insurances);
}
/**
* @OA\Get(
* path="/insurances/networks/{id}",
* summary="Afficher les infos sur un reseau d'assurance",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="id",
* name="id",
* description="ID du reseau",
* in="path",
* required=false,
* @OA\Schema(
* type="integer",
* default=78
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":250,"name":"Cnamgs-pharmacies", "age_limit_of_insured_and_spouse" : 30 ,
* "age_limit_of_child_beneficiary": 25 , "max_number_of_beneficiaries":"5", "months_prices":{{"id": 1,"number_of_months":"3","min_amount":"150000 XAF"}}}},
* "error":null
* }
* )
* )
* )
*/
public function getSingleInsuranceNetwork($id)
{
$insurance_network = current(DB::select("SELECT n.id , n.name , nhc.age_limit_of_insured_and_spouse, nhc.age_limit_of_child_beneficiary, nhc.max_number_of_beneficiaries, nhc.family_coverage_sharing, nhc.id as nhc_id
FROM networks n JOIN configWallet cw ON cw.id_network = n.id JOIN nh_networks_configs nhc
ON nhc.network_id = n.id WHERE nhc.network_id = :network_id AND cw.type = 'ilink_sante' AND n.status = 1", ['network_id' => $id]));
if (!$insurance_network)
return $this->errorResponse(trans('errors.network_not_found'));
$this->formatInsuranceNetwork($insurance_network);
return $this->successResponse($insurance_network);
}
private function formatInsuranceNetwork($insurance_network): void
{
$months_prices = DB::select("SELECT id , number_of_months , min_amount , max_insurance_coverage_amount, waiting_period_days, payment_period , number_of_fractions FROM nh_months_prices_grid
WHERE nh_network_config_id = :nhc_id ORDER BY number_of_fractions ASC",
['nhc_id' => $insurance_network->nhc_id]);
$years_prices = DB::select("SELECT min_age , max_age , markup_percentage FROM nh_years_prices_grid WHERE nh_network_config_id = :nhc_id",
['nhc_id' => $insurance_network->nhc_id]);
foreach ($months_prices as $mp) {
foreach ($years_prices as $cp) {
$cp->amount = $this->toMoneyWithCurrencyCode(round((100 + $cp->markup_percentage) * $mp->min_amount / 100), $country->currency_code ?? 'XAF');
}
$mp->min_amount = $this->toMoneyWithCurrencyCode($mp->min_amount, $country->currency_code ?? 'XAF');
$mp->max_insurance_coverage_amount = $this->toMoneyWithCurrencyCode($mp->max_insurance_coverage_amount, $country->currency_code ?? 'XAF');
$mp->payment_period = trans('states.' . $mp->payment_period);
$mp->child_prices = $years_prices;
}
foreach ($months_prices as $mp) {
foreach ($mp->child_prices as $cp) {
unset($cp->markup_percentage);
}
}
$insurance_network->months_prices = $months_prices;
unset($insurance_network->nhc_id);
}
/**
* @OA\Get(
* path="/insurances",
* summary="Afficher la liste des assurances ( par utilisateur et par type )",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="user_id",
* name="user_id",
* description="ID de l'utilisateur",
* in="query",
* required=true,
* @OA\Schema(
* type="integer",
* default=78
* )
* ),
* @OA\Parameter(
* parameter="type",
* name="type",
* description="Type d'assurance",
* in="query",
* required=false,
* @OA\Schema(
* type="string",
* enum={"ALL","EDITABLE","STOPPED"}
* )
* ),
* @OA\Parameter(
* parameter="page",
* name="page",
* description="Page",
* in="query",
* required=false,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* parameter="perPage",
* name="perPage",
* description="Pas de pagination",
* in="query",
* required=false,
* @OA\Schema(
* type="integer"
* )
* ),
* @OA\Parameter(
* parameter="pagination",
* name="pagination",
* description="pagination",
* in="query",
* required=false,
* @OA\Schema(
* type="boolean",
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":3,"insured_id":"GJZF4VK69V6S","start_at":"2021-11-08T13:13:27.000000Z",
* "end_at":"2022-02-08T13:13:27.000000Z","state":"PAY\u00c9E","created_at":"2021-11-08T12:13:27.000000Z","updated_at":"2021-11-08T12:13:27.000000Z",
* "network_id":250,"user_id":349,"number_of_months":3,"bonus_amount":"150\u202f000\u00a0FCFA",
* "number_of_beneficiaries":2,"total_bonus_amount":"495\u202f000\u00a0FCFA","network": { "id": 250, "name": "Cnamgs-pharmacies", "age_limit_of_insured_and_spouse": 30,
* "age_limit_of_child_beneficiary": 25, "max_number_of_beneficiaries": 5 },"beneficiaries":{{"id":5,"insurance_subscription_id":"3QM2DS9V4KEG",
* "lastname":"Djery","firstname":"DI","gender":"M","birthdate":"2001-10-05T00:00:00.00000 0Z","affiliation":"CHILD","bonus_amount":"195\u202f000\u00a0FCFA",
* "birthdate_proof":"CERTIFIED_COPY","birthdate_proof_doc":"birth.jpg","justice_doc":"just.png","marriage_certificate_doc":null,"id_document_type":null,
* "id_document_front":null,"id_document_back":null,"deleted_at":null,"created_at":"2021-11-01T15:18:34.000000Z","updated_at":"2021-11-01T15:18:34.000000Z","affiliation_tr":"ENFANT"}}}},
* "error":null
* }
* )
* )
* )
*/
public function getInsurances(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer|exists:users,id',
'type' => 'nullable|in:ALL,EDITABLE,STOPPED',
'pagination' => 'nullable|boolean'
]);
$userId = $request->input('user_id');
$type = $request->input('type');
$pagination = $request->input('pagination');
$query = NhInsurance::with(['network:id,name', 'beneficiaries', 'nhNetworkConfig'])->where('user_id', $userId);
if (!empty($state)) {
$query = $query->where('state', $state);
}
if (!empty($type)) {
if ($type == 'EDITABLE') {
$query = $query->whereIn('state', [InsuranceState::PAID, InsuranceState::PARTIALLY_PAID]);
}
if ($type == 'STOPPED') {
$query = $query->whereIn('state', [InsuranceState::STOPPED, InsuranceState::EXPIRED]);
}
}
$query = $query->orderBy('created_at', 'DESC');
if ($pagination) {
$insurances = $query->paginate($request->input('perPage', 10));
} else {
$insurances = $query->get();
}
$array = $pagination ? $insurances->items() : $insurances;
foreach ($array as $insurance) {
$monthPrice = $insurance->monthsGrid;
$insurance->state = trans('states.' . $insurance->state);
if ($type == 'EDITABLE') {
// Nécessaire seulement lors de la modification ( ajout de ayant droit)
$config = NhNetworksConfig::where('network_id', $insurance->network->id)->firstOrFail();
$insurance->network->age_limit_of_insured_and_spouse = $config->age_limit_of_insured_and_spouse;
$insurance->network->age_limit_of_child_beneficiary = $config->age_limit_of_child_beneficiary;
$insurance->network->max_number_of_beneficiaries = $config->max_number_of_beneficiaries;
}
$currency_code = $this->getNetworkCurrency($insurance->network_id);
$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_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_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);
}
/**
* @OA\Put(
* path="/insurances/{id}/add-beneficiaries",
* summary="Ajouter des ayants droits ou beneficiaires à une assurance",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="id",
* name="id",
* description="ID de l'assurance",
* in="path",
* required=true,
* @OA\Schema(
* type="integer",
* default=12
* )
* ),
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/add_beneficiaries"),
* example = {"password" : "1234", "beneficiaries":{{"lastname":"Djery","firstname":"DI","gender":"M","birthdate":"2001-10-05",
* "affiliation":"CHILD","birthdate_proof":"CERTIFIED_COPY","birthdate_proof_doc":"birth.jpg","justice_doc":"just.png","marriage_certificate_doc":"mariage.png",
* "id_document_type":"CNI","id_document_front":"cni_front.jpg","id_document_back":"cni_front.jpg","profile_image":"profile_image.jpg"}}}
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {"status":200,"response":"Transaction réussie","error":null}
* )
* )
* )
* @throws \App\Exceptions\AppException
*/
public function addBeneficiaries(Request $request, $id)
{
/**
* @OA\Schema(
* schema="add_beneficiaries",
* title = "Ajouter des beneficiaires à une assurance",
* required={"password", "beneficiaries"},
* @OA\Property(property="password",
* type="string",
* example="2021469",
* description="Mot de passe de l'utilisateur assuré"
* ),
* @OA\Property(property="beneficiaries",
* type="array",
* description="Listes des beneficiaires ou ayants droit",
* @OA\Items(ref="#/components/schemas/beneficiaries")
* )
* )
*
*/
$this->validate($request, [
'password' => 'required|string',
'beneficiaries' => 'nullable|array',
'beneficiaries.*.lastname' => 'required|string',
'beneficiaries.*.gender' => 'required|in:M,F',
'beneficiaries.*.birthdate' => 'required|date_format:Y-m-d|before:today',
'beneficiaries.*.affiliation' => 'required|in:CHILD,SPOUSE',
'beneficiaries.*.birthdate_proof' => 'required_if:beneficiaries.*.affiliation,CHILD|in:CERTIFIED_COPY,CERTIFICATE',
'beneficiaries.*.birthdate_proof_doc' => 'required_if:beneficiaries.*.affiliation,CHILD|string',
'beneficiaries.*.justice_doc' => 'nullable|string',
'beneficiaries.*.marriage_certificate_doc' => 'required_if:beneficiaries.*.affiliation,SPOUSE|string',
'beneficiaries.*.id_document_type' => 'required_if:beneficiaries.*.affiliation,SPOUSE|string',
'beneficiaries.*.id_document_front' => 'required_if:beneficiaries.*.affiliation,SPOUSE|string',
'beneficiaries.*.id_document_back' => 'required_if:beneficiaries.*.affiliation,SPOUSE|string',
'beneficiaries.*.profile_image' => 'required|string',
]);
$insurance = NhInsurance::findOrFail($id);
$this->insuranceVerification($insurance);
$this->latestSubscriptionVerification($request->input('network_id'), $request->input('user_id'));
$user = $insurance->user;
$identification = $insurance->user->identification;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
// $this->validate($request, [
// 'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
// ]);
$nbOfBeneficiaries = $insurance->beneficiaries()->count();
$networkConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first();
if ((sizeof($request->input('beneficiaries', [])) + $nbOfBeneficiaries) > $networkConfig->max_number_of_beneficiaries)
return $this->errorResponse(trans('errors.number_of_beneficiaries_exceeded'));
$monthPrice = $insurance->monthsGrid;
try {
DB::beginTransaction();
$datetime = $this->getCurrentTimeByCountryCode($networkConfig->network->country->code_country);
// Creer une nouvelle subscription
$newSubscription = NhInsurancesSubscription::create([
'network_id' => $insurance->network_id,
'user_id' => $insurance->user_id,
'insurance_subscription_id' => $this->generateSubscriptionID(),
'number_of_beneficiaries' => sizeof($request->input('beneficiaries', [])),
'months_grid_id' => $monthPrice->id,
'bonus_amount' => $monthPrice->min_amount,
'insurance_action' => InsuranceAction::ADDITION_OF_BENEFICIARY,
'state' => InsuranceSubscriptionState::UNDER_VALIDATION,
]);
// Ajouter les nouveaux ayant droit
$beneficiariesBonus = $this->storeBeneficiariesAndGetBonus($newSubscription, $request, $networkConfig, $monthPrice, $datetime);
$newSubscription->total_bonus_amount = $beneficiariesBonus; // Le total contient uniquement le montant la prime des ayants droits en cas
$newSubscription->created_at = $newSubscription->updated_at = $datetime;
$newSubscription->save();
NhInsurancesSubscriptionsHistory::create([
'action' => 'ADD',
'insurance_subscription_id' => $newSubscription->insurance_subscription_id,
'insurance_subscription_state' => $newSubscription->state,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
Event::dispatch(new InsuranceEvent($newSubscription, trans('messages.insurance_addition_beneficiary'), trans('messages.insurance_addition_beneficiary_mail', ['name' => $newSubscription->user->lastname, 'subscription_id' => $newSubscription->insurance_subscription_id,
'bonus_amount' => $this->toMoneyWithNetwork($newSubscription->total_bonus_amount, $newSubscription->network_id), 'number_of_beneficiaries' => $newSubscription->number_of_beneficiaries,
'gender' => trans('states.' . $identification->gender), 'insurance_name' => $networkConfig->network->name])));
DB::commit();
return $this->successResponse(trans('messages.insurance_addition_beneficiary_successful'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();
return $this->errorResponse(trans('errors.unexpected_error'), 500);
}
}
/**
* @OA\Put(
* path="/insurances/{id}/delete-beneficiaries",
* summary="Supprimer des ayants droits ou beneficiaires à une assurance",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="id",
* name="id",
* description="ID de l'assurance",
* in="path",
* required=true,
* @OA\Schema(
* type="integer",
* default=12
* )
* ),
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(ref="#/components/schemas/delete_beneficiaries"),
* example = {"password" : "1234", "beneficiaries_ids":{ 1, 4, 5}}
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {"status":200,"response":"Suprresion réussie","error":null}
* )
* )
* )
* @throws \App\Exceptions\AppException
*/
public function deleteBeneficiaries(Request $request, $id)
{
/**
* @OA\Schema(
* schema="delete_beneficiaries",
* title = "Supprimer des beneficiaires à une assurance",
* required={"password", "beneficiaries"},
* @OA\Property(property="password",
* type="string",
* example="2021469",
* description="Mot de passe de l'utilisateur assuré"
* ),
* @OA\Property(property="beneficiaries_ids",
* type="array",
* description="Listes des IDs beneficiaires ou ayants droit",
* @OA\Items(type="integer", format="binary")
* )
* )
*
*/
$this->validate($request, [
// 'password' => 'required|string',
'beneficiaries_ids' => 'required|array',
'beneficiaries_ids.*' => 'required|integer|exists:nh_having_rights,id',
]);
$insurance = NhInsurance::findOrFail($id);
$this->insuranceVerification($insurance);
$user = $insurance->user;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
$this->validate($request, [
'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
]);
$current_beneficiaries_ids = array_map(function ($b) {
return $b['id'];
}, $insurance->beneficiaries->toArray());
foreach ($request->input('beneficiaries_ids') as $index => $id) {
if (!in_array($id, $current_beneficiaries_ids)) {
return $this->errorResponse(__('errors.beneficiary_not_part_in_insurance', ['id' => $index + 1]));
}
}
try {
DB::beginTransaction();
$datetime = $this->getCurrentTimeByCountryCode($user->network->country->code_country);
$beneficiaries = NhInsurancesHavingRight::where('insurance_id', $insurance->id)->whereIn('having_right_id', $request->input('beneficiaries_ids'))->get();
$beneficiariesBonus = 0;
foreach ($beneficiaries as $b) {
$beneficiariesBonus += $b->beneficiary->bonus_amount;
}
$insurance->number_of_beneficiaries -= sizeof($beneficiaries);
$insurance->total_bonus_amount -= $beneficiariesBonus;
$insurance->updated_at = $datetime;
$insurance->save();
// Supprimer ces beneficiares de l'assurance
$beneficiaries->each->delete();
DB::commit();
return $this->successResponse(trans('messages.insurance_deletion_beneficiary_successful'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();
return $this->errorResponse(trans('errors.unexpected_error'), 500);
}
}
/**
* @OA\Put(
* path="/insurances/{id}/stop",
* summary="Arreter son assurance",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="id",
* name="id",
* description="ID de l'assurance",
* in="path",
* required=true,
* @OA\Schema(
* type="integer",
* default=12
* )
* ),
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="password",
* description = "Mot de passe",
* type="string",
* example= "12345"
* ),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {"status":200,"response":"Operation réussie","error":null}
* )
* )
* )
* @throws Exception
*/
public function stopInsurance(Request $request, $id)
{
// $this->validate($request, [
// 'password' => 'required|string',
// ]);
$insurance = NhInsurance::findOrFail($id);
$user = $insurance->user;
$identification = $insurance->user->identification;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
$this->validate($request, [
'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
]);
$this->insuranceVerification($insurance);
$this->latestSubscriptionVerification($insurance->network_id, $insurance->user_id);
if (NhInsurancesInvoice::where('insurance_id', $id)->where('state', InsuranceInvoiceState::UNPAID)->count() > 0) {
return $this->errorResponse(trans('errors.unpaid_bill'));
}
try {
DB::beginTransaction();
$datetime = $this->getCurrentTimeByCountryCode($user->network->country->code_country);
$newSubscription = NhInsurancesSubscription::create([
'network_id' => $insurance->network_id,
'user_id' => $insurance->user_id,
'insurance_subscription_id' => $this->generateSubscriptionID(),
'number_of_beneficiaries' => $insurance->number_of_beneficiaries,
'months_grid_id' => $insurance->months_grid_id,
'bonus_amount' => $insurance->bonus_amount,
'total_bonus_amount' => $insurance->total_bonus_amount,
'insurance_action' => InsuranceAction::STOP_INSURANCE,
'state' => InsuranceSubscriptionState::UNDER_VALIDATION,
]);
$newSubscription->created_at = $newSubscription->updated_at = $datetime;
$newSubscription->save();
foreach ($insurance->beneficiaries as $beneficiary) {
NhInsurancesHavingRight::create([
'insurance_subscription_id' => $newSubscription->id,
'having_right_id' => $beneficiary->id,
]);
}
Event::dispatch(new InsuranceEvent($newSubscription, trans('messages.insurance_stop'), trans('messages.insurance_stop_mail', ['name' => $newSubscription->user->lastname, 'subscription_id' => $newSubscription->insurance_subscription_id,
'bonus_amount' => $this->toMoneyWithNetwork($newSubscription->total_bonus_amount, $newSubscription->network_id), 'number_of_beneficiaries' => $newSubscription->number_of_beneficiaries,
'gender' => trans('states.' . $identification->gender), 'insurance_name' => $insurance->network->name])));
DB::commit();
return $this->successResponse(trans('messages.insurance_stop_successful'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();
return $this->errorResponse(trans('errors.unexpected_error'), 500);
}
}
/**
* @OA\Put(
* path="/insurances/{id}/renew",
* summary="Renouveller son assurance",
* tags={"Assurances"},
* security={{"api_key":{}}},
* @OA\Parameter(
* parameter="id",
* name="id",
* description="ID de l'assurance",
* in="path",
* required=true,
* @OA\Schema(
* type="integer",
* default=12
* )
* ),
* @OA\RequestBody(
* description="Corps de la requete",
* required=true,
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="password",
* description = "Mot de passe",
* type="string",
* example= "12345"
* ),
* @OA\Property(
* property="month_price_id",
* description = "Mot de passe",
* type="string",
* example= "12345"
* ),
* ),
* ),
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {"status":200,"response":"Operation réussie","error":null}
* )
* )
* )
* @throws Exception
*/
public function renewInsurance(Request $request, $id)
{
$this->validate($request, [
'password' => 'required|string',
'month_price_id' => 'required|integer|exists:nh_months_prices_grid,id'
]);
$insurance = NhInsurance::findOrFail($id);
if (!in_array($insurance->state, [InsuranceState::STOPPED, InsuranceState::EXPIRED])) {
return $this->errorResponse(__('errors.cannot_renew_insurance'));
}
if (NhInsurancesInvoice::where('insurance_id', $id)->where('state', InsuranceInvoiceState::UNPAID)->count() > 0) {
return $this->errorResponse(trans('errors.unpaid_bill'));
}
$user = $insurance->user;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
// $this->validate($request, [
// 'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
// ]);
$networkConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first();
if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante')
return $this->errorResponse(trans('errors.nano_health_not_activated'));
$monthPrice = $networkConfig->monthsPricesGrid()->where('id', $request->input('month_price_id'))->first();
if (!isset($monthPrice))
return $this->errorResponse(trans('errors.incorrect_selected_amount'));
// Verification de l'age du beneficiaire
$insuredAge = date_diff(date_create($user->identification->birth_date), date_create('now'))->y;
if ($insuredAge > $networkConfig->age_limit_of_insured_and_spouse) {
return $this->errorResponse(trans('errors.minimal_age_required'));
}
if (sizeof($insurance->beneficiaries) > $networkConfig->max_number_of_beneficiaries)
return $this->errorResponse(trans('errors.number_of_beneficiaries_exceeded'));
$currency = $this->getNetworkCurrency($insurance->network_id);
try {
DB::beginTransaction();
$bonus_amount = $monthPrice->min_amount; // Montant de la prime de l'assuré principal
$beneficiaries_bonus_amount = 0; // Montant total de la prime des ayant droits
foreach ($insurance->beneficiaries as $beneficiary) {
$amount = $this->calculateBeneficiaryBonusAmount($beneficiary, $networkConfig->yearsPricesGrid, $monthPrice);
$beneficiaries_bonus_amount += $amount;
$beneficiary->bonus_amount = $amount;
$beneficiary->save();
}
$total_bonus_amount = $bonus_amount + $beneficiaries_bonus_amount;
$amount_per_split = ceil($total_bonus_amount / $monthPrice->number_of_fractions);
$amount_last_payment = $total_bonus_amount - ($amount_per_split * ($monthPrice->number_of_fractions - 1));
$datetime = $this->getCurrentTimeByCountryCode($user->network->country->code_country);
$insurance->update([
'months_grid_id' => $monthPrice->id,
'number_of_beneficiaries' => sizeof($insurance->beneficiaries),
'total_bonus_amount' => $total_bonus_amount,
'bonus_amount' => $bonus_amount,
'insurance_coverage_amount' => 0,
'updated_at' => $datetime,
'state' => InsuranceState::UNDER_RENEW,
'start_at' => null,
'end_at' => null,
]);
// Reinitialiser les montants de couvertures de l'assurance
$insurance->beneficiaries->each->update([
'insurance_coverage_amount' => 0
]);
// Generer la facture
NhInsurancesInvoice::create([
'invoice_id' => $this->generateInsuranceInvoiceID(),
'insurance_id' => $insurance->id,
'amount' => $total_bonus_amount,
'next_payment_deadline' => $this->addDaysToDateTime($datetime, $networkConfig->reminder_delay_days + $networkConfig->suspension_delay_days_after_reminder),
'next_payment_reminder' => $this->addDaysToDateTime($datetime, $networkConfig->reminder_delay_days),
'deadlines' => $monthPrice->number_of_fractions,
'paid_deadlines' => 1,
'next_payment_deadlines_to_paid' => 1,
'amount_per_split' => $amount_per_split,
'amount_last_payment' => $amount_last_payment,
'state' => InsuranceInvoiceState::UNPAID,
'reason' => InsuranceAction::RENEWAL,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
Event::dispatch(new InsuranceEvent($insurance, trans('messages.insurance_renew'), trans('messages.insurance_renew_mail', ['name' => $user->lastname, 'insured_id' => $insurance->insured_id,
'bonus_amount' => $this->toMoneyWithCurrencyCode($bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($total_bonus_amount, $currency), 'number_of_beneficiaries' => $insurance->number_of_beneficiaries,
'gender' => trans('states.' . $user->identification->gender), 'insurance_name' => $insurance->network->name, 'months' => $monthPrice->number_of_months])));
DB::commit();
return $this->successResponse(trans('messages.insurance_renew_done'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();
return $this->errorResponse(trans('errors.unexpected_error'), 500);
}
}
}