o
    i)j~W                     @  sZ  d Z ddlmZ ddlZddlZddlm  mZ ddl	m	Z	 ddl
mZ ddlmZmZ ddlmZmZmZmZ ddlmZ dd	lmZ dd
lmZ ddlZddlmZmZmZmZ e ddZ!e ddZ"dZ#d7ddZ$d8ddZ%d9ddZ&d:d&d'Z'd;d)d*Z(d9d+d,Z)d9d-d.Z*G d/d0 d0eZ+ee+ge#d0ed1d2e d3Z,ee,Z-d<d5d6Z.dS )=a;  
Servicio SOAP compatible con el cliente MIG (Web Reference WSMIG.RibiSoft).

Mantiene los nombres de operacion exactamente como los espera el cliente
generado por la Web Reference original (RegistrarEmpresa, IngresoEmpresa,
ValidarEmpresa, RegistrarLicencia, ValidarLicenciaMensual, InactivarLicencia)
para que el cambio en el cliente sea solo de URL/namespace.

Namespace: http://migsistemas.com/licencias/  (ya no http://localhost/)

Montaje en Flask: register_soap(app) lo expone en /LicenciasService.asmx
sirviendo WSDL en GET ?wsdl y aceptando POST con sobre SOAP.
    )annotationsN)datetime)Optional)Flaskrequest)ApplicationServiceBaseUnicoderpc)Soap11)WsgiApplication)Response)EmpresaLicenciaEmpresaWebServiceLogdb	SOAP_USERadminSOAP_PASSWORDz123*/z!http://migsistemas.com/licencias/returnr   c                  C  s   ddl m}  |  S )z?Devuelve la app Flask actual para usar su contexto desde Spyne.r   current_app)flaskr   _get_current_objectr    r   */var/www/html/LicenciasMIG/soap_service.py
_flask_app(   s   r   usuarioOptional[str]contraseniaboolc                 C  s   | pdt ko|p	dtkS )N )r   r   )r   r   r   r   r   _autenticar.   s   r"   strc                   C  s   t rt jdt jp
dS dS )NzX-Forwarded-Forr!   )r   headersgetremote_addrr   r   r   r   _ip_cliente2   s   r'   metodonitequipo	resultadomensajeduracion_msintNonec              
   C  sZ   zt t | |t ||||d}tj| tj  W d S  ty,   tj	  Y d S w )N)FechaMetodor)   	IpClientenombreequipo	ResultadoMensaje
DuracionMs)
r   r   utcnowr'   r   sessionaddcommit	Exceptionrollback)r(   r)   r*   r+   r,   r-   logr   r   r   _log8   s    
r>   vc                 C  s$   | du rdS t |   }|dv S )z:El cliente manda 'SI'/'NO' o '1'/'0'; normalizamos a bool.NF)1SITRUETYYES)r#   stripupper)r?   sr   r   r   _bool_from_strK   s   rI   c                 C  sd   t d}| D ]#}t |d}|  D ]\}}|du rqt ||}t||_qqt j|ddS )a  Replica el formato DataSet.GetXml() de C# para ValidarEmpresa.

    El cliente espera un sobre tipo:
        <NewDataSet>
          <Table>
            <nit>...</nit>
            <razonsocial>...</razonsocial>
            ...
          </Table>
        </NewDataSet>
    
NewDataSetTableNunicodeencoding)ETElement
SubElementto_dictitemsr#   texttostring)empresasrootetcolvalsubr   r   r   _empresas_a_dataset_xmlS   s   
r]   c           	      C  s   i }|durdd |   D }td}| D ];}t|d}| D ]\}}|du r-q$t|t||_q$|  }dD ]}||}|du rIq=t|t||_q=qtj|ddS )	a  Sobre tipo DataSet.GetXml() con UNA fila por licencia.

    El cliente MIG (General.cs:1046 ValidarEmpresa) busca su `claveproducto`
    en las filas y mira `licenciaactiva`. Si esta False, borra
    ControlFechaTrabajo y hace Application.Exit(). Por eso ESTE metodo es
    el que activa el bloqueo desde el panel admin.

    Cada <Table> mezcla datos de la licencia (claveproducto, licenciaactiva,
    nombreequipo, etc.) con datos de la empresa (nit, razonsocial,
    mensualidad...) para retrocompat con cualquier consumidor que lea esos
    campos. licenciaactiva se serializa como 'True'/'False' porque el
    cliente hace bool.Parse() sobre el valor.
    Nc                 S  s   i | ]\}}|d vr||qS ))claveproductor3   	osversion	EmpresaIDfecharegistrofechaactualizacionr   ).0kr?   r   r   r   
