U
    Ý:jÛŠ  ã                   @  s0  d Z ddlmZ ddl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
m
Z
mZ ddlmZmZmZmZmZ ddlmZ dd	d
œdd„Zddddœdd„Zddœdd„Zdd	d	ddœdd„Zdd	d	ddœdd„Zdddœdd „Zddœd!d"„Zddœd#d$„Zddœd%d&„Zddd'œd(d)„Zdd*d+œd,d-„Zdd.d/œd0d1„Zd2dd3œd4d5„Z dddd.d6œd7d8„Z!dddd2d9d9dd:œd;d<„Z"dddd.d6œd=d>„Z#dd?œdddd@d.dAœdBdC„Z$d.ddDœdEdF„Z%ddddGdHœdIdJ„Z&ddd	d	d9ddKœdLdM„Z'ddddGdHœdNdO„Z(dddd.d6œdPdQ„Z)dRdœdSdT„Z*dRdœdUdV„Z+dS )WuX   Fechamento de perÃ­odo: arquiva linhas de pedido_diarios em pedido_periodos (MySQL 5.x).é    )ÚannotationsN)Údefaultdict)ÚdatetimeÚ	timedelta)ÚAnyÚDictÚListÚOptionalÚTuple)ÚconectarzOptional[str]r   )ÚsÚreturnc                 C  s4   | rt | ƒ ¡ stdƒ‚t t | ƒ ¡ d d… d¡S )Nu   Data obrigatÃ³riaé
   ú%Y-%m-%d)ÚstrÚstripÚ
ValueErrorr   Ústrptime)r   © r   ú7/var/www/html/LojaOnline/services/fechamento_periodo.pyÚ
_parse_dia   s    r   r   zTuple[datetime, datetime])Údata_inicioÚdata_fimr   c                 C  s2   t | ƒ}t |ƒtdd }||kr*tdƒ‚||fS )u;   Retorna [inÃ­cio inclusivo, fim exclusivo) em data_criacao.é   )Údaysz1data_inicio deve ser anterior ou igual a data_fim)r   r   r   )r   r   Úd0Úd1r   r   r   Úintervalo_datetimes   s
    r   z	List[str])r   c                 C  sb   |   d¡ |  ¡ }g }|D ]B}t|tƒs0|d n| d¡}|rt|ƒ ¡ dkr| t|ƒ¡ q|S )Nz SHOW COLUMNS FROM pedido_diariosr   ÚFieldÚchave)ÚexecuteÚfetchallÚ
isinstanceÚdictÚgetr   ÚlowerÚappend)ÚcursorÚrowsÚoutÚrÚnamer   r   r   Ú!_colunas_pedido_diarios_sem_chave   s    
r,   ÚintzTuple[str, Tuple[Any, ...]])Ú
id_clienter   r   r   c                 C  s   d}t | ƒ||f}| ¡ |fS )u¸   
    Linhas elegÃ­veis ao fechamento: ITEM_REMOVIDO (qualquer origem) ou recebidas.
    Recebido: origem MESA usa status_mesa=RECEBIDO; demais origens usam status_pedido=RECEBIDO.
    aí  
        id_cliente = %s
        AND data_criacao >= %s
        AND data_criacao < %s
        AND (
            UPPER(TRIM(COALESCE(status_pedido, ''))) = 'ITEM_REMOVIDO'
            OR (
                (UPPER(TRIM(COALESCE(origem, ''))) = 'MESA'
                 AND UPPER(TRIM(COALESCE(status_mesa, ''))) = 'RECEBIDO')
                OR (UPPER(TRIM(COALESCE(origem, ''))) <> 'MESA'
                    AND UPPER(TRIM(COALESCE(status_pedido, ''))) = 'RECEBIDO')
            )
        )
    ©r-   r   ©r.   r   r   ÚsqlÚparamsr   r   r   Ú_where_fechamento*   s    r3   c                 C  s   d}t | ƒ||f}| ¡ |fS )u7   Intervalo de data_criacao no diÃ¡rio (qualquer status).zZ
        id_cliente = %s
        AND data_criacao >= %s
        AND data_criacao < %s
    r/   r0   r   r   r   Ú_where_periodo_diarioA   s    r4   zException | str)Úexcr   c                 C  sB   t | pdƒ ¡ }|sdS t| tƒs:d| ¡ ks:d| ¡ kr>dS dS )NÚ zSPasta de relatorios indisponivel. Verifique as permissoes do diretorio configurado.zaccess is deniedzacesso negadoz^Pasta de relatorios sem permissao de acesso. Verifique as permissoes do diretorio configurado.zWNao foi possivel preparar a pasta de relatorios. Verifique a configuracao do diretorio.)r   r   r"   ÚPermissionErrorr%   )r5   Útextor   r   r   Ú_mensagem_erro_relatoriosL   s    "r9   c                   C  s   dS )už   
    Linha considerada recebida para faturamento / relatÃ³rios:
    origem MESA â†’ status_mesa = RECEBIDO; caso contrÃ¡rio â†’ status_pedido = RECEBIDO.
    zÝ(  (UPPER(TRIM(COALESCE(origem, ''))) = 'MESA'    AND UPPER(TRIM(COALESCE(status_mesa, ''))) = 'RECEBIDO')  OR (UPPER(TRIM(COALESCE(origem, ''))) <> 'MESA'       AND UPPER(TRIM(COALESCE(status_pedido, ''))) = 'RECEBIDO'))r   r   r   r   r   Ú_sql_recebido_para_faturamentoU   s    ÿr:   c                   C  s   dS )Nz8UPPER(TRIM(COALESCE(status_comanda, ''))) <> 'CANCELADA'r   r   r   r   r   Ú_sql_excluir_comanda_canceladad   s    r;   c                   C  s   dt ƒ › dtƒ › dS )Nú(z) AND (ú))r:   r;   r   r   r   r   Ú_sql_faturamento_linhah   s    r>   )Úlabelr   c                 C  sþ   t  ddt| pdƒ ¡  ¡ ¡}|s&dS d|kr2dS d|ksJd|ksJ|d	krNd
