U
    z6hir                    @   s   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 d dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlZG dd	 d	eZdS )
    N)sleep)gn_mysql)Request)
JsonByPath)datetime)Pathc                   @   st  e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Ze	dddZ
e	dddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zed$d%d&Zedd'd(Zd)d* Zd+d, Zd-d. Zd/d0 Zg fed1d2d3Zd4d5 Zd6d7 Zd8d9 Z d:d; Z!d<d= Z"d>d? Z#d@dA Z$dBdC Z%dDdE Z&dFdG Z'dHdI Z(dJdK Z)dLdM Z*dNdO Z+dPdQ Z,dRdS Z-dTdU Z.dVdW Z/dXdY Z0dd[d\Z1d]d^ Z2d_d` Z3dadb Z4dcdd Z5dedf Z6dgdh Z7didj Z8dkdl Z9dmdn Z:dodp Z;g feedqdrdsZ<dtdu Z=eddvdwZ>g feedxdydzZ?edd{d|Z@edd}d~ZAdeedddZBe	edddZCdd ZDe	edddZEdd ZFdd ZGdd ZHdd ZIedddZJg fddZKdd ZLdd ZMdd ZNdddZOdd ZPdd ZQeeRdddZSdddZTdddZUdd ZVdd ZWdddZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^e	dddĄZ_ddƄ Z`ddȄ Zaddʄ ZbdS )gn_apic                 C   sV   |  dd tttjj| _i | _i | _d| _| j	p8d| _	i | _
|   |   d S )N000zinicio da exportacao F)	createLogstrr   __file__parentroot_dirjsonWsconfigsqldb
tableNamesprepare_params	bootstrapself r   9/home/www/html/webservice/gn_integracao/generic/gn_api.py__init__   s    zgn_api.__init__c                 C   s   dt | krd| _dt | kr$d| _dt | kr6d| _| jd | _d| jkr| jd}|d d | _|d d t | krt| |d d | _d	S t	d
 t
  | jd t | krt| | jd | _nt	d
 t
  d	S )z Parametros sendOneByOneFrequest_urlBaserequest_headersZ_id#r   _requestNz"Nao definido a variavel de request)dirr   r   r   apiNameapplication_idsplitgetattrapi_requestprintexit)r   dadosr   r   r   r   $   s&    
zgn_api.prepare_paramsc                    s   d
 fdd	} j d}d  _ |d}|r |d _ |d}i  _|D ]<}d|kr|d}||d  j|d < qR|| jd	< qRd S )N&c                    s    | si S  fdd|  |D S )Nc              	      s2   i | ]*}  |d dt  |d dqS )=r      )	get_indexr$   r   ).0xr   r   r   
<dictcomp>J   s     z9gn_api.rote_handler.<locals>.<lambda>.<locals>.<dictcomp>)r$   )querysepr   r   r   <lambda>J   s   z%gn_api.rote_handler.<locals>.<lambda>?r,   r   ;z->r1   )r*   )roter$   	rote_datar-   )r   Zquery_str_to_jsonZ	rote_argsZrote_data_strZrote_data_listr7   Zrote_mapr   r   r   rote_handlerH   s    

zgn_api.rote_handlerc              	   C   s   |d | _ |d | _|d | _|d | _|d | _|d | _|d | _|d | _|d	 | _|d
 dkrjdnd| _	| 
d| sdn| j}| j  | | _| d| j d| j d| j d}|s| dd t  |   |   |S )Nr,                        	   debugTFsuffixZ_app_pedidos3zDSELECT * FROM  TBEMPRESA WHERE 1=1
                AND NMLKGRUPO = "z#"
                AND CDEMPRESA = "z#"
                AND CDFILIAL  = "z";
            Z404z0Base de dados sem dados, checar empresa e filial)r"   methodr6   nmbanco	nmlkgrupo	cdempresacdfilialsaidasaida_cobolrB   hasAttrrC   lowerdatabase_dbselectr   r(   get_environment_apiget_tokens_api)r   argvrC   setupr   r   r   rR   a   s6    








zgn_api.setupc                 C   s   z|  d| j  d| j d| j d| j d	}|rt|dkr|D ]\}|ddkrh|d	d | _qF|dd
kr|d	d | _	qF|ddkrF|d	d | _
qFn| dd t  W n   | dd t  Y nX d S )Nz
                SELECT
                    *
                FROM
                    TBTOKEN
                WHERE
                    lkgrupo    = "("
                    AND empresa    = "("
                    AND filial     = "("
                    AND nome_api   = "z<"
                    AND tipo_token = "A";
                r   
nome_tokenZambiente_apivalor_tokenZservidor_apiZ	porta_api  zNao existem tokens cadastradosz:Nao foi possivel carregar os dados de registro de ambiente)rN   rF   upperrG   rH   r"   lengetambiente
softdib_ipsoftdib_portr   r(   )r   Zenvironmentstokenr   r   r   rO      s2    	
zgn_api.get_environment_apic                 C   s   zh|  d| j  d| j d| j d| j d| j d}|d d|d d	d
d |D d| _W n   | 	dd t
  Y nX d S )Nz
                SELECT
                    *
                FROM
                    TBTOKEN
                WHERE
                    1 = 1
                    AND lkgrupo    = "rS   rT   rU   z("
                    AND tipo_token = "z";
                r   Z	url_tokenZ
tipo_tokenc                 S   s   i | ]}| d | dqS )rV   rW   )r[   )r.   r_   r   r   r   r0      s      z)gn_api.get_tokens_api.<locals>.<dictcomp>)urlr\   tokensrX   z1Nao foram encontrados dados de registro de tokens)rN   rF   rY   rG   rH   r"   r\   r[   environment_configr   r(   )r   ra   r   r   r   rP      s,    	
zgn_api.get_tokens_api)returnc                 C   s$   | j di |}|r ||iS i S )Nra   rb   r[   r   keyvaluer   r   r   	get_token   s    zgn_api.get_tokenc                 C   s    | j di |}|r|S dS )Nra   Frd   re   r   r   r   get_token_data   s    zgn_api.get_token_datac                 C   s   |    |   dS )z Gatilho de entrada N)load_api_maphandle_api_mapr   r   r   r   r      s    zgn_api.bootstrapc                    s  | j  d| j }| j  d| j d| j  }d| jkrz| jd}| j  d|d  }| j  d|d  d| j  }| d}| d}| j|d}| j|d}t|pd}t|pd}	|r|	rddlm	}
 d	d
