7cfd445c3d9342f2ed506030bd48c6fc3d56518c
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) 
Bernd Wurst 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) 
Bernd Wurst 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) 
Bernd Wurst InvoiceText als Blocksatz d...

Bernd Wurst authored 16 years ago

56) def _drawJustifiedString(x, y, text, canvas, width, font, size):
57)   text = text.strip()
58)   if canvas.stringWidth(text, font, size) > width:
59)     canvas.drawString(x, y, text)
60)     # too long line, I cannot handle this
61)     return
62)   if not ' ' in text:
63)     canvas.drawString(x, y, text)
64)     # no space in there, nothing to justify
65)     return
66)   
67)   words = [ '%s' % w for w in text.split(' ')]
68)   words_width = 0.0
69)   for word in words:
70)     words_width += canvas.stringWidth(word, font, size)
71)   
72)   available_space = width - words_width
73)   available_each = available_space / float((len(words) - 1))
74)   from pprint import pprint
75)   pprint( (width, words_width)) 
76)  
77)   my_x = x
78)   for idx in range(len(words)):
79)     word = words[idx]
80)     canvas.drawString(my_x, y, word)
81)     my_x += canvas.stringWidth(word, font, size) + available_each
82)   return
83) 
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

84) 
85) def _PageWrap(canvas):
86)   '''Seitenumbruch'''
87)   canvas.showPage()
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

88)   basicPage(canvas)
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

89) 
90) 
91) 
92) def InvoiceToPDF(iv):
93)   from StringIO import StringIO
94)   fd = StringIO()
95)   canvas = Canvas.Canvas(fd, pagesize=A4)
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

96)   
97)   
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

98)   canvas.setFont(font, 12)
99) 
100)   num_pages = 1
101) 
102)   # Waehrungssysmbol
103)   symbol = '€'
104)   y = topcontent
105)   font_size = default_font_size
106)   font_height = 0.35*cm
107)   line_padding = 0.1*cm
108)   line_height = font_height+0.1*cm
109) 
110)   def _partHeight(part):
111)     height = 0
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

113)       left, right = leftcontent, rightcontent
114)       if part.urgent:
115)         left += 1.5*cm
116)         right -= 1.5*cm
117)         height += len(part.paragraphs) * 3 * line_padding
118)       if part.headline:
119)         height += (len(_splitToWidth(canvas, part.headline, right-left, font+'-Bold', default_font_size+1)) * line_height) + line_padding
120)       for para in part.paragraphs:  
121)         height += (len(_splitToWidth(canvas, para, right-left, font, default_font_size)) * line_height) + line_padding
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

123)       ## FIXME: Das ist dreckig
124)       height = len(part.entries) * 1.1*cm
125)       height += 3*cm
126)     return height
127) 
128) 
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

129)    
130)   address(canvas, iv.addresslines)
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

131) 
132)   font_size = default_font_size
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

133)   y = firstPage(canvas)
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

134) 
135)   canvas.setFont(font+'-Bold', font_size+3)
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

136)   min_y = y
137)   if iv.caption:
138)     canvas.drawString(leftcontent, y, iv.caption)
139)     min_y -= (font_size + 3) + 0.5*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

140) 
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

146)   elif type(iv) == Invoice.Generic:
147)     canvas.setFont(font, font_size)
148)     canvas.drawString(rightcolumn, y, "Datum:")
149)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
150)     y -= (font_size + 0.1*cm)
151)   elif type(iv) == Invoice.Invoice:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

152)     canvas.setFont(font+'-Bold', font_size)
153)     canvas.drawString(rightcolumn, y, "Bei Fragen bitte immer angeben:")
154)     y -= (font_size + 0.2*cm)
155)     canvas.setFont(font, font_size)
156)     canvas.drawString(rightcolumn, y, "Rechnungsdatum:")
157)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
158)     y -= (font_size + 0.1*cm)
159)     canvas.drawString(rightcolumn, y, "Rechnungsnummer:")
160)     canvas.drawRightString(rightcontent, y, "%i" % iv.id)
161)     y -= (font_size + 0.1*cm)
162)   if iv.customerno:
163)     canvas.drawString(rightcolumn, y, "Kundennummer:")
164)     canvas.drawRightString(rightcontent, y, "%s" % iv.customerno)
165)     y -= (font_size + 0.5*cm)
166)   canvas.setFont(font, font_size)
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

