U
    ^¨jsÉ  ã                   @   sÒ  d dl mZ d dlmZ ddlmZmZ ddlZddlZddlZddl	Z	ddl
mZ ddlZddlmZ ddlmZmZmZmZmZmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZmZ ddlm Z  ddl!Z!ddl!m"Z" ddl#m$Z$ dZ%ddddddgZ&ddddddgZ'dZ(dd„ Z)dd„ Z*dd„ Z+dId d!„Z,dJd&d'„Z-d(d)„ Z.d*d+„ Z/d,d-„ Z0e1ee1 d.œd/d0„Z2d1d2„ Z3d3d4„ Z4d5d6„ Z5dKd7d8„Z6d9d:„ Z7d;d<„ Z8d=d>„ Z9d?d@„ Z:dAdB„ Z;dCdD„ Z<dEdF„ Z=dGdH„ Z>dS )Lé   )Úguardar_estructura_en_mongodb)Úsave_comap_dataé    ©ÚdatetimeÚ	timedeltaN)ÚOptional©Úget_column_letter)ÚBorderÚSideÚPatternFillÚFontÚGradientFillÚ	Alignment)Ú	LineChartÚ	Reference©ÚImage)ÚCharacterProperties)r
   Úcolumn_index_from_string)ÚWorkbookProtection)Úcreate_unicode_buffer)ÚPathZitg123chileÚhoraÚO2ÚSO2ÚTEMPZRLYZStartZTempé2   c                 C   sv   t d|› �ƒ | d }t dt| d|i¡ƒ›�ƒ | d|i¡D ]0}t |ƒ d|krjt dƒ | d¡  S  dS q@dS )	NzEN get_control_by_centro_id  Úmetadataz2list(metadata_col.find({'centro_id': centro_id}))=Ú	centro_idÚcontrolzENCONTRE EL CONTROLZVDFÚPS)ÚprintÚlistÚfindÚget)Ú	nanoox_dbr    Úmetadata_colÚdoc© r*   ú:/var/www/itgmanager/itgmanager/nanoox/nanoox_timeseries.pyÚget_control_by_centro_id:   s    r,   c                 C   sP   | | }|j d|idddœd�}td|› �ƒ t|ƒ |rLd|krL| d¡S dS )	zADevuelve control_version para el centro dado o None si no existe.r    r   r   )Úcontrol_versionÚ_id)Ú
projectionz%EN get_control_version_by_centro_id  r-   N)Úfind_oner#   r&   )r'   Úmetadata_col_namer    r(   r)   r*   r*   r+   Ú get_control_version_by_centro_id[   s    þr2   c                 C   s*   |   d¡}t|tƒrdS t|tƒr&dS dS )zæ
    Determina el formato de 'data' dentro del JSON recibido.
    
    Retorna:
      - "0" si 'data' es un diccionario (formato simple).
      - "nested" si 'data' es una lista (formato anidado).
      - None en otros casos.
    ÚdataÚdictÚnestedN)r&   Ú
isinstancer4   r$   )Údatosr3   r*   r*   r+   Útipo_de_datosj   s    	


r8   Fc              
   C   sÈ  t dd ¡ d›d�ƒ t | ¡ › d|› d|›�ƒ | d¡}t d|›�ƒ | dd	¡}z¼| d
