Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1039 lines (949 sloc) 41.4 KB
#!/usr/bin/python
# -*- coding: latin-1 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
"""Módulo para Trazabilidad de Medicamentos ANMAT - PAMI - INSSJP Disp. 3683/11
según Especificación Técnica para Pruebas de Servicios v2 (2013)"""
# Información adicional y documentación:
# http://www.sistemasagiles.com.ar/trac/wiki/TrazabilidadMedicamentos
__author__ = "Mariano Reingart <reingart@gmail.com>"
__copyright__ = "Copyright (C) 2011 Mariano Reingart"
__license__ = "GPL 3.0"
__version__ = "1.16c"
import os
import socket
import sys
import datetime, time
import traceback
import pysimplesoap.client
from pysimplesoap.client import SoapClient, SoapFault, parse_proxy, \
set_http_wrapper
from pysimplesoap.simplexml import SimpleXMLElement
from cStringIO import StringIO
# importo funciones compartidas:
from utils import leer, escribir, leer_dbf, guardar_dbf, N, A, I, json, dar_nombre_campo_dbf, get_install_dir, BaseWS, inicializar_y_capturar_excepciones
HOMO = False
TYPELIB = False
WSDL = "https://servicios.pami.org.ar/trazamed.WebService?wsdl"
LOCATION = "https://servicios.pami.org.ar/trazamed.WebService"
#WSDL = "https://trazabilidad.pami.org.ar:9050/trazamed.WebService?wsdl"
# Formato de MedicamentosDTO, MedicamentosDTODHSerie, MedicamentosDTOFraccion
MEDICAMENTOS = [
('f_evento', 10, A), # formato DD/MM/AAAA
('h_evento', 5, A), # formato HH:MM
('gln_origen', 13, A),
('gln_destino', 13, A),
('n_remito', 20, A),
('n_factura', 20, A),
('vencimiento', 10, A),
('gtin', 14, A),
('lote', 20, A),
('numero_serial', 20, A),
('desde_numero_serial', 20, A), # sendMedicamentosDHSerie
('hasta_numero_serial', 20, A), # sendMedicamentosDHSerie
('id_obra_social', 9, N),
('id_evento', 3, N),
('cuit_origen', 11, A),
('cuit_destino', 11, A),
('apellido', 50, A),
('nombres', 100, A),
('tipo_documento', 2, N), # 96: DNI,80: CUIT
('n_documento', 10, A),
('sexo', 1, A), # M o F
('direccion', 100, A),
('numero', 10, A),
('piso', 5, A),
('depto', 5, A),
('localidad', 50, A),
('provincia', 100, A),
('n_postal', 8, A),
('fecha_nacimiento', 100, A),
('telefono', 30, A),
('nro_asociado', 30, A),
('cantidad', 3, N), # sendMedicamentosFraccion
('codigo_transaccion', 14, A),
]
# Formato para TransaccionPlainWS (getTransaccionesNoConfirmadas)
TRANSACCIONES = [
('_id_transaccion', 14, A),
('_id_transaccion_global', 14, A),
('_f_evento', 10, A),
('_f_transaccion', 16, A), # formato DD/MM/AAAA HH:MM
('_gtin', 14, A),
('_lote', 20, A),
('_numero_serial', 20, A),
('_nombre', 200, A),
('_d_evento', 100, A),
('_gln_origen', 13, A),
('_razon_social_origen', 200, A),
('_gln_destino', 13, A),
('_razon_social_destino', 200, A),
('_n_remito', 20, A),
('_n_factura', 20, A),
('_vencimiento', 10, A),
('_id_evento', 3, N), # agregado el 30/01/2014
]
# Formato para Errores
ERRORES = [
('c_error', 4, A), # código
('d_error', 250, A), # descripción
]
class TrazaMed(BaseWS):
"Interfaz para el WebService de Trazabilidad de Medicamentos ANMAT - PAMI - INSSJP"
_public_methods_ = ['SendMedicamentos',
'SendCancelacTransacc', 'SendCancelacTransaccParcial',
'SendMedicamentosDHSerie',
'SendMedicamentosFraccion',
'SendConfirmaTransacc', 'SendAlertaTransacc',
'GetTransaccionesNoConfirmadas',
'GetEnviosPropiosAlertados', 'GetConsultaStock',
'GetTransaccionesWS', 'GetCatalogoElectronicoByGTIN',
'Conectar', 'LeerError', 'LeerTransaccion',
'SetUsername', 'SetPassword',
'SetParametro', 'GetParametro',
'GetCodigoTransaccion', 'GetResultado', 'LoadTestXML']
_public_attrs_ = [
'Username', 'Password',
'CodigoTransaccion', 'Errores', 'Resultado',
'XmlRequest', 'XmlResponse',
'Version', 'InstallDir',
'Traceback', 'Excepcion', 'LanzarExcepciones',
'CantPaginas', 'HayError', 'TransaccionPlainWS',
]
_reg_progid_ = "TrazaMed"
_reg_clsid_ = "{8472867A-AE6F-487F-8554-C2C896CFFC3E}"
if TYPELIB:
_typelib_guid_ = '{F992EB7E-AFBD-41BB-B717-5693D3A2BADB}'
_typelib_version_ = 1, 4
_com_interfaces_ = ['ITrazaMed']
# Variables globales para BaseWS:
HOMO = HOMO
WSDL = WSDL
Version = "%s %s %s" % (__version__, HOMO and 'Homologación' or '',
pysimplesoap.client.__version__)
def __init__(self, reintentos=1):
self.Username = self.Password = None
self.TransaccionPlainWS = []
BaseWS.__init__(self, reintentos)
def inicializar(self):
BaseWS.inicializar(self)
self.CodigoTransaccion = self.Errores = self.Resultado = None
self.Resultado = ''
self.Errores = [] # lista de strings para la interfaz
self.errores = [] # lista de diccionarios (uso interno)
self.CantPaginas = self.HayError = None
def __analizar_errores(self, ret):
"Comprueba y extrae errores si existen en la respuesta XML"
self.errores = ret.get('errores', [])
self.Errores = ["%s: %s" % (it['_c_error'], it['_d_error'])
for it in ret.get('errores', [])]
self.Resultado = ret.get('resultado')
def Conectar(self, cache=None, wsdl=None, proxy="", wrapper=None, cacert=None, timeout=30):
# Conecto usando el método estandard:
ok = BaseWS.Conectar(self, cache, wsdl, proxy, wrapper, cacert, timeout,
soap_server="jetty")
if ok:
# si el archivo es local, asumo que ya esta corregido:
if not self.wsdl.startswith("file"):
# corrijo ubicación del servidor (localhost:9050 en el WSDL)
location = self.wsdl[:-5]
if 'IWebServiceService' in self.client.services:
ws = self.client.services['IWebServiceService'] # version 1
else:
ws = self.client.services['IWebService'] # version 2
ws['ports']['IWebServicePort']['location'] = location
# Establecer credenciales de seguridad:
self.client['wsse:Security'] = {
'wsse:UsernameToken': {
'wsse:Username': self.Username,
'wsse:Password': self.Password,
}
}
return ok
@inicializar_y_capturar_excepciones
def SendMedicamentos(self, usuario, password,
f_evento, h_evento, gln_origen, gln_destino,
n_remito, n_factura, vencimiento, gtin, lote,
numero_serial, id_obra_social, id_evento,
cuit_origen='', cuit_destino='', apellido='', nombres='',
tipo_documento='', n_documento='', sexo='',
direccion='', numero='', piso='', depto='', localidad='', provincia='',
n_postal='', fecha_nacimiento='', telefono='',
nro_asociado=None,
):
"Realiza el registro de una transacción de medicamentos. "
# creo los parámetros para esta llamada
params = { 'f_evento': f_evento,
'h_evento': h_evento,
'gln_origen': gln_origen,
'gln_destino': gln_destino,
'n_remito': n_remito,
'n_factura': n_factura,
'vencimiento': vencimiento,
'gtin': gtin,
'lote': lote,
'numero_serial': numero_serial,
'id_obra_social': id_obra_social or None,
'id_evento': id_evento,
'cuit_origen': cuit_origen,
'cuit_destino': cuit_destino,
'apellido': apellido,
'nombres': nombres,
'tipo_documento': tipo_documento,
'n_documento': n_documento,
'sexo': sexo,
'direccion': direccion,
'numero': numero,
'piso': piso,
'depto': depto,
'localidad': localidad,
'provincia': provincia,
'n_postal': n_postal,
'fecha_nacimiento': fecha_nacimiento,
'telefono': telefono,
'nro_asociado': nro_asociado,
}
res = self.client.sendMedicamentos(
arg0=params,
arg1=usuario,
arg2=password,
)
ret = res['return']
self.CodigoTransaccion = ret['codigoTransaccion']
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def SendMedicamentosFraccion(self, usuario, password,
f_evento, h_evento, gln_origen, gln_destino,
n_remito, n_factura, vencimiento, gtin, lote,
numero_serial, id_obra_social, id_evento,
cuit_origen='', cuit_destino='', apellido='', nombres='',
tipo_documento='', n_documento='', sexo='',
direccion='', numero='', piso='', depto='', localidad='', provincia='',
n_postal='', fecha_nacimiento='', telefono='',
nro_asociado=None, cantidad=None,
):
"Realiza el registro de una transacción de medicamentos fraccionados"
# creo los parámetros para esta llamada
params = { 'f_evento': f_evento,
'h_evento': h_evento,
'gln_origen': gln_origen,
'gln_destino': gln_destino,
'n_remito': n_remito,
'n_factura': n_factura,
'vencimiento': vencimiento,
'gtin': gtin,
'lote': lote,
'numero_serial': numero_serial,
'id_obra_social': id_obra_social or None,
'id_evento': id_evento,
'cuit_origen': cuit_origen,
'cuit_destino': cuit_destino,
'apellido': apellido,
'nombres': nombres,
'tipo_documento': tipo_documento,
'n_documento': n_documento,
'sexo': sexo,
'direccion': direccion,
'numero': numero,
'piso': piso,
'depto': depto,
'localidad': localidad,
'provincia': provincia,
'n_postal': n_postal,
'fecha_nacimiento': fecha_nacimiento,
'telefono': telefono,
'nro_asociado': nro_asociado,
'cantidad': cantidad,
}
res = self.client.sendMedicamentosFraccion(
arg0=params,
arg1=usuario,
arg2=password,
)
ret = res['return']
self.CodigoTransaccion = ret['codigoTransaccion']
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def SendMedicamentosDHSerie(self, usuario, password,
f_evento, h_evento, gln_origen, gln_destino,
n_remito, n_factura, vencimiento, gtin, lote,
desde_numero_serial, hasta_numero_serial,
id_obra_social, id_evento,
cuit_origen='', cuit_destino='', apellido='', nombres='',
tipo_documento='', n_documento='', sexo='',
direccion='', numero='', piso='', depto='', localidad='', provincia='',
n_postal='', fecha_nacimiento='', telefono='',
nro_asociado=None,
):
"Envía un lote de medicamentos informando el desde-hasta número de serie"
# creo los parámetros para esta llamada
params = { 'f_evento': f_evento,
'h_evento': h_evento,
'gln_origen': gln_origen,
'gln_destino': gln_destino,
'n_remito': n_remito,
'n_factura': n_factura,
'vencimiento': vencimiento,
'gtin': gtin,
'lote': lote,
'desde_numero_serial': desde_numero_serial,
'hasta_numero_serial': hasta_numero_serial,
'id_obra_social': id_obra_social or None,
'id_evento': id_evento,
'cuit_origen': cuit_origen,
'cuit_destino': cuit_destino,
'apellido': apellido,
'nombres': nombres,
'tipo_documento': tipo_documento,
'n_documento': n_documento,
'sexo': sexo,
'direccion': direccion,
'numero': numero,
'piso': piso,
'depto': depto,
'localidad': localidad,
'provincia': provincia,
'n_postal': n_postal,
'fecha_nacimiento': fecha_nacimiento,
'telefono': telefono,
'nro_asociado': nro_asociado,
}
res = self.client.sendMedicamentosDHSerie(
arg0=params,
arg1=usuario,
arg2=password,
)
ret = res['return']
self.CodigoTransaccion = ret['codigoTransaccion']
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def SendCancelacTransacc(self, usuario, password, codigo_transaccion):
" Realiza la cancelación de una transacción"
res = self.client.sendCancelacTransacc(
arg0=codigo_transaccion,
arg1=usuario,
arg2=password,
)
ret = res['return']
self.CodigoTransaccion = ret.get('codigoTransaccion')
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def SendCancelacTransaccParcial(self, usuario, password, codigo_transaccion,
gtin_medicamento=None, numero_serial=None):
" Realiza la cancelación parcial de una transacción"
res = self.client.sendCancelacTransaccParcial(
arg0=codigo_transaccion,
arg1=usuario,
arg2=password,
arg3=gtin_medicamento,
arg4=numero_serial,
)
ret = res['return']
self.CodigoTransaccion = ret.get('codigoTransaccion')
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def SendConfirmaTransacc(self, usuario, password, p_ids_transac, f_operacion):
"Confirma la recepción de un medicamento"
res = self.client.sendConfirmaTransacc(
arg0=usuario,
arg1=password,
arg2={'p_ids_transac': p_ids_transac, 'f_operacion': f_operacion},
)
ret = res['return']
self.CodigoTransaccion = ret.get('id_transac_asociada')
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def SendAlertaTransacc(self, usuario, password, p_ids_transac_ws):
"Alerta un medicamento, acción contraria a “confirmar la transacción”."
res = self.client.sendAlertaTransacc(
arg0=usuario,
arg1=password,
arg2=p_ids_transac_ws,
)
ret = res['return']
self.CodigoTransaccion = ret.get('id_transac_asociada')
self.__analizar_errores(ret)
return True
@inicializar_y_capturar_excepciones
def GetTransaccionesNoConfirmadas(self, usuario, password,
p_id_transaccion_global=None, id_agente_informador=None,
id_agente_origen=None, id_agente_destino=None,
id_medicamento=None, id_evento=None,
fecha_desde_op=None, fecha_hasta_op=None,
fecha_desde_t=None, fecha_hasta_t=None,
fecha_desde_v=None, fecha_hasta_v=None,
n_remito=None, n_factura=None,
estado=None, lote=None, numero_serial=None,
):
"Trae un listado de las transacciones que no están confirmadas"
# preparo los parametros de entrada opcionales:
kwargs = {}
if p_id_transaccion_global is not None:
kwargs['arg2'] = p_id_transaccion_global
if id_agente_informador is not None:
kwargs['arg3'] = id_agente_informador
if id_agente_origen is not None:
kwargs['arg4'] = id_agente_origen
if id_agente_destino is not None:
kwargs['arg5'] = id_agente_destino
if id_medicamento is not None:
kwargs['arg6'] = id_medicamento
if id_evento is not None:
kwargs['arg7'] = id_evento
if fecha_desde_op is not None:
kwargs['arg8'] = fecha_desde_op
if fecha_hasta_op is not None:
kwargs['arg9'] = fecha_hasta_op
if fecha_desde_t is not None:
kwargs['arg10'] = fecha_desde_t
if fecha_hasta_t is not None:
kwargs['arg11'] = fecha_hasta_t
if fecha_desde_v is not None:
kwargs['arg12'] = fecha_desde_v
if fecha_hasta_v is not None:
kwargs['arg13'] = fecha_hasta_v
if n_remito is not None:
kwargs['arg14'] = n_remito
if n_factura is not None:
kwargs['arg15'] = n_factura
if estado is not None:
kwargs['arg16'] = estado
if lote is not None:
kwargs['arg17'] = lote
if numero_serial is not None:
kwargs['arg18'] = numero_serial
# llamo al webservice
res = self.client.getTransaccionesNoConfirmadas(
arg0=usuario,
arg1=password,
**kwargs
)
ret = res['return']
if ret:
self.__analizar_errores(ret)
self.CantPaginas = ret.get('cantPaginas')
self.HayError = ret.get('hay_error')
self.TransaccionPlainWS = [it for it in ret.get('list', [])]
return True
def LeerTransaccion(self):
"Recorro TransaccionPlainWS devuelto por GetTransaccionesNoConfirmadas"
# usar GetParametro para consultar el valor retornado por el webservice
if self.TransaccionPlainWS:
# extraigo el primer item
self.params_out = self.TransaccionPlainWS.pop(0)
return True
else:
# limpio los parámetros
self.params_out = {}
return False
def LeerError(self):
"Recorro los errores devueltos y devuelvo el primero si existe"
if self.Errores:
# extraigo el primer item
er = self.Errores.pop(0)
return er
else:
return ""
@inicializar_y_capturar_excepciones
def GetEnviosPropiosAlertados(self, usuario, password,
p_id_transaccion_global=None, id_agente_informador=None,
id_agente_origen=None, id_agente_destino=None,
id_medicamento=None, id_evento=None,
fecha_desde_op=None, fecha_hasta_op=None,
fecha_desde_t=None, fecha_hasta_t=None,
fecha_desde_v=None, fecha_hasta_v=None,
n_remito=None, n_factura=None,
):
"Obtiene las distribuciones y envíos propios que han sido alertados"
# preparo los parametros de entrada opcionales:
kwargs = {}
if p_id_transaccion_global is not None:
kwargs['arg2'] = p_id_transaccion_global
if id_agente_informador is not None:
kwargs['arg3'] = id_agente_informador
if id_agente_origen is not None:
kwargs['arg4'] = id_agente_origen
if id_agente_destino is not None:
kwargs['arg5'] = id_agente_destino
if id_medicamento is not None:
kwargs['arg6'] = id_medicamento
if id_evento is not None:
kwargs['arg7'] = id_evento
if fecha_desde_op is not None:
kwargs['arg8'] = fecha_desde_op
if fecha_hasta_op is not None:
kwargs['arg9'] = fecha_hasta_op
if fecha_desde_t is not None:
kwargs['arg10'] = fecha_desde_t
if fecha_hasta_t is not None:
kwargs['arg11'] = fecha_hasta_t
if fecha_desde_v is not None:
kwargs['arg12'] = fecha_desde_v
if fecha_hasta_v is not None:
kwargs['arg13'] = fecha_hasta_v
if n_remito is not None:
kwargs['arg14'] = n_remito
if n_factura is not None:
kwargs['arg15'] = n_factura
# llamo al webservice
res = self.client.getEnviosPropiosAlertados(
arg0=usuario,
arg1=password,
**kwargs
)
ret = res['return']
if ret:
self.__analizar_errores(ret)
self.CantPaginas = ret.get('cantPaginas')
self.HayError = ret.get('hay_error')
self.TransaccionPlainWS = [it for it in ret.get('list', [])]
return True
@inicializar_y_capturar_excepciones
def GetTransaccionesWS(self, usuario, password,
p_id_transaccion_global=None,
id_agente_origen=None, id_agente_destino=None,
id_medicamento=None, id_evento=None,
fecha_desde_op=None, fecha_hasta_op=None,
fecha_desde_t=None, fecha_hasta_t=None,
fecha_desde_v=None, fecha_hasta_v=None,
n_remito=None, n_factura=None,
id_estado=None, nro_pag=None,
):
"Obtiene los movimientos realizados y permite filtros de búsqueda"
# preparo los parametros de entrada opcionales:
kwargs = {}
if p_id_transaccion_global is not None:
kwargs['arg2'] = p_id_transaccion_global
if id_agente_origen is not None:
kwargs['arg3'] = id_agente_origen
if id_agente_destino is not None:
kwargs['arg4'] = id_agente_destino
if id_medicamento is not None:
kwargs['arg5'] = id_medicamento
if id_evento is not None:
kwargs['arg6'] = id_evento
if fecha_desde_op is not None:
kwargs['arg7'] = fecha_desde_op
if fecha_hasta_op is not None:
kwargs['arg8'] = fecha_hasta_op
if fecha_desde_t is not None:
kwargs['arg9'] = fecha_desde_t
if fecha_hasta_t is not None:
kwargs['arg10'] = fecha_hasta_t
if fecha_desde_v is not None:
kwargs['arg11'] = fecha_desde_v
if fecha_hasta_v is not None:
kwargs['arg12'] = fecha_hasta_v
if n_remito is not None:
kwargs['arg13'] = n_remito
if n_factura is not None:
kwargs['arg14'] = n_factura
if id_estado is not None:
kwargs['arg15'] = id_estado
if nro_pag is not None:
kwargs['arg16'] = nro_pag
# llamo al webservice
res = self.client.getTransaccionesWS(
arg0=usuario,
arg1=password,
**kwargs
)
ret = res['return']
if ret:
self.__analizar_errores(ret)
self.CantPaginas = ret.get('cantPaginas')
self.HayError = ret.get('hay_error')
self.TransaccionPlainWS = [it for it in ret.get('list', [])]
return True
@inicializar_y_capturar_excepciones
def GetCatalogoElectronicoByGTIN(self, usuario, password,
cuit_fabricante=None, gtin=None, descripcion=None,
id_monodroga=None,
):
"Obtiene el Catálogo Electrónico de Medicamentos"
# preparo los parametros de entrada opcionales:
kwargs = {}
if cuit_fabricante is not None:
kwargs['arg2'] = cuit_fabricante
if gtin is not None:
kwargs['arg3'] = gtin
if descripcion is not None:
kwargs['arg4'] = descripcion
if id_monodroga is not None:
kwargs['arg5'] = id_monodroga
# llamo al webservice
res = self.client.getCatalogoElectronicoByGTIN(
arg0=usuario,
arg1=password,
**kwargs
)
ret = res['return']
if ret:
self.__analizar_errores(ret)
self.CantPaginas = ret.get('cantPaginas')
self.HayError = ret.get('hay_error')
self.params_out = dict([(i, it) for i, it
in enumerate(ret.get('list', []))])
return len(self.params_out)
else:
return 0
@inicializar_y_capturar_excepciones
def GetConsultaStock(self, usuario, password,
id_medicamento=None, id_agente=None, descripcion=None,
cantidad=None, presentacion=None,
lote=None, numero_serial=None,
nro_pag=1, cant_reg=100,
):
"Permite consultar el stock actual del agente."
# preparo los parametros de entrada opcionales:
kwargs = {}
if id_medicamento is not None:
kwargs['arg2'] = id_medicamento
if id_agente is not None:
kwargs['arg3'] = id_agente
if descripcion is not None:
kwargs['arg4'] = descripcion
if cantidad is not None:
kwargs['arg5'] = cantidad
if presentacion is not None:
kwargs['arg6'] = presentacion
if lote is not None:
kwargs['arg7'] = lote
if numero_serial is not None:
kwargs['arg8'] = numero_serial
if nro_pag is not None:
kwargs['arg9'] = nro_pag
if cant_reg is not None:
kwargs['arg10'] = cant_reg
# llamo al webservice
res = self.client.getConsultaStock(
arg0=usuario,
arg1=password,
**kwargs
)
ret = res['return']
if ret:
self.__analizar_errores(ret)
self.CantPaginas = ret.get('cantPaginas')
self.HayError = ret.get('hay_error')
self.params_out = dict([(i, it) for i, it
in enumerate(ret.get('list', []))])
return len(self.params_out)
else:
return 0
def SetUsername(self, username):
"Establezco el nombre de usuario"
self.Username = username
def SetPassword(self, password):
"Establezco la contraseña"
self.Password = password
def GetCodigoTransaccion(self):
"Devuelvo el código de transacción"
return self.CodigoTransaccion
def GetResultado(self):
"Devuelvo el resultado"
return self.Resultado
def main():
"Función principal de pruebas (obtener CAE)"
import os, time, sys
global WSDL, LOCATION
DEBUG = '--debug' in sys.argv
ws = TrazaMed()
ws.Username = 'testwservice'
ws.Password = 'testwservicepsw'
if '--prod' in sys.argv and not HOMO:
WSDL = "https://trazabilidad.pami.org.ar:9050/trazamed.WebService"
print "Usando WSDL:", WSDL
sys.argv.pop(sys.argv.index("--prod"))
# Inicializo las variables y estructuras para el archivo de intercambio:
medicamentos = []
transacciones = []
errores = []
formatos = [('Medicamentos', MEDICAMENTOS, medicamentos),
('Transacciones', TRANSACCIONES, transacciones),
('Errores', ERRORES, errores),
]
if '--formato' in sys.argv:
print "Formato:"
for msg, formato, lista in formatos:
comienzo = 1
print "=== %s ===" % msg
print "|| %-25s || %-12s || %-5s || %-4s || %-10s ||" % (
"Nombre", "Tipo", "Long.", "Pos(txt)", "Campo(dbf)")
claves = []
for fmt in formato:
clave, longitud, tipo = fmt[0:3]
clave_dbf = dar_nombre_campo_dbf(clave, claves)
claves.append(clave_dbf)
print "|| %-25s || %-12s || %5d || %4d || %-10s ||" % (
clave, tipo, longitud, comienzo, clave_dbf)
comienzo += longitud
sys.exit(0)
if '--cargar' in sys.argv:
if '--dbf' in sys.argv:
leer_dbf(formatos[:1], {})
elif '--json' in sys.argv:
for formato in formatos[:1]:
archivo = open(formato[0].lower() + ".json", "r")
d = json.load(archivo)
formato[2].extend(d)
archivo.close()
else:
for formato, campos, lista in formatos[:1]:
archivo = open(formato.lower() + ".txt", "r")
for linea in archivo:
d = leer(linea, campos)
lista.append(d)
archivo.close()
if DEBUG:
for campo in campos:
print campo[0], "=", lista[0][campo[0]]
ws.Conectar("", WSDL)
if ws.Excepcion:
print ws.Excepcion
print ws.Traceback
sys.exit(-1)
# Datos de pruebas:
if '--test' in sys.argv:
medicamentos.append(dict(
f_evento=datetime.datetime.now().strftime("%d/%m/%Y"),
h_evento=datetime.datetime.now().strftime("%H:%M"),
gln_origen="9999999999918", gln_destino="glnws",
n_remito="R000100001234", n_factura="A000100001234",
vencimiento=(datetime.datetime.now()+datetime.timedelta(30)).strftime("%d/%m/%Y"),
gtin="GTIN1", lote=datetime.datetime.now().strftime("%Y"),
numero_serial=int(time.time()*10),
id_obra_social=None, id_evento=134,
cuit_origen="20267565393", cuit_destino="20267565393",
apellido="Reingart", nombres="Mariano",
tipo_documento="96", n_documento="26756539", sexo="M",
direccion="Saraza", numero="1234", piso="", depto="",
localidad="Hurlingham", provincia="Buenos Aires",
n_postal="1688", fecha_nacimiento="01/01/2000",
telefono="5555-5555",
nro_asociado="9999999999999",
cantidad=None,
desde_numero_serial=None, hasta_numero_serial=None,
codigo_transaccion=None,
))
if '--testfraccion' in sys.argv:
medicamentos.append(dict(
f_evento=datetime.datetime.now().strftime("%d/%m/%Y"),
h_evento=datetime.datetime.now().strftime("%H:%M"),
gln_origen="9999999999918", gln_destino="glnws",
n_remito="1234", n_factura="1234",
vencimiento=(datetime.datetime.now()+datetime.timedelta(30)).strftime("%d/%m/%Y"),
gtin="GTIN1", lote=datetime.datetime.now().strftime("%Y"),
numero_serial=int(time.time()*10),
id_obra_social=None, id_evento=134,
cuit_origen="20267565393", cuit_destino="20267565393",
apellido="Reingart", nombres="Mariano",
tipo_documento="96", n_documento="26756539", sexo="M",
direccion="Saraza", numero="1234", piso="", depto="",
localidad="Hurlingham", provincia="Buenos Aires",
n_postal="1688", fecha_nacimiento="01/01/2000",
telefono="5555-5555",
nro_asociado="9999999999999",
cantidad=5,
desde_numero_serial=None, hasta_numero_serial=None,
codigo_transaccion=None,
))
if '--testdh' in sys.argv:
medicamentos.append(dict(
f_evento=datetime.datetime.now().strftime("%d/%m/%Y"),
h_evento=datetime.datetime.now().strftime("%H:%M"),
gln_origen="9999999999918", gln_destino="glnws",
n_remito="1234", n_factura="1234",
vencimiento=(datetime.datetime.now()+datetime.timedelta(30)).strftime("%d/%m/%Y"),
gtin="GTIN1", lote=datetime.datetime.now().strftime("%Y"),
desde_numero_serial=int(time.time()*10)-1,
hasta_numero_serial=int(time.time()*10)+1,
id_obra_social=None, id_evento=134,
nro_asociado="1234",
cantidad=None, numero_serial=None,
codigo_transaccion=None,
))
# Opciones principales:
if '--cancela' in sys.argv:
if '--loadxml' in sys.argv:
ws.LoadTestXML("trazamed_cancela_err.xml") # cargo respuesta
ws.SendCancelacTransacc(*sys.argv[sys.argv.index("--cancela")+1:])
elif '--cancela_parcial' in sys.argv:
ws.SendCancelacTransaccParcial(*sys.argv[sys.argv.index("--cancela_parcial")+1:])
elif '--confirma' in sys.argv:
if '--loadxml' in sys.argv:
ws.LoadTestXML("trazamed_confirma.xml") # cargo respuesta
ok = ws.SendConfirmaTransacc(usuario="pruebasws", password="pruebasws",
p_ids_transac="1", f_operacion="31-12-2013")
if not ok:
raise RuntimeError(ws.Excepcion)
ws.SendConfirmaTransacc(*sys.argv[sys.argv.index("--confirma")+1:])
elif '--alerta' in sys.argv:
ws.SendAlertaTransacc(*sys.argv[sys.argv.index("--alerta")+1:])
elif '--consulta' in sys.argv:
if '--alertados' in sys.argv:
ws.GetEnviosPropiosAlertados(
*sys.argv[sys.argv.index("--alertados")+1:]
)
elif '--movimientos' in sys.argv:
ws.GetTransaccionesWS(
*sys.argv[sys.argv.index("--movimientos")+1:]
)
else:
ws.GetTransaccionesNoConfirmadas(
*sys.argv[sys.argv.index("--consulta")+1:]
#usuario="pruebasws", password="pruebasws",
#p_id_transaccion_global="1234",
#id_agente_informador="1",
#id_agente_origen="1",
#id_agente_destino="1",
#id_medicamento="1",
#id_evento="1",
#fecha_desde_op="01/01/2015",
#fecha_hasta_op="31/12/2013",
#fecha_desde_t="01/01/2013",
#fecha_hasta_t="31/12/2013",
#fecha_desde_v="01/04/2013",
#fecha_hasta_v="30/04/2013",
#n_factura=5, n_remito=6,
#estado=1,
#lote=88745,
#numero_serial=894124788,
)
print "CantPaginas", ws.CantPaginas
print "HayError", ws.HayError
#print "TransaccionPlainWS", ws.TransaccionPlainWS
# parametros comunes de salida (columnas de la tabla):
claves = [k for k, v, l in TRANSACCIONES]
# extiendo la lista de resultado para el archivo de intercambio:
transacciones.extend(ws.TransaccionPlainWS)
# encabezado de la tabla:
print "||", "||".join(["%s" % clave for clave in claves]), "||"
# recorro los datos devueltos (TransaccionPlainWS):
while ws.LeerTransaccion():
for clave in claves:
print "||", ws.GetParametro(clave), # imprimo cada fila
print "||"
elif '--catalogo' in sys.argv:
ret = ws.GetCatalogoElectronicoByGTIN(
*sys.argv[sys.argv.index("--catalogo")+1:]
)
for catalogo in ws.params_out.values():
print catalogo # imprimo cada fila
elif '--stock' in sys.argv:
ret = ws.GetConsultaStock(
*sys.argv[sys.argv.index("--stock")+1:]
)
print "\n".join([str(s) for s in ws.params_out.values()])
else:
argv = [argv for argv in sys.argv if not argv.startswith("--")]
if not medicamentos:
if len(argv)>16:
if '--dh' in sys.argv:
ws.SendMedicamentosDHSerie(*argv[1:])
elif '--fraccion' in sys.argv:
ws.SendMedicamentosFraccion(*argv[1:])
else:
ws.SendMedicamentos(*argv[1:])
else:
print "ERROR: no se indicaron todos los parámetros requeridos"
elif medicamentos:
try:
usuario, password = argv[1:3]
except:
print "ADVERTENCIA: no se indico parámetros usuario y passoword"
usuario = password = "pruebasws"
for i, med in enumerate(medicamentos):
print "Procesando registro", i
del med['codigo_transaccion']
if med.get("cantidad"):
del med["desde_numero_serial"]
del med["hasta_numero_serial"]
ws.SendMedicamentosFraccion(usuario, password, **med)
elif med.get("desde_numero_serial"):
del med["cantidad"]
del med["numero_serial"]
ws.SendMedicamentosDHSerie(usuario, password, **med)
else:
del med["cantidad"]
del med["desde_numero_serial"]
del med["hasta_numero_serial"]
ws.SendMedicamentos(usuario, password, **med)
med['codigo_transaccion'] = ws.CodigoTransaccion
errores.extend(ws.errores)
print "|Resultado %5s|CodigoTransaccion %10s|Errores|%s|" % (
ws.Resultado,
ws.CodigoTransaccion,
'|'.join(ws.Errores or []),
)
else:
print "ERROR: no se especificaron medicamentos a informar"
if not medicamentos:
print "|Resultado %5s|CodigoTransaccion %10s|Errores|%s|" % (
ws.Resultado,
ws.CodigoTransaccion,
'|'.join(ws.Errores or []),
)
if ws.Excepcion:
print ws.Traceback
if '--grabar' in sys.argv:
if '--dbf' in sys.argv:
guardar_dbf(formatos, True, {})
elif '--json' in sys.argv:
for formato in formatos:
archivo = open(formato[0].lower() + ".json", "w")
json.dump(formato[2], archivo, sort_keys=True, indent=4)
archivo.close()
else:
for formato, campos, lista in formatos:
archivo = open(formato.lower() + ".txt", "w")
for it in lista:
archivo.write(escribir(it, campos))
archivo.close()
# busco el directorio de instalación (global para que no cambie si usan otra dll)
INSTALL_DIR = TrazaMed.InstallDir = get_install_dir()
if __name__ == '__main__':
# ajusto el encoding por defecto (si se redirije la salida)
if not hasattr(sys.stdout, "encoding") or sys.stdout.encoding is None:
import codecs, locale
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout,"replace");
sys.stderr = codecs.getwriter(locale.getpreferredencoding())(sys.stderr,"replace");
if '--register' in sys.argv or '--unregister' in sys.argv:
import pythoncom
if TYPELIB:
if '--register' in sys.argv:
tlb = os.path.abspath(os.path.join(INSTALL_DIR, "typelib", "trazamed.tlb"))
print "Registering %s" % (tlb,)
tli=pythoncom.LoadTypeLib(tlb)
pythoncom.RegisterTypeLib(tli, tlb)
elif '--unregister' in sys.argv:
k = TrazaMed
pythoncom.UnRegisterTypeLib(k._typelib_guid_,
k._typelib_version_[0],
k._typelib_version_[1],
0,
pythoncom.SYS_WIN32)
print "Unregistered typelib"
import win32com.server.register
win32com.server.register.UseCommandLine(TrazaMed)
elif "/Automate" in sys.argv:
# MS seems to like /automate to run the class factories.
import win32com.server.localserver
#win32com.server.localserver.main()
# start the server.
win32com.server.localserver.serve([TrazaMed._reg_clsid_])
else:
main()