ddd	dddidddddddidddddddidddddidii}| 
d| rD| j}|
|}|||	}|d
i  t  fddd|d
< || _n|| _| jd| _dS )z+Busca e abre o arquivo de definicoes da api//companies/r   r   z	/map.jsonpath{})MergerZ
propertiesrotesZarrayZarrayMergeByIdZidRefpara	overwrite)typemergeStrategy)rv   ZmergeOptionsitems)fieldsZpedido_fieldsZitenscarrinho_fields)ru   rv   rw   merger_schemac                    s   |  dt S )Nid)r[   rZ   r6   rr   r   r   r3   >      z%gn_api.load_api_map.<locals>.<lambda>rf   r   N)r   r"   rF   rL   r$   	read_filejsonloadsZ	jsonmergerq   rK   ry   merger[   sortedr   r   )r   Zapi_pathZemp_fil_pathr)   Zapi_map_pathZemp_fil_map_pathZdefault_mapZapi_mapbaseheadrq   Zdefault_schemaZmergerZmergedr   r|   r   rj      sf    
 


+zgn_api.load_api_mapc                 C   sT  | j d }| j dkr$tt|}|D ]$}|| _| jd}|rT| j |krTq(| j	dksn| j	| jd kst
d| j	s| j	dks| | j	r(nq(| j	dkrd| jkr| jd sq(| j dkr| jd | _	|  }|sq(|   q(d	| jd
 kr| j d	kr|   q(d| jd
 kr:| j dkr:|   d| jd
 krd| j dkrd|   q(d| jd
 kr| j dkr|  }| jd| dd q(d| jd
 kr| j dkr|  }| jd| dd q(d| jd
 kr| j dkr|  }| jd| dd q(| j dkr(d|d
 ksFd|d
 kr(|   q(d S )Nrr   DELETEavailable_forALLr6   z&?[^=&]*=[^=&]*activeZSOAPGETmethodsZFILEPOSTZpost_route_handler_Tis_requiredPUTZput_route_handler_PATCHZpatch_route_handler_)ZSEND)r   rD   rY   listreversedatualWsr[   rF   rL   r6   rematchisFileZ
load_inputZsoap_handlerget_handlerfileHandlerdelete_handler
fixed_rotecallpost_put_handler)r   rr   r)   r   ZisValidZrouter   r   r   rk   H  sx    




    

zgn_api.handle_api_mapc                 C   s2   | j d ddddddddddS )	Nr6   rl   _.-{r
   })r   replacer   r   r   r   r     s     
     zgn_api.fixed_rotec           	      C   s   |   }| j d| j d}| j d| j d| j  d}d| jkr| jd}| j d|d  d}| j d|d  d| j  d}| d| d}| d| d}| j|d}| j|d}|r|S |S d S )Nrl   z
/templatesrm   r   r   z_template.txtrn   )r   r   r"   rF   rL   r$   r   )	r   r6   Zapi_path_templateZemp_fil_path_templater)   Zapi_map_path_templateZemp_fil_map_path_templateZdefault_map_templateZapi_map_templater   r   r   getTemplate  s    
 
"zgn_api.getTemplatec           
   	   C   s  |  d| sd S d| jkr$| jd n| jd }d| d}|  |\}}|jd d }|dkr| dd	|| j| j t	  | 
 }d