¡}|r†t| || dg ¡||||d� nt d|› d�ƒ t ddd›d�ƒ t d| d¡›�ƒ | dg ¡}|rØt| ||ƒ t dƒ |�s| d¡}t d|›�ƒ |�rt| ||ƒ W n< tk
�rN }	 zt d|	jj	› d|	› �ƒ W 5 d}	~	X Y nX z6| d¡�p`i }
|
�rvt
| ||
ƒ nt d|› �ƒ W n< tk
�rÂ }	 zt d|	jj	› d|	› �ƒ W 5 d}	~	X Y nX dS )u]   
    Procesa un Ãºnico registro de datos extrayendo cada bloque y guardÃ¡ndolo en la BD.
    Ú
zestamos en process_sensor_dataz*^100Ú z, new_version=r   z
timestamp=r!   r"   ÚmodulosÚ
generators©Ú	timestampzSin bloque 'modulos' para z#: no se actualiza estructura logicaz"  # Procesar historial de control z*^60zdata.get('historial_control')=Úhistorial_controlzantes de revisar generadoresÚ	generadorz
generador=zerror en linea NÚgenerators_comapzSin datos COMAP para zError procesando COMAP linea z: )r#   ÚupperÚkeysr&   r   Úsave_one_historial_dataÚsave_one_generator_dataÚ	ExceptionÚ__traceback__Ú	tb_linenor   )Údbr3   r    Únew_versionr>   r!   r;   Úlogsr@   ÚeZcomap_blockr*   r*   r+   Úprocess_sensor_data   s<    

 
*rM   ÚCé   é   é   c                 C   s¦   t |ƒ}t|ƒD ]ˆ}|||  }|dkr<td|› d�ƒ  qš|dk rVtd|› d�ƒ qt|ƒ}	|	› |› �}
t|ƒ}d|_d|_|  ||
¡ td	|
› �ƒ qtd
ƒ dS )uÙ  
    Inserta repetidamente la imagen en la hoja, avanzando horizontalmente
    columnas que pueden exceder la 'Z' (soporta AA, AB, etc.).
    
    :param worksheet: Hoja de cÃ¡lculo (openpyxl worksheet)
    :param img_path: Ruta al archivo de imagen
    :param start_column: Columna inicial (string), p.ej "C"
    :param start_row: Fila inicial (int)
    :param repeats: CuÃ¡ntas veces quieres repetir la imagen
    :param step: CuÃ¡ntas columnas saltar cada vez (int)
    i @  zLa columna calculada (u/   ) excede el lÃ­mite de Excel (XFD). Deteniendo.r   u   Ã�ndice de columna no vÃ¡lido (z). Se ignora.iX  iÂ  zImagen insertada en uG   Marca de agua agregada (con expansiÃ³n de columnas) satisfactoriamente.N)r   Úranger#   r
   ÚExcelImgÚwidthÚheightÚ	add_image)Ú	worksheetÚimg_pathÚstart_columnÚ	start_rowÚrepeatsÚstepZstart_col_numÚiZ	col_indexZnew_col_strZnew_positionZimg_copyr*   r*   r+   Úadd_markwater_imagesÌ   s"    r^   c                  C   s$   t dƒ} tjj dddd| ¡ | jS )zGObtiene la ruta del escritorio utilizando funciones nativas de Windows.i  r   )r   ÚctypesÚwindllZshell32ZSHGetFolderPathWÚvalue)Úbufr*   r*   r+   Úget_escritorio_pathø   s    rc   c           	   
   C   s¬   zt|d }t |ƒ}d|i}d|id|id|idœ}| jj||dd�}|jdkr`td	|› d
�ƒ ntd|› d�ƒ |W S  tk
r¦ } ztd|› �ƒ ‚ W 5 d}~X Y nX dS )u¦  
    Agrega un nuevo log al documento correspondiente a la fecha actual en la colecciÃ³n 'historial_control'.
    Si el documento de la fecha no existe, lo crea con el log como primer elemento en el arreglo 'logs'.

    :param db: ConexiÃ³n a la base de datos MongoDB.
    :param data: Diccionario que contiene la informaciÃ³n a guardar en el log.
    :return: Resultado de la operaciÃ³n de actualizaciÃ³n/inserciÃ³n.
    ÚfechaÚdater    rK   )ú$setOnInsertrf   ú$pushT©Úupsertr   z0Log agregado al documento existente de la fecha Ú.zDocumento creado para la fecha z y log agregado.z,Error al agregar log a 'historial_control': N)Ú__extract_dater?   Ú
update_oneÚmatched_countr#   rF   )	rI   r    r3   Zdate_from_logZformatted_current_dateÚqueryÚupdateÚresultrL   r*   r*   r+   Ú!original_add_to_historial_control   s     	ý
rq   c              
   C   s²  |sdS i }|D ]F}t | d¡ƒp6| dd¡ d¡d }||krHg ||< ||  |¡ qg }| ¡ D ]€\}}| j ||dœdd	i¡}	|	r´t|	 dg ¡ƒd
kr´td|› d|› d�ƒ qd| t	j
||dœ||dœdd|iidœdd�¡ qd|�r®z"| jj|dd� td|› �ƒ W nž t	jjk
�r| }
 zJ|
