If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

You can use downloading PollyReport.py and copying the file to the directory site-packages web2py or installed directly on the system.

 

 

Model
 
tb_tiposclientes = db.define_table('tiposclientes',
    Field('tipo', length=10),    
    format='%(tipo)s'
)

tb_clientes = db.define_table('clientes',
    Field('tipo', tb_tiposclientes),
    Field('nors', length=50),
    Field('domicilio'),
    format='%(nors)s'
)

tb_ventas = db.define_table('ventas',
    Field('fecha', 'date'),
    Field('cliente', tb_clientes),
    Field('total', 'double'),
)

if db(tb_clientes).isempty():
    from gluon.contrib.populate import populate
    tb_tiposclientes.insert(tipo='AAAA')
    tb_tiposclientes.insert(tipo='BBBB')
    tb_tiposclientes.insert(tipo='CCCC')
    populate(tb_clientes,12)
    populate(tb_ventas,100)
    
    

class Ventas(object):
    def iva(self):
        return self.ventas.total*0.21
tb_ventas.virtualfields.append(Ventas())
 
 
Controlller
 
import os
from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import landscape, portrait, A4, A5  
from PollyReports import *

def ventas():
    import os
    import urllib2
    #import urlparse
    from cStringIO import StringIO
    from reportlab.lib.utils import ImageReader    
          
    rel_tipo = (tb_clientes.tipo==tb_tiposclientes.id)
    rel_cliente = (tb_ventas.cliente==tb_clientes.id)
    
    data = db(rel_tipo & rel_cliente).select(
            tb_tiposclientes.tipo,
            tb_clientes.nors,
            tb_ventas.fecha,
            tb_ventas.total,            
            orderby=[tb_tiposclientes.tipo|tb_clientes.nors]
            ).as_list()
  
    
    rpt = Report(data)
    
    tiposclientes_tipo = lambda x: x['tiposclientes']['tipo']
    clientes_nors = lambda x: x['clientes']['nors']
    ventas_total = lambda x: x['ventas']['total']
    ventas_iva = lambda x: x['ventas']['iva']
    ventas_fecha = lambda x: x['ventas']['fecha']    
    
    data = urllib2.urlopen('http://www.python.org/images/python-logo.gif').read()
    buffer = StringIO(data)
    image = ImageReader(buffer)
    
    #Titulo
    rpt.titleband = Band([        
        Element((300, 0), ("Times-Bold", 26), text = "Informe de Ventas", align="center"),        
        Element((300, 25), ("Times-Bold", 18), text = "Período 2010-2012", align="center"),        
        #Image((36, 0), 120, 43, text='/home/jose/borro/freebsd.jpg'),        
        Image((36, 0), 120, 43, text=image),
    ])
    
    #Cabecera de página
    rpt.pageheader = Band([
        Element((36, 0), ("Times-Bold", 20), text = "Ventas"),        
        Element((36, 24), ("Helvetica", 12), text = "Fecha"),
        Element((100, 24), ("Helvetica", 12), text = "Nombre o Razón Social"),
        Element((500, 24), ("Helvetica", 12), text = "IVA", align = "right"),
        Element((600, 24), ("Helvetica", 12), text = "Total", align = "right"),
        Rule((36, 42), 7.5*75, thickness = 2),
    ])
    
    #Cabecera de grupo (se agrupará por nombre de cliente)
    rpt.groupheaders = [
        #Agrupo primero por tipo de cliente
        Band([
            Rule((36, 20), 7.5*72),
            Element((36, 4), ("Helvetica-Bold", 13), getvalue = tiposclientes_tipo, format = lambda x: "Clientes tipo %s" % x),
        ],        
        getvalue = tiposclientes_tipo
        ),
        
        #y luego por nombre de cliente
        Band([
            Rule((36, 20), 7.5*72),
            Element((36, 4), ("Helvetica-Bold", 12), getvalue = clientes_nors),
        ],        
        getvalue = clientes_nors
        )
    ]
    
    #Pie de grupo (se sumariza por cliente)
    rpt.groupfooters = [
        #sumarizo por nombre de cliente
        Band([
            Rule((500, 4), 100),    
            Element((36, 4), ("Helvetica-Bold", 12), getvalue = clientes_nors, format = lambda x: "Total de %s" % x),
            SumElement((600, 4), ("Helvetica-Bold", 12), getvalue = ventas_total, align = "right", format=lambda x:'$%0.2f'%x),    
        ],    
        getvalue = clientes_nors,
        ),
        
        #sumarizo por tipo de cliente
        Band([
            Rule((500, 4), 100),    
            Element((36, 4), ("Helvetica-Bold", 13), getvalue = tiposclientes_tipo, format = lambda x: "Total para clientes tipo %s" % x),
            SumElement((600, 4), ("Helvetica-Bold", 12), getvalue = ventas_total, align = "right", format=lambda x:'$%0.2f'%x),    
        ],    
        getvalue = tiposclientes_tipo,        
        #Inserto una nueva página luego de sumarizar
        newpageafter = True,
        ),
    ]
                            
    #Detalle    
    rpt.detailband = Band([
        Element((36, 0), ("Helvetica", 10), getvalue = ventas_fecha),        
        Element((500, 0), ("Helvetica", 10), getvalue = ventas_iva, align = "right", format=lambda x:'$%0.2f'%x),
        Element((600, 0), ("Helvetica", 10), getvalue = ventas_total, align = "right", format=lambda x:'$%0.2f'%x),        
    ])
    
    #Total de ventas
    rpt.reportfooter = Band([
        Rule((450, 4), 72),
        Element((400, 4), ("Helvetica-Bold", 12), text = "Total General"),
        SumElement((600, 4), ("Helvetica-Bold", 12), getvalue = ventas_total, align = "right", format=lambda x:'$%0.2f'%x),    
    ])
    
    #Pie de página        
    rpt.pagefooter = Band([
        Element((72*8, 0), ("Times-Bold", 18), text = "Ejemplo de Pie de Página", align = "right"),
        Element((36, 16), ("Helvetica-Bold", 12), sysvar = "pagenumber", format = lambda x: "Página %d" % x),
    ])
    
    _buffer = StringIO()
    
    canvas = Canvas(_buffer, pagesize=landscape(A4))
    canvas.setTitle('Prueba con url imagen')
    rpt.generate(canvas)
    canvas.save()
    
    response.headers['Content-Type']='application/pdf'
    response.headers['Content-Disposition'] = 'attachment; filename=ventas.pdf'
    
    return _buffer.getvalue()

 

Related slices

Comments (0)


Hosting graciously provided by:
Python Anywhere