
    Zi59                     @   d Z ddlZddlZddlmZ  ej        d          ZdZdZdZ	dZ
d	d
dddddZi dddddddddddddddd	ddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/Zd0d1d2d3d4d5d6d7d8d9d:d;d<d=d>Zd?ed@efdAZdBed@efdCZdIdEedFed@efdGZdId?edFed@efdHZdS )Ju  
ICAC v2.2 — Audit Mandats
Détection de fractionnement de commandes (split procurement).

Seuil MAPA: 40 000€ HT (fournitures/services)
Alerte si ≥3 mandats au même tiers cumulant >30 000€.
Alerte si un article montre des mandats réguliers juste sous seuil.

Fonctionne sur les chunks RAG extraits du Compte de Gestion (CG).
Les CG contiennent la balance des comptes mais PAS le détail par tiers.
On analyse donc les comptes de classe 6 (charges) et les opérations.
    N)Optionalzicac.audit_mandatsi@  i i0u     zAnnonces et insertionszFoires et expositionsu   Catalogues et imprimésPublicationszDivers (communication)u-   Publicité, publications, relations publiques)623162336236623762386236042zAchats prestations de services611u   Sous-traitance générale6156Maintenance6185u   Frais colloques, séminaires617u   Études et recherches6226
Honoraires6228u(   Divers (rémunérations intermédiaires)r   r   r
   zDivers communication6241zTransports de biens6248zDivers transports6251u   Voyages et déplacements6257u   Réceptions6262u   Frais télécommunications627zServices bancaires6281zConcours divers (cotisations)i  g\uBAgףp=8 +Ag)\ 5Ag
ףpAg    @g    0AgffffS@gfffM.Agz"AgQ#Ag3333@gp=
@gQ A)exercicetotal_charges_fonctionnementachats_charges_externescharges_personnelcharges_intervention"dont_personnes_morales_droit_privedont_autres_organismes_publicscharges_financieresresultat_exercicefournisseurs_debit_totalfournisseurs_credit_total6042_achats_prestations60611_eau_assainissement60612_electricite
rag_chunksreturnc                    g }| D ]}|                     dd          }|                     dd          }|                     dd          }t          j        d|          }|D ]}|d                                         }|d                                         d	d
         }	|d                             dd                              dd          }
	 t          |
          }n# t          $ r Y w xY w|                    d          r|                    ||	|| d| d           dD ]}||	                                v rt          j        d|          }|D ]}|                    dd                              dd          }	 t          |          }d|cxk     rdk     r&n n#|                    dd| d|| d| d           p# t          $ r Y |w xY wt                      }g }|D ]@}|d         |d         f}||vr*|                    |           |                    |           At                              dt          |                     |S )u   
    Extrait les données de mandats/comptes depuis les chunks RAG.
    Chaque chunk est un dict avec 'text', 'source', 'score', etc.

    Retourne une liste de dicts:
    {compte, libelle, montant, source_page}
    text sourcepage?u;   (\d{3,5})\s+([A-ZÀ-Ü][a-zà-ü].*?)\s+([\d\s]+[,\.]\d{2})r      NP       ,.6z p.)comptelibellemontantsource_page)communication
   publicitérelationu   imprimé	catalogue	insertionannonceu   ([\d\s]{2,10}[,\.]\d{2})\s*€?i  i  623xzCommunication ()r9   r;   u3   audit_mandats: %d entrées extraites des chunks RAG)getrefindallstripreplacefloat
ValueError
startswithappendlowersetaddloginfolen)r*   mandatschunkr-   r/   r0   pattern_balancematchr9   r:   montant_strr;   keywordamountsamt_strcleanvalseenuniquemkeys                        ,/var/www/icac/agents_python/audit_mandats.pyextraire_mandats_texterc   N   s    G 1! 1!yy$$8R((yy%% *& 	
 
 % 	 	E1X^^%%FAhnn&&ss+G(**333;;CEEK,,      %% $&&&,#7#7#7#7	      = 	! 	!G$**,,&&*%GNN& ! !G#OOC44<<S#FFE
!#Ell#.........#NN*0+GW+G+G+G+.28/C/CT/C/C	, ,    & ! ! ! !	!& 55DF  {AiL)d??HHSMMMMM!HHBCKKPPPMs%   C  
C-,C-AG
G	G	rT   c                    g }i }| D ]}|d         }||vr|d         ddg d||<   ||         dxx         |d         z  cc<   ||         dxx         d	z  cc<   |d
         ||         d         vr'||         d                              |d
                    dt          d         fdt          d         fdt          d         ffD ]H\  }}||vr?t                              |t                              |d                    }||d	dgd||<   Id}|                                D ]\  }}	|                    d          r||	d         z  }|	d         t          k    rM|t          v rD|                     d||	d         |	d         t          d| d|	d          d|	d         ddd           d|	d         cxk     rt          k     rPn |                     d||	d         |	d         t          d| d|	d          d|	d         ddt          dd 	d           |d!k    r&|                     d"d#d$|t          d%|dd&d           t          d'         }
