298 lines
12 KiB
PHP
298 lines
12 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\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 InsuranceInvoiceController extends Controller
|
|
{
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/insurances/invoices",
|
|
* summary="Afficher la liste des factures",
|
|
* tags={"Factures de 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="state",
|
|
* name="state",
|
|
* description="Etat de la facture",
|
|
* in="query",
|
|
* required=false,
|
|
* @OA\Schema(
|
|
* type="string",
|
|
* enum={"PAID","UNPAID","TO_PAID"}
|
|
* )
|
|
* ),
|
|
* @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,"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",
|
|
* "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"},
|
|
* "subscription":{"id":2,"insurance_subscription_id":"CX36UNA2VVOP","network_id":250,"user_id":349,"months_grid_id":77,"bonus_amount":"150000.00","number_of_beneficiaries":2,"
|
|
* total_bonus_amount":"495000.00","state":"ACCEPTED","insurance_action":"ACTIVATION","created_at":"2021-11-10T16:52:32.000000Z","updated_at":"2022-03-29T17:31:52.000000Z","reason":null}}},
|
|
* "error":null
|
|
* }
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function getInvoices(Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'user_id' => 'required|integer|exists:users,id',
|
|
'state' => 'nullable|in:PAID,UNPAID,TO_PAID',
|
|
'pagination' => 'nullable|boolean'
|
|
]);
|
|
$user_id = $request->input('user_id');
|
|
$user = User::findOrFail($user_id);
|
|
$currency_code = $user->network->country->currency_code;
|
|
$pagination = $request->input('pagination');
|
|
$state = $request->input('state');
|
|
$datetime = $this->getCurrentTimeByCountryCode($user->network->country->code_country);
|
|
|
|
$query = NhInsurancesInvoice::with(['insurance', 'subscription'])
|
|
->whereHas('insurance', function ($q) use ($user_id) {
|
|
return $q->where('user_id', $user_id);
|
|
});
|
|
|
|
if (!empty($state)) {
|
|
if ($state == 'TO_PAID') {
|
|
$query = $query->where('state', InsuranceInvoiceState::UNPAID)
|
|
->where('payment_deadline', '<', $datetime);
|
|
} else {
|
|
$query = $query->where('state', $state);
|
|
}
|
|
}
|
|
|
|
if ($pagination) {
|
|
$invoices = $query->paginate($request->input('perPage', 10));
|
|
} else {
|
|
$invoices = $query->get();
|
|
}
|
|
|
|
$array = $pagination ? $invoices->items() : $invoices;
|
|
foreach ($array as $invoice) {
|
|
$invoice->state = trans('states.' . $invoice->state);
|
|
$invoice->reason = trans('states.' . $invoice->reason);
|
|
$invoice->amount = $this->toMoneyWithCurrencyCode($invoice->amount, $currency_code);
|
|
}
|
|
return $this->successResponse($invoices);
|
|
}
|
|
|
|
/**
|
|
* @OA\Put(
|
|
* path="/insurances/invoices/{id}/pay",
|
|
* summary="Payer la facture de l'assurance",
|
|
* tags={"Factures de l'assurance"},
|
|
* security={{"api_key":{}}},
|
|
* @OA\Parameter(
|
|
* parameter="id",
|
|
* name="id",
|
|
* description="ID de la facture",
|
|
* 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 payInvoice($id, Request $request)
|
|
{
|
|
$this->validate($request, [
|
|
'password' => 'required|string',
|
|
]);
|
|
|
|
$invoice = NhInsurancesInvoice::findOrFail($id);
|
|
$datetime = $this->getCurrentTimeByCountryCode($invoice->insurance->network->country->code_country);
|
|
|
|
if ($invoice->state == InsuranceInvoiceState::PAID) {
|
|
return $this->errorResponse(trans('errors.invoice_already_paid'));
|
|
}
|
|
|
|
if ($invoice->payment_deadline < $datetime) {
|
|
return $this->errorResponse(trans('errors.payment_deadline_reached'));
|
|
}
|
|
|
|
$user = $invoice->insurance->user;
|
|
$this->userCredentialsVerification($user, $request->input('password'));
|
|
|
|
$currency = $this->getNetworkCurrency($invoice->insurance->network_id);
|
|
|
|
$amountToPaid = $invoice->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();
|
|
|
|
$hyperviseur = AgentPlus::where('category', 'hyper')->where('network_id', $invoice->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();
|
|
|
|
$invoice->update(['state' => InsuranceInvoiceState::PAID, 'updated_at' => $datetime]);
|
|
$invoice->insurance->paid_deadlines++;
|
|
$isPartialPayment = true;
|
|
if ($invoice->insurance->paid_deadlines == $invoice->insurance->deadlines) {
|
|
$invoice->insurance->state = InsuranceState::PAID;
|
|
$isPartialPayment = false;
|
|
}
|
|
|
|
if ($invoice->insurance->state == InsuranceState::PAID) {
|
|
|
|
if ($invoice->reason == InsuranceAction::ADDITION_OF_BENEFICIARY) {
|
|
$invoice->insurance->bonus_amount = $invoice->subscription->bonus_amount;
|
|
$invoice->insurance->total_bonus_amount += $invoice->subscription->total_bonus_amount;
|
|
$invoice->insurance->number_of_beneficiaries += $invoice->subscription->number_of_beneficiaries;
|
|
$invoice->insurance->updated_at = $datetime;
|
|
$invoice->insurance->save();
|
|
|
|
foreach ($invoice->subscription->beneficiaries as $b) {
|
|
NhInsurancesHavingRight::create([
|
|
'insurance_id' => $invoice->insurance->id,
|
|
'having_right_id' => $b->id
|
|
]);
|
|
}
|
|
}
|
|
|
|
if (in_array($invoice->reason, [InsuranceAction::ACTIVATION, InsuranceAction::RENEWAL])) {
|
|
if (empty($invoice->insurance->monthsGrid->waiting_period_days)) {
|
|
$start_at = $datetime;
|
|
} else {
|
|
$start_at = $this->addDaysToDateTime($datetime, $invoice->insurance->monthsGrid->waiting_period_days);
|
|
}
|
|
$end_at = $this->addMonthsToDateTime($start_at->format('Y-m-d H:i:s'), $invoice->insurance->monthsGrid->number_of_months);
|
|
$invoice->insurance->start_at = $start_at;
|
|
$invoice->insurance->end_at = $end_at;
|
|
}
|
|
}
|
|
|
|
$invoice->insurance->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,
|
|
'reason' => trans('states.' . $invoice->reason), 'title' => $isPartialPayment ? trans('messages.insurance_partially_paid_title') : trans('messages.insurance_fully_paid_title')])));
|
|
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);
|
|
}
|
|
}
|
|
}
|