From.php

PHP Guest 20 Views Size: 7.74 KB Posted on: Jun 2, 26 @ 9:25 PM
  1. 1<?php
  2. 2$isEdit = !empty($invoice['id']);
  3. 3?>
  4. 4<?php if (isset($edit)): ?>
  5. 5 <!-- Formulaire pré-rempli pour modification -->
  6. 6 <form method="POST" action="?action=update&id=<?= $edit['id'] ?>">
  7. 7 <input type="text" name="client_name" value="<?= htmlspecialchars($edit['client_name']) ?>">
  8. 8 <input type="date" name="invoice_date" value="<?= htmlspecialchars($edit['invoice_date']) ?>">
  9. 9 <!-- autres champs pré-remplis -->
  10. 10 <button type="submit">Mettre à jour</button>
  11. 11 </form>
  12. 12<?php else: ?>
  13. 13 <!-- Formulaire vide pour nouvelle facture -->
  14. 14 <form method="POST" action="?action=store">
  15. 15 <input type="text" name="client_name" placeholder="Nom du client">
  16. 16 <input type="date" name="invoice_date">
  17. 17 <!-- autres champs vides -->
  18. 18 <button type="submit">Créer</button>
  19. 19 </form>
  20. 20<?php endif; ?>
  21. 21<div class="card card-soft">
  22. 22 <div class="card-body">
  23. 23 <h2 class="h5 mb-3"><?= $isEdit ? 'Modifier la facture' : 'Nouvelle facture' ?></h2>
  24. 24
  25. 25 <form method="post" action="?action=<?= $isEdit ? 'update' : 'store' ?>">
  26. 26 <input type="hidden" name="id" value="<?= (int)($invoice['id'] ?? 0) ?>">
  27. 27<?php if (isset($edit)): ?>
  28. 28 <form method="POST" action="?action=update&id=<?= $edit->id ?>">
  29. 29 <!-- champs pré-remplis avec $edit -->
  30. 30 </form>
  31. 31<?php else: ?>
  32. 32 <form method="POST" action="?action=store">
  33. 33 <!-- champs vides -->
  34. 34 </form>
  35. 35<?php endif; ?>
  36. 36
  37. 37 <div class="row g-3">
  38. 38 <div class="col-md-6">
  39. 39 <label class="form-label">Numéro</label>
  40. 40 <input class="form-control" type="text" name="invoice_number" value="<?= e($invoice['invoice_number'] ?? $nextNumber ?? '') ?>" required>
  41. 41 </div>
  42. 42 <div class="col-md-6">
  43. 43 <label class="form-label">Date</label>
  44. 44 <input class="form-control" type="date" name="invoice_date" value="<?= e($invoice['invoice_date'] ?? date('Y-m-d')) ?>" required>
  45. 45 </div>
  46. 46 </div>
  47. 47
  48. 48 <div class="mt-3">
  49. 49 <label class="form-label">Notes</label>
  50. 50 <textarea class="form-control" name="notes" rows="3"><?= e($invoice['notes'] ?? '') ?></textarea>
  51. 51 </div>
  52. 52
  53. 53 <div class="mt-3">
  54. 54 <label class="form-label">Articles</label>
  55. 55 <div id="items-wrapper">
  56. 56 <?php if (!empty($invoice['items'])): ?>
  57. 57 <?php foreach ($invoice['items'] as $item): ?>
  58. 58 <div class="row g-2 mb-2 item-row">
  59. 59 <div class="col-md-6">
  60. 60 <input class="form-control desc" name="description[]" value="<?= e($item['description'] ?? '') ?>" placeholder="Désignation" required>
  61. 61 </div>
  62. 62 <div class="col-md-2">
  63. 63 <input class="form-control qty" type="number" step="0.01" min="1" name="quantity[]" value="<?= e($item['quantity'] ?? 1) ?>" required>
  64. 64 </div>
  65. 65 <div class="col-md-3">
  66. 66 <input class="form-control price" type="number" step="0.01" min="0" name="unit_price_ht[]" value="<?= e($item['unit_price_ht'] ?? 0) ?>" required>
  67. 67 </div>
  68. 68 <div class="col-md-1 d-flex align-items-center">
  69. 69 <button type="button" class="btn btn-outline-danger btn-sm remove-line">×</button>
  70. 70 </div>
  71. 71 </div>
  72. 72 <?php endforeach; ?>
  73. 73 <?php else: ?>
  74. 74 <div class="row g-2 mb-2 item-row">
  75. 75 <div class="col-md-6">
  76. 76 <input class="form-control desc" name="description[]" placeholder="Désignation" required>
  77. 77 </div>
  78. 78 <div class="col-md-2">
  79. 79 <input class="form-control qty" type="number" step="0.01" min="1" name="quantity[]" value="1" required>
  80. 80 </div>
  81. 81 <div class="col-md-3">
  82. 82 <input class="form-control price" type="number" step="0.01" min="0" name="unit_price_ht[]" placeholder="Prix HT" required>
  83. 83 </div>
  84. 84 <div class="col-md-1 d-flex align-items-center">
  85. 85 <button type="button" class="btn btn-outline-danger btn-sm remove-line">×</button>
  86. 86 </div>
  87. 87 </div>
  88. 88 <?php endif; ?>
  89. 89 </div>
  90. 90 <button type="button" class="btn btn-outline-secondary btn-sm mt-2" id="add-item">Ajouter un article</button>
  91. 91 </div>
  92. 92
  93. 93 <div class="card mt-3 mb-3">
  94. 94 <div class="card-body">
  95. 95 <div class="row g-3">
  96. 96 <div class="col-md-4">
  97. 97 <label class="form-label">Total HT</label>
  98. 98 <input class="form-control" id="total_ht" type="text" readonly value="0,00 MAD">
  99. 99 </div>
  100. 100 <div class="col-md-4">
  101. 101 <label class="form-label">TVA 20%</label>
  102. 102 <input class="form-control" id="total_vat" type="text" readonly value="0,00 MAD">
  103. 103 </div>
  104. 104 <div class="col-md-4">
  105. 105 <label class="form-label">Total TTC</label>
  106. 106 <input class="form-control" id="total_ttc" type="text" readonly value="0,00 MAD">
  107. 107 </div>
  108. 108 </div>
  109. 109 </div>
  110. 110 </div>
  111. 111
  112. 112 <div class="d-flex flex-wrap gap-2 mt-3">
  113. 113 <button type="submit" class="btn btn-primary"><?= $isEdit ? 'Mettre à jour' : 'Enregistrer' ?></button>
  114. 114 <a class="btn btn-outline-success" href="?action=csv">Export CSV</a>
  115. 115 <?php if ($isEdit && !empty($invoice['id'])): ?>
  116. 116 <a class="btn btn-success" href="?action=excel&id=<?= (int)$invoice['id'] ?>">Export Excel</a>
  117. 117 <a class="btn btn-danger" href="?action=pdf&id=<?= (int)$invoice['id'] ?>" target="_blank">PDF</a>
  118. 118 <?php endif; ?>
  119. 119 </div>
  120. 120 </form>
  121. 121 </div>
  122. 122</div>
  123. 123
  124. 124<script>
  125. 125function money(v){ return Number(v || 0).toFixed(2).replace('.', ',') + ' MAD'; }
  126. 126function calculateTotals(){
  127. 127 let ht = 0;
  128. 128 document.querySelectorAll('.item-row').forEach(row => {
  129. 129 const qty = parseFloat(row.querySelector('.qty')?.value || 0);
  130. 130 const price = parseFloat(row.querySelector('.price')?.value || 0);
  131. 131 if (!isNaN(qty) && !isNaN(price)) ht += qty * price;
  132. 132 });
  133. 133 const vat = ht * 0.20;
  134. 134 const ttc = ht + vat;
  135. 135 document.getElementById('total_ht').value = money(ht);
  136. 136 document.getElementById('total_vat').value = money(vat);
  137. 137 document.getElementById('total_ttc').value = money(ttc);
  138. 138}
  139. 139function addItemRow(){
  140. 140 const w = document.getElementById('items-wrapper');
  141. 141 const div = document.createElement('div');
  142. 142 div.className = 'row g-2 mb-2 item-row';
  143. 143 div.innerHTML = '<div class="col-md-6"><input class="form-control desc" name="description[]" placeholder="Désignation" required></div><div class="col-md-2"><input class="form-control qty" type="number" step="0.01" min="1" name="quantity[]" value="1" required></div><div class="col-md-3"><input class="form-control price" type="number" step="0.01" min="0" name="unit_price_ht[]" placeholder="Prix HT" required></div><div class="col-md-1 d-flex align-items-center"><button type="button" class="btn btn-outline-danger btn-sm remove-line">×</button></div>';
  144. 144 w.appendChild(div);
  145. 145 bindRow(div);
  146. 146 calculateTotals();
  147. 147}
  148. 148function bindRow(row){
  149. 149 row.querySelector('.qty')?.addEventListener('input', calculateTotals);
  150. 150 row.querySelector('.price')?.addEventListener('input', calculateTotals);
  151. 151 row.querySelector('.remove-line')?.addEventListener('click', function(){
  152. 152 if (document.querySelectorAll('.item-row').length > 1) row.remove();
  153. 153 calculateTotals();
  154. 154 });
  155. 155}
  156. 156document.querySelectorAll('.item-row').forEach(bindRow);
  157. 157document.getElementById('add-item')?.addEventListener('click', addItemRow);
  158. 158document.addEventListener('input', function(e){ if (e.target.classList.contains('qty') || e.target.classList.contains('price')) calculateTotals(); });
  159. 159document.addEventListener('DOMContentLoaded', calculateTotals);
  160. 160</script>

Paste brut

Comments 0
Login to join the discussion.
  • No comments yet — be the first.
Login to post a comment. Se connecter/S'enregistrer
We use cookies. To comply with GDPR in the EU and the UK we have to show you these.

We use cookies and similar technologies to keep this website functional (including spam protection via Google reCAPTCHA or Cloudflare Turnstile), and — with your consent — to measure usage and show ads. See Privacy.