|
d(k    r6|                     d)d*d+|
d,d-|
dd.|
t          d/         z  d0z  d1d2d           |||t          d3S )4u[  
    Analyse les mandats par compte et détecte les anomalies.
    Puisque le CG n'a pas de détail par tiers, on analyse par compte.

    Retourne un dict avec:
    - comptes_detail: liste des comptes avec montants
    - alertes: liste d'alertes de fractionnement
    - total_communication: total comptes 623x
    - resume: texte de résumé
    r9   r:   g        r   )r:   totalnb_ecrituressourcesre   r;   rf   r2   r<   rg   r   r'   60611r(   60612r)   r.   zCG 2024 Balancer   u   CUMUL_ÉLEVÉu   ⚠ Compte z (z): z,.2fu@   € — cumul élevé, vérifier s'il y a eu mise en concurrence)typer9   r:   r;   seuilmessagei  PROCHE_SEUILu   € — proche du seuil MAPA (r6   u!   € HT), risque de fractionnementiP  u   COMMUNICATION_ÉLEVÉErC   zCommunication (total)u    ⚠ Total communication (623x): u=   € — au-dessus du seuil MAPA, obligation de marché publicr   i 5 u   ACHATS_ÉLEVÉSz60-62zAchats et charges externesNu&   ℹ Total achats et charges externes: u   € — représente r   d   z.1fz% des charges de fonctionnement)comptes_detailalertestotal_communication
