o
    j7                     @  s   d Z ddlmZ ddl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mZmZ ddlmZ dZd$ddZd%ddZd&ddZG dd deZd'dd Zd(d"d#Z dS ))a  
SOAP service para gestion de solicitudes de licencia.

Endpoints (montados en /SolicitudesService.asmx):
  - RegistrarSolicitud      -> crea fila Solicitudes(Estado='Pendiente')
  - ConsultarEstadoSolicitud-> retorna estado actual para polling del cliente MIG

El cliente MIG genera Web Reference contra ?wsdl y consume estos metodos.
Las credenciales SOAP heredadas son admin/123*/ (igual que el panel viejo).
    )annotationsN)datetime)Optional)Flaskrequest)ApplicationServiceBaseUnicoderpc)Soap11)WsgiApplication)Response)	Solicituddb)Configz-http://migsistemas.com/licencias/solicitudes/returnr   c                  C  s   ddl m}  |  S )Nr   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 jko|p
dt jkS )N )r   	SOAP_USERSOAP_PASSWORD)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_cliente*   s   r%   c                   @  sf   e Zd ZdZe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eeddd ZdS )SolicitudesServicez#Endpoints expuestos al cliente MIG.)_returnsc                 C  sf  t ||sdS t }|  zptdi d|pdd|d|d|d|d|d	|	d
|
d|d|d|d|d|p=d  d|pFdd|d|d|d|pTd  dt dddt }t	j
| t	j
  d|j W W  d   S  ty } zt	j
  dt|j d| W  Y d}~W  d   S d}~ww 1 sw   Y  dS ) zCrea una solicitud nueva en estado Pendiente.

        Retorna:
          OK|<SolicitudID>   -> al cliente para que sepa que ID polling
          ERROR|<mensaje>    -> si algo fallo
        zERROR|Credenciales invalidasNITr   NombreEmpresaNombreComercial	DireccionTelefonoCelularDepartamentoCiudadResponsableTelefonoResponsableCorreoResponsableMotivoLicenciaTemporalNOClaveProductoClaveMesNombreEquipo	OSVersionModuloMIGFechaSolicitudEstado	Pendiente	IpClientezOK|NERROR|: r   )r    r   app_contextr   upperstripr   utcnowr%   r   sessionaddcommitSolicitudID	Exceptionrollbacktype__name__)ctxr   r   nitrazonsocialnombrecomercial	direcciontelefonocelulardepartamentociudadlicenciatemporalresponsablecorreoresponsabletelefonoresponsablemotivoclaveproductoclavemesnombreequipo	osversionmoduloapp	solicituder   r   r   RegistrarSolicitud6   sz   

	


 z%SolicitudesService.RegistrarSolicitudc                 C  sD  t ||sdS t }|  zctjtj|pdktj|pdktj|p$dk	tj
 }| }|du r>W W d   dS |jrG|jdnd}	|jpMddd}
|jr[|jdnd}|j d|	 d|
 d| W W  d   S  ty } zdt|j d	| d
W  Y d}~W  d   S d}~ww 1 sw   Y  dS )a  Para polling desde el cliente MIG mientras espera aprobacion.

        Busca la solicitud mas reciente del (nit, claveproducto, nombreequipo)
        y retorna el estado actual.

        Formato de respuesta (separador pipe):
            <Estado>|<FechaResolucion>|<Observaciones>|<FechaVencimiento>

        Estados posibles: Pendiente | Aprobada | Rechazada | NoEncontrada | ERROR
        zERROR|Credenciales invalidas|||r   NzNoEncontrada|||z%Y-%m-%d %H:%M:%S| r@   rA   z|||)r    r   rB   r   queryfilterr(   r8   r6   order_byrI   descfirstFechaResolucionstrftimeObservacionesreplaceFechaVencimientor=   rJ   rL   rM   )rN   r   r   rO   r\   r^   ra   qrb   	fecha_resobs
fecha_vencrc   r   r   r   ConsultarEstadoSolicitudu   sB   

"z+SolicitudesService.ConsultarEstadoSolicitudN)rM   
__module____qualname____doc__r
   r	   rd   ru   r   r   r   r   r&   3   s&    

5r&   ra   Nonec                   sD   t tgttddt d}t| | jdddgd fdd	}d
S )zMonta el endpoint SOAP en /SolicitudesService.asmx.

    Soporta:
      GET  ?wsdl  -> sirve el WSDL para wsdl.exe / svcutil
      POST        -> procesa sobres SOAP
    lxml)	validator)servicestnsin_protocolout_protocolz/SolicitudesService.asmxGETPOST)methodsc                    sB   t jdkrt jdd urtt j} d| d< t|  S tt j S )Nr   wsdlQUERY_STRING)r   methodargsr#   dictenviron
_wsgi_pass)r   	wsgi_soapr   r   solicitudes_asmx   s
   

z'register_soap.<locals>.solicitudes_asmxN)r   r&   NSr   r   route)ra   	spyne_appr   r   r   r   register_soap   s   r   r   c                   s^   dg d d fdd	}d || |} d r$t d dd	d
 nd}t|| d dS )zCAdapta la respuesta WSGI de Spyne para que Flask la pueda devolver.r   )statusr"   Nc                   s   |  d< | d< dd S )Nr   r"   c                 S  s   d S Nr   )xr   r   r   <lambda>   s    z4_wsgi_pass.<locals>.start_response.<locals>.<lambda>r   )r   r"   exc_infoholderr   r   start_response   s   z"_wsgi_pass.<locals>.start_response    r   rf      r      r"   r   )joinintsplitr   )r   r   r   bodystatus_coder   r   r   r      s
   
$r   )r   r   )r   r   r   r   r   r   )r   r!   )ra   r   r   ry   )r   r   )!rx   
__future__r   osr   typingr   r   r   r   spyner   r   r	   r
   spyne.protocol.soapr   spyne.server.wsgir   werkzeug.wrappersr   modelsr   r   configr   r   r   r    r%   r&   r   r   r   r   r   r   <module>   s&    



	
u