U
    ^¨jÔ9  ã                   @   s„  d dl mZmZ d dlmZmZmZ d dlmZ d dl	m
Z
 dZdZdZdZd	d
ddgZdd„ Zeeeedœdd„Zeedœdd„Zeedœdd„Zeedœdd„Zeedœdd„Zeeeedœdd „Zed!œd"d#„Zed$œd%d&„Zeedœd'd(„Zeed)œd*d+„Zd,d-„ Zd.d/„ Z eed0œd1d2„Z!eed3œd4d5„Z"eeed6œd7d8„Z#eeeed9œd:d;„Z$eeeed<œd=d>„Z%eeed?œd@dA„Z&dBS )Cé    )ÚFlaskÚjsonify)Ú
JWTManagerÚjwt_requiredÚget_jwt_identity)ÚMongoClient)ÚdefaultdictÚusersÚENVIROÚ
NANOOX__TSÚScappDBÚenviroÚnanooxÚpssÚscappc                   C   s   dt krtdƒt _t jS )u-   Obtiene una conexiÃ³n de MongoDB por request.Ú	db_clientzmongodb://localhost:27017/)Úgr   r   © r   r   ú=/var/www/itgmanager/itgmanager/modules/consolidado_estados.pyÚget_db   s    
r   )Ú
ciclo_infoÚuser_statusÚservicioÚreturnc                 C   s   t |o|  |i ¡ dd¡ƒS )z_
    Intersecta el estado de permiso del usuario con el estado del ciclo para un servicio.
    ÚstatusF)ÚboolÚget)r   r   r   r   r   r   Úintersect_service_status   s    r   )Úusernamer   c                 C   s6   |   d|i¡}|s*tj d|› d�¡ i S | di ¡S )uT   
    Obtiene los permisos crudos (raw) del usuario desde la colecciÃ³n 'users'.
    r   z	Usuario 'z' no encontrado.Úpermisos)Úfind_oneÚappÚloggerÚwarningr   )Úusers_collectionr   Úusuarior   r   r   Úget_accesos_usuario   s
    r&   )Úpermisos_usuariosr   c              	   C   sÚ   | t  j}i }| di ¡ ¡ D ]¶\}}i ||< | ¡ D ]œ\}}i || |< |D ]‚}| d| ¡ i¡}	|	szg || | |< qNi }
tD ]<}|d | | |  |i ¡ dd¡}dt|	||ƒi|
|< q‚|
|| | |< qNq6q|S )un   
    Cruza los permisos del usuario con los datos de la colecciÃ³n 'ciclos', retornando permisos activos.
    r   Ú	centro_idr   F)Úuser_database_nameÚciclosr   Úitemsr    ÚlowerÚSERVICE_KEYSr   )Úclientr'   r*   Ú	resultadoÚregionÚareasÚareaÚcentrosÚcentroÚinfoÚnodoÚsvcr   r   r   r   Úprocesar_permisos&   s.    
 ÿ ÿr8   )Úpermisos_procr   c                 C   s0   i }|   ¡ D ]\}}dd„ |  ¡ D ƒ||< q|S )zw
    Transforma {R:{A:{C_ids: [...]}}} en {R:{A:{clave:{'_id':orig}}}}.
    clave = texto antes de '-' en cada ID.
    c                 S   s    i | ]\}}|d d„ |D ƒ“qS )c                 S   s"   i | ]}|  d d¡d d|i“qS )Ú-é   r   Ú_id)Úsplit)Ú.0r(   r   r   r   Ú
<dictcomp>I   s   ÿ z6transformar_diccionario.<locals>.<dictcomp>.<dictcomp>r   )r>   r2   r3   r   r   r   r?   H   s
   ü þz+transformar_diccionario.<locals>.<dictcomp>)r+   )r9   Úoutr0   r1   r   r   r   Útransformar_diccionarioA   s    ûrA   )Údatar   c                 C   sJ   g }|   ¡ D ]8}|  ¡ D ]*}|  ¡ D ]}| d¡}|r$| |¡ q$qq|S )zP
    Extrae lista de todos los valores '_id' en la estructura transformada.
    r<   )Úvaluesr   Úappend)rB   Úidsr1   r3   r6   r<   r   r   r   Úobtener_idsR   s    
