{% extends 'sidebar.twig' %}
{% block title %}
IMMMY BEAUTY - Recettes
{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" href="{{ asset('css/style.css') }}">
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
{% endblock %}
{% block page_emoji %}
📋‍
{% endblock %}
{% block page_titre %}
Recettes
{% endblock %}
{% block page_info %}
Gérez vos recettes ici.
{% endblock %}
{% block admin_content %}
<div class="container">
<div class="flex flex-wrap justify-center mb-4"> <!-- Ajouter une marge inférieure -->
<div id="dateDisplay" class="text-3xl text-center font-bold cursor-pointer color-black" onclick="openCalendar()">
</div>
<label for="uniqueHiddenDateInput"></label><input type="text" id="uniqueHiddenDateInput" class="hidden" />
</div>
<div class="flex flex-wrap">
<div class="w-full lg:w-1/2 p-4 bg-white rounded shadow">
<h2 class="text-xl font-bold mb-4 text-center">Ajouter une recette</h2>
<form id="recetteForm" class="space-y-4">
{% set urlDate = app.request.query.get('date') %}
<input type="hidden" id="dateInput" name="date" value="{{ urlDate ? urlDate : "now"|date('d/m/Y') }}">
<div id="prestationsContainer">
<div class="prestation-group mb-4 flex items-center space-x-4">
<div class="flex-grow">
<label for="categorie_0" class="block text-gray-700">Catégorie <span style="color: red;">*</span></label>
<select name="prestations[0][categorie_id]" id="categorie_0" class="categorie-select mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
<option value="">Sélectionnez une catégorie</option>
{% for categorie in categories %}
<option value="{{ categorie.id }}">{{ categorie.nom }}</option>
{% endfor %}
</select>
</div>
<div class="hidden prestation-select-group mt-4 flex-grow">
<label for="prestation_0" class="block text-gray-700">Prestation <span style="color: red;">*</span></label>
<select name="prestations[0][prestation_id]" id="prestation_0" class="prestation-select mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
<option value="">Sélectionnez une prestation</option>
</select>
</div>
<button type="button" class="remove-prestation ml-2 text-red-500 hover:text-red-700 hidden">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<a href="#" id="addPrestationLink" class="mt-4 text-black-500 hover:text-gray-600-700">
<i class="fas fa-plus"></i> Ajouter une prestation
</a>
<div>
<label for="nomClient" class="block text-gray-700">Nom de la cliente <span style="color: red;">*</span></label>
<input type="text" id="nomClient" name="nom_client" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
</div>
<div>
<label for="acompte" class="block text-gray-700">Acompte</label>
<input type="number" step="0.01" min="0" id="acompte" name="acompte" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
</div>
<div>
<a href="#"
id="discountLabel"
class="mt-4 text-black-500 hover:text-gray-600-700"
onclick="showDiscountInput()"
>
<i class="fas fa-percent"></i> Réduction ?
</a>
</div>
<div id="discountInputContainer" class="flex items-center space-x-4" style="display:none;">
<label for="prixPayeSurPlace" class="block text-gray-700 flex-grow">Prix payé sur place</label>
<div class="flex items-center space-x-2 flex-grow">
<input type="number" id="prixPayeSurPlace" step="0.01" min="0" name="prix_paye_sur_place" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50">
<button type="button" id="removeDiscountInput" class="ml-2 text-red-500 hover:text-red-700">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<div>
<label for="typePaiement" class="block text-gray-700">Type de paiement <span style="color: red;">*</span></label>
<select name="type_paiement_id" id="typePaiement" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
<option value="">Sélectionnez un type de paiement</option>
<option value="1">Espèce</option>
<option value="2">Carte Bancaire</option>
<option value="3">Espèce & Carte bancaire</option>
</select>
</div>
<div id="paiementDetails" class="mt-4" style="display: none;">
<div id="especeContainer" class="flex items-center space-x-4" style="display: none;">
<div class="flex-grow">
<label for="montantEspece" class="block text-gray-700">Montant Espèce <span style="color: red;">*</span></label>
<input type="number" id="montantEspece" name="montant_espece" step="0.01" min="0" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
</div>
</div>
<div id="carteBancaireContainer" class="flex items-center space-x-4" style="display: none;">
<div class="flex-grow">
<label for="montantCarteBancaire" class="block text-gray-700">Montant Carte Bancaire <span style="color: red;">*</span></label>
<input type="number" id="montantCarteBancaire" name="montant_carte_bancaire" step="0.01" min="0" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
</div>
</div>
</div>
<div class="text-center">
<button class="inline-flex items-center px-4 py-2 btn btn-primary rounded-lg shadow-md transition duration-300 ease-in-out">
Ajouter
</button>
</div>
</form>
</div>
<div class="w-full lg:w-1/2 p-4 bg-white rounded shadow" id="recettesContainer" style="{{ recettes ? 'display:block;' : 'display:none;' }}">
<h2 class="text-xl font-bold mb-4 text-center">Recette du jour</h2>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200" id="recettesTable">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Cliente</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Prestation</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Acompte</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Payé</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type de règlement</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Total</th>
<th></th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% for recette in recettes %}
<tr data-id="{{ recette.id }}">
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ recette.nomClient }}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<ul>
{% for prestation in recette.prestations %}
<li>{{ prestation.nom }} <strong>({{ prestation.prix}} €)</strong></li>
{% endfor %}
</ul>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{% if recette.acompte %} {{ recette.acompte }} € {% else %} - {% endif %}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<ul>
{% for paiement in recette.paiements %}
<li>{% if paiement.sommePayee %} {{ paiement.sommePayee }} € {% else %} - {% endif %}</li>
{% endfor %}
</ul>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<ul>
{% for paiement in recette.paiements %}
<li>{{ paiement.typePaiement.nom }}</li>
{% endfor %}
</ul>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
{% set totalPaye = 0 %}
{% if recette.acompte %}
{% set totalPaye = totalPaye + recette.acompte %}
{% endif %}
{% for paiement in recette.paiements %}
{% if paiement.sommePayee %}
{% set totalPaye = totalPaye + paiement.sommePayee %}
{% endif %}
{% endfor %}
{{ totalPaye }} €
</td>
<td>
<button
class="relative h-10 max-h-[40px] w-10 max-w-[40px] select-none rounded-lg
bg-gray-900 text-center align-middle font-sans text-xs font-medium uppercase
text-white shadow-md shadow-gray-900/10 transition-all hover:shadow-lg
hover:shadow-gray-900/20 focus:opacity-[0.85] focus:shadow-none
active:opacity-[0.85] active:shadow-none disabled:pointer-events-none
disabled:opacity-50 disabled:shadow-none"
type="button"
data-ripple-light="true"
data-modal-target="deleteModal"
data-modal-toggle="deleteModal"
onclick="showDeleteModal({{ recette.id }})"
>
<span class="absolute transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2">
<i class="fas fa-trash" aria-hidden="true"></i>
</span>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="overflow-x-auto mt-8">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Espece</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Carte Bancaire</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Planity</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900" id="totalEspece">{{ totalEspece }} €</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900" id="totalCarteBancaire">{{ totalCarteBancaire }} €</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900" id="totalAcompte">{{ totalAcompte }} €</td>
</tr>
</tbody>
</table>
</div>
<div class="px-6 py-4 bg-gray-50 sm:px-6">
<div class="flex items-center justify-between">
<dl class="flex items-baseline">
<dt class="sr-only">Total</dt>
<dd class="text-lg font-bold text-gray-900" id="totalJour">Total : {{ totalJour }} €</dd>
</dl>
<button id="sendRecette"
class="inline-flex items-center px-4 py-2 btn btn-primary rounded-lg shadow-md transition duration-300 ease-in-out text-sm sm:text-base">
<svg class="w-6 h-6 mr-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12 12-5.373 12-12S18.627 0 12 0zm5.562 8.131l-1.844 8.688c-.137.646-.518.816-1.05.508l-2.904-2.14-1.402 1.35c-.156.156-.285.285-.588.285l.209-2.963 5.396-4.875c.234-.205-.052-.32-.363-.115l-6.674 4.201-2.877-.9c-.625-.195-.637-.624.131-.924l11.223-4.328c.521-.193.974.121.742 1.213z"/>
</svg>
Envoyer la recette
</button>
</div>
</div>
</div>
<div id="deleteModal" tabindex="-1" class="hidden overflow-y-auto overflow-x-hidden fixed inset-0 z-50 w-full h-full flex justify-center items-center">
<div class="relative p-4 w-full max-w-md mx-auto">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<button type="button" class="absolute top-3 end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide="deleteModal">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
</svg>
<span class="sr-only">Fermer</span>
</button>
<div class="p-4 md:p-5 text-center">
<svg class="mx-auto mb-4 text-gray-400 w-12 h-12 dark:text-gray-200" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
</svg>
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">Êtes-vous sûr de vouloir supprimer cette prestation ?</h3>
<button id="confirmDelete" type="button" class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center">
Oui, je suis sûr
</button>
<button data-modal-hide="deleteModal" type="button" class="py-2.5 px-5 ms-3 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">Non, annuler</button>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="https://unpkg.com/@material-tailwind/html@latest/scripts/ripple.js"></script>
<script src="https://cdn.jsdelivr.net/npm/moment@2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
initDatePicker();
initCategorieSelect();
initRecetteForm();
document.getElementById('addPrestationLink').addEventListener('click', addPrestation);
document.getElementById('removeDiscountInput').addEventListener('click', removeDiscountInput);
document.getElementById('typePaiement').addEventListener('change', handleTypePaiementChange);
});
function handleTypePaiementChange() {
const typePaiement = this.value;
const montantEspece = document.getElementById('montantEspece');
const montantCarteBancaire = document.getElementById('montantCarteBancaire');
const paiementDetails = document.getElementById('paiementDetails');
const especeContainer = document.getElementById('especeContainer');
const carteBancaireContainer = document.getElementById('carteBancaireContainer');
if (typePaiement === '3') {
paiementDetails.style.display = 'block';
especeContainer.style.display = 'flex';
carteBancaireContainer.style.display = 'flex';
montantEspece.required = true;
montantCarteBancaire.required = true;
} else {
paiementDetails.style.display = 'none';
especeContainer.style.display = 'none';
carteBancaireContainer.style.display = 'none';
montantEspece.required = false;
montantCarteBancaire.required = false;
montantEspece.value = ''; // Réinitialiser la valeur
montantCarteBancaire.value = ''; // Réinitialiser la valeur
}
}
let prestationIndex = 1;
function addPrestation(event) {
event.preventDefault();
const prestationsContainer = document.getElementById('prestationsContainer');
const newPrestationGroup = document.createElement('div');
newPrestationGroup.classList.add('prestation-group', 'mb-4', 'flex', 'items-center');
newPrestationGroup.innerHTML = `
<div class="flex-grow">
<label for="categorie_${prestationIndex}" class="block text-gray-700">Catégorie <span style="color: red;">*</span></label>
<select name="prestations[${prestationIndex}][categorie_id]" id="categorie_${prestationIndex}" class="categorie-select mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
<option value="">Sélectionnez une catégorie</option>
{% for categorie in categories %}
<option value="{{ categorie.id }}">{{ categorie.nom }}</option>
{% endfor %}
</select>
</div>
<div class="hidden prestation-select-group mt-4 flex-grow">
<label for="prestation_${prestationIndex}" class="block text-gray-700">Prestation <span style="color: red;">*</span></label>
<select name="prestations[${prestationIndex}][prestation_id]" id="prestation_${prestationIndex}" class="prestation-select mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50" required>
<option value="">Sélectionnez une prestation</option>
</select>
</div>
<button type="button" class="remove-prestation ml-2 text-red-500 hover:text-red-700">
<i class="fas fa-times"></i>
</button>
`;
prestationsContainer.appendChild(newPrestationGroup);
prestationIndex++;
initCategorieSelect();
initRemovePrestation();
}
document.getElementById('sendRecette').addEventListener('click', function() {
const sendButton = document.getElementById('sendRecette');
sendButton.disabled = true;
fetch('/admin/recette/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
date: document.getElementById('dateInput').value
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'Message envoyé') {
toastr.success('La recette a bien été envoyée', 'Succès');
} else {
toastr.error('Erreur lors de l\'envoi de la recette', 'Erreur');
}
})
.catch(error => {
console.error('Erreur:', error);
toastr.error('Erreur lors de l\'envoi de la recette', 'Erreur');
})
.finally(() => {
sendButton.disabled = false;
});
});
let recetteIdToDelete;
function showDeleteModal(id) {
recetteIdToDelete = id;
const modal = document.getElementById('deleteModal');
modal.classList.remove('hidden');
modal.classList.add('flex');
}
function hideDeleteModal() {
const modal = document.getElementById('deleteModal');
modal.classList.add('hidden');
modal.classList.remove('flex');
}
function deleteRecette() {
fetch(`/admin/delete/recette/${recetteIdToDelete}`, {
method: 'DELETE'
}).then(response => {
console.log('Réponse brute:', response);
return response.text();
}).then(text => {
console.log('Texte de la réponse:', text);
return JSON.parse(text);
}).then(data => {
if (data.status === 'success') {
const row = document.querySelector(`tr[data-id="${recetteIdToDelete}"]`);
if (row) row.remove();
hideDeleteModal();
updateTotals(data.totals);
checkTableEmpty();
} else {
throw new Error(data.error || 'Erreur inconnue');
}
}).catch(error => {
console.error('Erreur:', error);
alert('Une erreur est survenue lors de la suppression');
});
}
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('confirmDelete').addEventListener('click', deleteRecette);
document.querySelectorAll('[data-modal-hide="deleteModal"]').forEach(button => {
button.addEventListener('click', hideDeleteModal);
});
});
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('confirmDelete').addEventListener('click', deleteRecette);
});
function updateTotals(totals) {
document.getElementById('totalJour').textContent = `Total : ${totals.totalJour} €`;
document.getElementById('totalEspece').textContent = `${totals.totalEspece} €`;
document.getElementById('totalCarteBancaire').textContent = `${totals.totalCarteBancaire} €`;
document.getElementById('totalAcompte').textContent = `${totals.totalAcompte} €`;
}
function checkTableEmpty() {
const table = document.getElementById('recettesTable').getElementsByTagName('tbody')[0];
if (table.rows.length === 0) {
document.getElementById('recettesContainer').style.display = 'none';
}
}
function initCategorieSelect() {
document.querySelectorAll('.categorie-select').forEach(select => {
select.addEventListener('change', function () {
const selectedCategoryId = parseInt(this.value);
const prestationSelectGroup = this.closest('.prestation-group').querySelector('.prestation-select-group');
const prestationSelect = prestationSelectGroup.querySelector('.prestation-select');
prestationSelect.innerHTML = '<option value="">Sélectionnez une prestation</option>';
fetch(`/admin/prestations/${selectedCategoryId}`)
.then(response => response.json())
.then(data => {
if (data.length > 0) {
prestationSelectGroup.classList.remove('hidden');
data.forEach(prestation => {
const option = document.createElement('option');
option.value = prestation.id;
option.textContent = `${prestation.nom} (${prestation.prix}€)`;
prestationSelect.appendChild(option);
});
} else {
prestationSelectGroup.classList.add('hidden');
}
})
.catch(error => console.error('Erreur lors de la récupération des prestations:', error));
});
});
}
function initRemovePrestation() {
document.querySelectorAll('.remove-prestation').forEach(button => {
button.addEventListener('click', function () {
this.closest('.prestation-group').remove();
});
});
}
function removeDiscountInput() {
document.getElementById('discountInputContainer').style.display = 'none';
}
function initRemovePaiement() {
document.querySelectorAll('.remove-paiement').forEach(button => {
button.addEventListener('click', function () {
this.closest('.paiement-group').remove();
});
});
}
function initRecetteForm() {
document.getElementById('recetteForm').addEventListener('submit', function(event) {
event.preventDefault();
const formData = new FormData(this);
const nomClient = formData.get('nom_client');
const acompte = parseFloat(formData.get('acompte'));
const prixPayeSurPlace = parseFloat(formData.get('prix_paye_sur_place'));
const date = formData.get('date');
const prestations = [];
document.querySelectorAll('.prestation-group').forEach((group, index) => {
const categorieId = group.querySelector('.categorie-select').value;
const prestationId = group.querySelector('.prestation-select').value;
prestations.push({ categorie_id: categorieId, prestation_id: prestationId });
});
const typePaiementId = formData.get('type_paiement_id');
const resteAPayer = parseFloat(formData.get('reste_a_payer'));
const montantEspece = parseFloat(formData.get('montant_espece'));
const montantCarteBancaire = parseFloat(formData.get('montant_carte_bancaire'));
const data = {
nomClient: nomClient,
date: date,
prestations: prestations,
typePaiementId: typePaiementId,
};
if (acompte) {
data.acompte = acompte;
}
if (prixPayeSurPlace) {
data.prixPayeSurPlace = prixPayeSurPlace;
}
if (resteAPayer) {
data.resteAPayer = resteAPayer;
data.sommePayee = resteAPayer;
}
if (typePaiementId === '3') {
if (!montantEspece && !montantCarteBancaire) {
toastr.error('Veuillez renseigner les montants pour les paiements en espèce et carte bancaire', 'Erreur');
return;
}
if (resteAPayer && montantEspece + montantCarteBancaire !== resteAPayer) {
toastr.error('La somme des montants des paiements en espèce et carte bancaire doit être égale au montant payé sur place', 'Erreur');
return;
}
data.montantEspece = montantEspece || 0;
data.montantCarteBancaire = montantCarteBancaire || 0;
data.sommePayee = (montantEspece || 0) + (montantCarteBancaire || 0) + (acompte || 0);
}
fetch('/admin/recette/ajax', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
updateTable(data.recette, data.totals);
} else {
console.error('Erreur: ', data.message);
}
})
.catch(error => console.error('Erreur:', error));
});
}
function updateTable(recette, totals) {
const table = document.getElementById('recettesTable').getElementsByTagName('tbody')[0];
const newRow = table.insertRow(table.rows.length);
newRow.setAttribute('data-id', recette.id);
newRow.innerHTML = `
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${recette.nomClient}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<ul>
${recette.prestations.map(prestation => `<li>${prestation.nom}</li>`).join('')}
</ul>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${recette.acompte ? recette.acompte + ' €' : '-'}</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<ul>
${recette.paiements.map(paiement => `<li>${paiement.sommePayee ? paiement.sommePayee + ' €' : '-'}</li>`).join('')}
</ul>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<ul>
${recette.paiements.map(paiement => `<li>${paiement.typePaiement.nom}</li>`).join('')}
</ul>
</td>
<td>
<button
class="relative h-10 max-h-[40px] w-10 max-w-[40px] select-none
rounded-lg bg-gray-900 text-center align-middle font-sans text-xs font-medium
uppercase text-white shadow-md shadow-gray-900/10 transition-all hover:shadow-lg
hover:shadow-gray-900/20 focus:opacity-[0.85] focus:shadow-none
active:opacity-[0.85] active:shadow-none disabled:pointer-events-none
disabled:opacity-50 disabled:shadow-none"
type="button"
data-ripple-light="true"
data-modal-target="deleteModal"
data-modal-toggle="deleteModal"
onclick="showDeleteModal(${recette.id})"
>
<span class="absolute transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2">
<i class="fas fa-trash" aria-hidden="true"></i>
</span>
</button>
</td>`;
document.getElementById('totalJour').textContent = `Total : ${totals.totalJour} €`;
document.getElementById('totalEspece').textContent = `${totals.totalEspece} €`;
document.getElementById('totalCarteBancaire').textContent = `${totals.totalCarteBancaire} €`;
document.getElementById('totalAcompte').textContent = `${totals.totalAcompte} €`;
document.getElementById('recettesContainer').style.display = 'block';
}
function showDiscountInput() {
var discountInputContainer = document.getElementById('discountInputContainer');
discountInputContainer.style.display = 'block';
}
function initDatePicker() {
const urlDate = new URLSearchParams(window.location.search).get('date');
const parsedDate = urlDate ? flatpickr.parseDate(urlDate, "d/m/Y") : new Date();
const fp = flatpickr("#dateDisplay", {
enableTime: false,
dateFormat: "d/m/Y",
defaultDate: parsedDate,
locale: {
firstDayOfWeek: 1,
weekdays: {
shorthand: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
longhand: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
},
months: {
shorthand: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'],
longhand: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
},
},
onClose: function(selectedDates, dateStr, instance) {
window.location.href = `${window.location.pathname}?date=${dateStr}`;
},
disableMobile: true // Désactive l'interface mobile de Flatpickr
});
const months = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'];
const day = parsedDate.getDate();
const month = months[parsedDate.getMonth()];
const year = parsedDate.getFullYear();
document.getElementById('dateDisplay').innerText = `${day} ${month} ${year}`;
}
function openCalendar() {
document.querySelector('#dateDisplay').click(); // Correction : Utilisez l'ID unique pour ouvrir le calendrier
}
function initClientAutocomplete() {
const nomClientInput = document.getElementById('nomClient');
let timeoutId;
nomClientInput.addEventListener('input', function(e) {
clearTimeout(timeoutId);
const searchValue = e.target.value;
timeoutId = setTimeout(() => {
if (searchValue.length >= 1) {
fetch(`/admin/search-clients-planity?q=${encodeURIComponent(searchValue)}`)
.then(response => response.json())
.then(data => {
showSuggestions(data.hits || []);
})
.catch(error => console.error('Erreur:', error));
} else {
hideSuggestions();
}
}, 300);
});
// Créer et ajouter le conteneur de suggestions
const suggestionsContainer = document.createElement('div');
suggestionsContainer.id = 'clientSuggestions';
suggestionsContainer.className = 'absolute z-10 w-full bg-white border border-gray-300 rounded-md shadow-lg hidden';
nomClientInput.parentNode.style.position = 'relative';
nomClientInput.parentNode.appendChild(suggestionsContainer);
function showSuggestions(suggestions) {
const container = document.getElementById('clientSuggestions');
container.innerHTML = '';
if (suggestions.length > 0) {
suggestions.forEach(suggestion => {
const div = document.createElement('div');
div.className = 'p-2 hover:bg-gray-100 cursor-pointer';
div.textContent = suggestion.name;
div.onclick = () => {
nomClientInput.value = suggestion.name;
hideSuggestions();
};
container.appendChild(div);
});
container.classList.remove('hidden');
} else {
hideSuggestions();
}
}
function hideSuggestions() {
const container = document.getElementById('clientSuggestions');
container.classList.add('hidden');
}
// Cacher les suggestions quand on clique ailleurs
document.addEventListener('click', function(e) {
if (!nomClientInput.contains(e.target) && !suggestionsContainer.contains(e.target)) {
hideSuggestions();
}
});
}
// Ajouter l'appel Ă initClientAutocomplete dans le DOMContentLoaded
document.addEventListener('DOMContentLoaded', function() {
// ... autres initialisations ...
initClientAutocomplete();
});
</script>
{% endblock %}