| j d| d| j d| d	}| |}|D ]X}|| _| jf |}	|	r|  dd|| j  dd| dd| j dg i | _qd S )NdeleteFromApialiastablezW
            SELECT
                COUNT(*) as TOTAL
            FROM
                	
        r   ZTOTAL500zV{}:{} -> {} - Rota de delete sem dados para excluir, verifique o motivo de estar vaziaz`
            SELECT
                    REL.NMTABELA AS tabela
                ,   REL.IDAPI AS z
                ,   REL.IDSOFTDIB AS softdib_id
            FROM
                TBRELACIONAID REL
            WHERE
                NMTABELA = 'z#'
                AND NMNOMEAPI = 'z'
                AND IDSOFTDIB NOT IN (
                    SELECT
                        softdib_id
                    FROM
                        (z') AS TEMPTB
                );
        TBRELACIONAIDzIDAPI=''z
NMTABELA='zNMNOMEAPI=')rK   r   getDb
executesqlZ_rowsr   formatr6   rM   r(   deParar#   r"   rN   current_datar   delete)
r   ZtabelaZtabela_ref_totalZtabela_ref_resultadoerrorr   rN   Zto_delete_listitemZ
is_deletedr   r   r   r     sD    	

	zgn_api.delete_handlerc           	      C   s&  |   | _|   |  }td| jd   |   | jd rDdnd}d| d| d}t }| |}d	t	|kr| 
d
dj|jd |jd | jd d d S tdt |  dt|  |  }| d| |}|d kr|n|}|r"| |d  |D ]}|| _| | qn d S )Nz!Iniciando busca no banco - rota: r   MD5z WHERE request_method IS NOT NULLr
   z(
            SELECT *
            FROM (z) AS TEMPTB
            z
 
        argsZ
mysqlErrorz3{mysql_error} : {mysql_error_desc} -  rote : {rote}r   r,   r6   )Zmysql_errorZmysql_error_descr6   ztempo de execucao: z	; total: Zdb_data_)r   templatedoSetsr   r'   r   doProceduretimerN   r!   r   r   r   rZ   r   r   mount_ws_map_propsr   handle_db_data)	r   r   whererN   ZiniZdb_datar6   Zbefore_handle_db_dataeachr   r   r   r   -  s<    


 zgn_api.post_put_handlerc                    s>   i | _ |D ]. tt fdd| jd p.d g\| j  < q
d S )Nc                    s   | d  kS )Nrs   r   r   r~   r   r   r3   ]  r}   z+gn_api.mount_ws_map_props.<locals>.<lambda>rx   )ws_map_propsr   filterr   r   datar   r~   r   r   Z  s    zgn_api.mount_ws_map_propsc              
   C   sj   |  || j}zt|}W n> tk
rZ } z td|  t| W Y dS d}~X Y nX | | dS )zA
            Metodo que manipula os dados vindo do banco
        z####ERROR-JSON : N)replacementr   r   r   
ValueErrorr'   send_handler)r   r   r   Z	json_datar   r   r   r   r   a  s    zgn_api.handle_db_data)json_strc                 C   sv   |  D ]B\}}| j| }| ||}dt| d }t|||pFd}qtdd|}| |ddgddgg}|S )	z 
            Metodo que substitue valores de um json de acordo com suas dados 
            - Exemplo: { "attr": "voar" } - quero  {{attr}}  - resultado: quero voar
            - Returna o json_str de entrada com a mudanca
            
        z{{\s*z\s*}}rp   z
\s*None\s*z""z###LINEBREAK###z\nz"""")rw   r   process_value_replacementsr   escapesubmulti_replace)r   r   r   rf   rg   propsregexr   r   r   r   t  s    	
zgn_api.replacementc                 C   s,   |r$d|kr$| j |dd|dd}t|S )NZcustom_replacementr
   Tr   )r   r[   r   )r   rg   r   r   r   r   r     s    z!gn_api.process_value_replacementsc                 C   st  | j d| j }| jd }||kr.|| _n(||krPttdd |}|| _n|| _| jd | _d| jkr| jd D ]F}|d }t	| j |d  }d	t
| d
 }t
|d| | j| _qv| jd}	|	dks|	rdnd}
d| j kr*| j d dkr*d| jkr*d| j | j  }| j | | _d}
| jdrd| jd dkrd| j | j pXd|| jd < | j|
 | _dS )z; 
            Metodo que prepara os dados de envio
        request_methodr   c                 S   s   | dkS )N)r   r   r   r   r   r   r3     r}   z%gn_api.prepare_send.<locals>.<lambda>r6   Zcustom_pathders   z\/(z)(?=\/?)rl   	backslashNr
   r   Zput_databody)r   r[   rD   rY   r   current_methodnextr   current_roter   r   r   r   r   r#   )r   r   r   r   Z_filterZchanger   rs   r   Zhas_backslashr   Zitem_idr   r   r   prepare_send  s8    

zgn_api.prepare_sendc                 C   s   |  | |  }d| }| j||| jddd}t| drT| jdkrTd| _dS | | | jd rz| jj	t
d	d
krd| }| || i | _dS )z3
            Metodo para manipular o envio
        beforeSend_need_beforeSendFr   ignore_requestTNsend   i,  Z
afterSend_)r   r   r   r   r[   hasattrr   r   send_responsestatus_coderanger   )r   r   	func_rotefunc
beforeSendr   r   r   r     s    



zgn_api.send_handlerc           	      C   s   d| j kr| j d dkrdS | j d}| jd}|p>|p>d}|dkrVt|}d}|dkrbd}d	| jd
| j||i}td| d| j  | j	f || _
| j
jpd}d| }| || j
}|dkrtd| d|  dS )z, Envia dados para uma api - via POST ou PUT r   FNraw_typer   textr   Z
urlencodedr6   rD   z:params |> z

:data |> r   Zresponse_code_z:fail |> Funcao status code z nao criado ainda 
 data:)r   r[   r   r   dumpsr   r   r'   r   
throttlingr   r   r   )	r   r   Zraw_type_roteZraw_type_defaultr   paramsr   Zresponse_funcr   r   r   r   r     s0    
   
zgn_api.sendc                 K   sh   | j jf |}z$t|j}|d dkr0t| W n   Y nX | d|}|sRqdt| t| q |S )u    
            Metodo que controla throttling 
            - para ativar o throttling é preciso definir no map em config
            - Por padrao se nao existir o throttling definido ele nao é aplicado
        r   z3Bad Request: Rate limit exceeded, retry in 1 secondZthrottling_rules)r&   	doRequestr   r   r   r'   r   r   )r   r   reqr   Zthrottling_timer   r   r   r   /  s    
zgn_api.throttling)selectFieldsc              	   C   s  |   }|dkr"|d| d |dkrd| jkrd}d}d}| d| jd i}d| jkrl| jd	 n| jd }| jd
g | jd
< | jd
 ddd| d| dd| j dgd |d| j  || d d| jd  }d}	d| jkr8| || s"| dd|  nt	| d| jd   }	d| jd ksXd| jd krhd| d}d}|dks||dkrd| d|	 d| d }
||
 | 
|S )!z[summary]
        
        Keyword Arguments:
            fields {list} -- [description] (default: {[]})
        
        Returns:
            [type] -- [description]
        Fz
            /**
            *   GERA UM HASH MD5 DOS CAMPOS, 
            *   USADO PARA APOS O ENVIO GRAVAR NA TABELA DEPARA
            *   CRIADO EM MERCOS.PY
            */
            z as  hash_md5  
            r   r
   dbfield
primaryKeyr   r   joinszTBRELACIONAID TBRELINNERz	LEFT JOINzTBRELINNER.IDSOFTDIB = zTBRELINNER.NMTABELA = 'r   zTBRELINNER.NMNOMEAPI = ')tbNamer   onz9
                    TBRELINNER.IDAPI
                AS z AS softdib_idZcustom_case_r6   Zcustom_caseZ999zFuncao deve ser criada: r   r   a7  
                    /**
                    *   SE O PRODUTO JAH ESTIVER NA MERCOS, DEVEMOS ATUALIZAR COM UM PUT 
                    *   CRIADO EM MERCOS.PY
                    */ 
                    WHEN (
                        SELECT TBRELINNER.HASHMD5 IS NOT NULL AND UPPER(TBRELINNER.HASHMD5) <> UPPER(z)
                    )
                    THEN
                        'PUT'
                        
                    
                a  
                    /**
                    *   SE O ITEM NAO ESTIVER NA TABELA DE RELACIONAMENTO 
                    *   CRIADO EM MERCOS.PY
                    */
                    WHEN (
                        SELECT TBRELINNER.HASHMD5 IS NULL
                    )
                    THEN
                        'POST'
                        
                    
                aB  (
                    /**
                    *   CASE PARA A MONTAGEM DA COLUNA MERCOSHASH, 
                    *   ELA O METHODO DE ENNVIO, 
                    *   POST OU PUT 
                    *   CRIADO EM MERCOS.PY
                    */
                    CASE
                        
                        z2
                        
                        a  
                        
                        /**
                        *   SE O VALOR JA EXISTIR E O HASH FOR O MESMO, NAO PRECISA ENVIAR
                        *   CRIADO EM MERCOS.PY
                        */
                        ELSE
                            NULL
                            
                        
                    END 
                ) AS 'request_method'
                
                
                
                )controleMD5appendr   processItem_dbfieldr[   r"   r#   rK   r   r%   mountSelect)r   r   gn_md5Z_post_put_getr   r   r   Z_custom_caseZcaser   r   r   mountSelectputPostQ  s\    



 	#
zgn_api.mountSelectputPostc                 C   s"   z|  }W n   i }Y nX |S N)r   )r   r   r   r   r   r   tryJson  s
    
zgn_api.tryJsonc                 C   s   t d d S )Nresponse_code_0r'   )r   r   r   r   r   r     s    zgn_api.response_code_0c                 C   sL  d| j ks"d| j kr&| j d dkr&dS | j}| j| sd| j kr| j d}|dkrl| jd|dd| j|< nT|dkrd	|   }| j||dd| j|< n&| |}| ||p| j| | j|< | j|}| jd
}| jd}| j d| j d}	|s|s|	rd S | j|	|d||d}
| 	|
 t
d|	 d| d|  dS )NZrelacionaIdFz
control-idZcustomZcustom_control_idTr   Zby_roteZcustom_control_id_
softdib_idZhash_md5r   r   now())	NMNOMEAPINMTABELA	IDSOFTDIBDTULTIMAALTERACAOHASHMD5IDAPIz:ok |> [z]  - )r   r#   r   r[   r   r   r   jsonValueByPathr"   
relatementr'   )r   response
identifierZcontrolfnZjson_responser   Z
SOFTDIB_IDr   r   data_relaciona_idr   r   r   response_code_201  s8    "
	 	
zgn_api.response_code_201c                 C   s   |  | dS NFresponse_logr   r  r   r   r   response_code_400M  s    
zgn_api.response_code_400c                 C   sl   |  | | dpg }| jd |krh|  dd| jd  dd| j| j  dd| jd	  dg d S )
NZnot_allow_roter6   r   zIDSOFTDIB  ='r   r   zIDAPI      ='zNMTABELA   ='r   )r  r   r   r   r   r   r#   )r   r  ZnotAllowRoter   r   r   response_code_404Q  s    
zgn_api.response_code_404c                 C   s   t d d S )Nresponse_code_200r   r  r   r   r   r  `  s    zgn_api.response_code_200c                 C   s   |  | d S r   r
  r  r   r   r   response_code_422c  s    zgn_api.response_code_422c                 C   s   |  | d S r   r
  r  r   r   r   response_code_412g  s    zgn_api.response_code_412c                 C   sn   d| d dd| d dd| d dg}| dd	|}|sX|  d	| n|  d	||}d S )