<dictcomp>z   s    z,_licencias_a_dataset_xml.<locals>.<dictcomp>rJ   rK   )
LicenciaIDr^   licenciaactivabloquearlicencialicenciatemporalr3   r_   ra   responsablecorreoresponsabletelefonoponsablemotivolicenciaclavemesiddepartamentoidciudadrL   rM   )	rR   rS   rO   rP   rQ   r#   rT   r%   rU   )		licenciasempresaempresa_extrarW   lrY   rZ   r[   dr   r   r   _licencias_a_dataset_xmlj   s$   

	rv   c                   @  s   e Zd ZdZeeeeeeeeeeeeeddd Zeeeeeeeeeeeeeeeeddd Zeeeeeddd Zeeeeeeeeeeeeeeeeeeeeedd	d
 Z	eeeeeddd Z
eeeeeddd ZdS )LicenciasServicez8Implementa los 6 metodos que el cliente MIG consume hoy.)_returnsc                 C  s  t   }t }z|  t||s-td|d ddtt   | d  	 W d    W dS tjj|d	 }d}|d u rIt|d}t
j| d}||_||_||_||_||_t|	|_t|
|_||_t |_|rqt |_t
j  |rzdnd	}td|d d
|tt   | d  |W  d    W S 1 sw   Y  W d S  ty } z;| $ t
j  td|d dt|d d tt   | d  W d    n1 sw   Y  d| W  Y d }~S d }~ww )NRegistrarEmpresa	AUTH_FAILcredenciales invalidas  r)   FTCREADAACTUALIZADAOKERRORERROR: )timer   app_contextr"   r>   r.   r   query	filter_byfirstr   r8   r9   razonsocialnombrecomercial	direcciontelefonocelularrI   mensualidad
regularizatipotpvr   r7   rb   ra   r:   r;   r<   r#   )ctxr   r   r)   r   r   r   r   r   r   r   r   t0	flask_apprr   creadar+   exr   r   r   ry      sX   







(

z!LicenciasService.RegistrarEmpresac                 C  s  t   }t }z|  t||s-td||ddtt   | d  	 W d    W dS tjj|d	 }|d u }|rJt|t
 d}tj| ||_||_||_||_||_|ret|	|_t|
|_||_||_||_||_t
 |_tj  td||ddtt   | d  	 W d    W dS 1 sw   Y  W d S  ty } z;| $ tj  td||d	t|d d tt   | d  W d    n1 sw   Y  d
| W  Y d }~S d }~ww )NIngresoEmpresarz   r{   r|   r}   )r)   ra   r   
registrador   r   ) r   r   r   r"   r>   r.   r   r   r   r   r   r7   r   r8   r9   r   r   r   r   r   rI   r   r   r   r^   r3   r_   rb   r:   r;   r<   r#   )r   r   r   r)   r   r   r   r   r   r   r   r   r^   r3   r_   r   r   rr   r   r   r   r   r   r      sX   





("

zLicenciasService.IngresoEmpresac                 C  s  ddl m} t }t }z|  t||s3td|dddtt | d  	 W d   W dS tj	
|tjd	tj|ktjdtjdktj }tj
tjtj	
|jj }tj
j|d
 }	t||	}
td|ddt| dtt | d  |
W  d   W S 1 sw   Y  W dS  ty } z2|  td|ddt|dd tt | d  W d   n1 sw   Y  W Y d}~dS d}~ww )zRetorna una fila por licencia distinta (group by claveproducto)
        para que el cliente vea licenciaactiva. Sin esto el bloqueo desde
        el panel admin no llega al cliente.
        r   )funcValidarEmpresaNrz   r!   r|   z<NewDataSet/>max_idr}   r    licencia(s)r   ) 
sqlalchemyr   r   r   r   r"   r>   r.   r   r8   r   maxr   rf   labelfilterr)   r^   isnotgroup_bysubqueryin_cr   allr   r   r   rv   lenr;   r#   )r   r   r   r)   r   r   r   r\   rq   rr   xmlr   r   r   r   r     sX   

	