rF   )r   r(   r   r   c                 C   s¤   | t  j}dd|iiddddiiiddidddd	iiidd
iddddiiiddiddddidœiddid||dœiddddœig}t| |¡ƒ}|r |d d S dS )u\   
    Consulta la colecciÃ³n 'users' con pipeline para extraer el status de un servicio.
    z$matchr   z$projectr   z$objectToArrayz	$permisosz$unwindÚciudadesz$permisos.vz	$ciudadesr3   z$ciudades.vz$centrosz
$centros.kz
$centros.v)r(   Ú	serviciosz
$servicios)r(   zservicios.kr   z$servicios.v.status)r<   r   r   F)r)   r	   ÚlistÚ	aggregate)r.   r   r(   r   r	   ÚpipelineÚresr   r   r   Ústatus_servicio_permiso_usuario`   s    

õrM   )r(   c                 C   s0   | t  j}| d|iddi¡}|r&|S dddœS )uQ   
    Retorna el estado de 'enviro' y 'nanoox' desde la colecciÃ³n 'estados'.
    r(   r<   r   ÚB)r   r   )r)   Úestadosr    )r.   r(   ÚcolÚdocr   r   r   Úobtener_estado_servicio_centrov   s    
rR   )r   c                 C   s8   | |g}t dd„ |D ƒƒrdS t dd„ |D ƒƒr4dS dS )uh   
    Obtiene el estado resultante del centro segÃºn el estado de Enviro y Nanoox ('C' > 'A' > 'B').
    c                 s   s   | ]}|d kV  qdS )ÚCNr   ©r>   Úer   r   r   Ú	<genexpr>„   s     z estado_centro.<locals>.<genexpr>rS   c                 s   s   | ]}|d kV  qdS )ÚANr   rT   r   r   r   rV   †   s     rW   rN   )Úany)Úestado_enviroÚestado_nanooxrO   r   r   r   Úestado_centro   s    r[   c                 C   s`   t tƒ}|  ¡ D ]F\}}| ¡ D ]4\}}|› d|› �}| ¡ D ]}d|| |d < q>q qt|ƒS )zA
    Agrupa centros bajo clave 'region-area' con valor None.
    r:   Nr<   )r   Údictr+   rC   )rB   r@   r0   r1   r2   r3   Úkeyr6   r   r   r   Úagrupar_por_region_area‹   s    r^   )r.   r(   c                 C   sn   | t  j}| d| ¡ idddœ¡}|r0d|kr:dddœS |d }| d¡}| |i ¡}| d	¡| d
¡dœS )z‰
    Retorna {'lat': ..., 'lon': ...} desde db users coleccion ciclos
    inspeccionando gps_coordinates.active ('manual' o 'auto').
    r(   r   r;   )r<   Úgps_coordinatesr_   N)ÚlatÚlonÚactiver`   ra   )r)   r*   r    r,   r   )r.   r(   r*   rQ   ÚgpsZactivoÚsubr   r   r   Úobtener_coordenadas˜   s    

þ

þre   c                 C   sŽ   t | tƒr\g }|  ¡ D ],\}}t|ƒ}|dkr:| |¡ q|| |< q|D ]
}| |= qH| pZdS t | tƒrŠdd„ | D ƒ}dd„ |D ƒ}|pˆdS | S )u~   
    Elimina recursivamente claves con valor None o listas vacÃ­as.
    Devuelve None si el objeto completo queda vacÃ­o.
    Nc                 S   s   g | ]}t |ƒ‘qS r   )Ú
clean_none©r>   Úxr   r   r   Ú
<listcomp>Û   s     zclean_none.<locals>.<listcomp>c                 S   s   g | ]}|d k	r|‘qS )Nr   rg   r   r   r   ri   Ü   s      )Ú
isinstancer\   r+   rf   rD   rI   )rB   Zto_delÚkÚvÚcvÚcleanedr   r   r   rf   É   s    


rf   c                 C   s    d| krdS d| krdS dS dS )uÙ   
    A partir de una lista de estados retorna el valor predominante(C>A>B).
    Si existe al menos una C, retornarÃ¡ C; de existir al menos una A sin
    existencia de C, retornarÃ¡ A. De no existir, retornarÃ¡ B
    rS   rW   rN   Nr   )Úvalorr   r   r   Úactualizar_valorá   s
    rp   )Úconsolidado_por_centror   c                 C   sˆ   i }| p
i   ¡ D ]r\}}g }| ¡ D ]F}t|tƒrJd|krJ| |d ¡ q$t|tƒr`| |¡ q$| d¡ q$d |¡}t|ƒ||< q|S )z€
    Concatena y colapsa por 'R-A', luego aplica actualizar_valor.
    Extrae el campo 'estado' cuando el valor es un dict.
    ÚestadorN   Ú )r+   rC   rj   r\   rD   ÚstrÚjoinrp   )rq   r@   Úrar3   rO   ÚitemZconcatenatedr   r   r   Úestado_resultante_area_region	  s    

