[Tutor] Please comment my script

paulino1 at sapo.pt paulino1 at sapo.pt
Mon Nov 13 20:40:55 CET 2006


This is a script I have at work, it is running fine (gives the output I want).
Any comments are very welcome.

It queries a database and gives out a reportlab pdf file with a balance sheet of
costs per department.

In the first version there were neither functions nor classes, it worked as
well, but with no reusability.

A second version I defined the functions very close to the ones found here, but
had lots of problems because the variables were all local to each function. So
I changed direction to this final version.

Maybe the matter here is not best suited for OOP. The class definition sounds
more like action than object...

I think the Query method is the peace of code that is more in need of
improvement...

Paulino

:::::::::::::::::::::::::::::::::::::::::
# -*- coding: latin-1 -*-
# Balancete por departamento

import sys, re

# Importa modulo MS SQL
import pymssql
con=pymssql.connect(host='gi-clsql', database='baandb',user='baan',
password='baan' )
cur=con.cursor()


# Importa os modulos ReportLab
from reportlab.platypus import *
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus.flowables import Flowable


def FormCGI() :
    """Cathes the values 'ano', 'mes' and 'dept' from an HTML form """
    import cgi
    import cgitb; cgitb.enable()
    form=cgi.FieldStorage()
    try :
        ano=form["ano"].value
        mes=form["mes"].value
        dept=form["custo"].value
        return ano, mes, dept

    except KeyError :
        print "Content-type: text/html\n\n"
        print """<html><body>
        <h3>Balancete por centro de custo</h3>
        <p><b>É necessário preencher todos os campos</b></p>
        <form action="balcc01.pyw" method="POST" target="principal">
        Centro de custo: <input name="custo" type="text" /><br>
        Exercicio: <input name="ano" type="text" value="2006"/>
        Periodo até: <input name="mes" type="text" value="12"/>
        <input type="submit" value="Listar" />
        </body></html> """
        sys.exit(0)



class BalanceteCusto:
    """ Performs a query in a MS SQL database and returns a pdf file containing
a report of costs per department """

    def __init__(self, ano, mes, dept):
        self.ano = ano
        self.mes = mes
        self.dept = dept
        self.ppistyle = ParagraphStyle('normal', fontName='helvetica',
fontSize=8 )
        self.pag=( 21*cm, 29.7*cm)
        self.PL=self.pag[0]
        self.PA=self.pag[1]           # Largura, altura

        self.meses={1:'Janeiro', 2:'Fevereiro', 3:'Marco', 4:'Abril', 5:'Maio',
6:'Junho', 7:'Julho',
            8:'Agosto', 9:'Setembro', 10:'Outubro', 11:'Novembro',
12:'Dezembro', 13:'Regularizacoes'}
        self.titulo="BALANCETE POR CENTRO DE CUSTO"
        self.pdf = 'Balancetecc%s.pdf' %(self.dept)

        #### Definição dos formatos da tabela
        self.st=[('ALIGN', (2, 0), (-1,-1), 'RIGHT') ,
        ('FONT', (0,1), (-1,-1), 'Helvetica', 8),
        ('FONT', (0,0), (-1, 0), 'Helvetica', 9),
        ('FONT', (0,-1), (-1, -1), 'Helvetica', 9),
        ('LINEBELOW', (0,0), (-1,0), 1, colors.blue),
        ('TOPPADDING', (0,1), (-1,-1), 1),
        ('BOTTOMPADDING', (0,1), (-1,-1), 1) ]
        self.Query()
        self.CriaPDF()


    def Formata(self,num):
        """Formats numbers as the local settings"""
        import locale
        locale.setlocale(locale.LC_ALL, '')
        if num == 0.0 : return ''
        else : return locale.format("%.*f", (2, num), True)




    def Pagina(self, canvas, doc) :
        """Sets the fixed content of the pages (reportlab)"""
        # Cabeçalho
        canvas.setFont('Helvetica', 13)
        # Titulo centrado no papel
        canvas.drawCentredString( self.PL / 2.0, self.PA - 2*cm, self.titulo)
        canvas.setFont('Helvetica', 10)
        #canvas.drawRightString(PL-2.3*cm, PA-3.1*cm, 'De '+dini+' a '+dfim)
        canvas.drawString( 3.5*cm, self.PA - 2.6*cm, self.subtit1)
        canvas.drawString( 3.5*cm, self.PA - 3.1*cm, self.subtit2)

        # Rodape - lado direito
        canvas.setFont('Helvetica', 8)
        canvas.drawRightString( self.PL-60, 0.8*cm, 'Pagina %d' %(doc.page) )
        canvas.line( 60, 30, self.PL-60, 30)


    def Acumula(self, item, ctpai) :
        """Calculates grand-total and subtotals for the itermediate accounts"""
        tdeb = self.acum[ctpai][1] + item[1]
        tcred = self.acum[ctpai][2] + item[2]
        self.acum[ctpai] = [ self.contas[ctpai], tdeb, tcred ]

    def Desc(self, texto) :
        """Encodes text as required by reportlab"""
        #return Paragraph( unicode( re.sub('&', '&amp;', texto) , 'latin-1'),
