diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index edc6f69..2fd03e2 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -3,6 +3,8 @@ namespace App\Console; use App\BillingPeriodType; +use App\Events\InsuranceEvent; +use App\InsuranceInvoiceState; use App\InsuranceState; use App\InsuranceSubscriptionState; use App\Models\AgentPlus; @@ -10,13 +12,16 @@ use App\Models\CountriesCurrency; use App\Models\NhHealthCareSheet; use App\Models\NhInfosInsurances; use App\Models\NhInsurance; +use App\Models\NhInsurancesInvoice; use App\Models\NhInvoice; use App\Models\NhNetworksConfig; use App\Traits\Helper; use Barryvdh\DomPDF\Facade as PDF; +use Carbon\Carbon; use DateTime; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; use Laravel\Lumen\Console\Kernel as ConsoleKernel; @@ -199,5 +204,29 @@ class Kernel extends ConsoleKernel Log::error($t->getMessage() . " :\n" . $t->getTraceAsString()); } })->daily()->runInBackground(); + + // Generer les factures d'assurances chaque jour à minuit + $schedule->call(function () { + try { + DB::beginTransaction(); + $this->generateInsurancesInvoices(); + DB::commit(); + } catch (\Throwable $t) { + DB::rollBack(); + Log::error('-------- Generate Insurances Invoices -----------'); + Log::error($t->getMessage() . " :\n" . $t->getTraceAsString()); + } + })->daily()->runInBackground(); + + // Rappeler les assures de reglés leurs factures + $schedule->call(function () { + try { + $this->reminderInsurancesInvoices(); + } catch (\Throwable $t) { + DB::rollBack(); + Log::error('-------- Insurances Invoices Reminder -----------'); + Log::error($t->getMessage() . " :\n" . $t->getTraceAsString()); + } + })->daily()->runInBackground(); } } diff --git a/app/Http/Controllers/InsuranceInvoiceController.php b/app/Http/Controllers/InsuranceInvoiceController.php index a10be40..217a2f3 100644 --- a/app/Http/Controllers/InsuranceInvoiceController.php +++ b/app/Http/Controllers/InsuranceInvoiceController.php @@ -294,4 +294,32 @@ class InsuranceInvoiceController extends Controller return $this->errorResponse(trans('errors.unexpected_error'), 500); } } + + public function generateInvoices() + { + try { + DB::beginTransaction(); + $this->generateInsurancesInvoices(); + DB::commit(); + return $this->errorResponse("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() + { + try { + $this->reminderInsurancesInvoices(); + return $this->errorResponse("Success"); + } catch (\Throwable $t) { + DB::rollBack(); + Log::error('-------- Insurances Invoices expired insurance-----------'); + Log::error($t->getMessage() . " :\n" . $t->getTraceAsString()); + return $this->errorResponse("Error"); + } + } } diff --git a/app/Models/NhInsurancesInvoice.php b/app/Models/NhInsurancesInvoice.php index 2fe4eca..8c2f882 100644 --- a/app/Models/NhInsurancesInvoice.php +++ b/app/Models/NhInsurancesInvoice.php @@ -21,6 +21,7 @@ use Illuminate\Database\Eloquent\Model; * @property Carbon $payment_reminder * @property string $state * @property string $reason + * @property int $deadline_number * @property Carbon|null $created_at * @property Carbon|null $updated_at * @@ -33,6 +34,7 @@ class NhInsurancesInvoice extends Model protected $casts = [ 'insurance_id' => 'int', 'subscription_id' => 'int', + 'deadline_number' => 'int' ]; protected $fillable = [ @@ -43,7 +45,8 @@ class NhInsurancesInvoice extends Model 'payment_deadline', 'payment_reminder', 'state', - 'reason' + 'reason', + 'deadline_number' ]; public function insurance() diff --git a/app/Traits/Helper.php b/app/Traits/Helper.php index 8928ef1..a261104 100644 --- a/app/Traits/Helper.php +++ b/app/Traits/Helper.php @@ -4,8 +4,10 @@ namespace App\Traits; +use App\Events\InsuranceEvent; use App\Exceptions\AppException; use App\HealthCareSheetType; +use App\InsuranceInvoiceState; use App\InsuranceState; use App\InsuranceSubscriptionAffiliation; use App\InsuranceSubscriptionState; @@ -24,6 +26,7 @@ use App\Models\NhNetworksConfig; use App\Models\User; use Brick\Money\Context\AutoContext; use Brick\Money\Money; +use Carbon\Carbon; use DateTime; use DateTimeZone; use Exception; @@ -31,6 +34,7 @@ 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 Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; @@ -302,7 +306,7 @@ trait Helper */ // Verification de la limite de couverture public function verifyInsuranceCoverageAmount(NhNetworksConfig $nhConfig, NhInsurance $insurance, NhHealthCareSheet $sheet, NhHavingRight $beneficiary = null, - $currency_code = 'XAF', $currentInsuranceAmount = 0) // Current Insurance Amount en cas de mise à jour de la feuille de soins pour ne pas prendre en compte la couverture deja affecté + $currency_code = 'XAF', $currentInsuranceAmount = 0) // Current Insurance Amount en cas de mise à jour de la feuille de soins pour ne pas prendre en compte la couverture deja affecté { $insurance_coverage_amount = isset($beneficiary) ? $beneficiary->insurance_coverage_amount : $insurance->insurance_coverage_amount; $insurance_amount = $sheet->insurance_amount; @@ -340,7 +344,7 @@ trait Helper public function updateInsuranceCoverageAmount(NhHealthCareSheet $sheet, NhInsurance $insurance, $datetime, - NhHavingRight $beneficiary = null, $currentInsuranceAmount = 0): void + NhHavingRight $beneficiary = null, $currentInsuranceAmount = 0): void { // Current Insurance Amount en cas de mise à jour de la feuille de soins pour ne pas prendre en compte la couverture deja affecté) $sheet->insurance_consumed_at = $datetime; if (!empty($beneficiary)) { @@ -363,5 +367,67 @@ trait Helper return $code; } + // 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]) + ->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 paiment 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; + } + $current_deadline_number = $lastInvoice->deadline_number + 1; + 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 + ]); + } + } + } + } + + public function reminderInsurancesInvoices(): void + { + $invoices = NhInsurancesInvoice::with(['insurance'])->where('state', InsuranceInvoiceState::UNPAID) + ->whereDate('payment_reminder', date('Y-m-d'))->get(); + + foreach ($invoices as $invoice) { + // Reminders + $currency = $this->getNetworkCurrency($invoice->insurance->network_id); + Event::dispatch(new InsuranceEvent($invoice->insurance, trans('messages.insurance_payment_reminder'), + 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, + 'reason' => trans('states.' . $invoice->reason), 'title' => trans('messages.insurance_payment_reminder_title')]))); + } + + $invoices = NhInsurancesInvoice::with(['insurance'])->where('state', InsuranceInvoiceState::UNPAID) + ->whereDate('payment_deadline', Carbon::now()->subDay())->get(); + + foreach ($invoices as $invoice) { + // Reminders + $currency = $this->getNetworkCurrency($invoice->insurance->network_id); + 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, + 'reason' => trans('states.' . $invoice->reason), 'title' => trans('messages.insurance_payment_suspended_title')]))); + } + } + } diff --git a/database/migrations/2022_03_30_094142_add_dealine_number_to_nh_insurances_invoices.php b/database/migrations/2022_03_30_094142_add_dealine_number_to_nh_insurances_invoices.php new file mode 100644 index 0000000..17b9577 --- /dev/null +++ b/database/migrations/2022_03_30_094142_add_dealine_number_to_nh_insurances_invoices.php @@ -0,0 +1,33 @@ +unsignedInteger('deadline_number')->default(1)->comment("Numero de la dealine") + ->after('reason'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('nh_insurances_invoices', function (Blueprint $table) { + $table->dropColumn(['deadline_number']); + }); + } +} diff --git a/resources/lang/en/messages.php b/resources/lang/en/messages.php index 925052b..bc2a64f 100755 --- a/resources/lang/en/messages.php +++ b/resources/lang/en/messages.php @@ -210,5 +210,9 @@ Your insurance has expired. - Number of months: :months ", 'insurance_partially_paid_title' => "Your insurance has been partially paid", - 'insurance_fully_paid_title' => "Your insurance has been paid in full." + 'insurance_fully_paid_title' => "Your insurance has been paid in full.", + 'insurance_payment_reminder' => "Reminder to pay your insurance", + 'insurance_payment_reminder_title' => 'The deadline for paying your bill is approaching', + 'insurance_payment_suspended' => "Insurance suspended", + 'insurance_payment_suspended_title' => 'You have an outstanding payment' ]; diff --git a/resources/lang/fr/messages.php b/resources/lang/fr/messages.php index 662a40e..6c317e5 100755 --- a/resources/lang/fr/messages.php +++ b/resources/lang/fr/messages.php @@ -227,5 +227,9 @@ Votre assurance est arrivée à échéance. - Nombre de mois : :months ", 'insurance_partially_paid_title' => "Votre assurance a été payée partiellement.", - 'insurance_fully_paid_title' => "Votre assurance a été payée complétement." + 'insurance_fully_paid_title' => "Votre assurance a été payée complétement.", + 'insurance_payment_reminder' => "Rappel du paiement de votre assurance", + 'insurance_payment_reminder_title' => 'Le délai du paiement de votre facture est proche', + 'insurance_payment_suspended' => "Assurance suspendue", + 'insurance_payment_suspended_title' => 'Vous avez un paiement non effectué' ]; diff --git a/routes/web.php b/routes/web.php index 15ec556..ee41ada 100644 --- a/routes/web.php +++ b/routes/web.php @@ -40,6 +40,8 @@ $router->group(['prefix' => '', 'middleware' => 'auth'], function () use ($route $router->group(['prefix' => '/invoices'], function () use ($router) { $router->get('', 'InsuranceInvoiceController@getInvoices'); $router->put('{id}/pay', 'InsuranceInvoiceController@payInvoice'); + $router->get('generate', 'InsuranceInvoiceController@generateInvoices'); + $router->get('reminder', 'InsuranceInvoiceController@generateReminder'); }); });