Consulta una liquidación por No de Comprobante o CAE
966634
def ConsultarLiquidacion(self, tipo_cbte=None, pto_vta=None, nro_cbte=None,
                                   cae=None, cuit_comprador=None, pdf="liq.pdf"):
        ""
        if cae:
            ret = self.client.consultarLiquidacionPorCae(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        solicitud={
                            'cae': cae,
                            'pdf': pdf and True or False,
                            },
                        )
        else:
            ret = self.client.consultarLiquidacionPorNroComprobante(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        solicitud={
                            'cuitComprador': cuit_comprador,
                            'puntoVenta': pto_vta,
                            'nroComprobante': nro_cbte,
                            'tipoComprobante': tipo_cbte,
                            'pdf': pdf and True or False,
                            },
                        )
        ret = ret['respuesta']
        self.__analizar_errores(ret)
        if 'liquidacion' in ret:
            liqs = ret.get('liquidacion', [])
            liq = liqs[0] if liqs else None
            self.AnalizarLiquidacion(liq)
            # guardo el PDF si se indico archivo y vino en la respuesta:
            if pdf and 'pdf' in liq:
                open(pdf, "wb").write(liq['pdf'])
        return True
740529
def AutorizarAnticipo(self):
        ""

        # extraer y adaptar los campos para el anticipo
        anticipo = {"liquidacion": self.liquidacion}
        liq = anticipo["liquidacion"] 
        liq["campaniaPpal"] = self.liquidacion["campaniaPPal"]
        liq["codLocProcedencia"] = self.liquidacion["codLocalidadProcedencia"]
        liq["descPuertoLocalidad"] = self.liquidacion["desPuertoLocalidad"]
        
        if self.opcionales:
            liq['opcionales'] = self.opcionales

        if self.retenciones:
            anticipo['retenciones'] = self.retenciones

        if self.deducciones:
            anticipo['deducciones'] = self.deducciones
        
        # llamo al webservice:
        ret = self.client.lpgAutorizarAnticipo(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        anticipo=anticipo,
                        )

        # analizo la respusta
        ret = ret['liqReturn']
        self.__analizar_errores(ret)
        self.AnalizarLiquidacion(ret.get('autorizacion'), self.liquidacion)
        return True
75410
def AnalizarAjusteDebito(self):
        ""
        # para compatibilidad con la generacion de PDF (completo datos)
        liq = {}
        if hasattr(self, "liquidacion") and self.liquidacion:
            liq.update(self.liquidacion)
        if hasattr(self, "ajuste") and 'ajusteDebito' in self.ajuste:
            liq.update(self.ajuste['ajusteDebito'])
        if self.__ajuste_debito:
            liq.update(self.__ajuste_debito)
            self.AnalizarLiquidacion(aut=self.__ajuste_debito, liq=liq, ajuste=True)
            self.AnalizarAjuste(self.__ajuste_base, base=False)  # datos generales
        return True
18387
def ConsultarTiposCarne(self, cod_grupo_carne=1, sep="||"):
        ""
        ret = self.client.consultarTiposCarne(
                            authRequest={
                                'token': self.Token, 'sign': self.Sign,
                                'cuitRepresentada': self.Cuit, },
                            codGrupoCarne=cod_grupo_carne,
                            )['consultarTiposCarneReturn']
        self.__analizar_errores(ret)
        array = ret.get('arrayTiposCarne', [])
        lista = [it['codigoDescripcionString'] for it in array]
        return [(u"%s {codigo} %s {descripcion} %s" % (sep, sep, sep)).format(**it) if sep else it for it in lista]
1266983
def GenerarAjusteFisico(self):
        ""
        
        # renombrar la clave principal de la estructura
        if 'liquidacion' in self.solicitud:
            liq = self.solicitud.pop('liquidacion')
            self.solicitud = liq
        
        # llamar al webservice:
        ret = self.client.generarAjusteFisico(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        solicitud=self.solicitud,
                        )
        # analizar el resultado:
        ret = ret['respuesta']
        self.__analizar_errores(ret)
        liqs = ret.get('liquidacion', [])
        liq = liqs[0] if liqs else None
        self.AnalizarLiquidacion(liq)
        return True
