49b3062335d36e21f3f2176d7c4e9a406221d547
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

1) # -* coding: utf8 *-
2) 
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

3) import Invoice
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

4) import re
5) 
6) # reportlab imports
7) from reportlab.lib.units import cm
8) from reportlab.lib.pagesizes import A4
9) from reportlab.pdfbase.ttfonts import TTFont, TTFontFace, TTFontFile, TTFOpenFile, \
10)                                   TTFontParser, TTFontMaker, TTFError, \
11)                                   parse_utf8, makeToUnicodeCMap, \
12)                                   FF_SYMBOLIC, FF_NONSYMBOLIC, \
13)                                   calcChecksum
14) from reportlab.pdfbase import pdfmetrics
15) from reportlab.pdfgen import canvas as Canvas
16) 
17) 
18) def _formatPrice(price, symbol='€'):
19)   '''_formatPrice(price, symbol='€'):
20)   Gets a floating point value and returns a formatted price, suffixed by 'symbol'. '''
21)   s = ("%.2f" % price).replace('.', ',')
22)   pat = re.compile(r'([0-9])([0-9]{3}[.,])')
23)   while pat.search(s):
24)     s = pat.sub(r'\1.\2', s)
25)   return s+' '+symbol
26) 
27) def _niceCount(value):
28)   '''_niceCount(value):
29)   Returns a tuple (integer , decimals) where decimals can be None'''
30)   if type(value) == int:
31)     return ('%i' % value, None)
32)   if round(value, 2) == int(value):
33)     return ('%i' % int(value), None)
34)   s = '%.2f' % value
35)   (integer, decimals) = s.split('.', 1)
36)   if decimals[-1] == '0':
37)     decimals = decimals[:-1]
38)   return (integer, decimals)
39) 
40) 
41) def _registerFonts():
Bernd Wurst reportlab-2.1 erkennt den T...

Bernd Wurst authored 16 years ago

42)   pdfmetrics.registerFont(TTFont("Vera", "Vera.ttf"))
43)   pdfmetrics.registerFont(TTFont("Vera-Bold", "VeraBd.ttf"))
44)   pdfmetrics.registerFont(TTFont("Vera-Oblique", "VeraIt.ttf"))
45)   pdfmetrics.registerFont(TTFont("Vera-BoldOblique", "VeraBI.ttf"))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

46) 
47) 
48) 
49) def _splitToWidth(canvas, text, width, font, size):
50)   '''_splitToWidth(canvas, text, width, font, size)
51)   Split a string to several lines of a given width.'''
52)   lines = []
53)   paras = text.split('\n')
54)   for para in paras:
55)     words = para.split(' ')
56)     while len(words) > 0:
57)       mywords = [words[0], ]
58)       del words[0]
59)       while len(words) > 0 and canvas.stringWidth(' '.join(mywords) + ' ' + words[0], font, size) <= width:
60)         mywords.append(words[0])
61)         del words[0]
62)       lines.append(' '.join(mywords))
63)   return lines
64) 
65) 
66) def _PageMarkers(canvas):
67)   """Setzt Falzmarken"""
68)   from reportlab.lib.units import cm
69)   canvas.setStrokeColorRGB(0,0,0)
70)   canvas.setLineWidth(0.01*cm)
71)   canvas.lines(
72)    [(0.3*cm,-10.5*cm,0.65*cm,-10.5*cm),
73)     (0.3*cm,-21.0*cm,0.65*cm,-21.0*cm),
74)     (0.3*cm,-14.85*cm,0.7*cm,-14.85*cm)]);
75) 
76) 
77) 
78) def _PageWrap(canvas):
79)   '''Seitenumbruch'''
80)   canvas.showPage()
81)   canvas.translate(0, A4[1])
82)   _PageMarkers(canvas)
83) 
84) 
85) 
86) def InvoiceToPDF(iv):
87)   _registerFonts()
88)   from StringIO import StringIO
89)   fd = StringIO()
90)   canvas = Canvas.Canvas(fd, pagesize=A4)
91)   (width, height) = A4
92)   font = 'Vera'
93)   canvas.setFont(font, 12)
94)   # Set marker to top.
95)   canvas.translate(0, A4[1])
96)   # Set default font size
97)   default_font_size = 9
98)   # set margins
99)   topmargin = 2*cm
100)   bottommargin = 2.5*cm
101)   leftmargin = 2*cm
102)   rightmargin = 2*cm
103) 
104)   num_pages = 1
105) 
106)   topcontent = -topmargin
107)   leftcontent = leftmargin
108)   rightcontent = A4[0] - rightmargin
109)   bottomcontent =  -(A4[1] - bottommargin)
110) 
111)   rightcolumn = 13*cm
112) 
113)   # Waehrungssysmbol
114)   symbol = '€'
115)   y = topcontent
116)   font_size = default_font_size
117)   font_height = 0.35*cm
118)   line_padding = 0.1*cm
119)   line_height = font_height+0.1*cm
120)   _PageMarkers(canvas)
121) 
122)   def _partHeight(part):
123)     height = 0
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

