995a0ff040a59651602fa687128dbf8658fa35e6
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
122)       height = len(part.entries) * 1.1*cm
123)       height += 3*cm
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'] != '':
220)           desc = _splitToWidth(canvas, el['desc'], 14.5*cm, font, font_size)
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
247)           for line in desc:
248)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
249)             x += 1
250)         else:
251)           canvas.drawString(left+1.7*cm, y-font_height, subject[0])
252)           canvas.drawRightString(left+13.3*cm, y-font_height, _formatPrice(el['price']))
253)           canvas.drawString(left+13.7*cm, y-font_height, str(part.vat[el['vat']][1]))
254)           if el['tender']:  
255)             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
256)           else:
257)             canvas.drawRightString(left+16.8*cm, y-font_height, _formatPrice(el['total']))
258)           subject = subject[1:]
259)           x = 1
260)           for line in subject:
261)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
262)             x += 1
263)           for line in desc:
264)             canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
265)             x += 1
266)         odd = not odd
267)         y -= (need_lines * line_height) + line_padding
268)       if part.summary:
269)         y -= (0.3*cm)
270)         if part.vatType == 'gross':
271)           canvas.setFont(font+'-Bold', font_size)
272)           if iv.tender:
273)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Gesamtbetrag:')
274)           else:
275)             canvas.drawRightString(left + 14.5*cm, y-font_height, 'Rechnungsbetrag:')
276)           canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(part.sum))
277)           canvas.setFont(font, font_size)
278)           y -= line_height + line_padding
279)           summaries = []
280)           if len(part.vat) == 1:
281)             vat = part.vat.keys()[0]
Bernd Wurst Trennung von Firmen-spezifi...

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

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

Bernd Wurst authored 16 years ago

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

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

Bernd Wurst authored 16 years ago

292)               (integer, decimals) = _niceCount( (vat * 100) )
293)               vatstr = '%s' % integer
294)               if decimals:
295)                 vatstr += ',%s' % decimals
296)               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

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

316)               (integer, decimals) = _niceCount( (vat * 100) )
317)               vatstr = '%s' % integer
318)               if decimals:
319)                 vatstr += ',%s' % decimals
320)               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

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

Bernd Wurst authored 16 years ago

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

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

Bernd Wurst authored 16 years ago

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