1097901
def ConsultarTiposLiquidacion(self, sep="||"):
        ""
        ret = self.client.consultarTiposLiquidacion(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                            )['respuesta']
        self.__analizar_errores(ret)
        array = ret.get('tipoLiquidacion', [])
        if sep is None:
            return dict([(it['codigo'], it['descripcion']) for it in array])
        else:
            return [("%s %%s %s %%s %s" % (sep, sep, sep)) %
                    (it['codigo'], it['descripcion']) for it in array]
219883
def AutorizarLiquidacion(self):
        ""
        # limpio los elementos que no correspondan por estar vacios:
        for campo in ["guia", "dte", "gasto", "tributo"]:
            if campo in self.solicitud and not self.solicitud[campo]:
                del self.solicitud[campo]
        for item in self.solicitud['itemDetalleLiquidacion']:
            if not item.get("liquidacionCompraAsociada", True):
                del item["liquidacionCompraAsociada"]
        # llamo al webservice:
        ret = self.client.generarLiquidacion(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        solicitud=self.solicitud,
                        )
        # analizo la respusta
        ret = ret['respuesta']
        self.__analizar_errores(ret)
        self.AnalizarLiquidacion(ret)
        return True
647632
def ConsultarTiposOperacion(self, sep="||"):
        ""
        ops = []
        ret = self.client.tipoActividadConsultar(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                            )['tipoActividadReturn']
        self.__analizar_errores(ret)
        for it_act in ret.get('tiposActividad', []):

            ret = self.client.tipoOperacionXActividadConsultar(
                            auth={
                                'token': self.Token, 'sign': self.Sign,
                                'cuit': self.Cuit, },
                            nroActLiquida=it_act['codigoDescripcion']['codigo'],
                            )['tipoOperacionReturn']
            self.__analizar_errores(ret)
            array = ret.get('tiposOperacion', [])
            if sep:
                ops.extend([("%s %%s %s %%s %s %%s %s" % (sep, sep, sep, sep)) % 
                    (it_act['codigoDescripcion']['codigo'],
                     it['codigoDescripcion']['codigo'], 
                     it['codigoDescripcion']['descripcion']) 
                   for it in array])
            else:
                ops.extend([(it_act['codigoDescripcion']['codigo'],
                             it['codigoDescripcion']['codigo'], 
                             it['codigoDescripcion']['descripcion']) 
                           for it in array])
        return ops
1207828
def AnularLiquidacionSecundaria(self, coe):
        ""
        ret = self.client.lsgAnular(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        coe=coe,
                        )
        ret = ret['anulacionReturn']
        self.__analizar_errores(ret)
        self.Resultado = ret['resultado']
        return self.COE
423034
def AgregarItemDetalle(self, cuit_cliente, cod_categoria, tipo_liquidacion,
                           cantidad, precio_unitario, alicuota_iva, cod_raza,
                           cantidad_cabezas=None, nro_tropa=None, 
                           cod_corte=None, cantidad_kg_vivo=None,
                           precio_recupero=None, detalle_raza=None,
                           nro_item=None,
                           **kwargs):
        ""
        d = {'cuitCliente': cuit_cliente,
             'codCategoria': cod_categoria,
             'tipoLiquidacion': tipo_liquidacion, 
             'cantidad': cantidad,
             'precioUnitario': precio_unitario, 
             'alicuotaIVA': alicuota_iva, 
             'cantidadCabezas': cantidad_cabezas, 
             'raza': {'codRaza': cod_raza, 'detalle': detalle_raza}, 
             'nroTropa': nro_tropa, 
             'codCorte': cod_corte, 
             'cantidadKgVivo': cantidad_kg_vivo, 
             'precioRecupero': precio_recupero,
             'liquidacionCompraAsociada': [],
             'nroItem': nro_item,
            }
        self.solicitud['itemDetalleLiquidacion'].append(d)
        return True