167)   y = min(min_y, y)
168) 
169)   if iv.salutation:
170)     canvas.drawString(leftcontent, y, iv.salutation)
171)     y -= font_size + 0.2*cm
172)     if type(iv) in [Invoice.Tender, Invoice.Invoice]:
173)       introText = 'hiermit stellen wir Ihnen die nachfolgend genannten Leistungen in Rechnung.'
174)       if type(iv) == Invoice.Tender:
175)         introText = 'hiermit unterbreiten wir Ihnen folgendes Angebot.'
176)       intro = _splitToWidth(canvas, introText, rightcontent - leftcontent, font, font_size)
177)       for line in intro:
178)         canvas.drawString(leftcontent, y, line)
179)         y -= font_size + 0.1*cm
180)       y -= font_size + 0.1*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

181) 
182)   
183)   font_size = default_font_size
184)   for part in iv.parts:
185)     if y - _partHeight(part) < (bottomcontent + (0.5*cm)):
186)       num_pages += 1
187)       y = bottomcontent + (0.5*cm)
188)       canvas.setFont(font, default_font_size-2)
189)       canvas.drawRightString(rightcontent, bottomcontent + line_padding, 'Fortsetzung auf Seite %i' % num_pages)
190)       _PageWrap(canvas)
191)       y = topcontent - font_size
192)       canvas.setFillColor((0,0,0))
193)       canvas.setFont(font, font_size-2)
194)       canvas.drawCentredString(leftcontent + (rightcontent - leftcontent) / 2, y, '- Seite %i -' % num_pages)
195)       y -= line_padding*3
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

197)         
198)       left = leftcontent
199)       right = rightcontent
200)       top = topcontent
201)       bottom = bottomcontent
202)       canvas.setFont(font, font_size)
203)       canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
204)       canvas.drawString(left+(1.6*cm), y-line_height+line_padding, 'Beschreibung')
205)       if len(part.vat) == 1:
206)         canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
207)       else:
208)         canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
209)       canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
210)       canvas.setLineWidth(0.01*cm)
211)       canvas.line(left, y - line_height, right, y - line_height)
212)       y -= line_height + 0.02*cm
213)       odd=True
214)       for el in part.entries:
215)         subject = []
216)         if len(part.vat) == 1:
217)           subject = _splitToWidth(canvas, el['subject'], 10.3*cm, font, font_size)
218)         else:
219)           subject = _splitToWidth(canvas, el['subject'], 9.3*cm, font, font_size)
220)         desc = []
221)         if 'desc' in el and el['desc'] != '':
222)           desc = _splitToWidth(canvas, el['desc'], 14.5*cm, font, font_size)
223) 
224)         # draw the background
225)         if not odd:
226)           canvas.setFillColorRGB(0.9, 0.9, 0.9)
227)         else:
228)           canvas.setFillColorRGB(1, 1, 1)
229)         need_lines = len(subject) + len(desc)
230)         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)
231)         canvas.setFillColorRGB(0, 0, 0)
232)         y -= line_padding
233)         (integer, decimals) = _niceCount(el['count'])
234)         canvas.drawRightString(left+0.8*cm, y-font_height, integer)
235)         if decimals:
236)           canvas.drawString(left+0.8*cm, y-font_height, ',%s' % decimals)
237)         if len(part.vat) == 1:
238)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
239)           canvas.drawRightString(left+14.3*cm, y-font_height, _formatPrice(el['price']))
240)           if el['tender']:  
241)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
242)           else:
243)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
244)           subject = subject[1:]
245)           x = 1
246)           for line in subject:
247)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
248)             x += 1
249)           for line in desc:
250)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
251)             x += 1
252)         else:
253)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
254)           canvas.drawRightString(left+13.3*cm, y-font_height, _formatPrice(el['price']))
255)           canvas.drawString(left+13.7*cm, y-font_height, str(part.vat[el['vat']][1]))
256)           if el['tender']:  
257)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
258)           else:
259)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
260)           subject = subject[1:]
261)           x = 1
262)           for line in subject:
263)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
264)             x += 1
265)           for line in desc:
266)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
267)             x += 1
268)         odd = not odd
269)         y -= (need_lines * line_height) + line_padding
270)       if part.summary:
271)         y -= (0.3*cm)
272)         if part.vatType == 'gross':
273)           canvas.setFont(font+'-Bold', font_size)
274)           if iv.tender:
275)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
276)           else:
277)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
278)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
279)           canvas.setFont(font, font_size)
280)           y -= line_height + line_padding
281)           summaries = []
282)           if len(part.vat) == 1:
283)             vat = part.vat.keys()[0]
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