(
zLicenciasService.ValidarEmpresac                 C  s  t   }t }z|  t||s-td||ddtt   | d  	 W d    W dS tdi d|d|d|d|d	|d
|d|	d|
dt|dt	 d|d|d|d|d|d|d|d|dddd}t
j| t
j  td||d|pdtt   | d  	 W d    W dS 1 sw   Y  W d S  ty } z;| $ t
j  td||dt|d d tt   | d  W d    n1 sw   Y  d| W  Y d }~S d }~ww )NRegistrarLicenciarz   r!   r|   r)   r   r   r   r   r   ro   rp   ri   ra   rj   rk   rl   rm   r^   rn   r3   r_   rg   Trh   Fr   r   r   r   )r   r   r   r"   r>   r.   r   rI   r   r7   r   r8   r9   r:   r;   r<   r#   )r   r   r   r)   r   r   r   r   r   departamentociudadri   rj   rk   rl   rm   r^   rn   r3   r_   r   r   licr   r   r   r   r   4  s   


	

("

z"LicenciasService.RegistrarLicenciac                 C  s  t   }t }z|  t||s/td|d ddtt   | d  	 W d    W dS tjj|d	 }|sUtd|d ddtt   | d  	 W d    W dS |j
sqd|_
tj  td|d dd	tt   | d  tjj|dd
	 }|rtd|d ddtt   | d  	 W d    W dS t d}|jpd|krtd|d dd|j d| tt   | d  	 W d    W dS t d}	t| |	 }
tjj|dtj 	 }|r|
|_d|_tj  td|d dd|	 tt   | d  |
W  d    W S 1 sw   Y  W d S  ty] } z3|  td|d dt|d d tt   | d  W d    n	1 sMw   Y  W Y d }~dS d }~ww )NValidarLicenciaMensualrz   r!   r|   r}   
NO_EMPRESATAUTOFIX_MENSUALzmensualidad False->True)r)   rh   	BLOQUEADAz%Y-%m	NO_PAGADOzperiodopagado=z != z%mr   zmes=r   )r   r   r   r"   r>   r.   r   r   r   r   r   r   r8   r:   r   r   nowstrftimeperiodopagadocryptoencryptorder_byra   descrn   rg   r;   r#   )r   r   r   r)   r   r   rr   	bloqueadaperiodo_actualmmrn   r   r   r   r   r   r   m  s   


%
-
*=
z'LicenciasService.ValidarLicenciaMensualc                 C  s^  t   }t }z`| Q t||s-td|d ddtt   | d  	 W d    W dS tjj|d	ddd}t
j  td|d d	| d
tt   | d  	 W d    W d	S 1 s`w   Y  W d S  ty } z;| $ t
j  td|d dt|d d tt   | d  W d    n1 sw   Y  d| W  Y d }~S d }~ww )NInactivarLicenciarz   r!   r|   r}   FT)rg   rh   r   r   r   r   )r   r   r   r"   r>   r.   r   r   r   updater   r8   r:   r;   r<   r#   )r   r   r   r)   r   r   actualizadasr   r   r   r   r     sB   


(

z"LicenciasService.InactivarLicenciaN)__name__
__module____qualname____doc__r
   r	   ry   r   r   r   r   r   r   r   r   r   rw      s0    
.
3
/

5
Jrw   lxml)	validator)tnsnamein_protocolout_protocolappc                 C  s   | j dddgddd }dS )z'Monta el endpoint SOAP en la app Flask.z/LicenciasService.asmxGETPOST)methodsc                    s   ddl m}  tj}i  d
 fdd	}t||}t|ttfs#d|n|}t|| r.|	  t
 dd d }t|| dg d	S )Nr   )ClosingIteratorc                   s   |  d< | d< dd S )Nstatusr$   c                 S  s   d S Nr   )xr   r   r   <lambda>  s    z[register_soap.<locals>.licencias_service_endpoint.<locals>.start_response.<locals>.<lambda>r   )r   r$   exc_inforesponse_datar   r   start_response  s   zIregister_soap.<locals>.licencias_service_endpoint.<locals>.start_response    r   z200 OKr$   )r   r$   r   )werkzeug.wsgir   r   environ	_wsgi_app
isinstancebytes	bytearrayjoincloser.   r%   splitr   )r   r   r   	body_iterbodystatus_coder   r   r   licencias_service_endpoint  s   


z1register_soap.<locals>.licencias_service_endpointN)route)r   r   r   r   r   register_soap  s   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   
__future__r   osr   xml.etree.ElementTreeetreeElementTreerO   r   typingr   r   r   r   spyner   r   r	   r
   spyne.protocol.soapr   spyne.server.wsgir   werkzeug.wrappersr   r   modelsr   r   r   r   getenvr   r   NSr   r"   r'   r>   rI   r]   rv   rw   
_spyne_appr   r   r   r   r   r   <module>   sH    






-  A