You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

630 lines
28 KiB

<?php
namespace App\Controllers;
use App\Controllers\AdminController;
use App\Models\Orders;
use App\Models\Recouvrement;
use App\Models\SortieCaisse;
use App\Models\Avance;
use App\Models\Stores;
class RecouvrementController extends AdminController
{
public function __construct()
{
parent::__construct();
}
private $pageTitle = 'Recouvrements';
public function index()
{
$this->verifyRole('viewRecouvrement');
$data = $this->getTotalsArray();
$this->render_template('recouvrement/index', $data);
}
// Create an AJAX endpoint to access the fetchTotal() function
public function getTotalData()
{
echo $this->fetchTotal();
exit;
}
public function fetchTotal()
{
$data = $this->getTotalsArray();
return $this->response->setJSON($data);
}
private function getTotalsArray(): array
{
$orders = new Orders();
$recouvrement = new Recouvrement();
$sortieCaisse = new SortieCaisse();
$avance = new Avance();
// Récupère les données brutes
$paymentDataOrders = $orders->getPaymentModes();
$paymentDataAvance = $avance->getPaymentModesAvance();
$totalRecouvrement = $recouvrement->getTotalRecouvrements();
$total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();
// === EXTRACTION DES SORTIES PAR MODE DE PAIEMENT ===
$total_sortie_espece = isset($total_sortie_caisse->total_espece) ? (float) $total_sortie_caisse->total_espece : 0;
$total_sortie_mvola = isset($total_sortie_caisse->total_mvola) ? (float) $total_sortie_caisse->total_mvola : 0;
$total_sortie_virement = isset($total_sortie_caisse->total_virement) ? (float) $total_sortie_caisse->total_virement : 0;
// === TOTAUX RECOUVREMENT ===
$me = isset($totalRecouvrement->me) ? (float) $totalRecouvrement->me : 0;
$bm = isset($totalRecouvrement->bm) ? (float) $totalRecouvrement->bm : 0;
$be = isset($totalRecouvrement->be) ? (float) $totalRecouvrement->be : 0;
$mb = isset($totalRecouvrement->mb) ? (float) $totalRecouvrement->mb : 0;
// === TOTAUX PAIEMENTS ORDERS ===
$total_orders = isset($paymentDataOrders->total) ? (float) $paymentDataOrders->total : 0;
$mv1_orders = isset($paymentDataOrders->total_mvola1) ? (float) $paymentDataOrders->total_mvola1 : 0;
$mv2_orders = isset($paymentDataOrders->total_mvola2) ? (float) $paymentDataOrders->total_mvola2 : 0;
$es1_orders = isset($paymentDataOrders->total_espece1) ? (float) $paymentDataOrders->total_espece1 : 0;
$es2_orders = isset($paymentDataOrders->total_espece2) ? (float) $paymentDataOrders->total_espece2 : 0;
$vb1_orders = isset($paymentDataOrders->total_virement_bancaire1) ? (float) $paymentDataOrders->total_virement_bancaire1 : 0;
$vb2_orders = isset($paymentDataOrders->total_virement_bancaire2) ? (float) $paymentDataOrders->total_virement_bancaire2 : 0;
// === TOTAUX PAIEMENTS AVANCES ===
$total_avances = isset($paymentDataAvance->total) ? (float) $paymentDataAvance->total : 0;
$mv_avances = isset($paymentDataAvance->total_mvola) ? (float) $paymentDataAvance->total_mvola : 0;
$es_avances = isset($paymentDataAvance->total_espece) ? (float) $paymentDataAvance->total_espece : 0;
$vb_avances = isset($paymentDataAvance->total_virement_bancaire) ? (float) $paymentDataAvance->total_virement_bancaire : 0;
// === COMBINAISON ORDERS + AVANCES ===
$total_mvola = $mv1_orders + $mv2_orders + $mv_avances;
$total_espece = $es1_orders + $es2_orders + $es_avances;
$total_vb = $vb1_orders + $vb2_orders + $vb_avances;
$total = $total_orders + $total_avances;
// === AJUSTEMENTS AVEC RECOUVREMENTS ET SORTIES (PAR MODE DE PAIEMENT) ===
$total_mvola_final = $total_mvola -
$me -
$mb +
$bm -
$total_sortie_mvola;
$total_espece_final = $total_espece +
$me +
$be -
$total_sortie_espece;
$total_virement_bancaire_final = $total_vb -
$be -
$bm +
$mb -
$total_sortie_virement;
// === CALCUL DU TOTAL GÉNÉRAL ===
$total_sortie_global = $total_sortie_espece + $total_sortie_mvola + $total_sortie_virement;
$total_final = $total - $total_sortie_global;
return [
'total' => $total_final,
'total_mvola' => $total_mvola_final,
'total_espece' => $total_espece_final,
'total_virement_bancaire' => $total_virement_bancaire_final,
'page_title' => $this->pageTitle,
'permission' => $this->permission
];
}
public function fetchRecouvrementData()
{
helper(['url', 'form']);
$Recouvrement = new Recouvrement();
// Initialiser les variables pour DataTables
$draw = intval($this->request->getVar('draw'));
$session = session();
$users = $session->get('user');
if($users['group_name'] === "Caissière"){
$data = $Recouvrement->getAllRecouvrements($users['id'] );
$totalRecords = count($data); // Nombre total de recouvrements
$result = [
"draw" => $draw,
"recordsTotal" => $totalRecords,
"recordsFiltered" => $totalRecords,
"data" => []
];
foreach ($data as $key => $value) {
$buttons = '';
if (in_array('updateRecouvrement', $this->permission)) {
$buttons .= '<button type="button" class="btn btn-default" onclick="editFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#updateModal"><i class="fa fa-pencil"></i></button>';
}
if (in_array('deleteRecouvrement', $this->permission)) {
$buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
}
$result['data'][$key] = [
$value['recouvrement_id'],
number_format($value['recouvrement_montant'], 0, '.', ' '),
$value['recouvrement_date'],
$value['recouvrement_personnel'],
$value['send_money'],
$value['get_money'],
$buttons
];
}
return $this->response->setJSON($result);
}
$data = $Recouvrement->getAllRecouvrements();
$totalRecords = count($data); // Nombre total de recouvrements
$result = [
"draw" => $draw,
"recordsTotal" => $totalRecords,
"recordsFiltered" => $totalRecords,
"data" => []
];
foreach ($data as $key => $value) {
$buttons = '';
if (in_array('updateRecouvrement', $this->permission)) {
$buttons .= '<button type="button" class="btn btn-default" onclick="editFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#updateModal"><i class="fa fa-pencil"></i></button>';
}
if (in_array('deleteRecouvrement', $this->permission)) {
$buttons .= ' <button type="button" class="btn btn-danger" onclick="removeFunc(' . $value['recouvrement_id'] . ')" data-toggle="modal" data-target="#removeModal"><i class="fa fa-trash"></i></button>';
}
$result['data'][$key] = [
$value['recouvrement_id'],
number_format($value['recouvrement_montant'], 0, '.', ' '),
$value['recouvrement_date'],
$value['recouvrement_personnel'],
$value['send_money'],
$value['get_money'],
$buttons
];
}
return $this->response->setJSON($result);
}
public function removeRecouvrement()
{
$this->verifyRole('deleteRecouvrement');
$recouvrement_id = $this->request->getPost('recouvrement_id');
$response = [];
if ($recouvrement_id) {
$Recouvrement = new Recouvrement();
// ✅ Récupérer les infos du recouvrement avant suppression
$recouvrementData = $Recouvrement->getRecouvrementSingle($recouvrement_id);
if ($Recouvrement->deleteRecouvrement($recouvrement_id)) {
// ✅ Notification pour TOUS les Direction, DAF et SuperAdmin de TOUS les stores
try {
if (class_exists('App\Controllers\NotificationController') && $recouvrementData) {
$Notification = new NotificationController();
$Stores = new Stores();
$allStores = $Stores->getActiveStore();
$session = session();
$users = $session->get('user');
$message = "🗑️ Recouvrement supprimé<br>" .
"Montant: " . number_format($recouvrementData['recouvrement_montant'], 0, ',', ' ') . " Ar<br>" .
"Par: " . $users['firstname'] . ' ' . $users['lastname'];
// ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$message,
"Direction",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"DAF",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"SuperAdmin",
(int)$store['id'],
'recouvrement'
);
}
}
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification removeRecouvrement: ' . $e->getMessage());
}
$response['success'] = true;
$response['messages'] = "Recouvrement supprimé avec succès !<br><em>Notification envoyée à tous les Direction, DAF et SuperAdmin</em>";
} else {
$response['success'] = false;
$response['messages'] = "Erreur lors de la suppression du recouvrement.";
}
} else {
$response['success'] = false;
$response['messages'] = "Veuillez actualiser la page.";
}
return $this->response->setJSON($response);
}
public function createRecouvrement()
{
$this->verifyRole('createRecouvrement');
$data['page_title'] = $this->pageTitle;
// Load validation service
$validation = \Config\Services::validation();
$validation->setRules([
'send_mode' => 'required',
'get_mode' => 'required',
'recouvrement_montant' => 'required',
'recouvrement_date' => 'required',
]);
$validationData = [
'send_mode' => $this->request->getPost('send_mode'),
'get_mode' => $this->request->getPost('get_mode'),
'recouvrement_montant' => $this->request->getPost('recouvrement_montant'),
'recouvrement_date' => $this->request->getPost('recouvrement_date'),
];
$Notification = new NotificationController();
$Recouvrement = new Recouvrement();
$session = session();
$users = $session->get('user');
if ($users && isset($users['firstname'], $users['lastname'])) {
$fullname = $users['firstname'] . ' ' . $users['lastname'];
}
if ($validation->run($validationData)) {
$send_mode = $this->request->getPost('send_mode');
$get_mode = $this->request->getPost('get_mode');
$amount = (float) $this->request->getPost('recouvrement_montant');
// Vérifier si le recouvrement est possible
if (!$this->canMakeRecouvrement($send_mode, $get_mode, $amount)) {
$response['success'] = false;
$response['messages'] = 'Recouvrement impossible : solde insuffisant pour ce type de transaction';
return $this->response->setJSON($response);
}
// Préparer les données
$data = [
'recouvrement_montant' => $amount,
'recouvrement_date' => $this->request->getPost('recouvrement_date'),
'recouvrement_personnel' => $fullname,
'get_money' => $get_mode,
'send_money' => $send_mode,
'user_id' => $users['id'],
'store_id' => $users['store_id'],
];
if ($Recouvrement->addRecouvrement($data)) {
// ✅ Notification pour TOUS les Direction, DAF et SuperAdmin de TOUS les stores
try {
if (class_exists('App\Controllers\NotificationController')) {
$Stores = new Stores();
$allStores = $Stores->getActiveStore();
$message = "💱 Nouveau recouvrement créé<br>" .
"Montant: " . number_format($amount, 0, ',', ' ') . " Ar<br>" .
"De: " . $send_mode . " → Vers: " . $get_mode . "<br>" .
"Store: " . $this->returnStoreName($users['store_id']) . "<br>" .
"Par: " . $fullname;
// ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
// Notifier Direction
$Notification->createNotification(
$message,
"Direction",
(int)$store['id'],
'recouvrement'
);
// Notifier DAF
$Notification->createNotification(
$message,
"DAF",
(int)$store['id'],
'recouvrement'
);
// Notifier SuperAdmin
$Notification->createNotification(
$message,
"SuperAdmin",
(int)$store['id'],
'recouvrement'
);
}
}
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification createRecouvrement: ' . $e->getMessage());
// Continue même si la notification échoue
}
$response['success'] = true;
$response['messages'] = 'Recouvrement créé avec succès<br>' .
'Montant: ' . number_format($amount, 0, ',', ' ') . ' Ar<br>' .
$send_mode . ' → ' . $get_mode . '<br>' .
'<em>Notification envoyée à tous les Direction, DAF et SuperAdmin</em>';
} else {
$response['success'] = false;
$response['messages'] = 'Erreur lors de la création du recouvrement.';
}
} else {
// Validation failed, return error messages
$response['success'] = false;
$response['messages'] = $validation->getErrors();
}
return $this->response->setJSON($response);
}
public function updateRecouvrement($recouvrement_id)
{
$this->verifyRole('updateRecouvrement');
$data['page_title'] = $this->pageTitle;
// Load validation service
$validation = \Config\Services::validation();
// Set validation rules
$validation->setRules([
'product[]' => 'required'
]);
$validationData = [
'product[]' => $this->request->getPost('product[]')
];
$Recouvrement = new Recouvrement();
if ($this->request->getMethod() === 'post') {
$data = [
'recouvrement_montant' => (int) $this->request->getPost('recouvrement_montant_edit'),
'recouvrement_date' => $this->request->getPost('recouvrement_date_edit')
];
if ($Recouvrement->updateRecouvrement($recouvrement_id, $data)) {
// ✅ Notification pour TOUS les Direction, DAF et SuperAdmin de TOUS les stores
try {
if (class_exists('App\Controllers\NotificationController')) {
$Notification = new NotificationController();
$Stores = new Stores();
$allStores = $Stores->getActiveStore();
$session = session();
$users = $session->get('user');
$message = "✏️ Recouvrement modifié<br>" .
"Nouveau montant: " . number_format($data['recouvrement_montant'], 0, ',', ' ') . " Ar<br>" .
"Par: " . $users['firstname'] . ' ' . $users['lastname'];
// ✅ Notifier Direction, DAF et SuperAdmin de TOUS les stores
if (is_array($allStores) && count($allStores) > 0) {
foreach ($allStores as $store) {
$Notification->createNotification(
$message,
"Direction",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"DAF",
(int)$store['id'],
'recouvrement'
);
$Notification->createNotification(
$message,
"SuperAdmin",
(int)$store['id'],
'recouvrement'
);
}
}
}
} catch (\Exception $e) {
log_message('error', 'Erreur notification updateRecouvrement: ' . $e->getMessage());
}
return $this->response->setJSON([
'success' => true,
'messages' => 'Recouvrement modifié avec succès !<br><em>Notification envoyée à tous les Direction, DAF et SuperAdmin</em>'
]);
} else {
return $this->response->setJSON([
'success' => false,
'messages' => 'Erreur lors de la modification du recouvrement.'
]);
}
}
}
public function fetchRecouvrementSingle($id)
{
// die(var_dump('hghjbhj'));
if ($id) {
$recouvrement = new Recouvrement();
$data = $recouvrement->getRecouvrementSingle($id);
echo json_encode($data);
}
}
private function returnStoreName(int $id): string
{
$Stores = new Stores();
$stor = $Stores->getActiveStore();
$Storename = "";
foreach ($stor as $key => $value) {
if ($value['id'] == $id) {
$Storename = $value['name'];
}
}
return $Storename;
}
private function canMakeRecouvrement($send_mode, $get_mode, $amount): bool
{
$orders = new Orders();
$recouvrement = new Recouvrement();
$sortieCaisse = new SortieCaisse();
$avance = new Avance();
// Récupérer les données actuelles
$paymentDataOrders = $orders->getPaymentModes();
$paymentDataAvance = $avance->getPaymentModesAvance();
$totalRecouvrement = $recouvrement->getTotalRecouvrements();
$total_sortie_caisse = $sortieCaisse->getTotalSortieCaisse();
// === EXTRACTION DES SORTIES PAR MODE DE PAIEMENT ===
$total_sortie_espece = isset($total_sortie_caisse->total_espece) ? (float) $total_sortie_caisse->total_espece : 0;
$total_sortie_mvola = isset($total_sortie_caisse->total_mvola) ? (float) $total_sortie_caisse->total_mvola : 0;
$total_sortie_virement = isset($total_sortie_caisse->total_virement) ? (float) $total_sortie_caisse->total_virement : 0;
// === TOTAUX PAIEMENTS ORDERS ===
$mv1_orders = isset($paymentDataOrders->total_mvola1) ? (float) $paymentDataOrders->total_mvola1 : 0;
$mv2_orders = isset($paymentDataOrders->total_mvola2) ? (float) $paymentDataOrders->total_mvola2 : 0;
$es1_orders = isset($paymentDataOrders->total_espece1) ? (float) $paymentDataOrders->total_espece1 : 0;
$es2_orders = isset($paymentDataOrders->total_espece2) ? (float) $paymentDataOrders->total_espece2 : 0;
$vb1_orders = isset($paymentDataOrders->total_virement_bancaire1) ? (float) $paymentDataOrders->total_virement_bancaire1 : 0;
$vb2_orders = isset($paymentDataOrders->total_virement_bancaire2) ? (float) $paymentDataOrders->total_virement_bancaire2 : 0;
// === TOTAUX PAIEMENTS AVANCES ===
$mv_avances = isset($paymentDataAvance->total_mvola) ? (float) $paymentDataAvance->total_mvola : 0;
$es_avances = isset($paymentDataAvance->total_espece) ? (float) $paymentDataAvance->total_espece : 0;
$vb_avances = isset($paymentDataAvance->total_virement_bancaire) ? (float) $paymentDataAvance->total_virement_bancaire : 0;
// === TOTAUX RECOUVREMENT ===
$me = isset($totalRecouvrement->me) ? (float) $totalRecouvrement->me : 0;
$bm = isset($totalRecouvrement->bm) ? (float) $totalRecouvrement->bm : 0;
$be = isset($totalRecouvrement->be) ? (float) $totalRecouvrement->be : 0;
$mb = isset($totalRecouvrement->mb) ? (float) $totalRecouvrement->mb : 0;
// === CALCUL DES SOLDES ACTUELS ===
$solde_mvola = ($mv1_orders + $mv2_orders + $mv_avances) - $me - $mb + $bm - $total_sortie_mvola;
$solde_espece = ($es1_orders + $es2_orders + $es_avances) + $me + $be - $total_sortie_espece;
$solde_banque = ($vb1_orders + $vb2_orders + $vb_avances) - $be - $bm + $mb - $total_sortie_virement;
// === VÉRIFICATION EN FONCTION DU TYPE DE RECOUVREMENT ===
switch ($send_mode) {
case 'MVOLA':
if ($get_mode === 'En espèce') {
// MVOLA → Espèce : vérifier solde MVOLA
return $solde_mvola >= $amount;
} elseif ($get_mode === 'Virement Bancaire') {
// MVOLA → Banque : vérifier solde MVOLA
return $solde_mvola >= $amount;
}
break;
case 'Virement Bancaire':
if ($get_mode === 'MVOLA') {
// Banque → MVOLA : vérifier solde banque
return $solde_banque >= $amount;
} elseif ($get_mode === 'En espèce') {
// Banque → Espèce : vérifier solde banque
return $solde_banque >= $amount;
}
break;
}
return false;
}
public function fetchTotalRecouvrementData() {
helper(['url', 'form']);
$Recouvrement = new Recouvrement();
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
if ($start_date && $end_date) {
// Initialiser les variables pour DataTables
$draw = intval($this->request->getVar('draw'));
$session = session();
$users = $session->get('user');
if($users['group_name'] === "Caissière"){
$data = $Recouvrement->getTotalRecouvrements($users['id'] );
$result = [
"draw" => $draw,
"recordsTotal" => 1,
"recordsFiltered" => 1,
"data" => []
];
$totalRecouvrement = $Recouvrement->getTotalRecouvrements($users['id'], $start_date, $end_date );
$total_recouvrement_me = $totalRecouvrement->me;
$total_recouvrement_bm = $totalRecouvrement->bm;
$total_recouvrement_be = $totalRecouvrement->be;
$total_recouvrement_mb = $totalRecouvrement->mb;
$total_recouvrement = $total_recouvrement_me + $total_recouvrement_me + $total_recouvrement_be + $total_recouvrement_mb;
$data = [
number_format($total_recouvrement_me,0,'.',' '),
number_format($total_recouvrement_bm,0,'.',' '),
number_format($total_recouvrement_be,0,'.',' '),
number_format($total_recouvrement_mb,0,'.',' '),
number_format($total_recouvrement,0,'.',' '),
];
}
return $this->response->setJSON($result);
}
// Initialiser les variables pour DataTables
$draw = intval($this->request->getVar('draw'));
$session = session();
$users = $session->get('user');
if($users['group_name'] === "Caissière"){
$data = $Recouvrement->getTotalRecouvrements($users['id'] );
$result = [
"draw" => $draw,
"recordsTotal" => 1,
"recordsFiltered" => 1,
"data" => []
];
$totalRecouvrement = $Recouvrement->getTotalRecouvrements($users['id'] );
$total_recouvrement_me = $totalRecouvrement->me;
$total_recouvrement_bm = $totalRecouvrement->bm;
$total_recouvrement_be = $totalRecouvrement->be;
$total_recouvrement_mb = $totalRecouvrement->mb;
$total_recouvrement = $total_recouvrement_me + $total_recouvrement_me + $total_recouvrement_be + $total_recouvrement_mb;
$data = [
number_format($total_recouvrement_me,0,'.',' '),
number_format($total_recouvrement_bm,0,'.',' '),
number_format($total_recouvrement_be,0,'.',' '),
number_format($total_recouvrement_mb,0,'.',' '),
number_format($total_recouvrement,0,'.',' '),
];
}
return $this->response->setJSON($result);
}
}