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.
315 lines
9.8 KiB
315 lines
9.8 KiB
<?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);
|
|
}
|
|
}
|
|
|