style=ppistyle )
        return unicode( texto, 'latin-1')



    def Query( self ) :

        cur.execute( """SELECT A.t_leac, SUM(A.t_fdam), SUM(A.t_fcam)
        FROM ( SELECT c.t_leac, c.t_fdam, c.t_fcam
            FROM ttfgld202100 c
            WHERE c.t_cono=100 AND c.t_ptyp=1 AND c.t_year=%s AND c.t_prno<%d
AND c.t_dtyp=5 AND c.t_dimx='%s'
            AND c.t_leac BETWEEN '6' AND '79999') A
        GROUP BY A.t_leac """ % (self.ano, eval(self.mes)+1, self.dept ) )
        valores=cur.fetchall()

        # Obtem descritivo das contas e centro de custo
        cur.execute("SELECT gld8.t_leac, gld8.t_desc FROM ttfgld008100 gld8 " )
        self.contas={}
        for i in cur.fetchall() :
            self.contas[i[0].strip() ] = i[1].strip()

        cur.execute("SELECT g10.t_desc FROM ttfgld010100 g10 WHERE g10.t_dtyp=5
AND g10.t_dimx='%s'" %(self.dept) )
        self.deptdesc=cur.fetchone()


        self.acum={}
        self.final=[['Conta', 'Descricao', 'Debito', 'Credito', 'Saldo']]
        saldo, tdeb, tcred = 0, 0, 0
        for v in valores :
            cta = v[0].strip()
            saldo=saldo+v[1]-v[2]
            tdeb=tdeb+v[1]
            tcred=tcred+v[2]
            self.acum[cta]=[self.contas[cta], v[1], v[2] ]

            for n in range(1, len(cta)-1 ) :
                if cta[:-n] in self.contas.keys() :
                    if cta[:-n] in self.acum.keys() : self.Acumula( v, cta[:-n])
                    else :
                        self.acum[ cta[:-n] ] = [ self.contas[cta[:-n]], 0, 0 ]
                        self.Acumula( v, cta[:-n])

        ak=self.acum.keys()
        ak.sort()
        for v in ak :
            linpdf=[ v, self.Desc( self.acum[v][0] ),
                self.Formata( self.acum[v][1] ), self.Formata( self.acum[v][2]
), self.Formata( self.acum[v][1]-self.acum[v][2] ) ]
            self.final.append(linpdf)
        self.final.append( ['', 'Total', self.Formata(tdeb),
self.Formata(tcred), self.Formata(tdeb - tcred) ] )




    def CriaPDF(self):
        doc = SimpleDocTemplate(self.pdf, pagesize=self.pag, topMargin=3*cm,
bottomMargin=cm, rightMargin=2.5*cm, leftMargin=2.5*cm)
        tab=Table( self.final, colWidths=(50, 180, 70, 70, 70), style=self.st,
repeatRows=1 )
        story=[tab]
        self.subtit1="Centro de custo: %s - %s " %(self.dept,
unicode(self.deptdesc[0], 'latin-1') )
        self.subtit2="Ano %s, acumulado ate ao mes de %s" % (self.ano,
self.meses[eval(self.mes)] )
        doc.build(story, onFirstPage=self.Pagina, onLaterPages=self.Pagina)



    def GeraHTML(self):
        print "Content-Type:text/html\n\n<html><body><h2>%s</h2>" %(self.titulo)
        print '<a href="/%s" target="_blank">VISUALIZAR</a>' %(self.pdf)
        print '</body></html>'


if __name__ == '__main__' :

    for dpt in ('13', '14', '15') :
        BalanceteCusto( '2006', '10', dpt)
    con.close()

___________________________________________________________________

O SAPO já está livre de vírus com a Panda Software, fique você também!
Clique em: http://antivirus.sapo.pt



More information about the Tutor mailing list