def crear_factura_base(): from gluon.contrib.pyfpdf.template import Template mensaje = "" # Si no se creó la demo agregar a la base de datos template = db(db.pdftemplate.title == "Demo invoice pyfpdf").select().first() if not template: template = db.pdftemplate.insert(title="Demo invoice pyfpdf", format = "A4") mensaje += "Se creó el template por defecto. " else: mensaje += "El template ya existe en la base de datos. " # eliminar todos los elementos del template por defecto. db(db.pdfelement.pdftemplate == template.id).delete() f = Template() f.parse_csv(infile=os.path.join(request.env.web2py_path,'applications', request.application, 'private', 'invoice.csv'), delimiter=";", decimal_sep=",") nro = 0 creados = 0 for k, v in f.elements.items(): nro += 1 try: v['align']= {'I':'L','D':'R','C':'C','J':'J',"":""}.get(v['align'], 'L') v['pdftemplate'] = template.id db.pdfelement.insert(**v) creados += 1 except (AttributeError, ValueError, KeyError, TypeError), e: mensaje += "Error en elemento nro: " + str(nro) + " - " + str(e) + ". "
def sample(): # show the current user badge (or from another user if manager) if request.args and auth.has_membership(role='manager'): user_id = request.args[0] else: user_id = auth.user_id user = db(db.auth_user.id==user_id).select().first() # read elements from db elements = db(db.pdf_element.pdf_template_id==1).select(orderby=db.pdf_element.priority) f = Template(format=(75,105), elements = list(elements), title="Sample Badges", author="web2conf", subject="", keywords="") f.add_page() d = build_badge_dict(user) for k, v in d.items(): f[k] = v field = { 'name': 'h**o', 'type': 'T', 'x1': 65, 'y1': 120, 'x2': 0, 'y2': 0, 'font': "Arial", 'size': 30, 'rotate': 45, 'bold': True, 'italic': False, 'underline': False, 'foreground': 0xC0C0C0, 'background': 0xFFFFFF, 'align': "L", 'text': "SAMPLE", 'priority': 10000} if not auth.has_membership(role="manager"): f.elements.append(field) response.headers['Content-Type']='application/pdf' return f.render('badge.pdf', dest='S')
def import_csv(): from gluon.contrib.pyfpdf import Template f = Template() f.parse_csv(infile="/home/reingart/web2py/gluon/contrib/pyfpdf/invoice.csv", delimiter=";", decimal_sep=",") for v in f.fields.elements(): v["align"] = {"I": "L", "D": "R", "C": "C", "": ""}.get(v["align"], "L") v["pdf_template_id"] = 1 db.pdf_element.insert(**v)
def import_csv(): from gluon.contrib.pyfpdf import Template f = Template() f.parse_csv(infile="/home/reingart/web2py/gluon/contrib/pyfpdf/invoice.csv", delimiter=";", decimal_sep=",") for v in f.fields.elements(): v['align']= {'I':'L','D':'R','C':'C','':''}.get(v['align'], 'L') v['pdf_template_id'] = 1 db.pdf_element.insert(**v)
def speakers_badges(): # set template to use from the db: pdf_template_id = 3 # query registered users and generate speaker labels speakers = db(db.auth_user.id > 0).select(orderby=db.auth_user.last_name | db.auth_user.first_name) company_name = "web2conf" attendee_type = "Speaker" # read elements from db elements = db(db.pdf_element.pdf_template_id == pdf_template_id).select( orderby=db.pdf_element.priority) f = Template(format="A4", elements=elements, title="Speaker Badges", author="web2conf", subject="", keywords="") # calculate pages: label_count = len(speakers) max_labels_per_page = 5 * 2 pages = label_count / (max_labels_per_page - 1) if label_count % (max_labels_per_page - 1): pages = pages + 1 # fill placeholders for each page for page in range(1, pages + 1): f.add_page() k = 0 li = 0 for speaker in speakers: k = k + 1 if k > page * (max_labels_per_page): break if k > (page - 1) * (max_labels_per_page): li += 1 #f['item_quantity%02d' % li] = it['qty'] f['name%02d' % li] = unicode( "%s %s" % (speaker.first_name, speaker.last_name), "utf8") f['company_name%02d' % li] = unicode( "%s %s" % (company_name, ""), "utf8") f['attendee_type%02d' % li] = attendee_type ##f['no%02d' % li] = li response.headers['Content-Type'] = 'application/pdf' return f.render('badge.pdf', dest='S')
def import_csv(): from gluon.contrib.pyfpdf import Template f = Template() f.parse_csv( infile="/home/reingart/web2py/gluon/contrib/pyfpdf/invoice.csv", delimiter=";", decimal_sep=",") for v in f.fields.elements(): v['align'] = { 'I': 'L', 'D': 'R', 'C': 'C', '': '' }.get(v['align'], 'L') v['pdf_template_id'] = 1 db.pdf_element.insert(**v)
def crear_factura_base(): from gluon.contrib.pyfpdf.template import Template mensaje = "" # Si no se creó la demo agregar a la base de datos template = db( db.pdftemplate.title == "Demo invoice pyfpdf").select().first() if not template: template = db.pdftemplate.insert(title="Demo invoice pyfpdf", format="A4") mensaje += "Se creó el template por defecto. " else: mensaje += "El template ya existe en la base de datos. " # eliminar todos los elementos del template por defecto. db(db.pdfelement.pdftemplate == template.id).delete() f = Template() f.parse_csv(infile=os.path.join(request.env.web2py_path, 'applications', request.application, 'private', 'invoice.csv'), delimiter=";", decimal_sep=",") nro = 0 creados = 0 for k, v in f.elements.items(): nro += 1 try: v['align'] = { 'I': 'L', 'D': 'R', 'C': 'C', 'J': 'J', "": "" }.get(v['align'], 'L') v['pdftemplate'] = template.id db.pdfelement.insert(**v) creados += 1 except (AttributeError, ValueError, KeyError, TypeError), e: mensaje += "Error en elemento nro: " + str(nro) + " - " + str( e) + ". "
def organizers(): Template = template.Template import os.path # generate sample invoice (according Argentina's regulations) speakers = db(db.auth_user.organizer==True).select(orderby=db.auth_user.last_name|db.auth_user.first_name) # read elements from db elements = db(db.pdf_element.pdf_template_id==3).select(orderby=db.pdf_element.priority) f = Template(format="A4", elements = elements, title="Speaker Badges", author="web2conf", subject="", keywords="") # calculate pages: label_count = len(speakers) max_labels_per_page = 5*2 pages = label_count / (max_labels_per_page - 1) if label_count % (max_labels_per_page - 1): pages = pages + 1 # fill placeholders for each page for page in range(1, pages+1): f.add_page() k = 0 li = 0 #for speaker in speakers: for li in range(1, 11): ## k = k + 1 ##if k > page * (max_labels_per_page ): ## break ##if k > (page - 1) * (max_labels_per_page ): ## li += 1 #f['item_quantity%02d' % li] = it['qty'] ##f['name%02d' % li] = unicode("%s %s" % (speaker.first_name, speaker.last_name), "utf8") ##f['company_name%02d' % li] = unicode("%s %s" % (speaker.company_name.strip(), ""), "utf8") f['attendee_type%02d' % li] = "Organizador" ##f['no%02d' % li] = li response.headers['Content-Type']='application/pdf' return f.render('invoice.pdf', dest='S')
def speakers_badges(): # set template to use from the db: pdf_template_id = 3 # query registered users and generate speaker labels speakers = db(db.auth_user.id>0).select(orderby=db.auth_user.last_name|db.auth_user.first_name) company_name = "web2conf" attendee_type = "Speaker" # read elements from db elements = db(db.pdf_element.pdf_template_id==pdf_template_id).select(orderby=db.pdf_element.priority) f = Template(format="A4", elements = elements, title="Speaker Badges", author="web2conf", subject="", keywords="") # calculate pages: label_count = len(speakers) max_labels_per_page = 5*2 pages = label_count / (max_labels_per_page - 1) if label_count % (max_labels_per_page - 1): pages = pages + 1 # fill placeholders for each page for page in range(1, pages+1): f.add_page() k = 0 li = 0 for speaker in speakers: k = k + 1 if k > page * (max_labels_per_page ): break if k > (page - 1) * (max_labels_per_page ): li += 1 #f['item_quantity%02d' % li] = it['qty'] f['name%02d' % li] = unicode("%s %s" % (speaker.first_name, speaker.last_name), "utf8") f['company_name%02d' % li] = unicode("%s %s" % (company_name, ""), "utf8") f['attendee_type%02d' % li] = attendee_type ##f['no%02d' % li] = li response.headers['Content-Type']='application/pdf' return f.render('badge.pdf', dest='S')
# no point of sale defined # or db query error point_of_sale = "0000" from gluon.contrib.pyfpdf import Template # generate sample invoice (according Argentina's regulations) the_details = db(db.movement.operation_id == operation_id).select() import random from decimal import Decimal # Instantiate the PyFPDF template f = Template(format="A4", title=T("Operation number") + " %s" % operation_id, author="GestionLibre", subject=utftolatin(document.description), keywords="Sales/Stock/Purchases document") # Complete the template object with .csv file element difinition f.parse_csv(infile=os.path.join(config.PDF_TEMPLATES_FOLDER, 'invoice.csv'), delimiter=";", decimal_sep=",") detail = "" items = [] i = 0 # Here goes the actual document data
def invoice(): from gluon.contrib.pyfpdf import Template import os.path # generate sample invoice (according Argentina's regulations) import random from decimal import Decimal # read elements from db elements = db(db.pdf_element.pdf_template_id == 1).select( orderby=db.pdf_element.priority) f = Template(format="A4", elements=elements, title="Sample Invoice", author="Sample Company", subject="Sample Customer", keywords="Electronic TAX Invoice") detail = "Lorem ipsum dolor sit amet, consectetur. " * 5 items = [] for i in range(1, 30): ds = "Sample product %s" % i qty = random.randint(1, 10) price = round(random.random() * 100, 3) code = "%s%s%02d" % (chr(random.randint( 65, 90)), chr(random.randint(65, 90)), i) items.append( dict(code=code, unit='u', qty=qty, price=price, amount=qty * price, ds="%s: %s" % (i, ds))) # divide and count lines lines = 0 li_items = [] for it in items: qty = it['qty'] code = it['code'] unit = it['unit'] for ds in f.split_multicell(it['ds'], 'item_description01'): # add item description line (without price nor amount) li_items.append( dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # clean qty and code (show only at first) unit = qty = code = None # set last item line price and amount li_items[-1].update(amount=it['amount'], price=it['price']) obs = "\n<U>Detail:</U>\n\n" + detail for ds in f.split_multicell(obs, 'item_description01'): li_items.append( dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # calculate pages: lines = len(li_items) max_lines_per_page = 24 pages = lines / (max_lines_per_page - 1) if lines % (max_lines_per_page - 1): pages = pages + 1 # completo campos y hojas for page in range(1, pages + 1): f.add_page() f['page'] = 'Page %s of %s' % (page, pages) if pages > 1 and page < pages: s = 'Continues on page %s' % (page + 1) else: s = '' f['item_description%02d' % (max_lines_per_page + 1)] = s f["company_name"] = "Sample Company" f["company_logo"] = os.path.join(request.env.web2py_path, "applications", request.application, "private", "tutorial", "logo.png") f["company_header1"] = "Some Address - somewhere -" f["company_header2"] = "http://www.example.com" f["company_footer1"] = "Tax Code ..." f["company_footer2"] = "Tax/VAT ID ..." f['number'] = '0001-00001234' f['issue_date'] = '2010-09-10' f['due_date'] = '2099-09-10' f['customer_name'] = "Sample Client" f['customer_address'] = "Siempreviva 1234" # print line item... li = 0 k = 0 total = Decimal("0.00") for it in li_items: k = k + 1 if k > page * (max_lines_per_page - 1): break if it['amount']: total += Decimal("%.6f" % it['amount']) if k > (page - 1) * (max_lines_per_page - 1): li += 1 if it['qty'] is not None: f['item_quantity%02d' % li] = it['qty'] if it['code'] is not None: f['item_code%02d' % li] = it['code'] if it['unit'] is not None: f['item_unit%02d' % li] = it['unit'] f['item_description%02d' % li] = it['ds'] if it['price'] is not None: f['item_price%02d' % li] = "%0.3f" % it['price'] if it['amount'] is not None: f['item_amount%02d' % li] = "%0.2f" % it['amount'] if pages == page: f['net'] = "%0.2f" % (total / Decimal("1.21")) f['vat'] = "%0.2f" % (total * (1 - 1 / Decimal("1.21"))) f['total_label'] = 'Total:' else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % total response.headers['Content-Type'] = 'application/pdf' return f.render('invoice.pdf', dest='S')
def crear_pdf(el_cbte): from gluon.contrib.pyfpdf import Template import os.path # generate sample invoice (according Argentina's regulations) los_detalles = db(db.detalle.comprobante == el_cbte.id).select() las_variables = db(db.variables).select().first() import random from decimal import Decimal # read elements from db template = db(db.pdftemplate.title == "Demo invoice pyfpdf").select().first() elements = db(db.pdfelement.pdftemplate==template.id).select(orderby=db.pdfelement.priority) f = Template(format="A4", elements = elements, title=utftolatin(el_cbte.nombre_cliente), author=utftolatin(las_variables.empresa), subject=utftolatin(db.tipocbte[el_cbte.tipocbte].ds), keywords="Electronic TAX Invoice") if el_cbte.obs_comerciales: detail = el_cbte.obs_comerciales else: detail = "" items = [] i = 0 for detalle in los_detalles: i += 1 ds = utftolatin(detalle.ds) qty = "%.3f" % float(detalle.qty) price = str(detalle.precio) code = str(detalle.codigo) items.append(dict(code=code, unit=str(detalle.umed.ds[:1]), qty=qty, price=price, amount=str(detalle.imp_total), ds="%s: %s" % (i,ds))) # divide and count lines lines = 0 li_items = [] unit = qty = code = None for it in items: qty = it['qty'] code = it['code'] unit = it['unit'] for ds in f.split_multicell(it['ds'], 'item_description01'): # add item description line (without price nor amount) li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # clean qty and code (show only at first) unit = qty = code = None # set last item line price and amount li_items[-1].update(amount = it['amount'], price = it['price']) obs="\n<U>Observaciones:</U>\n\n" + detail # convertir a letras el importe try: importetmp = str(int(round(el_cbte.imp_total*100))) except (ValueError, TypeError): importetmp = "0000" try: montoiz = numero_a_letra.convertir(int(importetmp[:-2])) montoder = importetmp[-2:] except ValueError: montoiz = "cero" montoder = "00" obs += "Son %s %s con %s/100" % (el_cbte.moneda_id.ds, montoiz, montoder) if el_cbte.obs_comerciales is not None: obs += "\n" + el_cbte.obs_comerciales for ds in f.split_multicell(obs, 'item_description01'): li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # calculate pages: lines = len(li_items) max_lines_per_page = 24 pages = lines / (max_lines_per_page - 1) if lines % (max_lines_per_page - 1): pages = pages + 1 # completo campos y hojas for page in range(1, pages+1): f.add_page() f['page'] = u'Página %s de %s' % (page, pages) if pages>1 and page<pages: s = u'Continúa en la página %s' % (page+1) else: s = '' f['item_description%02d' % (max_lines_per_page+1)] = s try: if not las_variables.logo: logo = os.path.join(request.env.web2py_path,"applications",request.application,"static","images", "logo_fpdf.png") else: # path al logo logo = os.path.join(request.env.web2py_path,"applications",request.application,"uploads", las_variables.logo) except (AttributeError, ValueError, KeyError, TypeError): logo = os.path.join(request.env.web2py_path,"applications",request.application,"static","images", "logo_fpdf.png") f["company_name"] = utftolatin(las_variables.empresa) f["company_logo"] = logo f["company_header1"] = utftolatin(las_variables.domicilio) f["company_header2"] = "CUIT " + str(las_variables.cuit) f["company_footer1"] = utftolatin(el_cbte.tipocbte.ds) try: f["company_footer2"] = WSDESC[el_cbte.webservice] except KeyError: f["company_footer2"] = u"Factura electrónica" f['number'] = str(el_cbte.punto_vta).zfill(4) + "-" + str(el_cbte.cbte_nro).zfill(7) f['payment'] = utftolatin(el_cbte.forma_pago) f['document_type'] = el_cbte.tipocbte.ds[-1:] f['customer_address'] = utftolatin('Dirección') f['item_description'] = utftolatin('Descripción') try: cae = str(el_cbte.cae) if cae == "None": cae = "0000000000" elif "|" in cae: cae = cae.strip("|") f['barcode'] = cae f['barcode_readable'] = "CAE: " + cae except (TypeError, ValueError, KeyError, AttributeError): f['barcode'] = "0000000000" f['barcode_readable'] = u"CAE: no registrado" try: issue_date = el_cbte.fecha_cbte.strftime("%d-%m-%Y") except (TypeError, AttributeError): issue_date = "" try: due_date = el_cbte.fecha_vto.strftime("%d-%m-%Y") except (TypeError, AttributeError): due_date = "" f['issue_date'] = issue_date f['due_date'] = due_date f['customer_name'] = utftolatin(el_cbte.nombre_cliente) f['customer_address'] = utftolatin(el_cbte.domicilio_cliente) f['customer_vat'] = utftolatin(el_cbte.cp_cliente) f['customer_phone'] = utftolatin(el_cbte.telefono_cliente) f['customer_city'] = utftolatin(el_cbte.localidad_cliente) f['customer_taxid'] = utftolatin(el_cbte.nro_doc) # print line item... li = 0 k = 0 total = 0.00 for it in li_items: k = k + 1 if k > page * (max_lines_per_page - 1): break if it['amount']: total += float(it['amount']) if k > (page - 1) * (max_lines_per_page - 1): li += 1 if it['qty'] is not None: f['item_quantity%02d' % li] = it['qty'] if it['code'] is not None: f['item_code%02d' % li] = it['code'] if it['unit'] is not None: f['item_unit%02d' % li] = it['unit'] f['item_description%02d' % li] = it['ds'] if it['price'] is not None: f['item_price%02d' % li] = "%0.2f" % float(it['price']) if it['amount'] is not None: f['item_amount%02d' % li] = "%0.2f" % float(it['amount']) if pages == page: f['net'] = "%0.2f" % amountorzero(el_cbte.imp_neto) f['vat'] = "%0.2f" % amountorzero(el_cbte.impto_liq) f['total_label'] = 'Total:' else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % amountorzero(el_cbte.imp_total) return f.render('invoice.pdf', dest='S')
def porcobrar(): import csv, time, math from gluon.contrib.pyfpdf import Template import os.path import sys if request.args(0): if request.args(0) == 'todos': sql = "SELECT cf_proveedor_id, cf_proveedor.razon_social,fc_documento.fecha, \ fc_documento.correlativo,fc_documento.fecha_vencimiento,DATEDIFF(CURDATE(), \ fc_documento.fecha_vencimiento) dias,\ (select sum(total) from fc_documento_det where fc_documento_det.fc_documento_id=fc_documento.id) total,\ (select sum(monto) from fc_cobro_det where fc_cobro_det.fc_documento_id=fc_documento.id) cobrado \ FROM fc_documento \ inner join cf_proveedor on fc_documento.cf_proveedor_id=cf_proveedor.id \ where fc_documento.fc_tipo_doc_id=2\ having total=cobrado \ order by cf_proveedor_id;" sqlid = "SELECT cf_proveedor_id id, count(cf_proveedor_id) count, \ (select sum(total) from fc_documento_det where fc_documento_det.fc_documento_id=fc_documento.id) total, \ (select sum(monto) from fc_cobro_det where fc_cobro_det.fc_documento_id=fc_documento.id) cobrado \ FROM fc_documento \ inner join cf_proveedor on fc_documento.cf_proveedor_id=cf_proveedor.id \ where fc_documento.fc_tipo_doc_id=2 \ having total=cobrado \ order by cf_proveedor_id;" rec = db.executesql(sql, as_dict=True) rec_id = db.executesql(sqlid, as_dict=True) #doc_record=db(db.fc_documento.id == request.args(0)).select() #doc_det_rec=db(db.fc_documento_det.fc_documento_id == request.args(0)).select(orderby=db.fc_documento_det.id) emp_rec = db(db.cf_empresa.id == 1).select() #print emp_rec f = Template(format="A4", title="Cuentas por Cobrar", author="w.a", subject="w.a", keywords="") f.parse_csv(infile=request.folder + '/static/rpt/porcobrar.csv', delimiter=";", decimal_sep=",") max_lines_per_page = 49.0 lines = len(rec) ids = len(rec_id) if ids > lines: pages = ids else: pages = int(math.ceil(float(lines / (max_lines_per_page - 1)))) page = 0 # # # fill placeholders for each page total = float("0.00") for row in range(len(rec_id)): #primer proveedor para ruptura de control #nro paginas para este proveedore #print rec_id.index() subpages = int( math.ceil(float(rec_id[row]['count'] / (max_lines_per_page - 1)))) for pg in range(subpages): f.add_page() page += 1 f['page'] = 'Pagina %s de %s' % (page, pages) if pages > 1 and page < pages: s = 'Continua en la pagina %s' % (page + 1) else: s = '' # setting data from company rowemp = emp_rec[0] f["EMPRESA"] = rowemp.razon_social f["Logo"] = os.path.join(request.env.web2py_path, "applications", "flota", "uploads", rowemp.ruta_foto) f["membrete1"] = 'Rif.:' + rowemp.rif + ' - Nit.: ' + rowemp.nit f["membrete2"] = 'Tel.:' + rowemp.tlf + ' - Fax.: ' + rowemp.fax + 'Email.:' + rowemp.email #datos del proveedor f["proveedor.nombre"] = rowemp['razon_social'] proveedor = rec_id[row]['id'] # print line item... li = 0 k = 0 subtotal = float("0.00") for rowdet in rec: if rowdet['cf_proveedor_id'] == proveedor: k = k + 1 if k > page * (max_lines_per_page - 1): break if k > (page - 1) * (max_lines_per_page - 1): if rowdet['total'] == rowdet['cobrado']: li += 1 f['factura%02d' % li] = rowdet['correlativo'] f['fecha%02d' % li] = rowdet['fecha'] f['vencimiento%02d' % li] = rowdet['fecha_vencimiento'] f['dias%02d' % li] = rowdet['dias'] f['monto%02d' % li] = "%0.2f" % rowdet['total'] subtotal += rowdet['total'] total += subtotal else: f['subtotal.monto'] = "%0.2f" % subtotal break if subtotal > 0: f['subtotal.monto'] = "%0.2f" % subtotal f['total.monto'] = "%0.2f" % total f.render("./porcobrar.pdf") if sys.platform.startswith("linux"): #print os.getcwd() os.system("evince ./porcobrar.pdf") else: os.system("./porcobrar.pdf") redirect(URL(c='default', f='index'))
def generate(): #We want to have a preview mode, where the values are overlaid on the Uniform Hazardous Waste Management PDF form supplied by the EPA #Sample is here: https://www.epa.gov/hwgenerators/hazardous-waste-manifest-system #One option is to use PyPDF2, add the blank PDF form as a watermark, and combine the PDF generated by pyfpdf. But that requires loading the PyPDF2 library #What we are doing is converting the EPA PDF into a PNG offline. #Then we can just use the PNG as a background with pyfpdf included with web2py. from gluon.contrib.pyfpdf import Template import os.path printpreview = 1 elements = [ ] #Add all elements and positioning to form from the database #letter paper = 215.9 mm x 279.4 m for row in db(db.manifest_layout.element<2000).select(): elements.append({ 'name': row.name, 'type': row.type, 'x1': row.x1, 'y1': row.y1, 'x2': row.x2, 'y2': row.y2, 'font': 'Arial', 'size': 12.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': 'logo', 'priority': 2, },) elements.append({ 'name': 'Page_1_of', 'type': 'T', 'x1': 105.0, 'y1': 40.5, 'x2': 12.0, 'y2': 12.0, 'font': 'Arial', 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, }) # elements.append({ 'name': 'Emergency_Response_Phone', 'type': 'T', 'x1': 115.0, 'y1': 40.5, 'x2': 12.0, 'y2': 12.0, 'font': 'Arial', 'size': 12.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, }) #TESTING TESTING TESTING TESTING TESTING TESTING TESTING TESTING elements.append({ 'name': 'Emergency_Response_Phone', 'type': 'T', 'x1': 20.00, 'y1': 115.00, 'x2': 12.0, 'y2': 12.0, 'font': 'Arial', 'size': 12.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, }) elements.append( { 'name': 'Manifest_Tracking_Number', 'type': 'T', 'x1': 157.0, 'y1': 40.5, 'x2': 12.0, 'y2': 12.0, 'font': 'Arial', 'size': 12.0, 'bold': 1, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, },) elements.append( { 'name': 'Generator_Name_Address', 'type': 'T', 'x1': 20.0, 'y1': 40, 'x2': 100.0, 'y2': 37.0, 'font': 'Arial', 'size': 10.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, 'multiline' : 3 },) # elements.append( { 'name': 'Generator_Site_Address', 'type': 'T', 'x1': 115.0, 'y1': 40, 'x2': 180.0, 'y2': 37.0, 'font': 'Arial', 'size': 10.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, 'multiline' : 3 },) elements.append( { 'name': 'Generator_Name_Phone', 'type': 'T', 'x1': 35.0, 'y1': 49, 'x2': 180.0, 'y2': 37.0, 'font': 'Arial', 'size': 10.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, 'multiline' : 3 },) elements.append( { 'name': 'line1', 'type': 'L', 'x1': 100.0, 'y1': 25.0, 'x2': 100.0, 'y2': 57.0, 'font': 'Arial', 'size': 0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 3, },) elements.append({ 'name': 'barcode', 'type': 'BC', 'x1': 20.0, 'y1': 246.5, 'x2': 140.0, 'y2': 254.0, 'font': 'Interleaved 2of5 NT', 'size': 0.75, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '200000000001000159053338016581200810081', 'priority': 3, },) if (printpreview==1): elements.append({ 'name': 'background', 'type': 'I', 'x1': 3.3, 'y1': 3.3, 'x2': 212.6, 'y2': 276.1, 'font': None, 'size': 0.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': 'logo', 'priority': 0, },) # self.image("logo.png", x=10, y=8, w=23) f = Template(format="A4", elements = elements, title="Sample Manifest", author="ChemWastePro", subject="Sample Manifest", keywords="Sample Manifest Number") f.add_page() #logo=os.path.join(request.env.web2py_path,"static","images","manifest.png") #self.image(logo,10,8,33) #f["company_logo"] = os.path.join(request.env.web2py_path, "gluon", "contrib", "pyfpdf", "tutorial", "logo.png" #os.path.join(request.env.web2py_path,request.folder,"static","images","g3001.png") #if print preview, then add background if (printpreview==1): f["background"] = os.path.join(request.env.web2py_path,request.folder,"static","images","manifest.png") f["Generator_ID_Number"] = "123456789" f["Page_1_of"] = "2" f["Emergency_Response_Phone"] = "510-642-6908" f["Manifest_Tracking_Number"] = "NYB54321" f["Generator_Name_Address"] = "Somewhere, CA, USA\n123 Anywhere Rd.\nMain Campus" f["Generator_Name_Phone"] = "510-642-6073" f["Generator_Site_Address"] = "Somewhere, CA, USA\n123 Anywhere Rd.\nMain Site" f["Transporter_1_Company_Name"] = "Transporter1" f["Transporter_2_Company_Name"] = "Transporter2" f["Transporter_1_Company_Phone"] = "TransPhone1" f["Transporter_2_Company_Phone"] = "TransPhone2" response.headers['Content-Type']='application/pdf' return f.render('invoice.pdf', dest='S')
def invoice(): from gluon.contrib.pyfpdf import Template import os.path # generate sample invoice (according Argentina's regulations) import random from decimal import Decimal # read elements from db elements = db(db.pdf_element.pdf_template_id==1).select(orderby=db.pdf_element.priority) f = Template(format="A4", elements = elements, title="Sample Invoice", author="Sample Company", subject="Sample Customer", keywords="Electronic TAX Invoice") detail = "Lorem ipsum dolor sit amet, consectetur. " * 5 items = [] for i in range(1, 30): ds = "Sample product %s" % i qty = random.randint(1,10) price = round(random.random()*100,3) code = "%s%s%02d" % (chr(random.randint(65,90)), chr(random.randint(65,90)),i) items.append(dict(code=code, unit='u', qty=qty, price=price, amount=qty*price, ds="%s: %s" % (i,ds))) # divide and count lines lines = 0 li_items = [] for it in items: qty = it['qty'] code = it['code'] unit = it['unit'] for ds in f.split_multicell(it['ds'], 'item_description01'): # add item description line (without price nor amount) li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # clean qty and code (show only at first) unit = qty = code = None # set last item line price and amount li_items[-1].update(amount = it['amount'], price = it['price']) obs="\n<U>Detail:</U>\n\n" + detail for ds in f.split_multicell(obs, 'item_description01'): li_items.append(dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # calculate pages: lines = len(li_items) max_lines_per_page = 24 pages = lines / (max_lines_per_page - 1) if lines % (max_lines_per_page - 1): pages = pages + 1 # completo campos y hojas for page in range(1, pages+1): f.add_page() f['page'] = 'Page %s of %s' % (page, pages) if pages>1 and page<pages: s = 'Continues on page %s' % (page+1) else: s = '' f['item_description%02d' % (max_lines_per_page+1)] = s f["company_name"] = "Sample Company" f["company_logo"] = os.path.join(request.env.web2py_path,"applications",request.application,"private","tutorial","logo.png") f["company_header1"] = "Some Address - somewhere -" f["company_header2"] = "http://www.example.com" f["company_footer1"] = "Tax Code ..." f["company_footer2"] = "Tax/VAT ID ..." f['number'] = '0001-00001234' f['issue_date'] = '2010-09-10' f['due_date'] = '2099-09-10' f['customer_name'] = "Sample Client" f['customer_address'] = "Siempreviva 1234" # print line item... li = 0 k = 0 total = Decimal("0.00") for it in li_items: k = k + 1 if k > page * (max_lines_per_page - 1): break if it['amount']: total += Decimal("%.6f" % it['amount']) if k > (page - 1) * (max_lines_per_page - 1): li += 1 if it['qty'] is not None: f['item_quantity%02d' % li] = it['qty'] if it['code'] is not None: f['item_code%02d' % li] = it['code'] if it['unit'] is not None: f['item_unit%02d' % li] = it['unit'] f['item_description%02d' % li] = it['ds'] if it['price'] is not None: f['item_price%02d' % li] = "%0.3f" % it['price'] if it['amount'] is not None: f['item_amount%02d' % li] = "%0.2f" % it['amount'] if pages == page: f['net'] = "%0.2f" % (total/Decimal("1.21")) f['vat'] = "%0.2f" % (total*(1-1/Decimal("1.21"))) f['total_label'] = 'Total:' else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % total response.headers['Content-Type']='application/pdf' return f.render('invoice.pdf', dest='S')
def generate(): # We want to have a preview mode, where the values are overlaid on the Uniform Hazardous Waste Management PDF form supplied by the EPA # Sample is here: https://www.epa.gov/hwgenerators/hazardous-waste-manifest-system # One option is to use PyPDF2, add the blank PDF form as a watermark, and combine the PDF generated by pyfpdf. But that requires loading the PyPDF2 library # What we are doing is converting the EPA PDF into a PNG offline. # Then we can just use the PNG as a background with pyfpdf included with web2py. from gluon.contrib.pyfpdf import Template import os.path printpreview = 1 elements = [] # Add all elements and positioning to form from the database # See http://pyfpdf.readthedocs.io/en/latest/Templates/ # letter paper = 215.9 mm x 279.4 m for row in db(db.manifest_layout.element < 2000).select(): elements.append( { "name": row.name, "type": row.type, "x1": row.x1, "y1": row.y1, "x2": row.x2, "y2": row.y2, "font": row.font, "size": row.size, "bold": row.bold, "italic": row.italic, "underline": row.underline, "foreground": row.foreground, "background": row.background, "align": row.align, "text": "", "priority": row.priority, "multiline": row.multiline, } ) elements.append( { "name": "Page_1_of", "type": "T", "x1": 105.0, "y1": 40.5, "x2": 12.0, "y2": 12.0, "font": "Arial", "size": 0.0, "bold": 0, "italic": 0, "underline": 0, "foreground": 0, "background": 0, "align": "I", "text": "", "priority": 2, } ) # elements.append({ 'name': 'Emergency_Response_Phone', 'type': 'T', 'x1': 115.0, 'y1': 40.5, 'x2': 12.0, 'y2': 12.0, 'font': 'Arial', 'size': 12.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, }) # TESTING TESTING TESTING TESTING TESTING TESTING TESTING TESTING # elements.append({ 'name': 'Emergency_Response_Phone', 'type': 'T', 'x1': 25, 'y1': 172.00, 'x2': 25.0, 'y2': 30.0, 'font': 'Arial', 'size': 12.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, }) # elements.append( { 'name': 'Generator_Name_Address', 'type': 'T', 'x1': 20.0, 'y1': 40, 'x2': 100.0, 'y2': 37.0, 'font': 'Arial', 'size': 10.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, 'multiline' : 3 },) # elements.append( { 'name': 'Generator_Site_Address', 'type': 'T', 'x1': 115.0, 'y1': 40, 'x2': 180.0, 'y2': 37.0, 'font': 'Arial', 'size': 10.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, 'multiline' : 3 },) # elements.append( { 'name': 'Generator_Name_Phone', 'type': 'T', 'x1': 35.0, 'y1': 49, 'x2': 180.0, 'y2': 37.0, 'font': 'Arial', 'size': 10.0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '', 'priority': 2, 'multiline' : 3 },) # SAMPLE LINE # elements.append( { 'name': 'line1', 'type': 'L', 'x1': 100.0, 'y1': 25.0, 'x2': 100.0, 'y2': 57.0, 'font': 'Arial', 'size': 0, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': None, 'priority': 3, },) # SAMPLE BARCODE # elements.append({ 'name': 'barcode', 'type': 'BC', 'x1': 20.0, 'y1': 246.5, 'x2': 140.0, 'y2': 254.0, 'font': 'Interleaved 2of5 NT', 'size': 0.75, 'bold': 0, 'italic': 0, 'underline': 0, 'foreground': 0, 'background': 0, 'align': 'I', 'text': '200000000001000159053338016581200810081', 'priority': 3, },) if printpreview == 1: elements.append( { "name": "background", "type": "I", "x1": 3.3, "y1": 3.3, "x2": 212.6, "y2": 276.1, "font": None, "size": 0.0, "bold": 0, "italic": 0, "underline": 0, "foreground": 0, "background": 0, "align": "I", "text": "logo", "priority": 0, } ) # self.image("logo.png", x=10, y=8, w=23) f = Template( format="A4", elements=elements, title="Sample Manifest", author="ChemWastePro", subject="Sample Manifest", keywords="Sample Manifest Number", ) f.add_page() # logo=os.path.join(request.env.web2py_path,"static","images","manifest.png") # self.image(logo,10,8,33) # f["company_logo"] = os.path.join(request.env.web2py_path, "gluon", "contrib", "pyfpdf", "tutorial", "logo.png" # os.path.join(request.env.web2py_path,request.folder,"static","images","g3001.png") # if print preview, then add background if printpreview == 1: f["background"] = os.path.join(request.env.web2py_path, request.folder, "static", "images", "manifest.png") f["Generator_ID_Number"] = "123456789" f["Page_1_of"] = "2" f["Emergency_Response_Phone"] = "510-642-6908" f["Manifest_Tracking_Number"] = "NYB54321" f["Generator_Name_Address"] = "Somewhere, CA, USA\n123 Anywhere Rd.\nMain CampusAddress" f["Generator_Name_Phone"] = "510-642-6073" f["Generator_Site_Address"] = "Somewhere, CA, USA\n123 Anywhere Rd.\nMain Site" f["Transporter_1_Company_Name"] = "Transporter1" f["Transporter_2_Company_Name"] = "Transporter2" f["Transporter_1_Company_EPAID"] = "TransEPAID1" f["Transporter_2_Company_EPAID"] = "TransEPAID2" f["DesignatedFacilityName_Address"] = "Somewhere, CA, USA\n123 Anywhere Rd.\nMain Campus" f["DesignatedFacilityEPAID"] = "NYPD411512412" f["DesignatedFacilityPhone"] = "510-642-6073" f["9a1_HM"] = "X" f["9a2_HM"] = "X" f["9a3_HM"] = "X" f["9a4_HM"] = "X" f["Special_Handing_Instructions"] = "Special Handling Instructions" f["Generator_Site_Address"] = "Somewhere, CA, USA\n123 Anywhere Rd.\nMain Campus Site" f["9b1_HM"] = XML("UN2811 Waste Toxic solids, organic, n.o.s.,\n\(Phenol/Chloroform\),\n6.1,PG III") f["9b2_HM"] = XML("UN1992, 3, PGIII\nWaste Flammable Liquid\nAcetone n.o.s") f["9b3_HM"] = "UN1992, 3, PGIII\nWaste Flammable Liquid\nAcetone n.o.s" f["9b4_HM"] = "UN1992, 3, PGIII\nWaste Flammable Liquid\nAcetone n.o.s" f["10_1ContainersNo"] = "145" f["10_2ContainersNo"] = "165" f["10_3ContainersNo"] = "16" f["10_4ContainersNo"] = "40" f["10_1ContainersType"] = "DF" f["10_2ContainersType"] = "DM" f["10_3ContainersType"] = "CF" f["10_4ContainersType"] = "TT" response.headers["Content-Type"] = "application/pdf" return f.render("invoice.pdf", dest="S")
def all(): import os.path if False: pdf_template_id = 3 speaker = False elif request.args: pdf_template_id = int(request.args[0]) speaker = 'speaker' in request.args else: pdf_template_id = 2 speaker = True # generate sample invoice (according Argentina's regulations) q = db.auth_user.speaker==speaker #if not speaker: ## q = db.auth_user.id < 400 users = db(q).select(orderby=db.auth_user.id) # read elements from db elements = db(db.pdf_element.pdf_template_id==pdf_template_id).select(orderby=db.pdf_element.priority) f = Template(format=(315, 440), elements = elements, title="Speaker Badges", author="web2conf", subject="", keywords="") # calculate pages: label_count = len(users) max_labels_per_page = 4*2*2 pages = label_count / (max_labels_per_page - 1) if label_count % (max_labels_per_page - 1): pages = pages + 1 # fill placeholders for each page for page in range(1, pages+1): f.add_page() k = 0 li = 0 for user in users: k = k + 1 if k > page * (max_labels_per_page ): break if k > (page - 1) * (max_labels_per_page ): li += 1 d = build_badge_dict(user) for key, val in d.items(): f["%s%02d" % (key, li)] = val response.headers['Content-Type']='application/pdf' fn = "badges_%s_%s.pdf" % ('speakers' if speaker else 'public', pdf_template_id) response.headers["Content-Disposition"] \ = "attachment; filename=%s" % fn s = f.render('badges.pdf', dest='S') if request.env['remote_addr'] == '127.0.0.1': fn = os.path.join(request.folder, 'static', fn) f = open(fn, "wb") f.write(s) f.close() print "saved", fn else: return s
def imprimir(): import csv, time from gluon.contrib.pyfpdf import Template import os.path import sys es_para_guardar = False if request.args(0): doc_id = request.args(0) if request.args(1): es_para_guardar = True doc_record = db(db.fc_documento.id == request.args(0)).select() doc_det_rec = db( db.fc_documento_det.fc_documento_id == request.args(0)).select( orderby=db.fc_documento_det.id) emp_rec = db(db.cf_empresa.id == 1).select() #print emp_rec f = Template(format="A4", title="Presupuesto", author="w.a", subject="w.a", keywords="") if es_para_guardar: f.parse_csv(infile=request.folder + '/static/rpt/presupuesto_save.csv', delimiter=";", decimal_sep=",") else: f.parse_csv(infile=request.folder + '/static/rpt/presupuesto.csv', delimiter=";", decimal_sep=",") # # calculate pages: lines = len(doc_det_rec) max_lines_per_page = 24 pages = lines / (max_lines_per_page - 1) if lines % (max_lines_per_page - 1): pages = pages + 1 # # # fill placeholders for each page for page in range(1, pages + 1): f.add_page() f['page'] = 'Page %s of %s' % (page, pages) if pages > 1 and page < pages: s = 'Continues on page %s' % (page + 1) else: s = '' # setting data from company for row in emp_rec: f["EMPRESA"] = row.razon_social f["Logo"] = os.path.join(request.env.web2py_path, "applications", "flota", "uploads", row.ruta_foto) f["membrete1"] = 'Rif.:' + row.rif + ' - Nit.: ' + row.nit f["membrete2"] = 'Tel.:' + row.tlf + ' - Fax.: ' + row.fax f["iva"] = 'Email.:' + row.email #data from document for row in doc_record: f["numero"] = row.correlativo lafecha = row.fecha.strftime("%d/%m/%Y") f["Fecha.L"] = 'Fecha: ' + lafecha f["cliente.localidad.l"] = 'Contacto: ' f["cliente.localidad"] = row.contacto lafecha2 = row.fecha_vencimiento.strftime("%d/%m/%Y") f["cuit"] = 'Fecha Vencimiento: ' + lafecha2 f["vencimiento"] = '' f["vencimientol"] = '' f['PeriodoFacturadoL'] = '' f['Periodo.Hasta'] = '' f['Periodo.Desde'] = '' f['cae'] = '' #f['cae.l']='' f['cae.vencimiento'] = '' f['cae.vencimiento.l'] = '' f['codigobarras'] = str(row.id) + str(row.correlativo) f['codigobarraslegible'] = str(row.id) + str(row.correlativo) f['neto.L'] = 'Sub-Total' f['iva.L'] = 'I.V.A. 12%' notainf = row.nota_detalle #data from client f["cliente.iva.l"] = '' f["cliente.cuit.l"] = '' clt_rec = db(db.cf_proveedor.id == row.cf_proveedor_id).select() for row in clt_rec: f["cliente.nombre"] = row.razon_social f["cliente.domicilio"] = row.direccion f["cliente.telefono"] = row.tlf + ' Fax: ' + row.fax + ' Email: ' + row.email # print line item... li = 0 k = 0 total = float("0.00") for row in doc_det_rec: k = k + 1 if k > page * (max_lines_per_page - 1): break if row.importe: total += float("%.6f" % row.total) if k > (page - 1) * (max_lines_per_page - 1): li += 1 f['item.descripcion%02d' % li] = row.descripcion if row.importe is not None: f['item.importe%02d' % li] = "%0.2f" % row.total if row.cantidad is not None: f['item.cantidad%02d' % li] = "%0.2f" % row.cantidad # ojo para la nota del detalle # split detail into each line description k = k + 2 if k > (page - 1) * (max_lines_per_page - 1): obs = "\n<U>Nota:</U>\n\n" + notainf for ds in f.split_multicell(obs, 'item.descripcion%02d' % k): for ml in ds.splitlines(): f['item.descripcion%02d' % k] = ml k = k + 1 if pages == page: f['neto'] = "%0.2f" % (total) #f['vat'] = "%0.2f" % (total*(1-1/float("1.12"))) f['iva21'] = float("0.00") f['total_label'] = 'Total:' else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % total if es_para_guardar: f.render("./presupuesto_" + doc_id + ".pdf", dest='F') if sys.platform.startswith("linux"): #print os.getcwd() os.system("evince ./presupuesto_" + doc_id + ".pdf") else: os.system("./presupuesto_" + doc_id + ".pdf") redirect( URL(c='presupuesto', f='email/' + "presupuesto_" + doc_id + ".pdf")) else: f.render("./presupuesto_" + doc_id + ".pdf") if sys.platform.startswith("linux"): #print os.getcwd() os.system("evince ./presupuesto_" + doc_id + ".pdf") else: os.system("./presupuesto_" + doc_id + ".pdf") redirect(URL(c='presupuesto', f='index'))
def crear_pdf(el_cbte): from gluon.contrib.pyfpdf import Template import os.path # generate sample invoice (according Argentina's regulations) los_detalles = db(db.detalle.comprobante == el_cbte.id).select() las_variables = db(db.variables).select().first() import random from decimal import Decimal # read elements from db template = db( db.pdftemplate.title == "Demo invoice pyfpdf").select().first() elements = db(db.pdfelement.pdftemplate == template.id).select( orderby=db.pdfelement.priority) f = Template(format="A4", elements=elements, title=utftolatin(el_cbte.nombre_cliente), author=utftolatin(las_variables.empresa), subject=utftolatin(db.tipocbte[el_cbte.tipocbte].ds), keywords="Electronic TAX Invoice") if el_cbte.obs_comerciales: detail = el_cbte.obs_comerciales else: detail = "" items = [] i = 0 for detalle in los_detalles: i += 1 ds = utftolatin(detalle.ds) qty = "%.3f" % float(detalle.qty) price = str(detalle.precio) code = str(detalle.codigo) items.append( dict(code=code, unit=str(detalle.umed.ds[:1]), qty=qty, price=price, amount=str(detalle.imp_total), ds="%s: %s" % (i, ds))) # divide and count lines lines = 0 li_items = [] unit = qty = code = None for it in items: qty = it['qty'] code = it['code'] unit = it['unit'] for ds in f.split_multicell(it['ds'], 'item_description01'): # add item description line (without price nor amount) li_items.append( dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # clean qty and code (show only at first) unit = qty = code = None # set last item line price and amount li_items[-1].update(amount=it['amount'], price=it['price']) obs = "\n<U>Observaciones:</U>\n\n" + detail # convertir a letras el importe try: importetmp = str(int(round(el_cbte.imp_total * 100))) except (ValueError, TypeError): importetmp = "0000" try: montoiz = numero_a_letra.convertir(int(importetmp[:-2])) montoder = importetmp[-2:] except ValueError: montoiz = "cero" montoder = "00" obs += "Son %s %s con %s/100" % (el_cbte.moneda_id.ds, montoiz, montoder) if el_cbte.obs_comerciales is not None: obs += "\n" + el_cbte.obs_comerciales for ds in f.split_multicell(obs, 'item_description01'): li_items.append( dict(code=code, ds=ds, qty=qty, unit=unit, price=None, amount=None)) # calculate pages: lines = len(li_items) max_lines_per_page = 24 pages = lines / (max_lines_per_page - 1) if lines % (max_lines_per_page - 1): pages = pages + 1 # completo campos y hojas for page in range(1, pages + 1): f.add_page() f['page'] = u'Página %s de %s' % (page, pages) if pages > 1 and page < pages: s = u'Continúa en la página %s' % (page + 1) else: s = '' f['item_description%02d' % (max_lines_per_page + 1)] = s try: if not las_variables.logo: logo = os.path.join(request.env.web2py_path, "applications", request.application, "static", "images", "logo_fpdf.png") else: # path al logo logo = os.path.join(request.env.web2py_path, "applications", request.application, "uploads", las_variables.logo) except (AttributeError, ValueError, KeyError, TypeError): logo = os.path.join(request.env.web2py_path, "applications", request.application, "static", "images", "logo_fpdf.png") f["company_name"] = utftolatin(las_variables.empresa) f["company_logo"] = logo f["company_header1"] = utftolatin(las_variables.domicilio) f["company_header2"] = "CUIT " + str(las_variables.cuit) f["company_footer1"] = utftolatin(el_cbte.tipocbte.ds) try: f["company_footer2"] = WSDESC[el_cbte.webservice] except KeyError: f["company_footer2"] = u"Factura electrónica" f['number'] = str(el_cbte.punto_vta).zfill(4) + "-" + str( el_cbte.cbte_nro).zfill(7) f['payment'] = utftolatin(el_cbte.forma_pago) f['document_type'] = el_cbte.tipocbte.ds[-1:] f['customer_address'] = utftolatin('Dirección') f['item_description'] = utftolatin('Descripción') try: cae = str(el_cbte.cae) if cae == "None": cae = "0000000000" elif "|" in cae: cae = cae.strip("|") f['barcode'] = cae f['barcode_readable'] = "CAE: " + cae except (TypeError, ValueError, KeyError, AttributeError): f['barcode'] = "0000000000" f['barcode_readable'] = u"CAE: no registrado" try: issue_date = el_cbte.fecha_cbte.strftime("%d-%m-%Y") except (TypeError, AttributeError): issue_date = "" try: due_date = el_cbte.fecha_vto.strftime("%d-%m-%Y") except (TypeError, AttributeError): due_date = "" f['issue_date'] = issue_date f['due_date'] = due_date f['customer_name'] = utftolatin(el_cbte.nombre_cliente) f['customer_address'] = utftolatin(el_cbte.domicilio_cliente) f['customer_vat'] = utftolatin(el_cbte.cp_cliente) f['customer_phone'] = utftolatin(el_cbte.telefono_cliente) f['customer_city'] = utftolatin(el_cbte.localidad_cliente) f['customer_taxid'] = utftolatin(el_cbte.nro_doc) # print line item... li = 0 k = 0 total = 0.00 for it in li_items: k = k + 1 if k > page * (max_lines_per_page - 1): break if it['amount']: total += float(it['amount']) if k > (page - 1) * (max_lines_per_page - 1): li += 1 if it['qty'] is not None: f['item_quantity%02d' % li] = it['qty'] if it['code'] is not None: f['item_code%02d' % li] = it['code'] if it['unit'] is not None: f['item_unit%02d' % li] = it['unit'] f['item_description%02d' % li] = it['ds'] if it['price'] is not None: f['item_price%02d' % li] = "%0.2f" % float(it['price']) if it['amount'] is not None: f['item_amount%02d' % li] = "%0.2f" % float(it['amount']) if pages == page: f['net'] = "%0.2f" % amountorzero(el_cbte.imp_neto) f['vat'] = "%0.2f" % amountorzero(el_cbte.impto_liq) f['total_label'] = 'Total:' else: f['total_label'] = 'SubTotal:' f['total'] = "%0.2f" % amountorzero(el_cbte.imp_total) return f.render('invoice.pdf', dest='S')