rx   )Úarea_region_statesr   c                 C   sT   t tƒ}| pi  ¡ D ],\}}| dd¡d }||  |p:d7  < qdd„ | ¡ D ƒS )u‹   
    Agrupa por regiÃ³n (parte antes del guiÃ³n), concatena los valores resultantes
    de estado por Ã¡rea y aplica actualizar_valor.
    r:   r;   r   rN   c                 S   s   i | ]\}}|t |ƒ“qS r   )rp   )r>   Úrrl   r   r   r   r?   (  s      z,estado_resultante_region.<locals>.<dictcomp>)r   rt   r+   r=   )ry   Zaggrv   Úvalr0   r   r   r   Úestado_resultante_region  s
    r|   )r   Úpager   c                 C   s(   t ||ƒ}| ¡ dkr|S t| d|iƒS )uX   
    Retorna permisos de usuario procesados segÃºn PAGE: raw o cruzados con ciclos.
    ÚHOMEr   )r&   Úupperr8   )r.   Ú
users_collr   r}   Úrawr   r   r   Úfetch_effective_permissions6  s    
r‚   )r}   rB   r   r   c           
      C   sŽ   | t  j}i }t|ƒD ]r}| ¡ dkp6t| ||| ¡ ƒ}|s>qd}d}	| ¡ dkr`t| |ƒd }| ¡ dkrzt| |ƒd }	t||	ƒ||< q|S )uF   
    Calcula estado actual de cada centro segÃºn PAGE y permisos.
    r~   N)r~   r
   r   )r~   ÚNANOOXr   )r)   r*   rF   r   rM   r,   rR   r[   )
r.   r}   rB   r   r*   Únuevosr(   Z	permitidoZ	state_envZ	state_nanr   r   r   Úcompute_new_values@  s     
ÿr…   )ÚgrupoÚdict_estadosr.   r   c                 C   sD   |   ¡ D ]6\}}t|ƒD ]$}||kr|| t||ƒdœ||< qq| S )zT
    Inserta estado y coordenadas de cada centro en el diccionario de permisos.
    )rr   Zcoordenadas)r+   rI   re   )r†   r‡   r.   rv   r3   r(   r   r   r   Ú$agregar_estado_centros_a_consolidado_  s    þrˆ   )r.   r   r}   c              
   C   sæ   z t dƒ | t j}t| |||ƒ}t|ƒ}t| |||ƒ}ttt|ƒ|| ƒƒ}t d|›d�ƒ t	|pdi ƒ}t d|›d�ƒ t
|p€i ƒ}	t d|	›d�ƒ |||	dœW S  tk
rà }
 z"t d|
jj› d|
› �ƒ W Y ¢d	S d	}
~
X Y nX d	S )
u¦   
    Orquesta todo el flujo del consolidado:
      1. Permisos â†’ 2. Transformar â†’ 3. Valores â†’ 4. Merge+coords â†’
      5. JerarquÃ­as (Ã¡reas y regiones)
    zEN CONSOLIDADO EMPRESASzcentros=z 
zareas=z	regiones=)r3   r1   Úregionesu/   Error obteniendo consolidado empresa en lÃ­nea z: 
N)Úprintr)   r	   r‚   rA   r…   rf   rˆ   r^   rx   r|   Ú	ExceptionÚ__traceback__Ú	tb_lineno)r.   r   r}   r€   r   rB   r„   r3   r1   r‰   rU   r   r   r   Úconsolidado_empresa|  s,    
  ÿÿrŽ   N)'Úflaskr   r   Úflask_jwt_extendedr   r   r   Úpymongor   Úcollectionsr   r)   Zenviro_database_nameZnanoox_database_nameZscapp_database_namer-   r   r\   r   rt   r   r&   r8   rA   rI   rF   rM   rR   r[   r^   re   rf   rp   rx   r|   r‚   r…   rˆ   rŽ   r   r   r   r   Ú<module>   s6   	1(