199393
def AgregarCertificado(self, tipo_certificado_deposito=None,
                           nro_certificado_deposito=None,
                           peso_neto=None,
                           cod_localidad_procedencia=None,
                           cod_prov_procedencia=None,
                           campania=None, fecha_cierre=None, 
                           peso_neto_total_certificado=None,
                           coe_certificado_deposito=None,       # WSLPGv1.6
                           **kwargs):
        ""
        # limpio campos opcionales:
        if not peso_neto_total_certificado:
            peso_neto_total_certificado = None  # 0 no es válido
        # coe_certificado_deposito no es para LPG, unificar en futuras versiones
        if tipo_certificado_deposito and int(tipo_certificado_deposito) == 332:
            if coe_certificado_deposito and long(coe_certificado_deposito):
                nro_certificado_deposito = coe_certificado_deposito
                coe_certificado_deposito = None
        cert = dict(
                        tipoCertificadoDeposito=tipo_certificado_deposito,
                        nroCertificadoDeposito=nro_certificado_deposito,
                        pesoNeto=peso_neto,
                        codLocalidadProcedencia=cod_localidad_procedencia,
                        codProvProcedencia=cod_prov_procedencia,
                        campania=campania,
                        fechaCierre=fecha_cierre,
                        pesoNetoTotalCertificado=peso_neto_total_certificado,
                        coeCertificadoDeposito=coe_certificado_deposito,
                        coe=coe_certificado_deposito,       # WSLPGv1.17
                        pesoAjustado=peso_neto,             # WSLPGv1.17
                      )
        if self.liquidacion:
            self.liquidacion['certificados'].append({'certificado': cert})
        else:
            self.certificacion['retiroTransferencia']['certificadoDeposito'] = cert
        return True
142529
def AjustarLiquidacion(self):
        ""
        # limpio los elementos que no correspondan por estar vacios:
        for item_liq in self.solicitud['itemDetalleAjusteLiquidacion']:
            campo = 'ajusteCompraAsociada'
            if campo in item_liq and not item_liq[campo]:
                del item_liq[campo]
        for campo in self.solicitud.get('ajusteFinanciero', {}).copy():
            if not self.solicitud['ajusteFinanciero'][campo]:
                del self.solicitud['ajusteFinanciero'][campo]
        # llamo al webservice:
        ret = self.client.generarAjuste(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                        solicitud=self.solicitud,
                        )
        # analizo la respusta
        ret = ret['respuesta']
        self.__analizar_errores(ret)
        self.AnalizarLiquidacion(ret)
        return True