124)     if type(part) == Invoice.Text:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

125)       left, right = leftcontent, rightcontent
126)       if part.urgent:
127)         left += 1.5*cm
128)         right -= 1.5*cm
129)         height += len(part.paragraphs) * 3 * line_padding
130)       if part.headline:
131)         height += (len(_splitToWidth(canvas, part.headline, right-left, font+'-Bold', default_font_size+1)) * line_height) + line_padding
132)       for para in part.paragraphs:  
133)         height += (len(_splitToWidth(canvas, para, right-left, font, default_font_size)) * line_height) + line_padding
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

134)     elif type(part) == Invoice.Table:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

135)       ## FIXME: Das ist dreckig
136)       height = len(part.entries) * 1.1*cm
137)       height += 3*cm
138)     return height
139) 
140)   def _Footer():
141)     canvas.line(leftcontent, bottomcontent, rightcontent, bottomcontent)
142)     canvas.setFont(font, 8)
143)     canvas.drawCentredString(leftcontent+((rightcontent-leftcontent)/2), bottomcontent-10, 'schokokeks.org GbR · Bernd Wurst / Johannes Böck · http://www.schokokeks.org/')
144)     canvas.drawCentredString(leftcontent+((rightcontent-leftcontent)/2), bottomcontent-20, 'Steuernummer: 51072/01109 (FA Backnang) · USt-ID: DE255720588')
145)     canvas.drawCentredString(leftcontent+((rightcontent-leftcontent)/2), bottomcontent-30, 'Bankverbindung: Volksbank Backnang, BLZ 602 911 20, Konto Nr. 671279 017')
146)     canvas.drawCentredString(leftcontent+((rightcontent-leftcontent)/2), bottomcontent-40, 'IBAN: DE78602911200671279017, BIC: GENODES1VBK')
147)   
148)   
149)   addy_width = 8.5*cm
150)   addy_height = 5.0*cm
151) 
152)   font_size = 8
153)   x = 2.0 * cm
154)   y = -4.8 * cm - font_size - 1
155) 
156)   canvas.setFont(font, font_size)
157) 
158) 
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

159)   canvas.drawString(x, y+0.1*cm, ' schokokeks.org · Köchersberg 25 · 71540 Murrhardt')
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

160)   canvas.line(x, y, x + (8.5 * cm), y)
161)   y = y - font_size - 3
162) 
163)   font_size = 11
164)   x += 0.5*cm
165)   y -= 0.5*cm
166)   canvas.setFont(font, font_size)
167)   for line in iv.addresslines:
168)     canvas.drawString(x, y, line)
169)     y -= line_height
170) 
171) 
172)   font_size = default_font_size
173) 
174)   y = topcontent
175)   canvas.drawInlineImage("logo.png", rightcolumn, topcontent-(3*cm), width=4.08*cm, height=3*cm)
176)   y -= (3.5*cm)
177)   canvas.setFont(font+"-Bold", font_size)
178)   #canvas.drawString(rightcolumn, y, "schokokeks.org Webhosting")
179)   #y -= (font_size + 5 + 0.2*cm)
180)   canvas.drawString(rightcolumn, y, "schokokeks.org GbR")
181)   y -= (font_size + 5)
182)   canvas.setFont(font, font_size)
183)   canvas.drawString(rightcolumn, y, "Bernd Wurst / Johannes Böck")
184)   y -= (font_size + 5)
185)   canvas.drawString(rightcolumn, y, "Köchersberg 25")
186)   y -= (font_size + 5)
187)   canvas.drawString(rightcolumn, y, "71540 Murrhardt")
188)   y -= (font_size + 10)
189)   canvas.drawString(rightcolumn, y, "Tel: 07192-936432")
190)   y -= (font_size + 5)
191)   canvas.drawString(rightcolumn, y, "Fax: 07192-936431")
192)   y -= (font_size + 5)
193)   canvas.drawString(rightcolumn, y, "E-Mail: root@schokokeks.org")
194)   y -= (font_size + 10)
195)   y = -9.5*cm
196)   canvas.setFont(font+'-Bold', font_size+3)
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

