Add endpoint to add beneficiaries in insurance subscription

This commit is contained in:
Djery-Tom 2021-11-09 09:30:31 +01:00
parent 8b6adb870e
commit 4c91388197
12 changed files with 435 additions and 254 deletions

52
app/Helpers/common.php Normal file
View File

@ -0,0 +1,52 @@
<?php
if (!function_exists('compressImage')) {
function compressImage($source, $destination, $quality)
{
// Get image info
$imgInfo = getimagesize($source);
$mime = $imgInfo['mime'];
// Create a new image from file
switch ($mime) {
case 'image/jpeg':
$image = imagecreatefromjpeg($source);
break;
case 'image/png':
$image = imagecreatefrompng($source);
break;
case 'image/gif':
$image = imagecreatefromgif($source);
break;
default:
$image = imagecreatefromjpeg($source);
}
// Save image
imagejpeg($image, $destination, $quality);
// Return compressed image
return $destination;
}
}
if (!function_exists('checkPassword')) {
function checkPassword($password, $encrypted_password, $salt)
{
$encrypted_password_to_check = base64_encode(sha1($password . $salt, true) . $salt);
return $encrypted_password_to_check == $encrypted_password;
}
}
if (!function_exists('generateTransactionCode')) {
function generateTransactionCode($length = 12)
{
$characters = '23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
}

View File

@ -3,21 +3,14 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Events\InsuranceEvent; use App\Events\InsuranceEvent;
use App\InsuranceSubscriptionAffiliation; use App\InsuranceState;
use App\InsuranceSubscriptionState; use App\InsuranceSubscriptionState;
use App\Models\CountriesCurrency; use App\Models\CountriesCurrency;
use App\Models\Identification;
use App\Models\NhInsurance; use App\Models\NhInsurance;
use App\Models\NhInsurancesHavingRight;
use App\Models\NhInsurancesSubscription;
use App\Models\NhInsurancesSubscriptionsHistory; use App\Models\NhInsurancesSubscriptionsHistory;
use App\Models\NhMonthsPricesGrid;
use App\Models\NhNetworksConfig; use App\Models\NhNetworksConfig;
use App\Models\User;
use App\Traits\Helper; use App\Traits\Helper;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
@ -39,8 +32,8 @@ class InsuranceController extends Controller
/** /**
* @OA\Get( * @OA\Get(
* path="/insurances", * path="/insurances/networks",
* summary="Afficher la liste des assurances ( par pays )", * summary="Afficher la liste des reseaux d'assurances ( par pays )",
* tags={"Assurances"}, * tags={"Assurances"},
* security={{"api_key":{}}}, * security={{"api_key":{}}},
* @OA\Parameter( * @OA\Parameter(
@ -69,7 +62,7 @@ class InsuranceController extends Controller
* ) * )
* ) * )
*/ */
public function getInsurances(Request $request) public function getInsurancesNetworks(Request $request)
{ {
$this->validate($request, [ $this->validate($request, [
'country_id' => 'nullable|integer|exists:countries,id' 'country_id' => 'nullable|integer|exists:countries,id'
@ -95,4 +88,249 @@ class InsuranceController extends Controller
return $this->successResponse($insurances); return $this->successResponse($insurances);
} }
/**
* @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"}
* )
* ),
* @OA\Response(
* response=200,
* description="OK",
* @OA\JsonContent(
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":3,"insurance_subscription_id":"3QM2DS9V4KEG","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",
* "subscription":{"id":2,"insurance_subscription_id":"3QM2DS9V4KEG","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","state":"ACCEPT\u00c9E","created_at":"2021-11-01T15:18:34.000000Z",
* "updated_at":"2021-11-05T16:43:00.000000Z","reason":"Quel est ton vrai age ?","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'
]);
$userId = $request->input('user_id');
$type = $request->input('type');
$query = NhInsurance::with(['subscription', 'subscription.network:id,name', 'subscription.beneficiaries'])->whereHas('subscription', function ($query) use ($userId) {
return $query->where('user_id', $userId);
});
if ($request->has('type') && $type == 'EDITABLE') {
$query = $query->whereIn('state', [InsuranceState::PAID, InsuranceState::REMAINS]);
}
$insurances = $query->orderBy('created_at', 'DESC')->get();
foreach ($insurances as $insurance) {
$insurance->state = trans('states.' . $insurance->state);
if ($type == 'EDITABLE') {
//Necessaire seulement lors de la modification ( ajout de ayant droit;
$config = NhNetworksConfig::where('network_id', $insurance->subscription->network->id)->firstOrFail();
$insurance->subscription->network->age_limit_of_insured_and_spouse = $config->age_limit_of_insured_and_spouse;
$insurance->subscription->network->age_limit_of_child_beneficiary = $config->age_limit_of_child_beneficiary;
$insurance->subscription->network->max_number_of_beneficiaries = $config->max_number_of_beneficiaries;
}
$currency_code = $this->getNetworkCurrency($insurance->subscription->network_id);
$insurance->subscription->state = trans('states.' . $insurance->subscription->state);
$insurance->subscription->bonus_amount = $this->toMoneyWithCurrencyCode($insurance->subscription->bonus_amount, $currency_code);
$insurance->subscription->total_bonus_amount = $this->toMoneyWithCurrencyCode($insurance->subscription->total_bonus_amount, $currency_code);
foreach ($insurance->subscription->beneficiaries as $b) {
$b->bonus_amount = $this->toMoneyWithCurrencyCode($b->bonus_amount, $currency_code);
}
}
return $this->successResponse($insurances);
}
/**
* @OA\Put(
* path="/insurances/{id}/add-beneficiaires",
* 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"}}}
* )
* ),
* @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',
]);
$insurance = NhInsurance::findOrFail($id);
$subscription = $insurance->subscription;
if ($subscription->state != 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 (!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);
// Creer une nouvelle subscription en clonant l'anciene
$newSubscription = $subscription->replicate();
$newSubscription->insurance_subscription_id = $this->generateSubscriptionID();
$newSubscription->number_of_beneficiaries += sizeof($request->input('beneficiaries'));
$newSubscription->push();
//reset relations on EXISTING MODEL (this way you can control which ones will be loaded
$subscription->setRelations([]);
//load relations on EXISTING MODEL
$subscription->load('beneficiaries');
foreach ($subscription->getRelations() as $relation => $items) {
foreach ($items as $item) {
$item->insurance_subscription_id = $newSubscription->insurance_subscription_id;
unset($item->id);
$newSubscription->{$relation}()->create($item->toArray());
}
}
// Ajouter les nouveaux ayant droit
$beneficiariesBonus = $this->storeBeneficiariesAndGetBonus($newSubscription, $request, $networkConfig, $monthPrice, $datetime);
$newSubscription->total_bonus_amount += $beneficiariesBonus;
$newSubscription->created_at = $newSubscription->updated_at = $datetime;
$newSubscription->save();
$insurance->insurance_subscription_id = $newSubscription->insurance_subscription_id;
$insurance->state = InsuranceState::REMAINS;
$insurance->remaining_amount = $beneficiariesBonus;
$insurance->save();
NhInsurancesSubscriptionsHistory::create([
'action' => 'ADD',
'insurance_subscription_id' => $newSubscription->insurance_subscription_id,
'insurance_subscription_state' => $newSubscription->state,
'insurance_subscription' => json_encode($newSubscription),
'created_at' => $datetime, 'updated_at' => $datetime,
]);
Event::dispatch(new InsuranceEvent($newSubscription, trans('messages.insurance_subscription_updated'), trans('messages.insurance_subscription_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_subscription_updated_successful'));
} catch (Throwable $e) {
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
DB::rollBack();
return $this->errorResponse(trans('errors.unexpected_error'), 500);
}
}
} }

View File

@ -128,28 +128,6 @@ class InsuranceSubscriptionController extends Controller
]); ]);
} }
// Caculer le montant de la prime d'un ayant droit ou beneficiaire
private function calculateBeneficiaryBonusAmount(NhInsurancesHavingRight $beneficiary, Collection $yearsPricesGrid,
NhMonthsPricesGrid $monthPrice)
{
$bonus = 0;
if ($beneficiary->affiliation == 'CHILD') {
$age = date_diff(date_create($beneficiary->birthdate), date_create('now'))->y;
$levels = $yearsPricesGrid->filter(function ($level) use ($age) {
return $level->min_age <= $age && $level->max_age >= $age;
});
foreach ($levels as $level) {
$bonus += (100 + $level->markup_percentage) * $monthPrice->min_amount / 100;
}
} else {
$bonus = $monthPrice->min_amount;
}
return $bonus;
}
/** /**
* @OA\Post( * @OA\Post(
* path="/insurances/subscriptions", * path="/insurances/subscriptions",
@ -303,7 +281,7 @@ class InsuranceSubscriptionController extends Controller
if (!isset($identification) || $identification->status == 0) if (!isset($identification) || $identification->status == 0)
return $this->errorResponse(trans('errors.user_identification_required')); return $this->errorResponse(trans('errors.user_identification_required'));
if (!$this->checkPassword($request->password, $identification->user->encrypted_password, $identification->user->salt)) if (!checkPassword($request->password, $identification->user->encrypted_password, $identification->user->salt))
return $this->errorResponse(trans('messages.incorrect_user_password')); return $this->errorResponse(trans('messages.incorrect_user_password'));
$networkConfig = NhNetworksConfig::where('network_id', $request->input('network_id'))->first(); $networkConfig = NhNetworksConfig::where('network_id', $request->input('network_id'))->first();
@ -368,42 +346,6 @@ class InsuranceSubscriptionController extends Controller
} }
private function generateSubscriptionID(): string
{
do {
$code = $this->generateTransactionCode();
$codeCorrect = NhInsurancesSubscription::where('insurance_subscription_id', $code)->count() < 0;
} 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;
}
/** /**
* @OA\Post( * @OA\Post(
* path="/insurances/subscriptions/upload-images", * path="/insurances/subscriptions/upload-images",
@ -605,7 +547,7 @@ class InsuranceSubscriptionController extends Controller
} }
$user = $subscription->user; $user = $subscription->user;
if (!$this->checkPassword($request->password, $user->encrypted_password, $user->salt)) { if (!checkPassword($request->password, $user->encrypted_password, $user->salt)) {
return $this->errorResponse(trans('messages.incorrect_user_password')); return $this->errorResponse(trans('messages.incorrect_user_password'));
} }
@ -660,7 +602,7 @@ class InsuranceSubscriptionController extends Controller
private function generateInsuredID(): string private function generateInsuredID(): string
{ {
do { do {
$code = $this->generateTransactionCode(); $code = generateTransactionCode();
$codeCorrect = NhInsurance::where('insured_id', $code)->count() < 0; $codeCorrect = NhInsurance::where('insured_id', $code)->count() < 0;
} while ($codeCorrect); } while ($codeCorrect);
return $code; return $code;
@ -688,7 +630,7 @@ class InsuranceSubscriptionController extends Controller
* name="type", * name="type",
* description="Type de souscription", * description="Type de souscription",
* in="query", * in="query",
* required=true, * required=false,
* @OA\Schema( * @OA\Schema(
* type="string", * type="string",
* enum={"ALL","ACCEPTED"} * enum={"ALL","ACCEPTED"}
@ -746,132 +688,4 @@ class InsuranceSubscriptionController extends Controller
} }
return $this->successResponse($subscriptions); 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::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,
'gender' => trans('states.' . $identification->gender), 'insurance_name' => $networkConfig->network->name])));
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);
}
}
} }

View File

@ -7,4 +7,5 @@ abstract class InsuranceState
const PAID = 'PAID'; const PAID = 'PAID';
const UNDER_STOPPING = 'UNDER_STOPPING'; const UNDER_STOPPING = 'UNDER_STOPPING';
const STOPPED = 'STOPPED'; const STOPPED = 'STOPPED';
const REMAINS = 'REMAINS';
} }

View File

@ -55,7 +55,7 @@ class NotifyUser
$body = new stdClass(); $body = new stdClass();
$body->user_code = $user->user_code; $body->user_code = $user->user_code;
$body->message = $event->notification; $body->message = $event->notification;
$body->date = $subscription->created_at ?? date('Y-m-d H:i:s'); $body->date = $subscription->created_at->format('Y-m-d H:i:s') ?? date('Y-m-d H:i:s');
$data = new stdClass(); $data = new stdClass();
$data->screen = "notificationview"; $data->screen = "notificationview";

View File

@ -18,6 +18,7 @@ use Illuminate\Database\Eloquent\Model;
* @property Carbon|null $start_at * @property Carbon|null $start_at
* @property Carbon|null $end_at * @property Carbon|null $end_at
* @property string $state * @property string $state
* @property float $remaining_amount
* @property Carbon $created_at * @property Carbon $created_at
* @property Carbon $updated_at * @property Carbon $updated_at
* *
@ -37,6 +38,12 @@ class NhInsurance extends Model
'insured_id', 'insured_id',
'start_at', 'start_at',
'end_at', 'end_at',
'state' 'state',
'remaining_amount'
]; ];
public function subscription()
{
return $this->belongsTo(NhInsurancesSubscription::class, 'insurance_subscription_id', 'insurance_subscription_id');
}
} }

View File

@ -4,12 +4,20 @@
namespace App\Traits; namespace App\Traits;
use App\InsuranceSubscriptionAffiliation;
use App\InsuranceSubscriptionState;
use App\Models\CountriesCurrency; use App\Models\CountriesCurrency;
use App\Models\Country; use App\Models\Country;
use App\Models\NhInsurance;
use App\Models\NhInsurancesHavingRight;
use App\Models\NhInsurancesSubscription;
use App\Models\NhMonthsPricesGrid;
use Brick\Money\Context\AutoContext; use Brick\Money\Context\AutoContext;
use Brick\Money\Money; use Brick\Money\Money;
use DateTime; use DateTime;
use DateTimeZone; use DateTimeZone;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
@ -17,6 +25,14 @@ use Illuminate\Support\Str;
trait Helper trait Helper
{ {
public function getNetworkCurrency($networkId)
{
$currency = collect(DB::select('SELECT cu.code FROM networks n INNER JOIN countries c ON c.id = n.country_id INNER JOIN currencies cu ON cu.id = c.idCurrency
WHERE n.id = :id', ['id' => $networkId]))->first();
return isset($currency) ? $currency->code : 'XAF';
}
public function toMoneyWithNetwork($amount, $id_network) public function toMoneyWithNetwork($amount, $id_network)
{ {
$currency = collect(DB::select('SELECT cu.code FROM networks n INNER JOIN countries c ON c.id = n.country_id INNER JOIN currencies cu ON cu.id = c.idCurrency $currency = collect(DB::select('SELECT cu.code FROM networks n INNER JOIN countries c ON c.id = n.country_id INNER JOIN currencies cu ON cu.id = c.idCurrency
@ -39,23 +55,6 @@ trait Helper
return $money->formatTo(app()->getLocale()); return $money->formatTo(app()->getLocale());
} }
public function generateTransactionCode($length = 12)
{
$characters = '23456789ABCDEFGHJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
public function checkPassword($password, $encrypted_password, $salt)
{
$encrypted_password_to_check = base64_encode(sha1($password . $salt, true) . $salt);
return $encrypted_password_to_check == $encrypted_password;
}
public function uploadImage(UploadedFile $file, $imageCode, $folderName) public function uploadImage(UploadedFile $file, $imageCode, $folderName)
{ {
$original_filename = $file->getClientOriginalName(); $original_filename = $file->getClientOriginalName();
@ -70,7 +69,7 @@ trait Helper
mkdir($directoryName, 0755); mkdir($directoryName, 0755);
} }
$compressedImage = $this->compressImage($file, './' . $folderName . '/' . $image, 70); $compressedImage = compressImage($file, './' . $folderName . '/' . $image, 70);
if ($compressedImage) { if ($compressedImage) {
return $image; return $image;
} else { } else {
@ -78,41 +77,13 @@ trait Helper
} }
} }
private function compressImage($source, $destination, $quality)
{
// Get image info
$imgInfo = getimagesize($source);
$mime = $imgInfo['mime'];
// Create a new image from file
switch ($mime) {
case 'image/jpeg':
$image = imagecreatefromjpeg($source);
break;
case 'image/png':
$image = imagecreatefrompng($source);
break;
case 'image/gif':
$image = imagecreatefromgif($source);
break;
default:
$image = imagecreatefromjpeg($source);
}
// Save image
imagejpeg($image, $destination, $quality);
// Return compressed image
return $destination;
}
// Obtenir l'heure en fonction du pays de l'utilisateur // Obtenir l'heure en fonction du pays de l'utilisateur
public function getCurrentTime($id_country) public function getCurrentTime($id_country)
{ {
$country = CountriesCurrency::find($id_country); $country = CountriesCurrency::find($id_country);
$country_code = isset($country) ? $country->code_country : 'GA'; $country_code = isset($country) ? $country->code_country : 'GA';
$timezone = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $country_code); $timezone = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $country_code);
$date = (sizeof($timezone) > 0) ? new \DateTime('now', new \DateTimeZone($timezone[0])) : new \DateTime(); $date = (sizeof($timezone) > 0) ? new DateTime('now', new \DateTimeZone($timezone[0])) : new \DateTime();
return $date->format('Y-m-d H:i:s'); return $date->format('Y-m-d H:i:s');
} }
@ -124,4 +95,62 @@ trait Helper
return $date->format('Y-m-d H:i:s'); return $date->format('Y-m-d H:i:s');
} }
// Caculer le montant de la prime d'un ayant droit ou beneficiaire
public function calculateBeneficiaryBonusAmount(NhInsurancesHavingRight $beneficiary, Collection $yearsPricesGrid,
NhMonthsPricesGrid $monthPrice)
{
$bonus = 0;
if ($beneficiary->affiliation == 'CHILD') {
$age = date_diff(date_create($beneficiary->birthdate), date_create('now'))->y;
$levels = $yearsPricesGrid->filter(function ($level) use ($age) {
return $level->min_age <= $age && $level->max_age >= $age;
});
foreach ($levels as $level) {
$bonus += (100 + $level->markup_percentage) * $monthPrice->min_amount / 100;
}
} else {
$bonus = $monthPrice->min_amount;
}
return $bonus;
}
public 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;
}
public function generateSubscriptionID(): string
{
do {
$code = generateTransactionCode();
$codeCorrect = NhInsurancesSubscription::where('insurance_subscription_id', $code)->count() < 0;
} while ($codeCorrect);
return $code;
}
} }

View File

@ -25,7 +25,10 @@
"App\\": "app/", "App\\": "app/",
"Database\\Factories\\": "database/factories/", "Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/" "Database\\Seeders\\": "database/seeders/"
} },
"files": [
"app/Helpers/common.php"
]
}, },
"autoload-dev": { "autoload-dev": {
"classmap": [ "classmap": [

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRemainingColumnInNhInsurancesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('nh_insurances', function (Blueprint $table) {
$table->decimal('remaining_amount')->default(0)->after('state');
DB::statement("ALTER TABLE nh_insurances MODIFY state
ENUM('PAID', 'UNDER_STOPPING', 'STOPPED', 'REMAINS') DEFAULT 'PAID' NOT NULL;");
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('nh_insurances', function (Blueprint $table) {
$table->dropColumn('remaining_amount');
});
}
}

View File

@ -12,5 +12,5 @@ return [
"F" => "Mrs", "F" => "Mrs",
"AWAITING_FURTHER_INFORMATION" => "AWAITING FURTHER INFORMATION", "AWAITING_FURTHER_INFORMATION" => "AWAITING FURTHER INFORMATION",
"ENDED" => 'ENDED', "ENDED" => 'ENDED',
"individuel" => "INDIVIDUAL" "REMAINS" => "REMAINS"
]; ];

View File

@ -12,5 +12,5 @@ return [
"F" => "Mme", "F" => "Mme",
"AWAITING_FURTHER_INFORMATION" => "EN ATTENTE D'INFORMATIONS COMPLÉMENTAIRES", "AWAITING_FURTHER_INFORMATION" => "EN ATTENTE D'INFORMATIONS COMPLÉMENTAIRES",
"ENDED" => 'TERMINÉE', "ENDED" => 'TERMINÉE',
"individuel" => "INDIVIDUEL" "REMAINS" => "EN RESTE"
]; ];

View File

@ -16,6 +16,10 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route
// Insurances routes // Insurances routes
$router->group(['prefix' => '/insurances'], function () use ($router) { $router->group(['prefix' => '/insurances'], function () use ($router) {
$router->get('', 'InsuranceController@getInsurances'); $router->get('', 'InsuranceController@getInsurances');
$router->get('networks', 'InsuranceController@getInsurancesNetworks');
$router->put('{id}/add-beneficiaries', 'InsuranceController@addBeneficiaries');
// Subscriptions
$router->group(['prefix' => '/subscriptions'], function () use ($router) { $router->group(['prefix' => '/subscriptions'], function () use ($router) {
$router->post('bonus-amount', 'InsuranceSubscriptionController@calculateBonusAmount'); $router->post('bonus-amount', 'InsuranceSubscriptionController@calculateBonusAmount');
$router->post('upload-images', 'InsuranceSubscriptionController@uploadImages'); $router->post('upload-images', 'InsuranceSubscriptionController@uploadImages');
@ -24,7 +28,6 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route
$router->put('{id}/reject', 'InsuranceSubscriptionController@rejectSubscription'); $router->put('{id}/reject', 'InsuranceSubscriptionController@rejectSubscription');
$router->put('{id}/pay', 'InsuranceSubscriptionController@paySubscription'); $router->put('{id}/pay', 'InsuranceSubscriptionController@paySubscription');
$router->get('', 'InsuranceSubscriptionController@getSubscriptions'); $router->get('', 'InsuranceSubscriptionController@getSubscriptions');
$router->put('{id}', 'InsuranceSubscriptionController@addBeneficiaries');
}); });
}); });
}); });