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.
 
 
 
 
 
 

613 lines
24 KiB

<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Gérer les
<small>Motos</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Accueil</a></li>
<li class="active">Motos</li>
</ol>
</section>
<!-- Main content -->
<section class="content">
<!-- Small boxes (Stat box) -->
<div class="row">
<div class="col-md-12 col-xs-12">
<div id="messages"></div>
<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<?php echo session()->getFlashdata('success'); ?>
</div>
<?php elseif (session()->getFlashdata('error')): ?>
<div class="alert alert-error alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<?php echo session()->getFlashdata('error'); ?>
</div>
<?php endif; ?>
<?php if (in_array('createProduct', $user_permission)): ?>
<div class="d-flex gap-2 mb-3 align-items-center">
<a href="<?= base_url('products/create') ?>" class="btn btn-primary">
<i class="fa fa-plus"></i> Ajouter une moto
</a>
<button class="btn btn-secondary" id="openModalBtn">
<i class="fa fa-qrcode"></i>
</button>
<button
type="button"
class="btn btn-success"
id="importExcelBtn"
onclick="document.getElementById('excel_product').click()"
>
<i class="far fa-file-excel"></i> Importer un fichier
</button>
<form
action="<?= base_url('products/importExcel') ?>"
method="post"
enctype="multipart/form-data"
class="d-inline-flex align-items-center"
>
<input
type="file"
name="excel_product"
id="excel_product"
accept=".xls,.xlsx"
hidden
required
style="display: none;"
/>
</form>
</div>
<?php endif; ?>
<script>
document.addEventListener('DOMContentLoaded', function () {
const inputFile = document.getElementById('excel_product');
const form = inputFile ? inputFile.form : null;
if (inputFile && form) {
inputFile.addEventListener('change', function () {
if (this.files.length) {
const formData = new FormData(form);
$.ajax({
url: "<?= base_url('products/createByExcel') ?>",
type: 'post',
data: formData,
contentType: false,
processData: false,
dataType: 'json',
success: function(response) {
if (typeof manageTable !== 'undefined') {
manageTable.ajax.reload(null, false);
}
if (response.success === true) {
$("#messages").html(
'<div class="alert alert-success alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-ok-sign"></span></strong> ' +
response.messages +
'</div>'
);
} else {
if (response.messages instanceof Object) {
$.each(response.messages, function(index, value) {
var id = $("#" + index);
id.closest('.form-group')
.removeClass('has-error has-success')
.addClass(value.length > 0 ? 'has-error' : 'has-success');
id.after(value);
});
} else {
$("#messages").html(
'<div class="alert alert-danger alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' +
response.messages +
'</div>'
);
}
}
},
error: function(xhr, status, error) {
console.error("Erreur AJAX : ", error);
$("#messages").html(
'<div class="alert alert-danger alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' +
'Erreur lors de l\'upload du fichier' +
'</div>'
);
}
});
}
});
}
});
</script>
<div class="box">
<div class="box-header">
<h3 class="box-title">Gérer les produits</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="manageTable" class="table table-bordered table-striped">
<thead>
<tr>
<th>Image</th>
<th>UGS</th>
<th>Nom de produit</th>
<th>Prix</th>
<th>Magasin</th>
<th>Disponibilité</th>
<!-- ✅ MODIFICATION PRINCIPALE : Toujours afficher la colonne Action -->
<th>Action</th>
</tr>
</thead>
</table>
</div>
<!-- /.box-body -->
</div>
<!-- /.box -->
</div>
<!-- col-md-12 -->
</div>
<!-- /.row -->
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<?php if (in_array('deleteProduct', $user_permission)): ?>
<!-- remove brand modal -->
<div class="modal fade" tabindex="-1" role="dialog" id="removeModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Supprimer le produit</h4>
</div>
<form role="form" action="<?php echo base_url('products/remove') ?>" method="post" id="removeForm">
<div class="modal-body">
<p>Voulez-vous vraiment supprimer ce produit ?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
<button type="submit" class="btn btn-primary">Oui</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<?php endif; ?>
<div class="modal fade" id="assignStoreModal" tabindex="-1" role="dialog" aria-labelledby="assignStoreModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="assignStoreModalLabel">Assigner une moto à un Point de vente</h4>
</div>
<!-- Modal Body -->
<div class="modal-body">
<p>Point de vente actuel : <span class="badge badge-primary" id="current_magasin"></span></p>
<p>Veuillez sélectionner un magasin dans la liste ci-dessous :</p>
<!-- Store List -->
<div class="list-group">
<?php foreach ($stores as $store): ?>
<div class="list-group-item d-flex justify-content-between align-items-center">
<!-- Store Name -->
<span><?php echo $store['name']; ?></span>
<!-- Action Button -->
<button class="btn btn-primary btn-sm assign-store-btn"
style="border-radius: 15px;"
data-products-id=""
data-store-id="<?php echo $store['id']; ?>">
Assigner
</button>
</div>
<?php endforeach; ?>
</div>
</div>
<!-- Modal Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
<!-- QR Code Multiple Modal -->
<div class="modal fade" tabindex="-1" role="dialog" id="qrMultipleModal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Ajouter plusieur code QR</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="moto">Motos</label>
<select class="form-control select_group" id="moto" name="moto[]" multiple="multiple" style="display: block;width: 100%;">
<?php foreach ($motos as $k => $v): ?>
<option value="<?php echo $v['id'] ?>"><?php echo $v['name'] ?></option>
<?php endforeach ?>
</select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="prints">Imprimer</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<div id="qrcode" style="display: none;"></div>
<div id="qrContainer" style="display: none;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script type="text/javascript">
var manageTable;
var base_url = "<?php echo base_url(); ?>";
$(".select_group").select2();
$(document).ready(function() {
$("#mainProductNav").addClass('active');
$("#manageProductNav").addClass('active');
// Configuration DataTables en français
$.extend(true, $.fn.dataTable.defaults, {
language: {
sProcessing: "Traitement en cours...",
sSearch: "Rechercher&nbsp;:",
sLengthMenu: "Afficher _MENU_ &eacute;l&eacute;ments",
sInfo: "Affichage de l'&eacute;lement _START_ &agrave; _END_ sur _TOTAL_ &eacute;l&eacute;ments",
sInfoEmpty: "Affichage de l'&eacute;lement 0 &agrave; 0 sur 0 &eacute;l&eacute;ment",
sInfoFiltered: "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)",
sLoadingRecords: "Chargement en cours...",
sZeroRecords: "Aucun &eacute;l&eacute;ment &agrave; afficher",
sEmptyTable: "Aucune donn&eacute;e disponible dans le tableau",
oPaginate: {
sFirst: "Premier",
sPrevious: "Pr&eacute;c&eacute;dent",
sNext: "Suivant",
sLast: "Dernier"
},
oAria: {
sSortAscending: ": activer pour trier la colonne par ordre croissant",
sSortDescending: ": activer pour trier la colonne par ordre d&eacute;croissant"
}
}
});
// Initialisation DataTable
manageTable = $('#manageTable').DataTable({
'ajax': base_url + 'products/fetchProductData',
'order': [],
'columns': [
{
data: 0, // Colonne Image
render: function(data) {
return data; // Affiche le HTML brut (déjà formaté en PHP)
},
orderable: false // Désactive le tri sur cette colonne
},
{ data: 1 }, // SKU
{ data: 2 }, // Nom
{
data: 3, // Prix
render: function(data, type, row) {
if (type === 'display') {
// Format: "1 900 000 Ar"
return new Intl.NumberFormat('fr-FR').format(data) + ' Ar';
}
return data; // Valeur non formatée pour le tri/filtre
}
},
{ data: 4 }, // Magasin
{ data: 5 }, // Disponibilité
{ data: 6 } // Actions - ✅ Toujours présent maintenant
],
'columnDefs': [{
targets: 3,
className: 'text-right'
}]
});
// CORRECTION: Utilisation de la délégation d'événements pour les boutons
// Boutons d'assignation de magasin
$(document).on('click', '.assign-store-btn', function() {
const productId = $(this).data('products-id');
const storeId = $(this).data('store-id');
console.log('Product ID:', productId, 'Store ID:', storeId); // Debug
if (confirm('Êtes-vous sûr de vouloir assigner cette moto à ce magasin ?')) {
$.ajax({
url: base_url + 'products/assign_store',
type: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
data: JSON.stringify({
product_id: productId,
store_id: storeId
}),
dataType: 'json',
success: function(data) {
$("#assignStoreModal").modal("hide");
if (data.success) {
$("#messages").html(
'<div class="alert alert-success alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-ok-sign"></span></strong> ' +
(data.message || 'Moto assignée avec succès !') +
'</div>'
);
// Recharger seulement le DataTable au lieu de la page
manageTable.ajax.reload(null, false);
} else {
$("#messages").html(
'<div class="alert alert-danger alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' +
(data.message || 'Une erreur est survenue.') +
'</div>'
);
}
},
error: function(xhr, status, error) {
console.error('Error assigning store:', error);
$("#assignStoreModal").modal("hide");
$("#messages").html(
'<div class="alert alert-danger alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' +
'Erreur de connexion lors de l\'assignation.' +
'</div>'
);
}
});
}
});
// Boutons d'ouverture du modal d'assignation
$(document).on('click', '.assignbtn', function() {
const storeName = $(this).data('magasin');
const productId = $(this).data('products-id');
console.log('Opening modal for product:', productId, 'Current store:', storeName); // Debug
$('#current_magasin').text(storeName);
$('.assign-store-btn').attr('data-products-id', productId);
});
});
// Fonction QR Code PDF pour un seul produit
async function generateQrPdf(productId) {
const productUrl = `https://motorbike.c4m.mg/ventes/show/${productId}`;
// Generate QR Code
const qrDiv = document.getElementById("qrcode");
qrDiv.innerHTML = ""; // Clear previous QR code
new QRCode(qrDiv, {
text: productUrl,
width: 300, // Increased size for better resolution
height: 300
});
// Wait for QR code to render (small delay)
await new Promise(resolve => setTimeout(resolve, 500));
// Convert QR Code to Image
const qrCanvas = qrDiv.querySelector("canvas");
const qrImage = qrCanvas.toDataURL("image/png", 1.0); // Max quality
// Create PDF
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({
orientation: "portrait",
unit: "mm",
format: "a6" // Set to A6 size
});
pdf.addImage(qrImage, "PNG", 25, 40, 55, 55); // Adjust size & position
// Download PDF
pdf.save(`QRCode_Product_${productId}.pdf`);
}
// Function to show the QR multiple modal
function showQrMultipleModal() {
$('#qrMultipleModal').modal('show');
}
// Event listener pour le bouton d'ouverture du modal QR
document.addEventListener("DOMContentLoaded", function() {
const openModalBtn = document.getElementById("openModalBtn");
if (openModalBtn) {
openModalBtn.addEventListener("click", function() {
showQrMultipleModal();
});
}
});
// Génération PDF pour multiples QR codes
const moto = document.getElementById('moto');
const buttontest = document.getElementById('prints')
let arrayvalue = [];
if (buttontest) {
buttontest.addEventListener('click', async function() {
arrayvalue = Array.from(moto.selectedOptions).map(option => ({
id: option.value, // Value from <option value="...">
name: option.text // Label from <option>...</option>
}));
console.log(arrayvalue); // Debugging: Check selected values in console
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const qrSize = 50; // QR Code size
const marginX = 20; // Left margin
const marginY = 20; // Top margin
const spacingX = 65; // Space between QR codes horizontally
const spacingY = 80; // Space between QR codes vertically
let x = marginX;
let y = marginY;
let count = 0;
for (let i = 0; i < arrayvalue.length; i++) {
let moto = arrayvalue[i];
// Create a hidden div for the QR Code
let qrDiv = document.createElement("div");
document.getElementById("qrContainer").appendChild(qrDiv);
// Generate QR Code
let qrCode = new QRCode(qrDiv, {
text: `https://motorbike.c4m.mg/ventes/show/${moto.id}`,
width: qrSize,
height: qrSize
});
// Wait for QR code to render
await new Promise(resolve => setTimeout(resolve, 500));
// Convert QR code to Base64 Image
let canvas = qrDiv.querySelector("canvas");
if (!canvas) {
alert("Error: QR Code not generated!");
return;
}
let qrDataUrl = canvas.toDataURL("image/png");
// Draw text (Moto Name)
doc.text(moto.name, x + 5, y - 5);
// Draw QR Code
doc.addImage(qrDataUrl, "PNG", x, y, qrSize, qrSize);
// Remove QR code from the DOM
qrDiv.remove();
// Update position for next QR code
x += spacingX;
count++;
// If 3 QR codes in a row, move to the next row
if (count % 3 === 0) {
x = marginX; // Reset X position
y += spacingY; // Move to next row
}
// If 9 QR codes per page, add a new page
if (count % 9 === 0 && i !== arrayvalue.length - 1) {
doc.addPage();
x = marginX; // Reset X position
y = marginY; // Reset Y position
}
}
// Save PDF
doc.save(`QRCode_Motos.pdf`);
$("#qrMultipleModal").modal('hide');
});
}
// Remove functions avec délégation d'événements
function removeFunc(id) {
if (id) {
$("#removeForm").off('submit').on('submit', function(e) {
e.preventDefault();
var form = $(this);
$(".text-danger").remove();
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: { product_id: id },
dataType: 'json',
success: function(response) {
manageTable.ajax.reload(null, false);
if (response.success === true) {
$("#messages").html(
'<div class="alert alert-success alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-ok-sign"></span></strong> ' + response.messages +
'</div>'
);
$("#removeModal").modal('hide');
} else {
$("#messages").html(
'<div class="alert alert-warning alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' + response.messages +
'</div>'
);
}
},
error: function(xhr, status, error) {
console.error('Error removing product:', error);
$("#messages").html(
'<div class="alert alert-danger alert-dismissible" role="alert">' +
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
'<span aria-hidden="true">&times;</span>' +
'</button>' +
'<strong><span class="glyphicon glyphicon-exclamation-sign"></span></strong> ' +
'Erreur lors de la suppression.' +
'</div>'
);
}
});
});
}
}
</script>