197)   min_y = y
198)   if iv.caption:
199)     canvas.drawString(leftcontent, y, iv.caption)
200)     min_y -= (font_size + 3) + 0.5*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

201) 
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

202)   if type(iv) == Invoice.Tender:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

203)     canvas.setFont(font, font_size)
204)     canvas.drawString(rightcolumn, y, "Erstellungsdatum:")
205)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
206)     y -= (font_size + 0.1*cm)
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

207)   elif type(iv) == Invoice.Generic:
208)     canvas.setFont(font, font_size)
209)     canvas.drawString(rightcolumn, y, "Datum:")
210)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
211)     y -= (font_size + 0.1*cm)
212)   elif type(iv) == Invoice.Invoice:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

213)     canvas.setFont(font+'-Bold', font_size)
214)     canvas.drawString(rightcolumn, y, "Bei Fragen bitte immer angeben:")
215)     y -= (font_size + 0.2*cm)
216)     canvas.setFont(font, font_size)
217)     canvas.drawString(rightcolumn, y, "Rechnungsdatum:")
218)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
219)     y -= (font_size + 0.1*cm)
220)     canvas.drawString(rightcolumn, y, "Rechnungsnummer:")
221)     canvas.drawRightString(rightcontent, y, "%i" % iv.id)
222)     y -= (font_size + 0.1*cm)
223)   if iv.customerno:
224)     canvas.drawString(rightcolumn, y, "Kundennummer:")
225)     canvas.drawRightString(rightcontent, y, "%s" % iv.customerno)
226)     y -= (font_size + 0.5*cm)
227)   canvas.setFont(font, font_size)
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

228)   y = min(min_y, y)
229) 
230)   if iv.salutation:
231)     canvas.drawString(leftcontent, y, iv.salutation)
232)     y -= font_size + 0.2*cm
233)     if type(iv) in [Invoice.Tender, Invoice.Invoice]:
234)       introText = 'hiermit stellen wir Ihnen die nachfolgend genannten Leistungen in Rechnung.'
235)       if type(iv) == Invoice.Tender:
236)         introText = 'hiermit unterbreiten wir Ihnen folgendes Angebot.'
237)       intro = _splitToWidth(canvas, introText, rightcontent - leftcontent, font, font_size)
238)       for line in intro:
239)         canvas.drawString(leftcontent, y, line)
240)         y -= font_size + 0.1*cm
241)       y -= font_size + 0.1*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

242) 
243)   
244)   font_size = default_font_size
245)   for part in iv.parts:
246)     if y - _partHeight(part) < (bottomcontent + (0.5*cm)):
247)       num_pages += 1
248)       y = bottomcontent + (0.5*cm)
249)       canvas.setFont(font, default_font_size-2)
250)       canvas.drawRightString(rightcontent, bottomcontent + line_padding, 'Fortsetzung auf Seite %i' % num_pages)
251)       _Footer()
252)       _PageWrap(canvas)
253)       y = topcontent - font_size
254)       canvas.setFillColor((0,0,0))
255)       canvas.setFont(font, font_size-2)
256)       canvas.drawCentredString(leftcontent + (rightcontent - leftcontent) / 2, y, '- Seite %i -' % num_pages)
257)       y -= line_padding*3
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

258)     if type(part) == Invoice.Table:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