NzNMTABELA   = 'r   r   zIDSOFTDIB  = 'r   zNMNOMEAPI  = 'r   r   r   )r[   existsr   insertupdate)r   r   Zcond_paramsr  r1   r   r   r   r  j  s    zgn_api.relatementc              	   C   sf   d| j krd| j d< d}z| }W n   |j}Y nX | |jdj|| j d | jd | jd d S )Nr   Zrelaciona_cli_pedidor
   z;{text}| id Softdib: {sdid} | rote: {rote} | metodo {method}r6   )r   Zsdidr6   rD   )r   r   r   r   r   r   r   r   )r   r  r   r   r   r   r    s    

zgn_api.response_logc                 C   s   t d d S )NzAinda sera implementador   r   r   r   r   r     s    zgn_api.fileHandlerc                 C   s   |   }| d| }|r,| jd d | n| jd }| d| | d| |pT|}| |}| jd}|dksx|r|   | | jd d	 | dS )
z rote = self.atualWs['rote']
        func_filtro_rote = "rote_filter_" + self.atualWs['rote']
        if self.hasAttr(func_filtro_rote, self) :
            rote = self.atualWs['rote'] + "/?" + getattr(self, func_filtro_rote)() Zrote_filter_r6   r4   Z444Zformat_rote_use_softdib_apiNhandlerZ_handler)r   r   r   r   
paginationr[   define_sd_request)r   Z	rote_slugr   r6   r   r  r   r   r   r     s     
zgn_api.get_handlerc              	   C   s   |  d|    | j|d | _}|jsR| |jd| d|jd d g S | 	|}|sdg S |  d|   |}|d kr|}|  d||}|r|| j
|d }|S )	NZ
beforeGet_r{   zErro nos dados: r  zutf-8 Z	afterGet_Zpagination_rules)r   r   r   r  okr   r   contentdecoder   r  )r   r6   r  r   ZafterGet_dataZ	next_pager   r   r   r    s    $
 zgn_api.paginationc                 C   s   |  ddd| ddgS )Nr   r   zIDSOFTDIB='r   zNMTABELA ='TBCLIENTE')r  )r   coder   r   r   check_client_exists  s    zgn_api.check_client_existsc              	   C   sb  |D ]V}|  | jdd|}| ddd| dd| j dg}|rJqt }z|| _| jd| jd	d