S d|ksfd|ksfd|krjdS d|ks‚d|ks‚d|kr†dS d|ksžd|ksžd|kr¢dS d|ksÊd|ksÊd|ksÊd|ksÊd|krÎdS d|krÚdS d|ksêd |krîd!S d"|krúd#S dS )$u¦   
    Agrupa rÃ³tulos livres da baixa em categorias para prestaÃ§Ã£o de contas.
    Ordem de teste importa (ex.: 'cartÃ£o crÃ©dito' antes de genÃ©rico 'cartÃ£o').
    z\s+Ú r6   ÚOutrosZpixÚPIXZdinheirZespeci)ZdinZcashÚDinheirou   crÃ©dZcredZcreditou   CartÃ£o crÃ©ditou   dÃ©bZdebZdebitou   CartÃ£o dÃ©bitoZvaleZrefeiZalimenu   Vale/refeiÃ§Ã£oZtransfZtedÚdocu   depÃ³sZdepositou   TransferÃªnciaZboletoZBoletoZcartZcardu   CartÃ£o (nÃ£o especificado)ZmistozMisto (detalhe em baixa))ÚreÚsubr   r   r%   )r?   r   r   r   r   Ú_normalizar_forma_pagamentol   s,    (rG   zOptional[List[dict]])Úrawr   c              
   C  s  t | pdƒ ¡ } | r | d dkr$d S zt | ¡}W n tjttfk
