+
    ]kejl)                     .   ^ RI t ^ RIHt ^ RIHt ^ RIHtHtHtH	t	H
t
 ^ RIHt ^ RIHt ^ RIHtHtHt ^ RIHt ^ R	IHt ^ R
IHtHtHtHt ^ RIHt ^ RIHt ^ RI H!t! ]! RR.R7      t"Rt#R R lt$]"PK                  R]&],          R7      ]	! R^R7      ]	! RRR7      R3R R ll4       t']"PK                  R4      ]	! RRR7      3R R ll4       t(]"PK                  R4      ]	! ^^R7      3R  R! ll4       t)]"PK                  R"]R7      R# R$ l4       t*]"PW                  R]]
PX                  R%7      R& R' l4       t-]"PK                  R(]R7      R) R* l4       t.]"P_                  R(]R7      R+ R, l4       t0]"Pc                  R(]
Pd                  R-7      R. R/ l4       t3R# )0    N)	Annotated)UUID)	APIRouterDependsHTTPExceptionQuerystatus)text)AsyncSession)CurrentUsercurrent_userrequire_admin)get_session)schedule_backfill_for_company)CompanyCreate
CompanyOutCompanyUpdate	NifLookup)
lookup_nif)schedule_enrichment)is_valid_nifz
/companies	companies)prefixtagsab  
    c.id::text, c.nif, c.legal_name, c.trade_name, c.cae, c.address, c.status,
    c.monitored, c.monitoring_type, c.data_coverage_start, c.data_coverage_end,
    c.risk_score, c.ptdata_fetched_at, c.created_at, c.updated_at, c.active,
    (SELECT ac.alvara_number FROM alvara_companies ac
     WHERE ac.nipc = c.nif AND ac.alvara_type = 'A' AND ac.removed_at IS NULL
     LIMIT 1) AS alvara_number,
    (SELECT MIN(dp.date) FROM dre_publications dp
     WHERE dp.company_id = c.id
       AND dp.source = 'mj'
       AND (dp.title ILIKE '%constitui%' OR dp.change_kind = 'constitution')
    ) AS founded_date
c                $    V ^8  d   QhR\         /# )   return)r   )formats   "app/api/companies.py__annotate__r    #   s     	 	* 	    c                    \        R/ R V ^ ,          bRV ^,          bRV ^,          bRV ^,          bRV ^,          bRV ^,          bRV ^,          bRV ^,          bRV ^,          bR	V ^	,          bR
V ^
,          bRV ^,          bRV ^,          bRV ^,          bRV ^,          bR\        V 4      ^8  d
   V ^,          MRbR\        V 4      ^8  d
   V ^,          MRbR\        V 4      ^8  d   V ^,          b # Rb # )idnif
legal_name
trade_namecaeaddressr	   	monitoredmonitoring_typedata_coverage_startdata_coverage_end
risk_scoreptdata_fetched_at
created_at
updated_atactiveTalvara_numberNfounded_date )r   len)rs   &r   _row_to_companyr7   #   s0    Q4qT&'d78tAB1OPQRtt t56qT aD 56bE GHe B%	 -.bE	 ?@e	
 Aqu  #1v{ae "!frkQrU  04 r!    )response_model)default
max_lengthz/^(internal|competitor|analysis|related|client)$)r:   patternc                   V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        R,          R\        R,          R\        R,          R\        \        ,          /# )r   session_userqNr*   r1   r   )
r   r   r   r   r   r   strboollistr   )r   s   "r   r    r    0   ss     . .|W[%99:.[',"778. Tz. 4Z	. 4K. 
*.r!   c           	        "   . p/ pV'       d   VP                  R 4       RV R2VR&   V'       d   VP                  R4       W6R&   Ve   VP                  R4       WFR&   V'       d   RR	P                  V4      ,           MR
pV P                  \        R\         RV R24      V4      G Rj  xL
 P                  4       pV U	u. uF  p	\        V	4      NK  	  up	#  L-u up	i 5i)z)(c.legal_name ILIKE :q OR c.nif ILIKE :q)%r@   zc.monitoring_type = :mtmtNzc.active = :actactzWHERE z AND r8   SELECT z FROM companies c z ORDER BY c.legal_name)appendjoinexecuter
   _COMPANY_COLSallr7   )
r>   r?   r@   r*   r1   whereparams	where_sqlrowsr6   s
   &&&&&     r   list_companiesrR   /   s      E "F@A!Ahs./&t&'u49GLL//rIoo7=/);I;F\]^
 	
 
ce 	 )--1OA--	

 .s/   .C5C'AC*C+CCCCz	/mj-statec          
          V ^8  d   QhR\         \        \        \        4      3,          R\         \        \        \
        4      3,          R\        R,          R\        \        \        3,          /# )r   r>   r?   r*   Nr   )r   r   r   r   r   r   rA   dict)r   s   "r   r    r    O   sZ     - -|W[%99:-[',"778- 4Z- 