donnees_cg)	rM   DONNEES_CG_2024COMPTES_SENSIBLESrE   COMPTES_COMMUNICATIONitemsrL   SEUIL_ALERTE_CUMULSEUIL_MAPA_FOURNITURES)rT   rp   comptesr`   cptcpt_coder;   r:   
total_commdataachatss              rb   analyser_tiersr      s    GG  = =kgY< !	 GCL 	W9-^$$$)$$$]73<	#:::CL#**1]+;<<< 
!:;<	/"<=>	/"567  '
 7""'++H6K6O6OPXZ\6]6]^^G"  !-.	! !GH J]]__ " "	T>>%   	($w-'J =---#9J2J2JNN'	?=/A# A Ai A AG}BA A A     4=9999#999999NN&	?=/0# 0 0i 0 0G}H0 0.;0 0 0     E,.!+I:L I I I

 

 
	 
	 
	 67F%31N 1 1%o6T&UUVYYa1 1 1
 
 	 	 	 ")%	      r.   analysequeryc                    | d         }| d         }| d         }| d         }dd|d          dd	|d          d
ddd|d         ddd|d         ddd|d         ddd|d         ddd|d         ddd|d         ddd|d         ddd|d         dddd |d!         ddd"|d#         dddg}|                                 t          fd$d%D                       r|                    d&           |                    d'           t          |                                          D ]G\  }}|                    d(          r-|                    d)| d*|d+         d,d*|d-         dd           H|d.k    r|                    d/|dd           n?|                    d0           |                    d1           |                    d2           |                    d           |                    d3           |                    d4           |                    d5           |                    d6           |                    d7           |                    d8           |                    d           |r|                    d9           t          |                                d: d;<          }	|	d=d>         D ]A\  }}|t          v rd?nd}
|                    d@| d*|d+         d,d*|d-         dd|
            B|                    d           |rN|                    dA           |D ] }|                    d@|dB                     !|                    d           nT|                    dC           |                    dD           |                    dE           |                    d           |                    dF           |                    dGt          dHdI           |                    dJt          dHdI           |                    dK           |                    dL           dM	                    |          S )Nz1
    Formate le rapport d'audit pour le LLM.
    ro   rp   rr   rq   u,   AUDIT DES DÉPENSES — COMMUNE DE BESSÈGESz	Exercice r   u,    — Compte de Gestion (CG Budget Principal)zSource: CG Budget Principal z (DGFiP)r.   u"   ═══ CHIFFRES CLÉS ═══z!  Total charges fonctionnement : r   z>12,.2fu    €z!  Achats et charges externes   : r   z!  Charges de personnel         : r   z!  Charges d'intervention       : r    u%       dont pers. morales droit privé: r!   z>10,.2fz$    dont organismes publics       : r"   u"     Charges financières          : r#   u"     Résultat de l'exercice       : r$   u"     Fournisseurs (c.4011) débit  : r%   u"     Fournisseurs (c.4011) crédit : r&   c              3       K   | ]}|v V  	d S )N ).0kq_lows     rb   	<genexpr>z+formater_rapport_mandats.<locals>.<genexpr>/  s'      
R
R!1:
R
R
R
R
R
Rr   )r=   119r>   r?   u=   ═══ FOCUS COMMUNICATION / RELATIONS PUBLIQUES ═══z  Comptes 623x (Communication):r   z    r5   r:   z<35sre   r   z  TOTAL COMMUNICATION: u:     ⚠ Aucun détail trouvé dans les chunks RAG pour 623x.uA     Le CG indique 888 860€ en achats et charges externes (total).uF     Le détail par article nécessite le développement du chapitre 623.u7     NOTE: Le « 119 000€ de communication » mentionnéu=     se trouverait dans le compte 623 (Publicité, publications,u?     relations publiques). Le compte de gestion agrégé ne montreu;     pas le détail par prestataire mais par nature comptable.z>  Pour identifier les prestataires, il faudrait le grand livreu.     détaillé ou l'état des mandats par tiers.u%   ═══ COMPTES ANALYSÉS ═══c                     | d         d         S )Nr2   re   r   )xs    rb   <lambda>z*formater_rapport_mandats.<locals>.<lambda>I  s    qtG} r   T)ra   reverseN   u    ⚠z  u2   ═══ ALERTES ET POINTS DE VIGILANCE ═══rl   u,   ═══ AUCUNE ALERTE DÉTECTÉE ═══u5     Les montants analysés ne déclenchent pas d'alertez.  de fractionnement sur les seuils en vigueur.u3   ═══ SEUILS RÉGLEMENTAIRES (rappel) ═══z  MAPA fournitures/services : z>8,u    € HTz  MAPA travaux              : z,  Source: Code de la Commande Publique (CCP)u/     Art. R2122-8: procédure adaptée si > seuils
)
rN   anyrM   sortedrv   rL   rt   rx   SEUIL_MAPA_TRAVAUXjoin)r   r   ry   rp   cgr|   linesrz   r}   sorted_comptessensiblear   s               @rb   formater_rapport_mandatsr     s1    &'Gi G		B./J 	7PBzNPPP?r*~???
,\B/M,N\\\\WB/H,IWWWWQB/B,CQQQQTB/E,FTTTTf3W0Xffffar2R/SaaaaTR0E-FTTTTRR0C-DRRRR
YR0J-KYYYYZR0K-LZZZZ
#E* KKMME

R
R
R
RQ
R
R
RRR TUUU788800 	 	IC~~e$$ S3SSiSSSWSSSS   >>LLK:KKKKLLLLLLUVVVLL\]]]LLabbbRNOOOTUUUVWWWRSSSUVVVEFFFR  <===5L5LVZ[[[', 	 	IC!$(9!9!9vvrHLLWSWW4	?WWW$w-WWWXWW    	R  	IJJJ 	. 	.ALL,a	l,,----RCDDDLMMMEFFFR 
LLFGGG	LLU2HUUUUVVV	LLQ2DQQQQRRR	LL?@@@	LLBCCC99Ur   c                     t          |           }t          |          }t          ||          }t                              dt          |d                   t          |d                   |d                    |S )uf   
    Point d'entrée principal: prend les chunks RAG,
    extrait, analyse et formate le rapport.
    u3   audit_mandats: %d comptes, %d alertes, comm=%.2f€ro   rp   rq   )rc   r   r   rQ   rR   rS   )r*   r   rT   r   rapports        rb   audit_from_ragr   g  sw    
 %Z00GW%%G&w66GHH=G$%&&GI%&	   Nr   )r.   )__doc__rF   loggingtypingr   	getLoggerrQ   rx   r   rw   SEUIL_ALERTE_NB_MANDATSru   rt   rs   listrc   dictr   strr   r   r   r   rb   <module>r      sZ    
			       g,--      %#%$;  
,	' M *	
 
# L 6 $ % " !  & M (  
 !" +# . $.(#%*2&/#" )!*' ("! (Gt G G G G GTuD uT u u u upT Td T3 T T T T Tn t C       r   