rP   Y d S X t|tƒs`d S | 	d¡}t|t
ƒsxd S g }|D ]v}t|tƒsq€t | 	d¡pždƒ ¡ }zt| 	d¡p¶dƒ}W n ttfk
rØ   d}Y nX |dkr€|r€| ||dœ¡ q€|p d S )	Nr6   r   z{[Ú
pagamentosÚformaÚvalorç        )rJ   rK   )r   r   ÚjsonÚloadsÚJSONDecodeErrorÚ	TypeErrorr   r"   r#   r$   ÚlistÚfloatr&   )rH   ÚobjZpagr)   ÚprJ   rK   r   r   r   Ú_parse_baixa_pagamentos_json‰   s0    




rU   r#   )r.   r   c              
   C  s„   t j dd¡}z:t j|dd t jt j |tt| ƒƒ¡dd d|dœW S  tk
r~ } zdt	|ƒ|dœ W Y ¢S d}~X Y nX dS )	z/Cria C:\Geral\Relatorios e subpasta do cliente.ÚLOJA_RELATORIOS_DIRúC:\Geral\RelatoriosT©Úexist_ok)ÚsucessoÚbaseF)rZ   Úerror[   N)
ÚosÚenvironr$   ÚmakedirsÚpathÚjoinr   r-   ÚOSErrorr9   )r.   r[   Úer   r   r   Úgarantir_diretorio_relatorios¤   s     rd   rR   )Úvr   c              	   C  s>   zt | ƒ}W n ttfk
r(   d}Y nX d|d› dd¡ S )NrL   zR$ z.2fÚ.Ú,)rR   rP   r   Úreplace)re   Únr   r   r   Ú	_money_br¯   s
    
rj   )r.   r   r   r   c                 C  s0  t ||ƒ\}}t| ƒ d}d}zîtƒ }|jdd}t| ||ƒ\}}| d|› d|¡ t| ¡ pbi  	d¡pldƒ}	| d|› d	|¡ d
d„ | 
¡ p”g D ƒ}
| d|› d|¡ dd„ | 
¡ p¾g D ƒ}t| |dd… |dd… |	|
|ƒ}d|dd… |dd… |	|
||dœW ¢S |r| ¡  |r*| ¡  X dS )ug   Agregados financeiros no perÃ­odo: recebido (MESA: status_mesa; outras: status_pedido) e ITEM_REMOVIDO.NT©Ú
dictionaryz’
            SELECT COALESCE(SUM(CAST(preco AS DECIMAL(14,4)) * CAST(quantidade AS DECIMAL(14,4))), 0) AS t
            FROM pedido_diarios WHERE ú
            Útr   a&  
            SELECT
                CASE
                    WHEN UPPER(TRIM(COALESCE(status_pedido, ''))) = 'ITEM_REMOVIDO' THEN 'ITEM_REMOVIDO'
                    WHEN UPPER(TRIM(COALESCE(origem, ''))) = 'MESA'
                         AND UPPER(TRIM(COALESCE(status_mesa, ''))) = 'RECEBIDO' THEN 'RECEBIDO'
                    ELSE UPPER(TRIM(COALESCE(status_pedido, '')))
                END AS st,
                COALESCE(SUM(CAST(preco AS DECIMAL(14,4)) * CAST(quantidade AS DECIMAL(14,4))), 0) AS total
            FROM pedido_diarios WHERE á›  
            GROUP BY
                CASE
                    WHEN UPPER(TRIM(COALESCE(status_pedido, ''))) = 'ITEM_REMOVIDO' THEN 'ITEM_REMOVIDO'
                    WHEN UPPER(TRIM(COALESCE(origem, ''))) = 'MESA'
                         AND UPPER(TRIM(COALESCE(status_mesa, ''))) = 'RECEBIDO' THEN 'RECEBIDO'
                    ELSE UPPER(TRIM(COALESCE(status_pedido, '')))
                END
            c                 S  s.   g | ]&}|  d ¡pdt|  d¡p"dƒdœ‘qS )Ústr6   Útotalr   )Ústatusrq   ©r$   rR   ©Ú.0Úrowr   r   r   Ú
<listcomp>Þ   s   ÿz0resumo_financeiro_fechamento.<locals>.<listcomp>zê
            SELECT TRIM(COALESCE(NULLIF(formapagamento, ''), '(sem forma)')) AS fp,
                   COALESCE(SUM(CAST(preco AS DECIMAL(14,4)) * CAST(quantidade AS DECIMAL(14,4))), 0) AS total
            FROM pedido_diarios WHERE z|
            GROUP BY TRIM(COALESCE(NULLIF(formapagamento, ''), '(sem forma)'))
            ORDER BY total DESC
            c                 S  s.   g | ]&}|  d ¡pdt|  d¡p"dƒdœ‘qS )Úfpr6   rq   r   )rJ   rq   rs   rt   r   r   r   rw   ì   s   ÿr   )rZ   r   r   Útotal_geralÚ
por_statusZpor_forma_pagamentoÚtexto_impressao)r   rd   Úcloser   r'   r3   r    rR   Úfetchoner$   r!   Ú _formatar_resumo_texto_impressao)r.   r   r   r   r   ÚconnÚcurÚwrT   ry   Zpor_status_valÚ	por_formar8   r   r   r   Úresumo_financeiro_fechamento·   sj    þû	÷í
þýø

þ 
 
   ÿ

ù

rƒ   z
List[dict])r.   ÚdiÚdfry   rz   r‚   r   c                 C  sâ   dd| › d|› d|› ddt |ƒ› ddg}|D ]6}| d	| d
¡pHd› dt t| d¡p\dƒƒ› ¡ q2| d¡ | d¡ |D ]6}| d	| d¡p˜d› dt t| d¡p¬dƒƒ› ¡ q‚| d¡ | d¡ | d¡ d |¡S )Nz)========== FECHAMENTO DE CAIXA ==========úid_cliente: ú	Periodo: ú a ú (fim do dia incluso)zTOTAL GERAL: r6   z--- Por status ---ú  rr   Ú-z : rq   r   z5--- Por forma de pagamento (campo formapagamento) ---rJ   zu(Linhas elegiveis: ITEM_REMOVIDO; recebido: MESA com status_mesa=RECEBIDO, demais origens com status_pedido=RECEBIDO)z*==========================================Ú
)rj   r&   r$   rR   ra   )r.   r„   r…   ry   rz   r‚   ÚlinesÚxr   r   r   r~     s&    	ú4

4
ÿ
r~   c                 C  sF  t ||ƒ\}}t| ƒ}d }d }ztƒ }|jdd}t| ||ƒ\}}	| d|› |	¡ t| ¡ pbi  	d¡pldƒ}
| d|› d|	¡ dd	„ | 
¡ p”g D ƒ}| d
|› d|	¡ t| ¡ pºi  	d¡pÄdƒ}d|d d… |d d… |
||dœ}| 	d¡r| 	d¡|d< n| 	d¡|d< d|d< |W ¢S |r2| ¡  |r@| ¡  X d S )NTrk   z/SELECT COUNT(*) AS n FROM pedido_diarios WHERE ri   r   aØ  
            SELECT
                CASE
                    WHEN UPPER(TRIM(COALESCE(status_pedido, ''))) = 'ITEM_REMOVIDO' THEN 'ITEM_REMOVIDO'
                    WHEN UPPER(TRIM(COALESCE(origem, ''))) = 'MESA'
                         AND UPPER(TRIM(COALESCE(status_mesa, ''))) = 'RECEBIDO' THEN 'RECEBIDO'
                    ELSE UPPER(TRIM(COALESCE(status_pedido, '')))
                END AS st,
                COUNT(*) AS c
            FROM pedido_diarios WHERE ro   c                 S  s"   g | ]}|d  t |d ƒdœ‘qS )rp   Úc)rr   Úlinhas©r-   rt   r   r   r   rw   A  s     z&preview_fechamento.<locals>.<listcomp>z
            SELECT COUNT(DISTINCT CONCAT(COALESCE(origem,''), ':', CAST(nropedido AS CHAR(20)))) AS n
            FROM pedido_diarios WHERE rm   r   )rZ   r   r   r   Zpedidos_origem_numero_distintosrz   rZ   r[   Zpasta_relatoriosr\   Zpasta_relatorios_erroZpasta_relatorios_indisponivel)r   rd   r|   r   r'   r3   r    r-   r}   r$   r!   )r.   r   r   r   r   Z
pasta_infor   r€   r   rT   Ún_linhasrz   Zn_gruposr)   r   r   r   Úpreview_fechamento!  sP    	÷íþû

úr“   ©r'   zOptional[Any])r.   r   r   r'   r   c          1      C  s~  t ||ƒ\}}|dkrt| ƒ t| ||ƒ\}}|dd… }|dd… }	d}
|}|dk}zü|rxtƒ }
|
jdd}t| ƒ |dkrdddœW ¢ÈS tƒ }tƒ }| d|› d	|› d
|¡ g }d}d}| 	¡ pÌg D ]~}t
| d¡pàdƒ ¡ pêd}t| d¡púdƒ}t| d¡pdƒ}||7 }||7 }|dkr4|| nd}| ||||dœ¡ qÎ| d|› d|¡ | ¡ pni }t| d¡p€dƒ}t| d¡p”dƒ}| d|› d|¡ t| ¡ pºi  d¡pÆdƒ}| d|› d|› d|¡ t| ¡ pòi  d¡pþdƒ}| d|› d|¡ t| ¡ p$i  d¡p0dƒ}| d|› d|› d|¡ t| ¡ p\i  d¡phdƒ}| d|› d|¡ t| ¡ pŽi  d¡pšdƒ}| d|› d	|› d|¡ dd „ | 	¡ pÊg D ƒ}| d!|› d	|› d"|¡ d#d „ | 	¡ püg D ƒ} | d$|› d	|› d%|¡ t| 	¡ p*g ƒ}!ttƒ}"|!D ]ò}#t
|# d&¡pNd'ƒ ¡ }$t|$ƒ}%t|# d(¡pndƒ}&|%ræ|%D ]f}'t|' d)¡ƒ}(zt|' d*¡p dƒ})W n ttfk
rÄ   d})Y nX |)dkr||"|(  |)7  < q|nDt
|# d+¡pöd'ƒ ¡ }*t|*r
|*nd,ƒ}(|&dkr:|"|(  |&7  < q:td-d „ |" ¡ D ƒd.d/„ d0}+d},| d1¡ | ¡ r˜| d2t| ƒ||f¡ t| ¡ pˆi  d¡p”dƒ},g }-|dkrÜ|D ]0}.|- |.d3 td4t|.d5 ƒ | d6ƒd7œ¡ qª|| dkr td4| ||  d6ƒnd}/d||	t| ƒt|d6ƒ|||-|t|d6ƒ|/||||||+|| |,d8œ}0t|0ƒ|0d9< |0W ¢S |rj|rj| ¡  |
rx|
 ¡  X dS ):uW  
    RelatÃ³rio gerencial para prestaÃ§Ã£o de contas no mesmo intervalo do fechamento (pedido_diarios).
    Pagamentos: prioriza JSON em baixa_pagamento por pedido (origem+nropedido); senÃ£o formapagamento + total do pedido.
    Se `cursor` for passado (dict cursor), usa a mesma conexÃ£o/transaÃ§Ã£o (ex.: antes do DELETE no fechamento).
    Nr   Trk   Fu/   Cursor indisponÃ­vel para relatÃ³rio gerencial.©rZ   r\   a[  
            SELECT UPPER(TRIM(COALESCE(origem, ''))) AS og,
                   COALESCE(SUM(CAST(preco AS DECIMAL(14, 4)) * CAST(quantidade AS DECIMAL(14, 4))), 0) AS total,
                   COUNT(DISTINCT CONCAT(UPPER(TRIM(COALESCE(origem, ''))), ':', CAST(nropedido AS CHAR(20)))) AS pedidos
            FROM pedido_diarios
            WHERE z
              AND zD
            GROUP BY UPPER(TRIM(COALESCE(origem, '')))
            rL   r   Úogu   â€”rq   Úpedidos)ÚorigemÚfaturamentor—   Úticket_mediozÍ
            SELECT COUNT(*) AS n_linhas,
                   COALESCE(SUM(CAST(preco AS DECIMAL(14, 4)) * CAST(quantidade AS DECIMAL(14, 4))), 0) AS total
            FROM pedido_diarios
            WHERE zZ
              AND UPPER(TRIM(COALESCE(status_pedido, ''))) = 'ITEM_REMOVIDO'
            r’   z§
            SELECT COUNT(DISTINCT CONCAT(UPPER(TRIM(COALESCE(origem, ''))), ':', CAST(nropedido AS CHAR(20)))) AS n
            FROM pedido_diarios
            WHERE zX
              AND UPPER(TRIM(COALESCE(status_comanda, ''))) = 'MODIFICADA'
            ri   zc
              AND UPPER(TRIM(COALESCE(status_comanda, ''))) = 'MODIFICADA'
              AND NOT (z)
            zW
              AND UPPER(TRIM(COALESCE(status_comanda, ''))) = 'CANCELADA'
            zb
              AND UPPER(TRIM(COALESCE(status_comanda, ''))) = 'CANCELADA'
              AND NOT (zT
              AND UPPER(TRIM(COALESCE(status_pedido, ''))) = 'AGUARDE'
            až  
            SELECT COALESCE(NULLIF(TRIM(codigoproduto), ''), NULLIF(TRIM(produto), ''), '(sem ref)') AS ref,
                   MAX(TRIM(COALESCE(produto, ''))) AS nome,
                   COALESCE(SUM(CAST(quantidade AS DECIMAL(14, 4))), 0) AS qtd,
                   COALESCE(SUM(CAST(preco AS DECIMAL(14, 4)) * CAST(quantidade AS DECIMAL(14, 4))), 0) AS total
            FROM pedido_diarios
            WHERE z©
            GROUP BY COALESCE(NULLIF(TRIM(codigoproduto), ''), NULLIF(TRIM(produto), ''), '(sem ref)')
            ORDER BY total DESC
            LIMIT 20
            c              	   S  sn   g | ]f}|  d ¡p|  d¡pddd… |  d¡p<|  d ¡p<ddd… t|  d¡pRdƒt|  d¡pbdƒd	œ‘qS )
ÚrefÚnomer6   Néx   éÈ   Úqtdr   rq   )r›   ÚprodutoÚ
quantidaderq   rs   ©ru   r*   r   r   r   rw   í  s   ûüz/relatorio_gerencial_periodo.<locals>.<listcomp>zù
            SELECT HOUR(data_criacao) AS hr,
                   COUNT(*) AS n_itens,
                   COALESCE(SUM(CAST(preco AS DECIMAL(14, 4)) * CAST(quantidade AS DECIMAL(14, 4))), 0) AS total
            FROM pedido_diarios
            WHERE zM
            GROUP BY HOUR(data_criacao)
            ORDER BY hr
            c                 S  sB   g | ]:}t | d ¡pdƒt | d¡p&dƒt| d¡p6dƒdœ‘qS )Úhrr   Zn_itensrq   )ÚhoraÚitensrq   )r-   r$   rR   r¢   r   r   r   rw     s   ÿac  
            SELECT origem, nropedido,
                   MAX(COALESCE(baixa_pagamento, '')) AS baixa_pagamento,
                   MAX(COALESCE(formapagamento, '')) AS formapagamento,
                   COALESCE(SUM(CAST(preco AS DECIMAL(14, 4)) * CAST(quantidade AS DECIMAL(14, 4))), 0) AS total_pedido
            FROM pedido_diarios
            WHERE z4
            GROUP BY origem, nropedido
            Úbaixa_pagamentor6   Útotal_pedidorJ   rK   ÚformapagamentorA   c                 S  s$   g | ]\}}|t t|ƒd ƒdœ‘qS )é   )Ú	categoriarq   )ÚroundrR   )ru   Úkre   r   r   r   rw   ,  s     c                 S  s
   | d  S )Nrq   r   )rŽ   r   r   r   Ú<lambda>-  ó    z-relatorio_gerencial_periodo.<locals>.<lambda>)Úkeyz.SHOW COLUMNS FROM clientes LIKE 'data_criacao'zË
                SELECT COUNT(*) AS n
                FROM clientes
                WHERE id_cliente = %s
                  AND data_criacao >= %s
                  AND data_criacao < %s
                r˜   g      Y@r™   r©   )r˜   Úpercentual_faturamento)rZ   r   r   r.   Úfaturamento_recebido_totalÚpedidos_recebidos_distintosÚ	por_canalÚmix_percentual_canalÚitem_removido_linhasÚitem_removido_valorÚtaxa_remocao_valor_pctÚcomandas_modificadas_pedidosÚ)comandas_modificadas_nao_recebido_pedidosÚcomandas_canceladas_pedidosÚ(comandas_canceladas_nao_recebido_pedidosÚ!pedidos_aguarde_distintos_periodoÚpagamentos_por_categoriaÚtop_produtosÚpor_hora_recebidoÚnovos_clientes_cadastror{   )r   rd   r4   r|   r   r'   r>   r:   r    r!   r   r$   r   rR   r-   r&   r}   rQ   r   rU   rG   rP   r   ÚsortedÚitemsr«   Ú#_formatar_relatorio_gerencial_texto)1r.   r   r   r'   r   r   ZwpÚppr„   r…   r   r€   Z
own_cursorÚsrZsr_recebidor³   Ztot_recebidoZtot_pedidos_recebidorv   r–   rq   ÚpedZticketZrow_rmZ
rem_linhasZ	rem_valorZ	mod_totalZ
mod_abertoZcanceladas_totalZcanceladas_abertoZpedidos_aguarder¾   Zpor_horaZpedidos_rowsZpag_normÚprÚbpÚparsedZ	total_pedrT   Úbucketre   rx   Zpor_forma_normalizadaZnovos_clientesZmixr   Ztaxa_remocao_valorÚpayloadr   r   r   Úrelatorio_gerencial_periodo_  sl   ûú	öüø
ýù	ýûø
ýù	ýûø
ýù	úùóù
ûú
õþúù
õ


þ

ø

þÿ(ìrÌ   )Údr   c           	      C  sê  dd|   d¡› d|   d¡› d|   d¡› dd	d
ddtt|   d¡pDdƒƒ› d|   d¡› d
dg
}|   d¡png D ]V}| d|  d¡› dtt|  d¡p–dƒƒ› d|  d¡› dtt|  d¡pºdƒƒ› ¡ qp| d
¡ | d¡ |   d¡pèg D ](}| d|  d¡› d|  d¡› d¡ qê| d
¡ | d¡ | d ¡ |   d!¡p@g D ]6}| d|  d"¡› dtt|  d#¡pjdƒƒ› ¡ qB| d
¡ | d$¡ | d%|   d&¡› ¡ | d'tt|   d(¡p¼dƒƒ› ¡ | d)|   d*¡› d¡ | d
¡ | d+¡ | d,|   d-¡› ¡ | d.|   d/¡› ¡ | d
¡ | d0¡ | d1|   d2¡› ¡ | d.|   d3¡› ¡ | d
¡ | d4¡ | d5|   d6¡› ¡ | d
¡ |   d7¡}| d8¡ | d9|d k	r¼|nd:› ¡ | d
¡ | d;¡ t|   d<¡pêg d=ƒD ]f\}}| d|› d>|  d?¡p|  d@¡pdAd dB… › dC|  dD¡› dEtt|  d#¡pHdƒƒ› ¡ qð| d
¡ | dF¡ |   dG¡pzg D ]N}| dt|  dH¡p–dƒdI›dJ|  dK¡› dEtt|  d#¡p¼dƒƒ› ¡ q|| d
¡ | dL¡ dM |¡S )NNz?========== RELATORIO GERENCIAL (PRESTACAO DE CONTAS) ==========r†   r.   r‡   r   rˆ   r   r‰   u[   (Recebido: origem MESA â†’ status_mesa=RECEBIDO; demais origens â†’ status_pedido=RECEBIDO)r6   z--- Faturamento RECEBIDO ---zTotal geral: r±   r   zPedidos distintos (recebido): r²   z--- Por canal (origem) ---r³   rŠ   r˜   z: r™   z | pedidos=r—   z | ticket medio=rš   z(--- Mix % sobre faturamento recebido ---r´   r°   ú%z;--- Pagamentos (baixa_pagamento JSON ou formapagamento) ---zN(Categorias normalizadas: Dinheiro, PIX, cartoes, Vale, Transferencia, Outros)r½   rª   rq   z'--- Cancelamentos / itens removidos ---z  Linhas ITEM_REMOVIDO: rµ   z  Valor (itens removidos): r¶   z0  Taxa remocao sobre (recebido+removido) valor: r·   z---- Comandas modificadas (status_comanda) ---z$  Pedidos distintos com MODIFICADA: r¸   z  Destes, ainda nao RECEBIDO: r¹   z,--- Comandas canceladas (status_comanda) ---z#  Pedidos distintos com CANCELADA: rº   r»   z7--- Pedidos em AGUARDE no periodo (ainda no diario) ---z  Pedidos distintos: r¼   rÀ   z!--- Novos clientes (cadastro) ---z  Quantidade: z"(coluna data_criacao indisponivel)z*--- Top produtos (RECEBIDO, por valor) ---r¾   r   z. r    r›   r‹   é<   z | qtd=r¡   z | z1--- Movimento por hora (RECEBIDO, soma itens) ---r¿   r¤   Ú02dz	h: itens=r¥   z@================================================================rŒ   )r$   rj   rR   r&   Ú	enumerater-   ra   )	rÍ   r   r   ÚmrT   ZncÚirn   Úhr   r   r   rÃ   j  sv    öJÿ

&


4

$










Tÿ

@ÿ

rÃ   zTuple[str, str])r.   ÚloteÚconteudor   c           
   	   C  sœ   t j dd¡}t d¡}t j |tt| ƒƒ|¡}t j	|dd t d¡}d|d d… › d	|› d
}t j ||¡}t
|ddd}	|	 |¡ W 5 Q R X ||fS )NrV   rW   r   TrX   ú%H%M%SÚfechamento_é   Ú_z_gerencial.txtr   úutf-8©Úencoding©r]   r^   r$   ÚtimeÚstrftimer`   ra   r   r-   r_   ÚopenÚwrite©
r.   rÕ   rÖ   r[   ZdiaÚpastaÚsufixorœ   ÚcaminhoÚfr   r   r   Ú_gravar_relatorio_gerencial_txt«  s    

rè   )r.   rÕ   r   r   r   r   c                 C  sÒ   |pg }d| › d|› d|  d¡› d|  d¡› dt|ƒ› d}d}d	 |¡d
 }|D ]v}g }	|D ]V}