|d< |d d d dkrW q| jd| jd	d
|d< | jd| jdd
|d< | jd| jdd
|d< t|d r&|d d d r| jdr&|d \}| d|}| 	|p||d d d< | 
| W n" tk
rT   tt  Y nX i | _qdS )u   Funcao para manipular os dados vim do GET de pedidos de todas as integraçoes
            - Ela grava os dados dos pedidos no sistema Softdib
        Args:
            data (dict): []
        r  rz   ZIDTBPEDIDOSRETORNOTBPEDIDOSRETORNOzCDPEDIDOEXTERNO='r   zNMAPI='Zget_order_dataTr   pedidor   ZCDFRETEZget_order_itemsZitenscarrinhoZget_order_volumesFZvolumesZget_order_etiquetasZ	etiquetasZ	CDCLIENTEZalwaysUpdateClientcustomer_dataN)r  r   r[   r  r"   dictcurrent_orderr   rZ   salvar_cliente_softdibsalvar_pedido_softdibZeroDivisionErrorr'   	traceback
format_exc)r   r   orderr  Zorder_already_existsZorder_to_sendZcli_datar!  r   r   r   pedidos_handler  s8    


,
	zgn_api.pedidos_handlerc                 C   s
  |d \}|  dd|dd  | jjdt|dd}| |}|jd	kr|r|  |jd
|d d  d|d d   d| jkrt	|r| 
|}n|  |j| dS |r| dp|dpd}| jd|d d |d d ||d d d}| | dS dS )zE 
            Metodo para salvar pedidos na softdib
        
        r   Z001zInicio da gravacao do pedido: Z
IDTBPEDIDOr
   z/integracao/pedido/pedidor   )r6   r   rD   r   z Pedido cadastrado com sucesso : rA   CDPEDIDOr  CDPEDIDOEXTERNOsave_statusFZdateLastChangesr   r   r  ZNMCHAVEUNICAPEDIDO)r   r   r   r   r   r   TN)r   r[   softdib_requestr   r   r   r   r   r   rZ   r-  r   r"   r  )r   r   r   r  retorno_cobolZsavedZdtulitmaalteracaoZ
dataFieldsr   r   r   r%  T  s2    

*



zgn_api.salvar_pedido_softdibc                 C   sZ   |   d| j | j| j| j|d d |d d ddd|   d|d d  d	d
	S )zd 
            Por enquano cada api tem seu tratamento criar funcao dentro do arquivo da api
        ZTBPEDIDOSSTATUSrA   r,  r+  r   r,   z'O pedido foi cadastrado com sucesso em z	  : Cod. r  )	Z	NMLKGRUPO	CDEMPRESAZCDFILIALZNMAPIr,  r+  ZDTSTATUSZCDSTATUSZNMOBSERVACAO)r   r  rF   rY   rG   rH   r"   timeNow)r   r/  r   r   r   r-    s    


zgn_api.save_statusc              
   C   s   | j jd|dd}|jdkr| }|d d d }| jd||d	d
|dddd}| | | |jd| d|dd  |S dS )O 
            Cadastro de cliente quando nao existe no sistema softdib
        /integracao/pedido/clienter   r6   r   rD   r   clienter   CodigoZ	TBCLIENTEr   r   IDCLIENTEEXTERNOr
   NextUpdateWillGenerateNewHashr   r   r   r   r   r   !cliente cadastrado com sucesso : :Nr.  r   r   r   r"   r[   r  r   r   r   r  r/  Zcodigo_clienter  r   r   r   r$    s$    



"zgn_api.salvar_cliente_softdibc              
   C   s   d|d< | j jd|dd}|jdkr| }|d d d	 }| jd
||dd|dddd}| | | |jd| d|dd  |S dS )r2  SZFGTRANSPORTADORr3  r   r4  r   r5  r   r6  ZTBTRANSPORTADORr   r   r7  r
   r8  r9  r:  r;  Nr<  r=  r   r   r   salvar_transportadora_softdib  s&    



"z$gn_api.salvar_transportadora_softdib!/integracao/pedido/authenticationc                 C   s   d}| j rdn| j}d| jpd }| | | }t|d}|j|dd| j| j| jdd	}|jd
krt	d t	d|j d|j
 d|j  t  t|dd|j
dddd| _t	| j dS )zu 
            Monta a estrutura base de headers e paramentros para consumir ou enivar dados para api softdib
        zhttp://z192.168.1.3r;  i  )base_urlpostZSAC)userZlkgpZbancoZapiname)r6   rD   r   r   zFalha ao autenticar na SoftdibzFalhou: r  zapplication/json"r
   )zContent-TypeAcceptzx-access-token)rA  headersN)rB   r]   r^   r   r   rF   rE   r"   r   r'   r   reasonr(   r   r.  )r   ZrotaZprotr   portrA  authZauth_resr   r   r   r    s8    
 zgn_api.define_sd_requestc                 C   s.   | j | }| ||}| j|d< | j|d< |S )Nr0  ZFILIAL)r   generate_valuesrG   rH   )r   r   targetrx   valuesr   r   r   extractValues  s
    