523257
def ProcesarPlantillaPDF(self, num_copias=1, lineas_max=24, qty_pos='izq', 
                                   clave=''):
        ""
        try:
            f = self.template
            liq = self.params_out
            # actualizo los campos según la clave (ajuste debitos / creditos)
            if clave and clave in liq:
                liq = liq.copy()
                liq.update(liq[clave])  # unificar con AnalizarAjusteCredito/Debito

            if HOMO:
                self.AgregarDatoPDF("homo", u"HOMOLOGACIÓN")

            copias = {1: 'Original', 2: 'Duplicado', 3: 'Triplicado', 
                      4: 'Cuadruplicado', 5: 'Quintuplicado'}
                        
            # convierto el formato de intercambio para representar los valores:        
            fmt_encabezado = dict([(v[0], v[1:]) for v in ENCABEZADO])
            fmt_deduccion = dict([(v[0], v[1:]) for v in DEDUCCION])
            fmt_retencion = dict([(v[0], v[1:]) for v in RETENCION])
            
            def formatear(campo, valor, formato):
                "Convertir el valor a una cadena correctamente s/ formato ($ % ...)"
                if campo in formato and v is not None:
                    fmt = formato[campo]
                    if fmt[1] == N:
                        if 'cuit' in campo:
                            c = str(valor)
                            if len(c) == 11:
                                valor = "%s-%s-%s" % (c[0:2], c[2:10], c[10:])
                            else:
                                valor = ""
                        elif 'peso' in campo:
                            valor = "%s Kg" % valor
                        elif valor is not None and valor != "":
                            valor = "%d" % int(valor)
                        else:
                            valor = ""
                    elif fmt[1] == I:
                        valor = ("%%0.%df" % fmt[2]) % valor
                        if 'alic' in campo or 'comision' in campo:
                            valor = valor + " %"
                        elif 'factor' in campo or 'cont' in campo or 'cant' in campo:
                            pass
                        else:
                            valor = "$ " + valor
                    elif 'fecha' in campo:
                        d = valor
                        if isinstance(d, (datetime.date, datetime.datetime)):
                            valor = d.strftime("%d/%m/%Y")
                        else:
                            valor = "%s/%s/%s" % (d[8:10], d[5:7], d[0:4])
                return valor

            def buscar_localidad_provincia(cod_prov, cod_localidad): 
                "obtener la descripción de la provincia/localidad (usar cache)"
                cod_prov = int(cod_prov)
                cod_localidad = str(cod_localidad)
                provincia = datos.PROVINCIAS[cod_prov]
                localidad = self.BuscarLocalidades(cod_prov, cod_localidad)
                return localidad, provincia                

            # divido los datos adicionales (debe haber renglones 1 al 9):
            if liq.get('datos_adicionales') and f.has_key('datos_adicionales1'):
                d = liq.get('datos_adicionales')
                for i, ds in enumerate(f.split_multicell(d, 'datos_adicionales1')):
                    liq['datos_adicionales%s' % (i + 1)] = ds
                
            for copia in range(1, num_copias+1):
                
                # completo campos y hojas
                f.add_page()                   
                f.set('copia', copias.get(copia, "Adicional %s" % copia))
                
                f.set('anulado', {'AC': '', '': 'SIN ESTADO',
                                  'AN': "ANULADO"}.get(liq['estado'], "ERROR"))

                try:
                    cod_tipo_ajuste = int(liq["cod_tipo_ajuste"] or '0')
                except: 
                    cod_tipo_ajuste = None
                f.set('tipo_ajuste', {3: u'Liquidación de Débito', 
                                      4: u'Liquidación de Crédito',
                                      }.get(cod_tipo_ajuste, ''))

                # limpio datos del corredor si no corresponden:
                if liq.get('actua_corredor', 'N') == 'N':
                    if liq.get('cuit_corredor', None) == 0:
                        del liq['cuit_corredor']
                    
                # establezco campos según tabla encabezado:
                for k,v in liq.items():
                    v = formatear(k, v, fmt_encabezado)
                    if isinstance(v, (basestring, int, long, float)):
                        f.set(k, v)
                    elif isinstance(v, decimal.Decimal):
                        f.set(k, str(v))
                    elif isinstance(v, datetime.datetime):
                        f.set(k, str(v))

                import wslpg_datos as datos
                
                campania = int(liq.get('campania_ppal') or 0)
                f.set("campania_ppal", datos.CAMPANIAS.get(campania, campania))
                f.set("tipo_operacion", datos.TIPOS_OP.get(int(liq.get('cod_tipo_operacion') or 0), ""))
                f.set("actividad", datos.ACTIVIDADES.get(int(liq.get('nro_act_comprador') or 0), ""))
                if 'cod_grano' in liq and liq['cod_grano']:
                    cod_grano = int(liq['cod_grano'])
                else:
                    cod_grano = int(self.datos.get('cod_grano') or 0)
                f.set("grano", datos.GRANOS.get(cod_grano, ""))
                cod_puerto = int(liq.get('cod_puerto', self.datos.get('cod_puerto')) or 0)
                if cod_puerto in datos.PUERTOS:
                    f.set("des_puerto_localidad", datos.PUERTOS[cod_puerto])

                cod_grado_ref = liq.get('cod_grado_ref', self.datos.get('cod_grado_ref')) or ""
                if cod_grado_ref in datos.GRADOS_REF:
                    f.set("des_grado_ref", datos.GRADOS_REF[cod_grado_ref])
                else:
                    f.set("des_grado_ref", cod_grado_ref)
                cod_grado_ent = liq.get('cod_grado_ent', self.datos.get('cod_grado_ent'))
                if 'val_grado_ent' in liq and int(liq.get('val_grado_ent') or 0):
                    val_grado_ent = liq['val_grado_ent']
                elif 'val_grado_ent' in self.datos:
                    val_grado_ent = self.datos.get('val_grado_ent')
                elif cod_grano in datos.GRADO_ENT_VALOR: 
                    valores = datos.GRADO_ENT_VALOR[cod_grano]
                    if cod_grado_ent in valores:
                        val_grado_ent = valores[cod_grado_ent]
                    else:
                        val_grado_ent = ""
                else:
                    val_grado_ent = ""
                f.set("valor_grado_ent", "%s %s" % (cod_grado_ent or "", val_grado_ent or ""))
                f.set("cont_proteico", liq.get('cont_proteico', self.datos.get('cont_proteico', "")))
                
                if liq.get('certificados'):
                    # uso la procedencia del certificado de depósito 
                    cert = liq['certificados'][0]
                    localidad, provincia = buscar_localidad_provincia(
                        cert['cod_prov_procedencia'],
                        cert['cod_localidad_procedencia'])
                elif liq.get('cod_prov_procedencia_sin_certificado'):
                    localidad, provincia = buscar_localidad_provincia(
                        liq['cod_prov_procedencia_sin_certificado'], 
                        liq['cod_localidad_procedencia_sin_certificado'])
                else:
                    localidad, provincia = "", ""
    
                f.set("procedencia", "%s - %s" % (localidad, provincia))
                
                # si no se especifíca, uso la procedencia para el lugar
                if not self.datos.get('lugar_y_fecha'):
                    localidad, provincia = buscar_localidad_provincia(
                        liq['cod_prov_procedencia'], 
                        liq['cod_localidad_procedencia'])
                    lugar = "%s - %s " % (localidad, provincia)
                    fecha = datetime.datetime.today().strftime("%d/%m/%Y")
                    f.set("lugar_y_fecha", "%s, %s" % (fecha, lugar))
                    if 'lugar_y_fecha' in self.datos:
                        del self.datos['lugar_y_fecha']

                if HOMO:
                    homo = "(pruebas)"
                else:
                    homo = ""
                
                if int(liq['cod_tipo_operacion'] or 0) == 1: 
                    f.set("comprador.L", "COMPRADOR:")
                    f.set("vendedor.L", "VENDEDOR:")
                    f.set("formulario", u"Form. Electrónico 1116 B %s" % homo)
                else:
                    f.set("comprador.L", "MANDATARIO/CONSIGNATARIO:")
                    f.set("vendedor.L", "MANDANTE/COMITENTE:")
                    f.set("formulario", u"Form. Electrónico 1116 C %s" % homo)
                
                if int(liq.get("coe_ajustado") or 0) or int(liq.get("nro_contrato") or 0):
                    f.set("formulario", u"Ajuste Unificado %s" % homo)

                certs = []
                for cert in liq.get('certificados', []):
                    certs.append(u"%s Nº %s" % (
                        datos.TIPO_CERT_DEP[int(cert['tipo_certificado_deposito'])],
                        cert['nro_certificado_deposito']))
                f.set("certificados_deposito", ', '.join(certs))

                for i, deduccion in enumerate(liq.get('deducciones', [])):
                    for k, v in deduccion.items():
                        v = formatear(k, v, fmt_deduccion)
                        f.set("deducciones_%s_%02d" % (k, i + 1), v)

                for i, retencion in enumerate(liq.get('retenciones', [])):
                    for k, v in retencion.items():
                        v = formatear(k, v, fmt_retencion)
                        f.set("retenciones_%s_%02d" % (k, i + 1), v)
                    if retencion['importe_certificado_retencion']:
                        d = retencion['fecha_certificado_retencion']
                        f.set('retenciones_cert_retencion_%02d' % (i + 1),
                            "%s $ %0.2f %s" % (
                                retencion['nro_certificado_retencion'] or '',
                                retencion['importe_certificado_retencion'],
                                "%s/%s/%s" % (d[8:10], d[5:7], d[2:4]), 
                            ))

                # cargo campos adicionales ([PDF] en .ini y AgregarDatoPDF)
                for k,v in self.datos.items():
                    f.set(k, v)
                
                # Ajustes:
                
                if clave:
                    f.set('subtipo_ajuste', {'ajuste_debito': u'AJUSTE DÉBITO',
                           'ajuste_credito': u'AJUSTE CRÉDITO'}[clave])
                
                if int(liq.get('coe_ajustado') or 0):
                    f.set("leyenda_coe_nro", "COE Ajustado:")
                    f.set("nro_contrato_o_coe_ajustado", liq['coe_ajustado'])
                    f.set("coe_relacionados.L", "")
                    f.set("coe_relacionados", "")
                elif liq.get('nro_contrato'):
                    f.set("leyenda_coe_nro", "Contrato Ajustado:")
                    f.set("nro_contrato_o_coe_ajustado", liq['nro_contrato'])
                    ##f.set("coe_relacionados", TODO)
                    
            return True
        except Exception, e:
            ex = utils.exception_info()
            try:
                f.set('anulado', "%(name)s:%(lineno)s" % ex)
            except:
                pass
            self.Excepcion = ex['msg']
            self.Traceback = ex['tb']
            if DEBUG:
                print self.Excepcion
                print self.Traceback
            return False