|
dkrŽ|	 t| d¡p†| d¡p†dƒ¡ q^|	 t| |
¡d k	r¬| |
¡ndƒ¡ q^|d	 |	¡d
 7 }qR|| S )Nu,   FECHAMENTO DE PERÃODO (arquivo)
id_cliente=z
lote=z
periodo_inicio=z%Y-%m-%d %H:%M:%Sz
periodo_fim_exclusivo=z
linhas_arquivadas=z
---
)
Ú
chave_origr˜   Ú	nropedidoÚstatus_pedidoÚdata_criacaor    r¡   Úprecor¨   Úclienteú	rŒ   ré   Zchave_orig_pedido_diariosr   r6   )rà   Úlenra   r&   r   r$   )r.   rÕ   r   r   r   ÚheaderZ	cols_prefÚbodyr*   rv   r   r   r   r   Ú_montar_relatorio_texto¸  s    2ÿ	$(ró   c           
   	   C  sœ   t j dd¡}t d¡}t j |tt| ƒƒ|¡}t j	|dd t d¡}d|d d… › d	|› d
}t j ||¡}t
|ddd}	|	 |¡ W 5 Q R X ||fS )NrV   rW   r   TrX   r×   rØ   rÙ   rÚ   z.txtr   rÛ   rÜ   rÞ   rã   r   r   r   Ú_gravar_relatorio_txtá  s    

