2022-11-25 22:53:53 +00:00
< ? php
namespace App\Http\Controllers ;
use App\Enums\CreditCardType ;
use App\Enums\DocumentType ;
use App\Enums\Frequency ;
use App\Enums\MaritalStatus ;
use App\Enums\ResidentialStatus ;
use App\Events\CustomerAccountRequestEvent ;
use App\Exceptions\AppException ;
2022-12-19 16:01:23 +00:00
use App\Models\AgentPlus ;
2022-11-25 22:53:53 +00:00
use App\Models\CustomerAccountRequest ;
use App\Models\CustomerAccountRequestDocument ;
use App\Models\CustomerAccountType ;
use App\Models\Identification ;
2022-12-19 16:01:23 +00:00
use App\Models\InfosCustomerAccountOpeningRequest ;
use App\Models\PaymentAggregator ;
use App\Models\PaymentTransaction ;
use App\Models\User ;
use App\Models\Wallet ;
use App\Models\WalletsUser ;
use GuzzleHttp\Client ;
2022-11-25 22:53:53 +00:00
use Illuminate\Http\Request ;
2022-12-19 16:01:23 +00:00
use Illuminate\Http\Response ;
2022-11-25 22:53:53 +00:00
use Illuminate\Support\Carbon ;
use Illuminate\Support\Facades\DB ;
use Illuminate\Support\Facades\Event ;
use Illuminate\Support\Facades\Log ;
use Illuminate\Support\Str ;
2022-12-19 16:01:23 +00:00
use OpenApi\Annotations as OA ;
2022-11-25 22:53:53 +00:00
use Throwable ;
class CustomerAccountOpeningController extends Controller
{
//
/**
* @ OA\Post (
* path = " /customers_accounts_requests " ,
* summary = " Soumettre le formulaire d'ouverture de comptele " ,
* tags = { " Agency Banking " },
* security = {{ " api_key " : {}}},
* @ OA\RequestBody (
* description = " Corps de la requete " ,
* required = true ,
* @ OA\MediaType (
* mediaType = " multipart/form-data " ,
* @ OA\Schema (
* @ OA\Property ( property = " user_id " ,
* type = " integer " ,
* example = 308 ,
* description = " ID de l'utilisateur enregistré dans la base de données "
* ),
* @ OA\Property ( property = " network_id " ,
* type = " integer " ,
* example = 4 ,
* description = " ID du réseau auquel appartient il souhaitre faire sa demande "
* ),
* @ OA\Property ( property = " customer_account_type_id " ,
* type = " integer " ,
* example = 101 ,
* description = " ID du type de compte "
* ),
* @ OA\Property ( property = " title " ,
* type = " string " ,
* example = " Mr " ,
* description = " Title "
* ),
* @ OA\Property ( property = " lastname " ,
* type = " string " ,
* example = " John " ,
* description = " Noms "
* ),
* @ OA\Property ( property = " firstname " ,
* type = " string " ,
* example = " Doe " ,
* description = " Prenoms "
* ),
* @ OA\Property ( property = " spouse_name " ,
* type = " string " ,
* example = " Bill " ,
* description = " Nom Marital "
* ),
* @ OA\Property ( property = " nationality " ,
* type = " string " ,
* example = " Camerounaise " ,
* description = " Nationalité "
* ),
* @ OA\Property ( property = " birth_date " ,
* type = " date " ,
* example = " 1990-06-15 " ,
* description = " Date de naissance "
* ),
* @ OA\Property ( property = " birth_city " ,
* type = " string " ,
* example = " Douala " ,
* description = " Ville de naissance "
* ),
* @ OA\Property ( property = " birth_country " ,
* type = " string " ,
* example = " Cameroun " ,
* description = " Pays de naissance "
* ),
* @ OA\Property ( property = " birth_locality " ,
* type = " string " ,
* example = " Akwa " ,
* description = " Lieu exact de naissance "
* ),
* @ OA\Property ( property = " father_lastname " ,
* type = " string " ,
* example = " Doe " ,
* description = " Nom du père "
* ),
* @ OA\Property ( property = " father_firstname " ,
* type = " string " ,
* example = " Doe " ,
* description = " Prénom du père "
* ),
* @ OA\Property ( property = " mother_birth_lastname " ,
* type = " string " ,
* example = " Elize " ,
* description = " Nom de naissance de la mère "
* ),
* @ OA\Property ( property = " mother_firstname " ,
* type = " string " ,
* example = " marie " ,
* description = " Prénom de la mère "
* ),
* @ OA\Property ( property = " marital_status " ,
* type = " string " ,
* example = " SINGLE " ,
* description = " Situation matrimoniale "
* ),
* @ OA\Property ( property = " spouse_lastname " ,
* type = " string " ,
* example = " " ,
* description = " Nom du conjoint "
* ),
* @ OA\Property ( property = " spouse_firstname " ,
* type = " string " ,
* example = " " ,
* description = " Prénom du conjoint "
* ),
* @ OA\Property ( property = " profession " ,
* type = " string " ,
* example = " Student " ,
* description = " Profession "
* ),
* @ OA\Property ( property = " business_activity " ,
* type = " string " ,
* example = " " ,
* description = " Secteur d'activité économique "
* ),
* @ OA\Property ( property = " sub_sector_business_activity " ,
* type = " string " ,
* example = " " ,
* description = " Sous secteur d'activité "
* ),
* @ OA\Property ( property = " tax_number " ,
* type = " string " ,
* example = " " ,
* description = " Numéro Fiscal "
* ),
* @ OA\Property ( property = " security_number " ,
* type = " string " ,
* example = " " ,
* description = " Numéro de sécurité sociale "
* ),
* @ OA\Property ( property = " employee_number " ,
* type = " string " ,
* example = " " ,
* description = " Numéro de l'employeur "
* ),
* @ OA\Property ( property = " function " ,
* type = " string " ,
* example = " " ,
* description = " Fonction "
* ),
* @ OA\Property ( property = " employee_name " ,
* type = " string " ,
* example = " " ,
* description = " Nom de l'employeur "
* ),
* @ OA\Property ( property = " employee_address " ,
* type = " string " ,
* example = " " ,
* description = " Addresse de l'employeur "
* ),
* @ OA\Property ( property = " residential_status " ,
* type = " string " ,
* example = " RESIDENT " ,
* description = " Status de résident "
* ),
* @ OA\Property ( property = " residential_country " ,
* type = " string " ,
* example = " Cameroun " ,
* description = " Pays de résidence "
* ),
* @ OA\Property ( property = " residence_permit_number " ,
* type = " string " ,
* example = " " ,
* description = " Numéro de permis de séjour "
* ),
* @ OA\Property ( property = " residence_permit_issued_date " ,
* type = " date " ,
* example = " " ,
* description = " Date de délivrance du permis "
* ),
* @ OA\Property ( property = " residence_permit_expiry_date " ,
* type = " date " ,
* example = " " ,
* description = " Date d'expiration du permis "
* ),
* @ OA\Property ( property = " address_justification_doc " ,
* type = " string " ,
* example = " LOCALISATION_PLAN " ,
* description = " Justificatif d'adresse "
* ),
* @ OA\Property ( property = " address " ,
* type = " string " ,
* example = " Douala " ,
* description = " Adresse géographique "
* ),
* @ OA\Property ( property = " po_box " ,
* type = " string " ,
* example = " " ,
* description = " Adresse postale "
* ),
* @ OA\Property ( property = " phone_number " ,
* type = " string " ,
* example = " +237690716639 " ,
* description = " Numéro de téléphone "
* ),
* @ OA\Property ( property = " email_1 " ,
* type = " string " ,
* example = " ddietchi@ilink-app.com " ,
* description = " Email 1 "
* ),
* @ OA\Property ( property = " email_2 " ,
* type = " string " ,
* example = " " ,
* description = " Email 2 "
* ),
* @ OA\Property ( property = " person_to_contact_in_case_of_needs_name " ,
* type = " string " ,
* example = " Romeo Doe " ,
* description = " Personne à contacter en cas de besoin "
* ),
* @ OA\Property ( property = " person_to_contact_in_case_of_needs_phone_number " ,
* type = " string " ,
* example = " +237699000102 " ,
* description = " Numéro de téléphone de la personne à contacter en cas de besoin "
* ),
* @ OA\Property ( property = " identification_document_type " ,
* type = " string " ,
* example = " CNI " ,
* description = " Type de pièce "
* ),
* @ OA\Property ( property = " identification_document_number " ,
* type = " string " ,
* example = " 0987654321 " ,
* description = " Numéro d'identification "
* ),
* @ OA\Property ( property = " identification_document_issued_date " ,
* type = " date " ,
* example = " 2019-08-03 " ,
* description = " Date de délivrance du document "
* ),
* @ OA\Property ( property = " identification_document_expiry_date " ,
* type = " date " ,
* example = " 2029-08-03 " ,
* description = " Date d'expiration du document "
* ),
* @ OA\Property ( property = " identification_document_issuance_city " ,
* type = " string " ,
* example = " Douala " ,
* description = " Ville d'émission du document "
* ),
* @ OA\Property ( property = " identification_document_issuance_country " ,
* type = " string " ,
* example = " Cameroun " ,
* description = " Pays d'émission du document "
* ),
* @ OA\Property ( property = " customer_under_guardianship " ,
* type = " boolean " ,
* example = " 1 " ,
* description = " Client sous tutelle ? "
* ),
* @ OA\Property ( property = " guardian_fullname " ,
* type = " string " ,
* example = " " ,
* description = " Nom(s) et Prénom(s) du tuteur "
* ),
* @ OA\Property ( property = " guardian_phone_number " ,
* type = " string " ,
* example = " " ,
* description = " Numéro de téléphone du tuteur "
* ),
* @ OA\Property ( property = " how_did_you_know_company " ,
* type = " string " ,
* example = " " ,
* description = " Comment avez vous connu l'entreprise ? "
* ),
* @ OA\Property ( property = " introducer_fullname " ,
* type = " string " ,
* example = " " ,
* description = " Nom(s) et Prénom(s) de l'introducteur "
* ),
* @ OA\Property ( property = " introducer_address " ,
* type = " string " ,
* example = " " ,
* description = " Adresse de l'introducteur "
* ),
* @ OA\Property ( property = " expected_service " ,
* type = " string " ,
* example = " Services bancaires " ,
* description = " Service attendu "
* ),
* @ OA\Property ( property = " income_sources_and_frequency " ,
* type = " string " ,
* example = " " ,
* description = " Fréquence de revenus et Plafond des transactions "
* ),
* @ OA\Property ( property = " business_partners " ,
* type = " string " ,
* example = " " ,
* description = " Relation d'affaires "
* ),
* @ OA\Property ( property = " bank_references " ,
* type = " string " ,
* example = " " ,
* description = " Référence bancaires "
* ),
* @ OA\Property ( property = " has_account_with_other_bank " ,
* type = " boolean " ,
* example = " 1 " ,
* description = " Avez vous des comptes avec d'autres banques ? "
* ),
* @ OA\Property ( property = " has_operative_other_bank_account " ,
* type = " boolean " ,
* example = " 1 " ,
* description = " Si oui, le compte est-il opérationnel ? "
* ),
* @ OA\Property ( property = " has_engagement_with_other_banks " ,
* type = " boolean " ,
* example = " 0 " ,
* description = " Avez vous des engagements avec d'autres banques ? "
* ),
* @ OA\Property ( property = " is_politically_exposed_person " ,
* type = " boolean " ,
* example = " 0 " ,
* description = " Le demandeur est-il une personne politiquement exposée ? "
* ),
* @ OA\Property ( property = " is_politically_exposed_person_in_service " ,
* type = " boolean " ,
* example = " 0 " ,
* description = " En service ? "
* ),
* @ OA\Property ( property = " has_relationship_with_politically_exposed_person " ,
* type = " boolean " ,
* example = " 0 " ,
* description = " Le demandeur est-il une relation avec des personnes politiquement exposées ? "
* ),
* @ OA\Property ( property = " relationship_with_politically_exposed_person " ,
* type = " string " ,
* example = " " ,
* description = " Si oui, indiquez leurs noms et la nature de la relation "
* ),
* @ OA\Property ( property = " email_alerts " ,
* type = " boolean " ,
* example = " 1 " ,
* description = " Alertes Email "
* ),
* @ OA\Property ( property = " e_statement_frequency " ,
* type = " string " ,
* example = " MONTHLY " ,
* description = " Frequence Relevé bancaire "
* ),
* @ OA\Property ( property = " e_package " ,
* type = " boolean " ,
* example = " 1 " ,
* description = " E Package "
* ),
* @ OA\Property ( property = " debit_card_type " ,
* type = " string " ,
* example = " VISA_CLASSIC " ,
* description = " Type de carte de débit "
* ),
* @ OA\Property ( property = " document1 " ,
* type = " file " ,
* description = " Document 1 "
* ),
* @ OA\Property ( property = " document2 " ,
* type = " file " ,
* description = " Document 2 "
* ),
* )
* )
* ),
* @ OA\Response (
* response = 200 ,
* description = " OK " ,
* @ OA\JsonContent (
* ref = " #/components/schemas/ApiResponse " ,
* example = {
* " status " : 200 ,
* " response " : " Demande d'ouverture de compte client soumise " ,
* " error " : null
* }
* )
* )
* )
* @ throws AppException
*/
public function submit ( Request $request )
{
$this -> validate ( $request ,[
'user_id' => 'required|integer|exists:users,id' ,
'network_id' => 'required|integer|exists:networks,id' ,
'customer_account_type_id' => 'required|integer|exists:customer_account_types,id' ,
'title' => 'required|string' ,
'lastname' => 'required|string' ,
'firstname' => 'nullable|string' ,
'spouse_name' => 'nullable|string' ,
'nationality' => 'required|string' ,
'birth_date' => 'required|date_format:Y-m-d|before:today' ,
'birth_country' => 'required|string' ,
'birth_city' => 'required|string' ,
'birth_locality' => 'nullable|string' ,
'father_lastname' => 'required|string' ,
'father_firstname' => 'nullable|string' ,
'mother_birth_lastname' => 'required|string' ,
'mother_firstname' => 'nullable|string' ,
'marital_status' => 'required|string' ,
'spouse_lastname' => 'nullable|string' ,
'spouse_firstname' => 'nullable|string' ,
'profession' => 'nullable|string' ,
'business_activity' => 'nullable|string' ,
'sub_sector_business_activity' => 'nullable|string' ,
'tax_number' => 'nullable|string' ,
'security_number' => 'nullable|string' ,
'employee_number' => 'nullable|string' ,
'function' => 'nullable|string' ,
'employee_name' => 'nullable|string' ,
'employee_address' => 'nullable|string' ,
'residential_status' => 'required|string' ,
'residential_country' => 'required|string' ,
'residence_permit_number' => 'nullable|string' ,
'residence_permit_issued_date' => 'nullable|date_format:Y-m-d|before:today' ,
'residence_permit_expiry_date' => 'nullable|date_format:Y-m-d|after:residence_permit_issued_date' ,
'address_justification_doc' => 'required|string' ,
'address' => 'required|string' ,
'po_box' => 'nullable|string' ,
'phone_number' => 'required|string' ,
'email_1' => 'required|string' ,
'email_2' => 'nullable|string' ,
'person_to_contact_in_case_of_needs_name' => 'required|string' ,
'person_to_contact_in_case_of_needs_phone_number' => 'required|string' ,
'identification_document_type' => 'required|string' ,
'identification_document_number' => 'required|string' ,
'identification_document_issued_date' => 'required|date_format:Y-m-d|before:today' ,
'identification_document_expiry_date' => 'required|date_format:Y-m-d|after:identification_document_issued_date' ,
'identification_document_issuance_city' => 'required|string' ,
'identification_document_issuance_country' => 'required|string' ,
'customer_under_guardianship' => 'required|bool' ,
'guardian_fullname' => 'nullable|string' ,
'guardian_phone_number' => 'nullable|string' ,
'how_did_you_know_company' => 'required|string' ,
'introducer_fullname' => 'nullable|string' ,
'introducer_address' => 'nullable|string' ,
'expected_service' => 'required|string' ,
'income_sources_and_frequency' => 'nullable|string' ,
'business_partners' => 'nullable|string' ,
'bank_references' => 'nullable|string' ,
'has_account_with_other_bank' => 'required|bool' ,
'has_operative_other_bank_account' => 'required|bool' ,
'has_engagement_with_other_banks' => 'required|bool' ,
'is_politically_exposed_person' => 'required|bool' ,
'is_politically_exposed_person_in_service' => 'required|bool' ,
'has_relationship_with_politically_exposed_person' => 'required|bool' ,
'relationship_with_politically_exposed_person' => 'nullable|string' ,
'email_alerts' => 'required|bool' ,
'e_statement_frequency' => 'required|string' ,
'e_package' => 'nullable|bool' ,
'debit_card_type' => 'required|string' ,
]);
$accountType = CustomerAccountType :: with ( 'documents' ) -> find ( $request -> input ( 'customer_account_type_id' ));
$documents = [];
if ( ! empty ( $accountType -> documents )){
$rules [] = [];
foreach ( $accountType -> documents as $document ){
$rules [ $document -> name ] = 'required|image|mimes:jpeg,png,jpg,jpeg|max:1024' ;
}
$this -> validate ( $request , $rules );
foreach ( $accountType -> documents as $document ){
$doc = [];
$doc [ 'name' ] = $document -> name ;
$doc [ 'description' ] = $document -> description ;
$doc [ 'url' ] = $this -> uploadImage ( $request , $document -> name , 'CRD' , 'requests-docs' );
$documents [] = $doc ;
}
}
if ( CustomerAccountRequest :: where ( 'user_id' , $request -> input ( 'user_id' )) -> where ( 'network_id' , $request -> input ( 'network_id' ))
-> where ( 'status' , CustomerAccountRequest :: UNDER_VALIDATION ) -> exists ()){
return $this -> errorResponse ( __ ( 'messages.customer_account_opening_request_pending' ));
}
try {
DB :: beginTransaction ();
$accountRequest = CustomerAccountRequest :: create ( array_merge ( $request -> all (),[
2022-12-19 16:01:23 +00:00
'opening_amount' => $accountType -> opening_amount ,
2022-11-25 22:53:53 +00:00
'unique_id' => strtoupper ( Str :: random ( 12 ))
]));
$documents = array_map ( function ( $row ) use ( $accountRequest ) {
$row [ 'request_id' ] = $accountRequest -> id ;
$row [ 'created_at' ] = Carbon :: now ();
$row [ 'updated_at' ] = Carbon :: now ();
return $row ;
}, $documents );
CustomerAccountRequestDocument :: insert ( $documents );
DB :: commit ();
} catch ( Throwable $exception ){
Log :: error ( $exception -> getMessage ());
DB :: rollBack ();
return $this -> errorResponse ( trans ( 'errors.unexpected_error' ), 500 );
}
$mailParams = [ 'name' => $accountRequest -> user -> lastname , 'request_id' => $accountRequest -> unique_id , 'gender' => $accountRequest -> title , 'account_type' => $accountRequest -> account_type -> name ,
'opening_amount' => $this -> toMoneyWithNetwork ( $accountRequest -> account_type -> opening_amount , $accountRequest -> network_id )
];
Event :: dispatch ( new CustomerAccountRequestEvent ( $accountRequest , __ ( 'messages.customer_account_opening_request' ), __ ( 'messages.customer_account_opening_request_mail' , $mailParams )));
return $this -> successResponse ( __ ( 'messages.customer_account_opening_request_submitted' ));
}
2022-12-19 16:01:23 +00:00
/**
* @ OA\Get (
* path = " /customers_accounts_requests " ,
* summary = " Recuperer les demandes d'ouvertures " ,
* tags = { " Agency Banking " },
* security = {{ " api_key " : {}}},
* @ OA\Parameter (
* parameter = " user_id " ,
* name = " user_id " ,
* description = " ID de l'utilisateur " ,
* @ OA\Schema (
* type = " integer "
* ),
* in = " query " ,
* required = false
* ),
* @ OA\Parameter (
* parameter = " network_id " ,
* name = " network_id " ,
* description = " ID du reseau " ,
* @ OA\Schema (
* type = " integer " ,
* ),
* in = " query " ,
* required = false
* ),
* @ OA\Response (
* response = 200 ,
* description = " OK " ,
* @ OA\JsonContent (
* ref = " #/components/schemas/ApiResponse " ,
* example = {
* " status " : 200 ,
* " response " : {{ " id " : 19 , " unique_id " : " X4UK8JDG1Z0I " , " user_id " : 382 , " network_id " : 239 , " customer_account_type_id " : 4 , " opening_amount " : " 80 000 FCFA " ,
* " opening_amount_payment_deadline " : " 2022-12-13 " , " status " : " EN COURS DE VALIDATION " , " reject_reason " : null , " created_at " : " 2022-11-28T18:06:09.000000Z " , " account_type " : { " id " : 4 , " name " : " Compte courant regulier salarie " }}},
* " error " : null
* }
* )
* )
* )
*/
public function getRequests ( Request $request )
{
$this -> validate ( $request ,[
'user_id' => 'nullable|integer|exists:users,id' ,
'network_id' => 'nullable|integer|exists:networks,id'
]);
$user_id = $request -> input ( 'user_id' );
$network_id = $request -> input ( 'network_id' );
$query = CustomerAccountRequest :: with ([ 'account_type:id,name' ]);
$query -> when ( $user_id , function ( $q , $user_id ){
$q -> where ( 'user_id' , $user_id );
});
$query -> when ( $network_id , function ( $q , $network_id ){
$q -> where ( 'network_id' , $network_id );
});
$data = $query -> select ([ 'id' , 'unique_id' , 'user_id' , 'network_id' , 'customer_account_type_id' , 'opening_amount' , 'opening_amount_payment_deadline' , 'status' , 'reject_reason' , 'created_at' ])
-> get ();
$data -> map ( function ( $row ){
$this -> formatCustomerRequest ( $row );
});
return $this -> successResponse ( $data );
}
/**
* @ OA\Get (
* path = " /customers_accounts_requests/ { id} " ,
* summary = " Recuperer les details sur une demande d'ouverture " ,
* tags = { " Agency Banking " },
* security = {{ " api_key " : {}}},
* @ OA\Parameter (
* parameter = " id " ,
* name = " id " ,
* description = " ID de la demande " ,
* @ OA\Schema (
* type = " integer "
* ),
* in = " path " ,
* required = true
* ),
* @ OA\Response (
* response = 200 ,
* description = " OK " ,
* @ OA\JsonContent (
* ref = " #/components/schemas/ApiResponse " ,
* example = {
* " status " : 200 ,
* " response " : { " id " : 19 , " unique_id " : " X4UK8JDG1Z0I " , " user_id " : 382 , " network_id " : 239 , " customer_account_type_id " : 4 , " title " : " M " , " lastname " : " Doe " , " firstname " : " John " , " spouse_name " : null , " nationality " : " Cameroun " , " birth_date " : " 1988-03-01 " , " birth_country " : " Cameroun " ,
* " birth_city " : " Douala " , " birth_locality " : null , " father_lastname " : " Gates " , " father_firstname " : " " , " mother_birth_lastname " : " Marthe " , " mother_firstname " : null , " marital_status " : " SINGLE " , " spouse_lastname " : null , " spouse_firstname " : null , " profession " : null , " business_activity " : null ,
* " sub_sector_business_activity " : null , " tax_number " : null , " security_number " : null , " employee_number " : null , " function " : null , " employee_name " : null , " employee_address " : null , " residential_status " : " RESIDENT " , " residential_country " : " Cameroun " , " residence_permit_number " : null ,
* " residence_permit_issued_date " : null , " residence_permit_expiry_date " : null , " address_justification_doc " : " LOCALISATION_PLAN " , " address " : " Douala " , " po_box " : null , " phone_number " : " +237690716639 " , " email_1 " : " ddietchi@ilink-app.com " , " email_2 " : null , " person_to_contact_in_case_of_needs_name " : " Mark " ,
* " person_to_contact_in_case_of_needs_phone_number " : " +237690716630 " , " identification_document_type " : " CNI " , " identification_document_number " : " 1232266 " , " identification_document_issued_date " : " 2019-03-10 " , " identification_document_expiry_date " : " 2039-03-10 " , " identification_document_issuance_city " : " Douala " ,
* " identification_document_issuance_country " : " Cameroun " , " customer_under_guardianship " : 0 , " guardian_fullname " : null , " guardian_fullname_phone_number " : null , " how_did_you_know_company " : " medias " , " introducer_fullname " : null , " introducer_address " : null , " expected_service " : " banking " , " income_sources_and_frequency " : null ,
* " business_partners " : null , " bank_references " : null , " has_account_with_other_bank " : 0 , " has_operative_other_bank_account " : 0 , " has_engagement_with_other_banks " : 1 , " is_politically_exposed_person " : 0 , " is_politically_exposed_person_in_service " : 0 , " has_relationship_with_politically_exposed_person " : 0 ,
* " relationship_with_politically_exposed_person " : null , " email_alerts " : 1 , " e_statement_frequency " : " DAILY " , " e_package " : 0 , " debit_card_type " : " CLASSIC_GOLD " , " opening_amount " : " 80 000 FCFA " , " opening_amount_payment_deadline " : " 2022-12-13 " , " status " : " EN COURS DE VALIDATION " , " reject_reason " : null ,
* " validating_agent_id " : null , " created_at " : " 2022-11-28T18:06:09.000000Z " , " updated_at " : " 2022-11-28T18:06:09.000000Z " , " deleted_at " : null , " account_type " : { " id " : 4 , " name " : " Compte courant regulier salarie " }, " documents " : { { " request_id " : 19 , " name " : " photo " , " description " : " photo " ,
* " url " : " http://127.0.0.1:8088/requests-docs/CRD-23ccdda9-d234-4c18-a8b8-d637295b89c3.png " } } },
* " error " : null
* }
* )
* )
* )
*/
public function getSingleRequest ( $id )
2022-11-25 22:53:53 +00:00
{
2022-12-19 16:01:23 +00:00
$accountRequest = CustomerAccountRequest :: with ([ 'account_type:id,name' , 'documents:request_id,name,description,url' ]) -> where ( 'id' , $id ) -> firstOrFail ();
$this -> formatCustomerRequest ( $accountRequest );
2022-11-25 22:53:53 +00:00
2022-12-19 16:01:23 +00:00
return $this -> successResponse ( $accountRequest );
2022-11-25 22:53:53 +00:00
}
public function treatRequest ( $id , Request $request )
{
$this -> validate ( $request , [
'nh_validating_agent_id' => 'required_without:agent_id|nullable|integer|exists:nh_validating_agents,id' ,
'agent_id' => 'required_without:nh_validating_agent_id|nullable|integer|exists:agents,id' ,
'type' => 'required|in:ACCEPT,REJECT,MORE_INFORMATION' ,
'reason' => 'nullable|string'
]);
$accountRequest = CustomerAccountRequest :: findOrFail ( $id );
if ( ! in_array ( $accountRequest -> status ,[ CustomerAccountRequest :: UNDER_VALIDATION , CustomerAccountRequest :: AWAITING_FURTHER_INFORMATION ])){
return $this -> errorResponse ( __ ( 'errors.request_already_processed' ));
}
try {
DB :: beginTransaction ();
$datetime = $this -> getCurrentTimeByCountryCode ( $accountRequest -> user -> network -> country -> code_country );
$type = $request -> input ( 'type' );
$mailParams = [ 'name' => $accountRequest -> user -> lastname , 'request_id' => $accountRequest -> unique_id , 'reason' => $request -> input ( 'reason' ),
'gender' => $accountRequest -> title , 'account_type' => $accountRequest -> account_type -> name ,
];
$notificationParams = [ 'request_id' => $accountRequest -> unique_id ];
switch ( $type ){
case 'REJECT' :
$accountRequest -> status = CustomerAccountRequest :: REJECTED ;
$mailTitle = trans ( 'messages.customer_account_opening_request_rejected' );
$mailMessage = trans ( 'messages.customer_account_opening_request_rejected_mail' , $mailParams );
$notification = trans ( 'messages.customer_account_opening_request_rejected_notification' , $notificationParams );
break ;
case 'ACCEPT' :
2022-12-19 16:01:23 +00:00
if ( ! empty ( $accountRequest -> opening_amount )){
$mailParams [ 'opening_amount' ] = $this -> toMoneyWithNetwork ( $accountRequest -> opening_amount , $accountRequest -> network_id );
$accountRequest -> status = CustomerAccountRequest :: ACCEPTED_UNPAID ;
$accountRequest -> opening_amount_payment_deadline = Carbon :: now () -> addDays ( $accountRequest -> account_type -> opening_amount_payment_period_days );
$mailParams [ 'deadline' ] = $accountRequest -> opening_amount_payment_deadline ;
$mailMessage = trans ( 'messages.customer_account_opening_request_accepted_unpaid_mail' , $mailParams );
} else {
$accountRequest -> status = CustomerAccountRequest :: ACCEPTED ;
$mailMessage = trans ( 'messages.customer_account_opening_request_accepted_mail' , $mailParams );
}
2022-11-25 22:53:53 +00:00
$mailTitle = trans ( 'messages.customer_account_opening_request_accepted' );
$notification = trans ( 'messages.customer_account_opening_request_accepted_notification' , $notificationParams );
break ;
default :
$accountRequest -> status = CustomerAccountRequest :: AWAITING_FURTHER_INFORMATION ;
$mailTitle = trans ( 'messages.customer_account_opening_request_awaiting_more_information' );
$mailMessage = trans ( 'messages.customer_account_opening_request_awaiting_more_information_mail' , $mailParams );
$notification = trans ( 'messages.customer_account_opening_request_awaiting_more_information_notification' , $notificationParams );
}
$accountRequest -> validating_agent_id = $request -> input ( 'nh_validating_agent_id' ) ? ? $request -> input ( 'agent_id' );
$accountRequest -> reject_reason = $request -> input ( 'reason' );
$accountRequest -> updated_at = $datetime ;
$accountRequest -> save ();
Event :: dispatch ( new CustomerAccountRequestEvent ( $accountRequest , $mailTitle , $mailMessage , $notification ));
DB :: commit ();
return $this -> successResponse ( trans ( 'messages.successful_transaction' ));
} catch ( Throwable $e ) {
Log :: error ( $e -> getMessage () . '\n' . $e -> getTraceAsString ());
DB :: rollBack ();
return $this -> errorResponse ( trans ( 'errors.unexpected_error' ), 500 );
}
}
/**
* @ OA\Get (
* path = " /customers_accounts_requests/formData " ,
* summary = " Recuperer les informations necessaires avant la soumission du formulaire " ,
* tags = { " Agency Banking " },
* security = {{ " api_key " : {}}},
* @ OA\Parameter (
* parameter = " user_id " ,
* name = " user_id " ,
* description = " ID de l'utilisateur " ,
* @ OA\Schema (
* type = " integer "
* ),
* in = " query " ,
* required = true
* ),
* @ OA\Parameter (
* parameter = " network_id " ,
* name = " network_id " ,
* description = " ID du reseau " ,
* @ OA\Schema (
* type = " integer " ,
* ),
* in = " query " ,
* required = true
* ),
* @ OA\Response (
* response = 200 ,
* description = " OK " ,
* @ OA\JsonContent (
* ref = " #/components/schemas/ApiResponse " ,
* example = {
* " status " : 200 ,
* " response " : { " identification " : { " id " : 15 , " firstname " : " " , " lastname " : " John doe " , " birth_date " : " 2020-07-28T00:00:00.000000Z " , " gender " : " M " , " town " : " Libreville " , " country " : " Gabon " , " identity_document " : " Carte d'identité " ,
* " id_identity_document " : " 1234567890 " , " expiry_date_document " : " 2020-07-28T00:00:00.000000Z " , " id_user " : 321 , " status " : 1 , " createdAt " : " 2020-07-28T17:01:26.000000Z " , " user_image " : null , " document_image_front " : null , " document_image_back " : null ,
* " idNetwork " : 239 , " country_id " : null }, " customer_account_types " : {{ " id " : 1 , " name " : " Compte courant " , " description " : null , " children " : {{ " id " : 4 , " name " : " Compte courant regulier salarie " , " description " : " Compte courant regulier " , " parent_id " : 1 ,
* " documents " : { { " name " : " photo " , " description " : " photo " , " account_type_id " : 4 } } } } } }, " marital_status " : { { " title " : " Single " , " value " : " SINGLE " } }, " residential_status " : { { " title " : " Résident " , " value " : " RESIDENT " } },
* " address_justification_docs " : { { " title " : " Plan de localisation " , " value " : " LOCALISATION_PLAN " } }, " e_statement_frequencies " : { { " title " : " Daily " , " value " : " DAILY " } }, " debit_card_types " : { { " title " : " MASTER Card Classic " ,
* " value " : " MASTER_CARD_CLASSIC " } }},
* " error " : null
* }
* )
* )
* )
*/
// Fetch mandatory form data before submit request
public function getFormData ( Request $request )
{
$this -> validate ( $request ,[
'user_id' => 'required|integer|exists:users,id' ,
'network_id' => 'required|integer|exists:networks,id' ,
]);
if ( CustomerAccountRequest :: where ( 'user_id' , $request -> input ( 'user_id' )) -> where ( 'network_id' , $request -> input ( 'network_id' ))
-> where ( 'status' , CustomerAccountRequest :: UNDER_VALIDATION ) -> exists ()){
return $this -> errorResponse ( __ ( 'messages.customer_account_opening_request_pending' ));
}
$data [ 'identification' ] = Identification :: where ( 'id_user' , $request -> input ( 'user_id' )) -> first ();
$data [ 'customer_account_types' ] = CustomerAccountType :: has ( 'children' ) -> with ([ 'children:id,name,description,parent_id' , 'children.documents:name,description,account_type_id' ])
-> where ( 'network_id' , $request -> input ( 'network_id' )) -> select ([ 'id' , 'name' , 'description' ]) -> get ();
foreach ( MaritalStatus :: all () as $key => $value ){
$data [ 'marital_status' ][] = [
'title' => $value ,
'value' => $key
];
}
foreach ( ResidentialStatus :: all () as $key => $value ){
$data [ 'residential_status' ][] = [
'title' => $value ,
'value' => $key
];
}
foreach ( DocumentType :: all () as $key => $value ){
$data [ 'address_justification_docs' ][] = [
'title' => $value ,
'value' => $key
];
}
foreach ( Frequency :: all () as $key => $value ){
$data [ 'e_statement_frequencies' ][] = [
'title' => $value ,
'value' => $key
];
}
foreach ( CreditCardType :: all () as $key => $value ){
$data [ 'debit_card_types' ][] = [
'title' => $value ,
'value' => $key
];
}
return $this -> successResponse ( $data );
}
2022-12-19 16:01:23 +00:00
/**
* @ OA\Post (
* path = " /customers_accounts_requests/pay " ,
* summary = " Payer le montant requis pour la demande d'ouverture du compte " ,
* tags = { " Agency Banking " },
* security = {{ " api_key " : {}}},
* @ OA\RequestBody (
* description = " Corps de la requete " ,
* required = true ,
* @ OA\MediaType (
* mediaType = " application/json " ,
* @ OA\Schema (
* @ OA\Property ( property = " user_id " ,
* type = " integer " ,
* example = 10 ,
* description = " ID de l'utilisateur "
* ),
* @ OA\Property ( property = " password " ,
* type = " string " ,
* example = " 1234 " ,
* description = " Mot de passe de l'utilisateur "
* ),
* @ OA\Property ( property = " request_id " ,
* type = " integer " ,
* example = 39 ,
* description = " ID de la demande d'ouverture de compte "
* ),
* @ OA\Property ( property = " payment_method " ,
* type = " string " ,
* enum = { " wallet " , " mobile_money " , " card " },
* example = " wallet " ,
* description = " Methode de paiement "
* ),
* @ OA\Property ( property = " payment_phone " ,
* type = " string " ,
* example = " +237690716639 " ,
* description = " Numero de telephone avec lequel on souhaite payer de paiement "
* ),
* @ OA\Property ( property = " payment_transaction_id " ,
* type = " string " ,
* example = " ASMFOSDFFDODF " ,
* description = " ID de la transaction de paiement "
* ),
* @ OA\Property ( property = " payment_token " ,
* type = " string " ,
* example = " ASMFOSDFFDODF " ,
* description = " Token la transaction de paiement "
* )
* )
* )
* ),
* @ OA\Response (
* response = 200 ,
* description = " OK " ,
* @ OA\JsonContent (
* ref = " #/components/schemas/ApiResponse " ,
* example = {
* " status " : 200 ,
* " response " : " Transaction réussie " ,
* " error " : null
* }
* )
* )
* )
*/
public function payOpeningAmount ( Request $request )
{
$this -> validate ( $request , [
'request_id' => 'required|integer|exists:customer_account_opening_requests,id' ,
'user_id' => 'required|integer|exists:users,id' ,
'password' => 'required' ,
'payment_method' => 'required|string' , //wallet,MTN-Money,Orange-Money
'payment_phone' => 'required_unless:payment_method,wallet,cash|string' ,
'payment_transaction_id' => 'nullable|exists:payment_transactions,transaction_id' , // A envoyer apres avoir effectuer le paiement
'payment_token' => 'required_with:payment_transaction_id|string' , // A envoyer apres avoir effectuer le paiement,
'otp' => 'nullable|string'
]);
$payment_method = $request -> input ( 'payment_method' );
$transaction_id = $request -> input ( 'payment_transaction_id' );
$accountRequest = InfosCustomerAccountOpeningRequest :: findOrFail ( $request -> input ( 'request_id' ));
if ( $accountRequest -> status != CustomerAccountRequest :: ACCEPTED_UNPAID ){
return $this -> errorResponse ( __ ( 'errors.request_already_processed' ));
}
$user = User :: findOrFail ( $request -> input ( 'user_id' ));
if ( ! $this -> checkPassword ( $request -> input ( 'password' ), $user -> encrypted_password , $user -> salt ))
return $this -> errorResponse ( trans ( 'messages.incorrect_user_password' ));
$county = $user -> network -> country ;
$amountToPaid = $accountRequest -> opening_amount ;
if ( empty ( $transaction_id )) {
switch ( $payment_method ) {
case 'wallet' :
$walletUser = WalletsUser :: where ( 'idUser' , $user -> id ) -> firstOrFail ();
if ( $walletUser -> balance < $amountToPaid ) {
return $this -> errorResponse ( trans ( 'errors.insufficient_balance' , [ 'amount' => $this -> toMoneyWithCurrencyCode ( $amountToPaid , $accountRequest -> currency_code )]));
}
break ;
default :
$aggregator = PaymentAggregator :: where ( 'status' , 1 ) -> first ();
if ( ! $aggregator ) {
return $this -> errorResponse ( trans ( 'errors.payment_not_available' ));
}
}
} else {
$transaction = PaymentTransaction :: where ( 'transaction_id' , $transaction_id ) -> where ( 'payment_token' , $request -> input ( 'payment_token' )) -> where ( 'state' , 'ACCEPTED' ) -> first ();
if ( ! $transaction ) {
return $this -> errorResponse ( trans ( 'errors.payment_not_found' ), 404 );
}
$accountRequest = InfosCustomerAccountOpeningRequest :: where ( 'payment_transaction_id' , $transaction_id ) -> first ();
if ( $accountRequest ) {
return $this -> errorResponse ( trans ( 'errors.payment_invalid' ), 400 );
}
}
$hyperviseur = AgentPlus :: where ( 'category' , 'hyper' ) -> where ( 'network_id' , $accountRequest -> network_id ) -> firstOrFail ();
$walletHyperviseur = Wallet :: where ( 'id_agent' , $hyperviseur -> id ) -> firstOrFail ();
$datetime = $this -> getCurrentTimeByCountryCode ( $county -> code_country );
try {
DB :: beginTransaction ();
$walletHyperviseur -> balance_princ += $amountToPaid ;
$walletHyperviseur -> save ();
if ( empty ( $transaction_id )) {
if ( $payment_method == 'wallet' ) {
$walletUser -> balance -= $amountToPaid ;
$walletUser -> save ();
} else {
// Pay through payment service
$client = new Client ([
'base_uri' => config ( 'variables.payment_service_url' ),
'headers' => [
'Authorization' => config ( 'variables.payment_service_key' ),
]
]);
$paymentResponse = $client -> post ( '/pay' , [
'json' => [
'aggregator_id' => $aggregator -> id ,
'amount' => config ( 'variables.payment_test_amount' , $amountToPaid ),
'currency' => $accountRequest -> currency_code ,
'customer_id' => $user -> id ,
'customer_email' => $user -> email ,
'customer_name' => $user -> lastname ,
'customer_surname' => $user -> lastname ,
'customer_phone_number' => $request -> input ( 'payment_phone' ),
'customer_address' => $user -> adresse ,
'customer_country' => $county -> name ? ? '' ,
'customer_city' => $user -> adresse ,
'customer_state' => $county -> code_country ? ? '' ,
'customer_zip_code' => '00237' ,
'payment_method' => $request -> input ( 'payment_method' ),
'reason' => 'N° ' . __ ( 'messages.customer_account_opening_request' ) . " : " . $accountRequest -> unique_id ,
'otp' => $request -> input ( 'otp' )
],
'http_errors' => false
]);
$responseData = json_decode ( $paymentResponse -> getBody () -> getContents ());
$responseCode = $paymentResponse -> getStatusCode ();
if ( $responseCode == 200 ) {
// $transaction_id = $responseData->response->transaction_id;
return $this -> successResponse ( $responseData -> response );
} else {
return $this -> errorResponse ( $responseData -> error ? ? trans ( 'errors.unexpected_error' ), $responseCode );
}
}
}
CustomerAccountRequest :: where ( 'id' , $accountRequest -> id ) -> update ([
'status' => CustomerAccountRequest :: ACCEPTED_PAID ,
'payment_transaction_id' => $transaction_id ,
'updated_at' => $datetime
]);
DB :: commit ();
} catch ( Throwable $e ) {
DB :: rollBack ();
Log :: error ( $e -> getMessage ());
return $this -> errorResponse ( trans ( 'errors.unexpected_error' ));
}
return $this -> successResponse ( trans ( 'messages.successful_paid_receipt' ), Response :: HTTP_CREATED );
}
2022-11-25 22:53:53 +00:00
}