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 |