invoice_printer 2.0.0.beta3 → 2.2.0
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/Dockerfile +7 -6
- data/Gemfile +1 -1
- data/Gemfile.lock +29 -16
- data/README.md +9 -3
- data/assets/fonts/opensans/OpenSans-Bold.ttf +0 -0
- data/assets/fonts/overpass/Overpass-Bold.ttf +0 -0
- data/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
- data/benchmarks/render.yml +19 -13
- data/bin/invoice_printer +7 -0
- data/docs/COMMAND_LINE.md +122 -0
- data/docs/LIBRARY.md +16 -12
- data/docs/SERVER.md +8 -2
- data/examples/breakdown.rb +77 -0
- data/examples/international_invoice.rb +2 -2
- data/examples/long_invoice.rb +8 -8
- data/examples/picture.jpg +0 -0
- data/examples/promo.rb +19 -13
- data/examples/provider_purchaser_lines.rb +6 -15
- data/examples/simple_invoice.rb +15 -16
- data/examples/variable_field_invoice.rb +96 -0
- data/invoice_printer.gemspec +3 -2
- data/invoice_printer_fonts.gemspec +4 -1
- data/lib/invoice_printer.rb +27 -2
- data/lib/invoice_printer/document.rb +90 -148
- data/lib/invoice_printer/document/item.rb +34 -28
- data/lib/invoice_printer/pdf_document.rb +201 -208
- data/lib/invoice_printer/version.rb +1 -1
- data/test/api_test.rb +2 -2
- data/test/background_test.rb +1 -1
- data/test/cli_test.rb +1 -1
- data/test/dates_box_test.rb +4 -4
- data/test/examples_test.rb +2 -0
- data/test/inputs_test.rb +4 -4
- data/test/invoice_printer_test.rb +2 -2
- data/test/items_table_test.rb +2 -2
- data/test/labels_test.rb +2 -2
- data/test/notes_test.rb +1 -1
- data/test/page_numbers_test.rb +4 -4
- data/test/payment_box_test.rb +5 -5
- data/test/test_ext.rb +2 -1
- data/test/test_helper.rb +1 -1
- metadata +15 -15
- data/assets/logo.png +0 -0
- data/examples/background.png +0 -0
- data/examples/logo.png +0 -0
- data/examples/prawn.png +0 -0
- data/examples/stamp.png +0 -0
@@ -11,6 +11,7 @@ module InvoicePrinter
|
|
11
11
|
# document: invoice,
|
12
12
|
# labels: {},
|
13
13
|
# font: 'font.ttf',
|
14
|
+
# bold_font: 'bold_font.ttf',
|
14
15
|
# stamp: 'stamp.jpg',
|
15
16
|
# logo: 'example.jpg'
|
16
17
|
# )
|
@@ -20,7 +21,7 @@ module InvoicePrinter
|
|
20
21
|
class StampFileNotFound < StandardError; end
|
21
22
|
class InvalidInput < StandardError; end
|
22
23
|
|
23
|
-
attr_reader :invoice, :labels, :file_name, :font, :stamp, :logo
|
24
|
+
attr_reader :invoice, :labels, :file_name, :font, :bold_font, :stamp, :logo
|
24
25
|
|
25
26
|
DEFAULT_LABELS = {
|
26
27
|
name: 'Invoice',
|
@@ -36,6 +37,7 @@ module InvoicePrinter
|
|
36
37
|
iban: 'IBAN',
|
37
38
|
issue_date: 'Issue date',
|
38
39
|
due_date: 'Due date',
|
40
|
+
variable_symbol: 'Variable symbol',
|
39
41
|
item: 'Item',
|
40
42
|
variable: '',
|
41
43
|
quantity: 'Quantity',
|
@@ -65,10 +67,20 @@ module InvoicePrinter
|
|
65
67
|
@@labels = DEFAULT_LABELS.merge(labels)
|
66
68
|
end
|
67
69
|
|
68
|
-
def initialize(
|
70
|
+
def initialize(
|
71
|
+
document: Document.new,
|
72
|
+
labels: {},
|
73
|
+
font: nil,
|
74
|
+
bold_font: nil,
|
75
|
+
stamp: nil,
|
76
|
+
logo: nil,
|
77
|
+
background: nil,
|
78
|
+
page_size: :letter
|
79
|
+
)
|
69
80
|
@document = document
|
70
81
|
@labels = merge_custom_labels(labels)
|
71
82
|
@font = font
|
83
|
+
@bold_font = bold_font
|
72
84
|
@stamp = stamp
|
73
85
|
@logo = logo
|
74
86
|
@page_size = page_size ? PAGE_SIZES[page_size.to_sym] : PAGE_SIZES[:letter]
|
@@ -93,38 +105,10 @@ module InvoicePrinter
|
|
93
105
|
end
|
94
106
|
end
|
95
107
|
|
96
|
-
if used? @
|
97
|
-
use_font(@font)
|
98
|
-
|
99
|
-
|
100
|
-
# Version 2.1 deprecation warnings
|
101
|
-
warnings = [
|
102
|
-
@document.provider_street,
|
103
|
-
@document.provider_street_number,
|
104
|
-
@document.provider_postcode,
|
105
|
-
@document.provider_city,
|
106
|
-
@document.provider_city_part,
|
107
|
-
@document.provider_extra_address_line,
|
108
|
-
@document.purchaser_street,
|
109
|
-
@document.purchaser_street_number,
|
110
|
-
@document.purchaser_postcode,
|
111
|
-
@document.purchaser_city,
|
112
|
-
@document.purchaser_city_part,
|
113
|
-
@document.purchaser_extra_address_line
|
114
|
-
].delete_if(&:empty?)
|
115
|
-
|
116
|
-
unless warnings.empty?
|
117
|
-
warning = <<~WARN
|
118
|
-
WARNING: Following values are used in deprecated fields and
|
119
|
-
won't be rendered in future versions of InvoicePrinter:
|
120
|
-
|
121
|
-
#{warnings.join(", ")}
|
122
|
-
|
123
|
-
Use new provider_lines and purchaser_lines fields instead of
|
124
|
-
the old address fields.
|
125
|
-
WARN
|
126
|
-
|
127
|
-
$stderr.puts warning
|
108
|
+
if used?(@font) && used?(@bold_font)
|
109
|
+
use_font(@font, @bold_font)
|
110
|
+
elsif used?(@font)
|
111
|
+
use_font(@font, @font)
|
128
112
|
end
|
129
113
|
|
130
114
|
build_pdf
|
@@ -142,11 +126,11 @@ module InvoicePrinter
|
|
142
126
|
|
143
127
|
private
|
144
128
|
|
145
|
-
def use_font(font)
|
146
|
-
if File.exist?(
|
147
|
-
set_font_from_path(
|
129
|
+
def use_font(font, bold_font)
|
130
|
+
if File.exist?(font) && File.exist?(bold_font)
|
131
|
+
set_font_from_path(font, bold_font)
|
148
132
|
else
|
149
|
-
set_builtin_font(
|
133
|
+
set_builtin_font(font)
|
150
134
|
end
|
151
135
|
end
|
152
136
|
|
@@ -163,14 +147,14 @@ module InvoicePrinter
|
|
163
147
|
end
|
164
148
|
|
165
149
|
# Add font family in Prawn for a given +font+ file
|
166
|
-
def set_font_from_path(font)
|
150
|
+
def set_font_from_path(font, bold_font)
|
167
151
|
font_name = Pathname.new(font).basename
|
168
152
|
@pdf.font_families.update(
|
169
153
|
"#{font_name}" => {
|
170
154
|
normal: font,
|
171
155
|
italic: font,
|
172
|
-
bold:
|
173
|
-
bold_italic:
|
156
|
+
bold: bold_font,
|
157
|
+
bold_italic: bold_font
|
174
158
|
}
|
175
159
|
)
|
176
160
|
@pdf.font(font_name)
|
@@ -181,6 +165,7 @@ module InvoicePrinter
|
|
181
165
|
@push_down = 0
|
182
166
|
@push_items_table = 0
|
183
167
|
@pdf.fill_color '000000'
|
168
|
+
@pdf.stroke_color 'aaaaaa'
|
184
169
|
build_header
|
185
170
|
build_provider_box
|
186
171
|
build_purchaser_box
|
@@ -281,41 +266,6 @@ module InvoicePrinter
|
|
281
266
|
width: x(240)
|
282
267
|
)
|
283
268
|
end
|
284
|
-
else
|
285
|
-
@pdf.text_box(
|
286
|
-
"#{@document.provider_street} #{@document.provider_street_number}",
|
287
|
-
size: 10,
|
288
|
-
at: [10, y(620) - @push_down],
|
289
|
-
width: x(240)
|
290
|
-
)
|
291
|
-
@pdf.text_box(
|
292
|
-
@document.provider_postcode,
|
293
|
-
size: 10,
|
294
|
-
at: [10, y(605) - @push_down],
|
295
|
-
width: x(240)
|
296
|
-
)
|
297
|
-
@pdf.text_box(
|
298
|
-
@document.provider_city,
|
299
|
-
size: 10,
|
300
|
-
at: [60, y(605) - @push_down],
|
301
|
-
width: x(240)
|
302
|
-
)
|
303
|
-
unless @document.provider_city_part.empty?
|
304
|
-
@pdf.text_box(
|
305
|
-
@document.provider_city_part,
|
306
|
-
size: 10,
|
307
|
-
at: [60, y(590) - @push_down],
|
308
|
-
width: x(240)
|
309
|
-
)
|
310
|
-
end
|
311
|
-
unless @document.provider_extra_address_line.empty?
|
312
|
-
@pdf.text_box(
|
313
|
-
@document.provider_extra_address_line,
|
314
|
-
size: 10,
|
315
|
-
at: [10, y(575) - @push_down],
|
316
|
-
width: x(240)
|
317
|
-
)
|
318
|
-
end
|
319
269
|
end
|
320
270
|
unless @document.provider_tax_id.empty?
|
321
271
|
@pdf.text_box(
|
@@ -386,41 +336,6 @@ module InvoicePrinter
|
|
386
336
|
width: x(240)
|
387
337
|
)
|
388
338
|
end
|
389
|
-
else
|
390
|
-
@pdf.text_box(
|
391
|
-
"#{@document.purchaser_street} #{@document.purchaser_street_number}",
|
392
|
-
size: 10,
|
393
|
-
at: [x(284), y(620) - @push_down],
|
394
|
-
width: x(240)
|
395
|
-
)
|
396
|
-
@pdf.text_box(
|
397
|
-
@document.purchaser_postcode,
|
398
|
-
size: 10,
|
399
|
-
at: [x(284), y(605) - @push_down],
|
400
|
-
width: x(240)
|
401
|
-
)
|
402
|
-
@pdf.text_box(
|
403
|
-
@document.purchaser_city,
|
404
|
-
size: 10,
|
405
|
-
at: [x(334), y(605) - @push_down],
|
406
|
-
width: x(240)
|
407
|
-
)
|
408
|
-
unless @document.purchaser_city_part.empty?
|
409
|
-
@pdf.text_box(
|
410
|
-
@document.purchaser_city_part,
|
411
|
-
size: 10,
|
412
|
-
at: [x(334), y(590) - @push_down],
|
413
|
-
width: x(240)
|
414
|
-
)
|
415
|
-
end
|
416
|
-
unless @document.purchaser_extra_address_line.empty?
|
417
|
-
@pdf.text_box(
|
418
|
-
@document.purchaser_extra_address_line,
|
419
|
-
size: 10,
|
420
|
-
at: [x(284), y(575) - @push_down],
|
421
|
-
width: x(240)
|
422
|
-
)
|
423
|
-
end
|
424
339
|
end
|
425
340
|
unless @document.purchaser_tax_id.empty?
|
426
341
|
@pdf.text_box(
|
@@ -469,6 +384,10 @@ module InvoicePrinter
|
|
469
384
|
end
|
470
385
|
@payment_box_height = min_height
|
471
386
|
|
387
|
+
if big_info_box?
|
388
|
+
@payment_box_height = 110
|
389
|
+
end
|
390
|
+
|
472
391
|
if @document.bank_account_number.empty?
|
473
392
|
@pdf.text_box(
|
474
393
|
@labels[:payment],
|
@@ -580,6 +499,7 @@ module InvoicePrinter
|
|
580
499
|
@payment_box_height += 30
|
581
500
|
@push_items_table += 18
|
582
501
|
end
|
502
|
+
|
583
503
|
if min_height > @payment_box_height
|
584
504
|
@payment_box_height = min_height
|
585
505
|
@push_items_table += 25
|
@@ -600,6 +520,8 @@ module InvoicePrinter
|
|
600
520
|
# | Issue date sublabel |
|
601
521
|
# | Due date: 03/03/2016|
|
602
522
|
# | Due date sublabel |
|
523
|
+
# | Variable symbol: VS12345678|
|
524
|
+
# | Variable symbol sublabel |
|
603
525
|
# --------------------------------
|
604
526
|
#
|
605
527
|
def build_info_box
|
@@ -619,17 +541,17 @@ module InvoicePrinter
|
|
619
541
|
width: x(146),
|
620
542
|
align: :right
|
621
543
|
)
|
622
|
-
end
|
623
544
|
|
624
|
-
|
625
|
-
|
545
|
+
if used? @labels[:sublabels][:issue_date]
|
546
|
+
position = issue_date_present ? 483 : 498
|
626
547
|
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
548
|
+
@pdf.text_box(
|
549
|
+
@labels[:sublabels][:issue_date],
|
550
|
+
size: 10,
|
551
|
+
at: [x(284), y(position) - @push_down],
|
552
|
+
width: x(240)
|
553
|
+
)
|
554
|
+
end
|
633
555
|
end
|
634
556
|
|
635
557
|
due_date_present = !@document.due_date.empty?
|
@@ -651,29 +573,83 @@ module InvoicePrinter
|
|
651
573
|
width: x(146),
|
652
574
|
align: :right
|
653
575
|
)
|
576
|
+
|
577
|
+
if used? @labels[:sublabels][:due_date]
|
578
|
+
position = issue_date_present ? 463 : 478
|
579
|
+
position -= 10 if used? @labels[:sublabels][:issue_date]
|
580
|
+
|
581
|
+
@pdf.text_box(
|
582
|
+
@labels[:sublabels][:due_date],
|
583
|
+
size: 10,
|
584
|
+
at: [x(284), y(position) - @push_down],
|
585
|
+
width: x(240)
|
586
|
+
)
|
587
|
+
end
|
654
588
|
end
|
655
589
|
|
656
|
-
|
657
|
-
|
590
|
+
variable_symbol_present = !@document.variable_symbol.empty?
|
591
|
+
|
592
|
+
if variable_symbol_present
|
593
|
+
position = (issue_date_present || due_date_present) ? 483 : 498
|
594
|
+
position = issue_date_present && due_date_present ? 458 : 463
|
658
595
|
position -= 10 if used? @labels[:sublabels][:issue_date]
|
596
|
+
position -= 10 if used? @labels[:sublabels][:due_date]
|
659
597
|
|
660
598
|
@pdf.text_box(
|
661
|
-
@labels[:
|
662
|
-
size:
|
599
|
+
@labels[:variable_symbol],
|
600
|
+
size: 11,
|
663
601
|
at: [x(284), y(position) - @push_down],
|
664
602
|
width: x(240)
|
665
603
|
)
|
604
|
+
@pdf.text_box(
|
605
|
+
@document.variable_symbol,
|
606
|
+
size: 13,
|
607
|
+
at: [x(384), y(position) - @push_down],
|
608
|
+
width: x(146),
|
609
|
+
align: :right
|
610
|
+
)
|
611
|
+
|
612
|
+
if used? @labels[:sublabels][:variable_symbol]
|
613
|
+
position = issue_date_present ? 443 : 458
|
614
|
+
position -= 10 if used? @labels[:sublabels][:issue_date]
|
615
|
+
position -= 10 if used? @labels[:sublabels][:due_date]
|
616
|
+
|
617
|
+
@pdf.text_box(
|
618
|
+
@labels[:sublabels][:variable_symbol],
|
619
|
+
size: 10,
|
620
|
+
at: [x(284), y(position) - @push_down],
|
621
|
+
width: x(240)
|
622
|
+
)
|
623
|
+
end
|
666
624
|
end
|
667
625
|
|
668
|
-
if issue_date_present || due_date_present
|
626
|
+
if issue_date_present || due_date_present || variable_symbol_present
|
627
|
+
big_box = (issue_date_present && due_date_present && variable_symbol_present && info_box_sublabels_used?)
|
669
628
|
height = (issue_date_present && due_date_present) ? 75 : 60
|
629
|
+
height = big_box ? 110 : height
|
670
630
|
height = @payment_box_height if @payment_box_height > height
|
671
631
|
|
672
632
|
@pdf.stroke_rounded_rectangle([x(274), y(508) - @push_down], x(266), height, 6)
|
673
|
-
@push_items_table +=
|
633
|
+
@push_items_table += 23 if @push_items_table <= 18
|
634
|
+
@push_items_table += 24 if big_box
|
635
|
+
|
636
|
+
#@push_items_table += 30
|
674
637
|
end
|
675
638
|
end
|
676
639
|
|
640
|
+
def big_info_box?
|
641
|
+
!@document.issue_date.empty? &&
|
642
|
+
!@document.due_date.empty? &&
|
643
|
+
!@document.variable_symbol.empty? &&
|
644
|
+
info_box_sublabels_used?
|
645
|
+
end
|
646
|
+
|
647
|
+
def info_box_sublabels_used?
|
648
|
+
used?(@labels[:sublabels][:issue_date]) ||
|
649
|
+
used?(@labels[:sublabels][:due_date]) ||
|
650
|
+
used?(@labels[:sublabels][:variable_symbol])
|
651
|
+
end
|
652
|
+
|
677
653
|
# Build the following table for document items:
|
678
654
|
#
|
679
655
|
# =================================================================
|
@@ -700,26 +676,28 @@ module InvoicePrinter
|
|
700
676
|
items_params = determine_items_structure
|
701
677
|
items = build_items_data(items_params)
|
702
678
|
headers = build_items_header(items_params)
|
679
|
+
data = items.prepend(headers)
|
703
680
|
|
704
|
-
|
705
|
-
|
706
|
-
row_colors: ['
|
681
|
+
options = {
|
682
|
+
header: true,
|
683
|
+
row_colors: [nil, 'ededed'],
|
707
684
|
width: x(540, 2),
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
2 => :right,
|
712
|
-
3 => :right,
|
713
|
-
4 => :right,
|
714
|
-
5 => :right,
|
715
|
-
6 => :right,
|
716
|
-
7 => :right,
|
717
|
-
8 => :right
|
718
|
-
},
|
719
|
-
font_size: 10
|
685
|
+
cell_style: {
|
686
|
+
borders: []
|
687
|
+
}
|
720
688
|
}
|
721
689
|
|
722
|
-
|
690
|
+
unless items.empty?
|
691
|
+
@pdf.font_size(10) do
|
692
|
+
@pdf.table(data, options) do
|
693
|
+
row(0).background_color = 'e3e3e3'
|
694
|
+
row(0).border_color = 'aaaaaa'
|
695
|
+
row(0).borders = [:bottom]
|
696
|
+
row(items.size - 1).borders = [:bottom]
|
697
|
+
row(items.size - 1).border_color = 'd9d9d9'
|
698
|
+
end
|
699
|
+
end
|
700
|
+
end
|
723
701
|
end
|
724
702
|
|
725
703
|
# Determine sections of the items table to show based on provided data
|
@@ -743,31 +721,53 @@ module InvoicePrinter
|
|
743
721
|
def build_items_data(items_params)
|
744
722
|
@document.items.map do |item|
|
745
723
|
line = []
|
746
|
-
line << item
|
747
|
-
line << item.
|
748
|
-
line << item.
|
749
|
-
line << item.
|
750
|
-
line << item.
|
751
|
-
line << item.
|
752
|
-
line << item.
|
753
|
-
line << item.
|
754
|
-
line << item.
|
724
|
+
line << { content: name_cell(item), borders: [:bottom] } if items_params[:names]
|
725
|
+
#line << { content: item.name, borders: [:bottom], align: :left } if items_params[:names]
|
726
|
+
line << { content: item.variable, align: :right } if items_params[:variables]
|
727
|
+
line << { content: item.quantity, align: :right } if items_params[:quantities]
|
728
|
+
line << { content: item.unit, align: :right } if items_params[:units]
|
729
|
+
line << { content: item.price, align: :right } if items_params[:prices]
|
730
|
+
line << { content: item.tax, align: :right } if items_params[:taxes]
|
731
|
+
line << { content: item.tax2, align: :right } if items_params[:taxes2]
|
732
|
+
line << { content: item.tax3, align: :right } if items_params[:taxes3]
|
733
|
+
line << { content: item.amount, align: :right } if items_params[:amounts]
|
755
734
|
line
|
756
735
|
end
|
757
736
|
end
|
758
737
|
|
738
|
+
# Display item's name and breakdown if present
|
739
|
+
def name_cell(item)
|
740
|
+
data = if used?(item.breakdown)
|
741
|
+
data = [
|
742
|
+
[{ content: item.name, padding: [5, 0, 0, 5] }],
|
743
|
+
[{ content: item.breakdown, size: 8, padding: [2, 0, 5, 5] }]
|
744
|
+
]
|
745
|
+
|
746
|
+
options = {
|
747
|
+
cell_style: {
|
748
|
+
borders: []
|
749
|
+
},
|
750
|
+
position: :left
|
751
|
+
}
|
752
|
+
|
753
|
+
@pdf.make_table(data, options)
|
754
|
+
else
|
755
|
+
item.name
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
759
|
# Include only relevant headers
|
760
760
|
def build_items_header(items_params)
|
761
761
|
headers = []
|
762
|
-
headers << {
|
763
|
-
headers << {
|
764
|
-
headers << {
|
765
|
-
headers << {
|
766
|
-
headers << {
|
767
|
-
headers << {
|
768
|
-
headers << {
|
769
|
-
headers << {
|
770
|
-
headers << {
|
762
|
+
headers << { content: label_with_sublabel(:item), align: :left } if items_params[:names]
|
763
|
+
headers << { content: label_with_sublabel(:variable), align: :right } if items_params[:variables]
|
764
|
+
headers << { content: label_with_sublabel(:quantity), align: :right } if items_params[:quantities]
|
765
|
+
headers << { content: label_with_sublabel(:unit), align: :right } if items_params[:units]
|
766
|
+
headers << { content: label_with_sublabel(:price_per_item), align: :right } if items_params[:prices]
|
767
|
+
headers << { content: label_with_sublabel(:tax), align: :right } if items_params[:taxes]
|
768
|
+
headers << { content: label_with_sublabel(:tax2), align: :right } if items_params[:taxes2]
|
769
|
+
headers << { content: label_with_sublabel(:tax3), align: :right } if items_params[:taxes3]
|
770
|
+
headers << { content: label_with_sublabel(:amount), align: :right } if items_params[:amounts]
|
771
771
|
headers
|
772
772
|
end
|
773
773
|
|
@@ -794,54 +794,40 @@ module InvoicePrinter
|
|
794
794
|
@pdf.move_down(25)
|
795
795
|
|
796
796
|
items = []
|
797
|
-
items << ["#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", @document.subtotal] \
|
798
|
-
unless @document.subtotal.empty?
|
799
|
-
items << ["#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", @document.tax] \
|
800
|
-
unless @document.tax.empty?
|
801
|
-
items << ["#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", @document.tax2] \
|
802
|
-
unless @document.tax2.empty?
|
803
|
-
items << ["#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", @document.tax3] \
|
804
|
-
unless @document.tax3.empty?
|
805
|
-
|
806
|
-
width = [
|
807
|
-
"#{@labels[:subtotal]}#{@document.subtotal}".size,
|
808
|
-
"#{@labels[:tax]}#{@document.tax}".size,
|
809
|
-
"#{@labels[:tax2]}#{@document.tax2}".size,
|
810
|
-
"#{@labels[:tax3]}#{@document.tax3}".size
|
811
|
-
].max * 8
|
812
|
-
|
813
|
-
styles = {
|
814
|
-
border_width: 0,
|
815
|
-
align: {
|
816
|
-
0 => :right,
|
817
|
-
1 => :left
|
818
|
-
}
|
819
|
-
}
|
820
|
-
|
821
|
-
@pdf.span(x(width), position: :right) do
|
822
|
-
@pdf.table(items, styles) unless items.empty?
|
823
|
-
end
|
824
|
-
|
825
|
-
@pdf.move_down(15)
|
826
797
|
|
827
|
-
|
828
|
-
@
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
)
|
834
|
-
|
835
|
-
|
798
|
+
items << [
|
799
|
+
{ content: "#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", align: :left },
|
800
|
+
{ content: @document.subtotal, align: :right }
|
801
|
+
] unless @document.subtotal.empty?
|
802
|
+
|
803
|
+
items << [
|
804
|
+
{ content: "#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", align: :left },
|
805
|
+
{ content: @document.tax, align: :right }
|
806
|
+
] unless @document.tax.empty?
|
807
|
+
|
808
|
+
items << [
|
809
|
+
{ content: "#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", align: :left },
|
810
|
+
{ content: @document.tax2, align: :right }
|
811
|
+
] unless @document.tax2.empty?
|
812
|
+
|
813
|
+
items << [
|
814
|
+
{ content: "#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", align: :left },
|
815
|
+
{ content: @document.tax3, align: :right }
|
816
|
+
] unless @document.tax3.empty?
|
817
|
+
|
818
|
+
items << [
|
819
|
+
{ content: "\n#{@labels[:total]}:#{build_sublabel_for_total_table(:total)}", align: :left, font_style: :bold, size: 16 },
|
820
|
+
{ content: "\n#{@document.total}", align: :right, font_style: :bold, size: 16 }
|
821
|
+
] unless @document.total.empty?
|
822
|
+
|
823
|
+
options = {
|
824
|
+
cell_style: {
|
825
|
+
borders: []
|
826
|
+
},
|
827
|
+
position: :right
|
828
|
+
}
|
836
829
|
|
837
|
-
|
838
|
-
@pdf.text(
|
839
|
-
"#{@labels[:sublabels][:total]}: #{@document.total}",
|
840
|
-
size: 12,
|
841
|
-
align: :right
|
842
|
-
)
|
843
|
-
end
|
844
|
-
end
|
830
|
+
@pdf.table(items, options) unless items.empty?
|
845
831
|
end
|
846
832
|
|
847
833
|
# Return sublabel on a new line or empty string
|
@@ -858,7 +844,7 @@ module InvoicePrinter
|
|
858
844
|
# If a note is present, position it on top of it.
|
859
845
|
def build_logo
|
860
846
|
if @logo && !@logo.empty?
|
861
|
-
bottom = @document.note.empty? ? 75 :
|
847
|
+
bottom = @document.note.empty? ? 75 : (75 + note_height)
|
862
848
|
@pdf.image(@logo, at: [0, bottom], fit: [200, 50])
|
863
849
|
end
|
864
850
|
end
|
@@ -876,12 +862,19 @@ module InvoicePrinter
|
|
876
862
|
@pdf.text_box(
|
877
863
|
"#{@document.note}",
|
878
864
|
size: 10,
|
879
|
-
at: [0,
|
865
|
+
at: [0, note_height],
|
880
866
|
width: x(450),
|
881
867
|
align: :left
|
882
868
|
)
|
883
869
|
end
|
884
870
|
|
871
|
+
def note_height
|
872
|
+
@note_height ||= begin
|
873
|
+
num_of_lines = @document.note.lines.count
|
874
|
+
(num_of_lines * 11)
|
875
|
+
end
|
876
|
+
end
|
877
|
+
|
885
878
|
# Include page numbers if we got more than one page
|
886
879
|
def build_footer
|
887
880
|
@pdf.number_pages(
|