7b6e89a2a566bef303f7ca5634da0f4a6e45486e
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)  
75)   my_x = x
76)   for idx in range(len(words)):
77)     word = words[idx]
78)     canvas.drawString(my_x, y, word)
79)     my_x += canvas.stringWidth(word, font, size) + available_each
80)   return
81) 
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

94)   
95)   
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

121)       ## FIXME: Das ist dreckig
Bernd Wurst Bessere Höhen-Approximation

Bernd Wurst authored 16 years ago

122)       height = len(part.entries) * 2*cm
123)       height += 3.5*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

124)     return height
125) 
126) 
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

129) 
130)   font_size = default_font_size
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

138) 
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

195)         
196)       left = leftcontent
197)       right = rightcontent
198)       top = topcontent
199)       bottom = bottomcontent
200)       canvas.setFont(font, font_size)
201)       canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
202)       canvas.drawString(left+(1.6*cm), y-line_height+line_padding, 'Beschreibung')
203)       if len(part.vat) == 1:
204)         canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
205)       else:
206)         canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
207)       canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
208)       canvas.setLineWidth(0.01*cm)
209)       canvas.line(left, y - line_height, right, y - line_height)
210)       y -= line_height + 0.02*cm
211)       odd=True
212)       for el in part.entries:
213)         subject = []
214)         if len(part.vat) == 1:
215)           subject = _splitToWidth(canvas, el['subject'], 10.3*cm, font, font_size)
216)         else:
217)           subject = _splitToWidth(canvas, el['subject'], 9.3*cm, font, font_size)
218)         desc = []
219)         if 'desc' in el and el['desc'] != '':
Bernd Wurst Blocksatz auch für Beschrei...

Bernd Wurst authored 16 years ago

220)           desc = _splitToWidth(canvas, el['desc'], 11*cm, font, font_size)
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

221) 
222)         # draw the background
223)         if not odd:
224)           canvas.setFillColorRGB(0.9, 0.9, 0.9)
225)         else:
226)           canvas.setFillColorRGB(1, 1, 1)
227)         need_lines = len(subject) + len(desc)
228)         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)
229)         canvas.setFillColorRGB(0, 0, 0)
230)         y -= line_padding
231)         (integer, decimals) = _niceCount(el['count'])
232)         canvas.drawRightString(left+0.8*cm, y-font_height, integer)
233)         if decimals:
234)           canvas.drawString(left+0.8*cm, y-font_height, ',%s' % decimals)
235)         if len(part.vat) == 1:
236)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
237)           canvas.drawRightString(left+14.3*cm, y-font_height, _formatPrice(el['price']))
238)           if el['tender']:  
239)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
240)           else:
241)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
242)           subject = subject[1:]
243)           x = 1
244)           for line in subject:
245)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
246)             x += 1
Bernd Wurst Blocksatz auch für Beschrei...

Bernd Wurst authored 16 years ago

247)           for line in desc[:-1]:
248)             _drawJustifiedString(left+1.7*cm, y-(x * line_height)-font_height, line, canvas, 11*cm, font, font_size)
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

249)             x += 1
Bernd Wurst Blocksatz auch für Beschrei...

Bernd Wurst authored 16 years ago

250)           canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, desc[-1])
251)           x += 1
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

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)