259)         
260)       left = leftcontent
261)       right = rightcontent
262)       top = topcontent
263)       bottom = bottomcontent
264)       canvas.setFont(font, font_size)
265)       canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
266)       canvas.drawString(left+(1.6*cm), y-line_height+line_padding, 'Beschreibung')
267)       if len(part.vat) == 1:
268)         canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
269)       else:
270)         canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
271)       canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
272)       canvas.setLineWidth(0.01*cm)
273)       canvas.line(left, y - line_height, right, y - line_height)
274)       y -= line_height + 0.02*cm
275)       odd=True
276)       for el in part.entries:
277)         subject = []
278)         if len(part.vat) == 1:
279)           subject = _splitToWidth(canvas, el['subject'], 10.3*cm, font, font_size)
280)         else:
281)           subject = _splitToWidth(canvas, el['subject'], 9.3*cm, font, font_size)
282)         desc = []
283)         if 'desc' in el and el['desc'] != '':
284)           desc = _splitToWidth(canvas, el['desc'], 14.5*cm, font, font_size)
285) 
286)         # draw the background
287)         if not odd:
288)           canvas.setFillColorRGB(0.9, 0.9, 0.9)
289)         else:
290)           canvas.setFillColorRGB(1, 1, 1)
291)         need_lines = len(subject) + len(desc)
292)         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)
293)         canvas.setFillColorRGB(0, 0, 0)
294)         y -= line_padding
295)         (integer, decimals) = _niceCount(el['count'])
296)         canvas.drawRightString(left+0.8*cm, y-font_height, integer)
297)         if decimals:
298)           canvas.drawString(left+0.8*cm, y-font_height, ',%s' % decimals)
299)         if len(part.vat) == 1:
300)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
301)           canvas.drawRightString(left+14.3*cm, y-font_height, _formatPrice(el['price']))
302)           if el['tender']:  
303)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
304)           else:
305)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
306)           subject = subject[1:]
307)           x = 1
308)           for line in subject:
309)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
310)             x += 1
311)           for line in desc:
312)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
313)             x += 1
314)         else:
315)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
316)           canvas.drawRightString(left+13.3*cm, y-font_height, _formatPrice(el['price']))
317)           canvas.drawString(left+13.7*cm, y-font_height, str(part.vat[el['vat']][1]))
318)           if el['tender']:  
319)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
320)           else:
321)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
322)           subject = subject[1:]
323)           x = 1
324)           for line in subject:
325)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
326)             x += 1
327)           for line in desc:
328)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
329)             x += 1
330)         odd = not odd
331)         y -= (need_lines * line_height) + line_padding
332)       if part.summary:
333)         y -= (0.3*cm)
334)         if part.vatType == 'gross':
335)           canvas.setFont(font+'-Bold', font_size)
336)           if iv.tender:
337)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
338)           else:
339)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
340)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
341)           canvas.setFont(font, font_size)
342)           y -= line_height + line_padding
343)           summaries = []
344)           if len(part.vat) == 1:
345)             vat = part.vat.keys()[0]
346)             if iv.tender:
347)               summaries.append(('Im Gesamtbetrag sind %.1f%% MwSt enthalten:' % (vat*100), _formatPrice((part.sum/(vat+1))*vat)))
348)             else:
349)               summaries.append(('Im Rechnungsbetrag sind %.1f%% MwSt enthalten:' % (vat*100), _formatPrice((part.sum/(vat+1))*vat)))
350)           else:
351)             for vat, vatdata in part.vat.iteritems():
352)               summaries.append('%s: Im Teilbetrag von %s sind %.1f%% MwSt enthalten:' % (vatdata[1], _formatPrice(vatdata[0]), vat*100), _formatPrice((vatdata[0]/(vat+1))*vat))
353)           summaries.sort()
354)           for line in summaries:
355)             canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
356)             canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
357)             y -= line_height
358)         else:
359)           canvas.drawRightString(left + 14.5*cm, y-font_height, 'Nettobetrag:')
360)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
361)           y -= line_height
362)           summaries = []
363)           if len(part.vat) == 1:
364)             vat = part.vat.keys()[0]
365)             summaries.append(('zzgl. %.1f%% MwSt:' % (vat*100), _formatPrice(vat*part.sum)))
366)           else:
367)             for vat, vatdata in part.vat.iteritems():
368)               summaries.append(('zzgl. %.1f%% MwSt (%s):' % (vat*100, vatdata[1]), _formatPrice(vat*vatdata[0])))
369)           summaries.sort()
370)           for line in summaries:
371)             canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
372)             canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
373)             y -= line_height
374)           sum = 0
375)           for vat, vatdata in part.vat.iteritems():
376)             sum += (vat+1)*vatdata[0]
377)           canvas.setFont(font+'-Bold', font_size)
378)           if iv.tender:
379)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
380)           else:
381)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
382)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(sum))
383)           canvas.setFont(font, font_size)
384)           y -= line_height + line_padding
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

385)     elif type(part) == Invoice.Text: