Improve Insurance Subscription

This commit is contained in:
Djery-Tom 2021-10-20 14:05:23 +01:00
parent c34f901b07
commit 7ad3a8a431
10 changed files with 128 additions and 34 deletions

View File

@ -7,7 +7,7 @@ use Laravel\Lumen\Routing\Controller as BaseController;
/**
* @OA\Info(
* title="Nano Service API",
* title="Nano Santé Service API",
* version="1.0.0",
* @OA\Contact(
* email="administrateur@ilink-app.com",

View File

@ -9,8 +9,10 @@ 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\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
@ -55,8 +57,8 @@ class InsuranceController extends Controller
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":250,"name":"Cnamgs-pharmacies","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":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
* }
* )
@ -67,7 +69,8 @@ class InsuranceController extends Controller
{
$country = CountriesCurrency::findOrFail($countryId);
$insurances = DB::select("SELECT n.id , n.name , 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
$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) {
@ -143,16 +146,9 @@ class InsuranceController extends Controller
if (!isset($monthPrice))
return $this->errorResponse(trans('errors.incorrect_selected_amount'));
$bonus = 0;
$bonus = $monthPrice->min_amount;
foreach ($request->input('beneficiaries') as $b) {
$age = date_diff(date_create($b['birthdate']), date_create('now'))->y;
$levels = $networkConfig->yearsPricesGrid->filter(function ($level) use ($age) {
return $level->min_age <= $age && $level->max_age >= $age;
});
foreach ($levels as $level) {
$bonus += $level->markup_percentage * $monthPrice->min_amount / 100;
}
$bonus += $this->calculateBeneficiaryBonusAmount(new NhInsurancesHavingRight($b), $networkConfig->yearsPricesGrid, $monthPrice);
}
return $this->successResponse([
@ -161,6 +157,27 @@ class InsuranceController 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(
@ -174,7 +191,7 @@ class InsuranceController extends Controller
* @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,"bonus_amount":20000,"beneficiaries":{{"lastname":"Djery","firstname":"DI","gender":"M","birthdate":"2001-10-05",
* 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"}}}
* )
@ -195,7 +212,7 @@ class InsuranceController extends Controller
* @OA\Schema(
* schema="subscribe_incurance",
* title = "Souscription à une assurance",
* required={"network_id", "user_id" , "month_price_id","bonus_amount" , "beneficiaries"},
* required={"network_id", "user_id" , "password", "month_price_id", "beneficiaries"},
* @OA\Property(property="network_id",
* type="integer",
* example = 250,
@ -216,11 +233,6 @@ class InsuranceController extends Controller
* example=2,
* description="ID de la grille de prix choisit lors de la souscription"
* ),
* @OA\Property(property="bonus_amount",
* type="double",
* example=30000,
* description="Montant de la prime"
* ),
* @OA\Property(property="beneficiaries",
* type="array",
* description="Listes des beneficiaires ou ayants droit",
@ -302,7 +314,6 @@ class InsuranceController extends Controller
'user_id' => 'required|integer|exists:users,id',
'password' => 'required|string',
'month_price_id' => 'required|integer|exists:nh_months_prices_grid,id',
'bonus_amount' => 'required|numeric|min:0',
'beneficiaries' => 'required|array',
'beneficiaries.*.lastname' => 'required|string',
'beneficiaries.*.gender' => 'required|in:M,F',
@ -318,7 +329,7 @@ class InsuranceController extends Controller
]);
$identification = Identification::where('id_user', $request->input('user_id'))->first();
if (!isset($identification))
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))
@ -342,16 +353,22 @@ class InsuranceController extends Controller
$subscription->number_of_beneficiaries = sizeof($request->input('beneficiaries'));
$subscription->insurance_subscription_id = $this->generateSubscriptionID();
$subscription->number_of_months = $monthPrice->number_of_months;
$subscription->amount = $monthPrice->min_amount;
$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,

View File

@ -46,7 +46,7 @@ class NotifyUser
$body = new \stdClass();
$body->title = trans('messages.insurance_subscription');
$body->message = trans('messages.insurance_subscription_mail', ['name' => $user->lastname, 'subscription_id' => $subscription->insurance_subscription_id,
'bonus_amount' => $this->toMoneyWithNetwork($subscription->bonus_amount, $subscription->network_id), 'number_of_beneficiaries' => $subscription->number_of_beneficiaries]);
'bonus_amount' => $this->toMoneyWithNetwork($subscription->total_bonus_amount, $subscription->network_id), 'number_of_beneficiaries' => $subscription->number_of_beneficiaries]);
$body->email = $user->email;
$response = $client->request('POST', '/send-mail', ['json' => $body, 'headers' => $headers]);

View File

@ -20,6 +20,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @property string $gender
* @property Carbon $birthdate
* @property string $affiliation
* @property float $bonus_amount
* @property string|null $birthdate_proof
* @property string|null $birthdate_proof_doc
* @property string|null $justice_doc
@ -39,6 +40,10 @@ class NhInsurancesHavingRight extends Model
protected $table = 'nh_insurances_having_rights';
protected $casts = [
'bonus_amount' => 'float'
];
protected $dates = [
'birthdate'
];
@ -50,6 +55,7 @@ class NhInsurancesHavingRight extends Model
'gender',
'birthdate',
'affiliation',
'bonus_amount',
'birthdate_proof',
'birthdate_proof_doc',
'justice_doc',

View File

@ -17,9 +17,9 @@ use Illuminate\Database\Eloquent\Model;
* @property int $network_id
* @property int $user_id
* @property int $number_of_months
* @property int $amount
* @property int $number_of_beneficiaries
* @property float $bonus_amount
* @property int $number_of_beneficiaries
* @property float $total_bonus_amount
* @property string $state
* @property Carbon $created_at
* @property Carbon $updated_at
@ -34,7 +34,7 @@ class NhInsurancesSubscription extends Model
'network_id' => 'int',
'user_id' => 'int',
'number_of_months' => 'int',
'amount' => 'int',
'total_bonus_amount' => 'float',
'number_of_beneficiaries' => 'int',
'bonus_amount' => 'float'
];
@ -44,7 +44,7 @@ class NhInsurancesSubscription extends Model
'network_id',
'user_id',
'number_of_months',
'amount',
'total_bonus_amount',
'number_of_beneficiaries',
'bonus_amount',
'state'

View File

@ -15,8 +15,9 @@ use Illuminate\Database\Eloquent\Model;
* @property int $id
* @property int $network_id
* @property string $provider_billing_period
* @property float $max_number_of_beneficiaries
* @property float $age_limit_of_child_beneficiary
* @property int $max_number_of_beneficiaries
* @property int $age_limit_of_child_beneficiary
* @property int $age_limit_of_insured_and_spouse
* @property float $coverage_limit_per_insured_per_year
* @property float $current_affection_percentage_insurer
* @property float $current_affection_percentage_insured
@ -35,8 +36,9 @@ class NhNetworksConfig extends Model
protected $casts = [
'network_id' => 'int',
'max_number_of_beneficiaries' => 'float',
'age_limit_of_child_beneficiary' => 'float',
'max_number_of_beneficiaries' => 'int',
'age_limit_of_insured_and_spouse' => 'int',
'age_limit_of_child_beneficiary' => 'int',
'coverage_limit_per_insured_per_year' => 'float',
'current_affection_percentage_insurer' => 'float',
'current_affection_percentage_insured' => 'float',
@ -50,6 +52,7 @@ class NhNetworksConfig extends Model
'network_id',
'provider_billing_period',
'max_number_of_beneficiaries',
'age_limit_of_insured_and_spouse',
'age_limit_of_child_beneficiary',
'coverage_limit_per_insured_per_year',
'current_affection_percentage_insurer',

View File

@ -19,9 +19,9 @@ class CreateNhInsurancesSubscriptionsTable extends Migration
$table->integer('network_id');
$table->integer('user_id');
$table->integer('number_of_months')->comment("Durée de couverture en mois");
$table->integer('amount')->comment("Montant de la durée de couverture");
$table->decimal('bonus_amount', 10, 2)->comment("Montant de la prime pour la durée de couverture choisi");
$table->integer('number_of_beneficiaries');
$table->decimal('bonus_amount', 10, 2)->default(0);
$table->decimal('total_bonus_amount', 12, 2)->default(0)->comment("Montant total de la prime (assuré + ayants droit)");
$table->enum('state', ['UNDER_VALIDATION', 'ACCEPTED', 'REJECTED', 'UNDER_STOPPING', 'STOPPED'])->default('UNDER_VALIDATION');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent();

View File

@ -21,6 +21,7 @@ class CreateNhInsurancesHavingRights extends Migration
$table->enum('gender', ['M', 'F'])->default('M');
$table->date('birthdate');
$table->enum('affiliation', ['CHILD', 'SPOUSE'])->default('CHILD')->comment("Affiliation: enfant ou conjoint");
$table->decimal('bonus_amount', 10, 2)->default(0)->comment("Montant de la prime");
$table->enum('birthdate_proof', ['CERTIFIED_COPY', 'CERTIFICATE'])->default('CERTIFIED_COPY')->nullable()
->comment("Pour enfant ayant droit - Copie légalisée acte de naissance ou certificat de naissance");
$table->string('birthdate_proof_doc')->nullable()->comment("Nom du document uploadé");

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAgeLimitOfInsuredAndSpouseInNhNetworksConfigsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('nh_networks_configs', function (Blueprint $table) {
//
$table->decimal('age_limit_of_insured_and_spouse', 2, 0)->default(0)
->after('max_number_of_beneficiaries')
->comment('Age limite de lassuré et du conjoint : un nombre à 2 chiffres');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('nh_networks_configs', function (Blueprint $table) {
//
$table->dropColumn('age_limit_of_insured_and_spouse');
});
}
}

View File

@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateNhInfosInsurancesSubscriptionsView extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
DB::statement("CREATE VIEW nh_infos_insurances_subscriptions AS
SELECT nhis.* , cc.currency_code , u.lastname , u.phone, u.email FROM nh_insurances_subscriptions nhis JOIN networks n ON nhis.network_id = n.id
JOIN countries_currencies cc ON n.country_id = cc.id JOIN users u ON nhis.user_id = u.id");
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
DB::statement('DROP VIEW nh_infos_insurances_subscriptions_view');
}
}