def get_context_data(self, **kwargs): context = super(ComprobantePreview, self).get_context_data(**kwargs) if 'pk' in self.kwargs: comprobante = Comprobante.objects.get(pk=self.kwargs['pk']) obj = comprobante.get_data_para_imprimir() context['object'] = obj context['comprobante'] = comprobante importe_descuento = self.get_importe_descuento(comprobante) context[ 'importe_neto_gravado'] = Comprobante.formatNumericFieldToFloat( comprobante, comprobante.importe_neto_gravado) context[ 'importe_no_gravado'] = Comprobante.formatNumericFieldToFloat( comprobante, comprobante.importe_no_gravado) context['importe_exento'] = Comprobante.formatNumericFieldToFloat( comprobante, comprobante.importe_exento) context[ 'importe_descuento'] = Comprobante.formatNumericFieldToFloat( comprobante, importe_descuento) tributos = comprobante.tributocomprobante_set.aggregate( total_tributos=Sum(F('base_imponible') * F('alicuota') / 100)) total_tributos = tributos.get('total_tributos') if tributos.get( 'total_tributos') else 0 if not comprobante.es_comprobante_b(): subtotal = comprobante.importe_neto + comprobante.importe_dto_neto else: subtotal = comprobante.importe_total + importe_descuento - total_tributos context['subtotal'] = subtotal return context
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_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 _crear_comprobante_similar(comp, importe, id_tipo_comp, numero, gravado): iva = calcular_iva(importe, gravado.porcentaje) return Comprobante( **{ 'nombre_cliente': comp.nombre_cliente, 'domicilio_cliente': comp.domicilio_cliente, 'nro_cuit': comp.nro_cuit, 'gravado_paciente': comp.gravado_paciente, 'condicion_fiscal': comp.condicion_fiscal, 'responsable': comp.responsable, 'sub_tipo': comp.sub_tipo, 'estado': Comprobante.COBRADO, 'numero': numero, 'nro_terminal': comp.nro_terminal, 'total_facturado': importe + iva, 'total_cobrado': importe + iva, 'fecha_emision': date.today(), 'fecha_recepcion': date.today(), 'tipo_comprobante': TipoComprobante.objects.get(pk=id_tipo_comp), 'factura': comp, 'gravado': gravado, })
def consultar_proximo_numero(self, nro_terminal, tipo_comprobante, sub_tipo): codigo_afip = Comprobante(nro_terminal=nro_terminal, tipo_comprobante=tipo_comprobante, sub_tipo=sub_tipo).codigo_afip return int(self.webservice.CompUltimoAutorizado(codigo_afip, nro_terminal) or 0) + 1
def import_cbte_csv(csvfile): errors = [] lineerrs = [] linen = 0 empresa = Empresa.objects.first() prefetched = _prefetch(empresa) try: with transaction.atomic(): records = csv.DictReader(csvfile, fieldnames=cbte_import_fields, restval=None) last_item_number = None last_cbte = None for record in records: linen += 1 lineerrs = [] if not record["cbte_item_number"]: lineerrs.append( "la linea {} del archivo no tiene un numero de item". format(linen)) continue if record["cbte_item_number"] != last_item_number: last_cbte = None last_item_number = record["cbte_item_number"] # creo cbte tipo_cbte = get_or_error(lineerrs, linen, record, "cbte_tipo_cbte", prefetched[TipoComprobante], "tipo de comprobante") punto_vta = get_or_error(lineerrs, linen, record, "cbte_punto_vta", prefetched[PuntoDeVenta], "punto de venta") concepto = get_or_error(lineerrs, linen, record, "cbte_concepto", prefetched[Concepto], "concepto") nro_remito = check_str(lineerrs, linen, record, "cbte_nro_remito", 13, "numero de remito") fecha_emision = check_date(lineerrs, linen, record, "cbte_fecha_emision", "fecha de emision") fecha_vto = check_date(lineerrs, linen, record, "cbte_fecha_vencimiento", "fecha de vencimiento de pago") tipo_doc = get_or_error(lineerrs, linen, record, "cbte_id_tipo_doc_cliente", prefetched[TipoDoc], "tipo de documento del cliente") nro_doc = check_str(lineerrs, linen, record, "cbte_nro_doc_cliente", 128, "numero de documento del cliente") tipo_expo = get_or_error(lineerrs, linen, record, "cbte_tipo_exportacion", prefetched[TipoExportacion], "tipo de exportacion", opcional=True) moneda = get_or_error(lineerrs, linen, record, "cbte_id_moneda", prefetched[Moneda], "moneda", default="PES") cotizaccion = check_float(lineerrs, linen, record, "cbte_moneda_ctz", "cotizacion", default=1) idioma = get_or_error(lineerrs, linen, record, "cbte_id_idioma", prefetched[Idioma], "idioma", default=1) incoterms = get_or_error(lineerrs, linen, record, "cbte_id_incoterms", prefetched[Incoterms], "incoterms", opcional=True) incoterms_ds = check_str(lineerrs, linen, record, "cbte_incoterms_ds", 256, "incoterms - descripcion") pais_destino = get_or_error(lineerrs, linen, record, "cbte_id_pais_destino", prefetched[PaisDestino], "pais de destino", opcional=True) id_impositivo = check_str(lineerrs, linen, record, "cbte_id_impositivo", 256, "id impositivo") obs_comerciales = check_str( lineerrs, linen, record, "cbte_observaciones_comerciales", 9999, "observaciones comerciales") obs = check_str(lineerrs, linen, record, "cbte_observaciones", 9999, "observaciones") forma_pago = check_str(lineerrs, linen, record, "cbte_forma_pago", 256, "forma de pago") condicion_vta = get_or_error(lineerrs, linen, record, "cbte_id_condicion_vta", prefetched[CondicionVenta], "condicion de venta") condicion_vta_texto = check_str( lineerrs, linen, record, "cbte_condicion_vta_otra", 256, "condicion de venta - otra") # Info cliente nombre = check_str(lineerrs, linen, record, "cbte_cliente_nombre", 256, "razon social del cliente") condicion_iva = get_or_error( lineerrs, linen, record, "cbte_cliente_condicion_iva", prefetched[CondicionIva], "condicion de iva del cliente") domicilio = check_str(lineerrs, linen, record, "cbte_cliente_domicilio", 256, "domicilio del cliente") localidad = check_str(lineerrs, linen, record, "cbte_cliente_localidad", 256, "localidad del cliente") telefono = check_str(lineerrs, linen, record, "cbte_cliente_telefono", 256, "telefono del cliente") cod_postal = check_str(lineerrs, linen, record, "cbte_cliente_cp", 256, "codigo postal del cliente") email = check_str(lineerrs, linen, record, "cbte_cliente_email", 75, "email del cliente") if (tipo_doc.id_afip, nro_doc) in prefetched[Cliente]: cliente = prefetched[Cliente][(tipo_doc.id_afip, nro_doc)] if cliente_changed(cliente, nombre, condicion_iva, domicilio, localidad, telefono, cod_postal, email): cliente.nombre = nombre cliente.condicion_iva = condicion_iva cliente.domicilio = domicilio cliente.localidad = localidad cliente.telefono = telefono cliente.cod_postal = cod_postal cliente.email = email cliente.save() else: cliente = Cliente(tipo_doc=tipo_doc, nro_doc=nro_doc, nombre=nombre, condicion_iva=condicion_iva, domicilio=domicilio, localidad=localidad, telefono=telefono, cod_postal=cod_postal, email=email) cliente.save() prefetched[Cliente][(tipo_doc.id_afip, nro_doc)] = cliente last_cbte = Comprobante( empresa=empresa, tipo_cbte=tipo_cbte, punto_vta=punto_vta, concepto=concepto, remito_nro=nro_remito, fecha_emision=fecha_emision, fecha_venc_pago=fecha_vto, cliente_id=cliente.id, tipo_expo=tipo_expo, moneda=moneda, idioma=idioma, incoterms=incoterms, pais_destino=pais_destino, id_impositivo=id_impositivo, moneda_ctz=Decimal(cotizaccion), observaciones_comerciales=obs_comerciales, observaciones=obs, forma_pago=forma_pago, incoterms_ds=incoterms_ds, condicion_venta=condicion_vta, condicion_venta_texto=condicion_vta_texto, ) last_cbte.save() if record["det_nombre"] or record["det_codigo"]: codigo = check_str(lineerrs, linen, record, "det_codigo", 128, "codigo de producto") cantidad = check_float(lineerrs, linen, record, "det_cant", "cantidad") if codigo: if codigo in prefetched[Producto]: prod = prefetched[Producto][codigo] else: nombre = check_str(lineerrs, linen, record, "det_nombre", 256, "texto del detalle") precio_unit = check_float(lineerrs, linen, record, "det_precio_unit", "precio unitario") unidad = get_or_error(lineerrs, linen, record, "det_unidad", prefetched[Unidad], "unidad de medida") alicuota = get_or_error(lineerrs, linen, record, "det_id_alicuota", prefetched[AlicuotaIva], "alicuota IVA") prod = Producto(codigo=codigo, nombre=nombre, precio_unit=Decimal(precio_unit), alicuota_iva=alicuota, unidad=unidad) prefetched[Producto][codigo] = prod prod.save() det = DetalleComprobante( comprobante_id=last_cbte.id, producto_id=prod.id, cant=Decimal(cantidad), detalle=prod.nombre_completo, precio_unit=prod.precio_unit, alicuota_iva=prod.alicuota_iva, unidad=prod.unidad) else: nombre = check_str(lineerrs, linen, record, "det_nombre", 256, "texto del detalle") precio_unit = check_float(lineerrs, linen, record, "det_precio_unit", "precio unitario") unidad = get_or_error(lineerrs, linen, record, "det_unidad", prefetched[Unidad], "unidad de medida") alicuota = get_or_error(lineerrs, linen, record, "det_id_alicuota", prefetched[AlicuotaIva], "alicuota IVA") det = DetalleComprobante( comprobante_id=last_cbte.id, cant=Decimal(cantidad), detalle=nombre, precio_unit=Decimal(precio_unit), alicuota_iva=alicuota, unidad=unidad) det.save() if record["trib_id"]: tributo = get_or_error(lineerrs, linen, record, "trib_id", prefetched[Tributo], "tributo") detalle = check_str(lineerrs, linen, record, "trib_detalle", 256, "detalle del tributo") base_imponible = check_float(lineerrs, linen, record, "trib_base_imponible", "base imponible") alicuota = check_float(lineerrs, linen, record, "trib_alicuota", "alicuota") trib = TributoComprobante( comprobante_id=last_cbte.id, tributo_id=tributo.id, detalle=detalle, base_imponible=Decimal(base_imponible), alicuota=Decimal(alicuota)) trib.save() if record["op_id"]: opcional = get_or_error(lineerrs, linen, record, "op_id", prefetched[Opcional], "opcional") valor = check_str(lineerrs, linen, record, "op_valor", 256, "valor del opcional") op = OpcionalComprobante(comprobante_id=last_cbte.id, opcional_id=opcional.id, valor=valor) op.save() errors.extend(lineerrs) lineerrs = [] if errors: raise Exception() except Exception as e: errors.extend(lineerrs) errors.append( "Hubo un error al procesar el archivo. Ultima linea procesada: {}". format(linen or 0)) logger.exception("Error al importar") return errors
def test_factory_nota_debito_electronica(self): comprobante = Comprobante( tipo_comprobante=self.tipo_comprobante_nota_debito) instance_created = calculador_informe_factory(comprobante) self.assertTrue(isinstance(instance_created, CalculadorInformeFactura))
def test_factory_nota_credito(self): comprobante = Comprobante( tipo_comprobante=self.tipo_comprobante_nota_credito) instance_created = calculador_informe_factory(comprobante) self.assertTrue( isinstance(instance_created, CalculadorInformeNotaCredito))
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("")