703208
def ConsultarLiquidacionSecundariaUltNroOrden(self, pto_emision=1):
        ""
        ret = self.client.lsgConsultarUltimoNroOrden(
                    auth={
                        'token': self.Token, 'sign': self.Sign,
                        'cuit': self.Cuit, },
                    ptoEmision=pto_emision,
                    )
        ret = ret['liqUltNroOrdenReturn']
        self.__analizar_errores(ret)
        self.NroOrden = ret['nroOrden']
        return True
1062581
def AgregarDeduccion(self, codigo_concepto=None, detalle_aclaratorio=None,
                               dias_almacenaje=None, precio_pkg_diario=None,
                               comision_gastos_adm=None, base_calculo=None,
                               alicuota=None, **kwargs):
        ""
        # limpiar campo según validación (comision_gastos_adm puede ser 0.00!)
        if codigo_concepto != "CO" and comision_gastos_adm is not None \
            and float(comision_gastos_adm) == 0:
            comision_gastos_adm = None
        # no enviar campos para prevenir errores AFIP 1705, 1707, 1708
        if base_calculo is not None:
            if codigo_concepto == "AL":
                base_calculo = None
            if codigo_concepto == "CO" and float(base_calculo) == 0:
                base_calculo = None         # no enviar, por retrocompatibilidad
        if codigo_concepto != "AL":
            dias_almacenaje = None
            precio_pkg_diario = None
        self.deducciones.append(dict(
                                    deduccion=dict(
                                        codigoConcepto=codigo_concepto,
                                        detalleAclaratorio=detalle_aclaratorio,
                                        diasAlmacenaje=dias_almacenaje,
                                        precioPKGdiario=precio_pkg_diario,
                                        comisionGastosAdm=comision_gastos_adm,
                                        baseCalculo=base_calculo,
                                        alicuotaIva=alicuota, 
                                    ))
                            )
        return True