#t)_-r!   c                  "   Rp/ pV'       d   RpW$R&   V P                  \        RV R24      V4      G Rj  xL
 P                  4       pV Uu/ uF  pV^ ,          RV^,          '       d   V^,          P                  4       MRRV^,          '       d   V^,          P                  4       MRR	\	        V^,          ;'       g    ^ 4      R
\	        V^,          ;'       g    ^ 4      /bK  	  up#  Lu upi 5i)a  Per-company MJ publication capture state. Used by the companies
list + detail header to show "last updated" so the user knows which
firms are due for a re-capture and which were just refreshed.
Returned as a map keyed by company_id for cheap client-side merge.r8   zAND c.monitoring_type = :mtrF   a-  
                SELECT c.id::text,
                       MAX(d.created_at) AS last_captured_at,
                       MAX(d.date)       AS last_pub_date,
                       COUNT(d.id)       AS total,
                       COUNT(d.id) FILTER (
                         WHERE COALESCE(length(d.raw_json->>'detail_body'), 0) > 0
                       ) AS with_detail
                FROM companies c
                LEFT JOIN dre_publications d
                       ON d.company_id = c.id AND d.source = 'mj'
                WHERE c.active = true z/
                GROUP BY c.id
                Nlast_captured_atlast_pub_datetotalwith_detail)rK   r
   rM   	isoformatint)r>   r?   r*   where_corO   rQ   r6   s   &&&    r   companies_mj_stater]   N   s      H "F0&too' (0j 1  #
 	
& 
ce) 	8  A 	
!AaDD! 0d1QqT^^-4S1^3qtyyq>	
 	
  )	
(s9   5C3C,C3C.+'C.-C.C.C.)C3.C3z/lookup-by-name)
min_lengthr;   c          	          V ^8  d   QhR\         \        \        \        4      3,          R\        R\
        \        \        \        3,          ,          /# )r   _adminr@   r   )r   r   r   r   rA   rC   rT   object)r   s   "r   r    r       sC     # #k7=#99:#
# 
$sF{
#r!   c                :   "   ^ RI Hp V! V4      G Rj  xL
 #  L5i)u   Pesquisa inversa nome -> NIPC, via SICAE.

Útil quando um anúncio de insolvência ou uma publicação traz uma entidade
sem NIF: o nome é o único ponto de partida para a identificar.
)lookup_by_nameN)app.services.nif_lookuprc   )r`   r@   rc   s   && r   company_lookup_by_namere      s      7""""s   z/lookup/{nif}c                p    V ^8  d   QhR\         R\        \        \        \        4      3,          R\
        /# )r   r$   r`   r   )rA   r   r   r   r   r   )r   s   "r   r    r       s5      	k7=#99: r!   c                    "   \        V 4      '       g   \        V R RR7      # \        V 4      G Rj  xL
 p\        R/ VB #  L5i)Flocal)r$   validsourceNr4   )r   r   r   )r$   r`   datas   && r   company_lookuprl      s@     
 Sg>>C Dt !s   .AA A)r9   status_codec          
          V ^8  d   QhR\         R\        \        \        \        4      3,          R\        \
        \        \        4      3,          R\        /# )r   payloadr>   r`   r   )r   r   r   r   r   r   r   r   )r   s   "r   r    r       sT     K  K K |W[%99:K  k7=#99:K  	K r!   c                 <  "   \        V P                  4      '       g   \        \        P                  R 4      hVP                  \        R4      RV P                  /4      G Rj  xL
 P                  4       pV'       d   \        \        P                  R4      hV P                  '       dB   V P                  pV P                  pV P                  pV P                  pV P                  pRp	Rp
M\        V P                  4      G Rj  xL
 pVP                  R4      ;'       g    RpVP                  R4      pVP                  R	4      pVP                  R
