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.
643 lines
25 KiB
643 lines
25 KiB
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use DateTime;
|
|
use App\Models\Orders;
|
|
use App\Models\Stores;
|
|
use App\Models\Reports;
|
|
use App\Models\Products;
|
|
use App\Models\OrderItems;
|
|
use App\Models\Brands;
|
|
use App\Models\Users;
|
|
|
|
|
|
class ReportController extends AdminController
|
|
{
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
private $pageTitle = 'Reports';
|
|
|
|
public function index()
|
|
{
|
|
$this->verifyRole('viewReports');
|
|
$data['page_title'] = $this->pageTitle;
|
|
|
|
// Get the current year or the selected year from the form
|
|
$today_year = date('Y');
|
|
if ($this->request->getPost('select_year')) {
|
|
$today_year = $this->request->getPost('select_year');
|
|
}
|
|
|
|
// Fetch order data and years
|
|
$Reports = new Reports();
|
|
$Orders = new Orders();
|
|
$Store = new Stores();
|
|
$parking_data = $Reports->getOrderData($today_year);
|
|
$data['report_years'] = $Reports->getOrderYear();
|
|
|
|
|
|
// Process the parking data and calculate total amounts
|
|
$final_parking_data = [];
|
|
foreach ($parking_data as $month => $orders) {
|
|
$total_amount_earned = 0;
|
|
|
|
if (!empty($orders)) {
|
|
foreach ($orders as $order) {
|
|
// Utiliser le montant selon la logique : discount si existe, sinon gross_amount
|
|
if (!empty($order['discount']) && $order['discount'] > 0) {
|
|
$total_amount_earned += (float) $order['discount'];
|
|
} else {
|
|
$total_amount_earned += (float) $order['gross_amount'];
|
|
}
|
|
}
|
|
}
|
|
|
|
$final_parking_data[$month] = $total_amount_earned;
|
|
}
|
|
// Data for the camembert (pie chart)
|
|
$paymentModes = $Orders->getPaymentModes();
|
|
$total_mvola1 = $paymentModes->total_mvola1;
|
|
$total_mvola2 = $paymentModes->total_mvola2;
|
|
$total_espece1 = $paymentModes->total_espece1;
|
|
$total_espece2 = $paymentModes->total_espece2;
|
|
$total_banque1 = $paymentModes->total_virement_bancaire1;
|
|
$total_banque2 = $paymentModes->total_virement_bancaire2;
|
|
$total_mvola = $total_mvola1 + $total_mvola2;
|
|
$total_banque = $total_banque1 + $total_banque2;
|
|
$total_espece = $total_espece1 + $total_espece2;
|
|
$totalOrders = $Orders->getTotalOrders();
|
|
$totalAmountPerPaymentModes = ["MVOLA" => $total_mvola, "Espece" => $total_espece, "Virement Bancaire" => $total_banque];
|
|
$totalOrdersCount = (int) $totalOrders->total_orders;
|
|
$labels = [];
|
|
$totals = [];
|
|
|
|
if ($totalOrdersCount > 0) {
|
|
foreach ($totalAmountPerPaymentModes as $mode => $total) {
|
|
$labels[] = $mode;
|
|
$totals[] = $total;
|
|
}
|
|
}
|
|
|
|
$data['labels'] = json_encode($labels);
|
|
$data['totals'] = json_encode($totals);
|
|
|
|
// Prepare data for product chart
|
|
$OrderItem = new OrderItems();
|
|
$productTable = $OrderItem->getAllSoldProductToday();
|
|
|
|
$product_sold = (int) $productTable->total_product_sold;
|
|
$unsold_product = (int) $productTable->total_unsold_product;
|
|
|
|
$labels1 = ["Produits vendus", "Produits non vendus"];
|
|
$totals2 = [$product_sold, $unsold_product];
|
|
|
|
$data['labels_product'] = json_encode($labels1);
|
|
$data['totals_product'] = json_encode($totals2);
|
|
|
|
// Prepare data for the view
|
|
$data['selected_year'] = $today_year;
|
|
$data['company_currency'] = $this->companycurrency();
|
|
$data['results'] = $final_parking_data;
|
|
|
|
// Data for the camembert in dashboard
|
|
$totalStoreOrder = $Orders->getTotalOrderPerStore();
|
|
$totalOrders = $Orders->getTotalOrders();
|
|
$totalOrdersCount = (int) $totalOrders->total_orders;
|
|
|
|
// Initialisation des variables pour éviter l'erreur "Undefined variable"
|
|
$labelStore = [];
|
|
$totalPerStore = [];
|
|
|
|
foreach ($totalStoreOrder as $totalOrdersInStore) {
|
|
$storeList = $Store->getStoreById($totalOrdersInStore->store_id);
|
|
$labelStore[] = $storeList->name ?? 'Inconnu';
|
|
$totalPerStore[] = ((int) $totalOrdersInStore->total / $totalOrdersCount) * 100;
|
|
}
|
|
|
|
$data['labelStore'] = json_encode($labelStore);
|
|
$data['totalPerStore'] = json_encode($totalPerStore);
|
|
|
|
// Load the view
|
|
return $this->render_template('reports/index', $data);
|
|
}
|
|
|
|
private function companycurrency()
|
|
{
|
|
return 'AR'; // Replace with your actual logic for company currency
|
|
}
|
|
|
|
public function stockDetail()
|
|
{
|
|
$this->verifyRole('viewReports');
|
|
$data['page_title'] = $this->pageTitle;
|
|
$Orders = new Orders();
|
|
$Products = new Products();
|
|
$Stores = new Stores();
|
|
$productVente = $Orders->getTotalProductvente();
|
|
$produitStock = $Products->getProductData();
|
|
$stor = $Stores->getActiveStore();
|
|
|
|
$data['ventes'] = \json_encode($productVente);
|
|
$data['stock'] = \json_encode($produitStock);
|
|
$data['stores'] = $stor;
|
|
|
|
// echo '<pre>';
|
|
// die(var_dump($produitStock));
|
|
|
|
return $this->render_template('reports/stockDetail', $data);
|
|
}
|
|
|
|
private function returnName(int $id)
|
|
{
|
|
$Stores = new Stores();
|
|
$stor = $Stores->getActiveStore();
|
|
$Storename = "";
|
|
foreach ($stor as $key => $value) {
|
|
if ($value['id'] == $id) {
|
|
$Storename = $value['name'];
|
|
}
|
|
}
|
|
|
|
return $Storename;
|
|
}
|
|
|
|
public function fetchProductSodled(int $id)
|
|
{
|
|
$Orders = new Orders();
|
|
|
|
$productVente = $Orders->getTotalProductvente2($id);
|
|
$result = ['data' => []];
|
|
|
|
foreach ($productVente as $key => $value) {
|
|
// die(var_dump($value)); // Debugging: Check what $value contains
|
|
|
|
// Add the row data
|
|
$result['data'][$key] = [
|
|
$value->sku,
|
|
$value->date_time,
|
|
$this->returnName($value->store_id)
|
|
];
|
|
}
|
|
|
|
// Return data in JSON format
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
private function checkArrivalDate($dateArivage)
|
|
{
|
|
$dateArivage = new DateTime($dateArivage);
|
|
$today = new DateTime();
|
|
$interval = $dateArivage->diff($today);
|
|
|
|
// Return the date only if it is within the last 15 days
|
|
return $interval->days . " Jours";
|
|
}
|
|
|
|
public function fetchProductStock(int $id)
|
|
{
|
|
$Products = new Products();
|
|
|
|
$produitStock = $Products->getProductData2($id);
|
|
$result = ['data' => []];
|
|
|
|
foreach ($produitStock as $key => $value) {
|
|
// die(var_dump($value)); // Debugging: Check what $value contains
|
|
|
|
// Add the row data
|
|
$result['data'][$key] = [
|
|
$value['brand_name'],
|
|
$value['total_product'] . " Motos",
|
|
$this->returnName($value['store_id'])
|
|
];
|
|
}
|
|
|
|
// Return data in JSON format
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
public function fetchProductStock2(int $id)
|
|
{
|
|
$Products = new Orders();
|
|
|
|
$produitStock = $Products->getOrderVendue();
|
|
$result = ['data' => []];
|
|
// echo '<pre>';
|
|
// die(var_dump($produitStock));
|
|
|
|
foreach ($produitStock as $key => $value) {
|
|
// die(var_dump($value)); // Debugging: Check what $value contains
|
|
|
|
// Add the row data
|
|
$result['data'][$key] = [
|
|
$value['sku'],
|
|
$value['qty'],
|
|
$value['totalNet'],
|
|
(new DateTime($value['DateTime']))->format('Y-m-d'),
|
|
$this->returnName($value['store_id'])
|
|
];
|
|
}
|
|
|
|
// Return data in JSON format
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
public function performancedetail()
|
|
{
|
|
$this->verifyRole('viewReports');
|
|
$data['page_title'] = $this->pageTitle;
|
|
$Stores = new Stores();
|
|
|
|
// echo '<pre>';
|
|
// die(var_dump($orderTest));
|
|
$data['stores'] = $Stores->getActiveStore();
|
|
|
|
return $this->render_template('reports/performance', $data);
|
|
}
|
|
|
|
public function fetchPerformances()
|
|
{
|
|
$result = ['data' => []];
|
|
$Orders = new Orders();
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
|
|
// ✅ RÉCUPÉRER LES PARAMÈTRES DE FILTRE
|
|
$startDate = $this->request->getGet('startDate');
|
|
$endDate = $this->request->getGet('endDate');
|
|
$pvente = $this->request->getGet('pvente');
|
|
|
|
// ✅ CORRECTION : Bonne concaténation des chaînes
|
|
log_message('debug', 'Filtres Commercial reçus - startDate: ' . $startDate . ', endDate: ' . $endDate . ', pvente: ' . $pvente);
|
|
|
|
// Pour Direction et Conseil : afficher TOUTES les performances AVEC FILTRES
|
|
if ($users['group_name'] === "DAF" || $users['group_name'] === "Direction" || $users['group_name'] === "SuperAdmin") {
|
|
// ✅ PASSER LES FILTRES AU MODÈLE - UNIQUEMENT POUR L'ADMIN
|
|
$orderPaid = $Orders->getPerformanceByOrders($startDate, $endDate, $pvente);
|
|
foreach ($orderPaid as $key => $value) {
|
|
// Déterminer le prix de vente réel
|
|
$prix_vente_reel = (!empty($value['discount']) && $value['discount'] > 0)
|
|
? $value['discount']
|
|
: $value['prix_vente'];
|
|
|
|
// Calculer le bénéfice
|
|
$benefice = $prix_vente_reel - $value['price'];
|
|
|
|
$result['data'][$key] = [
|
|
$value['firstname'] . ' ' . $value['lastname'],
|
|
$value['email'],
|
|
($value['sku'] == "" ? $value['motoname'] : $value['sku']),
|
|
(new DateTime($value['datevente']))->format('Y-m-d'),
|
|
number_format($value['price'], 0, '.', ' '),
|
|
number_format($prix_vente_reel, 0, '.', ' '),
|
|
$this->returnName($value['store_id']),
|
|
number_format($benefice, 0, '.', ' '),
|
|
];
|
|
}
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
// ✅ POUR LES AUTRES RÔLES, GARDER L'ANCIENNE LOGIQUE SANS FILTRES
|
|
// Pour Cheffe d'Agence : performances de son magasin
|
|
if ($users['group_name'] === "Cheffe d'Agence") {
|
|
$orderPaid = $Orders->getPerformanceByOrders1();
|
|
foreach ($orderPaid as $key => $value) {
|
|
// Déterminer le prix de vente réel
|
|
$prix_vente_reel = (!empty($value['discount']) && $value['discount'] > 0)
|
|
? $value['discount']
|
|
: $value['prix_vente'];
|
|
|
|
$result['data'][$key] = [
|
|
$value['firstname'] . ' ' . $value['lastname'],
|
|
($value['sku'] == "" ? $value['motoname'] : $value['sku']),
|
|
(new DateTime($value['datevente']))->format('Y-m-d'),
|
|
number_format($prix_vente_reel, 0, '.', ' '),
|
|
];
|
|
}
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
if ($users['group_name'] === "Caissière") {
|
|
$orderPaid = $Orders->getPerformanceByCaissier($users['id']);
|
|
|
|
foreach ($orderPaid as $key => $value) {
|
|
// Calculer le prix de vente réel
|
|
$prix_vente_reel = (!empty($value['discount']) && $value['discount'] > 0)
|
|
? $value['discount']
|
|
: $value['prix_vente'];
|
|
|
|
// Colonnes à afficher : Caissier, Moto vendue, Date de vente, Prix de vente
|
|
$result['data'][$key] = [
|
|
$value['caissier_name'] ?? 'N/A', // Nom du caissier
|
|
($value['sku'] == "" ? $value['motoname'] : $value['sku']), // Moto
|
|
(new DateTime($value['datevente']))->format('d/m/Y'), // Date
|
|
number_format($prix_vente_reel, 0, '.', ' ') // Prix
|
|
];
|
|
}
|
|
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
// Pour COMMERCIALE : uniquement ses propres ventes
|
|
if ($users['group_name'] === "COMMERCIALE") {
|
|
$orderPaid = $Orders->getPerformanceByOrders2();
|
|
foreach ($orderPaid as $key => $value) {
|
|
// Déterminer le prix de vente réel
|
|
$prix_vente_reel = (!empty($value['discount']) && $value['discount'] > 0)
|
|
? $value['discount']
|
|
: $value['prix_vente'];
|
|
|
|
$result['data'][$key] = [
|
|
$value['firstname'] . ' ' . $value['lastname'],
|
|
($value['sku'] == "" ? $value['motoname'] : $value['sku']),
|
|
(new DateTime($value['datevente']))->format('Y-m-d'),
|
|
number_format($prix_vente_reel, 0, '.', ' '),
|
|
];
|
|
}
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
// Retour par défaut si aucun rôle ne correspond
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
public function fetchmecperformance()
|
|
{
|
|
$result = ['data'=> []];
|
|
|
|
}
|
|
|
|
public function fetchCaissierPerformances()
|
|
{
|
|
$result = ['data' => []];
|
|
$Orders = new Orders();
|
|
$session = session();
|
|
$users = $session->get('user');
|
|
|
|
if ($users['group_name'] !== "Caissière") {
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
$startDate = $this->request->getGet('startDate');
|
|
$endDate = $this->request->getGet('endDate');
|
|
|
|
// ✅ SI PAS DE DATES, PRENDRE AUJOURD'HUI PAR DÉFAUT
|
|
if (empty($startDate) && empty($endDate)) {
|
|
$startDate = date('Y-m-d');
|
|
$endDate = date('Y-m-d');
|
|
}
|
|
|
|
$orderPaid = $Orders->getPerformanceByCaissier($users['id'], $startDate, $endDate);
|
|
|
|
foreach ($orderPaid as $key => $value) {
|
|
$prix_vente_reel = (!empty($value['discount']) && $value['discount'] > 0)
|
|
? $value['discount']
|
|
: $value['prix_vente'];
|
|
|
|
$result['data'][$key] = [
|
|
$value['caissier_name'] ?? 'N/A',
|
|
($value['sku'] == "" ? $value['motoname'] : $value['sku']),
|
|
(new DateTime($value['datevente']))->format('d/m/Y H:i'),
|
|
number_format($prix_vente_reel, 0, '.', ' ') . ' Ar'
|
|
];
|
|
}
|
|
|
|
return $this->response->setJSON($result);
|
|
}
|
|
public function fetchSecuritePerformances()
|
|
{
|
|
$session = session();
|
|
$user = $session->get('user');
|
|
|
|
// ✅ RÉCUPÉRER LES PARAMÈTRES DE FILTRAGE
|
|
$startDate = $this->request->getGet('startDate');
|
|
$endDate = $this->request->getGet('endDate');
|
|
$storeFilter = $this->request->getGet('store_id');
|
|
|
|
// ✅ DEBUG
|
|
log_message('debug', '=== FILTRES REÇUS ===');
|
|
log_message('debug', 'startDate: ' . ($startDate ?? 'vide'));
|
|
log_message('debug', 'endDate: ' . ($endDate ?? 'vide'));
|
|
log_message('debug', 'store_id: ' . ($storeFilter ?? 'vide'));
|
|
|
|
// Charger les modèles
|
|
$orderModel = new \App\Models\Orders();
|
|
$orderItemModel = new \App\Models\OrderItems();
|
|
$productModel = new \App\Models\Products();
|
|
$brandModel = new \App\Models\Brands();
|
|
$userModel = new \App\Models\Users();
|
|
$storeModel = new \App\Models\Stores();
|
|
|
|
// Récupérer le store de l'utilisateur connecté
|
|
$userStore = null;
|
|
if (in_array($user['group_name'], ['SECURITE', 'Cheffe d\'Agence'])) {
|
|
$currentUser = $userModel->find($user['id']);
|
|
$userStore = $currentUser['store_id'] ?? null;
|
|
}
|
|
|
|
// ✅ CONSTRUCTION DE LA REQUÊTE AVEC FILTRES
|
|
$builder = $orderModel->builder();
|
|
$builder->select('
|
|
orders.id,
|
|
orders.bill_no,
|
|
orders.customer_name,
|
|
orders.customer_phone,
|
|
orders.customer_address,
|
|
orders.customer_cin,
|
|
orders.delivered_at,
|
|
orders.store_id,
|
|
CONCAT(deliverer.firstname, " ", deliverer.lastname) as agent_name,
|
|
deliverer.id as agent_id
|
|
')
|
|
->join('users as deliverer', 'deliverer.id = orders.delivered_by', 'left')
|
|
->where('orders.paid_status', 3)
|
|
->where('orders.delivered_by IS NOT NULL', null, false);
|
|
|
|
// ✅ FILTRER PAR STORE
|
|
// Si l'utilisateur a un store assigné, on filtre automatiquement par ce store
|
|
if ($userStore) {
|
|
$builder->where('orders.store_id', $userStore);
|
|
log_message('debug', '✅ Filtre userStore appliqué: ' . $userStore);
|
|
}
|
|
// Sinon, si un store est sélectionné dans le filtre, on l'applique
|
|
elseif (!empty($storeFilter)) {
|
|
$builder->where('orders.store_id', $storeFilter);
|
|
log_message('debug', '✅ Filtre storeFilter appliqué: ' . $storeFilter);
|
|
}
|
|
|
|
// ✅ FILTRAGE PAR DATE DE DÉBUT
|
|
if (!empty($startDate)) {
|
|
$builder->where('DATE(orders.delivered_at) >=', $startDate);
|
|
log_message('debug', '✅ Filtre startDate appliqué: ' . $startDate);
|
|
}
|
|
|
|
// ✅ FILTRAGE PAR DATE DE FIN
|
|
if (!empty($endDate)) {
|
|
$builder->where('DATE(orders.delivered_at) <=', $endDate);
|
|
log_message('debug', '✅ Filtre endDate appliqué: ' . $endDate);
|
|
}
|
|
|
|
$builder->orderBy('orders.delivered_at', 'DESC');
|
|
|
|
// ✅ DEBUG : Afficher la requête SQL
|
|
$sql = $builder->getCompiledSelect(false);
|
|
log_message('debug', '📋 SQL GÉNÉRÉ: ' . $sql);
|
|
|
|
$orders = $builder->get()->getResultArray();
|
|
|
|
log_message('debug', '📊 Nombre de commandes trouvées: ' . count($orders));
|
|
|
|
$result = [];
|
|
|
|
foreach ($orders as $order) {
|
|
$orderItems = $orderItemModel->where('order_id', $order['id'])->findAll();
|
|
|
|
foreach ($orderItems as $item) {
|
|
$qty = isset($item['qty']) ? (int)$item['qty'] : 1;
|
|
$product = $productModel->find($item['product_id']);
|
|
|
|
if ($product) {
|
|
$brand = $brandModel->find($product['marque']);
|
|
$brandName = $brand['name'] ?? 'Aucune marque';
|
|
|
|
$store = $storeModel->find($order['store_id']);
|
|
$storeName = $store['name'] ?? 'N/A';
|
|
|
|
$agentName = $order['agent_name'] ?? 'N/A';
|
|
$imageUrl = base_url('assets/images/products/' . $product['image']);
|
|
|
|
$validationDate = $order['delivered_at'] ?
|
|
date('d/m/Y H:i', strtotime($order['delivered_at'])) :
|
|
'N/A';
|
|
|
|
$result[] = [
|
|
$imageUrl, // 0 - Image
|
|
$order['bill_no'] ?? 'N/A', // 1 - N° Facture
|
|
$product['name'], // 2 - Désignation
|
|
$product['sku'], // 3 - UGS
|
|
$brandName, // 4 - Marque
|
|
$order['customer_name'], // 5 - Client
|
|
$agentName, // 6 - Agent Sécurité
|
|
$storeName, // 7 - Magasin
|
|
$validationDate, // 8 - Date Validation
|
|
'<span class="badge badge-success"><i class="fa fa-check"></i> VALIDÉE</span>', // 9
|
|
$qty, // 10 - Quantité
|
|
$product['sku'] ?? 'N/A', // 11
|
|
$order['customer_phone'] ?? 'N/A', // 12
|
|
$order['customer_address'] ?? 'N/A', // 13
|
|
$order['customer_cin'] ?? 'N/A', // 14
|
|
$product['numero_de_moteur'] ?? 'N/A', // 15
|
|
$product['chasis'] ?? 'N/A' // 16
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
log_message('debug', '✅ Nombre de lignes retournées: ' . count($result));
|
|
|
|
return $this->response->setJSON(['data' => $result]);
|
|
}
|
|
|
|
// ============================================
|
|
// MÉTHODE POUR RÉCUPÉRER LES DÉTAILS D'UNE VALIDATION
|
|
// ============================================
|
|
public function getSecuriteValidationDetails($orderId)
|
|
{
|
|
$session = session();
|
|
$user = $session->get('user');
|
|
|
|
$orderModel = new \App\Models\Orders();
|
|
$orderItemModel = new \App\Models\OrderItems();
|
|
$productModel = new \App\Models\Products();
|
|
$brandModel = new \App\Models\Brands();
|
|
$storeModel = new \App\Models\Stores();
|
|
$userModel = new \App\Models\Users();
|
|
|
|
$builder = $orderModel->builder();
|
|
$builder->select('
|
|
orders.*,
|
|
CONCAT(deliverer.firstname, " ", deliverer.lastname) as agent_name
|
|
')
|
|
->join('users as deliverer', 'deliverer.id = orders.delivered_by', 'left')
|
|
->where('orders.id', $orderId);
|
|
|
|
$order = $builder->get()->getRowArray();
|
|
|
|
if (!$order) {
|
|
return $this->response->setJSON(['error' => 'Commande non trouvée']);
|
|
}
|
|
|
|
// Récupérer le magasin
|
|
$store = $storeModel->find($order['store_id']);
|
|
$storeName = $store['name'] ?? 'N/A';
|
|
|
|
// Récupérer le premier item
|
|
$orderItem = $orderItemModel->where('order_id', $orderId)->first();
|
|
$product = null;
|
|
$brandName = 'Aucune marque';
|
|
$imageUrl = '';
|
|
$qty = 1;
|
|
|
|
if ($orderItem) {
|
|
// ✅ RÉCUPÉRER LA QUANTITÉ
|
|
$qty = isset($orderItem['qty']) ? (int)$orderItem['qty'] : 1;
|
|
|
|
$product = $productModel->find($orderItem['product_id']);
|
|
if ($product) {
|
|
$brand = $brandModel->find($product['marque']);
|
|
$brandName = $brand['name'] ?? 'Aucune marque';
|
|
$imageUrl = base_url('assets/images/products/' . $product['image']);
|
|
}
|
|
}
|
|
|
|
$agentName = $order['agent_name'] ?? 'N/A';
|
|
$validationDate = $order['delivered_at'] ?
|
|
date('d/m/Y H:i', strtotime($order['delivered_at'])) :
|
|
'N/A';
|
|
|
|
$result = [
|
|
$imageUrl, // 0
|
|
$order['bill_no'] ?? 'N/A', // 1
|
|
$product['name'] ?? 'N/A', // 2
|
|
$product['sku'] ?? 'N/A', // 3
|
|
$brandName, // 4
|
|
$order['customer_name'], // 5
|
|
$agentName, // 6
|
|
$storeName, // 7
|
|
$validationDate, // 8
|
|
'<span class="badge badge-success"><i class="fa fa-check"></i> VALIDÉE</span>', // 9
|
|
$qty, // 10 - ✅ QUANTITÉ
|
|
$product['sku'] ?? 'N/A', // 11
|
|
$order['customer_phone'] ?? 'N/A', // 12
|
|
$order['customer_address'] ?? 'N/A', // 13
|
|
$order['customer_cin'] ?? 'N/A', // 14
|
|
$product['numero_de_moteur'] ?? 'N/A', // 15
|
|
$product['chasis'] ?? 'N/A' // 16
|
|
];
|
|
|
|
return $this->response->setJSON($result);
|
|
}
|
|
|
|
public function securiteHistory()
|
|
{
|
|
$this->verifyRole('viewReports');
|
|
|
|
$session = session();
|
|
$user = $session->get('user');
|
|
|
|
$data['page_title'] = 'Historique des Validations Sécurité';
|
|
$data['user_role'] = $user['group_name']; // ✅ AJOUT DE LA VARIABLE user_role
|
|
|
|
// ✅ RÉCUPÉRER TOUS LES MAGASINS ACTIFS (comme dans AutresEncaissements)
|
|
$storeModel = new \App\Models\Stores();
|
|
$data['stores'] = $storeModel->getActiveStore();
|
|
|
|
log_message('debug', '📋 Nombre de magasins trouvés: ' . count($data['stores']));
|
|
log_message('debug', '👤 Rôle utilisateur: ' . $user['group_name']);
|
|
|
|
return $this->render_template('reports/securite_history', $data);
|
|
}
|
|
}
|