j dg ¡D ]6}| d¡dk�sXd| d¡k�r4td|› d�ƒ �q4W 5 d}
~
X Y n2 tk
�r¬ } ztd|› �ƒ W 5 d}~X Y nX dS )uP   
    Inserta logs usando BulkWrite y $addToSet con un lÃ­mite de seguridad.
    Nrd   re   Ú r:   r   )re   r    rK   r   i'  zAVISO: Documento de z para u6    estÃ¡ cerca del lÃ­mite de 16MB. Saltando inserciÃ³n.z$each)rf   z	$addToSetTrh   F)ÚorderedzBulkWrite exitoso para ÚwriteErrorsÚcodei^(  zlarger than 16777216Úerrmsgu   CRÃ�TICO: El documento de u%    alcanzÃ³ el lÃ­mite fÃ­sico de 16MB.zError en BulkWrite: )rk   r&   ÚsplitÚappendÚitemsr?   r0   Úlenr#   ÚpymongoÚ	UpdateOneÚ
bulk_writeÚerrorsÚBulkWriteErrorÚdetailsrF   )rI   r    Z	logs_listZlogs_por_fechaÚlogZ	fecha_docÚoperacionesrd   rK   Z
doc_actualÚbweÚerrorrL   r*   r*   r+   Ú_add_to_historial_control(  sB    $
þúÿ $r…   )Útimestamp_strÚreturnc                 C   sV   d}t  || ¡}|sdS z"t | dd… d¡}| ¡  ¡ W S  tk
rP   Y dS X dS )zÑ
    Validates and extracts the date from a timestamp string
    in the format "[YYYY/MM/DD - HH:MM:SS]".
    
    Returns the date as a string in "YYYY-MM-DD" format if valid,
    otherwise returns None.
    z7^\[(\d{4})/(\d{2})/(\d{2}) - (\d{2}):(\d{2}):(\d{2})\]$Nr   éÿÿÿÿz%Y/%m/%d - %H:%M:%S)ÚreÚmatchr   Ústrptimere   Ú	isoformatÚ
ValueError)r†   ÚpatternrŠ   Z	parsed_dtr*   r*   r+   rk   ^  s    rk   c              
   C   sV   z t | ||ƒ td|› d�ƒ W n0 tk
rP } ztd|› �ƒ W 5 d }~X Y nX d S )NzFDatos de historial de control actualizados correctamente para Centro: rj   zError al actualizar los datos: )r…   r#   rF   )rI   Zhistorial_datar    rL   r*   r*   r+   rD   ‚  s
    rD   c                 C   s   d|i}|   |¡}t|ƒS )NÚaviot_id)r%   r$   )Ú
collectionr�   ÚfiltroÚ	documentor*   r*   r+   Úget_documentos_historialŒ  s    
r“   c              
   C   s„   zB| j }| i ¡}i }|D ]"}| d¡}| dg ¡}|||< q|W S  tk
r~ } ztd|› d|jj› �ƒ ‚ W 5 d}~X Y nX dS )õ%  
    Obtiene todos los logs de la colecciÃ³n 'historial_control' y los organiza en un diccionario.
    Las llaves del diccionario son las fechas (en formato 'YYYY-MM-DD') y los valores son listas de logs.

    :return: Diccionario con las fechas como llaves y listas de logs como valores.
    re   rK   ú6Error al obtener el historial de 'historial_control': r:   N)r?   r%   r&   rF   r#   rG   rH   )rI   r�   Ú	documentsÚhistorial_dictr)   re   rK   rL   r*   r*   r+   Úget_historial_control_as_dict–  s    


r˜   c              
   C   s  zÈ| j }i }|r€| d¡}| d¡}|r>t |d¡}| d¡}|rXt |d¡}| d¡}	i |d< |rp||d d< |r€|	|d d< | |¡}
