user-service/app/Http/Controllers/CustomerAccountOpeningContr...

1033 lines
49 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;
use App\Models\AgentPlus;
use App\Models\CustomerAccountRequest;
use App\Models\CustomerAccountRequestDocument;
use App\Models\CustomerAccountType;
use App\Models\Identification;
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;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use OpenApi\Annotations as OA;
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(),[
'opening_amount' => $accountType->opening_amount,
'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'));
}
/**
* @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": "80000 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)
{
$accountRequest = CustomerAccountRequest::with(['account_type:id,name','documents:request_id,name,description,url'])->where('id', $id)->firstOrFail();
$this->formatCustomerRequest($accountRequest);
return $this->successResponse($accountRequest);
}
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':
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);
}
$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);
}
/**
* @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);
}
}