887 lines
43 KiB
PHP
887 lines
43 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Events\InsuranceEvent;
|
|
use App\InsuranceAction;
|
|
use App\InsuranceInvoiceState;
|
|
use App\InsuranceState;
|
|
use App\InsuranceSubscriptionAffiliation;
|
|
use App\InsuranceSubscriptionState;
|
|
use App\Models\AgentPlus;
|
|
use App\Models\CountriesCurrency;
|
|
use App\Models\Identification;
|
|
use App\Models\NhHavingRight;
|
|
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\NhMonthsPricesGrid;
|
|
use App\Models\NhNetworksConfig;
|
|
use App\Models\User;
|
|
use App\Models\Wallet;
|
|
use App\Rules\PasswordValidation;
|
|
use App\Traits\Helper;
|
|
use Carbon\Carbon;
|
|
use DateTime;
|
|
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 InsuranceSubscriptionController extends Controller
|
|
{
|
|
/**
|
|
* Create a new controller instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
//
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/insurances/subscriptions/bonus-amount",
|
|
* summary="Calculer le montant de la prime",
|
|
* tags={"Souscriptions à l'assurance"},
|
|
* security={{"api_key":{}}},
|
|
* @OA\RequestBody(
|
|
* description="Corps de la requete",
|
|
* required=true,
|
|
* @OA\MediaType(
|
|
* mediaType="application/json",
|
|
* @OA\Schema(
|
|
* @OA\Property(property="insurance_id",
|
|
* type="integer",
|
|
* example = 2,
|
|
* description="ID de l'assurance"
|
|
* ),
|
|
* @OA\Property(property="subscription_id",
|
|
* type="integer",
|
|
* example = 2,
|
|
* description="ID de la souscription"
|
|
* ),
|
|
* @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 = {"insurance_id":7,"subscription_id":7,"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, [
|
|
'insurance_id' => 'nullable|integer|exists:nh_insurances,id',
|
|
'subscription_id' => 'nullable|integer|exists:nh_insurances_subscriptions,id',
|
|
'network_id' => 'required_without_all::subscription_id,insurance_id|integer|exists:networks,id',
|
|
'month_price_id' => 'required_without_all::subscription_id,insurance_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'
|
|
]);
|
|
|
|
$subscription_id = $request->input('subscription_id');
|
|
$insurance_id = $request->input('insurance_id');
|
|
if (!empty($subscription_id)) {
|
|
$subscription = NhInsurancesSubscription::findOrFail($subscription_id);
|
|
$networkConfig = $subscription->nhNetworkConfig;
|
|
$monthPrice = $subscription->monthsGrid;
|
|
|
|
$beneficiaries = array_merge($subscription->beneficiaries->toArray(), $request->input('beneficiaries', []));
|
|
} elseif (!empty($insurance_id)) {
|
|
$insurance = NhInsurance::findOrFail($insurance_id);
|
|
$networkConfig = $insurance->nhNetworkConfig;
|
|
$monthPrice = $insurance->monthsGrid;
|
|
|
|
$beneficiaries = array_merge($insurance->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', []);
|
|
}
|
|
|
|
if (!isset($monthPrice))
|
|
return $this->errorResponse(trans('errors.incorrect_selected_amount'));
|
|
|
|
$bonus = $monthPrice->min_amount;
|
|
foreach ($beneficiaries as $b) {
|
|
$bonus += $this->calculateBeneficiaryBonusAmount(new NhHavingRight($b), $networkConfig->yearsPricesGrid, $monthPrice);
|
|
}
|
|
|
|
return $this->successResponse([
|
|
'bonus_amount' => $bonus,
|
|
'bonus_amount_formatted' => $this->toMoneyWithNetwork($bonus, $request->input('network_id'))
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/insurances/subscriptions",
|
|
* summary="Souscrire à une assurance",
|
|
* tags={"Souscriptions à l'assurance"},
|
|
* 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}
|
|
* )
|
|
* )
|
|
* )
|
|
* @throws \App\Exceptions\AppException
|
|
*/
|
|
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="string",
|
|
* example="20214666",
|
|
* 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"
|
|
* ),
|
|
* @OA\Property(property="profile_image",
|
|
* type="string",
|
|
* example="profile_image.jpg",
|
|
* description="Profile image"
|
|
* ),
|
|
* )
|
|
*/
|
|
$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' => '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',
|
|
]);
|
|
|
|
$user = User::findOrFail($request->input('user_id'));
|
|
$identification = $user->identification;
|
|
$this->userIdentificationVerification($user);
|
|
// Validation du mot de passe dépendamment de la configuration du réseau
|
|
$this->validate($request, [
|
|
'password' => [new PasswordValidation($request->input('network_id'), 'user', $user)]
|
|
]);
|
|
|
|
$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'));
|
|
|
|
$insurance = NhInsurance::where('network_id', $request->input('network_id'))->where('user_id', $request->input('user_id'))->first();
|
|
if (isset($insurance)) {
|
|
return $this->errorResponse(__('errors.already_insured'));
|
|
}
|
|
$this->latestSubscriptionVerification($request->input('network_id'), $request->input('user_id'));
|
|
|
|
// Verification de l'age du beneficiaire
|
|
$insuredAge = date_diff(date_create($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($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();
|
|
$datetime = $this->getCurrentTimeByCountryCode($networkConfig->network->country->code_country);
|
|
$subscription = new NhInsurancesSubscription($request->all());
|
|
$subscription->number_of_beneficiaries = sizeof($request->input('beneficiaries', []));
|
|
$subscription->insurance_subscription_id = $this->generateSubscriptionID();
|
|
$subscription->months_grid_id = $monthPrice->id;
|
|
$subscription->bonus_amount = $monthPrice->min_amount;
|
|
$subscription->insurance_action = InsuranceAction::ACTIVATION;
|
|
$subscription->save();
|
|
|
|
$beneficiariesBonus = $this->storeBeneficiariesAndGetBonus($subscription, $request, $networkConfig, $monthPrice, $datetime);
|
|
|
|
$subscription->total_bonus_amount = ($subscription->bonus_amount + $beneficiariesBonus);
|
|
$subscription->created_at = $subscription->updated_at = $datetime;
|
|
$subscription->save();
|
|
|
|
NhInsurancesSubscriptionsHistory::create([
|
|
'action' => 'ADD',
|
|
'insurance_subscription_id' => $subscription->insurance_subscription_id,
|
|
'insurance_subscription_state' => $subscription->state,
|
|
'created_at' => $datetime, 'updated_at' => $datetime,
|
|
]);
|
|
|
|
|
|
Event::dispatch(new InsuranceEvent($subscription, trans('messages.insurance_subscription'), 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_successful'));
|
|
} catch (Throwable $e) {
|
|
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
|
|
DB::rollBack();
|
|
return $this->errorResponse(trans('errors.unexpected_error'), 500);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @OA\Post(
|
|
* path="/insurances/subscriptions/upload-images",
|
|
* summary="Uploader les images de la souscription à l'assurance",
|
|
* tags={"Souscriptions à l'assurance"},
|
|
* 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:10240' // 10 Mb
|
|
]);
|
|
|
|
$files = [];
|
|
if ($request->hasfile('files')) {
|
|
foreach ($request->file('files') as $file) {
|
|
$filename = $this->uploadImage($file, 'NH', 'insurances-subscriptions-docs');
|
|
$files[] = $filename;
|
|
}
|
|
}
|
|
|
|
return $this->successResponse($files);
|
|
}
|
|
|
|
public function validateSubscription($id, Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'nh_validating_agent_id' => 'required_without:agent_id|nullable|integer|exists:nh_validating_agents,id',
|
|
'agent_id' => 'required_without:nh_validating_agent_id|nullable|integer|exists:agents,id',
|
|
]);
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
$subscription = NhInsurancesSubscription::findOrFail($id);
|
|
$datetime = $this->getCurrentTimeByCountryCode($subscription->network->country->code_country);
|
|
|
|
$subscription->state = InsuranceSubscriptionState::ACCEPTED;
|
|
$subscription->updated_at = $datetime;
|
|
$subscription->save();
|
|
|
|
$mail_data = ['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.' . $subscription->user->identification->gender), 'insurance_name' => $subscription->network->name];
|
|
if ($subscription->insurance_action == InsuranceAction::STOP_INSURANCE) {
|
|
$insurance = NhInsurance::where('user_id', $subscription->user_id)->where('network_id', $subscription->network_id)->firstOrFail();
|
|
$insurance->state = InsuranceState::STOPPED;
|
|
$insurance->updated_at = $datetime;
|
|
$insurance->save();
|
|
|
|
$message = trans('messages.insurance_stop_accepted');
|
|
$notification = trans('messages.insurance_stop_accepted_notification', ['subscription_id' => $subscription->insurance_subscription_id]);
|
|
$mail = trans('messages.insurance_stop_accepted_mail', $mail_data);
|
|
} else {
|
|
$amount_per_split = ceil($subscription->total_bonus_amount / $subscription->monthsGrid->number_of_fractions);
|
|
$amount_last_payment = $subscription->total_bonus_amount - ($amount_per_split * ($subscription->monthsGrid->number_of_fractions - 1));
|
|
|
|
$networkConfig = NhNetworksConfig::where('network_id', $subscription->network_id)->first();
|
|
if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante')
|
|
return $this->errorResponse(trans('errors.nano_health_not_activated'));
|
|
|
|
if ($subscription->insurance_action == InsuranceAction::ACTIVATION) {
|
|
$insurance = NhInsurance::create([
|
|
'network_id' => $subscription->network_id,
|
|
'user_id' => $subscription->user_id,
|
|
'insured_id' => $this->generateInsuredID(),
|
|
'months_grid_id' => $subscription->months_grid_id,
|
|
'total_bonus_amount' => $subscription->total_bonus_amount,
|
|
'number_of_beneficiaries' => $subscription->number_of_beneficiaries,
|
|
'bonus_amount' => $subscription->bonus_amount,
|
|
'created_at' => $datetime, 'updated_at' => $datetime,
|
|
'state' => InsuranceState::UNDER_ACTIVATION
|
|
]);
|
|
foreach ($subscription->beneficiaries as $b) {
|
|
NhInsurancesHavingRight::create([
|
|
'insurance_id' => $insurance->id,
|
|
'having_right_id' => $b->id
|
|
]);
|
|
}
|
|
}
|
|
|
|
if ($subscription->insurance_action == InsuranceAction::ADDITION_OF_BENEFICIARY) {
|
|
$insurance = NhInsurance::where('user_id', $subscription->user_id)->where('network_id', $subscription->network_id)->where('state', InsuranceState::PAID)->first();
|
|
if (!isset($insurance)) {
|
|
DB::rollBack();
|
|
return $this->errorResponse(trans('errors.not_insured'), 500);
|
|
}
|
|
|
|
$insurance->update([
|
|
'state' => InsuranceState::UNDER_ADDING_BENEFICIARY,
|
|
'updated_at' => $datetime,
|
|
]);
|
|
}
|
|
|
|
if (in_array($subscription->insurance_action, [InsuranceAction::ADDITION_OF_BENEFICIARY, InsuranceAction::ACTIVATION])) {
|
|
// Generer la facture
|
|
NhInsurancesInvoice::create([
|
|
'invoice_id' => $this->generateInsuranceInvoiceID(),
|
|
'insurance_id' => $insurance->id,
|
|
'subscription_id' => $subscription->id,
|
|
'amount' => $subscription->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),
|
|
'state' => InsuranceInvoiceState::UNPAID,
|
|
'deadlines' => $subscription->monthsGrid->number_of_fractions,
|
|
'paid_deadlines' => 0,
|
|
'amount_per_split' => $amount_per_split,
|
|
'amount_last_payment' => $amount_last_payment,
|
|
'reason' => $subscription->insurance_action,
|
|
'created_at' => $datetime, 'updated_at' => $datetime,
|
|
]);
|
|
}
|
|
$message = trans('messages.insurance_subscription_accepted');
|
|
$notification = trans('messages.insurance_subscription_accepted_notification', ['subscription_id' => $subscription->insurance_subscription_id]);
|
|
$mail = trans('messages.insurance_subscription_accepted_mail', $mail_data);
|
|
}
|
|
|
|
NhInsurancesSubscriptionsHistory::create([
|
|
'action' => 'EDIT',
|
|
'insurance_subscription_id' => $subscription->insurance_subscription_id,
|
|
'insurance_subscription_state' => $subscription->state,
|
|
'agent_id' => $request->input('agent_id'),
|
|
'nh_validating_agent_id' => $request->input('nh_validating_agent_id'),
|
|
'created_at' => $datetime, 'updated_at' => $datetime,
|
|
]);
|
|
|
|
Event::dispatch(new InsuranceEvent($subscription, $message, $mail, $notification));
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
public function rejectSubscription($id, Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'nh_validating_agent_id' => 'required_without:agent_id|nullable|integer|exists:nh_validating_agents,id',
|
|
'agent_id' => 'required_without:nh_validating_agent_id|nullable|integer|exists:agents,id',
|
|
'type' => 'required|in:NORMAL,MORE_INFORMATION',
|
|
'reason' => 'required'
|
|
]);
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
$subscription = NhInsurancesSubscription::findOrFail($id);
|
|
$datetime = $this->getCurrentTimeByCountryCode($subscription->network->country->code_country);
|
|
|
|
$type = $request->input('type');
|
|
$mailParams = ['name' => $subscription->user->lastname, 'subscription_id' => $subscription->insurance_subscription_id,
|
|
'bonus_amount' => $this->toMoneyWithNetwork($subscription->total_bonus_amount, $subscription->network_id), 'reason' => $request->input('reason'), 'number_of_beneficiaries' => $subscription->number_of_beneficiaries,
|
|
'gender' => trans('states.' . $subscription->user->identification->gender), 'insurance_name' => $subscription->network->name];
|
|
$notificationParams = ['subscription_id' => $subscription->insurance_subscription_id];
|
|
|
|
if ($type == 'NORMAL') {
|
|
$subscription->state = InsuranceSubscriptionState::REJECTED;
|
|
$mailTitle = trans('messages.insurance_subscription_rejected');
|
|
$mailMessage = trans('messages.insurance_subscription_rejected_mail', $mailParams);
|
|
$notification = trans('messages.insurance_subscription_rejected_notification', $notificationParams);
|
|
} else {
|
|
$subscription->state = InsuranceSubscriptionState::AWAITING_FURTHER_INFORMATION;
|
|
$mailTitle = trans('messages.insurance_subscription_awaiting_more_information');
|
|
$mailMessage = trans('messages.insurance_subscription_awaiting_more_information_mail', $mailParams);
|
|
$notification = trans('messages.insurance_subscription_awaiting_more_information_notification', $notificationParams);
|
|
|
|
}
|
|
$subscription->reason = $request->input('reason');
|
|
$subscription->updated_at = $datetime;
|
|
$subscription->save();
|
|
|
|
NhInsurancesSubscriptionsHistory::create([
|
|
'action' => 'EDIT',
|
|
'insurance_subscription_id' => $subscription->insurance_subscription_id,
|
|
'insurance_subscription_state' => $subscription->state,
|
|
'agent_id' => $request->input('agent_id'),
|
|
'nh_validating_agent_id' => $request->input('nh_validating_agent_id'),
|
|
'created_at' => $datetime, 'updated_at' => $datetime,
|
|
]);
|
|
|
|
Event::dispatch(new InsuranceEvent($subscription, $mailTitle, $mailMessage, $notification));
|
|
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\Put(
|
|
* path="/insurances/subscriptions/{id}/pay",
|
|
* summary="Activer et payer son assurance",
|
|
* 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(
|
|
* @OA\Property(property="password",
|
|
* type="string",
|
|
* example = "addfdf21",
|
|
* description="Mot de passe de l'utilisateur"
|
|
* )
|
|
* ),
|
|
* example = {"password":"adbc1215448"}
|
|
* )
|
|
* ),
|
|
* @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 paySubscription($id, Request $request)
|
|
{
|
|
// $this->validate($request, [
|
|
// 'password' => 'required|string',
|
|
// ]);
|
|
|
|
$subscription = NhInsurancesSubscription::findOrFail($id);
|
|
if ($subscription->state != InsuranceSubscriptionState::ACCEPTED) {
|
|
return $this->errorResponse(trans('errors.subscription_cannot_be_paid'));
|
|
}
|
|
|
|
if (isset($subscription->payment)) {
|
|
return $this->errorResponse(trans('errors.subscription_be_already_paid'));
|
|
}
|
|
|
|
$user = $subscription->user;
|
|
$this->userIdentificationVerification($user);
|
|
// Validation du mot de passe dépendamment de la configuration du réseau
|
|
$this->validate($request, [
|
|
'password' => [new PasswordValidation($subscription->network_id, 'user', $user)]
|
|
]);
|
|
|
|
$currency = $this->getNetworkCurrency($subscription->network_id);
|
|
|
|
$amountToPaid = $subscription->total_bonus_amount;
|
|
|
|
if ($user->wallet->balance < $amountToPaid) {
|
|
$amount = $amountToPaid - $user->wallet->balance;
|
|
return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($amount, $currency)]));
|
|
}
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
|
|
$datetime = $this->getCurrentTimeByCountryCode($subscription->network->country->code_country);
|
|
|
|
$hyperviseur = AgentPlus::where('category', 'hyper')->where('network_id', $subscription->network_id)->firstOrFail();
|
|
$walletHyperviseur = Wallet::where('id_networkAgent', $hyperviseur->network_agent_id)->firstOrFail();
|
|
$walletHyperviseur->balance_princ += $amountToPaid;
|
|
$walletHyperviseur->save();
|
|
|
|
$user->balance_nano_health += $amountToPaid;
|
|
$user->wallet->balance -= $amountToPaid;
|
|
$user->wallet->save();
|
|
$user->save();
|
|
|
|
if ($subscription->insurance_action == InsuranceAction::ACTIVATION) {
|
|
$insuredId = $this->generateInsuredID();
|
|
if (empty($subscription->monthsGrid->waiting_period_days)) {
|
|
$start_at = $datetime;
|
|
} else {
|
|
$start_at = $this->addDaysToDateTime($datetime, $subscription->monthsGrid->waiting_period_days)->format('Y-m-d H:i:s');
|
|
}
|
|
$end_at = $this->addMonthsToDateTime($start_at, $subscription->monthsGrid->number_of_months);
|
|
$insurance = NhInsurance::create([
|
|
'network_id' => $subscription->network_id,
|
|
'user_id' => $subscription->user_id,
|
|
'insured_id' => $insuredId,
|
|
'months_grid_id' => $subscription->months_grid_id,
|
|
'total_bonus_amount' => $subscription->total_bonus_amount,
|
|
'number_of_beneficiaries' => $subscription->number_of_beneficiaries,
|
|
'bonus_amount' => $subscription->bonus_amount,
|
|
'created_at' => $datetime, 'updated_at' => $datetime,
|
|
'state' => InsuranceState::PAID,
|
|
'start_at' => $start_at,
|
|
'end_at' => $end_at
|
|
]);
|
|
foreach ($subscription->beneficiaries as $b) {
|
|
NhInsurancesHavingRight::create([
|
|
'insurance_id' => $insurance->id,
|
|
'having_right_id' => $b->id
|
|
]);
|
|
}
|
|
} else {
|
|
$insurance = NhInsurance::where('network_id', $subscription->network_id)->where('user_id', $subscription->user_id)
|
|
->where('state', InsuranceState::PAID)->first();
|
|
if (!isset($insurance)) {
|
|
DB::rollBack();
|
|
return $this->errorResponse(trans('errors.not_insured'), 500);
|
|
}
|
|
|
|
if ($subscription->insurance_action == InsuranceAction::ADDITION_OF_BENEFICIARY) {
|
|
$insurance->bonus_amount = $subscription->bonus_amount;
|
|
$insurance->total_bonus_amount += $amountToPaid;
|
|
$insurance->number_of_beneficiaries += $subscription->number_of_beneficiaries;
|
|
$insurance->updated_at = $datetime;
|
|
$insurance->save();
|
|
|
|
foreach ($subscription->beneficiaries as $b) {
|
|
NhInsurancesHavingRight::create([
|
|
'insurance_id' => $insurance->id,
|
|
'having_right_id' => $b->id
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
$payment = NhInsurancesPayment::create([
|
|
'insurance_subscription_id' => $subscription->insurance_subscription_id,
|
|
'insured_id' => $insurance->insured_id,
|
|
'amount' => $amountToPaid,
|
|
'reason' => $subscription->insurance_action,
|
|
]);
|
|
$payment->created_at = $payment->updated_at = $datetime;
|
|
$payment->save();
|
|
|
|
Event::dispatch(new InsuranceEvent($subscription, trans('messages.insurance_subscription_paid'), trans('messages.insurance_subscription_paid_mail', ['name' => $subscription->user->lastname, 'subscription_id' => $subscription->insurance_subscription_id,
|
|
'bonus_amount' => $this->toMoneyWithCurrencyCode($subscription->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($subscription->total_bonus_amount, $currency), 'insured_id' => $insurance->insured_id, 'number_of_beneficiaries' => $subscription->number_of_beneficiaries,
|
|
'gender' => trans('states.' . $subscription->user->identification->gender), 'insurance_name' => $subscription->network->name, 'months' => $subscription->monthsGrid->number_of_months])));
|
|
DB::commit();
|
|
return $this->successResponse(trans('messages.insurance_subscription_paid'));
|
|
} catch (Throwable $e) {
|
|
Log::error($e->getMessage() . '\n' . $e->getTraceAsString());
|
|
DB::rollBack();
|
|
return $this->errorResponse(trans('errors.unexpected_error'), 500);
|
|
}
|
|
}
|
|
|
|
private function generateInsuredID(): string
|
|
{
|
|
do {
|
|
$code = generateTransactionCode();
|
|
$codeCorrect = NhInsurance::where('insured_id', $code)->count() < 0;
|
|
} while ($codeCorrect);
|
|
return $code;
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/insurances/subscriptions",
|
|
* summary="Afficher la liste des souscriptions d'assurances ( par utilisateur , par type)",
|
|
* tags={"Souscriptions à l'assurance"},
|
|
* 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=325
|
|
* )
|
|
* ),
|
|
* @OA\Parameter(
|
|
* parameter="type",
|
|
* name="type",
|
|
* description="Type de souscription",
|
|
* in="query",
|
|
* required=false,
|
|
* @OA\Schema(
|
|
* type="string",
|
|
* enum={"ALL","ACCEPTED"}
|
|
* )
|
|
* ),
|
|
* @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":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,"network": { "id": 250, "name": "Cnamgs-pharmacies" },
|
|
* "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
|
|
* }
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function getSubscriptions(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'user_id' => 'nullable|integer|exists:users,id',
|
|
'type' => 'nullable|in:ALL,ACCEPTED',
|
|
'pagination' => 'nullable|boolean'
|
|
]);
|
|
$user = User::findOrFail($request->input('user_id'));
|
|
$currency_code = $user->network->country->currency_code;
|
|
$pagination = $request->input('pagination');
|
|
|
|
$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 != 'ALL') {
|
|
// Les souscriptions payables
|
|
if ($type == 'ACCEPTED') {
|
|
$query = $query->whereNotIn('insurance_action', [InsuranceAction::STOP_INSURANCE]);
|
|
}
|
|
$query = $query->where('state', $type)->whereDoesntHave('payment');
|
|
}
|
|
}
|
|
|
|
if ($pagination) {
|
|
$subscriptions = $query->paginate($request->input('perPage', 10));
|
|
} else {
|
|
$subscriptions = $query->get();
|
|
}
|
|
|
|
$array = $pagination ? $subscriptions->items() : $subscriptions;
|
|
foreach ($array as $subscription) {
|
|
$subscription->state = trans('states.' . $subscription->state);
|
|
$subscription->insurance_action = trans('states.' . $subscription->insurance_action);
|
|
$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);
|
|
}
|
|
}
|