0% ont trouvé ce document utile (0 vote)
21 vues22 pages

Achat

Le script 'achat.js' gère un système d'achats en ligne, permettant d'ajouter, supprimer et imprimer des achats tout en interagissant avec une API ou un mode EEL. Il inclut des fonctionnalités pour afficher les produits, gérer un panier d'achats du jour, et afficher des alertes en cas d'erreurs ou d'actions réussies. Le code utilise des fonctions asynchrones pour charger les produits et gérer les requêtes API, tout en mettant à jour dynamiquement l'interface utilisateur.

Transféré par

fenoantra akasia
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
21 vues22 pages

Achat

Le script 'achat.js' gère un système d'achats en ligne, permettant d'ajouter, supprimer et imprimer des achats tout en interagissant avec une API ou un mode EEL. Il inclut des fonctionnalités pour afficher les produits, gérer un panier d'achats du jour, et afficher des alertes en cas d'erreurs ou d'actions réussies. Le code utilise des fonctions asynchrones pour charger les produits et gérer les requêtes API, tout en mettant à jour dynamiquement l'interface utilisateur.

Transféré par

fenoantra akasia
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

// 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 (![Link]('disabled')) {
loadProduits(1);
}
});
}

const prevBtn = [Link]('.prev');


if (prevBtn) {
[Link]('click', function() {
if (![Link]('disabled') &&
ACHAT_CONFIG.pageCourante > 1) {
loadProduits(ACHAT_CONFIG.pageCourante - 1);
}
});
}

const nextBtn = [Link]('.next');


if (nextBtn) {
[Link]('click', function() {
if (![Link]('disabled') &&
ACHAT_CONFIG.pageCourante < ACHAT_CONFIG.totalPages) {
loadProduits(ACHAT_CONFIG.pageCourante + 1);
}
});
}

const lastBtn = [Link]('.last');


if (lastBtn) {
[Link]('click', function() {
if (![Link]('disabled')) {
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");

})();

Vous aimerez peut-être aussi