457 lines
20 KiB
PHP
457 lines
20 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Events\InsuranceSubscribed;
|
|
use App\InsuranceSubscriptionState;
|
|
use App\Models\CountriesCurrency;
|
|
use App\Models\Identification;
|
|
use App\Models\NhInsurancesHavingRight;
|
|
use App\Models\NhInsurancesSubscription;
|
|
use App\Models\NhInsurancesSubscriptionsHistory;
|
|
use App\Models\NhMonthsPricesGrid;
|
|
use App\Models\NhNetworksConfig;
|
|
use App\Traits\Helper;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Event;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Throwable;
|
|
|
|
class InsuranceController extends Controller
|
|
{
|
|
use Helper;
|
|
|
|
/**
|
|
* Create a new controller instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/insurances/countries/{countryId}",
|
|
* summary="Afficher la liste des assurances d'un pays",
|
|
* tags={"Assurances"},
|
|
* security={{"api_key":{}}},
|
|
* @OA\Parameter(
|
|
* parameter="countryId",
|
|
* name="countryId",
|
|
* description="ID du pays",
|
|
* in="path",
|
|
* required=true,
|
|
* @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 getInsurancesByCountryId($countryId)
|
|
{
|
|
$country = CountriesCurrency::findOrFail($countryId);
|
|
|
|
$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.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' => $countryId]);
|
|
|
|
foreach ($insurances as $insurance) {
|
|
$months_prices = DB::select("SELECT id, number_of_months , min_amount FROM nh_months_prices_grid WHERE nh_network_config_id = :nhc_id",
|
|
['nhc_id' => $insurance->nhc_id]);
|
|
|
|
foreach ($months_prices as $mp) {
|
|
$mp->min_amount = $this->toMoneyWithCurrencyCode($mp->min_amount, $country->currency_code ?? 'XAF');
|
|
}
|
|
$insurance->months_prices = $months_prices;
|
|
unset($insurance->nhc_id);
|
|
}
|
|
|
|
return $this->successResponse($insurances);
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/insurances/bonus-amount",
|
|
* summary="Calculer le montant de la prime",
|
|
* tags={"Assurances"},
|
|
* security={{"api_key":{}}},
|
|
* @OA\RequestBody(
|
|
* description="Corps de la requete",
|
|
* required=true,
|
|
* @OA\MediaType(
|
|
* mediaType="application/json",
|
|
* @OA\Schema(
|
|
* @OA\Property(property="network_id",
|
|
* type="integer",
|
|
* example = 250,
|
|
* description="ID du reseau de l'assureur"
|
|
* ),
|
|
* @OA\Property(property="month_price_id",
|
|
* type="integer",
|
|
* example=2,
|
|
* description="ID de la grille de prix choisit lors de la souscription"
|
|
* ),
|
|
* @OA\Property(
|
|
* property="beneficiaries",
|
|
* description="Listes de quelques infos sur les beneficiaires ou ayants droit",
|
|
* example = {{"birthdate":"1998-10-05","affiliation":"CHILD"}}
|
|
* ),
|
|
* ),
|
|
* example = {"network_id":250,"month_price_id":3,"beneficiaries":{{"birthdate":"1998-10-05","affiliation":"CHILD"}}}
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="OK",
|
|
* @OA\JsonContent(
|
|
* ref="#/components/schemas/ApiResponse",
|
|
* example = {"status":200,"response":{"bonus_amount":75000,"bonus_amount_formatted":"75 000FCFA"},"error":null},
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
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',
|
|
'beneficiaries' => 'required|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'));
|
|
|
|
$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) {
|
|
$bonus += $this->calculateBeneficiaryBonusAmount(new NhInsurancesHavingRight($b), $networkConfig->yearsPricesGrid, $monthPrice);
|
|
}
|
|
|
|
return $this->successResponse([
|
|
'bonus_amount' => $bonus,
|
|
'bonus_amount_formatted' => $this->toMoneyWithNetwork($bonus, $request->input('network_id'))
|
|
]);
|
|
}
|
|
|
|
// 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(
|
|
* path="/insurances/subscribe",
|
|
* summary="Souscrire à une assurance",
|
|
* tags={"Assurances"},
|
|
* security={{"api_key":{}}},
|
|
* @OA\RequestBody(
|
|
* description="Corps de la requete",
|
|
* required=true,
|
|
* @OA\MediaType(
|
|
* mediaType="application/json",
|
|
* @OA\Schema(ref="#/components/schemas/subscribe_incurance"),
|
|
* example = {"network_id":250,"user_id":20,"password" : "1234", "month_price_id":3,"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 subscribe(Request $request)
|
|
{
|
|
/**
|
|
* @OA\Schema(
|
|
* schema="subscribe_incurance",
|
|
* title = "Souscription à une assurance",
|
|
* required={"network_id", "user_id" , "password", "month_price_id", "beneficiaries"},
|
|
* @OA\Property(property="network_id",
|
|
* type="integer",
|
|
* example = 250,
|
|
* description="ID du reseau de l'assureur"
|
|
* ),
|
|
* @OA\Property(property="user_id",
|
|
* type="integer",
|
|
* example=300,
|
|
* description="ID l'utilisateur identifié"
|
|
* ),
|
|
* @OA\Property(property="password",
|
|
* type="integer",
|
|
* example=300,
|
|
* description="Mot de passe de l'utilisateur identifié"
|
|
* ),
|
|
* @OA\Property(property="month_price_id",
|
|
* type="integer",
|
|
* example=2,
|
|
* description="ID de la grille de prix choisit lors de la souscription"
|
|
* ),
|
|
* @OA\Property(property="beneficiaries",
|
|
* type="array",
|
|
* description="Listes des beneficiaires ou ayants droit",
|
|
* @OA\Items(ref="#/components/schemas/beneficiaries")
|
|
* )
|
|
* )
|
|
*
|
|
* @OA\Schema(
|
|
* schema="beneficiaries",
|
|
* title = "Beneficiaires ou ayants droit",
|
|
* required={"lastname","gender", "birthdate", "affiliation" },
|
|
* @OA\Property(property="lastname",
|
|
* type="string",
|
|
* example = "Djery",
|
|
* description="Noms"
|
|
* ),
|
|
* @OA\Property(property="firstname",
|
|
* type="string",
|
|
* example="DI",
|
|
* description="Prenoms"
|
|
* ),
|
|
* @OA\Property(property="gender",
|
|
* type="string",
|
|
* enum = {"M" ,"F"},
|
|
* example= "M",
|
|
* description="Sexe"
|
|
* ),
|
|
* @OA\Property(property="birthdate",
|
|
* type="string",
|
|
* example= "2001-10-05",
|
|
* description="Date de naissance"
|
|
* ),
|
|
* @OA\Property(property="affiliation",
|
|
* type="string",
|
|
* enum = {"CHILD" ,"SPOUSE"},
|
|
* example= "CHILD",
|
|
* description="Affiliation"
|
|
* ),
|
|
* @OA\Property(property="birthdate_proof",
|
|
* type="string",
|
|
* enum = {"CERTIFIED_COPY" ,"CERTIFICATE"},
|
|
* example="CERTIFIED_COPY",
|
|
* description="Copie légalisée acte de naissance ou certificat de naissance"
|
|
* ),
|
|
* @OA\Property(property="birthdate_proof_doc",
|
|
* type="string",
|
|
* example="birthdate_proof_doc.jpg",
|
|
* description="Copie légalisée acte de naissance ou certificat de naissance"
|
|
* ),
|
|
* @OA\Property(property="justice_doc",
|
|
* type="string",
|
|
* example="justice_doc.jpg",
|
|
* description="Une page document de justice si enfant adopté ou sous tutelle"
|
|
* ),
|
|
* @OA\Property(property="marriage_certificate_doc",
|
|
* type="string",
|
|
* example="marriage_certificate_doc.jpg",
|
|
* description="Une page de l'acte de mariage"
|
|
* ),
|
|
* @OA\Property(property="id_document_type",
|
|
* type="string",
|
|
* example="CNI",
|
|
* description="Type de piece d'identité cni , carte sejour, permis"
|
|
* ),
|
|
* @OA\Property(property="id_document_front",
|
|
* type="string",
|
|
* example="id_document_front.jpg",
|
|
* description="Pièce identité recto"
|
|
* ),
|
|
* @OA\Property(property="id_document_back",
|
|
* type="string",
|
|
* example="id_document_back.jpg",
|
|
* description="Pièce identité verso"
|
|
* ),
|
|
* )
|
|
*/
|
|
$this->validate($request, [
|
|
'network_id' => 'required|integer|exists:networks,id',
|
|
'user_id' => 'required|integer|exists:users,id',
|
|
'password' => 'required|string',
|
|
'month_price_id' => 'required|integer|exists:nh_months_prices_grid,id',
|
|
'beneficiaries' => 'required|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' => 'required_if:beneficiaries.*.affiliation,CHILD|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',
|
|
]);
|
|
|
|
$identification = Identification::where('id_user', $request->input('user_id'))->first();
|
|
if (!isset($identification) || $identification->status == 0)
|
|
return $this->errorResponse(trans('errors.user_identification_required'));
|
|
|
|
if (!$this->checkPassword($request->password, $identification->user->encrypted_password, $identification->user->salt))
|
|
return $this->errorResponse(trans('messages.incorrect_user_password'));
|
|
|
|
$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'));
|
|
|
|
// Verification de l'age du beneficiaire
|
|
$insuredAge = date_diff(date_create($identification->birthdate), date_create('now'))->y;
|
|
if ($insuredAge < $networkConfig->age_limit_of_insured_and_spouse) {
|
|
return $this->errorResponse(trans('errors.minimal_age_required'));
|
|
}
|
|
|
|
$networkConfig = NhNetworksConfig::where('network_id', $request->input('network_id'))->first();
|
|
if (sizeof($request->input('beneficiaries')) > $networkConfig->max_number_of_beneficiaries)
|
|
return $this->errorResponse(trans('errors.number_of_beneficiaries_exceeded'));
|
|
|
|
$monthPrice = $networkConfig->monthsPricesGrid()->where('id', $request->input('month_price_id'))->first();
|
|
if (!isset($monthPrice))
|
|
return $this->errorResponse(trans('errors.incorrect_selected_amount'));
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
$subscription = new NhInsurancesSubscription($request->all());
|
|
$subscription->number_of_beneficiaries = sizeof($request->input('beneficiaries'));
|
|
$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;
|
|
$subscription->save();
|
|
|
|
$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;
|
|
$beneficiary->save();
|
|
}
|
|
|
|
$subscription->total_bonus_amount = ($subscription->bonus_amount + $beneficiariesBonus);
|
|
$subscription->save();
|
|
|
|
NhInsurancesSubscriptionsHistory::create([
|
|
'action' => 'ADD',
|
|
'insurance_subscription_id' => $subscription->insurance_subscription_id,
|
|
'insurance_subscription_state' => $subscription->state,
|
|
'insurance_subscription' => json_encode($subscription)
|
|
]);
|
|
|
|
|
|
Event::dispatch(new InsuranceSubscribed($subscription));
|
|
|
|
DB::commit();
|
|
return $this->successResponse(trans('messages.successful_transaction'));
|
|
} catch (Throwable $e) {
|
|
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
|
|
DB::rollBack();
|
|
return $this->errorResponse(trans('errors.unexpected_error'), 500);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/insurances/upload-images",
|
|
* summary="Uploader les images de l'assurance",
|
|
* tags={"Assurances"},
|
|
* security={{"api_key":{}}},
|
|
* @OA\RequestBody(
|
|
* description="Corps de la requete",
|
|
* required=true,
|
|
* @OA\MediaType(
|
|
* mediaType="multipart/form-data",
|
|
* @OA\Schema(
|
|
* @OA\Property(
|
|
* property="files[]",
|
|
* description = "Liste des documents à uploader",
|
|
* type="array",
|
|
* @OA\Items(type="string", format="binary")
|
|
* )
|
|
* ),
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="OK",
|
|
* @OA\JsonContent(
|
|
* ref="#/components/schemas/ApiResponse",
|
|
* example = {"status":200,"response":"Transaction réussie","error":null}
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function uploadImages(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'files' => 'required',
|
|
'files.*' => 'mimes:jpeg,png,jpg,jpeg|max:6144'
|
|
]);
|
|
|
|
$files = [];
|
|
if ($request->hasfile('files')) {
|
|
foreach ($request->file('files') as $file) {
|
|
$filename = $this->uploadImage($file, 'NH', 'insurances-subscriptions-docs');
|
|
array_push($files, $filename);
|
|
}
|
|
}
|
|
|
|
return $this->successResponse($files);
|
|
}
|
|
|
|
private function generateSubscriptionID(): string
|
|
{
|
|
do {
|
|
$code = $this->generateTransactionCode();
|
|
$codeCorrect = NhInsurancesSubscription::where('insurance_subscription_id', $code)->count() < 0;
|
|
} while ($codeCorrect);
|
|
return $code;
|
|
}
|
|
}
|