i }|
D ]&}| d¡}| dg ¡}|r’|||< q’|sÄW d	S |W S  tk
�r } ztd
|› d|jj	› �ƒ ‚ W 5 d	}~X Y nX d	S )u   
    Obtiene todos los logs de la colecciÃ³n 'historial_control' y los organiza en un diccionario.
    Las llaves del diccionario son las fechas (en formato 'YYYY-MM-DD') y los valores son listas de logs.
    
    Si se proporciona 'rango_fechas', se espera un diccionario con:
       {'startDate': '27/02/2025', 'endDate': '27/02/2025'}
    y se realiza la conversiÃ³n para filtrar los documentos entre ambas fechas.
    
    :return: Diccionario con las fechas como llaves y listas de logs como valores, o None si no se encuentran datos.
    Ú	startDateÚendDateú%d/%m/%Yú%Y-%m-%dre   z$gtez$lterK   Nr•   r:   )
r?   r&   r   r‹   Ústrftimer%   rF   r#   rG   rH   )rI   Úrango_fechasr�   rn   Zstart_date_inputZend_date_inputZdt_startZstart_date_strZdt_endZend_date_strr–   r—   r)   re   rK   rL   r*   r*   r+   Ú get_historial_control_as_dict_sm³  s<    






rŸ   c           
   
   C   s”   zR| j }t ¡  d¡}| ||dœ¡}g }|D ]}| d¡}| dg ¡}|}q.|W S  tk
rŽ }	 ztd|	› d|	jj	› �ƒ ‚ W 5 d}	~	X Y nX dS )r”   rœ   ©r    re   re   rK   r•   r:   N)
r?   r   Únowr�   r%   r&   rF   r#   rG   rH   )
rI   r    r�   rd   r–   r—   r)   re   rK   rL   r*   r*   r+   Úget_historial_controlå  s    
r¢   c           >      C   sl  t dƒ t |d d¡}t |d d¡}tt|| ƒ d¡ƒdkrntt|| ƒ d¡d ƒd }t d|d	ƒ nd}d
}�zªt| ƒ}d}	d}
d}dg|d  }d}||
 d }t 	¡ }g }t
ƒ }i }| ¡ D ]Ô\}}t|
d ƒ}t|
| ƒ}t|
d ƒ}|||t|td|	 ƒ ƒt|tt|ƒd |	 ƒ ƒdœ||< |D ]f}||k�rLg ||< |d dk�rn||  |d ¡ n,|d dk�rŒ||  d¡ n||  d¡ �q6qÊt|ƒD �]Ê}t|t|d� ƒ d¡d  d¡}d |¡}|| ¡ k�rbd}| |¡}| |¡ t|	ƒD ]}| g ¡ �qdg|
 dg }| |¡ dg|
 dddg }| |¡ || }t|ƒ} t|ƒD ]Æ\}!}"g }#|# d¡ |# d¡ z\|" dd¡}$|$ d¡}!|" d¡ d¡d }%|$d |!d … }&|$|!d d … }'|#|%|&|'g7 }#W n< tk
