Every save now forces a new revision, unconditionally: - Form: hide the "Create new revision" checkbox and the log message field (#access = FALSE, not just a default) so submitted values for either can't override them -- Form API discards user input for #access-denied elements and falls back to #default_value. - hook_node_presave(): the same thing enforced for any save that doesn't go through the form (drush scripts, etc.), plus explicitly setting the revision author (current user) and revision timestamp. setNewRevision(TRUE) alone does NOT refresh revision_timestamp -- it carries over the previous revision's value, which would silently mislabel every edit with its predecessor's save time. Verified via a drush test save before/after. - Applies regardless of figli_compta_ledger.skip_validation: that flag is about the répartition-sum check on historical imports, a different concern -- revision history is never exempted. New /lignes/historique page (HistoryController): a single reverse- chronological feed across every ligne_comptable's revisions, gated by the 'view ligne_comptable revisions' permission (granted to all three associate roles). Conceptually a revision of one ligne is a revision of the grand livre as a whole, so this aggregates across nodes rather than reusing Drupal's per-node revision history page. Each row links to that specific revision via core's existing revision-view route. Linked from the /lignes toolbar, shown only when the current user has the permission. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
116 lines
4.9 KiB
Twig
116 lines
4.9 KiB
Twig
{#
|
|
Dashboard shell: Drupal renders the page (nav, auth, permissions).
|
|
dashboard.js (Vue 3) fetches JSON:API and renders a spreadsheet-like table
|
|
of every ligne comptable, with filters and month/year grouping, client-side.
|
|
"Ajouter une ligne" opens the real Drupal node form in a modal
|
|
(core/drupal.dialog.ajax) -- no form logic duplicated in JS.
|
|
#}
|
|
{% verbatim %}
|
|
<div id="figli-home-app">
|
|
<div class="figli-toolbar">
|
|
<a href="/node/add/ligne_comptable" class="button button--primary" @click.prevent="openAddForm">+ Ajouter une ligne</a>
|
|
{% endverbatim %}
|
|
{% if can_view_history %}
|
|
<a href="{{ path('figli_compta_ledger.history') }}" class="button">Historique</a>
|
|
{% endif %}
|
|
{% verbatim %}
|
|
|
|
<label>Compte
|
|
<select v-model="filterCompte">
|
|
<option value="">Tous</option>
|
|
<option v-for="c in allComptes" :key="c" :value="c">{{ c }}</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label>Client
|
|
<select v-model="filterClient">
|
|
<option value="">Tous</option>
|
|
<option v-for="c in allClients" :key="c" :value="c">{{ c }}</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label>Type
|
|
<select v-model="filterType">
|
|
<option value="">Tous</option>
|
|
<option v-for="t in allTypes" :key="t.value" :value="t.value">{{ t.label }}</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label>Année
|
|
<select v-model="filterYear">
|
|
<option value="">Toutes</option>
|
|
<option v-for="y in allYears" :key="y" :value="y">{{ y }}</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label>Regrouper par
|
|
<select v-model="groupBy">
|
|
<option value="none">Aucun</option>
|
|
<option value="month">Mois</option>
|
|
<option value="year">Année</option>
|
|
</select>
|
|
</label>
|
|
|
|
<label class="figli-checkbox">
|
|
<input type="checkbox" v-model="onlyErrors" /> Écarts uniquement
|
|
</label>
|
|
|
|
<span class="figli-count" v-if="!loading">{{ filteredRows.length }} / {{ rows.length }} lignes{{ errorCount ? ' — ' + errorCount + ' avec écart' : '' }}</span>
|
|
</div>
|
|
|
|
<p v-if="loading">Chargement des données…</p>
|
|
<p v-else-if="error" class="figli-error">Erreur de chargement : {{ error }}</p>
|
|
<div v-else class="figli-table-wrap">
|
|
<table ref="tableEl" @mouseover="onCellHover" @mouseleave="clearColHover">
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Client</th>
|
|
<th>Type</th>
|
|
<th>Libellé / Détail</th>
|
|
<th class="amount">Montant HT</th>
|
|
<th class="amount">Montant TTC</th>
|
|
<th v-for="c in allComptes" :key="c" class="amount compte-col">{{ c }}</th>
|
|
<th class="amount">Écart</th>
|
|
<th class="actions-col"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-for="item in groupedRows" :key="item.key">
|
|
<tr v-if="item.isGroup" class="figli-group-row">
|
|
<td :colspan="6 + allComptes.length + 2">{{ item.label }} <span class="figli-note">({{ item.count }} lignes)</span></td>
|
|
</tr>
|
|
<tr v-else :class="{'figli-error-row': item.hasError}">
|
|
<td>{{ item.date }}</td>
|
|
<td>{{ item.client || '—' }}</td>
|
|
<td><span class="figli-badge" :class="'type-' + item.type">{{ typeLabel(item.type) }}</span></td>
|
|
<td class="figli-libelle">{{ item.libelle }}</td>
|
|
<td class="amount">{{ formatEur(item.montant_ht) }}</td>
|
|
<td class="amount">{{ formatEur(item.montant_ttc) }}</td>
|
|
<td v-for="c in allComptes" :key="c" class="amount compte-col">{{ item.parCompte[c] !== undefined ? formatEur(item.parCompte[c]) : '' }}</td>
|
|
<td class="amount" :class="{'figli-ecart': item.hasError}">{{ item.hasError ? formatEur(item.ecart) : '' }}</td>
|
|
<td class="actions-col">
|
|
<button type="button" class="figli-edit-btn" title="Modifier" @click="openEditForm(item.nid)">
|
|
<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M13.5 3.5l3 3L6 17l-3.5.5.5-3.5L13.5 3.5z" />
|
|
</svg>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
</template>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="figli-totals-row">
|
|
<td colspan="4">Solde (créditeur / débiteur) — {{ filteredRows.length }} lignes filtrées</td>
|
|
<td class="amount">{{ formatEur(footerTotals.montant_ht) }}</td>
|
|
<td class="amount">{{ formatEur(footerTotals.montant_ttc) }}</td>
|
|
<td v-for="c in allComptes" :key="c" class="amount compte-col" :class="soldeClass(footerTotals.parCompte[c])">{{ formatEur(footerTotals.parCompte[c]) }}</td>
|
|
<td class="amount" :class="soldeClass(footerTotals.ecart)">{{ formatEur(footerTotals.ecart) }}</td>
|
|
<td class="actions-col"></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% endverbatim %}
|