@extends('layouts.app') @push('styles') @endpush @section('content') @php /* |-------------------------------------------------------------------------- | Détection du rôle juriste |-------------------------------------------------------------------------- | | Certaines méthodes du contrôleur utilisent cette même vue. | On détermine donc directement ici si l'utilisateur connecté | est juriste. | */ $estJuriste = $estJuriste ?? auth()->user()->role === 'juriste'; @endphp

@if($modeClient) {{-- Un client précis est ouvert en saisie --}} Saisie client @elseif($vueGlobale ?? false) {{-- Tableau complet uniquement en consultation --}} Vue globale des saisies @else {{-- Écran principal léger --}} Rechercher un client @endif

@if($modeClient) {{ $clients->first()->first()->nom }} @elseif($vueGlobale ?? false) Consultation des saisies du portefeuille pour le mois sélectionné. @elseif($estJuriste) Recherchez un client pour accéder à ses prestations juridiques. @else Recherchez un client pour accéder directement à sa saisie mensuelle. @endif

@if($modeClient && auth()->user()->role !== 'juriste')
{{-- |-------------------------------------------------------------------------- | Retour à la recherche client |-------------------------------------------------------------------------- --}} Retour à la recherche {{-- |-------------------------------------------------------------------------- | Consultation du tableau global |-------------------------------------------------------------------------- | | On conserve la période actuellement consultée afin que | l'utilisateur revienne sur le même mois. | --}} Consulter le tableau global
@endif
{{-- |-------------------------------------------------------------------------- | État et gestion de la période |-------------------------------------------------------------------------- --}}
@if($periodeCloturee) Période clôturée @else Période ouverte @endif {{-- |-------------------------------------------------------------------------- | Gestion admin / manager |-------------------------------------------------------------------------- --}} @if(in_array(auth()->user()->role, ['admin', 'manager'], true)) @if(!$periodeCloturee) {{-- * Période ouverte : * possibilité de la clôturer. --}}
@csrf
@else {{-- * Période clôturée : * possibilité de la rouvrir. --}}
@csrf
@endif @endif
@if(!$modeClient && ($vueGlobale ?? false)) {{-- * Si l'utilisateur consulte le tableau global, * on conserve ce mode lorsqu'il change de mois. --}} @endif
{{-- |-------------------------------------------------------------------------- | Recherche rapide d'un client |-------------------------------------------------------------------------- | | Permet d'accéder directement au tableau de saisie | d'un client particulier. | | Cette fonctionnalité est disponible pour tous les utilisateurs. | Les droits sont ensuite contrôlés par le contrôleur. | --}} @if(!$estJuriste || !$modeClient)
{{-- * On conserve le mois actuellement sélectionné * pendant la recherche. --}}
{{-- |-------------------------------------------------------------------------- | Accès rapide par liste déroulante |-------------------------------------------------------------------------- | | Cette liste contient uniquement les clients auxquels | l'utilisateur connecté a accès. | | Pour une gestionnaire en mode remplacement : | - ses propres clients ; | - + les clients de la gestionnaire remplacée. | --}} @if(isset($clientsDisponibles))
@endif
{{-- |-------------------------------------------------------------------------- | Résultats de recherche |-------------------------------------------------------------------------- --}} @if(($recherche ?? '') !== '')
@if($resultatsRecherche->isEmpty())
Aucun client trouvé pour {{ $recherche }}.
@else @endif
@endif
@endif {{-- |-------------------------------------------------------------------------- | Accès au tableau global |-------------------------------------------------------------------------- | | Le tableau global sert uniquement à consulter | et contrôler les saisies du mois. | --}} @if(!$modeClient && !$estJuriste)
@if($vueGlobale ?? false) {{-- * Nous sommes dans le tableau global : * on propose de revenir à l'écran principal léger. --}} Retour à la recherche client @else {{-- * Nous sommes sur l'écran principal : * accès volontaire au tableau global. --}} Voir le tableau global @endif
@endif @if($estJuriste && $modeClient) @php /* |-------------------------------------------------------------------------- | Fiche de saisie Juriste |-------------------------------------------------------------------------- | | La vue "client()" ne contient qu'un seul client. | On le récupère donc directement depuis la collection groupée. | */ $clientJuriste = $clients->first()->first(); /* * Les saisies du client sont indexées par service. * Cela permet de retrouver très facilement * la saisie correspondant au service 35 ou 36. */ $saisiesJuridiques = $clientJuriste->saisies ->keyBy('service_id'); /* * Total des prestations juridiques du client * pour la période affichée. */ $totalJuridique = 0; @endphp {{-- |-------------------------------------------------------------------------- | Informations client |-------------------------------------------------------------------------- --}}
Client sélectionné

{{ $clientJuriste->nom }}

@if($clientJuriste->partenaire) {{ $clientJuriste->partenaire->cabinet ?? $clientJuriste->partenaire->contact }} @endif @if($clientJuriste->gestionnaire) Gestionnaire : {{ $clientJuriste->gestionnaire->nom ?? $clientJuriste->gestionnaire->name }} @endif
{{-- Retour vers la recherche --}} Rechercher un autre client
{{-- Titre de la zone de saisie --}}

Prestations juridiques

{{ \Carbon\Carbon::createFromFormat('Y-m', $periode) ->locale('fr') ->translatedFormat('F Y') }}
{{-- |-------------------------------------------------------------------------- | Cartes des services juridiques |-------------------------------------------------------------------------- --}}
@foreach($services as $service) @php /* * Normalement la méthode client() ne renvoie déjà * que les services 35 et 36 pour une juriste. * * On conserve malgré tout cette protection visuelle. */ if (!in_array((int) $service->id, [35, 36], true)) { continue; } $saisie = $saisiesJuridiques->get($service->id); $quantite = $saisie?->quantite; $prixUnitaire = $saisie?->prix_unitaire ?? 0; $montant = $saisie?->montant ?? 0; /* * Construction du total des prestations. */ $totalJuridique += (float) $montant; @endphp
{{-- Nom du service --}}
Prestation

{{ $service->libelle }}

Service {{ $service->id }}
{{-- Quantité --}}
{{-- Commentaire --}} {{-- |-------------------------------------------------------------------------- | Commentaire de la prestation |-------------------------------------------------------------------------- | | Le bouton est placé dans une ligne dédiée afin d'éviter | qu'il soit décalé ou collé dans le coin de la carte. | --}}
{{-- Montant du service --}}
Montant {{ number_format( $montant, 2, ',', ' ' ) }} €
@endforeach
{{-- Total juridique du client --}}
Total des prestations juridiques
{{ $clientJuriste->nom }}
{{ number_format( $totalJuridique, 2, ',', ' ' ) }} €
@endif @php /* * Initialisation du chiffre d'affaires affiché * dans le tableau. */ $totalGeneral = 0; @endphp {{-- |-------------------------------------------------------------------------- | Tableau des saisies |-------------------------------------------------------------------------- | | Le tableau est affiché : | - pour les utilisateurs classiques ; | - pour une juriste uniquement lorsqu'elle a ouvert un client précis. | | Sur l'écran de recherche d'une juriste, on ne veut surtout pas | afficher "Aucun client actif à afficher". | --}} @if( !$estJuriste && ( $modeClient || ($vueGlobale ?? false) ) ) @if($clients->isEmpty())
Aucun client actif à afficher.
@else
@php /* |-------------------------------------------------------------------------- | Totaux par colonne |-------------------------------------------------------------------------- | | Pour chaque service nous conservons : | - la quantité totale ; | - le montant total facturé. | */ $totauxParService = []; $montantsParService = []; foreach ($services as $service) { $totauxParService[$service->id] = 0; $montantsParService[$service->id] = 0; } @endphp {{-- En-tête unique du grand tableau --}} @foreach($services as $service) @php if ($service->lettre_mission_requise) { $classeEnteteService = 'service-lettre-mission'; } elseif ((int) $service->ordre_affichage >= 1 && (int) $service->ordre_affichage <= 16) { $classeEnteteService = 'service-courant'; } elseif ((int) $service->ordre_affichage >= 16 && (int) $service->ordre_affichage <= 24) { $classeEnteteService = 'service-embauche'; } else { $classeEnteteService = 'bg-light'; } @endphp @endforeach @foreach($clients as $clientsPartenaire) @php $partenaire = $clientsPartenaire->first()->partenaire; $totalPartenaire = 0; @endphp {{-- Ligne de séparation du partenaire --}} {{-- Clients du partenaire --}} @foreach($clientsPartenaire as $client) @php $totalClient = 0; /* * Indexation des saisies par service_id. */ $saisiesParService = $client->saisies ->keyBy('service_id'); @endphp {{-- Colonne client fixe --}} {{-- Cellules de services --}} @foreach($services as $service) @php $saisie = $saisiesParService->get($service->id); $quantite = $saisie?->quantite; $prixUnitaire = $saisie?->prix_unitaire ?? 0; $montant = $saisie?->montant ?? 0; $totalClient += (float) $montant; @endphp @php /* |-------------------------------------------------------------------------- | Total montant de la colonne |-------------------------------------------------------------------------- | | Le montant réellement enregistré en base est utilisé. | On ne recalcule surtout pas quantité × tarif ici. | | Cela permet de respecter exactement les tarifs historiques | enregistrés dans chaque saisie. | */ $montantsParService[$service->id] += (float) $montant; @endphp @php /* |-------------------------------------------------------------------------- | Valeur utilisée pour le total de la colonne |-------------------------------------------------------------------------- | | Par défaut, on additionne la quantité du service. | | Deux cas particuliers : | | - Bulletin (1) avec établissements : | la quantité réelle sera calculée plus bas à partir | des établissements. | | - DSN calculée (48) : | la colonne affiche un montant et non une quantité. | */ $valeurTotalColonne = (int) ($quantite ?? 0); /* * DSN calculée : * on totalise les montants affichés. */ if ((int) $service->id === 48) { $valeurTotalColonne = (float) $montant; } /* * Pour le Bulletin multi-établissements, * on ne l'ajoute pas encore. * Il sera ajouté après le calcul de $totalBulletins. */ if ( (int) $service->id === 1 && $client->etablissements->isNotEmpty() ) { $valeurTotalColonne = 0; } $totauxParService[$service->id] += $valeurTotalColonne; @endphp @php if ($service->lettre_mission_requise) { $classeCelluleService = 'service-lettre-mission-light'; } elseif ((int) $service->ordre_affichage >= 1 && (int) $service->ordre_affichage <= 15) { $classeCelluleService = 'service-courant-light'; } elseif ((int) $service->ordre_affichage >= 16 && (int) $service->ordre_affichage <= 24) { $classeCelluleService = 'service-embauche-light'; } else { $classeCelluleService = ''; } @endphp @endforeach @php $totalPartenaire += $totalClient; $totalGeneral += $totalClient; @endphp {{-- Total du client --}} @if($client->multi_etablissements) @foreach($client->etablissements as $etablissement) @php $saisieBulletinsEtablissement = $client->saisies ->first(function ($saisie) use ($etablissement) { return (int) $saisie->service_id === 1 && (int) $saisie->etablissement_id === (int) $etablissement->id; }); @endphp @foreach($services as $service) @endforeach @endforeach @endif @endforeach {{-- Sous-total du partenaire --}} @endforeach {{-- |-------------------------------------------------------------------------- | Ligne TOTAL des colonnes |-------------------------------------------------------------------------- | | Pour chaque service : | - quantité totale en principal ; | - montant total en dessous. | | Cas particulier : | - DSN (48) : on affiche uniquement le montant, | car la quantité enregistrée est technique. | --}} @foreach($services as $service) @endforeach {{-- Total général unique --}}
Client {{ $service->libelle }} Total
@if($partenaire) {{ $partenaire->contact }} @if($partenaire->cabinet) ({{ $partenaire->cabinet }}) @endif @else Sans partenaire @endif
{{ $client->saisies->isNotEmpty() ? '✓' : '–' }}
@if($client->multi_etablissements) @else @endif {{ $client->nom }}
@if($client->gestionnaire)
{{ $client->gestionnaire->nom ?? $client->gestionnaire->name }}
@endif
@if($vueGlobale ?? false) {{-- |-------------------------------------------------------------------------- | Vue globale : consultation uniquement |-------------------------------------------------------------------------- | | Dans la vue globale, aucune saisie n'est autorisée. | On affiche uniquement la valeur déjà enregistrée. | --}}
@if((int) $service->id === 48) {{-- DSN calculée : on affiche son montant --}} {{ number_format( $montant, 2, ',', ' ' ) }} € @elseif($quantite !== null) {{-- Tous les autres services : quantité enregistrée --}} {{ number_format( $quantite, 0, ',', ' ' ) }} @else {{-- Aucune saisie pour ce service --}} @endif
@elseif((int) $service->id === 26) {{-- SERVICE 26 : DSN La DSN est représentée par une case à cocher : - cochée = quantité 1 - décochée = quantité 0 --}} @elseif((int) $service->id === 43) {{-- SERVICE 43 : DEMAT La DEMAT ne doit jamais être saisie manuellement. Elle sera calculée automatiquement uniquement lorsque l’option DEMAT est activée sur la fiche du client. La règle de calcul sera : DEMAT = service 1 + service 2 + service 31 --}} @if((int) $client->option_demat === 1) {{-- L’option DEMAT est activée sur le client. Le champ est en lecture seule car sa valeur sera calculée automatiquement par le JavaScript. --}} @else {{-- L’option DEMAT n’est pas activée sur la fiche client. Le champ reste vide et complètement désactivé. Aucun calcul ni enregistrement ne devra être effectué. --}} @endif @elseif((int) $service->id === 48) {{-- |-------------------------------------------------------------------------- | SERVICE 48 : DSN |-------------------------------------------------------------------------- | | Cette colonne est calculée automatiquement. | | Elle affiche uniquement le montant total de la facturation DSN | du client pour la période. | | Le calcul est réalisé établissement par établissement puis | additionné sur la ligne principale. | | Aucune saisie manuelle n'est autorisée. | --}} @elseif( (int) $service->id === 1 && $client->etablissements->where('actif', 1)->isNotEmpty() ) {{-- SERVICE 1 : BULLETIN DE PAIE Lorsque le client possède des établissements, la quantité ne doit pas être saisie sur la ligne principale. Le champ affiche la somme des bulletins saisis dans les lignes établissements. --}} @php /* |-------------------------------------------------------------------------- | Total Bulletin pour un client multi-établissements |-------------------------------------------------------------------------- | | On calcule : | - la quantité totale de bulletins ; | - le montant total facturé. | | Ces informations proviennent des saisies des établissements, | car la ligne principale du client ne contient pas directement | les bulletins dans ce cas. | */ /* * Quantité totale de bulletins. */ $totalBulletins = $client->etablissements->sum( function ($etablissement) use ($periode) { return $etablissement->saisies ->filter(function ($saisie) use ($periode) { return (int) $saisie->service_id === 1 && $saisie->periode?->format('Y-m-d') === \Carbon\Carbon::parse($periode) ->format('Y-m-d'); }) ->sum('quantite'); } ); /* * Montant total facturé pour les bulletins * de tous les établissements. */ $montantBulletins = $client->etablissements->sum( function ($etablissement) use ($periode) { return $etablissement->saisies ->filter(function ($saisie) use ($periode) { return (int) $saisie->service_id === 1 && $saisie->periode?->format('Y-m-d') === \Carbon\Carbon::parse($periode) ->format('Y-m-d'); }) ->sum('montant'); } ); /* * Ajout de la quantité au total de la colonne Bulletin. */ $totauxParService[$service->id] += (int) $totalBulletins; /* * Ajout du montant au total de la colonne Bulletin. */ $montantsParService[$service->id] += (float) $montantBulletins; @endphp {{-- Champ total Bulletin de la ligne client. La classe total-bulletins-client permet au JavaScript de mettre à jour cette valeur sans recharger la page. Le champ reste readonly afin d’empêcher toute saisie manuelle. --}} @elseif(in_array((int) $service->id, [46, 45, 47], true)) {{-- |-------------------------------------------------------------------------- | Services automatiques liés aux options client |-------------------------------------------------------------------------- | | Ces services sont calculés automatiquement : | - 46 : Silae RH Pro | - 45 : VIP | - 47 : MySilae | | Ils sont affichés mais ne doivent jamais être saisis manuellement. | --}} @else {{-- TOUS LES AUTRES SERVICES Champ de saisie classique modifiable par l’utilisateur. --}} @php /* |-------------------------------------------------------------------------- | Services nécessitant un champ plus large |-------------------------------------------------------------------------- | | Ces services peuvent contenir des quantités importantes | (100, 500, 1500, ...). | */ $champLarge = in_array((int) $service->id, [4, 23, 35, 36], true); @endphp @php /* * Les services 39 et 41 deviennent non modifiables * lorsque le client est en DEMAT. */ $champDematVerrouille = $client->option_demat && in_array((int) $service->id, [39, 41], true); @endphp @endif
{{ number_format($totalClient, 2, ',', ' ') }} €
{{ $etablissement->nom }}
@if((int) $service->id === 1) @endif
TOTAL @if((int) $service->id === 48) {{-- SERVICE 48 : DSN La quantité technique n'a pas d'intérêt à l'affichage. On affiche uniquement le montant total DSN. --}}
{{ number_format( $totauxParService[$service->id] ?? 0, 0, ',', ' ' ) }}
@else {{-- Quantité totale du service. --}}
{{ number_format( $totauxParService[$service->id] ?? 0, 0, ',', ' ' ) }}
{{-- Montant total du service, affiché plus petit sous la quantité. --}}
{{ number_format( $montantsParService[$service->id] ?? 0, 2, ',', ' ' ) }} €
@endif
Total général {{ number_format($totalGeneral, 2, ',', ' ') }} €
@endif @endif @if( !$estJuriste && ( $modeClient || ($vueGlobale ?? false) ) )
Chiffre d'affaires total du mois
{{ \Carbon\Carbon::createFromFormat('Y-m', $periode) ->locale('fr') ->translatedFormat('F Y') }}
{{ number_format($totalGeneral, 2, ',', ' ') }} €
@endif
@push('scripts') @endpush @endsection