Files

385 lines
22 KiB
HTML

<!DOCTYPE html>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
template="/templates/main-template.xhtml">
<ui:define name="title">Caisse de l'Entité - UnionFlow</ui:define>
<ui:define name="content">
<!-- En-tête -->
<div class="grid">
<div class="col-12">
<div class="card">
<div class="flex align-items-center justify-content-between">
<div>
<h3 class="mb-2">
<i class="pi pi-wallet text-purple-500 mr-2"></i>
Caisse de l'Entité
</h3>
<p class="text-600 m-0">#{caisseBean.nomEntite} • Dernière mise à jour: #{caisseBean.derniereMAJ}</p>
</div>
<div class="flex gap-2">
<p:commandButton value="Nouvelle entrée"
icon="pi pi-plus-circle"
styleClass="ui-button-success"
onclick="PF('dlgNouvelleEntree').show();" />
<p:commandButton value="Nouvelle sortie"
icon="pi pi-minus-circle"
styleClass="ui-button-danger"
onclick="PF('dlgNouvelleSortie').show();" />
<p:commandButton value="Rapprochement"
icon="pi pi-sync"
styleClass="ui-button-outlined ui-button-info"
action="#{caisseBean.rapprochement}" />
</div>
</div>
</div>
</div>
</div>
<!-- Soldes et Statistiques -->
<div class="formgrid grid">
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Solde Principal" />
<ui:param name="value" value="#{caisseBean.soldePrincipal}" />
<ui:param name="icon" value="pi-wallet" />
<ui:param name="iconColor" value="purple-600" />
<ui:param name="showGrowth" value="false" />
<ui:param name="showProgress" value="false" />
</ui:include>
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Entrées (30j)" />
<ui:param name="value" value="#{caisseBean.totalEntrees}" />
<ui:param name="icon" value="pi-arrow-down" />
<ui:param name="iconColor" value="green-600" />
<ui:param name="showGrowth" value="false" />
<ui:param name="showProgress" value="false" />
</ui:include>
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Sorties (30j)" />
<ui:param name="value" value="#{caisseBean.totalSorties}" />
<ui:param name="icon" value="pi-arrow-up" />
<ui:param name="iconColor" value="red-600" />
<ui:param name="showGrowth" value="false" />
<ui:param name="showProgress" value="false" />
</ui:include>
<ui:include src="/templates/components/cards/kpi-card.xhtml">
<ui:param name="title" value="Wave Money" />
<ui:param name="value" value="#{caisseBean.soldeWaveMoney}" />
<ui:param name="icon" value="pi-mobile" />
<ui:param name="iconColor" value="blue-600" />
<ui:param name="showGrowth" value="false" />
<ui:param name="showProgress" value="false" />
</ui:include>
</div>
<!-- Graphiques -->
<div class="grid">
<div class="col-12 md:col-8">
<div class="card">
<h5>Évolution du Solde</h5>
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique temporaire</div></div><!--chart
-->
</div>
</div>
<div class="col-12 md:col-4">
<div class="card">
<h5>Répartition par Catégorie</h5>
<div class="surface-100 p-4 border-round text-center"><div class="text-2xl font-bold text-primary mb-2">📊</div><div class="text-600">Graphique temporaire</div></div><!--chart
-->
</div>
</div>
</div>
<!-- Journal de Caisse -->
<div class="card">
<h:form id="formCaisse">
<h5>Journal de Caisse</h5>
<!-- Filtres -->
<p:toolbar>
<p:toolbarGroup>
<div class="flex align-items-center gap-2">
<p:calendar id="dateDebut" value="#{caisseBean.dateDebut}"
pattern="dd/MM/yyyy" showIcon="true"
placeholder="Date début">
<p:ajax event="dateSelect" update="dtMouvements" />
</p:calendar>
<p:calendar id="dateFin" value="#{caisseBean.dateFin}"
pattern="dd/MM/yyyy" showIcon="true"
placeholder="Date fin">
<p:ajax event="dateSelect" update="dtMouvements" />
</p:calendar>
<p:selectOneMenu value="#{caisseBean.typeFilter}">
<f:selectItem itemLabel="Tous" itemValue="" />
<f:selectItem itemLabel="Entrées" itemValue="ENTREE" />
<f:selectItem itemLabel="Sorties" itemValue="SORTIE" />
<p:ajax update="dtMouvements" />
</p:selectOneMenu>
<p:selectOneMenu value="#{caisseBean.categorieFilter}">
<f:selectItem itemLabel="Toutes catégories" itemValue="" />
<f:selectItem itemLabel="Cotisations" itemValue="COTISATION" />
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
<f:selectItem itemLabel="Aides" itemValue="AIDE" />
<f:selectItem itemLabel="Frais admin" itemValue="FRAIS_ADMIN" />
<f:selectItem itemLabel="Autres" itemValue="AUTRE" />
<p:ajax update="dtMouvements" />
</p:selectOneMenu>
</div>
</p:toolbarGroup>
<p:toolbarGroup align="right">
<p:commandButton value="Imprimer"
icon="pi pi-print"
styleClass="ui-button-outlined ui-button-secondary mr-2"
action="#{caisseBean.imprimer}" />
<p:commandButton value="Exporter"
icon="pi pi-file-excel"
styleClass="ui-button-outlined ui-button-success"
action="#{caisseBean.exporter}" />
</p:toolbarGroup>
</p:toolbar>
<!-- DataTable Mouvements -->
<p:dataTable id="dtMouvements"
var="mouvement"
value="#{caisseBean.mouvements}"
paginator="true"
rows="15"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
currentPageReportTemplate="Affichage {startRecord}-{endRecord} sur {totalRecords}"
rowKey="#{mouvement.id}"
styleClass="mt-3">
<p:column headerText="Date" sortBy="#{mouvement.date}" style="width:120px">
<h:outputText value="#{mouvement.date}">
<f:convertDateTime pattern="dd/MM/yyyy HH:mm" type="localDateTime" />
</h:outputText>
</p:column>
<p:column headerText="Référence" sortBy="#{mouvement.reference}" style="width:120px">
<h:outputText value="#{mouvement.reference}" styleClass="font-mono" />
</p:column>
<p:column headerText="Libellé" sortBy="#{mouvement.libelle}">
<h:outputText value="#{mouvement.libelle}" />
</p:column>
<p:column headerText="Catégorie" sortBy="#{mouvement.categorie}" style="width:150px">
<p:tag value="#{mouvement.categorie}" styleClass="#{mouvement.categorieClass}" />
</p:column>
<p:column headerText="Entrée" style="width:120px">
<h:outputText value="#{mouvement.montantEntree}"
styleClass="text-green-600 font-bold"
rendered="#{mouvement.type == 'ENTREE'}">
<f:convertNumber type="currency" currencySymbol="+" />
</h:outputText>
</p:column>
<p:column headerText="Sortie" style="width:120px">
<h:outputText value="#{mouvement.montantSortie}"
styleClass="text-red-600 font-bold"
rendered="#{mouvement.type == 'SORTIE'}">
<f:convertNumber type="currency" currencySymbol="-" />
</h:outputText>
</p:column>
<p:column headerText="Solde" style="width:120px">
<h:outputText value="#{mouvement.soldeApres}" styleClass="font-bold">
<f:convertNumber type="currency" currencySymbol="" />
</h:outputText>
</p:column>
<p:column headerText="Mode" style="width:100px">
<div class="flex align-items-center">
<i class="pi #{mouvement.modeIcon} mr-2"></i>
<span>#{mouvement.modePaiement}</span>
</div>
</p:column>
<p:column headerText="Validé" style="width:80px; text-align: center;">
<i class="pi pi-check-circle text-green-500"
rendered="#{mouvement.valide}"
title="Validé le #{mouvement.dateValidation}" />
<i class="pi pi-clock text-orange-500"
rendered="#{!mouvement.valide}"
title="En attente de validation" />
</p:column>
<p:column headerText="Actions" style="width:120px">
<div class="flex gap-2">
<p:commandButton icon="pi pi-check"
styleClass="ui-button-rounded ui-button-text ui-button-success"
action="#{caisseBean.validerMouvement(mouvement)}"
title="Valider"
rendered="#{!mouvement.valide}" />
<p:commandButton icon="pi pi-file"
styleClass="ui-button-rounded ui-button-text ui-button-info"
action="#{caisseBean.voirJustificatif(mouvement)}"
title="Justificatif" />
<p:commandButton icon="pi pi-times"
styleClass="ui-button-rounded ui-button-text ui-button-danger"
action="#{caisseBean.annulerMouvement(mouvement)}"
onclick="return confirm('Êtes-vous sûr de vouloir annuler ce mouvement ?');"
title="Annuler"
rendered="#{!mouvement.valide}" />
</div>
</p:column>
</p:dataTable>
<!-- Totaux -->
<div class="mt-3 p-3 surface-100 border-round">
<div class="grid">
<div class="col-12 md:col-4">
<div class="text-center">
<div class="text-600">Total Entrées</div>
<div class="text-2xl font-bold text-green-600">#{caisseBean.totalEntreesPeriode}</div>
</div>
</div>
<div class="col-12 md:col-4">
<div class="text-center">
<div class="text-600">Total Sorties</div>
<div class="text-2xl font-bold text-red-600">#{caisseBean.totalSortiesPeriode}</div>
</div>
</div>
<div class="col-12 md:col-4">
<div class="text-center">
<div class="text-600">Solde Période</div>
<div class="text-2xl font-bold text-purple-600">#{caisseBean.soldePeriode}</div>
</div>
</div>
</div>
</div>
</h:form>
</div>
<!-- Dialog Nouvelle Entrée -->
<p:dialog header="Nouvelle Entrée" widgetVar="dlgNouvelleEntree" modal="true" width="500">
<h:form id="formNouvelleEntree">
<div class="ui-fluid">
<div class="field">
<p:outputLabel for="libelleEntree" value="Libellé" />
<p:inputText id="libelleEntree" value="#{caisseBean.nouvelleEntree.libelle}" required="true" />
</div>
<div class="field">
<p:outputLabel for="montantEntree" value="Montant" />
<p:inputNumber id="montantEntree" value="#{caisseBean.nouvelleEntree.montant}"
symbol=" FCFA" symbolPosition="s" required="true" />
</div>
<div class="field">
<p:outputLabel for="categorieEntree" value="Catégorie" />
<p:selectOneMenu id="categorieEntree" value="#{caisseBean.nouvelleEntree.categorie}" required="true">
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
<f:selectItem itemLabel="Cotisations" itemValue="COTISATION" />
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
<f:selectItem itemLabel="Dons" itemValue="DON" />
<f:selectItem itemLabel="Autres" itemValue="AUTRE" />
</p:selectOneMenu>
</div>
<div class="field">
<p:outputLabel for="modeEntree" value="Mode de paiement" />
<p:selectOneMenu id="modeEntree" value="#{caisseBean.nouvelleEntree.modePaiement}" required="true">
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
<f:selectItem itemLabel="Wave Money" itemValue="WAVE" />
<f:selectItem itemLabel="Virement" itemValue="VIREMENT" />
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
</p:selectOneMenu>
</div>
<div class="field">
<p:outputLabel for="justificatifEntree" value="Justificatif" />
<p:fileUpload id="justificatifEntree" mode="simple" skinSimple="true" />
</div>
</div>
<div class="flex gap-2 mt-3">
<p:commandButton value="Enregistrer" icon="pi pi-check"
styleClass="ui-button-success"
action="#{caisseBean.enregistrerEntree}"
update="@form :formCaisse"
oncomplete="if(!args.validationFailed) PF('dlgNouvelleEntree').hide();" />
<p:commandButton value="Annuler" icon="pi pi-times"
styleClass="ui-button-secondary"
onclick="PF('dlgNouvelleEntree').hide();" type="button" />
</div>
</h:form>
</p:dialog>
<!-- Dialog Nouvelle Sortie -->
<p:dialog header="Nouvelle Sortie" widgetVar="dlgNouvelleSortie" modal="true" width="500">
<h:form id="formNouvelleSortie">
<div class="ui-fluid">
<div class="field">
<p:outputLabel for="libelleSortie" value="Libellé" />
<p:inputText id="libelleSortie" value="#{caisseBean.nouvelleSortie.libelle}" required="true" />
</div>
<div class="field">
<p:outputLabel for="montantSortie" value="Montant" />
<p:inputNumber id="montantSortie" value="#{caisseBean.nouvelleSortie.montant}"
symbol=" FCFA" symbolPosition="s" required="true" />
</div>
<div class="field">
<p:outputLabel for="categorieSortie" value="Catégorie" />
<p:selectOneMenu id="categorieSortie" value="#{caisseBean.nouvelleSortie.categorie}" required="true">
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
<f:selectItem itemLabel="Aides" itemValue="AIDE" />
<f:selectItem itemLabel="Frais administratifs" itemValue="FRAIS_ADMIN" />
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
<f:selectItem itemLabel="Autres" itemValue="AUTRE" />
</p:selectOneMenu>
</div>
<div class="field">
<p:outputLabel for="beneficiaireSortie" value="Bénéficiaire" />
<p:inputText id="beneficiaireSortie" value="#{caisseBean.nouvelleSortie.beneficiaire}" />
</div>
<div class="field">
<p:outputLabel for="modeSortie" value="Mode de paiement" />
<p:selectOneMenu id="modeSortie" value="#{caisseBean.nouvelleSortie.modePaiement}" required="true">
<f:selectItem itemLabel="Sélectionner..." itemValue="" />
<f:selectItem itemLabel="Espèces" itemValue="ESPECES" />
<f:selectItem itemLabel="Wave Money" itemValue="WAVE" />
<f:selectItem itemLabel="Virement" itemValue="VIREMENT" />
<f:selectItem itemLabel="Chèque" itemValue="CHEQUE" />
</p:selectOneMenu>
</div>
<div class="field">
<p:outputLabel for="justificatifSortie" value="Justificatif" />
<p:fileUpload id="justificatifSortie" mode="simple" skinSimple="true" />
</div>
</div>
<div class="flex gap-2 mt-3">
<p:commandButton value="Enregistrer" icon="pi pi-check"
styleClass="ui-button-danger"
action="#{caisseBean.enregistrerSortie}"
update="@form :formCaisse"
oncomplete="if(!args.validationFailed) PF('dlgNouvelleSortie').hide();" />
<p:commandButton value="Annuler" icon="pi pi-times"
styleClass="ui-button-secondary"
onclick="PF('dlgNouvelleSortie').hide();" type="button" />
</div>
</h:form>
</p:dialog>
</ui:define>
</ui:composition>