def crear_comprobante_asociado(id_comp, importe, concepto, tipo_comprobante, tipo_iva=None): importe = importe.quantize(Decimal(10)**-2) comp = Comprobante.objects.get(pk=id_comp) gravado = Gravado.objects.get(pk=tipo_iva) if tipo_iva else comp.gravado if comp.tipo_comprobante.id == ID_TIPO_COMPROBANTE_LIQUIDACION: raise TipoComprobanteAsociadoNoValidoException( "No es posible usar una liquidacion como comprobante asociado") afip = Afip() nro_siguiente = afip.consultar_proximo_numero( comp.responsable, comp.nro_terminal, TipoComprobante.objects.get(pk=tipo_comprobante), comp.sub_tipo) comprobante = _crear_comprobante_similar(comp, importe, tipo_comprobante, nro_siguiente, gravado) lineas = _crear_linea(comprobante, importe, concepto, gravado) afip.emitir_comprobante(comprobante, lineas) comprobante.save() lineas[0].comprobante = Comprobante.objects.get(pk=comprobante.id) lineas[0].save() return comprobante
def test_sobre_singleton_afip_devuelve_la_misma_instancia_luego_de_crearse_mas_de_una_vez( self, mock_wsfev1, mock_wsaa): mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsfev1.return_value.Conectar.return_value = True instancia1 = Afip() instancia2 = Afip() assert instancia1 is instancia2
def test_error_de_conexion_lanza_excepcion(self, mock_wsfev1, mock_wsaa): mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.side_effect = ServerNotFoundError afip = Afip() comprobante = Comprobante.objects.get(pk=1) with self.assertRaises(AfipErrorRed): afip.emitir_comprobante(comprobante, [])
def test_comprobante_rechazado_por_webservice_lanza_excepcion( self, mock_wsfev1, mock_wsaa): mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.return_value = None mock_wsfev1.return_value.Resultado = "R" afip = Afip() comprobante = Comprobante.objects.get(pk=1) with self.assertRaises(AfipErrorValidacion): afip.emitir_comprobante(comprobante, [])
def test_emitir_factura_de_credito_electronica(self, mock_wsfev1, mock_wsaa): mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsaa.return_value.Expirado.return_value = False mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.return_value = None mock_wsfev1.return_value.Resultado = "A" mock_wsfev1.return_value.CAE = 1 mock_wsfev1.return_value.Vencimiento = "30191231" afip = Afip() numero = afip.consultar_proximo_numero( "Brunetti", 3, TipoComprobante.objects.get(pk=5), "B") factura_electronica = Comprobante( **{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Brunetti", "sub_tipo": "B", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 3, "total_facturado": "100000.00", "total_cobrado": "0.00", "fecha_emision": datetime.today(), "fecha_recepcion": datetime.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=5), }) lineas_factura_electronica = [ LineaDeComprobante( **{ "comprobante": factura_electronica, "importe_neto": 100000.00, "sub_total": 100000.00, "iva": 0, }) ] afip.emitir_comprobante(factura_electronica, lineas_factura_electronica) assert factura_electronica.cae == 1
def create(self, validated_data): lineas = [linea.save() for linea in validated_data['lineas']] neto = sum(linea.importe_neto for linea in lineas) gravado = Gravado.objects.get(pk=validated_data['gravado_id']) responsable = validated_data['responsable'] tipo_comprobante = TipoComprobante.objects.get( pk=validated_data['tipo_comprobante_id']) iva = neto * gravado.porcentaje / Decimal("100.00") total = neto + iva del validated_data["lineas"] comprobante = Comprobante( estado=Comprobante.NO_COBRADO, numero=0, # el numero nos lo va a dar la afip cuando emitamos fecha_emision=date.today(), fecha_recepcion=date.today(), total_facturado=total, total_cobrado=0, # Para que no explote el azul nro_terminal=CEDIR_PTO_VENTA if responsable == "Cedir" else BRUNETTI_PTO_VENTA, **validated_data) for linea in lineas: linea.comprobante = comprobante Afip().emitir_comprobante(comprobante, lineas) comprobante.save() for linea in lineas: linea.comprobante = comprobante linea.save() return comprobante
def test_comprobante_aceptado_por_weservice_setea_cae( self, mock_wsfev1, mock_wsaa): mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.return_value = None mock_wsfev1.return_value.Resultado = "A" mock_wsfev1.return_value.CAE = 1 mock_wsfev1.return_value.Vencimiento = "30191231" afip = Afip() comprobante = Comprobante.objects.get(pk=1) afip.emitir_comprobante(comprobante, []) assert comprobante.cae == 1 assert comprobante.vencimiento_cae.strftime("%Y-%m-%d") == "3019-12-31" assert comprobante.numero == 1
def test_comprobante_con_comprobantes_asociados(self, mock_wsfev1, mock_wsaa): mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsaa.return_value.Expirado.return_value = False mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.return_value = None mock_wsfev1.return_value.Resultado = "A" mock_wsfev1.return_value.CAE = 1 mock_wsfev1.return_value.Vencimiento = "30191231" afip = Afip() comprobante = Comprobante.objects.get(pk=1) comprobante.tipo_comprobante = TipoComprobante.objects.get(pk=3) comprobante.factura = Comprobante.objects.get(pk=2) afip.emitir_comprobante(comprobante, []) assert comprobante.cae == 1 assert comprobante.vencimiento_cae.strftime("%Y-%m-%d") == "3019-12-31" assert comprobante.numero == 1
def test_ticket_expirado_renueva_y_emite(self, mock_wsfev1, mock_wsaa, mock_afip): ''' Se mockea WSAA.Expirado para que devuelva false en la primer llamada y luego true, de manera de testear que en ese escenario, emitir_comprobante llama a WSAA.Autenticar antes de cumplir su tarea (en total se llama dos veces con al del constructor). ''' mock_wsaa.return_value.Autenticar.side_effect = [TICKET, TICKET] mock_wsaa.return_value.Expirado.side_effect = [True, False] mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.return_value = None mock_wsfev1.return_value.Resultado = "A" mock_wsfev1.return_value.CAE = 1 mock_wsfev1.return_value.Vencimiento = "30191231" afip = Afip() comprobante = Comprobante.objects.get(pk=1) assert mock_afip.call_count == 2 afip.emitir_comprobante(comprobante, []) assert mock_afip.call_count == 3 mock_wsfev1.return_value.CAESolicitar.assert_called()
def test_ticket_valido_no_renueva_y_emite(self, mock_wsfev1, mock_wsaa, mock_afip): ''' Se mockea WSAA.Expirado para que devuelva true y se testea que WSAA.Autenticar sea llamada una sola vez, para asegurarnos de que no se pierde tiempo piediendo tickets inutilmente. ''' mock_wsaa.return_value.Autenticar.return_value = TICKET mock_wsaa.return_value.Expirado.return_value = False mock_wsfev1.return_value.Conectar.return_value = True mock_wsfev1.return_value.CompUltimoAutorizado.return_value = 0 mock_wsfev1.return_value.AgregarIva.return_value = None mock_wsfev1.return_value.CAESolicitar.return_value = None mock_wsfev1.return_value.Resultado = "A" mock_wsfev1.return_value.CAE = 1 mock_wsfev1.return_value.Vencimiento = "30191231" afip = Afip() comprobante = Comprobante.objects.get(pk=1) assert mock_afip.call_count == 2 afip.emitir_comprobante(comprobante, []) assert mock_afip.call_count == 2 mock_wsfev1.return_value.CAESolicitar.assert_called()
def test_error_de_conexion_en_constructor_lanza_excepcion( self, mock_wsfev1): mock_wsfev1.return_value.Conectar.side_effect = ServerNotFoundError with self.assertRaises(AfipErrorRed): Afip()
def main(): # Iniciamos el la conexion con la AFIP. afip = Afip() ######### # Factura ######### # En la realidad podemos usar nuestro conteneo de numeros de comprobantes sin problemas, (si no coinciden hay algun problema grave) # pero aca no y de todas formas es util tener a mano esta info. numero = afip.consultar_proximo_numero("Cedir", 91, TipoComprobante.objects.get(pk=1), "A") # Esto es para poder usar la proxima id que pide afip y es un motivo fuerte para NO CORRER ESTE SCRIPT EN PRODUCCION!! # (los numeros en homologacion y produccion no coincididen entonces en la DB dev tenemos colisiones de numero) # Comprobante.objects.filter(nro_terminal=91, tipo_comprobante=TipoComprobante.objects.get(pk=1), numero=numero).delete() # Creamos un Factura # Esto crea el objeto, pero no lo guarda en DB. factura = Comprobante(**{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Cedir", "sub_tipo": "A", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 91, "total_facturado": "2800.00", "total_cobrado": "0.00", "fecha_emision": date.today(), "fecha_recepcion": date.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=1), }) # Creamos una linea de comprobante, parte necesaria de un comprobante para nuestro sistema. lineas_factura = [LineaDeComprobante(**{ "comprobante": factura, "importe_neto": 2800.00, "sub_total": 2800.00, "iva": 0, })] # Emitimos el comprobante en la AFIP. afip.emitir_comprobante(factura, lineas_factura) # Revisamos que los datos esten bien. # Si la emicion funciono correctamente, los datos se setean directamente en el comprobante. print("FACTURA") print("-------") print((factura.cae)) print((factura.vencimiento_cae)) # Le pedimos el comprobante a la AFIP y verificamos que los datos coincidan. print((afip.consultar_comprobante(factura))) # Si la AFIP emitio bien, ahora se guardan. # Aca deberia haber codigo que hizo las verificaciones en realidad, pero esto es un PoC. # factura.save() # lineas_factura[0].save() ######### # Nota de Debito ######### numero = afip.consultar_proximo_numero("Cedir", 91, TipoComprobante.objects.get(pk=3), "A") nota_debito = Comprobante(**{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Cedir", "sub_tipo": "A", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 91, "total_facturado": "2800.00", "total_cobrado": "0.00", "fecha_emision": date.today(), "fecha_recepcion": date.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=3), "factura": factura # Ponemos como comprobante asociado la factura que hicimos recien. }) lineas_nota_debito = [LineaDeComprobante(**{ "comprobante": nota_debito, "importe_neto": 2800.00, "sub_total": 2800.00, "iva": 0, })] afip.emitir_comprobante(nota_debito, lineas_nota_debito) print("NOTA DE DEBITO") print("--------------") print((nota_debito.cae)) print((nota_debito.vencimiento_cae)) print((afip.consultar_comprobante(nota_debito))) print("") ######### # Nota de Credito ######### numero = afip.consultar_proximo_numero("Cedir", 91, TipoComprobante.objects.get(pk=4), "A") nota_credito = Comprobante(**{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Cedir", "sub_tipo": "A", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 91, "total_facturado": "2800.00", "total_cobrado": "0.00", "fecha_emision": date.today(), "fecha_recepcion": date.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=4), "factura": nota_debito # Ponemos como comprobante asociado la factura que hicimos recien. }) lineas_nota_credito = [LineaDeComprobante(**{ "comprobante": nota_credito, "importe_neto": 2800.00, "sub_total": 2800.00, "iva": 0, })] print("NOTA DE CREDITO") print("---------------") afip.emitir_comprobante(nota_credito, lineas_nota_credito) print((nota_credito.cae)) print((nota_credito.vencimiento_cae)) print((afip.consultar_comprobante(nota_credito))) print("") ####################################### # Factura de Credito Electronica MiPyME ####################################### numero = afip.consultar_proximo_numero("Brunetti", 3, TipoComprobante.objects.get(pk=5), "B") factura_electronica = Comprobante(**{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Brunetti", "sub_tipo": "B", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 3, "total_facturado": "100000.00", "total_cobrado": "0.00", "fecha_emision": date.today(), "fecha_recepcion": date.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=5), }) lineas_factura_electronica = [LineaDeComprobante(**{ "comprobante": factura_electronica, "importe_neto": 100000.00, "sub_total": 100000.00, "iva": 0, })] print("FACTURA MIPYME") print("--------------") afip.emitir_comprobante(factura_electronica, lineas_factura_electronica) print((factura_electronica.cae)) print((factura_electronica.vencimiento_cae)) print((afip.consultar_comprobante(factura_electronica))) print("") ####################################### # Nota de Debito Electronica MiPyME ####################################### numero = afip.consultar_proximo_numero("Brunetti", 3, TipoComprobante.objects.get(pk=6), "B") nota_de_debito_electronica = Comprobante(**{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Brunetti", "sub_tipo": "B", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 3, "total_facturado": "100000.00", "total_cobrado": "0.00", "fecha_emision": date.today(), "fecha_recepcion": date.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=6), "factura": factura_electronica }) lineas_nota_de_debito_electronica = [LineaDeComprobante(**{ "comprobante": nota_de_debito_electronica, "importe_neto": 100000.00, "sub_total": 100000.00, "iva": 0, })] print("N DEBITO MIPYME") print("--------------") afip.emitir_comprobante(nota_de_debito_electronica, lineas_nota_de_debito_electronica) print((nota_de_debito_electronica.cae)) print((nota_de_debito_electronica.vencimiento_cae)) print((afip.consultar_comprobante(nota_de_debito_electronica))) print("") ####################################### # Nota de Credito Electronica MiPyME ####################################### numero = afip.consultar_proximo_numero("Brunetti", 3, TipoComprobante.objects.get(pk=7), "B") nota_de_credito_electronica = Comprobante(**{ "nombre_cliente": "Obra Social de los Trabajadores de la Planta Nuclear de Springfield", "domicilio_cliente": " - Springfield - (CP:2000)", "nro_cuit": "30604958640", "gravado_paciente": "", "condicion_fiscal": "EXENTO", "gravado": Gravado.objects.get(pk=1), "responsable": "Brunetti", "sub_tipo": "B", "estado": "PENDIENTE", "numero": numero, "nro_terminal": 3, "total_facturado": "100000.00", "total_cobrado": "0.00", "fecha_emision": date.today(), "fecha_recepcion": date.today(), "tipo_comprobante": TipoComprobante.objects.get(pk=7), "factura": factura_electronica }) lineas_nota_de_credito_electronica = [LineaDeComprobante(**{ "comprobante": nota_de_credito_electronica, "importe_neto": 100000.00, "sub_total": 100000.00, "iva": 0, })] print("N CREDITO MIPYME") print("--------------") afip.emitir_comprobante(nota_de_credito_electronica, lineas_nota_de_credito_electronica) print((nota_de_credito_electronica.cae)) print((nota_de_credito_electronica.vencimiento_cae)) print((afip.consultar_comprobante(nota_de_credito_electronica))) print("")