[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('&', '&', 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