@php use App\Support\Money; @endphp @extends('pdf.layout-rapport') @section('content') {{-- v3.5 §2 — « Je veux tous les détails disponibles de A à Z ». Onze sections, dans un ordre stable, chacune avec son sous-total. Long et complet plutôt que court et partiel : c'est exactement le reproche fait au rapport précédent, qui ne reprenait qu'une fraction de ce que l'écran montrait. --}} {{-- ─── 1. Identité ────────────────────────────────────────────────────────────────────── --}}
| {{ $cle }} | {{ $valeur }} |
Contractuel, facturé, encaissé, reste à encaisser. Jamais mélangés : un marché entièrement facturé et pas encore payé n'est pas un marché déficitaire, c'est un marché qui attend son règlement.
| Ligne | Ce qu'elle mesure | HT | TTC |
|---|---|---|---|
| Contractuel | Le montant du marché, tel que la fiche le porte | {{ Money::format($position['contractuel_ht']) }} | {{ Money::format($position['contractuel_ttc']) }} |
| Facturé | {{ $position['nombre_factures'] }} facture(s) émise(s), brouillons et annulations exclus | {{ Money::format($position['facture_ht']) }} | {{ Money::format($position['facture_ttc']) }} |
| Encaissé | {{ $position['nombre_factures_encaissees'] }} facture(s) réglée(s) | {{ Money::format($position['encaisse_ht']) }} | {{ Money::format($position['encaisse_ttc']) }} |
| Reste à encaisser | Facturé − encaissé : ce que le client doit encore | {{ Money::format($position['reste_a_encaisser_ht']) }} | {{ Money::format($position['reste_a_encaisser_ttc']) }} |
| Reste à facturer | Contractuel − facturé : ce qui n'a pas encore été émis | — | {{ Money::format($position['reste_a_facturer_ttc']) }} |
| Pour compte de tiers | {{ $position['nombre_hors_tresorerie'] }} facture(s) hors trésorerie — la société les émet, l'argent ne passe pas par ses comptes | {{ Money::format($position['hors_tresorerie_ht']) }} | {{ Money::format($position['hors_tresorerie_ttc']) }} |
Trois écrans ont longtemps affiché « CA encaissé » pour trois choses différentes. Ils ne sont pas réunifiés — un décompte n'est pas une facture, une facture n'est pas un encaissement — ils sont nommés.
| Registre | Ce qu'il mesure | Montant TTC |
|---|---|---|
| Décomptes | Jalons du marché passés « encaissé » — la vérité du marché public | {{ Money::format($registres['decomptes_ttc']) }} |
| Encaissements | Opérations de trésorerie entrantes validées — ce que la banque a vu | {{ Money::format($registres['encaissements_ttc']) }} |
| Facturé | Factures émises, brouillons et annulations exclus | {{ Money::format($registres['facture_ttc']) }} |
| Écart entre le plus haut et le plus bas | {{ Money::format(max($registres['decomptes_ttc'], $registres['encaissements_ttc'], $registres['facture_ttc']) - min($registres['decomptes_ttc'], $registres['encaissements_ttc'], $registres['facture_ttc'])) }} | |
Les trois registres concordent.
@endif {{-- ─── 4. Décomptes, factures, encaissements ──────────────────────────────────────────── --}}Aucun décompte enregistré sur ce marché.
@else| Décompte | Montant HT | Montant TTC | Échéance | Facturé le | Encaissé le | État |
|---|---|---|---|---|---|---|
| {{ $decompte->label }} | {{ Money::format($decompte->amount_ht) }} | {{ Money::format($decompte->amount_ttc) }} | {{ $decompte->expected_date?->format('d/m/Y') ?? '—' }} | {{ $decompte->invoiced_at?->format('d/m/Y') ?? '—' }} | {{ $decompte->collected_at?->format('d/m/Y') ?? '—' }} | {{ $decompte->status?->label() ?? '—' }} |
| Sous-total — {{ $decomptes->count() }} décompte(s) | {{ Money::format($decomptes->sum('amount_ht')) }} | {{ Money::format($decomptes->sum('amount_ttc')) }} | ||||
Aucune facture émise sur ce marché.
@else| Numéro | Date | Échéance | Total HT | Total TTC | Net à payer | État |
|---|---|---|---|---|---|---|
| {{ $facture->number ?? ('#'.$facture->id) }} | {{ $facture->date?->format('d/m/Y') ?? '—' }} | {{ $facture->due_date?->format('d/m/Y') ?? '—' }} | {{ Money::format($facture->total_ht) }} | {{ Money::format($facture->total_ttc) }} | {{ Money::format($facture->net_payable) }} | {{ $facture->status?->label() ?? '—' }} |
| Sous-total — {{ $factures->count() }} facture(s) | {{ Money::format($factures->sum('total_ht')) }} | {{ Money::format($factures->sum('total_ttc')) }} | {{ Money::format($factures->sum('net_payable')) }} | |||
Aucun encaissement validé rattaché à ce marché.
@else| Date | Libellé | Compte | Montant TTC | État |
|---|---|---|---|---|
| {{ $encaissement->date?->format('d/m/Y') ?? '—' }} | {{ $encaissement->label }} | {{ $encaissement->account?->name ?? '—' }} | {{ Money::format($encaissement->amount_ttc) }} | {{ $encaissement->status?->label() ?? '—' }} |
| Sous-total — {{ $encaissements->count() }} encaissement(s) | {{ Money::format($encaissements->sum('amount_ttc')) }} | |||
Dans ce socle, le bon de commande est un mode de passation du marché et non une pièce séparée : il commande le circuit de dépôt (caution, acte d'engagement).
| {{ $cle }} | {{ $valeur }} |
Aucune heure approuvée sur ce marché, et aucun coût RH n'y a été ventilé.
@else| Collaborateur / mois | Heures | Coût imputé | Taux horaire |
|---|---|---|---|
| {{ $ligne['nom'] }}@unless ($ligne['mode_heures']) — {{ $ligne['mode'] }}@endunless | {{ $ligne['mode_heures'] || $ligne['heures'] > 0 ? number_format($ligne['heures'], 2, ',', ' ').' h' : $ligne['mode'] }} | {{ $ligne['cout'] > 0 ? Money::format($ligne['cout']) : 'Aucune ventilation calculée' }} | {{ $ligne['taux_horaire'] !== null ? Money::format($ligne['taux_horaire']).' /h' : '—' }} |
| {{ $mois['label'] }} | {{ number_format($mois['heures'], 2, ',', ' ') }} h | {{ Money::format($mois['cout']) }} | |
| Sous-total — {{ $coutHumain->count() }} collaborateur(s) | {{ number_format($coutHumainTotaux['heures'], 2, ',', ' ') }} h | {{ Money::format($coutHumainTotaux['cout']) }} | {{ $coutHumainTotaux['heures'] > 0 ? Money::format(round($coutHumainTotaux['cout'] / $coutHumainTotaux['heures'], 2)).' /h' : '—' }} |
Aucune dépense validée rattachée à ce marché.
@else @if ($depenses->contains(fn (array $l): bool => $l['parasite']))| Catégorie | Montant HT | Opérations | Part |
|---|---|---|---|
| {{ $ligne['libelle'] }} | {{ Money::format($ligne['montant']) }} | {{ $ligne['nb'] }} | {{ number_format($ligne['part'], 1, ',', ' ') }} % |
| Sous-total — dépenses engagées | {{ Money::format($depenses->sum('montant')) }} | {{ $depenses->sum('nb') }} | 100 % |
Aucune opération à détailler.
@else| Date | Libellé | Catégorie | Montant HT | Justificatif |
|---|---|---|---|---|
| {{ $ligne['date'] }} | {{ $ligne['libelle'] }} | {{ $ligne['categorie'] }} | {{ Money::format($ligne['montant']) }} | {{ $ligne['justificatif'] ? 'Oui' : 'Non' }} |
| Sous-total — {{ $depensesDetail->count() }} opération(s), dont {{ $depensesDetail->where('justificatif', false)->count() }} sans justificatif | {{ Money::format($depensesDetail->sum('montant')) }} | |||
Ce n'est pas une dépense du marché : c'est une quote-part calculée des charges de fonctionnement de la société. Personne n'a payé cette somme « pour ce marché ». Clé employée : {{ $structureCle }}
@if ($structure->isEmpty())Aucune quote-part de structure calculée sur ce marché.
@else| Mois | Détail par source | Montant |
|---|---|---|
| {{ $mois['label'] }} | @foreach ($mois['sources'] as $source) {{ $source['libelle'] }} {{ Money::format($source['montant']) }}@unless ($loop->last) · @endunless @endforeach | {{ Money::format($mois['montant']) }} |
| Sous-total — structure allouée ({{ $structure->count() }} mois) | {{ Money::format($structureTotal) }} | |
| Total général — dépenses engagées + structure allouée | {{ Money::format(round($depenses->sum('montant') + $structureTotal, 2)) }} | |
Les cinq blocs dont la somme est le coût complet : {{ Money::format($coutComplet['total']) }}.
| Bloc | Part | Montant |
|---|---|---|
| {{ $titre }} | {{ number_format($coutComplet['blocs'][$cle]['part'], 1, ',', ' ') }} % | {{ Money::format($coutComplet['blocs'][$cle]['total']) }} |
| Coût complet | {{ Money::format($coutComplet['total']) }} | |
| Ligne | Clé | Montant |
|---|---|---|
| {{ $quoi($l) }} | {{ $comment($l) }} | {{ Money::format($l['montant']) }} |
| Sous-total | {{ Money::format($coutComplet['blocs'][$cle]['total']) }} | |
|
Marge dégagée — sur le facturé
{{ Money::format($position['marge_degagee']) }}
{{ number_format($position['marge_degagee_pct'], 1, ',', ' ') }} % · ce que le marché a produit
|
Marge réalisée — sur l'encaissé
{{ Money::format($position['marge_realisee']) }}
{{ number_format($position['marge_realisee_pct'], 1, ',', ' ') }} % · ce que la trésorerie en a vu
|
Les deux diffèrent de {{ Money::format($position['reste_a_encaisser_ttc']) }} TTC : c'est exactement ce que le client doit encore. Quand il aura réglé, elles se confondront — l'écart mesure un délai de paiement, pas une perte.
@endif @else|
Marge brute
{{ Money::format($marge['marge_brute']) }}
{{ number_format($marge['marge_brute_pct'], 1, ',', ' ') }} %
|
Marge après structure
{{ Money::format($marge['marge_apres_structure']) }}
{{ number_format($marge['marge_apres_structure_pct'], 1, ',', ' ') }} %
|
| Poste | Montant |
|---|---|
| Revenu retenu — {{ $marge['base_revenu'] }} | {{ Money::format($marge['revenu']) }} |
| − Dépenses engagées (HT) | {{ Money::format($marge['depenses_engagees']) }} |
| − Notes de frais approuvées | {{ Money::format($marge['notes_de_frais']) }} |
| − Primes liées au marché | {{ Money::format($marge['primes']) }} |
| − Coût humain ventilé (paie) | {{ Money::format($marge['cout_humain']) }} |
| = Marge brute (avant structure) | {{ Money::format($marge['marge_brute']) }} |
| − Structure allouée (quote-part calculée) | {{ Money::format($marge['structure']) }} |
| = Marge après structure — coût complet {{ Money::format($marge['cout_complet']) }} | {{ Money::format($marge['marge_apres_structure']) }} |
| {{ $cle }} | {{ $valeur }} |
| Échéance | Date | Reste |
|---|---|---|
| {{ $echeance['label'] }} | {{ $echeance['date']->format('d/m/Y') }} | {{ $echeance['days'] < 0 ? 'dépassé de '.abs($echeance['days']).' j' : 'J-'.$echeance['days'] }} |
| Immobilisé au journal (sorties − retours) | {{ Money::format($position['caution_immobilisee']) }} |
Aucune fiche caution rattachée à ce marché.
@else| Type | Montant exigé | Montant immobilisé | Émise le | État |
|---|---|---|---|---|
| {{ $caution->type?->label() ?? '—' }} | {{ Money::format($caution->required_amount) }} | {{ Money::format($caution->amount) }} | {{ $caution->issued_date?->format('d/m/Y') ?? '—' }} | {{ $caution->status?->label() ?? '—' }} |
| Sous-total — {{ $cautions->count() }} caution(s) | {{ Money::format($cautions->sum('required_amount')) }} | {{ Money::format($cautions->sum('amount')) }} | ||
Rappel : une caution n'est jamais une charge ni un coût de marché — c'est une somme immobilisée, restituée à la réception. Elle n'entre donc dans aucun total ci-dessus.
@endif @endsection