eefd9cc7c07ee95dababc6c68fb06e987390e3fb
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
Bernd Wurst Break long address-lines

Bernd Wurst authored 15 years ago

9) from custom_elements import basicPage, firstPage, address_header
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

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) 
Bernd Wurst Break long address-lines

Bernd Wurst authored 15 years ago

89) def address(canvas, lines):
90)   x = 2.0 * cm
91)   y = page_height - 5.0*cm
92)   canvas.setFont(font, 8)
93)   canvas.drawString(x+0.5*cm, y+0.1*cm, 'schokokeks.org · Köchersberg 25 · 71540 Murrhardt')
94)   canvas.setLineWidth(1)
95)   canvas.line(x+0.4*cm, y, x + address_width, y)
96)   y = y - 0.2*cm
97) 
98)   line_height = 11 + 0.1*cm
99)   y -= line_height
100)   canvas.setFont(font, 11)
101)   for line in lines:
102)     fontsize = 11
103)     if canvas.stringWidth(line, font, fontsize) > address_width:
104)       # Wenn es in zwei Zeilen passt, dann ist alles okay, ansonsten verkleinern
105)       if canvas.stringWidth(line, font, fontsize) > 2*address_width:
106)         for fontsize in [10.5, 10, 9.5, 9, 8.5]:
107)           if canvas.stringWidth(line, font, fontsize) <= 2*address_width:
108)             break
109)       mylines = _splitToWidth(canvas, line, address_width, font, fontsize)
110)       for l in mylines:
111)         canvas.drawString(x+0.5*cm, y, l)
112)         y -= line_height
113)     else:
114)       canvas.drawString(x+0.5*cm, y, line)
115)       y -= line_height
116) 
117) 
118) 
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

119) 
120) def InvoiceToPDF(iv):
121)   from StringIO import StringIO
122)   fd = StringIO()
123)   canvas = Canvas.Canvas(fd, pagesize=A4)
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

124)   
125)   
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

126)   canvas.setFont(font, 12)
127) 
128)   num_pages = 1
129) 
130)   # Waehrungssysmbol
131)   symbol = '€'
132)   y = topcontent
133)   font_size = default_font_size
134)   font_height = 0.35*cm
135)   line_padding = 0.1*cm
136)   line_height = font_height+0.1*cm
137) 
138)   def _partHeight(part):
139)     height = 0
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

141)       left, right = leftcontent, rightcontent
142)       if part.urgent:
143)         left += 1.5*cm
144)         right -= 1.5*cm
145)         height += len(part.paragraphs) * 3 * line_padding
146)       if part.headline:
147)         height += (len(_splitToWidth(canvas, part.headline, right-left, font+'-Bold', default_font_size+1)) * line_height) + line_padding
148)       for para in part.paragraphs:  
149)         height += (len(_splitToWidth(canvas, para, right-left, font, default_font_size)) * line_height) + line_padding
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

150)     elif type(part) == Invoice.Table:
Bernd Wurst Höhe der Tabelle besser app...

Bernd Wurst authored 15 years ago

151)       height = line_height
152)       for el in part.entries:
153)         # Die Breite ist konservativ
154)         height += line_height*len(_splitToWidth(canvas, el['subject'], 9.3*cm, font, font_size))
155)         if 'desc' in el and el['desc'] != '':
156)           height += line_height * len(_splitToWidth(canvas, el['desc'], 11*cm, font, font_size))
157)       # 4 Zeilen sollten reichen für die Summen
158)       height += line_height * 4
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

159)     return height
160) 
161) 
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

164) 
165)   font_size = default_font_size
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

169)   min_y = y
170)   if iv.caption:
171)     canvas.drawString(leftcontent, y, iv.caption)
172)     min_y -= (font_size + 3) + 0.5*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

173) 
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

179)   elif type(iv) == Invoice.Generic:
180)     canvas.setFont(font, font_size)
181)     canvas.drawString(rightcolumn, y, "Datum:")
182)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
183)     y -= (font_size + 0.1*cm)
184)   elif type(iv) == Invoice.Invoice:
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

