@php $analyse = $this->analyse(); $series = $analyse['series']; $parMois = $this->previsionsParMois(); $fenetre = $analyse['fenetre']; $regulieresNonDeclarees = collect($series) ->filter(fn (array $s) => ! ($s['declaree'] ?? false) && ($s['regularite'] ?? 0) >= 0.7); @endphp {{-- La prévision fiable, c'est la charge déclarée : la table existe, elle était vide. Ce bandeau pousse à y inscrire ce que le journal répète déjà — le bouton est sur chaque ligne des séries, plus bas. --}} @if ($regulieresNonDeclarees->isNotEmpty())
{{ $regulieresNonDeclarees->count() }} série{{ $regulieresNonDeclarees->count() > 1 ? 's' : '' }} régulière{{ $regulieresNonDeclarees->count() > 1 ? 's' : '' }} ({{ $regulieresNonDeclarees->pluck('libelle')->take(3)->implode(', ') }}{{ $regulieresNonDeclarees->count() > 3 ? '…' : '' }}) n'{{ $regulieresNonDeclarees->count() > 1 ? 'ont' : 'a' }} pas de charge récurrente déclarée. Les inscrire — bouton « Inscrire en charge récurrente » sur chaque ligne des séries observées — rend la prévision indépendante des libellés du journal.
@endif D'où sortent ces chiffres

Rien n'est estimé à vue. Les {{ \App\Domaines\Comptabilite\Services\ChargesRecurrentesObservees::FENETRE_MOIS }} derniers mois du journal — du {{ $fenetre['du']->format('d/m/Y') }} au {{ $fenetre['au']->format('d/m/Y') }} — sont relus, les dépenses regroupées par catégorie et par tiers, et une série n'est retenue que si ses passages se répètent à cadence mensuelle, trimestrielle ou annuelle, pour un montant voisin d'une fois sur l'autre.

Le montant annoncé est la médiane des montants observés — non leur moyenne, qu'un passage exceptionnel suffirait à emporter. La régularité dit quelle part des passages attendus a réellement eu lieu, et quelle part des montants reste voisine de la médiane.

Chaque prévision s'ouvre sur les opérations qui la fondent : un chiffre qu'on ne peut pas remonter jusqu'à ses écritures n'a rien à faire ici. Le bouton « Mettre en mots » demande à l'IA un commentaire de ce tableau — elle ne produit aucun chiffre, et sa réponse est écartée si elle en avance un.

{{-- La lecture par l'IA : un commentaire, jamais la source. --}} @if ($this->lecture) Ce que ce tableau dit Rédigé par l'IA à partir des seuls chiffres ci-dessous. Aucun montant n'en sort.
{{ $this->lecture }}
@elseif ($this->lectureMotif) Lecture écartée
{{ $this->lectureMotif }}
@if ($this->lectureEcarts)
Chiffres avancés qui ne sortent pas du calcul : {{ implode(', ', $this->lectureEcarts) }}
@endif
@endif @if ($series === [])
Aucune charge récurrente ne se dégage encore du journal.
Il faut au moins trois passages d'une même charge, à cadence régulière et pour un montant voisin, pour qu'une prévision soit calculable. Mieux vaut ne rien annoncer que d'annoncer un chiffre qui ne tiendra pas.
@else {{-- Ce qui va tomber, mois par mois. --}} Ce qui va tomber Les {{ \App\Domaines\Comptabilite\Services\ChargesRecurrentesObservees::HORIZON_MOIS }} prochains mois, déduits des passages observés. @if ($parMois === [])
Aucune échéance annoncée : les séries observées ont toutes cessé de passer, ou leur cadence ne permet pas de dire quand elles reviendront.
@else
@foreach ($parMois as $mois => $previsions) @php $total = round(array_sum(array_column($previsions, 'montant')), 2); $libelleMois = \Illuminate\Support\Carbon::createFromFormat('Y-m-d', $mois.'-01') ->locale('fr')->isoFormat('MMMM YYYY'); @endphp
{{ $libelleMois }}
{{ dh($total) }}
@foreach ($previsions as $prevision) @endforeach
{{ $prevision['date']->format('d/m/Y') }} {{ $prevision['libelle'] }} {{ $prevision['cadence'] }}, {{ $prevision['regularite_dite'] }}, {{ $prevision['occurrences'] }} passage(s) observé(s) @if ($prevision['passee']) attendue et non constatée @endif {{ dh($prevision['montant']) }} {{ ($this->operationsAction)(['cle' => $prevision['serie']]) }}
@endforeach
@endif
{{-- Les séries elles-mêmes, ce qu'elles valent et ce qui mérite l'œil. --}} Les séries observées Ce que le journal montre de répétitif, et ce qui s'en écarte. Une série peut être inscrite parmi les charges récurrentes déclarées — c'est une proposition, aucune écriture n'est créée.
@foreach ($series as $serie) @endforeach
Charge Cadence Montant attendu Régularité Dernier passage Déclarée
{{ $serie['libelle'] }}
@foreach ($serie['signaux'] as $signal)
in_array($signal['nature'], ['doublee', 'disparue'], true), 'text-warning-600 dark:text-warning-400' => in_array($signal['nature'], ['hausse', 'baisse'], true), ])>{{ $signal['texte'] }}
@endforeach
{{ $serie['cadence'] }} {{ dh($serie['montant_attendu']) }} {{ $serie['regularite_dite'] }} ({{ $serie['occurrences'] }} passages) {{ $serie['derniere']->locale('fr')->isoFormat('MMM YYYY') }} — {{ dh($serie['dernier_montant']) }} @if ($serie['declaree']) déjà déclarée @else @if ($this->declarerAction()->isVisible()) {{ ($this->declarerAction)(['cle' => $serie['cle']]) }} @endif @endif
@endif