zgn_api.extractValuesc                 C   sr   t  }|D ]b}| ||}t|tr,|s,d}|d }d|krdtdd |dD rd| ||| q
|||< q
|S )Nr   rs   rl   c                 s   s   | ]}|  V  qd S r   )isdigit)r.   partr   r   r   	<genexpr>+  s     z)gn_api.generate_values.<locals>.<genexpr>)r"  handleField
isinstanceboolanyr$   set_nested_value)r   rx   r   rL  field	new_valueZ	para_pathr   r   r   rJ     s     
zgn_api.generate_valuesc                 C   s"  | d}|}t|dd D ]\}}| rt|}t|tsftdd|d|  dt| t	||kr~|
i  qf|| }q||kr|d t	|k r||d  nd}	|	r|	 rg ||< ni ||< || }q|d }
|
 rt|
}t	||kr|
d q|||< n|||
< dS )z
        Define um valor em uma estrutura aninhada baseada no caminho
        Exemplo: path = "telefones/0/numero" 
        Resultado: obj["telefones"][0]["numero"] = value
        rl   NrA   zEsperado lista no caminho z, mas encontrou r,   )r$   	enumeraterN  intrR  r   r   joinru   rZ   r   )r   objro   rg   partscurrentirO  indexZ	next_partZ	last_partr   r   r   rU  2  s.    

&
 



zgn_api.set_nested_valuec           	         s  d}|_ d|kr2|d |}|d dkr2|}d|kr||di  t|tr^ |gS t|tr| fdd|D S d|kr|di }||S d|kr|s|d }d	|krȈ|d	 |}d
|kr|d
 ||}d|kr$|}|d  dj	  }|||}|d kr$|}d|krBj
||d dd}d|kr\||d }d|kr|d }t|tr~|n|d }t|dd| |S )NFintegrationrootr   c                    s   g | ]}  |qS r   )rJ  )r.   v
field_listr   r   r   
<listcomp>s  s     z&gn_api.handleField.<locals>.<listcomp>rx   defaultcustom_translatetranslate_by_itemtranslate_by_branchr   	translateT)rz   r   reversetranslate_by_type
globalThisrl   )	item_datar  r[   rR  r"  rJ  r   r   rF   rL   rj  translateByTyper   setattrr   )	r   r   r   rg   field_childcurrentValue	func_namerm  attrr   rc  r   rQ  a  sH    






zgn_api.handleFieldc                 K   s   d}d}d|kr$|d dkr$d}d}| d}| dd}d| d	| d
| d| d|d  d| d| j d| d	| d|r|d nd|d  d}|rd| dS |  |}| ||S )u   
            A Tradução eh a relacao do codigo da api com a codigo da softdib ou vice versa
            - Por padrao a traducao ocorre de um codigo da softdib para um codigo da api.
            - se quiser ao contrario mduar reverse para true na chamada da funcao
            - sql = True retonar apenas o sql gerado
            - lembrando que o codigo ja deve estar cadastrado na tabela de relacionamento
            - @params - reverse = False, id = id da softdib ou da integracao, sql = False
        r   r   rk  Tr   r   Fz
            SELECT r   z# 
            FROM   TBRELACIONAID z%
            WHERE  
                z.NMTABELA = 'r   z#' 
            AND
                z.NMNOMEAPI  = 'z = rz   z'{}'r   ())r[   randNamer"   r   r   rN   
fetchFirst)r   r   Zrelaciona_fieldZrelaciona_keyZretorno_sqlZrandom_namer   	resultador   r   r   rj    s@    

zgn_api.translatec                 C   s   t |trt |trdS |dkr:tdd|}|dd  S |dkr\tdd|}|dd S |dkrr|d	d S |d
kr|d	d S dS d S )NERRORZnumeroz(^([0]|[(])+|[^\d])r
   r9   Zdddr   dater  hourr,   )rR  r"  r   r   r   r$   )r   rg   _typeZtelefoner   r   r   ro    s    zgn_api.translateByTypec                 C   s   | j | jd S )Nr  )r#  r[   r   )r   rg   r   r   r   order_id  s    zgn_api.order_idc                 C   sf   d|  g  d|   d| g  d|   d|   d}| d|   |}| |pZ| |pd|S )N
            r   ZprocessSQL_)r   
mountJoins
mountWheremountGroupBymountOrderByr   r   println)r   r   Zsql_processedr   r   r   r     s    zgn_api.deParac                 C   s   d| j krt| j d tkr*d| j d  n| j d }t| j d ts\|  d| d q| j d D ]}|  d| d qfndS d S )N	procedureZsp_r6   zCALL z();r
   )r   ru   rS  rR  r   r   r   )r   r  Zeach_procedurer   r   r   r   )  s    
*zgn_api.doProcedurec                 C   sB   d| j kr|  d d| j kr:|  | j d ndS d S )NZgroup_concatz8SET SESSION group_concat_max_len = 18446744073709551615;setr
   )r   r   r   r[   r   r   r   r   r   ;  s
    

zgn_api.doSets)rx   rc   c                 C   sD   | j d D ]}|| | q
d|}d| d| j dd S )a)  Monta o SELECT para o sql 
        
        Keyword Arguments:
            fields {list} -- [Lista de campos, passado por paramentro para poder extender mais facilmente] (default: {[]})
        
        Returns:
            str -- [Retorna o script assim: "SELECT CAMPO1, CAMPO2, CAMPO3"]
        rx   z,                  zSELECT z  FROM r   r
   )r   r   processItemrZ  r[   )r   rx   Zdador   r   r   r   I  s    

zgn_api.mountSelectc                 C   s(  d| j kr | j d r g }d| j krt| j d D ]V\}}|d}d}d|krt| |d |}|| j d | d< |pz|}|o|| q4nft| j d D ]V\}}|d}d}d|kr| |d |}|| j d | d< |p|}|o|| qt|}| dd|i}d| d	}|S dS d
S )z???
        r   	md5Fieldsr   FZcustom_dbfieldrx   z + zMD5(rv  N)r   rX  r[   r   r   r   r   rZ  )r   r  r_  rV  r   ZcustomDbfieldr   r   r   r   r   ]  s0    


zgn_api.controleMD5c                 C   s   d}| j dg }|rg }| j d D ]T}|d }d}d|krVd|d }d| d}|d }|| d	| d	|  q$d
|}|S )Nr
   r   r   r    AND zON (rv  r   r  
)r   r[   rZ  r   )r   Zjoins_queryr   Zstr_joinrZ  r   r   r   r   r   r   r    s    