185)     canvas.setFont(font+'-Bold', font_size)
186)     canvas.drawString(rightcolumn, y, "Bei Fragen bitte immer angeben:")
187)     y -= (font_size + 0.2*cm)
188)     canvas.setFont(font, font_size)
189)     canvas.drawString(rightcolumn, y, "Rechnungsdatum:")
190)     canvas.drawRightString(rightcontent, y, "%s" % iv.date.strftime('%d. %m. %Y'))
191)     y -= (font_size + 0.1*cm)
192)     canvas.drawString(rightcolumn, y, "Rechnungsnummer:")
193)     canvas.drawRightString(rightcontent, y, "%i" % iv.id)
194)     y -= (font_size + 0.1*cm)
195)   if iv.customerno:
196)     canvas.drawString(rightcolumn, y, "Kundennummer:")
197)     canvas.drawRightString(rightcontent, y, "%s" % iv.customerno)
198)     y -= (font_size + 0.5*cm)
199)   canvas.setFont(font, font_size)
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

200)   y = min(min_y, y)
201) 
202)   if iv.salutation:
203)     canvas.drawString(leftcontent, y, iv.salutation)
204)     y -= font_size + 0.2*cm
205)     if type(iv) in [Invoice.Tender, Invoice.Invoice]:
206)       introText = 'hiermit stellen wir Ihnen die nachfolgend genannten Leistungen in Rechnung.'
207)       if type(iv) == Invoice.Tender:
208)         introText = 'hiermit unterbreiten wir Ihnen folgendes Angebot.'
209)       intro = _splitToWidth(canvas, introText, rightcontent - leftcontent, font, font_size)
210)       for line in intro:
211)         canvas.drawString(leftcontent, y, line)
212)         y -= font_size + 0.1*cm
213)       y -= font_size + 0.1*cm
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

214) 
215)   
216)   font_size = default_font_size
217)   for part in iv.parts:
218)     if y - _partHeight(part) < (bottomcontent + (0.5*cm)):
219)       num_pages += 1
220)       y = bottomcontent + (0.5*cm)
221)       canvas.setFont(font, default_font_size-2)
222)       canvas.drawRightString(rightcontent, bottomcontent + line_padding, 'Fortsetzung auf Seite %i' % num_pages)
223)       _PageWrap(canvas)
224)       y = topcontent - font_size
225)       canvas.setFillColor((0,0,0))
226)       canvas.setFont(font, font_size-2)
227)       canvas.drawCentredString(leftcontent + (rightcontent - leftcontent) / 2, y, '- Seite %i -' % num_pages)
228)       y -= line_padding*3
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

230)         
231)       left = leftcontent
232)       right = rightcontent
233)       top = topcontent
234)       bottom = bottomcontent
235)       canvas.setFont(font, font_size)
236)       canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
237)       canvas.drawString(left+(1.6*cm), y-line_height+line_padding, 'Beschreibung')
238)       if len(part.vat) == 1:
239)         canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
240)       else:
241)         canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
242)       canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
243)       canvas.setLineWidth(0.01*cm)
244)       canvas.line(left, y - line_height, right, y - line_height)
245)       y -= line_height + 0.02*cm
246)       odd=True
247)       for el in part.entries:
248)         subject = []
249)         if len(part.vat) == 1:
250)           subject = _splitToWidth(canvas, el['subject'], 10.3*cm, font, font_size)
251)         else:
252)           subject = _splitToWidth(canvas, el['subject'], 9.3*cm, font, font_size)
253)         desc = []
254)         if 'desc' in el and el['desc'] != '':
Bernd Wurst Blocksatz auch für Beschrei...

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

256) 
257)         # draw the background
258)         if not odd:
259)           canvas.setFillColorRGB(0.9, 0.9, 0.9)
260)         else:
261)           canvas.setFillColorRGB(1, 1, 1)
262)         need_lines = len(subject) + len(desc)
263)         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)
264)         canvas.setFillColorRGB(0, 0, 0)
265)         y -= line_padding
266)         (integer, decimals) = _niceCount(el['count'])
267)         canvas.drawRightString(left+0.8*cm, y-font_height, integer)
268)         if decimals:
269)           canvas.drawString(left+0.8*cm, y-font_height, ',%s' % decimals)
270)         if len(part.vat) == 1:
271)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
272)           canvas.drawRightString(left+14.3*cm, y-font_height, _formatPrice(el['price']))
273)           if el['tender']:  
274)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
275)           else:
276)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
277)           subject = subject[1:]
278)           x = 1
279)           for line in subject:
280)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
281)             x += 1
Bernd Wurst Blocksatz auch für Beschrei...

Bernd Wurst authored 16 years ago

282)           for line in desc[:-1]:
283)             _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

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

