def process_invoices(invoices, selling_point): """Generate the invoices in PDF using AFIP API resources.""" wsfev1 = _get_afip() # init PDF builder fepdf = FEPDF() fepdf.CargarFormato( os.path.join(settings.BASE_DIR, "templates", "factura.csv")) fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" fepdf.CUIT = settings.AFIP['cuit'] for k, v in CONFIG_PDF.items(): fepdf.AgregarDato(k, v) # safeguard when using test webservice endpoints if "h**o" in settings.AFIP['url_wsaa']: fepdf.AgregarCampo("DEMO", 'T', 120, 260, 0, 0, text="DEMOSTRACION", size=70, rotate=45, foreground=0x808080, priority=-1) fepdf.AgregarDato("motivos_obs", "Ejemplo Sin Validez Fiscal") # get CAE for each record and generate corresponding PDF results = {} for invoice in invoices: authorized_ok = invoice.autorizar(wsfev1) invoice_number = invoice.header["cbte_nro"] print(" invoice generated: number={} CAE={} authorized={}".format( invoice_number, invoice.header["cae"], authorized_ok)) results[invoice_number] = {'invoice_ok': authorized_ok} if not authorized_ok: print("WARNING not auth") return # another safeguard if "h**o" in settings.AFIP['url_wsfev1']: invoice.header["motivos_obs"] = "Ejemplo Sin validez fiscal" # generate the PDF pdf_name = "FacturaPyArAC-{:04d}-{:08d}.pdf".format( selling_point, invoice_number) pdf_path = os.path.join(PDF_PATH, pdf_name) invoice.generate_pdf(fepdf, pdf_path) print(" PDF generated {!r}".format(pdf_path)) results[invoice_number]['pdf_path'] = pdf_path return results
def pdf(): id = request.args[0] from pyafipws.pyfepdf import FEPDF fepdf = FEPDF() fepdf.CUIT = 20267565393 # cargo el formato CSV por defecto (factura.csv) t = os.path.join(request.env.web2py_path,'applications',request.application,'modules', 'pyafipws', 'factura.csv') fepdf.CargarFormato(t) f = db(db.pagos.id == id).select().first() if not f.cae: raise HTTP(500, "Debe soliticar CAE a AFIP antes de generar el PDF!") # creo una factura de ejemplo tipo_cbte = int(f.tipo_cbte) punto_vta = int(f.pto_vta) fecha = f.fecha.strftime("%Y%m%d") concepto = 3 tipo_doc = int(f.tipo_doc); nro_doc = int(f.nro_doc) cbte_nro = int(f.cbte_nro) imp_total = f.imp_total imp_tot_conc = "0.00" imp_neto = "0.00" imp_iva = "0.00" imp_trib = "0.00" imp_op_ex = "0.00" imp_subtotal = "0.00" fecha_cbte = fecha fecha_venc_pago = fecha # Fechas del período del servicio facturado (solo si concepto = 1?) fecha_serv_desde = fecha; fecha_serv_hasta = fecha moneda_id = 'PES'; moneda_ctz = '1.000' obs_generales = u"EMAIL: %s" % f.email obs_comerciales = u"En tu resumen verás el cargo como WWW.MERCADOPAGO.COM" nombre_cliente = "%s, %s" % (f.last_name, f.first_name) domicilio_cliente = "" pais_dst_cmp = 16 id_impositivo = "" moneda_id = 'PES' moneda_ctz = 1 forma_pago = f.forma_pago incoterms = 'FOB' idioma_cbte = 1 motivo = f.motivo cae = f.cae fch_venc_cae = f.fecha_vto fepdf.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fch_venc_cae, id_impositivo, nombre_cliente, domicilio_cliente, pais_dst_cmp, obs_comerciales, obs_generales, forma_pago, incoterms, idioma_cbte, motivo) #tipo = 91 #pto_vta = 2 #nro = 1234 #fepdf.AgregarCmpAsoc(tipo, pto_vta, nro) #tributo_id = 99 #desc = 'Impuesto Municipal Matanza' #base_imp = "100.00" #alic = "1.00" #importe = "1.00" #fepdf.AgregarTributo(tributo_id, desc, base_imp, alic, importe) #iva_id = 5 # 21% #base_imp = 100 #importe = 21 #fepdf.AgregarIva(iva_id, base_imp, importe) u_mtx = 123456 cod_mtx = 1234567890123 codigo = "P0001" ds = f.ds qty = 1.00 umed = 7 precio = f.imp_total bonif = 0.00 iva_id = 1 imp_iva = 0 importe = f.imp_total despacho = "" fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho) #fepdf.AgregarDato("pedido", "1234") fepdf.CrearPlantilla(papel="A4", orientacion="portrait") fepdf.ProcesarPlantilla(num_copias=3, lineas_max=24, qty_pos='izq') salida = t = os.path.join(request.env.web2py_path,'applications',request.application, 'private', 'factura%s.pdf' % id) fepdf.GenerarPDF(archivo=salida) response.headers['Content-Type']='application/pdf' return open(salida).read()
def generar_pdf(): CONFIG_FILE = "/home/web2py/pyafipws/sp/rece1.ini" config = SafeConfigParser() config.read(CONFIG_FILE) conf_fact = dict(config.items('FACTURA')) conf_pdf = dict(config.items('PDF')) from pyafipws.pyfepdf import FEPDF fepdf = FEPDF() # cargo el formato CSV por defecto (factura.csv) fepdf.CargarFormato(conf_fact.get("formato", "factura.csv")) # establezco formatos (cantidad de decimales) según configuración: fepdf.FmtCantidad = conf_fact.get("fmt_cantidad", "0.2") fepdf.FmtPrecio = conf_fact.get("fmt_precio", "0.2") # creo una factura de ejemplo H**O = True # obtengo el registro general del comprobante (encabezado y totales) id_comprobante = int(request.args[0]) reg = db(db.comprobante_afip.id==id_comprobante).select().first() tipo_cbte = reg.tipo_cbte punto_vta = reg.punto_vta cbte_nro = reg.cbte_nro fecha = reg.fecha_cbte #.strftime("%Y%m%d") # formato AAAAMMDD concepto = reg.concepto tipo_doc = reg.tipo_doc # 80: CUIT, 96: DNI nro_doc = reg.nro_doc.replace("-", "") # del cliente, sin rayita cbt_desde = cbte_nro; cbt_hasta = cbte_nro imp_total = reg.imp_total imp_tot_conc = reg.imp_tot_conc imp_neto = reg.imp_neto imp_iva = reg.impto_liq imp_trib = "0.00" imp_op_ex = reg.imp_op_ex fecha_cbte = fecha # Fechas del per�odo del servicio facturado y vencimiento de pago: if concepto > 1: fecha_venc_pago = reg.fecha_venc_pago fecha_serv_desde = reg.fecha_serv_desde fecha_serv_hasta = reg.fecha_serv_desde else: fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None moneda_id = reg.moneda_id moneda_ctz = reg.moneda_ctz # datos generales del encabezado: incoterms = 'FOB' # solo exportación idioma_cbte = 1 # 1: es, 2: en, 3: pt # datos adicionales del encabezado: nombre_cliente = reg.nombre_cliente domicilio_cliente = reg.domicilio_cliente pais_dst_cmp = 212 # 200: Argentina, ver tabla id_impositivo = reg.id_impositivo # cat. iva (mercado interno) forma_pago = reg.forma_pago obs_generales = reg.obs obs_comerciales = reg.obs_comerciales # datos devueltos por el webservice (WSFEv1, WSMTXCA, etc.): motivo_obs = "Factura individual, DocTipo: 80, DocNro 30000000007 no se encuentra registrado en los padrones de AFIP." cae = reg.cae fch_venc_cae = reg.fecha_vto fepdf.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fch_venc_cae, id_impositivo, nombre_cliente, domicilio_cliente, pais_dst_cmp, obs_comerciales, obs_generales, forma_pago, incoterms, idioma_cbte, motivo_obs) # completo campos extra del encabezado: ok = fepdf.EstablecerParametro("localidad_cliente", "Hurlingham") ok = fepdf.EstablecerParametro("provincia_cliente", "Buenos Aires") # imprimir leyenda "Comprobante Autorizado" (constatar con WSCDC!) ok = fepdf.EstablecerParametro("resultado", "A") # tributos adicionales: tributo_id = 99 desc = 'Impuesto Municipal Matanza' base_imp = "100.00" alic = "1.00" importe = "1.00" fepdf.AgregarTributo(tributo_id, desc, base_imp, alic, importe) tributo_id = 4 desc = 'Impuestos Internos' base_imp = None alic = None importe = "0.00" fepdf.AgregarTributo(tributo_id, desc, base_imp, alic, importe) # subtotales por alícuota de IVA: iva_id = 5 # 21% base_imp = 100 importe = 21 fepdf.AgregarIva(iva_id, base_imp, importe) # detalle de artículos: registros = db(db.detalle_afip.comprobante_id==id_comprobante).select() for registro in registros: u_mtx = 123456 cod_mtx = 1234567890123 codigo = registro.codigo ds = registro.ds qty = registro.qty umed = 7 precio = registro.precio imp_iva = registro.imp_iva bonif = 0.00 iva_id = registro.iva_id importe = registro.imp_total despacho = u'' dato_a = "" fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho, dato_a) # descuento general (a tasa 21%): u_mtx = cod_mtx = codigo = None ds = u"Bonificación/Descuento 10%" qty = precio = bonif = None umed = 99 iva_id = 5 if tipo_cbte in (1, 2, 3, 4, 5, 34, 39, 51, 52, 53, 54, 60, 64): # discriminar IVA si es clase A / M imp_iva = -2.21 else: imp_iva = None importe = -12.10 fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, "") # descripción (sin importes ni cantidad): u_mtx = cod_mtx = codigo = None qty = precio = bonif = iva_id = imp_iva = importe = None umed = 0 ds = u"Descripción Ejemplo" fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, "") # completo campos personalizados de la plantilla: fepdf.AgregarDato("custom-nro-cli", "Cod.123") fepdf.AgregarDato("custom-pedido", "1234") fepdf.AgregarDato("custom-remito", "12345") fepdf.AgregarDato("custom-transporte", "Camiones Ej.") # datos fijos: for k, v in conf_pdf.items(): fepdf.AgregarDato(k, v) if k.upper() == 'CUIT': fepdf.CUIT = v # CUIT del emisor para código de barras fepdf.CrearPlantilla(papel=conf_fact.get("papel", "legal"), orientacion=conf_fact.get("orientacion", "portrait")) fepdf.ProcesarPlantilla(num_copias=int(conf_fact.get("copias", 1)), lineas_max=int(conf_fact.get("lineas_max", 24)), qty_pos=conf_fact.get("cant_pos") or 'izq') salida = "/tmp/factura.pdf" fepdf.GenerarPDF(archivo=salida) fepdf.MostrarPDF(archivo=salida,imprimir=False) response.headers['Content-Type'] = "application/pdf" return open(salida, "rb")
def pdf(): id = request.args[0] from pyafipws.pyfepdf import FEPDF fepdf = FEPDF() fepdf.CUIT = 20267565393 # cargo el formato CSV por defecto (factura.csv) t = os.path.join(request.env.web2py_path, 'applications', request.application, 'modules', 'pyafipws', 'factura.csv') fepdf.CargarFormato(t) f = db(db.pagos.id == id).select().first() if not f.cae: raise HTTP(500, "Debe soliticar CAE a AFIP antes de generar el PDF!") # creo una factura de ejemplo tipo_cbte = int(f.tipo_cbte) punto_vta = int(f.pto_vta) fecha = f.fecha.strftime("%Y%m%d") concepto = 3 tipo_doc = int(f.tipo_doc) nro_doc = int(f.nro_doc) cbte_nro = int(f.cbte_nro) imp_total = f.imp_total imp_tot_conc = "0.00" imp_neto = "0.00" imp_iva = "0.00" imp_trib = "0.00" imp_op_ex = "0.00" imp_subtotal = "0.00" fecha_cbte = fecha fecha_venc_pago = fecha # Fechas del período del servicio facturado (solo si concepto = 1?) fecha_serv_desde = fecha fecha_serv_hasta = fecha moneda_id = 'PES' moneda_ctz = '1.000' obs_generales = u"EMAIL: %s" % f.email obs_comerciales = u"En tu resumen verás el cargo como WWW.MERCADOPAGO.COM" nombre_cliente = "%s, %s" % (f.last_name, f.first_name) domicilio_cliente = "" pais_dst_cmp = 16 id_impositivo = "" moneda_id = 'PES' moneda_ctz = 1 forma_pago = f.forma_pago incoterms = 'FOB' idioma_cbte = 1 motivo = f.motivo cae = f.cae fch_venc_cae = f.fecha_vto fepdf.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fch_venc_cae, id_impositivo, nombre_cliente, domicilio_cliente, pais_dst_cmp, obs_comerciales, obs_generales, forma_pago, incoterms, idioma_cbte, motivo) #tipo = 91 #pto_vta = 2 #nro = 1234 #fepdf.AgregarCmpAsoc(tipo, pto_vta, nro) #tributo_id = 99 #desc = 'Impuesto Municipal Matanza' #base_imp = "100.00" #alic = "1.00" #importe = "1.00" #fepdf.AgregarTributo(tributo_id, desc, base_imp, alic, importe) #iva_id = 5 # 21% #base_imp = 100 #importe = 21 #fepdf.AgregarIva(iva_id, base_imp, importe) u_mtx = 123456 cod_mtx = 1234567890123 codigo = "P0001" ds = f.ds qty = 1.00 umed = 7 precio = f.imp_total bonif = 0.00 iva_id = 1 imp_iva = 0 importe = f.imp_total despacho = "" fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho) #fepdf.AgregarDato("pedido", "1234") fepdf.CrearPlantilla(papel="A4", orientacion="portrait") fepdf.ProcesarPlantilla(num_copias=3, lineas_max=24, qty_pos='izq') salida = t = os.path.join(request.env.web2py_path, 'applications', request.application, 'private', 'factura%s.pdf' % id) fepdf.GenerarPDF(archivo=salida) response.headers['Content-Type'] = 'application/pdf' return open(salida).read()
def facturar(registros): """Rutina para emitir facturas electrónicas en PDF c/CAE AFIP Argentina""" # inicialización AFIP: wsaa = WSAA() wsfev1 = WSFEv1() # obtener ticket de acceso (token y sign): ta = wsaa.Autenticar( "wsfe", CERT, PRIVATEKEY, wsdl=URL_WSAA, cache=CACHE, debug=True ) wsfev1.Cuit = CUIT wsfev1.SetTicketAcceso(ta) wsfev1.Conectar(CACHE, URL_WSFEv1) # inicialización PDF fepdf = FEPDF() fepdf.CargarFormato("factura.csv") fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" fepdf.CUIT = CUIT for k, v in CONF_PDF.items(): fepdf.AgregarDato(k, v) if "h**o" in URL_WSAA: fepdf.AgregarCampo( "DEMO", "T", 120, 260, 0, 0, text="DEMOSTRACION", size=70, rotate=45, foreground=0x808080, priority=-1, ) fepdf.AgregarDato("motivos_obs", "Ejemplo Sin validez fiscal") # recorrer los registros a facturar, solicitar CAE y generar el PDF: for reg in registros: hoy = datetime.date.today().strftime("%Y%m%d") cbte = Comprobante( tipo_cbte=6, punto_vta=4000, fecha_cbte=hoy, cbte_nro=reg.get("nro"), tipo_doc=96, nro_doc=reg["dni"], nombre_cliente=reg["nombre"], # "Juan Perez" domicilio_cliente=reg["domicilio"], # "Balcarce 50" fecha_serv_desde=reg.get("periodo_desde"), fecha_serv_hasta=reg.get("periodo_hasta"), fecha_venc_pago=reg.get("venc_pago", hoy), ) cbte.agregar_item( ds=reg["descripcion"], qty=reg.get("cantidad", 1), precio=reg.get("precio", 0), tasa_iva=reg.get("tasa_iva", 21.0), ) ok = cbte.autorizar(wsfev1) nro = cbte.encabezado["cbte_nro"] print("Factura autorizada", nro, cbte.encabezado["cae"]) if "h**o" in URL_WSFEv1: cbte.encabezado["motivos_obs"] = "Ejemplo Sin validez fiscal" ok = cbte.generar_pdf(fepdf, "/tmp/factura_{}.pdf".format(nro)) print("PDF generado", ok)
def create(self, cr, uid, ids, datas, context): import pooler pool = pooler.get_pool(cr.dbname) model_obj = pool.get("account.invoice") try: # import and instantiate the helper: from pyafipws.pyfepdf import FEPDF fepdf = FEPDF() # load CSV default format (factura.csv) fepdf.CargarFormato( os.path.join(os.path.dirname(__file__), "pyafipws", "factura.csv")) # set the logo image fepdf.AgregarDato( "logo", os.path.join(os.path.dirname(__file__), "pyafipws", "logo.png")) # set amount format (decimal places): fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" # TODO: complete all fields and additional data for invoice in model_obj.browse(cr, uid, ids)[:1]: # get the electronic invoice type, point of sale and service: journal = invoice.journal_id company = journal.company_id tipo_cbte = journal.pyafipws_invoice_type punto_vta = journal.pyafipws_point_of_sale # set basic AFIP data: fepdf.CUIT = company.pyafipws_cuit # get the last 8 digit of the invoice number cbte_nro = int(invoice.number[-8:]) cbt_desde = cbt_hasta = cbte_nro fecha_cbte = invoice.date_invoice concepto = tipo_expo = int(invoice.pyafipws_concept or 0) if int(concepto) != 1: fecha_venc_pago = invoice.date_invoice if invoice.pyafipws_billing_start_date: fecha_serv_desde = invoice.pyafipws_billing_start_date else: fecha_serv_desde = None if invoice.pyafipws_billing_end_date: fecha_serv_hasta = invoice.pyafipws_billing_end_date else: fecha_serv_hasta = None else: fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None # customer tax number: if invoice.partner_id.vat: nro_doc = invoice.partner_id.vat.replace("-", "") else: nro_doc = "0" # only "consumidor final" tipo_doc = 99 if nro_doc.startswith("AR"): nro_doc = nro_doc[2:] if int(nro_doc) == 0: tipo_doc = 99 # consumidor final elif len(nro_doc) < 11: tipo_doc = 96 # DNI else: tipo_doc = 80 # CUIT # invoice amount totals: imp_total = str("%.2f" % abs(invoice.amount_total)) imp_tot_conc = "0.00" imp_neto = str("%.2f" % abs(invoice.amount_untaxed)) imp_iva = str("%.2f" % abs(invoice.amount_tax)) imp_subtotal = imp_neto # TODO: not allways the case! imp_trib = "0.00" imp_op_ex = "0.00" if invoice.currency_id.name == 'ARS': moneda_id = "PES" moneda_ctz = 1 else: moneda_id = {'USD': 'DOL'}[invoice.currency_id.name] moneda_ctz = str(invoice.currency_id.rate) # foreign trade data: export permit, country code, etc.: if False: ##invoice.pyafipws_incoterms: incoterms = invoice.pyafipws_incoterms.code incoterms_ds = invoice.pyafipws_incoterms.name else: incoterms = incoterms_ds = None if int(tipo_cbte) == 19 and tipo_expo == 1: permiso_existente = "N" or "S" # not used now else: permiso_existente = "" obs_generales = invoice.comment if invoice.payment_term: forma_pago = invoice.payment_term.name obs_comerciales = invoice.payment_term.name else: forma_pago = obs_comerciales = None idioma_cbte = 1 # invoice language: spanish / español # customer data (foreign trade): nombre_cliente = invoice.partner_id.name if invoice.partner_id.vat: if invoice.partner_id.vat.startswith("AR"): # use the Argentina AFIP's global CUIT for the country: cuit_pais_cliente = invoice.partner_id.vat[2:] id_impositivo = None else: # use the VAT number directly id_impositivo = invoice.partner_id.vat[2:] # TODO: the prefix could be used to map the customer country cuit_pais_cliente = None else: cuit_pais_cliente = id_impositivo = None # address_invoice_id -> partner_id if invoice.partner_id: domicilio_cliente = " - ".join([ invoice.partner_id.name or '', invoice.partner_id.street or '', invoice.partner_id.street2 or '', ]) localidad_cliente = " - ".join([ invoice.partner_id.city or '', invoice.partner_id.zip or '', ]) provincia_cliente = invoice.partner_id.state_id else: domicilio_cliente = "" localidad_cliente = "" provincia_cliente = "" if invoice.partner_id.country_id: # map ISO country code to AFIP destination country code: iso_code = invoice.partner_id.country_id.code.lower() pais_dst_cmp = AFIP_COUNTRY_CODE_MAP[iso_code] # set AFIP returned values cae = invoice.pyafipws_cae or "" fch_venc_cae = (invoice.pyafipws_cae_due_date or "").replace("-", "") motivo = invoice.pyafipws_message or "" # create the invoice internally in the helper fepdf.CrearFactura( concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fch_venc_cae, id_impositivo, nombre_cliente, domicilio_cliente, pais_dst_cmp, obs_comerciales, obs_generales, forma_pago, incoterms, idioma_cbte, motivo) # set custom extra data: fepdf.AgregarDato("localidad_cliente", localidad_cliente) fepdf.AgregarDato("provincia_cliente", provincia_cliente) # analyze VAT (IVA) and other taxes (tributo): for tax_line in invoice.tax_line: if "IVA" in tax_line.name: if '0%' in tax_line.name: iva_id = 3 elif '10,5%' in tax_line.name: iva_id = 4 elif '21%' in tax_line.name: iva_id = 5 elif '27%' in tax_line.name: iva_id = 6 else: ivva_id = 0 base_imp = ("%.2f" % abs(tax_line.base)) importe = ("%.2f" % abs(tax_line.amount)) # add the vat detail in the helper fepdf.AgregarIva(iva_id, base_imp, importe) else: if 'impuesto' in tax_line.name.lower(): tributo_id = 1 # nacional elif 'iibbb' in tax_line.name.lower(): tributo_id = 3 # provincial elif 'tasa' in tax_line.name.lower(): tributo_id = 4 # municipal else: tributo_id = 99 desc = tax_line.name base_imp = ("%.2f" % abs(tax_line.base)) importe = ("%.2f" % abs(tax_line.amount)) alic = "%.2f" % tax_line.base # add the other tax detail in the helper fepdf.AgregarTributo(id, desc, base_imp, alic, importe) # analize line items - invoice detail for line in invoice.invoice_line: codigo = line.product_id.code u_mtx = 1 # TODO: get it from uom? cod_mtx = line.product_id.ean13 ds = line.name qty = line.quantity umed = 7 # TODO: line.uos_id...? precio = line.price_unit importe = line.price_subtotal bonif = line.discount or None iva_id = 5 # TODO: line.tax_code_id? imp_iva = importe * line.invoice_line_tax_id[0].amount fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho="") fepdf.CrearPlantilla(papel="A4", orientacion="portrait") fepdf.ProcesarPlantilla(num_copias=1, lineas_max=24, qty_pos='izq') report_type = datas.get('report_type', 'pdf') pdf = fepdf.GenerarPDF() return (pdf, report_type) except: # catch the exception and send a better message for the user: from pyafipws import utils ex = utils.exception_info() raise osv.except_osv(ex['msg'], ex['tb'])
def generar_pdf(): CONFIG_FILE = "/home/rodrigo/pyafipws/rece.ini" config = SafeConfigParser() config.read(CONFIG_FILE) conf_fact = dict(config.items('FACTURA')) conf_pdf = dict(config.items('PDF')) fepdf = FEPDF() # cargo el formato CSV por defecto (factura.csv) fepdf.CargarFormato(conf_fact.get("formato", "factura.csv")) # establezco formatos (cantidad de decimales) según configuración: fepdf.FmtCantidad = conf_fact.get("fmt_cantidad", "0.2") fepdf.FmtPrecio = conf_fact.get("fmt_precio", "0.2") # creo una factura de ejemplo H**O = True # datos generales del encabezado: tipo_cbte = 1 punto_vta = 4000 fecha = datetime.datetime.now().strftime("%Y%m%d") concepto = 3 tipo_doc = 80; nro_doc = "30000000007" cbte_nro = 12345678 imp_total = "127.00" imp_tot_conc = "3.00" imp_neto = "100.00" imp_iva = "21.00" imp_trib = "1.00" imp_op_ex = "2.00" imp_subtotal = "105.00" fecha_cbte = fecha fecha_venc_pago = fecha # Fechas del período del servicio facturado (solo si concepto> 1) fecha_serv_desde = fecha fecha_serv_hasta = fecha # campos p/exportación (ej): DOL para USD, indicando cotización: moneda_id = 'PES' moneda_ctz = 1 incoterms = 'FOB' # solo exportación idioma_cbte = 1 # 1: es, 2: en, 3: pt # datos adicionales del encabezado: nombre_cliente = 'Juan Perez' domicilio_cliente = 'Rua 76 km 34.5 Alagoas' pais_dst_cmp = 212 # 200: Argentina, ver tabla id_impositivo = 'PJ54482221-l' # cat. iva (mercado interno) forma_pago = '30 dias' obs_generales = "Observaciones Generales<br/>linea2<br/>linea3" obs_comerciales = "Observaciones Comerciales<br/>texto libre" # datos devueltos por el webservice (WSFEv1, WSMTXCA, etc.): motivo_obs = "Factura individual, DocTipo: 80, DocNro 30000000007 no se encuentra registrado en los padrones de AFIP." cae = session.cae fch_venc_cae = "20110320" fepdf.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fch_venc_cae, id_impositivo, nombre_cliente, domicilio_cliente, pais_dst_cmp, obs_comerciales, obs_generales, forma_pago, incoterms, idioma_cbte, motivo_obs) # completo campos extra del encabezado: ok = fepdf.EstablecerParametro("localidad_cliente", "Hurlingham") ok = fepdf.EstablecerParametro("provincia_cliente", "Buenos Aires") # imprimir leyenda "Comprobante Autorizado" (constatar con WSCDC!) ok = fepdf.EstablecerParametro("resultado", "A") # tributos adicionales: tributo_id = 99 desc = 'Impuesto Municipal Matanza' base_imp = "100.00" alic = "1.00" importe = "1.00" fepdf.AgregarTributo(tributo_id, desc, base_imp, alic, importe) tributo_id = 4 desc = 'Impuestos Internos' base_imp = None alic = None importe = "0.00" fepdf.AgregarTributo(tributo_id, desc, base_imp, alic, importe) # subtotales por alícuota de IVA: iva_id = 5 # 21% base_imp = 100 importe = 21 fepdf.AgregarIva(iva_id, base_imp, importe) # detalle de artículos: u_mtx = 123456 cod_mtx = 1234567890123 codigo = "P0001" ds = "Descripcion del producto P0001\n" qty = 1.00 umed = 7 if tipo_cbte in (1, 2, 3, 4, 5, 34, 39, 51, 52, 53, 54, 60, 64): # discriminar IVA si es clase A / M precio = 110.00 imp_iva = 23.10 else: # no discriminar IVA si es clase B (importe final iva incluido) precio = 133.10 imp_iva = None bonif = 0.00 iva_id = 5 importe = 133.10 despacho = u'Nº 123456' dato_a = "Dato A" fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho, dato_a) # descuento general (a tasa 21%): u_mtx = cod_mtx = codigo = None ds = u"Bonificación/Descuento 10%" qty = precio = bonif = None umed = 99 iva_id = 5 if tipo_cbte in (1, 2, 3, 4, 5, 34, 39, 51, 52, 53, 54, 60, 64): # discriminar IVA si es clase A / M imp_iva = -2.21 else: imp_iva = None importe = -12.10 fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, "") # descripción (sin importes ni cantidad): u_mtx = cod_mtx = codigo = None qty = precio = bonif = iva_id = imp_iva = importe = None umed = 0 ds = u"Descripción Ejemplo" fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, "") # completo campos personalizados de la plantilla: fepdf.AgregarDato("custom-nro-cli", "Cod.123") fepdf.AgregarDato("custom-pedido", "1234") fepdf.AgregarDato("custom-remito", "12345") fepdf.AgregarDato("custom-transporte", "Camiones Ej.") print "Prueba!" # datos fijos: for k, v in conf_pdf.items(): fepdf.AgregarDato(k, v) if k.upper() == 'CUIT': fepdf.CUIT = v # CUIT del emisor para código de barras fepdf.CrearPlantilla(papel=conf_fact.get("papel", "legal"), orientacion=conf_fact.get("orientacion", "portrait")) fepdf.ProcesarPlantilla(num_copias=int(conf_fact.get("copias", 1)), lineas_max=int(conf_fact.get("lineas_max", 24)), qty_pos=conf_fact.get("cant_pos") or 'izq') salida = "/tmp/factura.pdf" fepdf.GenerarPDF(archivo=salida) ##fepdf.MostrarPDF(archivo=salida,imprimir=False) response.headers['Content-Type'] = "application/pdf" return open(salida, "rb")
def ImprimeFactura(self, idcabecera=None, mostrar=True, *args, **kwargs): if not idcabecera: return cabfact = Cabfact().get_by_id(idcabecera) print("imprimir factura {}".format(cabfact.numero)) pyfpdf = FEPDF() #cuit del emisor pyfpdf.CUIT = LeerIni(clave='cuit', key='WSFEv1') #establezco formatos (cantidad de decimales): pyfpdf.FmtCantidad = "0.4" pyfpdf.FmtPrecio = "0.2" #Datos del encabezado de la factura: tipo_cbte = cabfact.tipocomp.codigo punto_vta = cabfact.numero[:4] cbte_nro = cabfact.numero[-8:] fecha = FechaMysql(cabfact.fecha) concepto = cabfact.concepto #datos del cliente: tipo_doc = "80" if cabfact.cliente.tiporesp_id != 3 else "96" nro_doc = cabfact.cliente.cuit if cabfact.cliente.tiporesp_id != 3 else str( cabfact.cliente.dni) nombre_cliente = cabfact.nombre if cabfact.nombre != '' else cabfact.cliente.nombre domicilio_cliente = cabfact.domicilio #totales del comprobante: imp_total = cabfact.total imp_tot_conc = "0.00" imp_neto = cabfact.neto imp_iva = cabfact.iva imp_trib = cabfact.percepciondgr imp_op_ex = "0.00" imp_subtotal = cabfact.neto fecha_cbte = fecha fecha_venc_pago = fecha #Fechas del período del servicio facturado if int(cabfact.concepto) in [ FEv1().SERVICIOS, FEv1().PRODUCTOYSERVICIOS ]: fecha_serv_desde = FechaMysql(cabfact.desde) fecha_serv_hasta = FechaMysql(cabfact.hasta) else: fecha_serv_hasta = None fecha_serv_desde = None moneda_id = "PES" moneda_ctz = "1.000" obs_generales = "" obs_comerciales = "" moneda_id = "" moneda_ctz = 1 cae = cabfact.cae fecha_vto_cae = FechaMysql(cabfact.venccae) #Creo la factura(internamente en la interfaz) ok = pyfpdf.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fecha_vto_cae, "", nombre_cliente, domicilio_cliente, 0) pyfpdf.EstablecerParametro("forma_pago", cabfact.formapago.detalle) pyfpdf.EstablecerParametro( "custom-nro-cli", "[{}]".format(str(cabfact.cliente.idcliente).zfill(5))) pyfpdf.EstablecerParametro("localidad_cli", cabfact.cliente.localidad.nombre) pyfpdf.EstablecerParametro("provincia_cli", cabfact.cliente.localidad.provincia) pyfpdf.EstablecerParametro("iva_cli", cabfact.cliente.tiporesp.nombre) #Agregar comprobantes asociados(si es una NC / ND): if cabfact.tipocomp.codigo in [3, 8, 13]: cpbterel = CpbteRel().select().where( CpbteRel.idcabfact == cabfact.idcabfact) for cp in cpbterel: tipo = cp.idtipocpbte.codigo pto_vta = cp.numero[:4] nro = cp.numero[-8:] pyfpdf.AgregarCmpAsoc(tipo, pto_vta, nro) # if str(self.view.cboComprobante.text()).find('credito'): # tipo = 19 # pto_vta = 2 # nro = 1234 # pyfepdf.AgregarCmpAsoc(tipo, pto_vta, nro) #Agrego subtotales de IVA(uno por alicuota) if cabfact.netoa != 0: iva_id = 5 #c�digo para al�cuota del 21 % base_imp = cabfact.netoa #importe neto sujeto a esta al�cuota importe = cabfact.netoa * 21 / 100 #importe liquidado de iva ok = pyfpdf.AgregarIva(iva_id, base_imp, importe) if cabfact.netob != 0: iva_id = 4 # c�digo para al�cuota del 10.5 % base_imp = cabfact.netob # importe neto sujeto a esta al�cuota importe = cabfact.netob * 10.5 / 100 # importe liquidado de iva ok = pyfpdf.AgregarIva(iva_id, base_imp, importe) if cabfact.netoa == 0 and cabfact.netob == 0: iva_id = 3 # c�digo para al�cuota del 21 % base_imp = cabfact.netob # importe neto sujeto a esta al�cuota importe = 0 # importe liquidado de iva ok = pyfpdf.AgregarIva(iva_id, base_imp, importe) if cabfact.percepciondgr != 0: #Agregar cada impuesto(por ej.IIBB, retenciones, percepciones, etc.): tributo_id = 99 #codigo para 99 - otros tributos Desc = cabfact.cliente.percepcion.detalle base_imp = cabfact.neto #importe sujeto a estetributo alic = cabfact.cliente.percepcion.porcentaje #alicuota(porcentaje) de estetributo importe = cabfact.percepciondgr #importe liquidado de este tributo ok = pyfpdf.AgregarTributo(tributo_id, Desc, base_imp, alic, importe) det = Detfact().select().where(Detfact.idcabfact == cabfact.idcabfact) for d in det: #Agrego detalles de cada item de la factura: u_mtx = 0 #unidades cod_mtx = "" #c�digo de barras codigo = d.idarticulo.idarticulo #codigo interno a imprimir(ej. "articulo") ds = d.descad.strip() qty = d.cantidad #cantidad umed = 7 #c�digo de unidad de medida(ej. 7 para"unidades") precio = d.precio #precio neto(A) o iva incluido(B) bonif = 0 #importe de descuentos iva_id = FEv1().TASA_IVA[str(float( d.tipoiva.iva))] #c�digopara al�cuota del 21 % imp_iva = d.montoiva #importe liquidado deiva importe = d.precio * d.cantidad #importe total del item despacho = "" #numero de despacho de importaci�n dato_a = "" #primer dato adicional del item dato_b = "" dato_c = "" dato_d = "" dato_e = "" #ultimo dato adicionaldel item ok = pyfpdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho, dato_a, dato_b, dato_c, dato_d, dato_e) #Agrego datos adicionales fijos: ok = pyfpdf.AgregarDato("logo", ubicacion_sistema() + "plantillas/logo.png") fondo = ParamSist.ObtenerParametro("FONDO_FACTURA") if fondo: x1 = ParamSist.ObtenerParametro("FONDO_FACTURA_X1") or 50 y1 = ParamSist.ObtenerParametro("FONDO_FACTURA_Y1") or 117.1 x2 = ParamSist.ObtenerParametro("FONDO_FACTURA_X2") or 150 y2 = ParamSist.ObtenerParametro("FONDO_FACTURA_Y2") or 232.9 pyfpdf.AgregarCampo("fondo_factura", 'I', x1, y1, x2, y2, foreground=0x808080, priority=-1, text=imagen(fondo)) ok = pyfpdf.AgregarDato( "EMPRESA", "Razon social: {}".format( DeCodifica(LeerIni(clave='empresa', key='FACTURA')))) ok = pyfpdf.AgregarDato( "MEMBRETE1", "Domicilio Comercial: {}".format( DeCodifica(LeerIni(clave='membrete1', key='FACTURA')))) ok = pyfpdf.AgregarDato( "MEMBRETE2", DeCodifica(LeerIni(clave='membrete2', key='FACTURA'))) ok = pyfpdf.AgregarDato( "CUIT", 'CUIT: {}'.format(LeerIni(clave='cuit', key='WSFEv1'))) ok = pyfpdf.AgregarDato("IIBB", LeerIni(clave='iibb', key='FACTURA')) ok = pyfpdf.AgregarDato( "IVA", "Condicion frente al IVA: {}".format( LeerIni(clave='iva', key='FACTURA'))) ok = pyfpdf.AgregarDato( "INICIO", "Fecha inicio actividades: {}".format( LeerIni(clave='inicio', key='FACTURA'))) if int(cabfact.tipocomp.codigo ) in Constantes.COMPROBANTES_FCE: #si es una FCE pyfpdf.AgregarDato('CBUFCE', LeerIni('CBUFCE', key='FACTURA')) pyfpdf.AgregarDato('ALIASFCE', LeerIni('ALIASFCE', key='FACTURA')) pyfpdf.AgregarDato('nombre_condvta', Constantes.COND_VTA['T']) ok = pyfpdf.CargarFormato(ubicacion_sistema() + "/plantillas/factura-fce.csv") else: #Cargo el formato desde el archivo CSV(opcional) #(carga todos los campos a utilizar desde la planilla) ok = pyfpdf.CargarFormato(ubicacion_sistema() + "/plantillas/factura.csv") #Creo plantilla para esta factura(papel A4vertical): if LeerIni(clave='h**o') == 'S': pyfpdf.AgregarCampo("h**o", 'T', 150, 350, 0, 0, size=70, rotate=45, foreground=0x808080, priority=-1, text="HOMOLOGACION") papel = "A4" #o "letter" para carta, "legal" para oficio orientacion = "portrait" #o landscape(apaisado) ok = pyfpdf.CrearPlantilla(papel, orientacion) num_copias = int( LeerIni(clave='num_copias', key='FACTURA')) #original, duplicado y triplicado lineas_max = 24 #cantidad de linas de items porp�gina qty_pos = "izq" #(cantidad a la izquierda de la descripci�n del art�culo) #Proceso la plantilla ok = pyfpdf.ProcesarPlantilla(num_copias, lineas_max, qty_pos) if not os.path.isdir('facturas'): os.mkdir('facturas') #Genero el PDF de salida seg�n la plantilla procesada salida = join( 'facturas', "{}-{}.pdf".format(cabfact.tipocomp.nombre, cabfact.numero)) ok = pyfpdf.GenerarPDF(salida) #Abro el visor de PDF y muestro lo generado #(es necesario tener instalado Acrobat Reader o similar) imprimir = False #cambiar a True para que lo envie directo a laimpresora if mostrar: pyfpdf.MostrarPDF(salida, imprimir) self.facturaGenerada = salida
import os import sys import datetime import pytest from pyafipws.wsaa import WSAA from pyafipws.pyfepdf import FEPDF from pyafipws.pyfepdf import main from builtins import str from pyafipws.utils import SafeConfigParser import shutil CERT = "reingart.crt" PKEY = "reingart.key" CONFIG_FILE = "rece.ini" fepdf = FEPDF() pytestmark = [pytest.mark.dontusefix] shutil.copy("tests/facturas.json", "facturas.json") def test_crear_factura(): """Test de creación de una factura (Interna).""" tipo_cbte = 19 if "--expo" in sys.argv else 201 punto_vta = 4000 fecha = datetime.datetime.now().strftime("%Y%m%d") concepto = 3 tipo_doc = 80 nro_doc = "30000000007" cbte_nro = 12345678
def generate_invoices(records): """Generate the invoices in PDF using AFIP API resources.""" wsfev1 = _get_afip() # init PDF builder fepdf = FEPDF() fepdf.CargarFormato("factura.csv") fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" fepdf.CUIT = settings.AFIP['cuit'] for k, v in CONFIG_PDF.items(): fepdf.AgregarDato(k, v) # safeguard when using test webservice endpoints if "h**o" in settings.AFIP['url_wsaa']: fepdf.AgregarCampo("DEMO", 'T', 120, 260, 0, 0, text="DEMOSTRACION", size=70, rotate=45, foreground=0x808080, priority=-1) fepdf.AgregarDato("motivos_obs", "Ejemplo Sin Validez Fiscal") # get CAE for each record and generate corresponding PDF results = {} for record in records: invoice = MemberInvoice(document_number=record['dni'], fullname=record['fullname'], address=record['address'], city=record['city'], zip_code=record['zip_code'], province=record['province'], invoice_date=record['invoice_date'], invoice_number=record['invoice'], service_date_from=record['service_date_from'], service_date_to=record['service_date_to']) invoice.add_item(description=record['description'], quantity=record['quantity'], amount=record['amount'], comment=record['payment_comment']) authorized_ok = invoice.autorizar(wsfev1) invoice_number = invoice.header["cbte_nro"] print(" invoice generated: number={} CAE={} authorized={}".format( invoice_number, invoice.header["cae"], authorized_ok)) results[invoice_number] = {'invoice_ok': authorized_ok} if not authorized_ok: print("WARNING not auth") return # another safeguard if "h**o" in settings.AFIP['url_wsfev1']: invoice.header["motivos_obs"] = "Ejemplo Sin validez fiscal" # generate the PDF pdf_name = "FacturaPyArAC-{:04d}-{:08d}.pdf".format( settings.AFIP['selling_point'], invoice_number) pdf_path = os.path.join(PDF_PATH, pdf_name) invoice.generate_pdf(fepdf, pdf_path) print(" PDF generated {!r}".format(pdf_path)) results[invoice_number]['pdf_path'] = pdf_path return results
def create(self, cr, uid, ids, datas, context): import pooler pool = pooler.get_pool(cr.dbname) model_obj = pool.get("account.invoice") try: # import and instantiate the helper: from pyafipws.pyfepdf import FEPDF fepdf = FEPDF() # load CSV default format (factura.csv) fepdf.CargarFormato(os.path.join(os.path.dirname(__file__), "pyafipws", "factura.csv")) # set the logo image fepdf.AgregarDato("logo", os.path.join(os.path.dirname(__file__), "pyafipws", "logo.png")) # set amount format (decimal places): fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" # TODO: complete all fields and additional data for invoice in model_obj.browse(cr, uid, ids)[:1]: # get the electronic invoice type, point of sale and service: journal = invoice.journal_id company = journal.company_id tipo_cbte = journal.pyafipws_invoice_type punto_vta = journal.pyafipws_point_of_sale # set basic AFIP data: fepdf.CUIT = company.pyafipws_cuit # get the last 8 digit of the invoice number cbte_nro = int(invoice.number[-8:]) cbt_desde = cbt_hasta = cbte_nro fecha_cbte = invoice.date_invoice concepto = tipo_expo = int(invoice.pyafipws_concept or 0) if int(concepto) != 1: fecha_venc_pago = invoice.date_invoice if invoice.pyafipws_billing_start_date: fecha_serv_desde = invoice.pyafipws_billing_start_date else: fecha_serv_desde = None if invoice.pyafipws_billing_end_date: fecha_serv_hasta = invoice.pyafipws_billing_end_date else: fecha_serv_hasta = None else: fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None # customer tax number: if invoice.partner_id.vat: nro_doc = invoice.partner_id.vat.replace("-","") else: nro_doc = "0" # only "consumidor final" tipo_doc = 99 if nro_doc.startswith("AR"): nro_doc = nro_doc[2:] if int(nro_doc) == 0: tipo_doc = 99 # consumidor final elif len(nro_doc) < 11: tipo_doc = 96 # DNI else: tipo_doc = 80 # CUIT # invoice amount totals: imp_total = str("%.2f" % abs(invoice.amount_total)) imp_tot_conc = "0.00" imp_neto = str("%.2f" % abs(invoice.amount_untaxed)) imp_iva = str("%.2f" % abs(invoice.amount_tax)) imp_subtotal = imp_neto # TODO: not allways the case! imp_trib = "0.00" imp_op_ex = "0.00" if invoice.currency_id.name == 'ARS': moneda_id = "PES" moneda_ctz = 1 else: moneda_id = {'USD':'DOL'}[invoice.currency_id.name] moneda_ctz = str(invoice.currency_id.rate) # foreign trade data: export permit, country code, etc.: if False: ##invoice.pyafipws_incoterms: incoterms = invoice.pyafipws_incoterms.code incoterms_ds = invoice.pyafipws_incoterms.name else: incoterms = incoterms_ds = None if int(tipo_cbte) == 19 and tipo_expo == 1: permiso_existente = "N" or "S" # not used now else: permiso_existente = "" obs_generales = invoice.comment if invoice.payment_term: forma_pago = invoice.payment_term.name obs_comerciales = invoice.payment_term.name else: forma_pago = obs_comerciales = None idioma_cbte = 1 # invoice language: spanish / español # customer data (foreign trade): nombre_cliente = invoice.partner_id.name if invoice.partner_id.vat: if invoice.partner_id.vat.startswith("AR"): # use the Argentina AFIP's global CUIT for the country: cuit_pais_cliente = invoice.partner_id.vat[2:] id_impositivo = None else: # use the VAT number directly id_impositivo = invoice.partner_id.vat[2:] # TODO: the prefix could be used to map the customer country cuit_pais_cliente = None else: cuit_pais_cliente = id_impositivo = None # address_invoice_id -> partner_id if invoice.partner_id: domicilio_cliente = " - ".join([ invoice.partner_id.name or '', invoice.partner_id.street or '', invoice.partner_id.street2 or '', ]) localidad_cliente = " - ".join([ invoice.partner_id.city or '', invoice.partner_id.zip or '', ]) provincia_cliente = invoice.partner_id.state_id else: domicilio_cliente = "" localidad_cliente = "" provincia_cliente = "" if invoice.partner_id.country_id: # map ISO country code to AFIP destination country code: iso_code = invoice.partner_id.country_id.code.lower() pais_dst_cmp = AFIP_COUNTRY_CODE_MAP[iso_code] # set AFIP returned values cae = invoice.pyafipws_cae or "" fch_venc_cae = (invoice.pyafipws_cae_due_date or "").replace("-", "") motivo = invoice.pyafipws_message or "" # create the invoice internally in the helper fepdf.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbte_nro, imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, moneda_id, moneda_ctz, cae, fch_venc_cae, id_impositivo, nombre_cliente, domicilio_cliente, pais_dst_cmp, obs_comerciales, obs_generales, forma_pago, incoterms, idioma_cbte, motivo) # set custom extra data: fepdf.AgregarDato("localidad_cliente", localidad_cliente) fepdf.AgregarDato("provincia_cliente", provincia_cliente) # analyze VAT (IVA) and other taxes (tributo): for tax_line in invoice.tax_line: if "IVA" in tax_line.name: if '0%' in tax_line.name: iva_id = 3 elif '10,5%' in tax_line.name: iva_id = 4 elif '21%' in tax_line.name: iva_id = 5 elif '27%' in tax_line.name: iva_id = 6 else: ivva_id = 0 base_imp = ("%.2f" % abs(tax_line.base)) importe = ("%.2f" % abs(tax_line.amount)) # add the vat detail in the helper fepdf.AgregarIva(iva_id, base_imp, importe) else: if 'impuesto' in tax_line.name.lower(): tributo_id = 1 # nacional elif 'iibbb' in tax_line.name.lower(): tributo_id = 3 # provincial elif 'tasa' in tax_line.name.lower(): tributo_id = 4 # municipal else: tributo_id = 99 desc = tax_line.name base_imp = ("%.2f" % abs(tax_line.base)) importe = ("%.2f" % abs(tax_line.amount)) alic = "%.2f" % tax_line.base # add the other tax detail in the helper fepdf.AgregarTributo(id, desc, base_imp, alic, importe) # analize line items - invoice detail for line in invoice.invoice_line: codigo = line.product_id.code u_mtx = 1 # TODO: get it from uom? cod_mtx = line.product_id.ean13 ds = line.name qty = line.quantity umed = 7 # TODO: line.uos_id...? precio = line.price_unit importe = line.price_subtotal bonif = line.discount or None iva_id = 5 # TODO: line.tax_code_id? imp_iva = importe * line.invoice_line_tax_id[0].amount fepdf.AgregarDetalleItem(u_mtx, cod_mtx, codigo, ds, qty, umed, precio, bonif, iva_id, imp_iva, importe, despacho="") fepdf.CrearPlantilla(papel="A4", orientacion="portrait") fepdf.ProcesarPlantilla(num_copias=1, lineas_max=24, qty_pos='izq') report_type = datas.get('report_type', 'pdf') pdf = fepdf.GenerarPDF() return (pdf, report_type) except: # catch the exception and send a better message for the user: from pyafipws import utils ex = utils.exception_info() raise osv.except_osv(ex['msg'], ex['tb'])
def generate_invoices(records): """Generate the invoices in PDF using AFIP API resources.""" # AFIP init wsaa = WSAA() wsfev1 = WSFEv1() # get access ticket (token y sign) certificate = settings.AFIP['auth_cert_path'] private_key = settings.AFIP['auth_key_path'] if not os.path.exists(certificate): raise ValueError( "Auth certificate can not be found (got {!r})".format(certificate)) if not os.path.exists(private_key): raise ValueError( "Auth key can not be found (got {!r})".format(private_key)) ta = wsaa.Autenticar("wsfe", certificate, private_key, wsdl=settings.AFIP['url_wsaa'], cache=CACHE, debug=True) wsfev1.Cuit = settings.AFIP['cuit'] wsfev1.SetTicketAcceso(ta) wsfev1.Conectar(CACHE, settings.AFIP['url_wsfev1']) # init PDF builder fepdf = FEPDF() fepdf.CargarFormato("factura.csv") fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" fepdf.CUIT = settings.AFIP['cuit'] for k, v in CONFIG_PDF.items(): fepdf.AgregarDato(k, v) # safeguard when using test webservice endpoints if "h**o" in settings.AFIP['url_wsaa']: fepdf.AgregarCampo("DEMO", 'T', 120, 260, 0, 0, text="DEMOSTRACION", size=70, rotate=45, foreground=0x808080, priority=-1) fepdf.AgregarDato("motivos_obs", "Ejemplo Sin Validez Fiscal") # get CAE for each record and generate corresponding PDF results = {} for record in records: invoice = MemberInvoice(document_number=record['dni'], fullname=record['fullname'], address=record['address'], city=record['city'], zip_code=record['zip_code'], province=record['province'], invoice_date=record['invoice_date'], invoice_number=record['invoice'], service_date_from=record['service_date_from'], service_date_to=record['service_date_to']) invoice.add_item(description=record['description'], quantity=record['quantity'], amount=record['amount'], comment=record['payment_comment']) authorized_ok = invoice.autorizar(wsfev1) invoice_number = invoice.header["cbte_nro"] print(" invoice generated: number={} CAE={} authorized={}".format( invoice_number, invoice.header["cae"], authorized_ok)) results[invoice_number] = {'invoice_ok': authorized_ok} if not authorized_ok: print("WARNING not auth") return # another safeguard if "h**o" in settings.AFIP['url_wsfev1']: invoice.header["motivos_obs"] = "Ejemplo Sin validez fiscal" # generate the PDF pdf_name = "FacturaPyArAC-{:04d}-{:08d}.pdf".format( settings.AFIP['selling_point'], invoice_number) pdf_path = os.path.join(PDF_PATH, pdf_name) invoice.generate_pdf(fepdf, pdf_path) print(" PDF generated {!r}".format(pdf_path)) results[invoice_number]['pdf_path'] = pdf_path return results