2022-03-29 19:20:43 +00:00
< ? 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 - 10 T16 : 52 : 32.000000 Z " , " updated_at " : " 2022 - 03 - 29 T17 : 31 : 52.000000 Z " , " 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 )
2022-03-31 11:57:44 +00:00
-> where ( 'payment_deadline' , '>=' , $datetime );
2022-03-29 19:20:43 +00:00
} 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 ++ ;
if ( $invoice -> insurance -> paid_deadlines == $invoice -> insurance -> deadlines ) {
$invoice -> insurance -> state = InsuranceState :: PAID ;
$isPartialPayment = false ;
2022-03-31 11:57:44 +00:00
} else {
$invoice -> insurance -> state = InsuranceState :: PARTIALLY_PAID ;
$isPartialPayment = true ;
2022-03-29 19:20:43 +00:00
}
2022-03-31 11:57:44 +00:00
// Si c'est le 1er paiement
if ( $invoice -> insurance -> paid_deadlines == 1 ) {
2022-03-29 19:20:43 +00:00
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 {
2022-03-31 11:57:44 +00:00
$start_at = $this -> addDaysToDateTime ( $datetime , $invoice -> insurance -> monthsGrid -> waiting_period_days ) -> format ( 'Y-m-d H:i:s' );
2022-03-29 19:20:43 +00:00
}
2022-03-31 11:57:44 +00:00
$end_at = $this -> addMonthsToDateTime ( $start_at , $invoice -> insurance -> monthsGrid -> number_of_months );
2022-03-29 19:20:43 +00:00
$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 ,
2022-03-31 11:57:44 +00:00
'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
])));
2022-03-29 19:20:43 +00:00
DB :: commit ();
2022-03-31 11:57:44 +00:00
return $this -> successResponse ( trans ( 'messages.insurance_invoice_paid' ));
2022-03-29 19:20:43 +00:00
} catch ( Throwable $e ) {
Log :: error ( $e -> getMessage () . '\n' . $e -> getTraceAsString ());
DB :: rollBack ();
return $this -> errorResponse ( trans ( 'errors.unexpected_error' ), 500 );
}
}
2022-03-30 10:32:40 +00:00
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 " );
}
}
2022-03-29 19:20:43 +00:00
}