287)         else:
288)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
289)           canvas.drawRightString(left+13.3*cm, y-font_height, _formatPrice(el['price']))
290)           canvas.drawString(left+13.7*cm, y-font_height, str(part.vat[el['vat']][1]))
291)           if el['tender']:  
292)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
293)           else:
294)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
295)           subject = subject[1:]
296)           x = 1
297)           for line in subject:
298)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
299)             x += 1
300)           for line in desc:
301)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
302)             x += 1
303)         odd = not odd
304)         y -= (need_lines * line_height) + line_padding
305)       if part.summary:
306)         y -= (0.3*cm)
307)         if part.vatType == 'gross':
308)           canvas.setFont(font+'-Bold', font_size)
309)           if iv.tender:
310)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
311)           else:
312)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
313)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
314)           canvas.setFont(font, font_size)
315)           y -= line_height + line_padding
316)           summaries = []
317)           if len(part.vat) == 1:
318)             vat = part.vat.keys()[0]
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

319)             (integer, decimals) = _niceCount( (vat * 100) )
320)             vatstr = '%s' % integer
321)             if decimals:
322)               vatstr += ',%s' % decimals
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

324)               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

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

Bernd Wurst authored 16 years ago

326)               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

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

Bernd Wurst authored 16 years ago

329)               (integer, decimals) = _niceCount( (vat * 100) )
330)               vatstr = '%s' % integer
331)               if decimals:
332)                 vatstr += ',%s' % decimals
333)               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

334)           summaries.sort()
335)           for line in summaries:
336)             canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
337)             canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
338)             y -= line_height
339)         else:
340)           canvas.drawRightString(left + 14.5*cm, y-font_height, 'Nettobetrag:')
341)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
342)           y -= line_height
343)           summaries = []
344)           if len(part.vat) == 1:
345)             vat = part.vat.keys()[0]
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

346)             (integer, decimals) = _niceCount( (vat * 100) )
347)             vatstr = '%s' % integer
348)             if decimals:
349)               vatstr += ',%s' % decimals
350)             summaries.append(('zzgl. %s%% MwSt:' % vatstr, _formatPrice(vat*part.sum)))
Bernd Wurst Struktur verändern (broken!)

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

353)               (integer, decimals) = _niceCount( (vat * 100) )
354)               vatstr = '%s' % integer
355)               if decimals:
356)                 vatstr += ',%s' % decimals
357)               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

358)           summaries.sort()
359)           for line in summaries:
360)             canvas.drawRightString(left + 14.5*cm, y-font_height, line[0])
361)             canvas.drawRightString(left + 16.8*cm, y-font_height, line[1])
362)             y -= line_height
363)           sum = 0
364)           for vat, vatdata in part.vat.iteritems():
365)             sum += (vat+1)*vatdata[0]
366)           canvas.setFont(font+'-Bold', font_size)
367)           if iv.tender:
368)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
369)           else:
370)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
371)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(sum))
372)           canvas.setFont(font, font_size)
373)           y -= line_height + line_padding
Bernd Wurst Generisch

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

375)       my_font_size = font_size
376)       canvas.setFont(font, my_font_size)
377)       left, right = leftcontent, rightcontent
378)       firsttime = True
379)       headlines = []
380)       if part.urgent:
381)         left += 1.5*cm
382)         right -= 1.5*cm
383)       if part.headline:
384)         headlines = _splitToWidth(canvas, part.headline, right-left, font, my_font_size)
385)       for para in part.paragraphs:
386)         lines = _splitToWidth(canvas, para, right-left, font, my_font_size)
387)         if part.urgent:
388)           need_height = len(lines) * line_height
389)           if len(headlines) > 0:
390)             need_height += len(headlines) * (line_height + 1) + line_padding
391)           canvas.setFillColorRGB(0.95, 0.95, 0.95)
392)           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)
393)           canvas.setFillColorRGB(0, 0, 0)
394)           y -= line_padding*3
395)         if part.headline and firsttime:
396)           firsttime = False
397)           canvas.setFont(font+'-Bold', my_font_size+1)
398)           for line in headlines:
399)             canvas.drawString(left, y-(font_height+1), line)
400)             y -= line_height + 1
401)           y -= line_padding
402)           canvas.setFont(font, my_font_size)
Bernd Wurst InvoiceText als Blocksatz d...

Bernd Wurst authored 16 years ago

403)         for line in lines[:-1]:
404)           _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

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

Bernd Wurst authored 16 years ago

406)         canvas.drawString(left, y-font_height, lines[-1])
407)         y -= line_height
408)