�r" }( zt d|(› d |(jj› �ƒ W 5 d }(~(X Y nX | |#¡ �qjzXtj tj t¡¡})tj |)d!d"¡}*tj |*¡�sttd#|*› �ƒ‚t ||*d$d%dd&d'� W n2 tk
�r¼ }( zt d(|(› �ƒ W 5 d }(~(X Y nX t!dd)d*�}+t"d+d,d,d-�},t"d+d.d.d-�}-t"d+d/d/d-�}.t#t$d0d1d2�t$d0d1d2�t$d0d1d2�t$d0d1d2�d3�}/t|
d ƒ}0t|
d ƒ}1t|
d ƒ}2||0t|	d ƒ  }3|+|3_%|,|3_&||0t|	d ƒ  }4||1t|	d ƒ  }5||2t|	d ƒ  }6|+|4_%|+|5_%|+|6_%|,|4_&|,|5_&|,|6_&|j'|	d |
d |	d |
d d4� ||| d5 || d6 … }7|7D ]}8|8D ]}9|/|9_(�q�q
t|j)|	d | |	 d d7�ƒD ]6\}!}8|8D ]&}9t!|| |! dd … d8� |9_%}+�qN�qBt|j)|	d | |	 d d7�ƒD ](\}!}8|8D ]}9t*d9d9dd
d:�|9_+�q¤�q˜|j,D ]v}:d};|:D ]B}9z.|9j-d k	�rtt|9j-ƒƒ|;k�rt|9j-ƒ};W n   Y nX �qÔ|;d }<|<dk�rÈ|<|j.|:d j/ _0�qÈd|j1_2d|j1_3d|j1_4t5|j1_5nt d;|› d<�ƒ �q¨t d=|› �ƒ |�s˜t d>ƒ W d
S tj ||¡}=t d?|=› �ƒ tj |¡�sÐtd@|› �ƒ‚dA|j6k�rê| 7|dA ¡ t5|j8_9d|j8_:| ;|=¡ | <¡  t dB|=› �ƒ W dS W nD tk
�rf }( z$t dC|(› dD|(jj› dE�ƒ W Y ¢d S d }(~(X Y nX d S )FNz1********ENTRANDO A GENERAR HISTORIAL ************r™   r›   rš   r:   r   r   zSe han seleccionado z diasFé   é   rr   rP   é   )Z	L_InicialZL_FinalZL_GraphÚceldaInicialÚ
celdaFinalÚcolorz#FFFFFFz#E6E6FAz#000000©ÚdaysÚ-TzHistorial de controlZHorau
   CategorÃ­au   DescripciÃ³nÚmsgú]re   zError: z  ÚimagesúLogo_Reportes.pngúNo se encuentra la imagen en: rN   rO   rQ   ©rY   rZ   r[   r\   ú#Error al agregar la marca de agua: ZFFFFFF)Úbr¨   ÚsolidZe84e0e)Ú	fill_typeÚstart_colorÚ	end_colorZa2ff00ZC8C8C8ÚthinÚ000000)Zborder_styler¨   ©ÚleftÚrightÚtopÚbottom)rZ   rY   Zend_rowZ
end_columnr¦   r§   )Úmin_rowÚmax_row)r¨   Úcenter)Ú
horizontalÚverticalZshrink_to_fitÚ	wrap_textõ"   DEBUG: No se generarÃ¡ hoja para 'ú' (sin datos)z/DEBUG: Finalizado el for. hay_hoja_con_datos = ú&DEBUG: No hubo datos en todo el rango.z)DEBUG: A punto de guardar el Workbook en úNo existe la carpeta destino: ÚSheetú/DEBUG: Archivo Excel guardado correctamente en z"DEBUG: Error en gen_reporte_data: õ	    (lÃ­nea ú))=r#   r   r‹   rz   Ústrrw   Úintr˜   ÚopenpyxlÚWorkbookr4   ry   r
   rx   rR   r   ÚjoinrC   Úcreate_sheetÚ	enumerater&   r%   rF   rG   rH   ÚosÚpathÚdirnameÚabspathÚ__file__ÚexistsÚFileNotFoundErrorr^   r   r   r   r   ÚfontÚfillZmerge_cellsÚborderÚ	iter_rowsr   Ú	alignmentÚcolumnsra   Úcolumn_dimensionsZcolumn_letterrT   Z
protectionZsheetZobjectsZ	scenariosÚpasswordÚ
sheetnamesÚremoveÚsecurityZworkbookPasswordZlockStructureÚsaveÚclose)>rI   rž   Ú	save_pathÚ	file_nameÚstartÚendÚ	diasEntreÚhay_hoja_con_datosZ	dicc_logsZv_offsetZh_offsetZtablas_distZtablas_spaceZcant_keys_tablaZspace_titlesÚworkbookZws_namesZcolorsZRangosÚkeyra   Zcell_inicial_LetraZcell_final_LetraZ
cell_graphÚregr]   ÚdiaÚfecha_formatrW   Z
estructuraZfilaZsheet_data_srcZ
max_columnÚidxr�   Z
nueva_filar¬   Zts_hh_mm_ssÚcatÚdecrL   Úbase_dirrX   rÛ   rÜ   Z
fill_errorZfill_vdfrÝ   ZLetra1ZLetra2ZLetra3Z
cell_mergeZcell_1Zcell_2Zcell_3Z
cell_rangeÚrowÚcellÚcolumnÚ
max_lengthÚadjusted_widthÚ	dest_pathr*   r*   r+   Úgen_reporte_historial  sD   ú
	
"







* þþþ


