Teile Tabelle auch mittendrin auf wenn es nötig ist
Bernd Wurst

Bernd Wurst commited on 2013-05-24 12:05:43
Zeige 1 geänderte Dateien mit 80 Einfügungen und 42 Löschungen.

... ...
@@ -13,6 +13,9 @@ from reportlab.lib.units import cm
13 13
 from reportlab.pdfgen import canvas as Canvas
14 14
 
15 15
 
16
+num_pages = 1
17
+
18
+
16 19
 def _formatPrice(price, symbol='€'):
17 20
   '''_formatPrice(price, symbol='€'):
18 21
   Gets a floating point value and returns a formatted price, suffixed by 'symbol'. '''
... ...
@@ -80,12 +83,6 @@ def _drawJustifiedString(x, y, text, canvas, width, font, size):
80 83
   return
81 84
 
82 85
 
83
-def _PageWrap(canvas):
84
-  '''Seitenumbruch'''
85
-  canvas.showPage()
86
-  basicPage(canvas)
87
-
88
-
89 86
 def address(canvas, lines):
90 87
   x = 2.0 * cm
91 88
   y = page_height - 5.0*cm
... ...
@@ -97,20 +94,25 @@ def address(canvas, lines):
97 94
 
98 95
   line_height = 11 + 0.1*cm
99 96
   y -= line_height
100
-  canvas.setFont(font, 11)
101
-  for line in lines:
97
+
102 98
   fontsize = 11
99
+  for line in lines:
103 100
     if canvas.stringWidth(line, font, fontsize) > address_width:
104 101
       # 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:
102
+      if len(lines) > 4 or canvas.stringWidth(line, font, fontsize) > 2*address_width:
103
+        for candidate in [10.5, 10, 9.5, 9, 8.5, 8]:
104
+	  fontsize = candidate
105
+          if (len(lines) <= 4 and canvas.stringWidth(line, font, fontsize) <= 2*address_width) or canvas.stringWidth(line, font, fontsize) <= address_width:
108 106
             break
107
+  for line in lines:
108
+    if canvas.stringWidth(line, font, fontsize) > address_width:
109 109
       mylines = _splitToWidth(canvas, line, address_width, font, fontsize)
110 110
       for l in mylines:
111
+  	canvas.setFont(font, fontsize)
111 112
         canvas.drawString(x+0.5*cm, y, l)
112 113
         y -= line_height
113 114
     else:
115
+      canvas.setFont(font, fontsize)
114 116
       canvas.drawString(x+0.5*cm, y, line)
115 117
       y -= line_height
116 118
 
... ...
@@ -129,7 +131,6 @@ def InvoiceToPDF(iv):
129 131
   
130 132
   canvas.setFont(font, 12)
131 133
 
132
-  num_pages = 1
133 134
 
134 135
   # Waehrungssysmbol
135 136
   symbol = '€'
... ...
@@ -156,7 +157,8 @@ def InvoiceToPDF(iv):
156 157
     elif type(part) == Invoice.Table:
157 158
       # Eine Zeile plus 2 mal line_padding für Tabellenkopf
158 159
       height = line_height + 2 * line_padding
159
-      for el in part.entries:
160
+      # Wenn nur ein Element (plus Summen) hin passt, reicht uns das
161
+      el = part.entries[0]
160 162
       # Die Abstände oben und unten
161 163
       height += 2 * line_padding
162 164
       # Die Breite ist konservativ
... ...
@@ -173,6 +175,33 @@ def InvoiceToPDF(iv):
173 175
     return height
174 176
 
175 177
 