rô   c                 C  s”  t ||ƒ\}}t ¡ j}t ¡ }d}d}zFzÂtƒ }| ¡ }z| 	¡  W n t
k
r^   Y nX | dt| ||ƒd  d t| ||ƒd ¡ dd„ | ¡ D ƒ}	|	s¼| ¡  dd	d
œW W ¢¸S t|ƒ}
|
sâ| ¡  ddd
œW W ¢’S d |
¡}d|› d|› dd dgt|	ƒ ¡› d}||f|	˜}| ||¡ dddœ}|jdd}zRztt| ƒ|||d}W n4 t
k
r } zdt|ƒddœ}W 5 d}~X Y nX W 5 | ¡  X dd dgt|	ƒ ¡› d}| |t|	ƒ¡ | ¡  |jdd}| dt| ƒ|f¡ t| ¡ pg ƒ}| ¡  t| ||||ƒ}t| ||ƒ\}}d|t|	ƒ||dœ}| d¡rÈt| d¡p^dƒ ¡ rÈz,t| |t|d ƒƒ\}}||d< ||d< W n0 tk
rÄ } zt|ƒ|d < W 5 d}~X Y nX n | d¡sè| d!¡pâd"|d#< |W W ¢‚S  t
k
rl } z\|r.z| ¡  W n t
k
r,   Y nX t|tƒrBt|ƒnt|ƒ}d|d
œ W Y ¢W ¢S d}~X Y nX W 5 |r€| ¡  |rŽ| ¡  X dS )$u¦   
    TransaÃ§Ã£o: copia linhas elegÃ­veis para pedido_periodos e remove de pedido_diarios.
    Em seguida grava .txt com o lote (dados lidos de pedido_periodos).
    Nz'SELECT chave FROM pedido_diarios WHERE r   z FOR UPDATEr   c                 S  s(   g | ] }|r|d  dk	rt |d  ƒ‘qS )r   Nr‘   r¢   r   r   r   rw     s       z'executar_fechamento.<locals>.<listcomp>FuO   Nenhuma linha elegÃ­vel no perÃ­odo (recebido conforme origem / ITEM_REMOVIDO).r•   u1   NÃ£o foi possÃ­vel ler colunas de pedido_diarios.z, zINSERT INTO pedido_periodos (z8, arquivado_em, lote, chave_orig_pedido_diarios) SELECT z4, %s, %s, chave FROM pedido_diarios WHERE chave IN (rg   z%sr=   r6   )rZ   r{   Trk   r”   )rZ   r\   r{   z+DELETE FROM pedido_diarios WHERE chave IN (a%  
            SELECT chave, chave_orig_pedido_diarios, origem, nropedido, status_pedido, data_criacao,
                   produto, quantidade, preco, formapagamento, cliente
            FROM pedido_periodos
            WHERE id_cliente = %s AND lote = %s
            ORDER BY chave
            )rZ   rÕ   Zlinhas_arquivadasÚarquivoræ   rZ   r{   Zarquivo_gerencialZcaminho_gerencialZarquivo_gerencial_error\   u%   Falha ao montar relatÃ³rio gerencial.Zrelatorio_gerencial_erro) r   ÚuuidÚuuid4Úhexr   Únowr|   r   r'   Ústart_transactionÚ	Exceptionr    r3   r!   Úrollbackr,   ra   rð   rÌ   r-   r   ÚtupleÚcommitrQ   ró   rô   r$   r   rè   rb   r9   r"   )r.   r   r   r   r   rÕ   Z	arquivador   r€   ZchavesÚcolsÚcol_listZsql_insZ
params_insZ	gerencialZcur_dictZe_gerZsql_delZcur2Zrel_rowsr8   ræ   rœ   r)   Zc_gerZn_gerZoerc   r\   r   r   r   Úexecutar_fechamentoî  s’    
,
&ÿ
&