4      pVP                  R4      pVP                  R4      p	VP                  R4      R8w  d   RMRp
TP                  \        RV
 R\         R24      RV P                  RTRTR	TRTRTRV	'       d   \         P"                  ! V	4      MRRV P$                  RV P&                  /	4      G Rj  xL
 P                  4       pVP)                  4       G Rj  xL
  V'       g   \+        V^ ,          V P                  4       V P$                  '       d   \-        V^ ,          V P                  4       \/        V4      #  EL0 EL L Lk5i)zinvalid NIF checksumz&SELECT 1 FROM companies WHERE nif = :nnNzNIF already existsNULLr%   r8   r&   r'   r(   r	   rawrj   rh   znow()aX  
                INSERT INTO companies (nif, legal_name, trade_name, cae, address, status,
                                       ptdata_payload, ptdata_fetched_at, monitored,
                                       monitoring_type)
                VALUES (:nif, :legal, :trade, :cae, :addr, :status,
                        CAST(:pt AS JSONB), zE, :monitored,
                        :mt)
                RETURNING 
                r$   legaltradeaddrptr)   rF   )r   r$   r   r	   HTTP_400_BAD_REQUESTrK   r
   firstHTTP_409_CONFLICTr%   r&   r'   r(   r   getrL   jsondumpsr)   r*   commitr   r   r7   )ro   r>   r`   existingru   rv   r'   rw   stptdata_payloadptdata_fetched_at_sqlenrichrows   &&&          r   create_companyr      sK     $$F779OPPood#KLsT[T_T_N`aaeg  F446JKK
 """"kk^^ &!'++..

<(..B

<(jjzz)$ZZ!E* ,2::h+?7+JPV oo-
 .C,C D(/ *
 w{{s"Ndjj0W..g--

 	
0 eg3 4 ..
 CFGKK0 %c!fgkk:3G 	b" /	
2 sh   A J"J#J=+J)AJJJC)JJ	%J.J/J;.J*)JJJJz/{company_id}c          
          V ^8  d   QhR\         R\        \        \        \        4      3,          R\        \
        \        \        4      3,          R\        /# )r   
company_idr>   r?   r   )r   r   r   r   r   r   r   r   )r   s   "r   r    r       sN         |W[%99:  [',"778  	 r!   c                    "   VP                  \        R \         R24      R\        V 4      /4      G Rj  xL
 P	                  4       pV'       g   \        \        P                  4      h\        V4      #  L>5i)rH   z" FROM companies c WHERE c.id = :idr#   N)	rK   r
   rL   rA   rz   r   r	   HTTP_404_NOT_FOUNDr7   )r   r>   r?   r   s   &&& r   get_companyr      sj      oo7=/)KLM3z?#
 	
 eg  F55663	
s   2A5A3A5%A5c                    V ^8  d   QhR\         R\        R\        \        \	        \
        4      3,          R\        \        \	        \        4      3,          R\        /# )r   r   ro   r>   r`   r   )	r   r   r   r   r   r   r   r   r   )r   s   "r   r    r       sX           |W[%99:  k7=#99:	 
  r!   c           	        "   VP                  R R7      pV'       g   \        \        P                  R4      hRP	                  R VP                  4        4       4      p/ VCR\        V 4      /CpVP                  \        RV R\         R24      V4      G R	j  xL
 P                  4       pV'       g   \        \        P                  4      hVP                  4       G R	j  xL
  \        V4      #  LV L5i)
T)exclude_unsetznothing to updatez, c              3   .   "   T F  q R V 2x  K  	  R# 5i)z = :Nr4   ).0ks   & r   	<genexpr>!update_company.<locals>.<genexpr>  s     :Mqs$qc]Ms   r#   z&
                UPDATE companies SET z>, updated_at = now() WHERE id = :id
                RETURNING rt   N)
model_dumpr   r	   ry   rJ   keysrA   rK   r
   rL   rz   r   r   r7   )r   ro   r>   r`   fieldssetsrO   r   s   &&&&    r   update_companyr      s      d3FF779LMM99:FKKM::D..c*o.Foo&&*V ,(/ * 
 	
 eg  F5566
..
3	
 s*   BC2C.C22,C2C0C20C2)rm   c          
          V ^8  d   QhR\         R\        \        \        \        4      3,          R\        \
        \        \        4      3,          RR/# )r   r   r>   r`   r   N)r   r   r   r   r   r   r   )r   s   "r   r    r      sN      |W[%99: k7=#99: 
	r!   c                    "   VP                  \        R 4      R\        V 4      /4      G Rj  xL
  VP                  4       G Rj  xL
  R#  L L5i)z$DELETE FROM companies WHERE id = :idr#   N)rK   r
   rA   r   )r   r>   r`   s   &&&r   delete_companyr     sD      //$EFsS]H_
```
..
 as!   *AAAAAA)4r}   typingr   uuidr   fastapir   r   r   r   r	   
sqlalchemyr
   sqlalchemy.ext.asyncior   app.auth.depsr   r   r   app.dbr   app.jobs.schedulerr   app.schemas.companyr   r   r   r   rd   r   app.services.enrichmentr   app.services.nifr   routerrL   r7   r|   rC   rR   r]   re   rl   postHTTP_201_CREATEDr   r   patchr   deleteHTTP_204_NO_CONTENTr   r4   r!   r   <module>r      s      D D  / B B  < S S . 7 )	,k]	;	 BtJ/0 $37"'O# . 1.< K #(O#- -`  aC0# # OI6 7 R
8O8OPK  QK \ OJ7  8   oj9  : 8 F,F,FG Hr!   