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 |