{% extends 'basee.html.twig' %}
{% block title %}Facture de Service{% endblock %}
{% block subtitle %}Facture de Service{% endblock %}
{% block subtitle2 %}Détails de la Facture{% endblock %}
{% block body %}
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header pb-0">
<div class="d-flex align-items-center">
<p class="mb-0">Détails de la Facture</p>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="form-control-label" style="font-weight:bold">Id</label>
<p>{{ facture_service.id }}</p>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-control-label" style="font-weight:bold">Numéro</label>
<p>{{ facture_service.numero }}</p>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-control-label" style="font-weight:bold">Date de création</label>
<p>{{ facture_service.dateCreation ? facture_service.dateCreation|date('d/m/Y H:i') : 'N/A' }}</p>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-control-label" style="font-weight:bold">Status</label>
<select id="statut-facture" class="form-select">
<option value="En attente" {{ facture_service.status == 'En attente' ? 'selected' }}>En attente</option>
<option value="Partiellement payé" {{ facture_service.status == 'Partiellement payé' ? 'selected' }}>Partiellement payé</option>
<option value="Payé" {{ facture_service.status == 'Payé' ? 'selected' }}>Payé</option>
<option value="Annulé" {{ facture_service.status == 'Annulé' ? 'selected' }}>Annulé</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-control-label" style="font-weight:bold">Client</label>
<p>{{ facture_service.client ? facture_service.client.nom : 'Non spécifié' }}</p>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="form-control-label" style="font-weight:bold">Type de Paiement</label>
<select id="type-paiement" class="form-select">
<option value="Espèces" {{ facture_service.typePaiement == 'Espèces' ? 'selected' }}>Espèces</option>
<option value="Yas" {{ facture_service.typePaiement == 'Yas' ? 'selected' }}>Yas</option>
<option value="Flooz" {{ facture_service.typePaiement == 'Flooz' ? 'selected' }}>Flooz</option>
<option value="TPE" {{ facture_service.typePaiement == 'TPE' ? 'selected' }}>TPE</option>
<option value="WAVE" {{ facture_service.typePaiement == 'WAVE' ? 'selected' }}>WAVE</option>
<option value="ORANGE MONEY" {{ facture_service.typePaiement == 'ORANGE MONEY' ? 'selected' }}>ORANGE MONEY</option>
<option value="VIREMENT BANCAIRE" {{ facture_service.typePaiement == 'VIREMENT BANCAIRE' ? 'selected' }}>VIREMENT BANCAIRE</option>
</select>
</div>
</div>
</div>
<hr class="horizontal dark">
<h3>Services facturés</h3>
{% if facture_service.serviceFactureLignes|length > 0 %}
<form id="update-services-form">
<table class="table table-striped">
<thead>
<tr>
<th>Service</th>
<th class="text-end">Prix</th>
</tr>
</thead>
<tbody>
{% for ligne in facture_service.serviceFactureLignes %}
<tr>
<td>{{ ligne.service ? ligne.service.nom : 'Service inconnu' }}</td>
<td class="text-end">
<input type="number"
class="form-control service-prix text-end"
value="{{ ligne.prix }}"
data-ligne-id="{{ ligne.id }}"
data-original-prix="{{ ligne.prix }}"
step="0.01" min="0">
</td>
</tr>
{% endfor %}
<tr class="table-active">
<th>Montant total</th>
<th class="text-end" id="montant-total">{{ facture_service.montantTotal|number_format(2, ',', ' ') }} CFA</th>
</tr>
</tbody>
</table>
<div class="text-end mt-3">
<button type="button" id="reset-prix-btn" class="btn btn-outline-secondary btn-sm">Réinitialiser les prix</button>
<button type="submit" class="btn btn-primary btn-sm">Enregistrer les modifications</button>
</div>
</form>
{% else %}
<div class="alert alert-info">Aucun service associé à cette facture.</div>
{% endif %}
</div>
<div class="card-footer d-flex align-items-center">
<a href="{{ path('app_facture_service_index') }}" class="btn btn-outline-secondary btn-sm ms-auto me-4">Retour à la liste</a>
<a href="{{ path('app_facture_service_edit', {'id': facture_service.id}) }}" class="btn btn-outline-primary btn-sm me-4">Modifier</a>
<button onclick="imprimerFacture({{ facture_service.id }})" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-printer"></i> Imprimer la facture
</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const statutFactureSelect = document.getElementById('statut-facture');
const typePaiementSelect = document.getElementById('type-paiement');
const servicePrixInputs = document.querySelectorAll('.service-prix');
const montantTotalElement = document.getElementById('montant-total');
const updateServicesForm = document.getElementById('update-services-form');
const resetPrixBtn = document.getElementById('reset-prix-btn');
// Fonction pour mettre à jour le type de paiement
typePaiementSelect.addEventListener('change', function() {
const factureId = {{ facture_service.id }};
const nouveauType = this.value;
fetch("{{ path('app_facture_service_update_type_paiement') }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
},
body: JSON.stringify({
id: factureId,
typePaiement: nouveauType
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Afficher une notification de succès
const notification = document.createElement('div');
notification.className = 'alert alert-success alert-dismissible fade show';
notification.innerHTML = `
Type de paiement mis à jour avec succès !
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
`;
document.querySelector('.card-body').prepend(notification);
// Suppression automatique après 3 secondes
setTimeout(() => {
notification.remove();
}, 3000);
} else {
alert("Erreur lors de la mise à jour du type de paiement : " + data.message);
}
})
.catch(error => {
console.error("Erreur:", error);
alert("Une erreur s'est produite lors de la mise à jour du type de paiement.");
});
});
// Fonction pour mettre à jour le statut de la facture
statutFactureSelect.addEventListener('change', function() {
const factureId = {{ facture_service.id }};
const nouveauStatut = this.value;
fetch("{{ path('app_facture_service_update_status') }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
},
body: JSON.stringify({
id: factureId,
status: nouveauStatut
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert("Le statut de la facture a été mis à jour avec succès.");
} else {
alert("Erreur lors de la mise à jour du statut : " + data.message);
}
})
.catch(error => {
console.error("Erreur:", error);
alert("Une erreur s'est produite lors de la mise à jour du statut.");
});
});
// Fonction pour calculer le montant total
function calculerMontantTotal() {
let total = 0;
servicePrixInputs.forEach(input => {
total += parseFloat(input.value) || 0;
});
return total;
}
// Mise à jour du montant total lors de la modification des prix
servicePrixInputs.forEach(input => {
input.addEventListener('input', function() {
const total = calculerMontantTotal();
montantTotalElement.textContent = total.toLocaleString('fr-FR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}) + ' CFA';
});
});
// Réinitialiser les prix
resetPrixBtn.addEventListener('click', function() {
servicePrixInputs.forEach(input => {
input.value = input.dataset.originalPrix;
});
// Mettre à jour le montant total
const total = calculerMontantTotal();
montantTotalElement.textContent = total.toLocaleString('fr-FR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}) + ' CFA';
});
// Enregistrer les modifications
updateServicesForm.addEventListener('submit', function(e) {
e.preventDefault();
const factureId = {{ facture_service.id }};
const lignes = [];
servicePrixInputs.forEach(input => {
lignes.push({
id: input.dataset.ligneId,
prix: parseFloat(input.value)
});
});
const montantTotal = calculerMontantTotal();
fetch("{{ path('app_facture_service_update_prix') }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Requested-With": "XMLHttpRequest"
},
body: JSON.stringify({
factureId: factureId,
lignes: lignes,
montantTotal: montantTotal
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert("Les prix ont été mis à jour avec succès.");
// Mettre à jour les prix originaux
servicePrixInputs.forEach(input => {
input.dataset.originalPrix = input.value;
});
} else {
alert("Erreur lors de la mise à jour des prix : " + data.message);
}
})
.catch(error => {
console.error("Erreur:", error);
alert("Une erreur s'est produite lors de la mise à jour des prix.");
});
});
});
// Fonction pour imprimer la facture
function imprimerFacture(id) {
const url = "{{ path('app_facture_service_print', {'id': 'REPLACE_ID'}) }}".replace('REPLACE_ID', id);
window.open(url, '_blank');
}
</script>
{% endblock %}