zgn_api.mountJoins)whereFieldsrc   c                 C   s   dg}d| j kr|| j d 7 }||7 }d|}d|krN|dtt| j}d|krl|dtt| j}t| dr| jrt	| jt
rd| jkr| jd }t	|t
r| D ]\}}|d| d| d7 }qd	| d
S )Nz1=1r   r  z@empresaz@filialr7   z = 'r   z WHERE r  )r   rZ  r   r   rY  rG   rH   r   r7   rR  r"  rw   )r   r  r   Zwhere_conditionsrf   rg   r   r   r   r    s    

&

zgn_api.mountWherec                 C   s,   d}d| j kr(d| j d }d| }|S )zVMonta a condicao orderby
        
        Returns:
            str -- OrderBy
        r
   orderByr  z
 ORDER BY )r   rZ  )r   r  r   r   r   r    s
    

zgn_api.mountOrderByc                 C   s<   d}d| j kr8t| j d r8d| j d }d| d}|S )zVMonta a condicao groupBy
        
        Returns:
            str -- groupBy
        r
   groupByr  z
 GROUP BY z HAVING COUNT(*) > 0)r   rZ   rZ  )r   r  r   r   r   r    s
    zgn_api.mountGroupByT)r   rc   c                 C   st   d}|| j kr| j | S dd t|D }d|}d| d| }|sL|S || j  krf| |}n
|| j |< |S )zGenerate a random string of fixed length
        
        Arguments:
            table {str} -- [description]
        
        Returns:
            str -- [description]
        
   c                 S   s   g | ]}t tjqS r   )randomchoicestringascii_uppercase)r.   r^  r   r   r   re    s     z#gn_api.randName.<locals>.<listcomp>r
   z/*z*/)r   r   rZ  rL  rw  )r   r   saveZstringLengthZ
aleatoriosZrandNmr   r   r   rw    s    	



zgn_api.randName)r   rc   c                 C   s   d}d|kr|  |}d|kr(| |}d|krD| j||d dd}d|krZ|sZ| |}d|krz| d	|d  d	|}d
|kr| |d	|d
  d	}d|kr| ||d }| d|d  d}d| d}|S )z Monta o formado do select r
   r   _customrj  T)rz   r   r   rf  Zprependr   r   r}  z AS 'rs   z' z    r  )r   processItem__customrj  processItem_default
concat_sqlprocess_type)r   r   rg   r   r   r   r  #  s$    


zgn_api.processItemc                 C   sb   |}|dkrd| d| d}|dkr2d| d}d|  kr^|d	d
 }d| d| d}|S )Nintegerz(SELECT IF (z='', 0, FLOOR(z)))r   z(SELECT REPLACE(z, CHAR(10), '###LINEBREAK###'))castr;  rA   z(SELECT CAST(z AS z)))rL   r$   )r   Zvalue_inr}  Z	value_outZto_castr   r   r   r  F  s    zgn_api.process_type)rV  rc   c                 C   sN   ddddg}|d }||kr"d}n(d|kr>|d dkr>| }nd| d}|S )	a  Faz o processamento de valores do tipo defaults
        
        Arguments:
            field {object} -- Objeto com os dados da coluna {'dbfield':str, 'para':str, 'type':str ,'desc': str} 
        
        Returns:
            str -- string do canpo tratado
        nullz'null'NULLz'NULL'rf  ru   ZBooleanr   r   )r   rV  ZnulsVariationsrg   retornor   r   r   r  Z  s    zgn_api.processItem_defaultc                 C   s>   |d }| dd  | _d|kr(|S t d|}| j| S )Nr   r   r   +z\+(?=(?:[^']*'[^']*')*[^']*$))r$   stripr   r   r  )r   rV  Zpartesr   r   r   r   }  s    zgn_api.processItem_dbfieldc                 C   s   t | |d |S )Nr  )r%   )r   rV  r   r   r   r    s    zgn_api.processItem__customc                 C   s   |   |}|S r   )r   rN   )r   r   ry  r   r   r   rN     s    zgn_api.selectc                 C   s$   | j dkrt| j| j| j| _ | j S r	  )r   r   rF   rM   rB   r   r   r   r   r     s    
zgn_api.getDb)rL  c                    s0   dd  dd }d  fdd|D }||S )z Funcacao para criar concat de retono para o mysql
            Ele insere o valor puro, se quiser concatenar uma string use "'{}'".format(value)
        c                 S   s   d|    dS )NzCAST(COALESCE(z,"") AS CHAR))r  r   r   r   r   r3     r}   z#gn_api.concat_sql.<locals>.<lambda>c                 S   s   d|  dS )NzCONCAT(rv  r   r  r   r   r   r3     r}   z, c                    s   g | ]} |qS r   r   )r.   rg   r  r   r   re    s     z%gn_api.concat_sql.<locals>.<listcomp>rZ  )r   rL  concatZcastsr   r  r   r    s    zgn_api.concat_sqlc                 C   sX   t |dkrdd| }d| d| d| }|  |}|d d dkrTdS d	S )
a   
            Verifica se um registro ja existe na tabela.
            -------------
            Params:
            
            ``field`` - Campo de referencia.
            ``table`` - Tabela que deseja consultar.
            ``where`` - Condicao exclusiva .
        r   zWHERE 1=1 AND r  z#
        SELECT 
            COUNT(z) AS qtd 
        FROM r  ZqtdTF)rZ   rZ  r   rN   )r   rV  r   r   r   r  r   r   r   r    s    zgn_api.existsc                 C   s*   | j rt| n| t|| jd  d S )NZpath_log)rB   r'   writeLogr   r   )r   Z_printr   r   r   r    s    
zgn_api.printlnc                 C   s   t t  dS )Nz%d/%m/%Y %H:%M:%S)r   strftimenowr   r   r   r   r1    s    zgn_api.timeNowc                 C   s>   |dkrdnd}|    d| d| d}| || j| d S )Nr	   w+a+r5   r  )r1  r  rI   )r   r   ZmensagemflagZconteudor   r   r   r     s    
zgn_api.createLogr
   r  c                 C   s   | j |||dd d S )Nutf8)r   ro   r  encoding)