ý	
ý	&(&ý
 




rý   c           B      C   s²  ddl }ddl}ddlm} ddlm}m}m}	 ddlm}
m	} ddl
m} ddd	d
dg}dddddg}| d¡d }�zð| j}|
 |d d¡}|
 |d d¡}|| jd }|dk rÄtdƒ W dS td|› d�ƒ | ¡ }d|jkrô| |d ¡ d}d}d}|	ddd�}|||||d �}t|ƒD �]N}|||d!� }| d"¡}t| ||ƒd }td#|› d$t|ƒ› �ƒ |�rbt|ƒdk�rbd%}td&|› d'�ƒ | |¡}d(g| | }t|d ƒD ]} | g ¡ �q¶| |¡ |d) D ]P}!d(g| |! dd(¡|! dd(¡|! d	d(¡|! d
d(¡|! dd(¡g }"| |"¡ �qÚt|d) |ƒ}#|#�rT||#ƒ}$| |$d*¡ t|d) ƒ}%|}&||% }'|d }(|t|ƒ })|j|&|'|(|)d+�D ]&}*|*D ]}+||+_|d,d,d-�|+_�qš�q’t|(|)d ƒD ]v},||,ƒ}-d}.t|&|'d ƒD ]:}/|j |/|,d.�j!}0|0�rætt"|0ƒƒ|.k�rætt"|0ƒƒ}.�qæt#|.d d/ƒ}1|1|j$|- _%�qÈdd0lm&}2 |2d1d1d2d3�}3|2d4d4d2d3�}4|2d5d5d2d3�}5|| 'd¡ d }6|| 'd
¡ d }7|j|d |'|(|)d+�D ]®}8|8|6|(  }9|8|7|(  }:zt(|9j!ƒ};t(|:j!ƒ}<W n" t)t*fk
�r   d};d}<Y nX d}=|;d6k�r&|<d7k�rD|3}=n|;d7k�r6|4}=n|;d8k�rD|5}=|=�r°|8D ]}+|=|+_+�qN�q°ntd9|› d:�ƒ �q$|�rX|j, -|¡�s˜t.d;|› �ƒ‚zX|j, /|j, 0t1¡¡}>|j, 2|>d<d=¡}?|j, -|?¡�sÚt.d>|?› �ƒ‚t3||?d?d@ddAdB� W n2 t4k
�r" }@ ztdC|@› �ƒ W 5 d}@~@X Y nX |j, 2||¡}A| 5|A¡ | 6¡  tdD|A› �ƒ W d%S tdEƒ W dS W nD t4k
�r¬ }@ z$tdF|@› dG|@j7j8› dH�ƒ W Y ¢dS d}@~@X Y nX dS )Iu§  
    Genera un reporte en Excel dentro del rango de fechas (rango_fechas['startDate'], rango_fechas['endDate']).
    Se apoya en la colecciÃ³n 'generadores' dentro de la BD 'db'.

    Retorna:
      - True  => si al menos un dÃ­a tuvo datos y se generÃ³ el archivo exitosamente.
      - False => si no hubo datos en ningÃºn dÃ­a (no se genera archivo).
      - None  => si ocurre un error no controlado (excepciÃ³n).

    ParÃ¡metros visuales:
      - La tabla de cada hoja comienza en la fila 18
      - Deja siempre 2 columnas en blanco (inicio en la columna C)
      - Aplica bordes 'thin' a toda la tabla
      - Ajuste automÃ¡tico de columnas con un ancho mÃ¡ximo de 50
    r   Nr	   )r   r   r   r   r   r>   Ú