284)             (integer, decimals) = _niceCount( (vat * 100) )
285)             vatstr = '%s' % integer
286)             if decimals:
287)               vatstr += ',%s' % decimals
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

288)             if iv.tender:
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

289)               summaries.append(('Im Gesamtbetrag sind %s%% MwSt enthalten:' % vatstr, _formatPrice((part.sum/(vat+1))*vat)))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

290)             else:
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

291)               summaries.append(('Im Rechnungsbetrag sind %s%% MwSt enthalten:' % vatstr, _formatPrice((part.sum/(vat+1))*vat)))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

292)           else:
293)             for vat, vatdata in part.vat.iteritems():
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

294)               (integer, decimals) = _niceCount( (vat * 100) )
295)               vatstr = '%s' % integer
296)               if decimals:
297)                 vatstr += ',%s' % decimals
298)               summaries.append(('%s: Im Teilbetrag von %s sind %s%% MwSt enthalten:' % (vatdata[1], _formatPrice(vatdata[0]), vatstr), _formatPrice((vatdata[0]/(vat+1))*vat)))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

299)           summaries.sort()
300)           for line in summaries:
301)             canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
302)             canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
303)             y -= line_height
304)         else:
305)           canvas.drawRightString(left + 14.5*cm, y-font_height, 'Nettobetrag:')
306)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
307)           y -= line_height
308)           summaries = []
309)           if len(part.vat) == 1:
310)             vat = part.vat.keys()[0]
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

311)             (integer, decimals) = _niceCount( (vat * 100) )
312)             vatstr = '%s' % integer
313)             if decimals:
314)               vatstr += ',%s' % decimals
315)             summaries.append(('zzgl. %s%% MwSt:' % vatstr, _formatPrice(vat*part.sum)))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

316)           else:
317)             for vat, vatdata in part.vat.iteritems():
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

318)               (integer, decimals) = _niceCount( (vat * 100) )
319)               vatstr = '%s' % integer
320)               if decimals:
321)                 vatstr += ',%s' % decimals
322)               summaries.append(('zzgl. %s%% MwSt (%s):' % (vatstr, vatdata[1]), _formatPrice(vat*vatdata[0])))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

323)           summaries.sort()
324)           for line in summaries:
325)             canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
326)             canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
327)             y -= line_height
328)           sum = 0
329)           for vat, vatdata in part.vat.iteritems():
330)             sum += (vat+1)*vatdata[0]
331)           canvas.setFont(font+'-Bold', font_size)
332)           if iv.tender:
333)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
334)           else:
335)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
336)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(sum))
337)           canvas.setFont(font, font_size)
338)           y -= line_height + line_padding
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

340)       my_font_size = font_size
341)       canvas.setFont(font, my_font_size)
342)       left, right = leftcontent, rightcontent
343)       firsttime = True
344)       headlines = []
345)       if part.urgent:
346)         left += 1.5*cm
347)         right -= 1.5*cm
348)       if part.headline:
349)         headlines = _splitToWidth(canvas, part.headline, right-left, font, my_font_size)
350)       for para in part.paragraphs:
351)         lines = _splitToWidth(canvas, para, right-left, font, my_font_size)
352)         if part.urgent:
353)           need_height = len(lines) * line_height
354)           if len(headlines) > 0:
355)             need_height += len(headlines) * (line_height + 1) + line_padding
356)           canvas.setFillColorRGB(0.95, 0.95, 0.95)
357)           canvas.rect(left-0.5*cm, y - (need_height+(6*line_padding)), height = need_height+(6*line_padding), width = right-left+1*cm, fill=1, stroke=1)
358)           canvas.setFillColorRGB(0, 0, 0)
359)           y -= line_padding*3
360)         if part.headline and firsttime:
361)           firsttime = False
362)           canvas.setFont(font+'-Bold', my_font_size+1)
363)           for line in headlines:
364)             canvas.drawString(left, y-(font_height+1), line)
365)             y -= line_height + 1
366)           y -= line_padding
367)           canvas.setFont(font, my_font_size)
Bernd Wurst InvoiceText als Blocksatz d...

Bernd Wurst authored 16 years ago

368)         for line in lines[:-1]:
369)           _drawJustifiedString(left, y-font_height, line, canvas, right-left, font, my_font_size)
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

370)           y -= line_height
Bernd Wurst InvoiceText als Blocksatz d...

Bernd Wurst authored 16 years ago

371)         canvas.drawString(left, y-font_height, lines[-1])
372)         y -= line_height
373)