Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
1) # -* coding: utf8 *-
2)
|
Generisch
Bernd Wurst authored 16 years ago
|
3) import Invoice
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
4) import re
5)
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
6) # our page size and margins
7) from metrics import *
8) # our custom page style
9) from custom_elements import basicPage, firstPage, address
10)
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
11) # reportlab imports
12) from reportlab.lib.units import cm
13) from reportlab.pdfgen import canvas as Canvas
14)
15)
16) def _formatPrice(price, symbol='€'):
17) '''_formatPrice(price, symbol='€'):
18) Gets a floating point value and returns a formatted price, suffixed by 'symbol'. '''
19) s = ("%.2f" % price).replace('.', ',')
20) pat = re.compile(r'([0-9])([0-9]{3}[.,])')
21) while pat.search(s):
22) s = pat.sub(r'\1.\2', s)
23) return s+' '+symbol
24)
25) def _niceCount(value):
26) '''_niceCount(value):
27) Returns a tuple (integer , decimals) where decimals can be None'''
28) if type(value) == int:
29) return ('%i' % value, None)
30) if round(value, 2) == int(value):
31) return ('%i' % int(value), None)
32) s = '%.2f' % value
33) (integer, decimals) = s.split('.', 1)
34) if decimals[-1] == '0':
35) decimals = decimals[:-1]
36) return (integer, decimals)
37)
38)
39) def _splitToWidth(canvas, text, width, font, size):
40) '''_splitToWidth(canvas, text, width, font, size)
41) Split a string to several lines of a given width.'''
42) lines = []
43) paras = text.split('\n')
44) for para in paras:
45) words = para.split(' ')
46) while len(words) > 0:
47) mywords = [words[0], ]
48) del words[0]
49) while len(words) > 0 and canvas.stringWidth(' '.join(mywords) + ' ' + words[0], font, size) <= width:
50) mywords.append(words[0])
51) del words[0]
52) lines.append(' '.join(mywords))
53) return lines
54)
55)
56)
57) def _PageWrap(canvas):
58) '''Seitenumbruch'''
59) canvas.showPage()
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
60) basicPage(canvas)
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
61)
62)
63)
64) def InvoiceToPDF(iv):
65) from StringIO import StringIO
66) fd = StringIO()
67) canvas = Canvas.Canvas(fd, pagesize=A4)
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
68)
69)
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
70) canvas.setFont(font, 12)
71)
72) num_pages = 1
73)
74) # Waehrungssysmbol
75) symbol = '€'
76) y = topcontent
77) font_size = default_font_size
78) font_height = 0.35*cm
79) line_padding = 0.1*cm
80) line_height = font_height+0.1*cm
81)
82) def _partHeight(part):
83) height = 0
|
Generisch
Bernd Wurst authored 16 years ago
|
84) if type(part) == Invoice.Text:
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
85) left, right = leftcontent, rightcontent
86) if part.urgent:
87) left += 1.5*cm
88) right -= 1.5*cm
89) height += len(part.paragraphs) * 3 * line_padding
90) if part.headline:
91) height += (len(_splitToWidth(canvas, part.headline, right-left, font+'-Bold', default_font_size+1)) * line_height) + line_padding
92) for para in part.paragraphs:
93) height += (len(_splitToWidth(canvas, para, right-left, font, default_font_size)) * line_height) + line_padding
|
Generisch
Bernd Wurst authored 16 years ago
|
94) elif type(part) == Invoice.Table:
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
95) ## FIXME: Das ist dreckig
96) height = len(part.entries) * 1.1*cm
97) height += 3*cm
98) return height
99)
100)
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
101)
102) address(canvas, iv.addresslines)
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
103)
104) font_size = default_font_size
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
105) y = firstPage(canvas)
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
106)
107) canvas.setFont(font+'-Bold', font_size+3)
|
Generisch
Bernd Wurst authored 16 years ago
|
108) min_y = y
109) if iv.caption:
110) canvas.drawString(leftcontent, y, iv.caption)
111) min_y -= (font_size + 3) + 0.5*cm
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
112)
|
Generisch
Bernd Wurst authored 16 years ago
|
113) if type(iv) == Invoice.Tender:
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
114) canvas.setFont(font, font_size)
115) canvas.drawString(rightcolumn, y, "Erstellungsdatum:")
116) canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
117) y -= (font_size + 0.1*cm)
|
Generisch
Bernd Wurst authored 16 years ago
|
118) elif type(iv) == Invoice.Generic:
119) canvas.setFont(font, font_size)
120) canvas.drawString(rightcolumn, y, "Datum:")
121) canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
122) y -= (font_size + 0.1*cm)
123) elif type(iv) == Invoice.Invoice:
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
124) canvas.setFont(font+'-Bold', font_size)
125) canvas.drawString(rightcolumn, y, "Bei Fragen bitte immer angeben:")
126) y -= (font_size + 0.2*cm)
127) canvas.setFont(font, font_size)
128) canvas.drawString(rightcolumn, y, "Rechnungsdatum:")
129) canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
130) y -= (font_size + 0.1*cm)
131) canvas.drawString(rightcolumn, y, "Rechnungsnummer:")
132) canvas.drawRightString(rightcontent, y, "%i" % iv.id)
133) y -= (font_size + 0.1*cm)
134) if iv.customerno:
135) canvas.drawString(rightcolumn, y, "Kundennummer:")
136) canvas.drawRightString(rightcontent, y, "%s" % iv.customerno)
137) y -= (font_size + 0.5*cm)
138) canvas.setFont(font, font_size)
|
Generisch
Bernd Wurst authored 16 years ago
|
139) y = min(min_y, y)
140)
141) if iv.salutation:
142) canvas.drawString(leftcontent, y, iv.salutation)
143) y -= font_size + 0.2*cm
144) if type(iv) in [Invoice.Tender, Invoice.Invoice]:
145) introText = 'hiermit stellen wir Ihnen die nachfolgend genannten Leistungen in Rechnung.'
146) if type(iv) == Invoice.Tender:
147) introText = 'hiermit unterbreiten wir Ihnen folgendes Angebot.'
148) intro = _splitToWidth(canvas, introText, rightcontent - leftcontent, font, font_size)
149) for line in intro:
150) canvas.drawString(leftcontent, y, line)
151) y -= font_size + 0.1*cm
152) y -= font_size + 0.1*cm
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
153)
154)
155) font_size = default_font_size
156) for part in iv.parts:
157) if y - _partHeight(part) < (bottomcontent + (0.5*cm)):
158) num_pages += 1
159) y = bottomcontent + (0.5*cm)
160) canvas.setFont(font, default_font_size-2)
161) canvas.drawRightString(rightcontent, bottomcontent + line_padding, 'Fortsetzung auf Seite %i' % num_pages)
162) _PageWrap(canvas)
163) y = topcontent - font_size
164) canvas.setFillColor((0,0,0))
165) canvas.setFont(font, font_size-2)
166) canvas.drawCentredString(leftcontent + (rightcontent - leftcontent) / 2, y, '- Seite %i -' % num_pages)
167) y -= line_padding*3
|
Generisch
Bernd Wurst authored 16 years ago
|
168) if type(part) == Invoice.Table:
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
169)
170) left = leftcontent
171) right = rightcontent
172) top = topcontent
173) bottom = bottomcontent
174) canvas.setFont(font, font_size)
175) canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
176) canvas.drawString(left+(1.6*cm), y-line_height+line_padding, 'Beschreibung')
177) if len(part.vat) == 1:
178) canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
179) else:
180) canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
181) canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
182) canvas.setLineWidth(0.01*cm)
183) canvas.line(left, y - line_height, right, y - line_height)
184) y -= line_height + 0.02*cm
185) odd=True
186) for el in part.entries:
187) subject = []
188) if len(part.vat) == 1:
189) subject = _splitToWidth(canvas, el['subject'], 10.3*cm, font, font_size)
190) else:
191) subject = _splitToWidth(canvas, el['subject'], 9.3*cm, font, font_size)
192) desc = []
193) if 'desc' in el and el['desc'] != '':
194) desc = _splitToWidth(canvas, el['desc'], 14.5*cm, font, font_size)
195)
196) # draw the background
197) if not odd:
198) canvas.setFillColorRGB(0.9, 0.9, 0.9)
199) else:
200) canvas.setFillColorRGB(1, 1, 1)
201) need_lines = len(subject) + len(desc)
202) canvas.rect(left, y - (need_lines*line_height)-(2*line_padding), height = (need_lines*line_height)+(2*line_padding), width = right-left, fill=1, stroke=0)
203) canvas.setFillColorRGB(0, 0, 0)
204) y -= line_padding
205) (integer, decimals) = _niceCount(el['count'])
206) canvas.drawRightString(left+0.8*cm, y-font_height, integer)
207) if decimals:
208) canvas.drawString(left+0.8*cm, y-font_height, ',%s' % decimals)
209) if len(part.vat) == 1:
210) canvas.drawString(left+1.7*cm, y-font_height, subject[0])
211) canvas.drawRightString(left+14.3*cm, y-font_height, _formatPrice(el['price']))
212) if el['tender']:
213) canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
214) else:
215) canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
216) subject = subject[1:]
217) x = 1
218) for line in subject:
219) canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
220) x += 1
221) for line in desc:
222) canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
223) x += 1
224) else:
225) canvas.drawString(left+1.7*cm, y-font_height, subject[0])
226) canvas.drawRightString(left+13.3*cm, y-font_height, _formatPrice(el['price']))
227) canvas.drawString(left+13.7*cm, y-font_height, str(part.vat[el['vat']][1]))
228) if el['tender']:
229) canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
230) else:
231) canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
232) subject = subject[1:]
233) x = 1
234) for line in subject:
235) canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
236) x += 1
237) for line in desc:
238) canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
239) x += 1
240) odd = not odd
241) y -= (need_lines * line_height) + line_padding
242) if part.summary:
243) y -= (0.3*cm)
244) if part.vatType == 'gross':
245) canvas.setFont(font+'-Bold', font_size)
246) if iv.tender:
247) canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
248) else:
249) canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
250) canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
251) canvas.setFont(font, font_size)
252) y -= line_height + line_padding
253) summaries = []
254) if len(part.vat) == 1:
255) vat = part.vat.keys()[0]
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
256) (integer, decimals) = _niceCount( (vat * 100) )
257) vatstr = '%s' % integer
258) if decimals:
259) vatstr += ',%s' % decimals
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
260) if iv.tender:
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
261) summaries.append(('Im Gesamtbetrag sind %s%% MwSt enthalten:' % vatstr, _formatPrice((part.sum/(vat+1))*vat)))
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
262) else:
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
263) summaries.append(('Im Rechnungsbetrag sind %s%% MwSt enthalten:' % vatstr, _formatPrice((part.sum/(vat+1))*vat)))
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
264) else:
265) for vat, vatdata in part.vat.iteritems():
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
266) (integer, decimals) = _niceCount( (vat * 100) )
267) vatstr = '%s' % integer
268) if decimals:
269) vatstr += ',%s' % decimals
270) summaries.append(('%s: Im Teilbetrag von %s sind %s%% MwSt enthalten:' % (vatdata[1], _formatPrice(vatdata[0]), vatstr), _formatPrice((vatdata[0]/(vat+1))*vat)))
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
271) summaries.sort()
272) for line in summaries:
273) canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
274) canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
275) y -= line_height
276) else:
277) canvas.drawRightString(left + 14.5*cm, y-font_height, 'Nettobetrag:')
278) canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
279) y -= line_height
280) summaries = []
281) if len(part.vat) == 1:
282) vat = part.vat.keys()[0]
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
283) (integer, decimals) = _niceCount( (vat * 100) )
284) vatstr = '%s' % integer
285) if decimals:
286) vatstr += ',%s' % decimals
287) summaries.append(('zzgl. %s%% MwSt:' % vatstr, _formatPrice(vat*part.sum)))
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
288) else:
289) for vat, vatdata in part.vat.iteritems():
|
Trennung von Firmen-spezifi...
Bernd Wurst authored 16 years ago
|
290) (integer, decimals) = _niceCount( (vat * 100) )
291) vatstr = '%s' % integer
292) if decimals:
293) vatstr += ',%s' % decimals
294) summaries.append(('zzgl. %s%% MwSt (%s):' % (vatstr, vatdata[1]), _formatPrice(vat*vatdata[0])))
|
Struktur verändern (broken!)
Bernd Wurst authored 16 years ago
|
295) summaries.sort()
296) for line in summaries:
297) canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
298) canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
299) y -= line_height
300) sum = 0
301) for vat, vatdata in part.vat.iteritems():
302) sum += (vat+1)*vatdata[0]
303) canvas.setFont(font+'-Bold', font_size)
304) if iv.tender:
305) canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
306) else:
307) canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
308) canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(sum))
309) canvas.setFont(font, font_size)
310) y -= line_height + line_padding
|
Generisch
Bernd Wurst authored 16 years ago
|
311) elif type(part) == Invoice.Text:
|