invoice_printer 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +67 -4
- data/examples/background.png +0 -0
- data/examples/complex_invoice.pdf +1042 -402
- data/examples/complex_invoice.png +0 -0
- data/examples/complex_invoice.rb +1 -1
- data/examples/czech_invoice.pdf +427 -374
- data/examples/czech_invoice.rb +1 -1
- data/examples/international_invoice.pdf +1152 -1
- data/examples/international_invoice.rb +84 -0
- data/examples/simple_invoice.pdf +0 -0
- data/examples/simple_invoice.rb +1 -1
- data/examples/stamp.png +0 -0
- data/lib/invoice_printer/pdf_document.rb +282 -100
- data/lib/invoice_printer/version.rb +1 -1
- data/lib/invoice_printer.rb +8 -0
- data/test/background_test.rb +1 -1
- data/test/dates_box_test.rb +8 -8
- data/test/examples_test.rb +33 -0
- data/test/payment_box_test.rb +10 -10
- data/test/test_ext.rb +7 -7
- data/test/test_helper.rb +3 -0
- metadata +8 -6
- data/examples/background.jpg +0 -0
- data/examples/czech_invoice.jpg +0 -0
- data/examples/example.jpg +0 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This is an example of a international invoice with Czech labels and English translation.
|
3
|
+
#
|
4
|
+
# Due to the special characters it requires Overpass-Regular.ttf font to be
|
5
|
+
# present in this directory.
|
6
|
+
|
7
|
+
lib = File.expand_path('../../lib', __FILE__)
|
8
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
9
|
+
require 'invoice_printer'
|
10
|
+
|
11
|
+
labels = {
|
12
|
+
name: 'Faktura',
|
13
|
+
provider: 'Prodejce',
|
14
|
+
purchaser: 'Kupující',
|
15
|
+
tax_id: 'IČ',
|
16
|
+
tax_id2: 'DIČ',
|
17
|
+
payment: 'Forma úhrady',
|
18
|
+
payment_by_transfer: 'Platba na následující účet:',
|
19
|
+
account_number: 'Číslo účtu',
|
20
|
+
issue_date: 'Datum vydání',
|
21
|
+
due_date: 'Datum splatnosti',
|
22
|
+
item: 'Položka',
|
23
|
+
quantity: 'Počet',
|
24
|
+
unit: 'MJ',
|
25
|
+
price_per_item: 'Cena za položku',
|
26
|
+
amount: 'Celkem bez daně',
|
27
|
+
subtotal: 'Cena bez daně',
|
28
|
+
tax: 'DPH 21 %',
|
29
|
+
total: 'Celkem'
|
30
|
+
}
|
31
|
+
|
32
|
+
# Default English labels as sublabels
|
33
|
+
sublabels = InvoicePrinter::PDFDocument::DEFAULT_LABELS
|
34
|
+
labels.merge!({ sublabels: sublabels })
|
35
|
+
|
36
|
+
first_item = InvoicePrinter::Document::Item.new(
|
37
|
+
name: 'Konzultace',
|
38
|
+
quantity: '2',
|
39
|
+
unit: 'hod',
|
40
|
+
price: 'Kč 500',
|
41
|
+
amount: 'Kč 1.000'
|
42
|
+
)
|
43
|
+
|
44
|
+
second_item = InvoicePrinter::Document::Item.new(
|
45
|
+
name: 'Programování',
|
46
|
+
quantity: '10',
|
47
|
+
unit: 'hod',
|
48
|
+
price: 'Kč 900',
|
49
|
+
amount: 'Kč 9.000'
|
50
|
+
)
|
51
|
+
|
52
|
+
invoice = InvoicePrinter::Document.new(
|
53
|
+
number: 'č. 198900000001',
|
54
|
+
provider_name: 'Petr Nový',
|
55
|
+
provider_tax_id: '56565656',
|
56
|
+
provider_street: 'Rolnická',
|
57
|
+
provider_street_number: '1',
|
58
|
+
provider_postcode: '747 05',
|
59
|
+
provider_city: 'Opava',
|
60
|
+
provider_city_part: 'Kateřinky',
|
61
|
+
purchaser_name: 'Adam Černý',
|
62
|
+
purchaser_street: 'Ostravská',
|
63
|
+
purchaser_street_number: '1',
|
64
|
+
purchaser_postcode: '747 70',
|
65
|
+
purchaser_city: 'Opava',
|
66
|
+
issue_date: '05/03/2016',
|
67
|
+
due_date: '19/03/2016',
|
68
|
+
subtotal: 'Kč 10.000',
|
69
|
+
tax: 'Kč 2.100',
|
70
|
+
total: 'Kč 12.100,-',
|
71
|
+
bank_account_number: '156546546465',
|
72
|
+
account_iban: 'IBAN464545645',
|
73
|
+
account_swift: 'SWIFT5456',
|
74
|
+
items: [first_item, second_item],
|
75
|
+
note: 'Osoba je zapsána v živnostenském rejstříku.'
|
76
|
+
)
|
77
|
+
|
78
|
+
InvoicePrinter.print(
|
79
|
+
document: invoice,
|
80
|
+
labels: labels,
|
81
|
+
font: File.expand_path('../Overpass-Regular.ttf', __FILE__),
|
82
|
+
logo: 'prawn.png',
|
83
|
+
file_name: 'international_invoice.pdf'
|
84
|
+
)
|
data/examples/simple_invoice.pdf
CHANGED
Binary file
|
data/examples/simple_invoice.rb
CHANGED
data/examples/stamp.png
CHANGED
Binary file
|
@@ -44,7 +44,8 @@ module InvoicePrinter
|
|
44
44
|
tax3: 'Tax 3',
|
45
45
|
amount: 'Amount',
|
46
46
|
subtotal: 'Subtotal',
|
47
|
-
total: 'Total'
|
47
|
+
total: 'Total',
|
48
|
+
sublabels: {}
|
48
49
|
}
|
49
50
|
|
50
51
|
def self.labels
|
@@ -66,7 +67,7 @@ module InvoicePrinter
|
|
66
67
|
raise InvalidInput, 'document is not a type of InvoicePrinter::Document' \
|
67
68
|
unless @document.is_a?(InvoicePrinter::Document)
|
68
69
|
|
69
|
-
if @logo
|
70
|
+
if used? @logo
|
70
71
|
if File.exist?(@logo)
|
71
72
|
@logo = logo
|
72
73
|
else
|
@@ -74,7 +75,7 @@ module InvoicePrinter
|
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
77
|
-
if @font
|
78
|
+
if used? @font
|
78
79
|
if File.exist?(@font)
|
79
80
|
set_fonts(@font) if @font
|
80
81
|
else
|
@@ -129,7 +130,10 @@ module InvoicePrinter
|
|
129
130
|
build_footer
|
130
131
|
end
|
131
132
|
|
132
|
-
# Build the document name and number
|
133
|
+
# Build the document name and number at the top:
|
134
|
+
#
|
135
|
+
# NAME NO. 901905374583579
|
136
|
+
# Sublabel name
|
133
137
|
def build_header
|
134
138
|
@pdf.text_box(
|
135
139
|
@labels[:name],
|
@@ -138,6 +142,17 @@ module InvoicePrinter
|
|
138
142
|
width: 300,
|
139
143
|
align: :left
|
140
144
|
)
|
145
|
+
|
146
|
+
if used? @labels[:sublabels][:name]
|
147
|
+
@pdf.text_box(
|
148
|
+
@labels[:sublabels][:name],
|
149
|
+
size: 12,
|
150
|
+
at: [0, 720 - @push_down - 22],
|
151
|
+
width: 300,
|
152
|
+
align: :left
|
153
|
+
)
|
154
|
+
end
|
155
|
+
|
141
156
|
@pdf.text_box(
|
142
157
|
@document.number,
|
143
158
|
size: 20,
|
@@ -146,34 +161,47 @@ module InvoicePrinter
|
|
146
161
|
align: :right
|
147
162
|
)
|
148
163
|
@pdf.move_down(250)
|
164
|
+
|
165
|
+
if used? @labels[:sublabels][:name]
|
166
|
+
@pdf.move_down(12)
|
167
|
+
end
|
149
168
|
end
|
150
169
|
|
151
170
|
# Build the following provider box:
|
152
171
|
#
|
153
|
-
#
|
154
|
-
# | Provider
|
155
|
-
# | PROVIDER co.
|
156
|
-
# | 5th Street
|
157
|
-
# | 747 27 City
|
158
|
-
# | Part of the city
|
159
|
-
# |
|
160
|
-
# | Identification number: Number
|
161
|
-
# | Identification number: Number 2
|
162
|
-
#
|
172
|
+
# ------------------------------------------
|
173
|
+
# | Provider Optinal provider sublabel|
|
174
|
+
# | PROVIDER co. |
|
175
|
+
# | 5th Street |
|
176
|
+
# | 747 27 City |
|
177
|
+
# | Part of the city |
|
178
|
+
# | |
|
179
|
+
# | Identification number: Number |
|
180
|
+
# | Identification number: Number 2 |
|
181
|
+
# ------------------------------------------
|
163
182
|
#
|
164
183
|
def build_provider_box
|
165
184
|
@pdf.text_box(
|
166
|
-
@
|
167
|
-
size:
|
168
|
-
at: [10,
|
185
|
+
@document.provider_name,
|
186
|
+
size: 15,
|
187
|
+
at: [10, 640 - @push_down],
|
169
188
|
width: 240
|
170
189
|
)
|
171
190
|
@pdf.text_box(
|
172
|
-
@
|
173
|
-
size:
|
174
|
-
at: [10,
|
191
|
+
@labels[:provider],
|
192
|
+
size: 11,
|
193
|
+
at: [10, 660 - @push_down],
|
175
194
|
width: 240
|
176
195
|
)
|
196
|
+
if used? @labels[:sublabels][:provider]
|
197
|
+
@pdf.text_box(
|
198
|
+
@labels[:sublabels][:provider],
|
199
|
+
size: 10,
|
200
|
+
at: [10, 660 - @push_down],
|
201
|
+
width: 250,
|
202
|
+
align: :right
|
203
|
+
)
|
204
|
+
end
|
177
205
|
@pdf.text_box(
|
178
206
|
"#{@document.provider_street} #{@document.provider_street_number}",
|
179
207
|
size: 10,
|
@@ -229,30 +257,39 @@ module InvoicePrinter
|
|
229
257
|
|
230
258
|
# Build the following purchaser box:
|
231
259
|
#
|
232
|
-
#
|
233
|
-
# | Purchaser
|
234
|
-
# | PURCHASER co.
|
235
|
-
# | 5th Street
|
236
|
-
# | 747 27 City
|
237
|
-
# | Part of the city
|
238
|
-
# |
|
239
|
-
# | Identification number: Number
|
240
|
-
# | Identification number: Number 2
|
241
|
-
#
|
260
|
+
# -------------------------------------------
|
261
|
+
# | Purchaser Optinal purchaser sublabel|
|
262
|
+
# | PURCHASER co. |
|
263
|
+
# | 5th Street |
|
264
|
+
# | 747 27 City |
|
265
|
+
# | Part of the city |
|
266
|
+
# | |
|
267
|
+
# | Identification number: Number |
|
268
|
+
# | Identification number: Number 2 |
|
269
|
+
# ------------------------------------------
|
242
270
|
#
|
243
271
|
def build_purchaser_box
|
244
272
|
@pdf.text_box(
|
245
|
-
@
|
246
|
-
size:
|
247
|
-
at: [290,
|
273
|
+
@document.purchaser_name,
|
274
|
+
size: 15,
|
275
|
+
at: [290, 640 - @push_down],
|
248
276
|
width: 240
|
249
277
|
)
|
250
278
|
@pdf.text_box(
|
251
|
-
@
|
252
|
-
size:
|
253
|
-
at: [290,
|
279
|
+
@labels[:purchaser],
|
280
|
+
size: 11,
|
281
|
+
at: [290, 660 - @push_down],
|
254
282
|
width: 240
|
255
283
|
)
|
284
|
+
|
285
|
+
if used? @labels[:sublabels][:purchaser]
|
286
|
+
@pdf.text_box(
|
287
|
+
@labels[:sublabels][:purchaser],
|
288
|
+
size: 10,
|
289
|
+
at: [10, 660 - @push_down],
|
290
|
+
align: :right
|
291
|
+
)
|
292
|
+
end
|
256
293
|
@pdf.text_box(
|
257
294
|
"#{@document.purchaser_street} #{@document.purchaser_street_number}",
|
258
295
|
size: 10,
|
@@ -310,14 +347,27 @@ module InvoicePrinter
|
|
310
347
|
#
|
311
348
|
# -----------------------------------------
|
312
349
|
# | Payment on the following bank account: |
|
313
|
-
# | Number:
|
314
|
-
# |
|
315
|
-
# |
|
350
|
+
# | Number: 3920392032|
|
351
|
+
# | Optional number sublabel |
|
352
|
+
# | SWIFT: xy|
|
353
|
+
# | Optional SWIFT sublabel |
|
354
|
+
# | IBAN: xy|
|
355
|
+
# | Optional IBAN sublabel |
|
316
356
|
# -----------------------------------------
|
317
357
|
#
|
318
358
|
# If the bank account number is not provided include a note about payment
|
319
359
|
# in cash.
|
320
360
|
def build_payment_method_box
|
361
|
+
@push_down -= 3
|
362
|
+
|
363
|
+
# Match the height of next box if needed
|
364
|
+
# TODO: it's smaller without sublabels
|
365
|
+
min_height = 60
|
366
|
+
if used?(@document.issue_date) || used?(@document.due_date)
|
367
|
+
min_height = (used?(@document.issue_date) && used?(@document.due_date)) ? 75 : 60
|
368
|
+
end
|
369
|
+
@payment_box_height = min_height
|
370
|
+
|
321
371
|
if @document.bank_account_number.empty?
|
322
372
|
@pdf.text_box(
|
323
373
|
@labels[:payment],
|
@@ -333,8 +383,9 @@ module InvoicePrinter
|
|
333
383
|
)
|
334
384
|
@pdf.stroke_rounded_rectangle([0, 508 - @push_down], 270, 45, 6)
|
335
385
|
else
|
336
|
-
|
337
|
-
push_iban = 0
|
386
|
+
@payment_box_height = 60
|
387
|
+
@push_iban = 0
|
388
|
+
sublabel_change = 0
|
338
389
|
@pdf.text_box(
|
339
390
|
@labels[:payment_by_transfer],
|
340
391
|
size: 10,
|
@@ -342,95 +393,178 @@ module InvoicePrinter
|
|
342
393
|
width: 240
|
343
394
|
)
|
344
395
|
@pdf.text_box(
|
345
|
-
"#{@labels[:account_number]}
|
346
|
-
size:
|
396
|
+
"#{@labels[:account_number]}",
|
397
|
+
size: 11,
|
347
398
|
at: [10, 483 - @push_down],
|
348
|
-
width:
|
399
|
+
width: 140
|
349
400
|
)
|
350
401
|
@pdf.text_box(
|
351
402
|
@document.bank_account_number,
|
352
|
-
size:
|
353
|
-
at: [
|
354
|
-
width: 240
|
403
|
+
size: 13,
|
404
|
+
at: [21, 483 - @push_down],
|
405
|
+
width: 240,
|
406
|
+
align: :right
|
355
407
|
)
|
356
|
-
|
408
|
+
if used? @labels[:sublabels][:account_number]
|
357
409
|
@pdf.text_box(
|
358
|
-
"#{@labels[:
|
410
|
+
"#{@labels[:sublabels][:account_number]}",
|
359
411
|
size: 10,
|
360
412
|
at: [10, 468 - @push_down],
|
361
|
-
width:
|
413
|
+
width: 340
|
414
|
+
)
|
415
|
+
else
|
416
|
+
@payment_box_height -= 10
|
417
|
+
sublabel_change -= 10
|
418
|
+
end
|
419
|
+
unless @document.account_swift.empty?
|
420
|
+
@pdf.text_box(
|
421
|
+
"#{@labels[:swift]}",
|
422
|
+
size: 11,
|
423
|
+
at: [10, 453 - @push_down - sublabel_change],
|
424
|
+
width: 140
|
362
425
|
)
|
363
426
|
@pdf.text_box(
|
364
427
|
@document.account_swift,
|
365
|
-
size:
|
366
|
-
at: [
|
367
|
-
width: 240
|
428
|
+
size: 13,
|
429
|
+
at: [21, 453 - @push_down - sublabel_change],
|
430
|
+
width: 240,
|
431
|
+
align: :right
|
368
432
|
)
|
369
|
-
|
370
|
-
|
371
|
-
|
433
|
+
|
434
|
+
if used? @labels[:sublabels][:swift]
|
435
|
+
@pdf.text_box(
|
436
|
+
"#{@labels[:sublabels][:swift]}",
|
437
|
+
size: 10,
|
438
|
+
at: [10, 438 - @push_down - sublabel_change],
|
439
|
+
width: 340
|
440
|
+
)
|
441
|
+
@push_items_table += 10
|
442
|
+
else
|
443
|
+
@payment_box_height -= 10
|
444
|
+
sublabel_change -= 10
|
445
|
+
end
|
446
|
+
|
447
|
+
@payment_box_height += 30
|
448
|
+
@push_iban = 30
|
449
|
+
@push_items_table += 18
|
372
450
|
end
|
373
451
|
unless @document.account_iban.empty?
|
374
452
|
@pdf.text_box(
|
375
|
-
"#{@labels[:iban]}
|
376
|
-
size:
|
377
|
-
at: [10,
|
378
|
-
width:
|
453
|
+
"#{@labels[:iban]}",
|
454
|
+
size: 11,
|
455
|
+
at: [10, 453 - @push_iban - @push_down - sublabel_change],
|
456
|
+
width: 140
|
379
457
|
)
|
380
458
|
@pdf.text_box(
|
381
459
|
@document.account_iban,
|
382
|
-
size:
|
383
|
-
at: [
|
384
|
-
width: 240
|
460
|
+
size: 13,
|
461
|
+
at: [21, 453 - @push_iban - @push_down - sublabel_change],
|
462
|
+
width: 240,
|
463
|
+
align: :right
|
385
464
|
)
|
386
|
-
|
387
|
-
|
465
|
+
|
466
|
+
if used? @labels[:sublabels][:iban]
|
467
|
+
@pdf.text_box(
|
468
|
+
"#{@labels[:sublabels][:iban]}",
|
469
|
+
size: 10,
|
470
|
+
at: [10, 438 - @push_iban - @push_down - sublabel_change],
|
471
|
+
width: 340
|
472
|
+
)
|
473
|
+
@push_items_table += 10
|
474
|
+
else
|
475
|
+
@payment_box_height -= 10
|
476
|
+
end
|
477
|
+
|
478
|
+
@payment_box_height += 30
|
479
|
+
@push_items_table += 18
|
480
|
+
end
|
481
|
+
if min_height > @payment_box_height
|
482
|
+
@payment_box_height = min_height
|
483
|
+
@push_items_table += 25
|
388
484
|
end
|
389
|
-
|
485
|
+
|
486
|
+
if !@document.account_swift.empty? && !@document.account_iban.empty?
|
487
|
+
@push_items_table += 2
|
488
|
+
end
|
489
|
+
|
490
|
+
@pdf.stroke_rounded_rectangle([0, 508 - @push_down], 270, @payment_box_height, 6)
|
390
491
|
end
|
391
492
|
end
|
392
493
|
|
393
494
|
# Build the following info box:
|
394
495
|
#
|
395
496
|
# --------------------------------
|
396
|
-
# | Issue date:
|
397
|
-
# |
|
497
|
+
# | Issue date: 03/03/2016|
|
498
|
+
# | Issue date sublabel |
|
499
|
+
# | Due date: 03/03/2016|
|
500
|
+
# | Due date sublabel |
|
398
501
|
# --------------------------------
|
399
502
|
#
|
400
503
|
def build_info_box
|
401
504
|
issue_date_present = !@document.issue_date.empty?
|
402
|
-
|
505
|
+
|
403
506
|
if issue_date_present
|
404
507
|
@pdf.text_box(
|
405
|
-
|
406
|
-
size:
|
508
|
+
@labels[:issue_date],
|
509
|
+
size: 11,
|
407
510
|
at: [290, 498 - @push_down],
|
408
511
|
width: 240
|
409
512
|
)
|
410
513
|
@pdf.text_box(
|
411
514
|
@document.issue_date,
|
412
|
-
size:
|
515
|
+
size: 13,
|
413
516
|
at: [390, 498 - @push_down],
|
414
|
-
|
517
|
+
align: :right
|
415
518
|
)
|
416
519
|
end
|
417
|
-
|
520
|
+
|
521
|
+
if used? @labels[:sublabels][:issue_date]
|
418
522
|
position = issue_date_present ? 483 : 498
|
523
|
+
|
419
524
|
@pdf.text_box(
|
420
|
-
|
525
|
+
@labels[:sublabels][:issue_date],
|
421
526
|
size: 10,
|
422
527
|
at: [290, position - @push_down],
|
423
528
|
width: 240
|
424
529
|
)
|
530
|
+
end
|
531
|
+
|
532
|
+
due_date_present = !@document.due_date.empty?
|
533
|
+
|
534
|
+
if due_date_present
|
535
|
+
position = issue_date_present ? 478 : 493
|
536
|
+
position -= 10 if used? @labels[:sublabels][:issue_date]
|
537
|
+
|
538
|
+
@pdf.text_box(
|
539
|
+
@labels[:due_date],
|
540
|
+
size: 11,
|
541
|
+
at: [290, position - @push_down],
|
542
|
+
width: 240
|
543
|
+
)
|
425
544
|
@pdf.text_box(
|
426
545
|
@document.due_date,
|
427
|
-
size:
|
546
|
+
size: 13,
|
428
547
|
at: [390, position - @push_down],
|
548
|
+
align: :right
|
549
|
+
)
|
550
|
+
end
|
551
|
+
|
552
|
+
if used? @labels[:sublabels][:due_date]
|
553
|
+
position = issue_date_present ? 463 : 478
|
554
|
+
position -= 10 if used? @labels[:sublabels][:issue_date]
|
555
|
+
|
556
|
+
@pdf.text_box(
|
557
|
+
@labels[:sublabels][:due_date],
|
558
|
+
size: 10,
|
559
|
+
at: [290, position - @push_down],
|
429
560
|
width: 240
|
430
561
|
)
|
431
562
|
end
|
563
|
+
|
432
564
|
if issue_date_present || due_date_present
|
433
|
-
height = (issue_date_present && due_date_present) ?
|
565
|
+
height = (issue_date_present && due_date_present) ? 75 : 60
|
566
|
+
height = @payment_box_height if @payment_box_height > height
|
567
|
+
|
434
568
|
@pdf.stroke_rounded_rectangle([280, 508 - @push_down], 270, height, 6)
|
435
569
|
end
|
436
570
|
end
|
@@ -438,15 +572,24 @@ module InvoicePrinter
|
|
438
572
|
# Build the following table for document items:
|
439
573
|
#
|
440
574
|
# =================================================================
|
441
|
-
# |Item |
|
575
|
+
# |Item | Quantity| Unit| Price per item| Tax| Total per item|
|
442
576
|
# |-----|----------|------|----------------|-----|----------------|
|
443
|
-
# |
|
577
|
+
# |x | 2| hr| $2| $1| $4|
|
444
578
|
# =================================================================
|
445
579
|
#
|
446
580
|
# If a specific column miss data, it's omittted.
|
447
|
-
#
|
581
|
+
# tax2 and tax3 fields can be added as well if necessary.
|
582
|
+
#
|
583
|
+
# Using sublabels one can change the table to look as:
|
584
|
+
#
|
585
|
+
# =================================================================
|
586
|
+
# |Item | Quantity| Unit| Price per item| Tax| Total per item|
|
587
|
+
# |it. | nom.| un.| ppi.| t.| tpi.|
|
588
|
+
# |-----|----------|------|----------------|-----|----------------|
|
589
|
+
# |x | 2| hr| $2| $1| $4|
|
590
|
+
# =================================================================
|
448
591
|
def build_items
|
449
|
-
@pdf.move_down(
|
592
|
+
@pdf.move_down(23 + @push_items_table + @push_down)
|
450
593
|
|
451
594
|
items_params = determine_items_structure
|
452
595
|
items = build_items_data(items_params)
|
@@ -465,7 +608,8 @@ module InvoicePrinter
|
|
465
608
|
5 => :right,
|
466
609
|
6 => :right,
|
467
610
|
7 => :right
|
468
|
-
}
|
611
|
+
},
|
612
|
+
font_size: 10
|
469
613
|
}
|
470
614
|
|
471
615
|
@pdf.table(items, styles) unless items.empty?
|
@@ -506,17 +650,26 @@ module InvoicePrinter
|
|
506
650
|
# Include only relevant headers
|
507
651
|
def build_items_header(items_params)
|
508
652
|
headers = []
|
509
|
-
headers << { text:
|
510
|
-
headers << { text:
|
511
|
-
headers << { text:
|
512
|
-
headers << { text:
|
513
|
-
headers << { text:
|
514
|
-
headers << { text:
|
515
|
-
headers << { text:
|
516
|
-
headers << { text:
|
653
|
+
headers << { text: label_with_sublabel(:item) } if items_params[:names]
|
654
|
+
headers << { text: label_with_sublabel(:quantity) } if items_params[:quantities]
|
655
|
+
headers << { text: label_with_sublabel(:unit) } if items_params[:units]
|
656
|
+
headers << { text: label_with_sublabel(:price_per_item) } if items_params[:prices]
|
657
|
+
headers << { text: label_with_sublabel(:tax) } if items_params[:taxes]
|
658
|
+
headers << { text: label_with_sublabel(:tax2) } if items_params[:taxes2]
|
659
|
+
headers << { text: label_with_sublabel(:tax3) } if items_params[:taxes3]
|
660
|
+
headers << { text: label_with_sublabel(:amount) } if items_params[:amounts]
|
517
661
|
headers
|
518
662
|
end
|
519
663
|
|
664
|
+
# This merge a label with its sublabel on a new line
|
665
|
+
def label_with_sublabel(symbol)
|
666
|
+
value = @labels[symbol]
|
667
|
+
if used? @labels[:sublabels][symbol]
|
668
|
+
value += "\n#{@labels[:sublabels][symbol]}"
|
669
|
+
end
|
670
|
+
value
|
671
|
+
end
|
672
|
+
|
520
673
|
# Build the following summary:
|
521
674
|
#
|
522
675
|
# Subtotal: 175
|
@@ -531,10 +684,14 @@ module InvoicePrinter
|
|
531
684
|
@pdf.move_down(25)
|
532
685
|
|
533
686
|
items = []
|
534
|
-
items << ["#{@labels[:subtotal]}:", @document.subtotal]
|
535
|
-
|
536
|
-
items << ["#{@labels[:
|
537
|
-
|
687
|
+
items << ["#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", @document.subtotal] \
|
688
|
+
unless @document.subtotal.empty?
|
689
|
+
items << ["#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", @document.tax] \
|
690
|
+
unless @document.tax.empty?
|
691
|
+
items << ["#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", @document.tax2] \
|
692
|
+
unless @document.tax2.empty?
|
693
|
+
items << ["#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", @document.tax3] \
|
694
|
+
unless @document.tax3.empty?
|
538
695
|
|
539
696
|
width = [
|
540
697
|
"#{@labels[:subtotal]}#{@document.subtotal}".size,
|
@@ -557,12 +714,33 @@ module InvoicePrinter
|
|
557
714
|
|
558
715
|
@pdf.move_down(15)
|
559
716
|
|
560
|
-
@
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
717
|
+
unless @document.total.empty?
|
718
|
+
@pdf.text(
|
719
|
+
"#{@labels[:total]}: #{@document.total}",
|
720
|
+
size: 16,
|
721
|
+
align: :right,
|
722
|
+
style: :bold
|
723
|
+
)
|
724
|
+
|
725
|
+
@pdf.move_down(5)
|
726
|
+
|
727
|
+
if used? @labels[:sublabels][:total]
|
728
|
+
@pdf.text(
|
729
|
+
"#{@labels[:sublabels][:total]}: #{@document.total}",
|
730
|
+
size: 12,
|
731
|
+
align: :right
|
732
|
+
)
|
733
|
+
end
|
734
|
+
end
|
735
|
+
end
|
736
|
+
|
737
|
+
# Return sublabel on a new line or empty string
|
738
|
+
def build_sublabel_for_total_table(sublabel)
|
739
|
+
if used? @labels[:sublabels][sublabel]
|
740
|
+
"\n#{@labels[:sublabels][sublabel]}:"
|
741
|
+
else
|
742
|
+
''
|
743
|
+
end
|
566
744
|
end
|
567
745
|
|
568
746
|
# Insert a logotype at the left bottom of the document
|
@@ -604,5 +782,9 @@ module InvoicePrinter
|
|
604
782
|
size: 12
|
605
783
|
) unless @pdf.page_count == 1
|
606
784
|
end
|
785
|
+
|
786
|
+
def used?(element)
|
787
|
+
element && !element.empty?
|
788
|
+
end
|
607
789
|
end
|
608
790
|
end
|