ø
û& 
(r  ÚNonec                  C  s  d} d}zÚz~tƒ } |  ¡ }| d¡ | d¡ | ¡ dkrD| d¡ | d¡ | ¡ dkr~z| d¡ W n tk
r|   Y nX |  ¡  W nV tk
rÞ } z8z| r¨|  ¡  W n tk
r¾   Y nX td|dd	 W 5 d}~X Y nX W 5 |rð|  ¡  | rü|   ¡  X dS )
zWCria pedido_periodos a partir do layout atual de pedido_diarios e colunas de auditoria.NzX
            CREATE TABLE IF NOT EXISTS pedido_periodos LIKE pedido_diarios
            z5SHOW COLUMNS FROM pedido_periodos LIKE 'arquivado_em'z’ALTER TABLE pedido_periodos ADD COLUMN arquivado_em DATETIME NULL, ADD COLUMN lote VARCHAR(36) NULL, ADD COLUMN chave_orig_pedido_diarios INT NULLzESHOW INDEX FROM pedido_periodos WHERE Key_name = 'idx_pp_cliente_arq'zMCREATE INDEX idx_pp_cliente_arq ON pedido_periodos (id_cliente, arquivado_em)z[PEDIDO_PERIODOS TABELA ERRO]T©Úflush)	r|   r   r'   r    r}   rû   rþ   rü   Úprint)r   r€   rc   r   r   r   Úensure_pedido_periodos_tableT  sB    ÿ