plc_statusZ	hf_statusÚpartidaZ	detencionÚ	Timestampz
PLC Statusz	HF StatusÚPartidau
   DetenciÃ³nz-reporter™   r›   rš   r   u/   DEBUG: Rango de fechas invÃ¡lido (end < start).FzDEBUG: Se han seleccionado u    dÃ­a(s)rÉ   é   r£   r¸   r¹   )Ústyler¨   rº   r©   rœ   zDEBUG: Fecha 'z': documentos hallados = Tz"DEBUG: Creando hoja de Excel para z...rr   r@   ZC2)r¿   rÀ   Zmin_colZmax_colrÁ   )rÂ   rÃ   )r÷   rù   r   )r   ZFF296F4Dr´   )r¶   r·   rµ   ZFF7F1D1DZFFD7592Aé<   éd   rˆ   rÅ   rÆ   rÈ   r®   r¯   r°   rN   rO   rQ   r±   r²   rÊ   rÇ   z)DEBUG: Error en gen_reporte_generadores: rË   rÌ   )9rÔ   rÏ   Úopenpyxl.utilsr
   Úopenpyxl.stylesr   r   r   r   r   Úopenpyxl.drawing.imager   rw   Úgeneradoresr‹   rª   r#   rÐ   rã   rä   rR   r�   Ú get_documentos_fecha_generadoresrz   rÒ   rx   r&   Úcreate_boolean_plotrV   rÞ   rÝ   rß   rø   ra   rÍ   Úminrá   rT   r   ÚindexrÎ   r�   Ú	TypeErrorrÜ   rÕ   rÙ   rÚ   rÖ   r×   rØ   rÑ   r^   rF   ræ   rç   rG   rH   )BrI   rž   rè   ré   rÔ   rÏ   r
   r   r   r   r   r   Z
ExcelImageZLLAVESZHEADERSr    Zgeneradores_collectionrê   rë   rì   rî   rí   Z	START_ROWZ
BLANK_COLSZthin_border_sideZthin_borderr]   Úfecha_actualrò   Údocumentos_fecharW   Ú
header_rowÚ_r)   Zdata_rowÚimg_dataZimg_for_excelZtotal_filasZfirst_data_rowZlast_data_rowZfirst_data_colZlast_data_colZ	row_cellsrø   Zcol_idxZ
col_letterrú   Zrow_idxZ
cell_valuerû   r   Z
fill_greenZfill_redZfill_orangeZcol_plc_statusZcol_partida_statusr÷   Zplc_cellZpartida_cellZplc_valZpartida_valrÜ   rö   rX   rL   rü   r*   r*   r+   Úgen_reporte_generadores?  s
   
ü







ûü
ü






 

r  c              
   C   s”   t dƒ zD| j}t ¡  d¡}| ||dœ¡}d}|D ]}|d d }q6|W S  tk
rŽ } z$t d|› d|› d	|jj› �ƒ ‚ W 5 d}~X Y nX dS )
r”   z En GET generator version antiguarœ   r    Nr@   rˆ   z0Error al obtener datos de generador para centro z': r:   )	r#   r	  r   r¡   r�   r%   rF   rG   rH   )rI   r    r�   re   r–   Zgenerador_datar)   rL   r*   r*   r+   Úlegacy_get_generator/  s    r  c              
   C   s’   zV| j }t ¡  d¡}| ||dœdddii¡}|rRd|krR|d rR|d d W S W dS  tk
rŒ } ztd|› �ƒ W Y ¢dS d}~X Y nX dS )	z<
    Optimizado para no iterar cursor innecesariamente.
    rœ   r    r@   z$slicerˆ   r   NzError get_generator: )r	  r   r¡   r�   r0   rF   r#   )rI   r    r�   re   r)   rL   r*   r*   r+   Úget_generatorI  s    
