Spaces:
Running
Running
EL GHAFRAOUI AYOUB
commited on
Commit
·
d21a6a2
1
Parent(s):
8721c9a
- app/templates/index.html +80 -29
- run_app.py +0 -0
app/templates/index.html
CHANGED
@@ -391,6 +391,10 @@
|
|
391 |
<h5 class="mb-0">Totaux</h5>
|
392 |
</div>
|
393 |
<div class="card-body">
|
|
|
|
|
|
|
|
|
394 |
<div class="mb-3">
|
395 |
<label for="totalHT" class="form-label">Total HT</label>
|
396 |
<input type="number" class="form-control" id="totalHT" readonly>
|
@@ -540,6 +544,25 @@
|
|
540 |
</div>
|
541 |
</div>
|
542 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
543 |
<!-- Bootstrap JS -->
|
544 |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
545 |
|
@@ -568,38 +591,61 @@
|
|
568 |
|
569 |
// Function to add a new item row
|
570 |
function addItemRow(item, tableBody) {
|
571 |
-
|
572 |
-
const
|
573 |
-
|
574 |
-
|
575 |
-
<td><input type="text" class="form-control" name="description" value="${item.description}" readonly></td>
|
576 |
-
<td><input type="text" class="form-control" name="unit" value="${item.unit}" readonly></td>
|
577 |
-
<td><input type="number" class="form-control" name="quantity" value="${item.quantity}" required></td>
|
578 |
-
<td><input type="number" class="form-control" name="length" value="${item.length}" step="0.01" required></td>
|
579 |
-
<td><input type="number" class="form-control" name="unitPrice" value="${item.unit_price}" step="0.01" required></td>
|
580 |
-
<td><input type="number" class="form-control" name="totalHT" value="${total}" readonly></td>
|
581 |
-
<td><button type="button" class="btn btn-danger btn-sm remove-item">×</button></td>
|
582 |
-
`;
|
583 |
-
|
584 |
-
row.querySelector(".remove-item").addEventListener("click", () => {
|
585 |
-
row.remove();
|
586 |
-
updateTotals();
|
587 |
});
|
588 |
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
updateTotals();
|
598 |
});
|
599 |
-
});
|
600 |
|
601 |
-
|
602 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
603 |
}
|
604 |
|
605 |
// Function to update totals
|
@@ -608,14 +654,19 @@
|
|
608 |
.reduce((sum, input) => sum + (parseFloat(input.value) || 0), 0);
|
609 |
|
610 |
const formattedTotalHT = totalHT.toFixed(2);
|
611 |
-
const
|
612 |
-
|
|
|
|
|
613 |
|
614 |
document.querySelector("#totalHT").value = formattedTotalHT;
|
615 |
document.querySelector("#tax").value = tax;
|
616 |
document.querySelector("#totalTTC").value = totalTTC;
|
617 |
}
|
618 |
|
|
|
|
|
|
|
619 |
// Initialize tables with default items
|
620 |
defaultItems.poutrelles.forEach(item => addItemRow(item, poutrellesTable));
|
621 |
defaultItems.hourdis.forEach(item => addItemRow(item, hourdisTable));
|
|
|
391 |
<h5 class="mb-0">Totaux</h5>
|
392 |
</div>
|
393 |
<div class="card-body">
|
394 |
+
<div class="mb-3 form-check form-switch">
|
395 |
+
<input class="form-check-input" type="checkbox" id="tvaSwitch" checked>
|
396 |
+
<label class="form-check-label" for="tvaSwitch">Appliquer TVA 20%</label>
|
397 |
+
</div>
|
398 |
<div class="mb-3">
|
399 |
<label for="totalHT" class="form-label">Total HT</label>
|
400 |
<input type="number" class="form-control" id="totalHT" readonly>
|
|
|
544 |
</div>
|
545 |
</div>
|
546 |
|
547 |
+
<!-- Replace the existing confirmation modal with this -->
|
548 |
+
<div class="modal fade" id="confirmationModal" tabindex="-1">
|
549 |
+
<div class="modal-dialog">
|
550 |
+
<div class="modal-content">
|
551 |
+
<div class="modal-header">
|
552 |
+
<h5 class="modal-title">Article Existant</h5>
|
553 |
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
554 |
+
</div>
|
555 |
+
<div class="modal-body">
|
556 |
+
<p>Cet article existe déjà dans le tableau. Voulez-vous le remplacer ?</p>
|
557 |
+
</div>
|
558 |
+
<div class="modal-footer">
|
559 |
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
560 |
+
<button type="button" class="btn btn-primary" id="confirmReplace">Remplacer</button>
|
561 |
+
</div>
|
562 |
+
</div>
|
563 |
+
</div>
|
564 |
+
</div>
|
565 |
+
|
566 |
<!-- Bootstrap JS -->
|
567 |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
|
568 |
|
|
|
591 |
|
592 |
// Function to add a new item row
|
593 |
function addItemRow(item, tableBody) {
|
594 |
+
// Vérifier si l'article existe déjà
|
595 |
+
const existingRow = Array.from(tableBody.querySelectorAll('tr')).find(row => {
|
596 |
+
const description = row.querySelector('input[name="description"]').value;
|
597 |
+
return description === item.description;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
598 |
});
|
599 |
|
600 |
+
if (existingRow) {
|
601 |
+
// Afficher la modal de confirmation
|
602 |
+
const confirmationModal = new bootstrap.Modal(document.getElementById('confirmationModal'));
|
603 |
+
confirmationModal.show();
|
604 |
+
|
605 |
+
// Gérer la confirmation de remplacement
|
606 |
+
document.getElementById('confirmReplace').onclick = function() {
|
607 |
+
existingRow.remove();
|
608 |
+
creerNouvelleRow();
|
609 |
+
confirmationModal.hide();
|
610 |
+
};
|
611 |
+
} else {
|
612 |
+
creerNouvelleRow();
|
613 |
+
}
|
614 |
+
|
615 |
+
function creerNouvelleRow() {
|
616 |
+
const row = document.createElement("tr");
|
617 |
+
const total = (item.quantity * item.length * item.unit_price).toFixed(2);
|
618 |
+
|
619 |
+
row.innerHTML = `
|
620 |
+
<td><input type="text" class="form-control" name="description" value="${item.description}" readonly></td>
|
621 |
+
<td><input type="text" class="form-control" name="unit" value="${item.unit}" readonly></td>
|
622 |
+
<td><input type="number" class="form-control" name="quantity" value="${item.quantity}" required></td>
|
623 |
+
<td><input type="number" class="form-control" name="length" value="${item.length}" step="0.01" required></td>
|
624 |
+
<td><input type="number" class="form-control" name="unitPrice" value="${item.unit_price}" step="0.01" required></td>
|
625 |
+
<td><input type="number" class="form-control" name="totalHT" value="${total}" readonly></td>
|
626 |
+
<td><button type="button" class="btn btn-danger btn-sm remove-item">×</button></td>
|
627 |
+
`;
|
628 |
+
|
629 |
+
row.querySelector(".remove-item").addEventListener("click", () => {
|
630 |
+
row.remove();
|
631 |
updateTotals();
|
632 |
});
|
|
|
633 |
|
634 |
+
// Ajouter les écouteurs d'événements pour mettre à jour le total
|
635 |
+
['quantity', 'length', 'unitPrice'].forEach(field => {
|
636 |
+
row.querySelector(`input[name='${field}']`).addEventListener('input', () => {
|
637 |
+
const quantite = parseFloat(row.querySelector('input[name="quantity"]').value) || 0;
|
638 |
+
const longueur = parseFloat(row.querySelector('input[name="length"]').value) || 0;
|
639 |
+
const prix = parseFloat(row.querySelector('input[name="unitPrice"]').value) || 0;
|
640 |
+
const totalLigne = (quantite * longueur * prix).toFixed(2);
|
641 |
+
row.querySelector('input[name="totalHT"]').value = totalLigne;
|
642 |
+
updateTotals();
|
643 |
+
});
|
644 |
+
});
|
645 |
+
|
646 |
+
tableBody.appendChild(row);
|
647 |
+
updateTotals();
|
648 |
+
}
|
649 |
}
|
650 |
|
651 |
// Function to update totals
|
|
|
654 |
.reduce((sum, input) => sum + (parseFloat(input.value) || 0), 0);
|
655 |
|
656 |
const formattedTotalHT = totalHT.toFixed(2);
|
657 |
+
const tvaEnabled = document.querySelector("#tvaSwitch").checked;
|
658 |
+
|
659 |
+
const tax = tvaEnabled ? (totalHT * 0.20).toFixed(2) : "0.00";
|
660 |
+
const totalTTC = tvaEnabled ? (totalHT * 1.20).toFixed(2) : totalHT.toFixed(2);
|
661 |
|
662 |
document.querySelector("#totalHT").value = formattedTotalHT;
|
663 |
document.querySelector("#tax").value = tax;
|
664 |
document.querySelector("#totalTTC").value = totalTTC;
|
665 |
}
|
666 |
|
667 |
+
// Add event listener for TVA switch
|
668 |
+
document.querySelector("#tvaSwitch").addEventListener('change', updateTotals);
|
669 |
+
|
670 |
// Initialize tables with default items
|
671 |
defaultItems.poutrelles.forEach(item => addItemRow(item, poutrellesTable));
|
672 |
defaultItems.hourdis.forEach(item => addItemRow(item, hourdisTable));
|
run_app.py
ADDED
File without changes
|