ÿ
ÿ$r  c                  C  sÐ   d} d}z¨zLtƒ } |  ¡ }| d¡ t| ¡ p2dgd ƒ}|dkrT| d¡ |  ¡  W nV tk
r¬ } z8z| rv|  ¡  W n tk
rŒ   Y nX t	d|dd W 5 d}~X Y nX W 5 |r¾|  ¡  | rÊ|   ¡  X dS )uQ   Tenta registrar EVENT diÃ¡rio para expurgo > 1 ano (pode falhar sem privilÃ©gio).Nz¥
            SELECT COUNT(*) FROM information_schema.EVENTS
            WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = 'ev_loja_purge_pedido_periodos'
            r   aq  
                CREATE EVENT ev_loja_purge_pedido_periodos
                ON SCHEDULE EVERY 1 DAY
                STARTS (TIMESTAMP(CURRENT_DATE) + INTERVAL 3 HOUR)
                DO
                  DELETE FROM pedido_periodos
                  WHERE arquivado_em IS NOT NULL
                    AND arquivado_em < DATE_SUB(NOW(), INTERVAL 1 YEAR)
                z[PEDIDO_PERIODOS EVENT ERRO]Tr  )
r|   r   r'   r    r-   r}   rþ   rû   rü   r  )r   r€   ri   rc   r   r   r   Úensure_purge_event~  s2    ÿÿ$r  ),Ú__doc__Ú
__future__r   rM   r]   rE   rß   rö   Úcollectionsr   r   r   Útypingr   r   r   r	   r
   Údatabaser   r   r   r,   r3   r4   r9   r:   r;   r>   rG   rU   rd   rj   rƒ   r~   r“   rÌ   rÃ   rè   ró   rô   r  r  r  r   r   r   r   Ú<module>   sJ   		LCû  A)f*