þr  c           	      C   s„   ||dœ}t | j |¡ƒ}g }|D ]\}z$| d¡}t|gƒs>n
| |¡ W q" tk
r| } ztd|jj	|ƒ W 5 d }~X Y q"X q"|S )Nr    r@   u   OcurriÃ³ un error:)
r$   r	  r%   r&   Úallrx   rF   r#   rG   rH   )	rI   r    rd   r‘   Ú
documentosZfiltered_documentsr’   r@   rL   r*   r*   r+   r
  `  s    


r
  c                 C   sÂ  ddl }| d¡ ddlm} ddlm} ddlm} ddlm} g }g }| D ] }	| 	|	d d¡}
|	 
d¡d	krª|	 
d
¡dkr”| d¡ | |
¡ qî| d¡ | |
¡ qN|	 
d¡dkrÚ|g krî| |d ¡ | |
¡ qN| d¡ | |
¡ qN|jddd�\}}| d|› �¡ | d¡ | d¡ |j | d¡¡ |j | ¡ ¡ | ¡  |j||dddd� | ddg¡ | ddg¡ | ¡  | ¡  |ƒ }|j|ddddd� | |¡ | d¡ |S )u=  
    Crea una grÃ¡fica de los valores booleanos 'detencion' y 'partida'
    a lo largo del tiempo (eje X).

    ParÃ¡metros:
    -----------
    documentos_fecha : list
        Lista de documentos (diccionarios) que contienen los campos:
          - timestamp (str)
          - detencion (bool)
          - partida (bool)

    fecha_str : str
        String representando la fecha (por ejemplo, "YYYY-MM-DD") 
        que se usarÃ¡ para el tÃ­tulo de la grÃ¡fica.

    Retorna:
    --------
    image_data : BytesIO
        Objeto BytesIO con la imagen en formato PNG.
    r   NÚAgg)r   )ÚBytesIOr>   z%Y-%m-%d %H:%M:%Srþ   r  rÿ   r  r   rˆ   )é   r¥   )ÚfigsizeÚdpiu   Generador: Arranques dÃ­a ZTiempozEstado Generadorz%H:%Mz#296f4dr  Úpost)r¨   ÚlabelÚwhereÚOFFÚONÚpngZtightgš™™™™™¹?)Úformatr  Zbbox_inchesZ
pad_inches)Ú
matplotlibÚuseÚmatplotlib.pyplotÚpyplotZmatplotlib.datesÚdatesr   Úior  r‹   r&   rx   ÚsubplotsÚ	set_titleÚ
set_xlabelÚ
set_ylabelZxaxisZset_major_formatterZDateFormatterZset_major_locatorZAutoDateLocatorZautofmt_xdater\   Z
set_yticksZset_yticklabelsÚlegendZtight_layoutZsavefigrç   Úseek)r  Ú	fecha_strr%  ÚpltZmdatesr   r  ÚtimesZpartida_valsr)   ÚtÚfigÚaxZ
image_datar*   r*   r+   r  �  sN    





 

r  c                 C   sv  �z>|�r*t d|›�ƒ t ¡  d¡}||dœ}| j |ddi¡}|�r
|d d }dd	„ | ¡ D ƒ}||krút d
|d
 idd|ii¡}z*| j 	|g¡}	t d|	j
› d|	j› �ƒ W nB tk
rö }
 z$t d|› d|
jj› d|
› d�ƒ W 5 d }
~
X Y nX nt |› d�ƒ n| j |||gdœ¡ t dƒ nt d|› �ƒ W d S W n0 tk
�rp }
 zt |
jjƒ W 5 d }
~
X Y nX d S )Nzsave_one_generator_data data=rœ   r    zgenerador.timestampFr@   rˆ   c                 S   s   i | ]\}}|d kr||“qS r=   r*   )Ú.0ÚkÚvr*   r*   r+   Ú
<dictcomp>ñ  s       z+save_one_generator_data.<locals>.<dictcomp>r.   rg   z*Upsert realizado. Documentos modificados: z, documentos insertados: z.Error al guardar datos de generador en centro r:   z: 
z5: Datos de generador sin cambios, no se actualiza BD.)r    re   r@   zNuevo documento insertado.zNo hay datos de generadores: )r#   r   r¡   r�   r	  r0   ry   r{   r|   r}   Úmodified_countÚupserted_countrF   rG   rH   Ú
insert_one)rI   r    r3   re   rn   Úexisting_docZalredy_dataÚnew_dataÚupdate_operationrp   rL   r*   r*   r+   rE   Ý  s8    þ

þ4

rE   )F)rN   rO   rP   rQ   )N)?Z	save_datar   Z
comap_datar   r   r   r{   Úcopyr‰   rÔ   Útypingr   rÏ   r  r
   r  r   r   r   r   r   r   Zopenpyxl.chartr   r   r  r   rS   Zopenpyxl.drawing.textr   r   Zopenpyxl.workbook.protectionr   r_   r   Úpathlibr   râ   ZKEYS_INTERESZKEYS_INTERES_AUXÚ#HISTORIAL_CONTROL_ARRAY_LEN_TO_SENDr,   r2   r8   rM   r^   rc   rq   r…   rÍ   rk   rD   r“   r˜   rŸ   r¢   rý   r  r  r  r
  r  rE   r*   r*   r*   r+   Ú<module>   s\    
!
M
,(6$


2  > q!\