motorbike/app/Controllers/HistoriqueController.php
2025-09-11 16:45:26 +03:00

316 lines
9.8 KiB
PHP
Raw Permalink 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\Controllers;
use App\Models\Historique;
use App\Models\Products;
use App\Models\Stores;
class HistoriqueController extends AdminController
{
private $pageTitle = 'Historique des Mouvements';
public function __construct()
{
parent::__construct();
helper(['form', 'url']);
}
/**
* Page principale de l'historique
*/
public function index()
{
$this->verifyRole('viewCom');
$storesModel = new Stores();
$data['page_title'] = $this->pageTitle;
$data['stores'] = $storesModel->getActiveStore();
return $this->render_template('historique/index', $data);
}
/**
* Récupérer les données pour DataTables
*/
public function fetchHistoriqueData()
{
$historiqueModel = new Historique();
// Récupération des paramètres envoyés par DataTables
$draw = intval($this->request->getGet('draw'));
$start = intval($this->request->getGet('start'));
$length = intval($this->request->getGet('length'));
// Filtres personnalisés
$filters = [
'action' => $this->request->getGet('action'),
'store_name' => $this->request->getGet('store_name'),
'product_name'=> $this->request->getGet('product'),
'sku' => $this->request->getGet('sku'),
'date_from' => $this->request->getGet('date_from'),
'date_to' => $this->request->getGet('date_to')
];
// 1⃣ Nombre total de lignes (sans filtre)
$recordsTotal = $historiqueModel->countAll();
// 2⃣ Récupération des données filtrées
$allDataFiltered = $historiqueModel->getHistoriqueWithFilters($filters);
$recordsFiltered = count($allDataFiltered);
// 3⃣ Pagination
$dataPaginated = array_slice($allDataFiltered, $start, $length);
// 4⃣ Formatage pour DataTables
$data = [];
foreach ($dataPaginated as $row) {
$data[] = [
date('d/m/Y H:i:s', strtotime($row['created_at'])),
$row['product_name'] ?? 'N/A',
$row['sku'] ?? 'N/A',
$row['store_name'] ?? 'N/A',
$this->getActionBadge($row['action']),
$row['description'] ?? ''
];
}
// 5⃣ Retour JSON
return $this->response->setJSON([
'draw' => $draw,
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $data
]);
}
/**
* Historique spécifique d'un produit
*/
public function product($productId)
{
$this->verifyRole('viewCom');
$historiqueModel = new Historique();
$productsModel = new Products();
$product = $productsModel->find($productId);
if (!$product) {
session()->setFlashdata('error', 'Produit introuvable');
return redirect()->to('/historique');
}
$data['page_title'] = 'Historique - ' . $product['name'];
$data['product'] = $product;
$data['historique'] = $historiqueModel->getHistoriqueByProduct($productId);
return $this->render_template('historique/product', $data);
}
/**
* Enregistrer un mouvement d'entrée
*/
public function entrer()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(404);
}
$data = $this->request->getJSON(true);
if (!isset($data['product_id']) || !isset($data['store_id'])) {
return $this->response->setJSON([
'success' => false,
'message' => 'Paramètres manquants.'
]);
}
$productsModel = new Products();
$storesModel = new Stores();
$historiqueModel = new Historique();
$product = $productsModel->find($data['product_id']);
$store = $storesModel->find($data['store_id']);
if (!$product || !$store) {
return $this->response->setJSON([
'success' => false,
'message' => 'Produit ou magasin introuvable.'
]);
}
// Mettre à jour le produit
$updateData = [
'store_id' => $data['store_id'],
'availability' => 1
];
if ($productsModel->update($data['product_id'], $updateData)) {
// Enregistrer dans l'historique
$description = "Produit ajouté au magasin " . $store['name'] . " depuis TOUS";
$historiqueModel->logMovement(
'products',
'ENTRER',
$product['id'],
$product['name'],
$product['sku'],
$store['name'],
$description
);
return $this->response->setJSON(['success' => true]);
}
return $this->response->setJSON([
'success' => false,
'message' => 'Erreur lors de la mise à jour.'
]);
}
/**
* Enregistrer un mouvement de sortie
*/
public function sortie()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(404);
}
$data = $this->request->getJSON(true);
if (!isset($data['product_id'])) {
return $this->response->setJSON([
'success' => false,
'message' => 'ID produit manquant.'
]);
}
$productsModel = new Products();
$storesModel = new Stores();
$historiqueModel = new Historique();
$product = $productsModel->find($data['product_id']);
if (!$product) {
return $this->response->setJSON([
'success' => false,
'message' => 'Produit introuvable.'
]);
}
$currentStore = $storesModel->find($product['store_id']);
$currentStoreName = $currentStore ? $currentStore['name'] : 'TOUS';
// Mettre à jour le produit (retirer du magasin)
$updateData = [
'store_id' => 0, // TOUS
'availability' => 0 // Non disponible
];
if ($productsModel->update($data['product_id'], $updateData)) {
// Enregistrer dans l'historique
$description = "Produit retiré du magasin " . $currentStoreName . " vers TOUS";
$historiqueModel->logMovement(
'products',
'SORTIE',
$product['id'],
$product['name'],
$product['sku'],
'TOUS',
$description
);
return $this->response->setJSON(['success' => true]);
}
return $this->response->setJSON([
'success' => false,
'message' => 'Erreur lors de la mise à jour.'
]);
}
/**
* Exporter l'historique
*/
public function export()
{
$this->verifyRole('viewCom');
$historiqueModel = new Historique();
$filters = [
'action' => $this->request->getGet('action'),
'store_name' => $this->request->getGet('store_name'), // Utilise le nom du magasin
'product_name' => $this->request->getGet('product'),
'sku' => $this->request->getGet('sku'),
'date_from' => $this->request->getGet('date_from'),
'date_to' => $this->request->getGet('date_to')
];
$csvData = $historiqueModel->exportHistorique($filters);
$filename = 'historique_' . date('Y-m-d_H-i-s') . '.csv';
return $this->response
->setHeader('Content-Type', 'text/csv')
->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
->setBody($csvData);
}
/**
* Nettoyer l'historique ancien
*/
public function clean()
{
$this->verifyRole('updateCom');
$days = $this->request->getPost('days') ?? 365;
$historiqueModel = new Historique();
$deleted = $historiqueModel->cleanOldHistory($days);
if ($deleted) {
session()->setFlashdata('success', "Historique nettoyé ($deleted entrées supprimées)");
} else {
session()->setFlashdata('info', 'Aucune entrée à supprimer');
}
return redirect()->to('/historique');
}
/**
* Obtenir le badge HTML pour une action
*/
private function getActionBadge($action)
{
$badges = [
'CREATE' => '<span class="label label-success">Création</span>',
'UPDATE' => '<span class="label label-warning">Modification</span>',
'DELETE' => '<span class="label label-danger">Suppression</span>',
'ASSIGN_STORE' => '<span class="label label-info">Assignation</span>',
'ENTRER' => '<span class="label label-primary">Entrée</span>',
'SORTIE' => '<span class="label label-default">Sortie</span>',
'IMPORT' => '<span class="label label-success"><i class="fa fa-upload"></i> Import</span>'
];
return $badges[$action] ?? '<span class="label label-secondary">' . $action . '</span>';
}
/**
* API pour obtenir les statistiques
*/
public function getStats()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(404);
}
$historiqueModel = new Historique();
$stats = $historiqueModel->getHistoriqueStats();
return $this->response->setJSON($stats);
}
}