write_file)r   r  	file_namer  r   r   r   r    s    zgn_api.writeLogc                    s    fdd}|S )Nc                     s   t d jjf  dS )Nz$"%s" Nao eh um metodo da classe "%s"F)r'   	__class____name__)r   kwargsnamer   r   r   error__  s    z#gn_api.__getattr__.<locals>.error__r   )r   r  r  r   r  r   __getattr__  s    zgn_api.__getattr__c                 C   s   t dd|S )Nz[^\d]r
   )r   r   r   r   r   r   only_numbers	  s    zgn_api.only_numbers)arrr_  c                 C   s   z
|| W S    Y d S X d S r   r   )r   r  r_  r   r   r   r-   	  s    
zgn_api.get_indexrr  c                 C   s   | j d|||dS )Nread)handlero   r  r  handle_file)r   ro   r  r  r   r   r   r   	  s    zgn_api.read_filer  c                 C   s   | j d||||dS )Nwrite)r  r   ro   r  r  r  )r   r   ro   r  r  r   r   r   r  	  s    zgn_api.write_filec              
   K   s   ztt |d |d |d dP}|d dkr@| W  5 Q R  W S |d dkrh||d W  5 Q R  W S W 5 Q R X W n( tk
r } z
W Y d S d }~X Y nX d S )	Nro   r  r  r  r  r  r  r   )openr  r  IOError)r   r  filer   r   r   r   r  	  s    zgn_api.handle_filec                 C   s"   |D ]}|\}}| ||}q|S r   )r   )r   rg   Zreplacementsr   Z_fromZ_tor   r   r   r   #	  s    zgn_api.multi_replacec              
   C   sf   z0t |d|d}| W  5 Q R  W S Q R X W n0 tk
r` } zt| t  W 5 d }~X Y nX d S )Nr  r  )r  r  r  r'   r(   )r   ro   r  r  r   r   r   r   readFile,	  s     zgn_api.readFilec                 C   s   | j dkrt| j  d S r	  )Zrequest_sleepr   r   r   r   r   r   5	  s    
zgn_api.sleepc                 C   s&   z
|d W S  t k
r    Y dS X d S )Nr   r
   )r   )r   r  r   r   r   	arr_first:	  s    
zgn_api.arr_firstc                 C   s,   t |dkr$||d kr$|d | S dS d S )Nr   F)rZ   )r   r  rf   r   r   r   rx  A	  s    zgn_api.fetchFirstc                 C   s   |t |kS r   )r!   )r   	attributeZ_objectr   r   r   rK   H	  s    zgn_api.hasAttrc                 O   s   | d}|r|d }ntd| || rfd|kr:|d= zt| ||dd |W S     Y qX n|r|td| dndS dS )a   
            Parameters
            ----------

            `` args[0]`` str
                The name's funtion to be called.
                
            ``args[1:]`` parameter's function
                
            ``kwargs`` object params.
            
            ``is_required`` bool
                To determine if this function is required or not
                ``default`` None.
                
            Raises
            ------
            ``Exception``
                If args[0] not defined will raise Exception
        r   r   z-call() missing 1 required positional argumentr,   Nzname 'z+' is not defined, this function is required)r[   	ExceptionrK   r%   )r   r   r  requiredr   r   r   r   r   L	  s    

 
zgn_api.callc                 C   s   t td|S )Nz^.*\.[^\\]+$)r   r   findall)r   Zpossibly_a_filer   r   r   r   v	  s    zgn_api.isFilerw   c                    s   d  fdd D S )Nr*   c                 3   s    | ]}| d  |  V  qdS )r+   Nr   )r.   rf   r  r   r   rP  {	  s     z*gn_api.mountRouteParams.<locals>.<genexpr>r  )r   rw   r   r  r   mountRouteParamsz	  s    zgn_api.mountRouteParamsc                 C   s,   t ||d}t|jtr"|j S |jS d S )N)ro   r   )r   rR  rg   r   r  )r   ro   r   ZJsonr   r   r   r  ~	  s    
zgn_api.jsonValueByPathc                 C   sP   d|krd t|dS d|krLd t|}|ddddddS d S )	Nr{  z{:%d/%m/%Y}z%Y-%m-%dcurrencyz{:,.2f},rb  r   )r   r   strptimefloatr   )r   rg   r}  r  r   r   r   mask	  s
    zgn_api.maskc                    s    fdd}t |||S )Nc                 3   s   t |  | D ]}|| krv||krvt| | trft|| trf|t | | || fV  q||| fV  q|| kr|| | fV  q||| fV  qd S r   )r  keysunionrR  r"  	deepMerge)Zdict1Zdict2kr   r   r   r   	  s     zgn_api.deepMerge.<locals>.merge)r"  )r   Zd1Zd2r   r   r   r   r  	  s    zgn_api.deepMergeN)r@  )T)r
   r
   r  )r
   r  r  )r
   r
   r  r  )r  )cr  
__module____qualname__r   r   r8   rR   rO   rP   r"  rh   ri   r   rj   rk   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r  r   r   r  r  r*  r%  r-  r$  r?  r  rM  rJ  rU  rQ  rj  ro  r~  r   r   r   r   r   r  r  r  r  rw  r  r  r  r   r  rN   r   r  r  r  r1  r   r  r  r  rY  r-   r   r  r  r   r  r   r  rx  rK   r   r   r  r  r  r  r   r   r   r   r      s   $*%#R_
+Q-	E#-" =	4 '$R9
1/J1!A(!!###


	
	*	
r   )r   r   r  r  r   r   Zgeneric.gn_mysqlr   generic.gn_requestr   Zgeneric.JsonByPathr   r   pathlibr   r'  objectr   r   r   r   r   <module>   s8   (                   .