Crear PDF de AFIP en Python
Con pocas líneas de código
Luego de obtener el CAE vamos a generar la factura o un ticket en PDF para nuestro cliente.
HTML de la factura
HTML del ticket
Preparamos los datos para el PDF
Aqui debemos cambiar los datos por los del comprobante que estamos generando
# Datos de la empresa
business_data = {
'business_name': 'Empresa imaginaria S.A.', # Nombre / Razon social
'address': 'Calle falsa 123', # Direccion
'tax_id': 12345678912, # CUIL/CUIT
'gross_income_id': 12345432, # Ingresos brutos
'start_date': '25/10/2017', # Fecha inicio de actividades
'vat_condition': 'Responsable inscripto' # Condicion frente al IVA
}
# Datos del comprobante
bill = {
'number': '000000032', # Numero de comprobante
'point_of_sale': '0001', # Numero del punto de venta
'date': '25/10/2017', # Fecha de emision del comprobante
'since': '25/10/2017', # Fecha de comienzo
'until': '25/10/2017', # Fecha de fin
'expiration': '25/10/2017', # Fecha de expiracion del comprobante
'type': 'B', # Tipo de comprobante
'code': '6', # Codigo de tipo del comprobante
'concept': 'Productos', # Concepto del comprobante (Productos / Servicios / Productos y servicios)
'CAE': 12345678912345, # CAE
'CAE_expiration': '05/11/2017' # Fecha de expiracion del CAE
}
# Items del comprobante
items = [
{
'code': '321', # Codigo
'name': 'Cafe Americano', # Nombre
'quantity': '1,00', # Cantidad
'measurement_unit': 'Unidad', # Unidad de medida
'price': '1500,00', # Precio
'tax_percent': '21%', # Precio
'percent_subsidized': '0,00', # Precio subsidiado
'impost_subsidized': '0,00', # Impuestos subsidiado
'subtotal': '1500,00' # Subtotal
}
]
# Datos de a quien va emitido del comprobante
billing_data = {
'tax_id': 12345678912, # Document/CUIT/CUIL
'name': 'Pepe perez', # Nombre / Razon social
'vat_condition': 'Consumidor final', # Condicion frente al iva
'address': 'Calle falsa 123', # Direccion
'payment_method': 'Efectivo' # Forma de pago
}
# Resumen
overall = {
'subtotal': '150,00', # Subtotal
'impost_tax': '0,00', # Tributos
'total': '150,00', # Total
}
Preparamos el QR
Para generar el QR vamos a utilizar segno
pip install segno
Y generamos el codigo QR
import json
import base64
import segno
# Datos para el QR
qr_code_data = {
'ver': 1, # Versión del formato de los datos (1 por defecto)
'fecha': '2017-10-25', # Fecha de emisión del comprobante
'cuit': 12345678912, # Cuit del Emisor del comprobante
'ptoVta': 1, # Punto de venta utilizado para emitir el comprobante
'tipoCmp': 6, # Tipo de comprobante
'nroCmp': 32, # Tipo de comprobante
'importe': 150, # Importe Total del comprobante (en la moneda en la que fue emitido)
'moneda': 'ARS', # Moneda del comprobante
'ctz': 1, # Cotización en pesos argentinos de la moneda utilizada
'tipoDocRec': 80, # Código del Tipo de documento del receptor
'nroDocRec': 12345678912, # Número de documento del receptor
'tipoCodAut': 'E', # “A” para comprobante autorizado por CAEA, “E” para comprobante autorizado por CAE
'codAut': 12345678912345 # CAE o CAEA, segun corresponda
}
# Preparamos el texto para el qr en base a https://www.afip.gob.ar/fe/qr/especificaciones.asp
qr_code_text = 'https://www.afip.gob.ar/fe/qr/?p=' + base64.urlsafe_b64encode(json.dumps(qr_code_data).encode('utf-8')).decode('utf-8')
qrcode = segno.make_qr(qr_code_text)
qr_code_image = qrcode.png_data_uri(scale=4)
Generamos el HTML
Debemos descargar el HTML de la factura o ticket de ejemplo y guardarlo como bill.html
Para agregar nuestros datos al HTML descargado vamos a utilizar jinja
pip install Jinja2
Y ahora debemos llamar a jinja con el HTML que descargamos previamente.
from jinja2 import Template
# Leemos el HTML descargado
html = open("./bill.html").read()
# Iniciamos el template con el HTML
template = Template(html)
# Generamos el HTML con los datos de nuestro comprobante
template_html = template.render(
business_data= business_data,
bill= bill,
items= items,
billing_data= billing_data,
overall= overall,
qr_code_image=qr_code_image
)
Creamos el PDF con pdfkit
Y finalmente lo que nos queda es generar el PDF, para esto vamos a utilizar pdfkit
pip install pdfkit
Luego debemos instalar wkhtmltopdf siguiendo las siguientes instrucciones
Una vez instalado wkhtmltopdf procedemos a generar el PDF
import pdfkit
# Guardamos el PDF como Comprobante.pdf
res = pdfkit.from_string(template_html, 'Comprobante.pdf')
Ya tenemos el PDF listo para enviarle al cliente.
(Opcional) Usar Afip SDK
Si se complica la instalacion al usar pdfkit podemos opcionalmente utilizar Afip.py
pip install afip.py
Creamos una instancia de la clase Afip
from afip import Afip
# CUIT que emitio la factura
#
# Podes usar 20409378472 para desarrollo
# sin necesidad de key o cert
# Para mas info https://docs.afipsdk.com/paso-a-paso/instalacion
CUIT = 20409378472
afip = Afip({ "CUIT": CUIT })
Generamos el PDF
# Nombre para el archivo (sin .pdf)
name = "PDF de prueba"
# Opciones para el archivo
options = {
"width": 8, # Ancho de pagina en pulgadas. Usar 3.1 para ticket
"marginLeft": 0.4, # Margen izquierdo en pulgadas. Usar 0.1 para ticket
"marginRight": 0.4, # Margen derecho en pulgadas. Usar 0.1 para ticket
"marginTop": 0.4, # Margen superior en pulgadas. Usar 0.1 para ticket
"marginBottom": 0.4 # Margen inferior en pulgadas. Usar 0.1 para ticket
}
# Creamos el PDF
res = afip.ElectronicBilling.createPDF({
"html": template_html,
"file_name": name,
"options": options
})
# Mostramos la url del archivo creado
print(res["file"])
# Los PDFs creados con el SDK duran 24hs.
# Debes descargar el archivo antes de que expire la URL
Ahora descargamos y guardamos el PDF. Para esto vamos a utilizar la libreria requests
pip install requests
Descargamos el PDF
import requests
# Descargamos el PDF
response = requests.get(res['file'])
# Guardamos el PDF como Comprobante.pdf
open("./Comprobante.pdf", 'wb').write(response.content)
Ya tenemos el PDF listo para enviarle al cliente.
Lo único que nos queda es pasar a modo producción, para más información de cómo hacerlo pueden dirigirse a la documentación de la librería https://docs.afipsdk.com/