// achat.
js - Version avec impression et quantité en input text
(function() {
'use strict';
if ([Link] === true) {
[Link]("🚫 [Link] déjà chargé - Arrêt immédiat");
return;
}
[Link] = true;
[Link]("🎯 [Link] - Chargement initial");
const ACHAT_CONFIG = {
dernierClick: 0,
requeteEnCours: false,
API_BASE_URL: "[Link]
pageCourante: 1,
produitsParPage: 10,
totalProduits: 0,
totalPages: 0,
achatsDuJour: [] // Stocke les achats du jour
};
function getMode() {
if (typeof eel !== 'undefined' && typeof eel.get_produits ===
'function') {
[Link]("🔧 Mode EEL détecté");
return 'EEL';
} else {
[Link]("🌐 Mode API directe détecté");
return 'API';
}
}
function safeJsonParse(responseText) {
try {
const cleanedText = [Link](/<!--.*?-->/g,
'').trim();
return [Link](cleanedText);
} catch (error) {
[Link]("❌ Erreur parsing JSON:", error);
[Link]("📄 Texte reçu:", responseText);
throw new Error("Réponse invalide du serveur");
}
}
async function safeFetch(url, options = {}) {
try {
[Link](`📡 Requête API: ${url}`);
[Link](`📦 Données envoyées:`, [Link] ?
[Link]([Link]) : 'Aucune');
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...[Link]
}
});
[Link](`📊 Statut HTTP: ${[Link]}
${[Link]}`);
if (![Link]) {
let errorMessage = `Erreur HTTP: ${[Link]}
${[Link]}`;
try {
const errorText = await [Link]();
[Link]("📄 Réponse d'erreur:", errorText);
const errorData = safeJsonParse(errorText);
errorMessage = [Link] || [Link] ||
errorMessage;
} catch (e) {
// Ignorer si on ne peut pas parser l'erreur
}
throw new Error(errorMessage);
}
const text = await [Link]();
const data = safeJsonParse(text);
return data;
} catch (error) {
[Link]('❌ Erreur requête API:', error);
throw error;
}
}
function initAchat() {
[Link]("🚀 INIT ACHAT - Début de l'initialisation");
const tbody = [Link]('produits-body');
const table = [Link]('achat-table');
if (!tbody || !table) {
[Link]("❌ Éléments DOM manquants");
return;
}
[Link]("✅ Éléments DOM trouvés");
loadProduits(1);
setupEvents();
[Link]("✅ Module achat initialisé avec succès");
}
// Mettre à jour l'affichage des achats du jour
function updateAchatsDuJourDisplay() {
const container = [Link]('achats-jour-list');
const totalArticles = [Link]('total-articles');
const totalAchats = [Link]('total-achats-jour');
const montantFinal = [Link]('montant-final');
if (!container) return;
if (ACHAT_CONFIG.[Link] === 0) {
[Link] = `
<div class="empty-state">
<div class="empty-icon">📝</div>
<p>Panier vide</p>
<small>Les produits validés apparaîtront ici</small>
</div>
`;
[Link] = '0';
[Link] = '0 Ar';
[Link] = '0 Ar';
return;
}
let totalGeneral = 0;
let totalItems = 0;
let html = '';
ACHAT_CONFIG.[Link]((achat, index) => {
const total = [Link] * [Link];
totalGeneral += total;
totalItems += [Link];
// Formater la date de péremption
const datePeremption = [Link] ?
new Date([Link]).toLocaleDateString('fr-FR') :
'Non définie';
// Vérifier si la date de péremption est proche (moins de 7 jours)
const aujourdhui = new Date();
const datePeremp = new Date([Link]);
const joursRestants = [Link]((datePeremp - aujourdhui) / (1000
* 60 * 60 * 24));
const isPeremptionProche = [Link] && joursRestants
<= 7 && joursRestants >= 0;
const isPerime = [Link] && joursRestants < 0;
let peremptionClass = '';
if (isPerime) peremptionClass = 'peremption-warning';
else if (isPeremptionProche) peremptionClass = 'peremption-alert';
html += `
<div class="purchase-item">
<div class="purchase-header">
<div>
<div class="purchase-
name">${[Link]}</div>
<div class="purchase-
code">${[Link]}</div>
</div>
<button class="purchase-delete"
onclick="supprimerAchatDuJour(${index})" title="Supprimer">
❌
</button>
</div>
<div class="purchase-details">
<div class="purchase-quantity">
<span>Quantité:</span>
<span>${[Link]}</span>
</div>
<div class="purchase-price">
<span>Prix unitaire:</span>
<span>${formatPrix([Link])}</span>
</div>
<div class="purchase-total">
<span>Sous-total:</span>
<span>${formatPrix(total)}</span>
</div>
<div class="purchase-dates">
<span>Péremption:</span>
<span
class="${peremptionClass}">${datePeremption}</span>
</div>
</div>
</div>
`;
});
[Link] = html;
[Link] = totalItems;
[Link] = formatPrix(totalGeneral);
[Link] = formatPrix(totalGeneral);
}
// Ajouter un achat à la liste du jour
function ajouterAchatDuJour(achatData) {
const achat = {
id: [Link](), // ID unique
idProduit: [Link],
nomProduit: [Link],
quantite: [Link],
prixUnitaire: [Link],
dateAchat: [Link],
datePeremption: [Link] || null
};
ACHAT_CONFIG.[Link](achat);
updateAchatsDuJourDisplay();
showToast(`✅ Achat ajouté au panier`, 'success');
}
// Supprimer un achat de la liste du jour
function supprimerAchatDuJour(index) {
if (index >= 0 && index < ACHAT_CONFIG.[Link]) {
ACHAT_CONFIG.[Link](index, 1);
updateAchatsDuJourDisplay();
showToast('🗑️ Achat supprimé du panier', 'info');
}
}
// Vider tous les achats du jour
function viderAchatsDuJour() {
if (ACHAT_CONFIG.[Link] === 0) {
showToast('ℹ️ Le panier est déjà vide', 'info');
return;
}
if (confirm('Voulez-vous vraiment vider tout le panier ?')) {
ACHAT_CONFIG.achatsDuJour = [];
updateAchatsDuJourDisplay();
showToast('🗑️ Panier vidé', 'info');
}
}
// Imprimer la liste des achats
function imprimerAchats() {
if (ACHAT_CONFIG.[Link] === 0) {
showToast('ℹ️ Aucun achat à imprimer', 'info');
return;
}
const dateJour = new Date().toLocaleDateString('fr-FR');
let html = `
<!DOCTYPE html>
<html>
<head>
<title>Liste des Achats - ${dateJour}</title>
<style>
body { font-family: Arial, sans-serif; margin: 15px; font-
size: 12px; }
.header { text-align: center; margin-bottom: 20px; border-
bottom: 2px solid #333; padding-bottom: 8px; }
.header h1 { margin: 0; color: #2c3e50; font-size: 16px; }
.date { color: #7f8c8d; font-size: 11px; }
table { width: 100%; border-collapse: collapse; margin:
15px 0; font-size: 10px; }
th { background: #34495e; color: white; padding: 8px;
text-align: left; }
td { padding: 6px; border-bottom: 1px solid #ddd; }
.total { font-weight: bold; font-size: 12px; text-align:
right; margin-top: 15px; padding-top: 8px; border-top: 2px solid #333; }
.peremption-proche { background: #fff3cd; }
.perime { background: #f8d7da; }
.footer { margin-top: 20px; text-align: center; color:
#7f8c8d; font-size: 10px; }
</style>
</head>
<body>
<div class="header">
<h1>🛒 Liste des Achats</h1>
<div class="date">Date: ${dateJour}</div>
</div>
<table>
<thead>
<tr>
<th>Produit</th>
<th>Code</th>
<th>Quantité</th>
<th>Prix Unitaire</th>
<th>Total</th>
<th>Date Péremption</th>
</tr>
</thead>
<tbody>
`;
let totalGeneral = 0;
ACHAT_CONFIG.[Link](achat => {
const total = [Link] * [Link];
totalGeneral += total;
const aujourdhui = new Date();
const datePeremp = new Date([Link]);
const joursRestants = [Link]((datePeremp - aujourdhui) / (1000
* 60 * 60 * 24));
const isPeremptionProche = [Link] && joursRestants
<= 7 && joursRestants >= 0;
const isPerime = [Link] && joursRestants < 0;
const classePeremption = isPerime ? 'perime' : (isPeremptionProche
? 'peremption-proche' : '');
html += `
<tr class="${classePeremption}">
<td>${[Link]}</td>
<td>${[Link]}</td>
<td>${[Link]}</td>
<td>${formatPrix([Link])}</td>
<td>${formatPrix(total)}</td>
<td>${[Link] ? new
Date([Link]).toLocaleDateString('fr-FR') : 'Non définie'}</td>
</tr>
`;
});
html += `
</tbody>
</table>
<div class="total">
TOTAL GÉNÉRAL: ${formatPrix(totalGeneral)}
</div>
<div class="footer">
Généré le ${new Date().toLocaleString('fr-FR')} |
${ACHAT_CONFIG.[Link]} articles
</div>
</body>
</html>
`;
const printWindow = [Link]('', '_blank');
[Link](html);
[Link]();
[Link] = function() {
[Link]();
[Link] = function() {
[Link]();
};
};
showToast('🖨️ Impression en cours...', 'info');
}
// Exposer les fonctions globalement
[Link] = supprimerAchatDuJour;
[Link] = imprimerAchats;
[Link] = viderAchatsDuJour;
async function loadProduits(page = 1) {
[Link](`📦 CHARGEMENT PRODUITS - Page ${page}`);
const tbody = [Link]('produits-body');
if (!tbody) return;
showLoadingMessage();
try {
const mode = getMode();
[Link](`📡 Chargement en mode: ${mode}`);
let produits = [];
if (mode === 'EEL') {
const result = await eel.get_produits()();
if (result && [Link]) {
produits = [Link];
ACHAT_CONFIG.totalProduits = [Link];
ACHAT_CONFIG.totalPages = [Link]([Link] /
ACHAT_CONFIG.produitsParPage);
} else {
throw new Error(result?.message || 'Erreur EEL');
}
} else {
const endpoint =
`${ACHAT_CONFIG.API_BASE_URL}/achats/produits?page=${page}&limit=${ACHAT_CONFI
[Link]}`;
try {
const data = await safeFetch(endpoint);
produits = [Link]?.produits || [];
ACHAT_CONFIG.totalProduits =
[Link]?.pagination?.total_items || [Link];
ACHAT_CONFIG.totalPages =
[Link]?.pagination?.total_pages || [Link](ACHAT_CONFIG.totalProduits /
ACHAT_CONFIG.produitsParPage);
[Link](`✅ Pagination: ${ACHAT_CONFIG.totalProduits}
produits, ${ACHAT_CONFIG.totalPages} pages`);
} catch (error) {
[Link]('❌ Endpoint achats/produits échoue,
tentative avec produits:', error);
const data = await
safeFetch(`${ACHAT_CONFIG.API_BASE_URL}/produits?page=${page}&limit=${ACHAT_CO
[Link]}`);
produits = [Link] || [Link]?.produits || [];
ACHAT_CONFIG.totalProduits = [Link] ||
[Link]?.pagination?.total_items || [Link];
ACHAT_CONFIG.totalPages = [Link] ||
[Link]?.pagination?.total_pages || [Link](ACHAT_CONFIG.totalProduits /
ACHAT_CONFIG.produitsParPage);
}
}
[Link](`✅ ${[Link]} produits récupérés`);
if ([Link] === 0 && page === 1) {
produits = getDemoProduits();
ACHAT_CONFIG.totalProduits = [Link];
ACHAT_CONFIG.totalPages = [Link](ACHAT_CONFIG.totalProduits
/ ACHAT_CONFIG.produitsParPage);
}
ACHAT_CONFIG.pageCourante = page;
displayProduits(produits);
updatePaginationControls();
showToast(`✅ ${[Link]} produits chargés (page
${page}/${ACHAT_CONFIG.totalPages})`, 'success');
} catch (error) {
[Link]('❌ Erreur lors du chargement:', error);
if (page === 1) {
const produitsDemo = getDemoProduits();
ACHAT_CONFIG.totalProduits = [Link];
ACHAT_CONFIG.totalPages = [Link](ACHAT_CONFIG.totalProduits
/ ACHAT_CONFIG.produitsParPage);
displayProduits(produitsDemo);
updatePaginationControls();
showToast("⚠️ Mode démonstration - Données locales", "info");
} else {
showToast("❌ Erreur lors du chargement de la page", "error");
}
}
}
function updatePaginationControls() {
const paginationContainer = [Link]('.pagination');
if (!paginationContainer) return;
const firstBtn = [Link]('.first');
const prevBtn = [Link]('.prev');
const nextBtn = [Link]('.next');
const lastBtn = [Link]('.last');
[Link]('disabled', ACHAT_CONFIG.pageCourante <= 1);
[Link]('disabled', ACHAT_CONFIG.pageCourante <= 1);
[Link]('disabled', ACHAT_CONFIG.pageCourante >=
ACHAT_CONFIG.totalPages);
[Link]('disabled', ACHAT_CONFIG.pageCourante >=
ACHAT_CONFIG.totalPages);
const pageIndicator = [Link]('.page-
indicator');
if (pageIndicator) {
[Link] = `Page ${ACHAT_CONFIG.pageCourante} /
${ACHAT_CONFIG.totalPages}`;
}
const totalItems = [Link]('.total-items');
if (totalItems) {
[Link] = `${ACHAT_CONFIG.totalProduits} produits`;
}
updatePageNumbers();
}
function updatePageNumbers() {
const paginationNumbers = [Link]('.pagination-
numbers');
if (!paginationNumbers) return;
[Link] = '';
const currentPage = ACHAT_CONFIG.pageCourante;
const totalPages = ACHAT_CONFIG.totalPages;
if (totalPages <= 1) {
const pageNumber = [Link]('span');
[Link] = 'page-number active';
[Link] = '1';
[Link](pageNumber);
return;
}
let startPage = [Link](1, currentPage - 2);
let endPage = [Link](totalPages, currentPage + 2);
if (currentPage <= 3) {
endPage = [Link](5, totalPages);
}
if (currentPage >= totalPages - 2) {
startPage = [Link](1, totalPages - 4);
}
if (startPage > 1) {
const firstPage = [Link]('span');
[Link] = 'page-number';
[Link] = '1';
[Link]('click', () => loadProduits(1));
[Link](firstPage);
if (startPage > 2) {
const ellipsis = [Link]('span');
[Link] = 'page-number ellipsis';
[Link] = '...';
[Link](ellipsis);
}
}
for (let i = startPage; i <= endPage; i++) {
const pageNumber = [Link]('span');
[Link] = `page-number ${i === currentPage ? 'active'
: ''}`;
[Link] = i;
if (i !== currentPage) {
[Link]('click', () => loadProduits(i));
}
[Link](pageNumber);
}
if (endPage < totalPages) {
if (endPage < totalPages - 1) {
const ellipsis = [Link]('span');
[Link] = 'page-number ellipsis';
[Link] = '...';
[Link](ellipsis);
}
const lastPage = [Link]('span');
[Link] = 'page-number';
[Link] = totalPages;
[Link]('click', () =>
loadProduits(totalPages));
[Link](lastPage);
}
}
function getDemoProduits() {
return [
{idProd: "DEMO001", nom: "Ordinateur Portable", prixUnitaire:
1200000},
{idProd: "DEMO002", nom: "Souris USB", prixUnitaire: 15000},
{idProd: "DEMO003", nom: "Clavier Mécanique", prixUnitaire:
45000},
{idProd: "DEMO004", nom: "Écran 24\"", prixUnitaire: 320000},
{idProd: "DEMO005", nom: "Casque Audio", prixUnitaire: 25000}
];
}
function displayProduits(produits) {
[Link]("🖥️ AFFICHAGE PRODUITS - Début");
const tbody = [Link]('produits-body');
if (!tbody) return;
[Link] = '';
if ([Link] === 0) {
[Link] = `
<tr>
<td colspan="9" class="text-center">
<div style="padding: 40px; color: #666;">
📭 Aucun produit disponible
</div>
</td>
</tr>
`;
return;
}
[Link](`📊 Création de ${[Link]} lignes de produits`);
[Link](produit => {
const row = [Link]('tr');
[Link]('data-id', [Link]);
// Date de péremption par défaut (1 mois à partir d'aujourd'hui)
const datePeremptionDefaut = new Date();
[Link]([Link]() +
1);
const datePeremptionStr =
[Link]().split('T')[0];
[Link] = `
<td><input type="checkbox" class="select-produit"></td>
<td class="code-prod">${[Link]}</td>
<td class="nom-prod">${[Link]}</td>
<td class="prix-unit">${formatPrix([Link])}
Ar</td>
<td>
<input type="text" class="quantite-input"
placeholder="Quantité" value="1"
disabled>
</td>
<td class="total-ligne">${formatPrix([Link])}
Ar</td>
<td>
<input type="date" class="date-input"
value="${new Date().toISOString().split('T')[0]}">
</td>
<td>
<input type="date" class="date-peremption-input"
value="${datePeremptionStr}" title="Date de
péremption">
</td>
<td>
<button class="btn-save" disabled>💾 Valider</button>
</td>
`;
[Link](row);
});
[Link]("✅ Produits affichés dans le tableau");
updateTotals();
}
function setupEvents() {
[Link]("🔧 SETUP EVENTS - Début");
// Sélection globale
const selectAll = [Link]('select-all');
if (selectAll) {
[Link]('change', function(e) {
const isChecked = [Link];
const checkboxes = [Link]('.select-
produit');
const inputs = [Link]('.quantite-input');
const buttons = [Link]('.btn-save');
[Link](cb => [Link] = isChecked);
[Link](input => [Link] = !isChecked);
[Link](btn => [Link] = !isChecked);
updateTotals();
});
}
// Événements de changement
[Link]('change', function(e) {
if ([Link]('select-produit')) {
const row = [Link]('tr');
const input = [Link]('.quantite-input');
const button = [Link]('.btn-save');
[Link] = ![Link];
[Link] = ![Link];
if ([Link]) {
[Link]();
}
updateTotals();
}
if ([Link]('quantite-input')) {
updateRowTotal([Link]('tr'));
updateTotals();
}
});
// Événements d'input pour la quantité (input text)
[Link]('input', function(e) {
if ([Link]('quantite-input')) {
// Valider et formater l'entrée
const input = [Link];
let value = [Link](/[^\d,.]/g, ''); // Garder
seulement chiffres, virgules et points
// Remplacer le point par une virgule pour la décimale
française
value = [Link]('.', ',');
// S'assurer qu'il n'y a qu'une virgule décimale
const parts = [Link](',');
if ([Link] > 2) {
value = parts[0] + ',' + [Link](1).join('');
}
[Link] = value;
updateRowTotal([Link]('tr'));
updateTotals();
}
});
// Boutons valider
[Link]('click', function(e) {
if ([Link]('btn-save')) {
handleAchat([Link]);
}
});
// Bouton impression
const imprimerBtn = [Link]('imprimer-achats');
if (imprimerBtn) {
[Link]('click', imprimerAchats);
}
// Bouton vider panier
const viderBtn = [Link]('vider-achats');
if (viderBtn) {
[Link]('click', viderAchatsDuJour);
}
// Recherche
const searchInput = [Link]('search-produit');
if (searchInput) {
[Link]('input', function() {
const searchTerm = [Link]();
const rows = [Link]('#produits-body tr');
[Link](row => {
const nom = [Link]('.nom-
prod').[Link]();
const code = [Link]('.code-
prod').[Link]();
const isVisible = [Link](searchTerm) ||
[Link](searchTerm);
[Link] = isVisible ? '' : 'none';
});
updateTotals();
});
}
// Tri
const sortSelect = [Link]('sort-produit');
if (sortSelect) {
[Link]('change', function() {
[Link]('Tri sélectionné:', [Link]);
});
}
// Événements de pagination
setupPaginationEvents();
[Link]("✅ Événements configurés");
}
function setupPaginationEvents() {
const paginationContainer = [Link]('.pagination');
if (!paginationContainer) return;
const firstBtn = [Link]('.first');
if (firstBtn) {
[Link]('click', function() {
if () {
loadProduits(1);
}
});
}
const prevBtn = [Link]('.prev');
if (prevBtn) {
[Link]('click', function() {
if ( &&
ACHAT_CONFIG.pageCourante > 1) {
loadProduits(ACHAT_CONFIG.pageCourante - 1);
}
});
}
const nextBtn = [Link]('.next');
if (nextBtn) {
[Link]('click', function() {
if ( &&
ACHAT_CONFIG.pageCourante < ACHAT_CONFIG.totalPages) {
loadProduits(ACHAT_CONFIG.pageCourante + 1);
}
});
}
const lastBtn = [Link]('.last');
if (lastBtn) {
[Link]('click', function() {
if () {
loadProduits(ACHAT_CONFIG.totalPages);
}
});
}
}
async function handleAchat(button) {
const maintenant = [Link]();
if ([Link] || ACHAT_CONFIG.requeteEnCours || (maintenant -
ACHAT_CONFIG.dernierClick < 2000)) {
return;
}
ACHAT_CONFIG.dernierClick = maintenant;
ACHAT_CONFIG.requeteEnCours = true;
const row = [Link]('tr');
const idProduit = [Link];
const quantiteInput = [Link]('.quantite-input');
const dateInput = [Link]('.date-input');
const datePeremptionInput = [Link]('.date-peremption-
input');
let quantiteValue = [Link](',', '.');
const quantite = parseFloat(quantiteValue);
const dateAchat = [Link];
const datePeremption = [Link];
const nomProduit = [Link]('.nom-prod').textContent;
const prixUnitaire = parseFloat([Link]('.prix-
unit').[Link](/[^\d,]/g, '').replace(',', '.'));
// Validation
if (!quantite || quantite <= 0 || isNaN(quantite)) {
showToast("❌ Veuillez entrer une quantité valide", 'error');
ACHAT_CONFIG.requeteEnCours = false;
return;
}
if (!dateAchat) {
showToast("❌ Veuillez sélectionner une date d'achat", 'error');
ACHAT_CONFIG.requeteEnCours = false;
return;
}
if (!idProduit) {
showToast("❌ ID produit manquant", 'error');
ACHAT_CONFIG.requeteEnCours = false;
return;
}
// Désactiver le bouton
[Link] = true;
[Link] = '⏳ En cours...';
try {
const mode = getMode();
let result;
// FORMAT EXACT ATTENDU PAR L'API SYMFONY
const achatData = {
idProd: idProduit,
quantite: quantite,
date: dateAchat,
datePeremption: datePeremption || null
};
[Link]('📦 Données envoyées (format API Symfony):',
achatData);
if (mode === 'EEL' && typeof eel.ajouter_achat === 'function') {
result = await eel.ajouter_achat(idProduit, quantite,
dateAchat, datePeremption)();
} else {
result = await
safeFetch(`${ACHAT_CONFIG.API_BASE_URL}/achats`, {
method: 'POST',
body: [Link](achatData)
});
}
if (result && [Link]) {
showToast(`✅ ${[Link] || 'Achat enregistré avec
succès'}`, 'success');
// Ajouter à la liste des achats du jour
ajouterAchatDuJour({
idProd: idProduit,
nomProduit: nomProduit,
quantite: quantite,
prixUnitaire: prixUnitaire,
dateAchat: dateAchat,
datePeremption: datePeremption
});
resetRow(row);
} else {
throw new Error(result?.message || 'Erreur lors de
l\'enregistrement');
}
} catch (error) {
[Link]('❌ Erreur ajout achat:', error);
showToast(`❌ ${[Link]}`, 'error');
[Link] = false;
[Link] = '💾 Valider';
} finally {
ACHAT_CONFIG.requeteEnCours = false;
}
}
function resetRow(row) {
const quantiteInput = [Link]('.quantite-input');
const button = [Link]('.btn-save');
[Link] = '1';
[Link] = true;
[Link]('.select-produit').checked = false;
[Link] = true;
[Link] = '💾 Valider';
updateRowTotal(row);
updateTotals();
}
function updateRowTotal(row) {
const prixText = [Link]('.prix-unit').textContent;
const quantiteValue = [Link]('.quantite-
input').[Link](',', '.');
const prix = parseFloat([Link](/[^\d,]/g, '').replace(',',
'.')) || 0;
const quantite = parseFloat(quantiteValue) || 0;
const total = prix * quantite;
[Link]('.total-ligne').textContent = formatPrix(total);
}
function updateTotals() {
const checkedRows = [Link]('.select-
produit:checked');
let totalCoches = 0;
let totalPrix = 0;
[Link](checkbox => {
const row = [Link]('tr');
if ([Link] !== 'none') {
const prixText = [Link]('.total-
ligne').textContent;
const prix = parseFloat([Link](/[^\d,]/g,
'').replace(',', '.')) || 0;
totalPrix += prix;
totalCoches++;
}
});
[Link]('total-coches').textContent = totalCoches;
[Link]('total-prix').textContent =
formatPrix(totalPrix);
const allCheckboxes = [Link]('.select-produit');
const selectAll = [Link]('select-all');
if (selectAll) {
const visibleCheckboxes = [Link](allCheckboxes).filter(cb => {
const row = [Link]('tr');
return [Link] !== 'none';
});
[Link] = [Link] > 0 &&
[Link](cb => [Link]);
}
}
function formatPrix(montant) {
return parseFloat(montant).toLocaleString('fr-FR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}) + ' Ar';
}
function showLoadingMessage() {
const tbody = [Link]('produits-body');
if (tbody) {
[Link] = `
<tr>
<td colspan="9" class="text-center loading-message">
<div class="loading-spinner"></div>
Chargement des produits...
</td>
</tr>
`;
}
}
function showToast(message, type = 'info') {
let container = [Link]('toast-container');
if (!container) {
container = [Link]('div');
[Link] = 'toast-container';
[Link] = 'position: fixed; top: 20px; right:
20px; z-index: 10000;';
[Link](container);
}
const toast = [Link]('div');
[Link] = message;
[Link] = `
padding: 12px 20px;
border-radius: 8px;
color: white;
margin-bottom: 10px;
font-weight: bold;
background: ${type === 'success' ? '#4CAF50' : type === 'error' ?
'#f44336' : '#2196F3'};
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
border-left: 4px solid ${type === 'success' ? '#45a049' : type ===
'error' ? '#d32f2f' : '#1976d2'};
`;
[Link](toast);
setTimeout(() => {
[Link] = '0';
[Link] = 'opacity 0.5s';
setTimeout(() => {
if ([Link]) {
[Link](toast);
}
}, 500);
}, 4000);
}
// === INITIALISATION ===
[Link]("🔧 INITIALISATION - Début");
function tryInitialization() {
if ([Link] === 'loading') {
[Link]('DOMContentLoaded', initAchat);
} else {
setTimeout(initAchat, 100);
}
}
tryInitialization();
[Link]("✅ [Link] prêt - Attente initialisation");
})();