Made insurance invoice payment more flexible, so user can pay what he wants

This commit is contained in:
Djery-Tom 2022-05-02 08:03:42 +01:00
parent b9a5487f66
commit 50fd541415
16 changed files with 352 additions and 228 deletions

View File

@ -206,11 +206,11 @@ class Kernel extends ConsoleKernel
}
})->daily()->runInBackground();
// Generer les factures d'assurances chaque jour à minuit
// Mettre a jour les delai de paiements des factures d'assurances chaque jour à minuit
$schedule->call(function () {
try {
DB::beginTransaction();
$this->generateInsurancesInvoices();
$this->updateInsurancesInvoices();
DB::commit();
} catch (\Throwable $t) {
DB::rollBack();

View File

@ -340,7 +340,7 @@ class InsuranceController extends Controller
*
*/
$this->validate($request, [
// 'password' => 'required|string',
'password' => 'required|string',
'beneficiaries' => 'nullable|array',
'beneficiaries.*.lastname' => 'required|string',
'beneficiaries.*.gender' => 'required|in:M,F',
@ -362,9 +362,9 @@ class InsuranceController extends Controller
$identification = $insurance->user->identification;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
$this->validate($request, [
'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
]);
// $this->validate($request, [
// 'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
// ]);
$nbOfBeneficiaries = $insurance->beneficiaries()->count();
$networkConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first();
@ -666,21 +666,25 @@ class InsuranceController extends Controller
*/
public function renewInsurance(Request $request, $id)
{
// $this->validate($request, [
// 'password' => 'required|string',
// ]);
$this->validate($request, [
'password' => 'required|string',
]);
$insurance = NhInsurance::findOrFail($id);
if (!in_array($insurance->state, [InsuranceState::STOPPED, InsuranceState::EXPIRED])) {
return $this->errorResponse(__('errors.cannot_renew_insurance'));
}
if (NhInsurancesInvoice::where('insurance_id', $id)->where('state', InsuranceInvoiceState::UNPAID)->count() > 0) {
return $this->errorResponse("Vous avez des factures non payés");
}
$user = $insurance->user;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
$this->validate($request, [
'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
]);
// $this->validate($request, [
// 'password' => [new PasswordValidation($insurance->network_id, 'user', $user)]
// ]);
$networkConfig = NhNetworksConfig::where('network_id', $insurance->network_id)->first();
if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante')
@ -715,65 +719,42 @@ class InsuranceController extends Controller
$amount_per_split = ceil($total_bonus_amount / $monthPrice->number_of_fractions);
$amount_last_payment = $total_bonus_amount - ($amount_per_split * ($monthPrice->number_of_fractions - 1));
// Paiement de la 1ere facture
$amountToPaid = $amount_per_split;
if ($user->wallet->balance < $amountToPaid) {
$amount = $amountToPaid - $user->wallet->balance;
return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($amount, $currency)]));
}
$datetime = $this->getCurrentTimeByCountryCode($user->network->country->code_country);
$hyperviseur = AgentPlus::where('category', 'hyper')->where('network_id', $insurance->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 (empty($monthPrice->waiting_period_days)) {
$start_at = $datetime;
} else {
$start_at = $this->addDaysToDateTime($datetime, $monthPrice->waiting_period_days)->format('Y-m-d H:i:s');
}
$end_at = $this->addMonthsToDateTime($start_at, $monthPrice->number_of_months);
$insurance->update([
'number_of_beneficiaries' => sizeof($insurance->beneficiaries),
'total_bonus_amount' => $total_bonus_amount,
'bonus_amount' => $bonus_amount,
'insurance_coverage_amount' => 0,
'updated_at' => $datetime,
'state' => $monthPrice->number_of_fractions == 1 ? InsuranceState::PAID : InsuranceState::PARTIALLY_PAID,
'start_at' => $start_at,
'end_at' => $end_at,
'deadlines' => $monthPrice->number_of_fractions,
'paid_deadlines' => 1,
'amount_per_split' => $amount_per_split,
'amount_last_payment' => $amount_last_payment
'state' => InsuranceState::UNDER_RENEW,
'start_at' => null,
'end_at' => null,
]);
// Reinitialiser les montants de couvertures de l'assurance
$insurance->beneficiaries->each->update([
'insurance_coverage_amount' => 0
]);
// Generer la 1ere facture
// Generer la facture
NhInsurancesInvoice::create([
'invoice_id' => $this->generateInsuranceInvoiceID(),
'insurance_id' => $insurance->id,
'amount' => $amount_per_split,
'payment_deadline' => $this->addDaysToDateTime($datetime, $networkConfig->reminder_delay_days + $networkConfig->suspension_delay_days_after_reminder),
'payment_reminder' => $this->addDaysToDateTime($datetime, $networkConfig->reminder_delay_days),
'state' => InsuranceInvoiceState::PAID,
'amount' => $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),
'deadlines' => $monthPrice->number_of_fractions,
'paid_deadlines' => 1,
'next_payment_deadlines_to_paid' => 1,
'amount_per_split' => $amount_per_split,
'amount_last_payment' => $amount_last_payment,
'state' => InsuranceInvoiceState::UNPAID,
'reason' => InsuranceAction::RENEWAL,
'created_at' => $datetime, 'updated_at' => $datetime,
]);
Event::dispatch(new InsuranceEvent($insurance, trans('messages.insurance_renew'), trans('messages.insurance_renew_mail', ['name' => $user->lastname, 'insured_id' => $insurance->insured_id,
'bonus_amount' => $this->toMoneyWithCurrencyCode($bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($amountToPaid, $currency), 'number_of_beneficiaries' => $insurance->number_of_beneficiaries,
'bonus_amount' => $this->toMoneyWithCurrencyCode($bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($total_bonus_amount, $currency), 'number_of_beneficiaries' => $insurance->number_of_beneficiaries,
'gender' => trans('states.' . $user->identification->gender), 'insurance_name' => $insurance->network->name, 'months' => $monthPrice->number_of_months])));
DB::commit();
return $this->successResponse(trans('messages.insurance_renew_paid'));

View File

@ -102,7 +102,7 @@ class InsuranceInvoiceController extends Controller
* ref="#/components/schemas/ApiResponse",
* example = {
* "status" : 200,
* "response" : {{"id":1,"invoice_id":"SFSF6565656","insurance_id":5,"subscription_id":2,"amount":"495\u202f000 FCFA","payment_deadline":"2022-04-08 17:31:52","payment_reminder":"2022-04-05 17:31:52","state":"NON PAY\u00c9E",
* "response" : {{"id":1,"invoice_id":"SFSF6565656","insurance_id":5,"subscription_id":2,"amount":"495\u202f000 FCFA","next_payment_deadline":"2022-04-08 17:31:52","next_payment_reminder":"2022-04-05 17:31:52","state":"NON PAY\u00c9E",
* "reason":"ACTIVATION DE L'ASSURANCE","created_at":"2022-03-29T16:31:52.000000Z","updated_at":"2022-03-29T16:31:52.000000Z","insurance":{"id":5,"network_id":250,"user_id":349,"insured_id":"5DSTKZ7PQZX4",
* "months_grid_id":77,"bonus_amount":"150000.00","number_of_beneficiaries":2,"total_bonus_amount":"495000.00","insurance_coverage_amount":"0.00","start_at":null,"end_at":null,"state":"UNDER_ACTIVATION",
* "deadlines":1,"amount_last_payment":"495000.00","amount_per_split":"495000.00","paid_deadlines":0,"created_at":"2022-03-29T16:31:52.000000Z","updated_at":"2022-03-29T16:31:52.000000Z"},
@ -136,7 +136,7 @@ class InsuranceInvoiceController extends Controller
if (!empty($state)) {
// if ($state == 'TO_PAID') {
// $query = $query->where('state', InsuranceInvoiceState::UNPAID)
// ->where('payment_deadline', '>=', $datetime);
// ->where('next_payment_deadline', '>=', $datetime);
// } else {
$query = $query->where('state', $state);
// }
@ -184,6 +184,11 @@ class InsuranceInvoiceController extends Controller
* type="string",
* example = "addfdf21",
* description="Mot de passe de l'utilisateur"
* ),
* @OA\Property(property="amount",
* type="number",
* example = 32450,
* description="Montant à payer"
* )
* ),
* example = {"password":"adbc1215448"}
@ -202,10 +207,12 @@ class InsuranceInvoiceController extends Controller
*/
public function payInvoice($id, Request $request)
{
// $this->validate($request, [
// 'password' => 'required|string',
// ]);
$this->validate($request, [
'password' => 'required|string',
'amount' => 'required|numeric|min:0'
]);
$amountToPaid = $request->input('amount');
$invoice = NhInsurancesInvoice::findOrFail($id);
$datetime = $this->getCurrentTimeByCountryCode($invoice->insurance->network->country->code_country);
@ -213,25 +220,38 @@ class InsuranceInvoiceController extends Controller
return $this->errorResponse(trans('errors.invoice_already_paid'));
}
// if ($invoice->payment_deadline < $datetime) {
// return $this->errorResponse(trans('errors.payment_deadline_reached'));
// }
$networkConfig = NhNetworksConfig::where('network_id', $invoice->insurance->network_id)->first();
if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante') {
return $this->errorResponse(trans('errors.nano_health_not_activated'));
}
$user = $invoice->insurance->user;
$this->userIdentificationVerification($user);
// Validation du mot de passe dépendamment de la configuration du réseau
$this->validate($request, [
'password' => [new PasswordValidation($invoice->insurance->network_id, 'user', $user)]
]);
// $this->validate($request, [
// 'password' => [new PasswordValidation($invoice->insurance->network_id, 'user', $user)]
// ]);
$currency = $this->getNetworkCurrency($invoice->insurance->network_id);
$amountToPaid = $invoice->amount;
$total_paid_amount = NhInsurancesPayment::where('invoice_id', $id)->sum('amount');
$total_remains_amount = $invoice->amount - $total_paid_amount;
if ($amountToPaid > $total_remains_amount) {
return $this->errorResponse("Le montant maximum à payer est de " . $this->toMoneyWithCurrencyCode($total_remains_amount, $currency));
}
if ($amountToPaid < $invoice->amount_per_split && $amountToPaid < $total_remains_amount) {
if ($total_remains_amount < $invoice->amount_per_split) {
return $this->errorResponse(trans('errors.minimum amount_to_paid', ['amount' => $this->toMoneyWithCurrencyCode($total_remains_amount, $currency)]));
}
return $this->errorResponse(trans('errors.minimum amount_to_paid', ['amount' => $this->toMoneyWithCurrencyCode($invoice->amount_per_split, $currency)]));
}
if ($user->wallet->balance < $amountToPaid) {
$amount = $amountToPaid - $user->wallet->balance;
return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($amount, $currency)]));
$remains_amount = $amountToPaid - $user->wallet->balance;
return $this->errorResponse(trans('errors.insufficient_balance', ['amount' => $this->toMoneyWithCurrencyCode($remains_amount, $currency)]));
}
try {
@ -247,21 +267,37 @@ class InsuranceInvoiceController extends Controller
$user->wallet->save();
$user->save();
$invoice->update(['state' => InsuranceInvoiceState::PAID, 'updated_at' => $datetime]);
$invoice->insurance->paid_deadlines++;
if ($invoice->insurance->paid_deadlines == $invoice->insurance->deadlines) {
$payment = NhInsurancesPayment::create([
'payment_id' => $this->generateID('nh_insurances_payments', 'payment_id', 10),
'invoice_id' => $invoice->id,
'amount' => $amountToPaid
]);
// Calcul de l'equivalence en nombre d'echeance
$paid_deadlines = $amountToPaid < $invoice->amount_per_split ? 1 : intval($amountToPaid / $invoice->amount_per_split);
$invoice->paid_deadlines += $paid_deadlines;
$invoice->next_payment_deadlines_to_paid -= $paid_deadlines;
if ($invoice->next_payment_deadlines_to_paid < 0) {
$invoice->next_payment_deadlines_to_paid = 0;
}
if ($invoice->paid_deadlines == $invoice->deadlines) {
$invoice->insurance->state = InsuranceState::PAID;
$invoice->state = InsuranceInvoiceState::PAID;
$isPartialPayment = false;
} else {
$countUnpaidInvoices = NhInsurancesInvoice::where('insurance_id', $invoice->insurance->id)->where('state', InsuranceInvoiceState::UNPAID)->count();
if ($countUnpaidInvoices == 0) {
if ($invoice->next_payment_deadlines_to_paid == 0) {
$invoice->insurance->state = InsuranceState::PARTIALLY_PAID;
}
$deadline = $invoice->next_payment_deadline;
$invoice->next_payment_deadline = $this->addDaysToDateTime($deadline, $networkConfig->reminder_delay_days + $networkConfig->suspension_delay_days_after_reminder); // 1 semaines + 3 jours
$invoice->next_payment_reminder = $this->addDaysToDateTime($deadline, $networkConfig->reminder_delay_days);
$isPartialPayment = true;
}
// Si c'est le 1er paiement
if ($invoice->insurance->paid_deadlines == 1) {
if ($invoice->paid_deadlines == 1) {
if ($invoice->reason == InsuranceAction::ADDITION_OF_BENEFICIARY) {
$invoice->insurance->bonus_amount = $invoice->subscription->bonus_amount;
@ -290,17 +326,19 @@ class InsuranceInvoiceController extends Controller
}
}
$invoice->updated_at = $datetime;
$invoice->insurance->updated_at = $datetime;
$invoice->insurance->save();
$invoice->save();
Event::dispatch(new InsuranceEvent($invoice->insurance, $isPartialPayment ? trans('messages.insurance_partially_paid') : trans('messages.insurance_subscription_paid'),
trans('messages.insurance_paid_mail', ['name' => $invoice->insurance->user->lastname, 'insured_id' => $invoice->insurance->insured_id,
'bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->total_bonus_amount, $currency), 'number_of_beneficiaries' => $invoice->insurance->number_of_beneficiaries,
'gender' => trans('states.' . $invoice->insurance->user->identification->gender), 'insurance_name' => $invoice->insurance->network->name, 'months' => $invoice->insurance->monthsGrid->number_of_months, 'invoice_id' => $invoice->invoice_id,
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'paid_deadlines' => $invoice->insurance->paid_deadlines, 'remains_deadlines' => $invoice->insurance->deadlines - $invoice->insurance->paid_deadlines,
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'paid_amount' => $this->toMoneyWithCurrencyCode($total_paid_amount + $amountToPaid, $currency), 'remains_amount' => $this->toMoneyWithCurrencyCode($total_remains_amount - $amountToPaid, $currency),
'payment_period' => trans('states.' . $invoice->insurance->monthsGrid->payment_period), 'reason' => trans('states.' . $invoice->reason), 'title' => $isPartialPayment ? trans('messages.insurance_partially_paid_title') : trans('messages.insurance_fully_paid_title'),
'deadlines' => $invoice->insurance->deadlines, 'amount_per_split' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_per_split, $currency), 'amount_last_payment' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_last_payment, $currency),
'waiting_days' => empty($invoice->insurance->monthsGrid->waiting_period_days) ? trans('messages.none') : trans('messages.n_days', ['n' => $invoice->insurance->monthsGrid->waiting_period_days]),
'start_at' => $invoice->insurance->start_at
'start_at' => $invoice->insurance->start_at, 'payment_id' => $payment->payment_id
])));
DB::commit();
return $this->successResponse(trans('messages.insurance_invoice_paid'));
@ -311,20 +349,20 @@ class InsuranceInvoiceController extends Controller
}
}
public function generateInvoices()
{
try {
DB::beginTransaction();
$this->generateInsurancesInvoices();
DB::commit();
return $this->successResponse("Success");
} catch (\Throwable $t) {
DB::rollBack();
Log::error('-------- Insurances Invoices expired insurance-----------');
Log::error($t->getMessage() . " :\n" . $t->getTraceAsString());
return $this->errorResponse("Error");
}
}
// public function generateInvoices()
// {
// try {
// DB::beginTransaction();
// $this->generateInsurancesInvoices();
// DB::commit();
// return $this->successResponse("Success");
// } catch (\Throwable $t) {
// DB::rollBack();
// Log::error('-------- Insurances Invoices expired insurance-----------');
// Log::error($t->getMessage() . " :\n" . $t->getTraceAsString());
// return $this->errorResponse("Error");
// }
// }
public function reminderInvoices()
{

View File

@ -462,11 +462,7 @@ class InsuranceSubscriptionController extends Controller
'number_of_beneficiaries' => $subscription->number_of_beneficiaries,
'bonus_amount' => $subscription->bonus_amount,
'created_at' => $datetime, 'updated_at' => $datetime,
'state' => InsuranceState::UNDER_ACTIVATION,
'deadlines' => $subscription->monthsGrid->number_of_fractions,
'paid_deadlines' => 0,
'amount_per_split' => $amount_per_split,
'amount_last_payment' => $amount_last_payment
'state' => InsuranceState::UNDER_ACTIVATION
]);
foreach ($subscription->beneficiaries as $b) {
NhInsurancesHavingRight::create([
@ -485,24 +481,24 @@ class InsuranceSubscriptionController extends Controller
$insurance->update([
'state' => InsuranceState::UNDER_ADDING_BENEFICIARY,
'deadlines' => $subscription->monthsGrid->number_of_fractions,
'paid_deadlines' => 0,
'amount_per_split' => $amount_per_split,
'amount_last_payment' => $amount_last_payment,
'updated_at' => $datetime,
]);
}
if (in_array($subscription->insurance_action, [InsuranceAction::ADDITION_OF_BENEFICIARY, InsuranceAction::ACTIVATION])) {
// Generer la 1ere facture
// Generer la facture
NhInsurancesInvoice::create([
'invoice_id' => $this->generateInsuranceInvoiceID(),
'insurance_id' => $insurance->id,
'subscription_id' => $subscription->id,
'amount' => $amount_per_split,
'payment_deadline' => $this->addDaysToDateTime($datetime, $networkConfig->reminder_delay_days + $networkConfig->suspension_delay_days_after_reminder),
'payment_reminder' => $this->addDaysToDateTime($datetime, $networkConfig->reminder_delay_days),
'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,
]);

View File

@ -49,11 +49,7 @@ class NhInsurance extends Model
'bonus_amount',
'start_at',
'end_at',
'state',
'deadlines',
'paid_deadlines',
'amount_per_split',
'amount_last_payment'
'state'
];
public function network()

View File

@ -9,24 +9,6 @@ namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class NhInsurancesInvoice
*
* @property int $id
* @property string $invoice_id
* @property int $insurance_id
* @property int $subscription_id
* @property float $amount
* @property Carbon $payment_deadline
* @property Carbon $payment_reminder
* @property string $state
* @property string $reason
* @property int $deadline_number
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @package App\Models
*/
class NhInsurancesInvoice extends Model
{
protected $table = 'nh_insurances_invoices';
@ -37,17 +19,7 @@ class NhInsurancesInvoice extends Model
'deadline_number' => 'int'
];
protected $fillable = [
'invoice_id',
'insurance_id',
'subscription_id',
'amount',
'payment_deadline',
'payment_reminder',
'state',
'reason',
'deadline_number'
];
protected $guarded = ['id'];
public function insurance()
{

View File

@ -9,33 +9,14 @@ namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class NhInsurancesPayment
*
* @property int $id
* @property string $insurance_subscription_id
* @property string $insured_id
* @property float $amount
* @property string $reason
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @package App\Models
*/
class NhInsurancesPayment extends Model
{
protected $table = 'nh_insurances_payments';
protected $casts = [
'invoice_id' => 'int',
'amount' => 'float'
];
protected $fillable = [
'insurance_subscription_id',
'insured_id',
'amount',
'reason',
'created_at',
'updated_at'
];
protected $guarded = ['id'];
}

View File

@ -20,7 +20,9 @@ use App\Models\NhInfosHealthCareSheets;
use App\Models\NhInsurance;
use App\Models\NhInsurancesHavingRight;
use App\Models\NhInsurancesInvoice;
use App\Models\NhInsurancesPayment;
use App\Models\NhInsurancesSubscription;
use App\Models\NhInvoice;
use App\Models\NhMonthsPricesGrid;
use App\Models\NhNetworksConfig;
use App\Models\User;
@ -39,6 +41,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use stdClass;
use function Clue\StreamFilter\fun;
trait Helper
{
@ -367,53 +370,89 @@ trait Helper
return $code;
}
// Generer les factures des assurances à payer
public function generateInsurancesInvoices(): void
public function generateID($table, $column, $length = 12): string
{
$insurances = NhInsurance::with('monthsGrid')->whereIn('state', [InsuranceState::UNDER_ACTIVATION, InsuranceState::UNDER_ADDING_BENEFICIARY, InsuranceState::UNDER_RENEW,
InsuranceState::PARTIALLY_PAID, InsuranceState::SUSPENDED])
->whereColumn('paid_deadlines', '<', 'deadlines')->get();
do {
$code = generateTransactionCode($length);
$codeCorrect = count(DB::select("SELECT * FROM $table WHERE $column = :code", ['code' => $code])) < 0;
} while ($codeCorrect);
return $code;
}
foreach ($insurances as $i) {
$lastInvoice = NhInsurancesInvoice::where('insurance_id', $i->id)->orderBy('id', 'DESC')->first();
if (isset($lastInvoice) && $lastInvoice->deadline_number < $i->deadlines) {
if (in_array($i->monthsGrid->payment_period, ['DAILY', 'MONTHLY'])) {
// Si le paiement est mensuel, se rassurer que cela fait deja 1 mois
if ($i->monthsGrid->payment_period == 'MONTHLY' && $lastInvoice->created_at->diff(date('Y-m-d'))->m < 1) {
continue;
}
// Generer les factures des assurances à payer
// public function generateInsurancesInvoices(): void
// {
// $insurances = NhInsurance::with('monthsGrid')->whereIn('state', [InsuranceState::UNDER_ACTIVATION, InsuranceState::UNDER_ADDING_BENEFICIARY, InsuranceState::UNDER_RENEW,
// InsuranceState::PARTIALLY_PAID, InsuranceState::SUSPENDED])
// ->whereColumn('paid_deadlines', '<', 'deadlines')->get();
//
// foreach ($insurances as $i) {
// $lastInvoice = NhInsurancesInvoice::where('insurance_id', $i->id)->orderBy('id', 'DESC')->first();
// if (isset($lastInvoice) && $lastInvoice->deadline_number < $i->deadlines) {
// if (in_array($i->monthsGrid->payment_period, ['DAILY', 'MONTHLY'])) {
// // Si le paiement est mensuel, se rassurer que cela fait deja 1 mois
// if ($i->monthsGrid->payment_period == 'MONTHLY' && $lastInvoice->created_at->diff(date('Y-m-d'))->m < 1) {
// continue;
// }
//
// $networkConfig = NhNetworksConfig::where('network_id', $i->network_id)->first();
// if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante') {
// Log::error("Insurance Invoice generated " . trans('errors.nano_health_not_activated'));
// continue;
// }
//
// $current_deadline_number = $lastInvoice->deadline_number + 1;
// $invoice = NhInsurancesInvoice::create([
// 'invoice_id' => $this->generateInsuranceInvoiceID(),
// 'insurance_id' => $i->id,
// 'subscription_id' => $lastInvoice->subscription_id ?? null,
// 'amount' => $current_deadline_number == $i->deadlines ? $i->amount_last_payment : $i->amount_per_split,
// 'next_payment_deadline' => Carbon::now()->addDays(10), // 1 semaines + 3 jours
// 'next_payment_reminder' => Carbon::now()->addDays(7),
// 'state' => InsuranceInvoiceState::UNPAID,
// 'reason' => $lastInvoice->reason,
// 'deadline_number' => $current_deadline_number
// ]);
// $currency = $this->getNetworkCurrency($invoice->insurance->network_id);
// // Envoyer le mail
// Event::dispatch(new InsuranceEvent($invoice->insurance, trans('messages.insurance_invoice_generated_title'),
// trans('messages.insurance_invoice_generated_mail', ['name' => $invoice->insurance->user->lastname, 'insured_id' => $invoice->insurance->insured_id,
// 'bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->total_bonus_amount, $currency), 'number_of_beneficiaries' => $invoice->insurance->number_of_beneficiaries,
// 'gender' => trans('states.' . $invoice->insurance->user->identification->gender), 'insurance_name' => $invoice->insurance->network->name, 'months' => $invoice->insurance->monthsGrid->number_of_months, 'invoice_id' => $invoice->invoice_id,
// 'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'remains_deadlines' => $invoice->insurance->deadlines - $invoice->insurance->paid_deadlines - 1,
// 'payment_period' => trans('states.' . $invoice->insurance->monthsGrid->payment_period), 'reason' => trans('states.' . $invoice->reason), 'title' => trans('messages.insurance_invoice_generated_mail_title', ['deadline' => $current_deadline_number]), 'object' => trans('messages.the_invoice'),
// 'deadlines' => $invoice->insurance->deadlines, 'amount_per_split' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_per_split, $currency), 'amount_last_payment' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_last_payment, $currency),
// 'waiting_days' => empty($invoice->insurance->monthsGrid->waiting_period_days) ? trans('messages.none') : trans('messages.n_days', ['n' => $invoice->insurance->monthsGrid->waiting_period_days]),
// 'start_at' => $invoice->insurance->start_at
// ])));
// }
// }
// }
// }
$networkConfig = NhNetworksConfig::where('network_id', $i->network_id)->first();
if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante') {
Log::error("Insurance Invoice generated " . trans('errors.nano_health_not_activated'));
continue;
}
// Mettre a jour les factures chaque jour
public function updateInsurancesInvoices(): void
{
$invoices = NhInsurancesInvoice::whereHas('insurance')->with(['insurance.monthsGrid'])->where('state', InsuranceInvoiceState::UNPAID)
->whereDate('next_payment_reminder', date('Y-m-d'))->get();
$current_deadline_number = $lastInvoice->deadline_number + 1;
$invoice = NhInsurancesInvoice::create([
'invoice_id' => $this->generateInsuranceInvoiceID(),
'insurance_id' => $i->id,
'subscription_id' => $lastInvoice->subscription_id ?? null,
'amount' => $current_deadline_number == $i->deadlines ? $i->amount_last_payment : $i->amount_per_split,
'payment_deadline' => Carbon::now()->addDays(10), // 1 semaines + 3 jours
'payment_reminder' => Carbon::now()->addDays(7),
'state' => InsuranceInvoiceState::UNPAID,
'reason' => $lastInvoice->reason,
'deadline_number' => $current_deadline_number
]);
$currency = $this->getNetworkCurrency($invoice->insurance->network_id);
// Envoyer le mail
Event::dispatch(new InsuranceEvent($invoice->insurance, trans('messages.insurance_invoice_generated_title'),
trans('messages.insurance_invoice_generated_mail', ['name' => $invoice->insurance->user->lastname, 'insured_id' => $invoice->insurance->insured_id,
'bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->total_bonus_amount, $currency), 'number_of_beneficiaries' => $invoice->insurance->number_of_beneficiaries,
'gender' => trans('states.' . $invoice->insurance->user->identification->gender), 'insurance_name' => $invoice->insurance->network->name, 'months' => $invoice->insurance->monthsGrid->number_of_months, 'invoice_id' => $invoice->invoice_id,
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'remains_deadlines' => $invoice->insurance->deadlines - $invoice->insurance->paid_deadlines - 1,
'payment_period' => trans('states.' . $invoice->insurance->monthsGrid->payment_period), 'reason' => trans('states.' . $invoice->reason), 'title' => trans('messages.insurance_invoice_generated_mail_title', ['deadline' => $current_deadline_number]), 'object' => trans('messages.the_invoice'),
'deadlines' => $invoice->insurance->deadlines, 'amount_per_split' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_per_split, $currency), 'amount_last_payment' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_last_payment, $currency),
'waiting_days' => empty($invoice->insurance->monthsGrid->waiting_period_days) ? trans('messages.none') : trans('messages.n_days', ['n' => $invoice->insurance->monthsGrid->waiting_period_days]),
'start_at' => $invoice->insurance->start_at
])));
foreach ($invoices as $invoice) {
if (in_array($invoice->insurance->monthsGrid->payment_period, ['DAILY', 'MONTHLY'])) {
// Si le paiement est mensuel, se rassurer que cela fait deja 1 mois
if ($invoice->monthsGrid->payment_period == 'MONTHLY' && date_create($invoice->next_payment_deadline)->diff(new DateTime())->m < 1) {
continue;
}
$networkConfig = NhNetworksConfig::where('network_id', $invoice->insurance->network_id)->first();
if (!isset($networkConfig) || $networkConfig->configWallet->type != 'ilink_sante') {
continue;
}
$deadline = $invoice->next_payment_deadline;
$invoice->next_payment_deadlines_to_paid++;
$invoice->next_payment_deadline = $this->addDaysToDateTime($deadline, $networkConfig->reminder_delay_days + $networkConfig->suspension_delay_days_after_reminder); // 1 semaines + 3 jours
$invoice->next_payment_reminder = $this->addDaysToDateTime($deadline, $networkConfig->reminder_delay_days);
$invoice->save();
}
}
}
@ -421,25 +460,28 @@ trait Helper
public function reminderInsurancesInvoices(): void
{
$invoices = NhInsurancesInvoice::with(['insurance'])->where('state', InsuranceInvoiceState::UNPAID)
->whereDate('payment_reminder', date('Y-m-d'))->get();
->whereDate('next_payment_reminder', date('Y-m-d'))->get();
foreach ($invoices as $invoice) {
// Reminders
$currency = $this->getNetworkCurrency($invoice->insurance->network_id);
$total_paid_amount = NhInsurancesPayment::where('invoice_id', $invoice->id)->sum('amount');
Event::dispatch(new InsuranceEvent($invoice->insurance, trans('messages.insurance_payment_reminder'),
trans('messages.insurance_invoice_generated_mail', ['name' => $invoice->insurance->user->lastname, 'insured_id' => $invoice->insurance->insured_id,
'bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->total_bonus_amount, $currency), 'number_of_beneficiaries' => $invoice->insurance->number_of_beneficiaries,
'gender' => trans('states.' . $invoice->insurance->user->identification->gender), 'insurance_name' => $invoice->insurance->network->name, 'months' => $invoice->insurance->monthsGrid->number_of_months, 'invoice_id' => $invoice->invoice_id,
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'deadline' => $invoice->deadline_number, 'remains_deadlines' => $invoice->insurance->deadlines - $invoice->insurance->paid_deadlines, 'object' => trans('messages.the_payment'),
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'object' => trans('messages.the_payment'),
'payment_period' => trans('states.' . $invoice->insurance->monthsGrid->payment_period), 'reason' => trans('states.' . $invoice->reason), 'title' => trans('messages.insurance_payment_reminder_title', ['invoice_id' => $invoice->invoice_id, 'n_reminder' => 7, 'n_suspension' => 3]),
'deadlines' => $invoice->insurance->deadlines, 'amount_per_split' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_per_split, $currency), 'amount_last_payment' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_last_payment, $currency),
'paid_amount' => $this->toMoneyWithCurrencyCode($total_paid_amount, $currency), 'remains_amount' => $this->toMoneyWithCurrencyCode($invoice->amount - $total_paid_amount, $currency),
'waiting_days' => empty($invoice->insurance->monthsGrid->waiting_period_days) ? trans('messages.none') : trans('messages.n_days', ['n' => $invoice->insurance->monthsGrid->waiting_period_days]),
'start_at' => $invoice->insurance->start_at
])));
}
$invoices = NhInsurancesInvoice::whereHas('insurance')->with(['insurance'])->where('state', InsuranceInvoiceState::UNPAID)
->whereDate('payment_deadline', Carbon::now()->subDay())->get();
$invoices = NhInsurancesInvoice::whereHas('insurance', function ($q) {
return $q->whereNotIn('state', [InsuranceState::STOPPED, InsuranceState::EXPIRED]);
})->with(['insurance'])->where('state', InsuranceInvoiceState::UNPAID)
->whereDate('next_payment_deadline', Carbon::now()->subDay())->get();
foreach ($invoices as $invoice) {
$invoice->insurance->update([
@ -450,13 +492,14 @@ trait Helper
foreach ($invoices as $invoice) {
// Reminders
$currency = $this->getNetworkCurrency($invoice->insurance->network_id);
$total_paid_amount = NhInsurancesPayment::where('invoice_id', $invoice->id)->sum('amount');
Event::dispatch(new InsuranceEvent($invoice->insurance, trans('messages.insurance_payment_suspended'),
trans('messages.insurance_paid_mail', ['name' => $invoice->insurance->user->lastname, 'insured_id' => $invoice->insurance->insured_id,
'bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->bonus_amount, $currency), 'total_bonus_amount' => $this->toMoneyWithCurrencyCode($invoice->insurance->total_bonus_amount, $currency), 'number_of_beneficiaries' => $invoice->insurance->number_of_beneficiaries,
'gender' => trans('states.' . $invoice->insurance->user->identification->gender), 'insurance_name' => $invoice->insurance->network->name, 'months' => $invoice->insurance->monthsGrid->number_of_months, 'invoice_id' => $invoice->invoice_id,
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency), 'paid_deadlines' => $invoice->insurance->paid_deadlines, 'remains_deadlines' => $invoice->insurance->deadlines - $invoice->insurance->paid_deadlines,
'amount' => $this->toMoneyWithCurrencyCode($invoice->amount, $currency),
'payment_period' => trans('states.' . $invoice->insurance->monthsGrid->payment_period), 'reason' => trans('states.' . $invoice->reason), 'title' => trans('messages.insurance_payment_suspended_title'),
'deadlines' => $invoice->insurance->deadlines, 'amount_per_split' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_per_split, $currency), 'amount_last_payment' => $this->toMoneyWithCurrencyCode($invoice->insurance->amount_last_payment, $currency),
'paid_amount' => $this->toMoneyWithCurrencyCode($total_paid_amount, $currency), 'remains_amount' => $this->toMoneyWithCurrencyCode($invoice->amount - $total_paid_amount, $currency),
'waiting_days' => empty($invoice->insurance->monthsGrid->waiting_period_days) ? trans('messages.none') : trans('messages.n_days', ['n' => $invoice->insurance->monthsGrid->waiting_period_days]),
'start_at' => $invoice->insurance->start_at
])));

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class RecreateNhInsurancesPaymentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::dropIfExists('nh_insurances_payments');
Schema::create('nh_insurances_payments', function (Blueprint $table) {
$table->id();
$table->string('payment_id')->unique();
$table->integer('invoice_id');
$table->decimal('amount', 10, 2);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('nh_insurances_payments');
}
}

View File

@ -0,0 +1,48 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddDeadlinesAndSplitAmountsToNhInsurancesInvoicesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('nh_insurances_invoices', function (Blueprint $table) {
$table->renameColumn('payment_deadline', 'next_payment_deadline');
$table->renameColumn('payment_reminder', 'next_payment_reminder');
$table->unsignedInteger('deadlines')->nullable()->comment("Nombre total d'écheances")
->after('state');
$table->unsignedInteger('paid_deadlines')->nullable()->comment("Nombre d'écheances payées")
->after('deadlines');
$table->decimal('amount_per_split', 10)->nullable()->comment("Montant par echeance")
->after('paid_deadlines');
$table->decimal('amount_last_payment', 10)->nullable()->comment("Montant de la derniere echeance")
->after('amount_per_split');
$table->unsignedInteger('next_payment_deadlines_to_paid')->default(1)->comment("Nombre d'echeances à payer lors du prochain payment pour reactiver son assurance")
->after('paid_deadlines');
$table->dropColumn('deadline_number');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('nh_insurances_invoices', function (Blueprint $table) {
$table->dropColumn(['deadlines', 'paid_deadlines', 'amount_per_split', 'amount_last_payment', 'next_payment_deadlines_to_paid']);
$table->renameColumn('next_payment_deadline', 'payment_deadline');
$table->renameColumn('next_payment_reminder', 'payment_reminder');
$table->unsignedInteger('deadline_number')->default(1)->comment("Numero de la dealine")
->after('reason');
});
}
}

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class RemoveDeadlinesDetailsToNhInsurances extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('nh_insurances', function (Blueprint $table) {
$table->dropColumn(['deadlines', 'paid_deadlines', 'amount_per_split', 'amount_last_payment']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('nh_insurances', function (Blueprint $table) {
$table->unsignedInteger('deadlines')->default(0)->comment("Nombre total d'écheances")
->after('state');
$table->unsignedInteger('paid_deadlines')->default(0)->comment("Nombre d'écheances payées")
->after('deadlines');
$table->decimal('amount_per_split', 10)->default(0)->comment("Montant par echeance")
->after('paid_deadlines');
$table->decimal('amount_last_payment', 10)->default(0)->comment("Montant de la derniere echeance")
->after('amount_per_split');
});
}
}

View File

@ -69,5 +69,7 @@ return [
'act_authorization_request_required' => "An authorization is required to apply the act :act_name",
'act_unit_quantity_required' => "The unit quantity is required for the act :act_name",
'prescription_ordered_quantity_must_not_greater_than_ordered_quantity' => "Prescription quantity :id must not be greater than :quantity",
'consultation_prescription_not_found' => "The consultation attached to this prescription does not exist"
'consultation_prescription_not_found' => "The consultation attached to this prescription does not exist",
'minimum amount_to_paid' => "The minimum amount to pay is :amount",
'maximum amount_to_paid' => "The maximum amount to pay is :amount"
];

View File

@ -195,10 +195,11 @@ Your insurance has expired.
:title
Payment information :
- ID: :invoice_id
- ID: :payment_id
- Invoice ID: :invoice_id
- Amount: :amount
- Number of paid installments: :paid_deadlines
- Number of remaining deadlines: :remains_deadlines :remains_deadlines
- Amount paid: :paid_amount
- Remaining amount: :remains_amount
- Reason: :reason
Insurance information :
@ -209,9 +210,6 @@ Your insurance has expired.
- Number of beneficiaries : :number_of_beneficiaries
- Number of months: :months
- Payment period: :payment_period
- Total number of instalments: :deadlines
- Amount per due date: :amount_per_split
- Amount of the last payment: :amount_last_payment
- Waiting period: :waiting_days
- Start date of the insurance: :start_at
",
@ -232,8 +230,8 @@ Your insurance has expired.
:object information :
- ID: :invoice_id
- Amount: :amount
- Due : :deadline
- Number of remaining deadlines : :remains_deadlines
- Amount paid: :paid_amount
- Remaining amount: :remains_amount
- Reason: :reason
Insurance information :
@ -244,9 +242,6 @@ Your insurance has expired.
- Number of beneficiaries : :number_of_beneficiaries
- Number of months: :months
- Payment period: :payment_period
- Number of total deadlines: :deadlines
- Amount per due date: :amount_per_split
- Amount of the last payment: :amount_last_payment
- Waiting period: :waiting_days
- Start date of the insurance: :start_at
",

View File

@ -72,6 +72,8 @@ return [
'consultation_prescription_not_found' => "La consultation rattaché à cette prescription n'existe pas",
'sheet_performances_duplicata' => "La feuille de soins a des duplicata de prestations",
'sheet_exams_duplicata' => "La feuille de soins a des duplicata d'examens",
'sheet_prescriptions_duplicata' => "La feuille de soins a des duplicata de prescriptions médicales"
'sheet_prescriptions_duplicata' => "La feuille de soins a des duplicata de prescriptions médicales",
'minimum_amount_to_paid' => "Le montant minimum à payer est de :amount",
'maximum_amount_to_paid' => "Le montant maximum à payer est de :amount"
];

View File

@ -212,10 +212,11 @@ Votre assurance est arrivée à échéance.
:title
Informations sur le paiement :
- ID : :invoice_id
- ID : :payment_id
- ID de la facture : :invoice_id
- Montant : :amount
- Nombre d'échéances payées : :paid_deadlines
- Nombre d'échéances restantes : :remains_deadlines
- Montant payé : :paid_amount
- Montant restant : :remains_amount
- Motif : :reason
Informations de l'assurance :
@ -226,9 +227,6 @@ Votre assurance est arrivée à échéance.
- Nombre d'ayants droit : :number_of_beneficiaries
- Nombre de mois : :months
- Période de paiement : :payment_period
- Nombre d'échéances totales : :deadlines
- Montant par échéance : :amount_per_split
- Montant de la dernière échéance : :amount_last_payment
- Délai de carence : :waiting_days
- Date de debut de l'assurance : :start_at
",
@ -249,8 +247,8 @@ Votre assurance est arrivée à échéance.
Informations sur :object :
- ID : :invoice_id
- Montant : :amount
- Echéance : :deadline
- Nombre d'échéances restantes : :remains_deadlines
- Montant payé : :paid_amount
- Montant restant : :remains_amount
- Motif : :reason
Informations de l'assurance :
@ -261,9 +259,6 @@ Votre assurance est arrivée à échéance.
- Nombre d'ayants droit : :number_of_beneficiaries
- Nombre de mois : :months
- Période de paiement : :payment_period
- Nombre d'échéances totales : :deadlines
- Montant par échéance : :amount_per_split
- Montant de la dernière échéance : :amount_last_payment
- Délai de carence : :waiting_days
- Date de debut de l'assurance : :start_at
",

View File

@ -32,7 +32,7 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route
$router->post('', 'InsuranceSubscriptionController@subscribe');
$router->put('{id}/validate', 'InsuranceSubscriptionController@validateSubscription');
$router->put('{id}/reject', 'InsuranceSubscriptionController@rejectSubscription');
$router->put('{id}/pay', 'InsuranceSubscriptionController@paySubscription');
// $router->put('{id}/pay', 'InsuranceSubscriptionController@paySubscription'); //OLD
$router->get('', 'InsuranceSubscriptionController@getSubscriptions');
});