feat: ajout du numéro de chèque et du commentaire sur les paiements

This commit is contained in:
2026-06-29 11:28:52 +02:00
parent 7e036c1966
commit 7249b45533
4 changed files with 73 additions and 6 deletions
@@ -29,6 +29,12 @@ public class Paiement {
@Column(name = "gestionnaire")
private String gestionnaire;
@Column(name = "numero_cheque", length = 50)
private String numeroCheque;
@Column(name = "commentaire", columnDefinition = "TEXT")
private String commentaire;
// Getters and Setters
public Long getId() { return id; }
@@ -48,4 +54,10 @@ public class Paiement {
public String getGestionnaire() { return gestionnaire; }
public void setGestionnaire(String gestionnaire) { this.gestionnaire = gestionnaire; }
public String getNumeroCheque() { return numeroCheque; }
public void setNumeroCheque(String numeroCheque) { this.numeroCheque = numeroCheque; }
public String getCommentaire() { return commentaire; }
public void setCommentaire(String commentaire) { this.commentaire = commentaire; }
}
@@ -0,0 +1,2 @@
ALTER TABLE paiement ADD COLUMN numero_cheque VARCHAR(50);
ALTER TABLE paiement ADD COLUMN commentaire TEXT;
@@ -40,6 +40,8 @@ public class PaiementController {
@RequestParam BigDecimal montant,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate datePaiement,
@RequestParam Long modePaiementId,
@RequestParam(required = false) String numeroCheque,
@RequestParam(required = false) String commentaire,
Principal principal) {
Licence licence = licenceRepository.findById(id)
@@ -58,6 +60,8 @@ public class PaiementController {
paiement.setModePaiement(mode);
paiement.setMontant(montant);
paiement.setDatePaiement(datePaiement);
paiement.setNumeroCheque(numeroCheque);
paiement.setCommentaire(commentaire);
if (principal != null) {
paiement.setGestionnaire(principal.getName());
}
@@ -82,6 +86,8 @@ public class PaiementController {
@RequestParam BigDecimal montant,
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate datePaiement,
@RequestParam Long modePaiementId,
@RequestParam(required = false) String numeroCheque,
@RequestParam(required = false) String commentaire,
@RequestParam(required = false) String redirect,
Principal principal) {
@@ -106,6 +112,8 @@ public class PaiementController {
paiement.setModePaiement(mode);
paiement.setMontant(montant);
paiement.setDatePaiement(datePaiement);
paiement.setNumeroCheque(numeroCheque);
paiement.setCommentaire(commentaire);
if (principal != null) {
paiement.setGestionnaire(principal.getName());
}
@@ -278,6 +278,7 @@
<tr class="bg-gray-50 text-gray-500 uppercase font-medium">
<th class="py-2 px-3 text-left">Date</th>
<th class="py-2 px-3 text-left">Mode</th>
<th class="py-2 px-3 text-left">Infos</th>
<th class="py-2 px-3 text-left">Géré par</th>
<th class="py-2 px-3 text-right font-medium">Montant</th>
<th class="py-2 px-3 text-right font-medium pr-4">Actions</th>
@@ -289,6 +290,14 @@
<td class="py-2 px-3 text-gray-600">
<span class="px-2 py-0.5 rounded bg-gray-100 text-gray-700 font-mono text-[10px]" th:text="${paiement.modePaiement.nom}">Chèque</span>
</td>
<td class="py-2 px-3 text-gray-500 text-xs">
<div th:if="${paiement.numeroCheque != null and !paiement.numeroCheque.isEmpty()}" class="text-[10px]">
<span class="font-semibold text-gray-600">N°:</span> <span th:text="${paiement.numeroCheque}">123</span>
</div>
<div th:if="${paiement.commentaire != null and !paiement.commentaire.isEmpty()}" class="text-[10px] italic mt-0.5 text-gray-400 truncate max-w-[120px]" th:title="${paiement.commentaire}" th:text="${paiement.commentaire}">
Commentaire
</div>
</td>
<td class="py-2 px-3 text-gray-500 text-xs italic" th:text="${paiement.gestionnaire != null ? paiement.gestionnaire : '-'}">-</td>
<td class="py-2 px-3 text-right font-semibold text-green-600" th:text="${paiement.montant + ' €'}">50.00 €</td>
<td class="py-2 px-3 text-right pr-4">
@@ -300,7 +309,9 @@
th:data-mode-id="${paiement.modePaiement.id}"
th:data-licence-id="${lic.id}"
th:data-max-amount="${lic.getResteAPayer().add(paiement.montant)}"
onclick="openEditPaiementModal(this.getAttribute('data-paiement-id'), this.getAttribute('data-montant'), this.getAttribute('data-date'), this.getAttribute('data-mode-id'), this.getAttribute('data-licence-id'), this.getAttribute('data-max-amount'))"
th:data-cheque="${paiement.numeroCheque}"
th:data-commentaire="${paiement.commentaire}"
onclick="openEditPaiementModal(this.getAttribute('data-paiement-id'), this.getAttribute('data-montant'), this.getAttribute('data-date'), this.getAttribute('data-mode-id'), this.getAttribute('data-licence-id'), this.getAttribute('data-max-amount'), this.getAttribute('data-cheque'), this.getAttribute('data-commentaire'))"
class="text-blue-600 hover:text-blue-900 bg-blue-50 hover:bg-blue-100 p-1.5 rounded transition-colors inline-flex items-center"
title="Modifier">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@@ -529,11 +540,19 @@
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Mode de paiement</label>
<select name="modePaiementId" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
<select id="addPaiementMode" name="modePaiementId" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none" onchange="toggleChequeVisibility(this, 'addChequeBlock', 'addNumeroCheque')">
<option value="">Sélectionnez un mode...</option>
<option th:each="mode : ${modesPaiement}" th:value="${mode.id}" th:text="${mode.nom}"></option>
<option th:each="mode : ${modesPaiement}" th:value="${mode.id}" th:data-nom="${#strings.toLowerCase(mode.nom)}" th:text="${mode.nom}"></option>
</select>
</div>
<div id="addChequeBlock" class="hidden">
<label class="block text-sm font-medium text-gray-700 mb-1">Numéro du chèque <span class="text-red-500">*</span></label>
<input type="text" id="addNumeroCheque" name="numeroCheque" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Commentaire (facultatif)</label>
<textarea id="addCommentaire" name="commentaire" rows="2" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none"></textarea>
</div>
<div class="items-center px-4 py-3 flex justify-end space-x-2">
<button type="button" onclick="closePaiementModal()" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Annuler</button>
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700">Payer</button>
@@ -561,11 +580,19 @@
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Mode de paiement</label>
<select id="editPaiementMode" name="modePaiementId" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
<select id="editPaiementMode" name="modePaiementId" required class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none" onchange="toggleChequeVisibility(this, 'editChequeBlock', 'editNumeroCheque')">
<option value="">Sélectionnez un mode...</option>
<option th:each="mode : ${modesPaiement}" th:value="${mode.id}" th:text="${mode.nom}"></option>
<option th:each="mode : ${modesPaiement}" th:value="${mode.id}" th:data-nom="${#strings.toLowerCase(mode.nom)}" th:text="${mode.nom}"></option>
</select>
</div>
<div id="editChequeBlock" class="hidden">
<label class="block text-sm font-medium text-gray-700 mb-1">Numéro du chèque <span class="text-red-500">*</span></label>
<input type="text" id="editNumeroCheque" name="numeroCheque" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Commentaire (facultatif)</label>
<textarea id="editCommentaire" name="commentaire" rows="2" class="w-full border border-gray-300 rounded-lg px-4 py-2 text-sm focus:ring-2 focus:ring-blue-500 outline-none"></textarea>
</div>
<div class="items-center px-4 py-3 flex justify-end space-x-2">
<button type="button" onclick="closeEditPaiementModal()" class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">Annuler</button>
<button type="submit" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700">Enregistrer</button>
@@ -688,17 +715,35 @@
document.getElementById('paiementModal').classList.add('hidden');
}
function openEditPaiementModal(paiementId, montant, date, modePaiementId, licenceId, maxAmount) {
function openEditPaiementModal(paiementId, montant, date, modePaiementId, licenceId, maxAmount, numeroCheque, commentaire) {
document.getElementById('editPaiementModal').classList.remove('hidden');
document.getElementById('editPaiementForm').action = '/paiements/' + paiementId + '/update';
document.getElementById('editPaiementMontant').value = montant;
document.getElementById('editPaiementMontant').max = maxAmount;
document.getElementById('editPaiementDate').value = date;
document.getElementById('editPaiementMode').value = modePaiementId;
document.getElementById('editNumeroCheque').value = numeroCheque || '';
document.getElementById('editCommentaire').value = commentaire || '';
toggleChequeVisibility(document.getElementById('editPaiementMode'), 'editChequeBlock', 'editNumeroCheque');
}
function closeEditPaiementModal() {
document.getElementById('editPaiementModal').classList.add('hidden');
}
function toggleChequeVisibility(selectElement, blockId, inputId) {
const block = document.getElementById(blockId);
const input = document.getElementById(inputId);
const selectedOption = selectElement.options[selectElement.selectedIndex];
if (selectedOption && selectedOption.getAttribute('data-nom') && selectedOption.getAttribute('data-nom').includes('chèque')) {
block.classList.remove('hidden');
input.required = true;
} else {
block.classList.add('hidden');
input.required = false;
input.value = '';
}
}
document.addEventListener("DOMContentLoaded", function() {
const dateInput = document.getElementById('dateNaissance');
const repBlock = document.getElementById('representantBlock');