From b339341e8ab6d836b509b3667b0c4c43ddfe9e51 Mon Sep 17 00:00:00 2001 From: Djery-Tom Date: Mon, 1 Nov 2021 15:26:21 +0100 Subject: [PATCH] Add routes to add beneficiaries --- app/Http/Controllers/InsuranceController.php | 272 ++++++++++++++++--- app/Models/NhInsurancesHavingRight.php | 4 - app/Models/NhInsurancesSubscription.php | 19 +- resources/lang/en/errors.php | 3 +- resources/lang/en/messages.php | 4 +- resources/lang/fr/errors.php | 3 +- resources/lang/fr/messages.php | 4 +- routes/web.php | 1 + 8 files changed, 252 insertions(+), 58 deletions(-) diff --git a/app/Http/Controllers/InsuranceController.php b/app/Http/Controllers/InsuranceController.php index 2db17fe..4fc785b 100644 --- a/app/Http/Controllers/InsuranceController.php +++ b/app/Http/Controllers/InsuranceController.php @@ -13,6 +13,7 @@ use App\Models\NhInsurancesSubscription; use App\Models\NhInsurancesSubscriptionsHistory; use App\Models\NhMonthsPricesGrid; use App\Models\NhNetworksConfig; +use App\Models\User; use App\Traits\Helper; use Illuminate\Database\Eloquent\Collection; use Illuminate\Http\Request; @@ -98,7 +99,7 @@ class InsuranceController extends Controller * @OA\Post( * path="/insurances/subscriptions/bonus-amount", * summary="Calculer le montant de la prime", - * tags={"Assurances"}, + * tags={"Souscriptions à l'assurance"}, * security={{"api_key":{}}}, * @OA\RequestBody( * description="Corps de la requete", @@ -106,6 +107,11 @@ class InsuranceController extends Controller * @OA\MediaType( * mediaType="application/json", * @OA\Schema( + * @OA\Property(property="subscription_id", + * type="integer", + * example = 2, + * description="ID de la souscription" + * ), * @OA\Property(property="network_id", * type="integer", * example = 250, @@ -138,23 +144,35 @@ class InsuranceController extends Controller public function calculateBonusAmount(Request $request) { $this->validate($request, [ - 'network_id' => 'required|integer|exists:networks,id', - 'month_price_id' => 'required|integer|exists:nh_months_prices_grid,id', + 'subscription_id' => 'nullable|integer|exists:nh_insurances_subscriptions,id', + 'network_id' => 'required_without:subscription_id|integer|exists:networks,id', + 'month_price_id' => 'required_without:subscription_id|integer|exists:nh_months_prices_grid,id', 'beneficiaries' => 'nullable|array', 'beneficiaries.*.birthdate' => 'required|date_format:Y-m-d|before:today', 'beneficiaries.*.affiliation' => 'required|in:CHILD,SPOUSE' ]); - $networkConfig = NhNetworksConfig::where('network_id', $request->input('network_id'))->first(); - if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante') - return $this->errorResponse(trans('errors.nano_health_not_activated')); + if ($request->has('subscription_id')) { + $subscription = NhInsurancesSubscription::findOrFail($request->input('subscription_id')); + $networkConfig = $subscription->nhNetworkConfig; + $monthPrice = $networkConfig->monthsPricesGrid()->where('number_of_months', $subscription->number_of_months)->first(); + + $beneficiaries = array_merge($subscription->beneficiaries->toArray(), $request->input('beneficiaries')); + } else { + $networkConfig = NhNetworksConfig::where('network_id', $request->input('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(); + + $beneficiaries = $request->input('beneficiaries'); + } - $monthPrice = $networkConfig->monthsPricesGrid()->where('id', $request->input('month_price_id'))->first(); if (!isset($monthPrice)) return $this->errorResponse(trans('errors.incorrect_selected_amount')); $bonus = $monthPrice->min_amount; - foreach ($request->input('beneficiaries') as $b) { + foreach ($beneficiaries as $b) { $bonus += $this->calculateBeneficiaryBonusAmount(new NhInsurancesHavingRight($b), $networkConfig->yearsPricesGrid, $monthPrice); } @@ -190,7 +208,7 @@ class InsuranceController extends Controller * @OA\Post( * path="/insurances/subscriptions", * summary="Souscrire à une assurance", - * tags={"Assurances"}, + * tags={"Souscriptions à l'assurance"}, * security={{"api_key":{}}}, * @OA\RequestBody( * description="Corps de la requete", @@ -231,8 +249,8 @@ class InsuranceController extends Controller * description="ID l'utilisateur identifié" * ), * @OA\Property(property="password", - * type="integer", - * example=300, + * type="string", + * example="20214666", * description="Mot de passe de l'utilisateur identifié" * ), * @OA\Property(property="month_price_id", @@ -375,27 +393,7 @@ class InsuranceController extends Controller $subscription->insurance_subscription_id = $this->generateSubscriptionID(); $subscription->number_of_months = $monthPrice->number_of_months; $subscription->bonus_amount = $monthPrice->min_amount; - $subscription->state = InsuranceSubscriptionState::UNDER_VALIDATION; - - $beneficiariesBonus = 0; - foreach ($request->input('beneficiaries') as $b) { - $beneficiary = new NhInsurancesHavingRight($b); - $beneficiary->insurance_subscription_id = $subscription->insurance_subscription_id; - $beneficiary->bonus_amount = $this->calculateBeneficiaryBonusAmount($beneficiary, $networkConfig->yearsPricesGrid, $monthPrice); - $beneficiariesBonus += $beneficiary->bonus_amount; - if ($beneficiary->affiliation == InsuranceSubscriptionAffiliation::CHILD) { - $beneficiary->marriage_certificate_doc = null; - $beneficiary->id_document_type = null; - $beneficiary->id_document_back = null; - $beneficiary->id_document_front = null; - } else { - $beneficiary->justice_doc = null; - $beneficiary->birthdate_proof_doc = null; - $beneficiary->birthdate_proof = null; - } - $beneficiary->created_at = $beneficiary->updated_at = $datetime; - $beneficiary->save(); - } + $beneficiariesBonus = $this->storeBeneficiariesAndGetBonus($subscription, $request, $networkConfig, $monthPrice, $datetime); $subscription->total_bonus_amount = ($subscription->bonus_amount + $beneficiariesBonus); $subscription->created_at = $subscription->updated_at = $datetime; @@ -426,8 +424,8 @@ class InsuranceController extends Controller /** * @OA\Post( * path="/insurances/subscriptions/upload-images", - * summary="Uploader les images de l'assurance", - * tags={"Assurances"}, + * summary="Uploader les images de la souscription à l'assurance", + * tags={"Souscriptions à l'assurance"}, * security={{"api_key":{}}}, * @OA\RequestBody( * description="Corps de la requete", @@ -541,8 +539,8 @@ class InsuranceController extends Controller /** * @OA\Get( * path="/insurances/subscriptions", - * summary="Afficher la liste des souscriptions d'assurances ( par utilisateur )", - * tags={"Assurances"}, + * summary="Afficher la liste des souscriptions d'assurances ( par utilisateur , par type)", + * tags={"Souscriptions à l'assurance"}, * security={{"api_key":{}}}, * @OA\Parameter( * parameter="user_id", @@ -555,6 +553,17 @@ class InsuranceController extends Controller * default=325 * ) * ), + * @OA\Parameter( + * parameter="type", + * name="type", + * description="Type de souscription", + * in="query", + * required=true, + * @OA\Schema( + * type="string", + * enum={"ALL","EDITABLE"} + * ) + * ), * @OA\Response( * response=200, * description="OK", @@ -562,8 +571,13 @@ class InsuranceController extends Controller * 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"}}}}, + * "response" : {{"id":1,"insurance_subscription_id":"BOKWRWZ245JX","network_id":250,"user_id":321,"number_of_months":3, + * "bonus_amount":"150\u202f000\u00a0FCFA","number_of_beneficiaries":2,"total_bonus_amount":"495\u202f000\u00a0FCFA","state":"EN COURS DE VALIDATION", + * "created_at":"2021-10-29T14:26:05.000000Z","updated_at":"2021-10-29T14:26:05.000000Z","start_at":null,"end_at":null,"reason":null, + * "beneficiaries":{{"id":1,"insurance_subscription_id":"BOKWRWZ245JX","lastname":"Djery","firstname":"DI","gender":"M","birthdate":"2001-10-05T00:00:00.000000Z", + * "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-10-29T14:26:05.000000Z", + * "updated_at":"2021-10-29T14:26:05.000000Z","affiliation_tr":"ENFANT"}}}}, * "error":null * } * ) @@ -573,16 +587,164 @@ class InsuranceController extends Controller public function getSubscriptions(Request $request) { $this->validate($request, [ - 'user_id' => 'nullable|integer|exists:users,id' + 'user_id' => 'nullable|integer|exists:users,id', + 'type' => 'nullable|in:ALL,EDITABLE' ]); - $subscriptions = NhInsurancesSubscription::with(['beneficiaries'])->where('user_id', $request->input('user_id'))->get(); + $user = User::findOrFail($request->input('user_id')); + $currency_code = $user->network->country->currency_code; + + $query = NhInsurancesSubscription::with(['network:id,name', 'beneficiaries']); + + if ($request->has('user_id')) { + $query = $query->where('user_id', $request->input('user_id')); + } + if ($request->has('type')) { + $type = $request->input('type'); + if ($type == 'EDITABLE') { + $query = $query->whereIn('state', [InsuranceSubscriptionState::UNDER_VALIDATION, InsuranceSubscriptionState::ACCEPTED]); + } + } + + $subscriptions = $query->get(); foreach ($subscriptions as $subscription) { $subscription->state = trans('states.' . $subscription->state); - $subscription->bonus_amount = trans('states.' . $subscription->state); + $subscription->bonus_amount = $this->toMoneyWithCurrencyCode($subscription->bonus_amount, $currency_code); + $subscription->total_bonus_amount = $this->toMoneyWithCurrencyCode($subscription->total_bonus_amount, $currency_code); + foreach ($subscription->beneficiaries as $b) { + $b->bonus_amount = $this->toMoneyWithCurrencyCode($b->bonus_amount, $currency_code); + } } return $this->successResponse($subscriptions); } + + /** + * @OA\Put( + * path="/insurances/subscriptions/{id}", + * summary="Ajouter des ayants droits ou beneficiaires à une souscription", + * tags={"Souscriptions à l'assurance"}, + * security={{"api_key":{}}}, + * @OA\Parameter( + * parameter="id", + * name="id", + * description="ID de la souscription", + * 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"}}} + * ) + * ), + * @OA\Response( + * response=200, + * description="OK", + * @OA\JsonContent( + * ref="#/components/schemas/ApiResponse", + * example = {"status":200,"response":"Transaction réussie","error":null} + * ) + * ) + * ) + */ + 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', + ]); + + $subscription = NhInsurancesSubscription::findOrFail($id); + if (!in_array($subscription->state, [InsuranceSubscriptionState::UNDER_VALIDATION, InsuranceSubscriptionState::ACCEPTED])) { + return $this->errorResponse(trans('errors.subscription_cannot_be_updated')); + } + $user = $subscription->user; + $identification = $subscription->user->identification; + + if (!isset($identification) || $identification->status == 0) + return $this->errorResponse(trans('errors.user_identification_required')); + + if (!$this->checkPassword($request->password, $user->encrypted_password, $user->salt)) + return $this->errorResponse(trans('messages.incorrect_user_password')); + + $nbOfBeneficiaries = $subscription->beneficiaries()->count(); + $networkConfig = NhNetworksConfig::where('network_id', $subscription->network_id)->first(); + if ((sizeof($request->input('beneficiaries')) + $nbOfBeneficiaries) > $networkConfig->max_number_of_beneficiaries) + return $this->errorResponse(trans('errors.number_of_beneficiaries_exceeded')); + + $monthPrice = $networkConfig->monthsPricesGrid()->where('number_of_months', $subscription->number_of_months)->first(); + if (!isset($monthPrice)) + return $this->errorResponse(trans('errors.incorrect_selected_amount')); + + try { + DB::beginTransaction(); + $datetime = $this->getCurrentTimeByCountryCode($networkConfig->network->country->code_country); + $subscription->number_of_beneficiaries += sizeof($request->input('beneficiaries')); + + $beneficiariesBonus = $this->storeBeneficiariesAndGetBonus($subscription, $request, $networkConfig, $monthPrice, $datetime); + + $subscription->total_bonus_amount += $beneficiariesBonus; + $subscription->created_at = $subscription->updated_at = $datetime; + $subscription->save(); + + NhInsurancesSubscriptionsHistory::create([ + 'action' => 'EDIT', + 'insurance_subscription_id' => $subscription->insurance_subscription_id, + 'insurance_subscription_state' => $subscription->state, + 'insurance_subscription' => json_encode($subscription), + 'created_at' => $datetime, 'updated_at' => $datetime, + ]); + + Event::dispatch(new InsuranceEvent($subscription, trans('messages.insurance_subscription_updated'), trans('messages.insurance_subscription_mail', ['name' => $subscription->user->lastname, 'subscription_id' => $subscription->insurance_subscription_id, + 'bonus_amount' => $this->toMoneyWithNetwork($subscription->total_bonus_amount, $subscription->network_id), 'number_of_beneficiaries' => $subscription->number_of_beneficiaries]))); + + DB::commit(); + return $this->successResponse(trans('messages.insurance_subscription_updated_successful')); + } catch (Throwable $e) { + Log::error($e->getMessage() . '\n' . $e->getTraceAsString()); + DB::rollBack(); + return $this->errorResponse(trans('errors.unexpected_error'), 500); + } + } + private function generateSubscriptionID(): string { do { @@ -591,4 +753,32 @@ class InsuranceController extends Controller } while ($codeCorrect); return $code; } + + + private function storeBeneficiariesAndGetBonus(NhInsurancesSubscription $subscription, Request $request, + $networkConfig, NhMonthsPricesGrid $monthPrice, string $datetime) + { + $subscription->state = InsuranceSubscriptionState::UNDER_VALIDATION; + + $beneficiariesBonus = 0; + foreach ($request->input('beneficiaries') as $b) { + $beneficiary = new NhInsurancesHavingRight($b); + $beneficiary->insurance_subscription_id = $subscription->insurance_subscription_id; + $beneficiary->bonus_amount = $this->calculateBeneficiaryBonusAmount($beneficiary, $networkConfig->yearsPricesGrid, $monthPrice); + $beneficiariesBonus += $beneficiary->bonus_amount; + if ($beneficiary->affiliation == InsuranceSubscriptionAffiliation::CHILD) { + $beneficiary->marriage_certificate_doc = null; + $beneficiary->id_document_type = null; + $beneficiary->id_document_back = null; + $beneficiary->id_document_front = null; + } else { + $beneficiary->justice_doc = null; + $beneficiary->birthdate_proof_doc = null; + $beneficiary->birthdate_proof = null; + } + $beneficiary->created_at = $beneficiary->updated_at = $datetime; + $beneficiary->save(); + } + return $beneficiariesBonus; + } } diff --git a/app/Models/NhInsurancesHavingRight.php b/app/Models/NhInsurancesHavingRight.php index 6be7df1..c8220e8 100644 --- a/app/Models/NhInsurancesHavingRight.php +++ b/app/Models/NhInsurancesHavingRight.php @@ -41,10 +41,6 @@ class NhInsurancesHavingRight extends Model protected $table = 'nh_insurances_having_rights'; protected $appends = ['affiliation_tr']; - protected $casts = [ - 'bonus_amount' => 'float' - ]; - protected $dates = [ 'birthdate' ]; diff --git a/app/Models/NhInsurancesSubscription.php b/app/Models/NhInsurancesSubscription.php index 52d45fa..57300e6 100644 --- a/app/Models/NhInsurancesSubscription.php +++ b/app/Models/NhInsurancesSubscription.php @@ -30,15 +30,6 @@ class NhInsurancesSubscription extends Model { protected $table = 'nh_insurances_subscriptions'; - protected $casts = [ - 'network_id' => 'int', - 'user_id' => 'int', - 'number_of_months' => 'int', - 'total_bonus_amount' => 'float', - 'number_of_beneficiaries' => 'int', - 'bonus_amount' => 'float' - ]; - protected $fillable = [ 'insurance_subscription_id', 'network_id', @@ -50,6 +41,11 @@ class NhInsurancesSubscription extends Model 'state' ]; + public function network() + { + return $this->belongsTo(Network::class, 'network_id'); + } + public function user() { return $this->belongsTo(User::class, 'user_id'); @@ -60,4 +56,9 @@ class NhInsurancesSubscription extends Model return $this->hasMany(NhInsurancesHavingRight::class, 'insurance_subscription_id', 'insurance_subscription_id'); } + public function nhNetworkConfig() + { + return $this->belongsTo(NhNetworksConfig::class, 'network_id', 'network_id'); + } + } diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php index f72fc96..3ab8759 100755 --- a/resources/lang/en/errors.php +++ b/resources/lang/en/errors.php @@ -26,5 +26,6 @@ return [ 'number_of_beneficiaries_exceeded' => 'The number of beneficiaries is greater than the authorized limit', 'incorrect_selected_amount' => 'The amount selected is incorrect', 'minimal_age_required' => "Your age is above the age limit required to subscribe to this insurance", - 'cannot_subscribe_again' => "You can no longer subscribe to this insurance. You already have a request :state" + 'cannot_subscribe_again' => "You can no longer subscribe to this insurance. You already have a request :state", + "subscription_cannot_be_updated" => "This subscription request cannot be modified" ]; diff --git a/resources/lang/en/messages.php b/resources/lang/en/messages.php index 66280cd..5e08532 100755 --- a/resources/lang/en/messages.php +++ b/resources/lang/en/messages.php @@ -50,5 +50,7 @@ Your application has been rejected. Reason for rejection: :reason ", 'insurance_subscription_rejected_notification' => "Your :subscription_id application has been rejected", - "insurance_subscription_successful" => "Insurance subscription successful" + "insurance_subscription_successful" => "Insurance subscription successful", + 'insurance_subscription_updated' => "Insurance subscription update", + "insurance_subscription_updated_successful" => "Insurance subscription update successful" ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index bd9bfe7..f2c622d 100755 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -26,5 +26,6 @@ return [ 'number_of_beneficiaries_exceeded' => "Le nombre d'ayant droit est superieur à la limite autorisée", 'incorrect_selected_amount' => 'Le montant choisi est incorrect', 'minimal_age_required' => "Votre âge est supérieur à l'âge limite requis pour souscrire à cette assurance", - 'cannot_subscribe_again' => "Vous ne pouvez plus souscrire à cette assurance. Vous avez déjà une demande :state" + 'cannot_subscribe_again' => "Vous ne pouvez plus souscrire à cette assurance. Vous avez déjà une demande :state", + "subscription_cannot_be_updated" => "Cette demande de souscription ne peut etre modifiée" ]; diff --git a/resources/lang/fr/messages.php b/resources/lang/fr/messages.php index 1771ed8..692c0f6 100755 --- a/resources/lang/fr/messages.php +++ b/resources/lang/fr/messages.php @@ -50,5 +50,7 @@ Votre demande de souscription a été rejetée. Motif du rejet : :reason ", 'insurance_subscription_rejected_notification' => "Votre demande de souscription :subscription_id a été rejetée.", - "insurance_subscription_successful" => "Souscription à l'assurance réussie" + "insurance_subscription_successful" => "Souscription à l'assurance réussie", + 'insurance_subscription_updated' => "Mise à jour de la souscription à l'assurance", + "insurance_subscription_updated_successful" => "Mise à jour de la souscription à l'assurance réussie" ]; diff --git a/routes/web.php b/routes/web.php index 4ac9585..8312553 100644 --- a/routes/web.php +++ b/routes/web.php @@ -23,6 +23,7 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route $router->put('{id}/validate', 'InsuranceController@validateSubscription'); $router->put('{id}/reject', 'InsuranceController@rejectSubscription'); $router->get('', 'InsuranceController@getSubscriptions'); + $router->put('{id}', 'InsuranceController@addBeneficiaries'); }); }); });