1133553
def AgregarTributo(self, cod_tributo, descripcion=None,     
                       base_imponible=None, alicuota=None, importe=None):
        ""
        trib = {'codTributo': cod_tributo, 'descripcion': descripcion, 
                'baseImponible': base_imponible, 'alicuota': alicuota, 
                'importe': importe}
        if 'ajusteFinanciero' in self.solicitud:
            self.solicitud['ajusteFinanciero']['tributo'].append(trib)
        else:
            self.solicitud['tributo'].append(trib)
        return True
47456
def ConsultarTipoActividadRepresentado(self, sep="||"):
        ""
        try:
            ret = self.client.tipoActividadRepresentadoConsultar(
                        auth={
                            'token': self.Token, 'sign': self.Sign,
                            'cuit': self.Cuit, },
                            )['tipoActividadReturn']
            self.__analizar_errores(ret)
            array = ret.get('tiposActividad', [])
            self.Excepcion = self.Traceback = ""
            return [("%s %%s %s %%s %s" % (sep, sep, sep)) %
                    (it['codigoDescripcion']['codigo'], 
                     it['codigoDescripcion']['descripcion']) 
               for it in array]
        except Exception:
            ex = utils.exception_info()
            self.Excepcion = ex['msg']
            self.Traceback = ex['tb']
            if sep:
                return ["ERROR"]