From.php

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