178
+  def _tableHead(y):
179
+    canvas.setFont(font, font_size)
180
+    canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
181
+    canvas.drawString(left+(2.6*cm), y-line_height+line_padding, 'Beschreibung')
182
+    if len(part.vat) == 1:
183
+      canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
184
+    else:
185
+      canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
186
+    canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
187
+    canvas.setLineWidth(0.01*cm)
188
+    canvas.line(left, y - line_height, right, y - line_height)
189
+    y -= line_height + 0.02*cm
190
+    return y
191
+   
192
+  def _PageWrap(canvas):
193
+    '''Seitenumbruch'''
194
+    global num_pages
195
+    num_pages += 1
196
+    canvas.setFont(font, default_font_size-2)
197
+    canvas.drawRightString(rightcontent, bottomcontent + line_padding, 'Fortsetzung auf Seite %i' % num_pages)
198
+    canvas.showPage()
199
+    basicPage(canvas)
200
+    y = topcontent - font_size
201
+    canvas.setFillColor((0,0,0))
202
+    canvas.setFont(font, font_size-2)
203
+    canvas.drawCentredString(leftcontent + (rightcontent - leftcontent) / 2, y, '- Seite %i -' % num_pages)
204
+
176 205
 
177 206
   address(canvas, iv.addresslines)
178 207
 
... ...
@@ -230,16 +258,8 @@ def InvoiceToPDF(iv):
230 258
   font_size = default_font_size
231 259
   for part in iv.parts:
232 260
     if y - _partHeight(part) < (bottomcontent + (0.5*cm)):
233
-      num_pages += 1
234
-      y = bottomcontent + (0.5*cm)
235
-      canvas.setFont(font, default_font_size-2)
236
-      canvas.drawRightString(rightcontent, bottomcontent + line_padding, 'Fortsetzung auf Seite %i' % num_pages)
237 261
       _PageWrap(canvas)
238
-      y = topcontent - font_size
239
-      canvas.setFillColor((0,0,0))
240
-      canvas.setFont(font, font_size-2)
241
-      canvas.drawCentredString(leftcontent + (rightcontent - leftcontent) / 2, y, '- Seite %i -' % num_pages)
242
-      y -= line_padding*3
262
+      y = topcontent - font_size - line_padding*3
243 263
     # Debug: Was hat die Höhenbestimmung für diesen Teil als Höhe herausgefunden?
244 264
     #canvas.line(leftcontent, y-_partHeight(part), rightcontent, y-_partHeight(part))
245 265
 
... ...
@@ -249,17 +269,8 @@ def InvoiceToPDF(iv):
249 269
       right = rightcontent
250 270
       top = topcontent
251 271
       bottom = bottomcontent
252
-      canvas.setFont(font, font_size)
253
-      canvas.drawString(left+(0.1*cm), y-line_height+line_padding, 'Anz.')
254
-      canvas.drawString(left+(1.6*cm), y-line_height+line_padding, 'Beschreibung')
255
-      if len(part.vat) == 1:
256
-        canvas.drawRightString(left+(14.3*cm), y-line_height+line_padding, 'Einzelpreis')
257
-      else:
258
-        canvas.drawRightString(left+(13.7*cm), y-line_height+line_padding, 'Einzelpreis')
259
-      canvas.drawRightString(left+(16.8*cm), y-line_height+line_padding, 'Gesamtpreis')
260
-      canvas.setLineWidth(0.01*cm)
261
-      canvas.line(left, y - line_height, right, y - line_height)
262
-      y -= line_height + 0.02*cm
272
+      temp_sum = 0.0
273
+      y = _tableHead(y)
263 274
       odd=True
264 275
       for el in part.entries:
265 276
         subject = []
... ...
@@ -270,22 +281,48 @@ def InvoiceToPDF(iv):
270 281
         desc = []
271 282
         if 'desc' in el and el['desc'] != '':
272 283
           desc = _splitToWidth(canvas, el['desc'], 11*cm, font, font_size)
284
+        need_lines = len(subject) + len(desc)
285
+
286
+	# need page wrap?
287
+      	if y - (need_lines+2 * font_size) < (bottomcontent + 2*cm):
288
+          canvas.setFont(font, font_size)
289
+	  # Zwischensumme
290
+          canvas.drawRightString(left + 14.5*cm, y-font_height, 'Zwischensumme:')
291
+          canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(temp_sum))
292
+	  # page wrap
293
+	  _PageWrap(canvas)
294
+          y = topcontent - font_size - line_padding*3
295
+	  # header
296
+	  y = _tableHead(y)
297
+          odd=True
298
+	  # übertrag
299
+          canvas.setFont(font, font_size)
300
+          canvas.drawRightString(left + 14.5*cm, y-font_height, 'Übertrag:')
301
+          canvas.drawRightString(left + 16.8*cm, y-font_height, _formatPrice(temp_sum))
302
+	  y -= font_height + line_padding
273 303
 
304
+	# Zwischensumme (inkl. aktueller Posten)
305
+        temp_sum += el['total']
274 306
         # draw the background
275 307
         if not odd:
276 308
           canvas.setFillColorRGB(0.9, 0.9, 0.9)
277 309
         else:
278 310
           canvas.setFillColorRGB(1, 1, 1)
279
-        need_lines = len(subject) + len(desc)
280 311
         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)
281 312
         canvas.setFillColorRGB(0, 0, 0)
282 313
         y -= line_padding
283 314
         (integer, decimals) = _niceCount(el['count'])
284 315
         canvas.drawRightString(left+0.8*cm, y-font_height, integer)
316
+	suffix = ''
285 317
 	if decimals:
286
-          canvas.drawString(left+0.8*cm, y-font_height, ',%s' % decimals)
318
+	  suffix = ',%s' % decimals
319
+	if el['unit']:
320
+	  suffix = suffix + ' ' + el['unit']
321
+        if suffix:
322
+          canvas.drawString(left+0.8*cm, y-font_height, '%s' % suffix)
323
+	  
287 324
         if len(part.vat) < 2:
288
-          canvas.drawString(left+1.7*cm, y-font_height, subject[0])
325
+          canvas.drawString(left+2.7*cm, y-font_height, subject[0])
289 326
           canvas.drawRightString(left+14.3*cm, y-font_height, _formatPrice(el['price']))
290 327
           if el['tender']:  
291 328
             canvas.drawRightString(left+16.8*cm, y-font_height, 'eventual')
... ...
@@ -294,15 +331,15 @@ def InvoiceToPDF(iv):
294 331
           subject = subject[1:]
295 332
           x = 1
296 333
           for line in subject:
297
-            canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
334
+            canvas.drawString(left+2.7*cm, y-(x * line_height)-font_height, line)
298 335
             x += 1
299 336
           for line in desc[:-1]:
300
-            _drawJustifiedString(left+1.7*cm, y-(x * line_height)-font_height, line, canvas, 11*cm, font, font_size)
337
+            _drawJustifiedString(left+2.7*cm, y-(x * line_height)-font_height, line, canvas, 11*cm, font, font_size)
301 338
             x += 1
302
-          canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, desc[-1])
339
+          canvas.drawString(left+2.7*cm, y-(x * line_height)-font_height, desc[-1])
303 340
           x += 1
304 341
         else:
305
-          canvas.drawString(left+1.7*cm, y-font_height, subject[0])
342
+          canvas.drawString(left+2.7*cm, y-font_height, subject[0])
306 343
           canvas.drawRightString(left+13.3*cm, y-font_height, _formatPrice(el['price']))
307 344
           canvas.drawString(left+13.7*cm, y-font_height, str(part.vat[el['vat']][1]))
308 345
           if el['tender']:  
... ...
@@ -312,10 +349,10 @@ def InvoiceToPDF(iv):
312 349
           subject = subject[1:]
313 350
           x = 1
314 351
           for line in subject:
315
-            canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
352
+            canvas.drawString(left+2.7*cm, y-(x * line_height)-font_height, line)
316 353
             x += 1
317 354
           for line in desc:
318
-            canvas.drawString(left+1.7*cm, y-(x * line_height)-font_height, line)
355
+            canvas.drawString(left+2.7*cm, y-(x * line_height)-font_height, line)
319 356
             x += 1
320 357
         odd = not odd
321 358
         y -= (need_lines * line_height) + line_padding
322 359