invoice_printer 2.0.0.alpha1 → 2.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +37 -0
- data/Gemfile.lock +27 -14
- data/README.md +2 -2
- data/benchmarks/render.yml +13 -8
- data/bin/invoice_printer +2 -2
- data/docs/COMMAND_LINE.md +120 -1
- data/docs/INSTALLATION.md +33 -2
- data/docs/LIBRARY.md +14 -11
- data/docs/SERVER.md +23 -7
- data/examples/czech_invoice.rb +2 -5
- data/examples/czech_invoice_long.rb +2 -5
- data/examples/international_invoice.rb +4 -7
- data/examples/long_invoice.rb +4 -4
- data/examples/picture.jpg +0 -0
- data/examples/promo.rb +17 -16
- data/examples/provider_purchaser_lines.rb +8 -20
- data/examples/simple_invoice.rb +15 -16
- data/invoice_printer.gemspec +18 -4
- data/invoice_printer_fonts.gemspec +39 -0
- data/invoice_printer_server.gemspec +3 -0
- data/lib/invoice_printer/document.rb +84 -148
- data/lib/invoice_printer/pdf_document.rb +79 -84
- data/lib/invoice_printer/version.rb +1 -1
- data/test/api_test.rb +3 -3
- 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 +1 -1
- 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_helper.rb +1 -1
- metadata +11 -9
@@ -94,41 +94,7 @@ module InvoicePrinter
|
|
94
94
|
end
|
95
95
|
|
96
96
|
if used? @font
|
97
|
-
|
98
|
-
set_fonts(@font) if @font
|
99
|
-
else
|
100
|
-
raise FontFileNotFound, "Font file not found at #{@font}"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Version 2.1 deprecation warnings
|
105
|
-
warnings = [
|
106
|
-
@document.provider_street,
|
107
|
-
@document.provider_street_number,
|
108
|
-
@document.provider_postcode,
|
109
|
-
@document.provider_city,
|
110
|
-
@document.provider_city_part,
|
111
|
-
@document.provider_extra_address_line,
|
112
|
-
@document.purchaser_street,
|
113
|
-
@document.purchaser_street_number,
|
114
|
-
@document.purchaser_postcode,
|
115
|
-
@document.purchaser_city,
|
116
|
-
@document.purchaser_city_part,
|
117
|
-
@document.purchaser_extra_address_line
|
118
|
-
].delete_if(&:empty?)
|
119
|
-
|
120
|
-
unless warnings.empty?
|
121
|
-
warning = <<~WARN
|
122
|
-
WARNING: Following values are used in deprecated fields and
|
123
|
-
won't be rendered in future versions of InvoicePrinter:
|
124
|
-
|
125
|
-
#{warnings.join(", ")}
|
126
|
-
|
127
|
-
Use new provider_lines and purchaser_lines fields instead of
|
128
|
-
the old address fields.
|
129
|
-
WARN
|
130
|
-
|
131
|
-
$stderr.puts warning
|
97
|
+
use_font(@font)
|
132
98
|
end
|
133
99
|
|
134
100
|
build_pdf
|
@@ -146,8 +112,28 @@ module InvoicePrinter
|
|
146
112
|
|
147
113
|
private
|
148
114
|
|
115
|
+
def use_font(font)
|
116
|
+
if File.exist?(@font)
|
117
|
+
set_font_from_path(@font)
|
118
|
+
else
|
119
|
+
set_builtin_font(@font)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_builtin_font(font)
|
124
|
+
require 'invoice_printer/fonts'
|
125
|
+
|
126
|
+
@pdf.font_families.update(
|
127
|
+
"#{font}" => InvoicePrinter::Fonts.paths_for(font)
|
128
|
+
)
|
129
|
+
@pdf.font(font)
|
130
|
+
|
131
|
+
rescue StandardError
|
132
|
+
raise FontFileNotFound, "Font file not found for #{font}"
|
133
|
+
end
|
134
|
+
|
149
135
|
# Add font family in Prawn for a given +font+ file
|
150
|
-
def
|
136
|
+
def set_font_from_path(font)
|
151
137
|
font_name = Pathname.new(font).basename
|
152
138
|
@pdf.font_families.update(
|
153
139
|
"#{font_name}" => {
|
@@ -165,6 +151,7 @@ module InvoicePrinter
|
|
165
151
|
@push_down = 0
|
166
152
|
@push_items_table = 0
|
167
153
|
@pdf.fill_color '000000'
|
154
|
+
@pdf.stroke_color 'aaaaaa'
|
168
155
|
build_header
|
169
156
|
build_provider_box
|
170
157
|
build_purchaser_box
|
@@ -447,7 +434,6 @@ module InvoicePrinter
|
|
447
434
|
end
|
448
435
|
|
449
436
|
# Match the height of next box if needed
|
450
|
-
# TODO: it's smaller without sublabels
|
451
437
|
min_height = 60
|
452
438
|
if used?(@document.issue_date) || used?(@document.due_date)
|
453
439
|
min_height = (used?(@document.issue_date) && used?(@document.due_date)) ? 75 : 60
|
@@ -467,7 +453,8 @@ module InvoicePrinter
|
|
467
453
|
at: [10, y(483) - @push_down],
|
468
454
|
width: x(234)
|
469
455
|
)
|
470
|
-
|
456
|
+
|
457
|
+
@pdf.stroke_rounded_rectangle([0, y(508) - @push_down], x(266), @payment_box_height, 6)
|
471
458
|
else
|
472
459
|
@payment_box_height = 60
|
473
460
|
@push_iban = 0
|
@@ -654,6 +641,7 @@ module InvoicePrinter
|
|
654
641
|
height = @payment_box_height if @payment_box_height > height
|
655
642
|
|
656
643
|
@pdf.stroke_rounded_rectangle([x(274), y(508) - @push_down], x(266), height, 6)
|
644
|
+
@push_items_table += 12 if @push_items_table <= 18
|
657
645
|
end
|
658
646
|
end
|
659
647
|
|
@@ -683,26 +671,28 @@ module InvoicePrinter
|
|
683
671
|
items_params = determine_items_structure
|
684
672
|
items = build_items_data(items_params)
|
685
673
|
headers = build_items_header(items_params)
|
674
|
+
data = items.prepend(headers)
|
686
675
|
|
687
|
-
|
688
|
-
|
689
|
-
row_colors: ['
|
676
|
+
options = {
|
677
|
+
header: true,
|
678
|
+
row_colors: [nil, 'ededed'],
|
690
679
|
width: x(540, 2),
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
2 => :right,
|
695
|
-
3 => :right,
|
696
|
-
4 => :right,
|
697
|
-
5 => :right,
|
698
|
-
6 => :right,
|
699
|
-
7 => :right,
|
700
|
-
8 => :right
|
701
|
-
},
|
702
|
-
font_size: 10
|
680
|
+
cell_style: {
|
681
|
+
borders: []
|
682
|
+
}
|
703
683
|
}
|
704
684
|
|
705
|
-
|
685
|
+
unless items.empty?
|
686
|
+
@pdf.font_size(10) do
|
687
|
+
@pdf.table(data, options) do
|
688
|
+
row(0).background_color = 'e3e3e3'
|
689
|
+
row(0).border_color = 'aaaaaa'
|
690
|
+
row(0).borders = [:bottom]
|
691
|
+
row(items.size - 1).borders = [:bottom]
|
692
|
+
row(items.size - 1).border_color = 'd9d9d9'
|
693
|
+
end
|
694
|
+
end
|
695
|
+
end
|
706
696
|
end
|
707
697
|
|
708
698
|
# Determine sections of the items table to show based on provided data
|
@@ -726,15 +716,15 @@ module InvoicePrinter
|
|
726
716
|
def build_items_data(items_params)
|
727
717
|
@document.items.map do |item|
|
728
718
|
line = []
|
729
|
-
line << item.name if items_params[:names]
|
730
|
-
line << item.variable if items_params[:variables]
|
731
|
-
line << item.quantity if items_params[:quantities]
|
732
|
-
line << item.unit if items_params[:units]
|
733
|
-
line << item.price if items_params[:prices]
|
734
|
-
line << item.tax if items_params[:taxes]
|
735
|
-
line << item.tax2 if items_params[:taxes2]
|
736
|
-
line << item.tax3 if items_params[:taxes3]
|
737
|
-
line << item.amount if items_params[:amounts]
|
719
|
+
line << { content: item.name, borders: [:bottom], align: :left } if items_params[:names]
|
720
|
+
line << { content: item.variable, align: :right } if items_params[:variables]
|
721
|
+
line << { content: item.quantity, align: :right } if items_params[:quantities]
|
722
|
+
line << { content: item.unit, align: :right } if items_params[:units]
|
723
|
+
line << { content: item.price, align: :right } if items_params[:prices]
|
724
|
+
line << { content: item.tax, align: :right } if items_params[:taxes]
|
725
|
+
line << { content: item.tax2, align: :right } if items_params[:taxes2]
|
726
|
+
line << { content: item.tax3, align: :right } if items_params[:taxes3]
|
727
|
+
line << { content: item.amount, align: :right } if items_params[:amounts]
|
738
728
|
line
|
739
729
|
end
|
740
730
|
end
|
@@ -742,15 +732,15 @@ module InvoicePrinter
|
|
742
732
|
# Include only relevant headers
|
743
733
|
def build_items_header(items_params)
|
744
734
|
headers = []
|
745
|
-
headers << {
|
746
|
-
headers << {
|
747
|
-
headers << {
|
748
|
-
headers << {
|
749
|
-
headers << {
|
750
|
-
headers << {
|
751
|
-
headers << {
|
752
|
-
headers << {
|
753
|
-
headers << {
|
735
|
+
headers << { content: label_with_sublabel(:item), align: :left } if items_params[:names]
|
736
|
+
headers << { content: label_with_sublabel(:variable), align: :right } if items_params[:variables]
|
737
|
+
headers << { content: label_with_sublabel(:quantity), align: :right } if items_params[:quantities]
|
738
|
+
headers << { content: label_with_sublabel(:unit), align: :right } if items_params[:units]
|
739
|
+
headers << { content: label_with_sublabel(:price_per_item), align: :right } if items_params[:prices]
|
740
|
+
headers << { content: label_with_sublabel(:tax), align: :right } if items_params[:taxes]
|
741
|
+
headers << { content: label_with_sublabel(:tax2), align: :right } if items_params[:taxes2]
|
742
|
+
headers << { content: label_with_sublabel(:tax3), align: :right } if items_params[:taxes3]
|
743
|
+
headers << { content: label_with_sublabel(:amount), align: :right } if items_params[:amounts]
|
754
744
|
headers
|
755
745
|
end
|
756
746
|
|
@@ -777,13 +767,13 @@ module InvoicePrinter
|
|
777
767
|
@pdf.move_down(25)
|
778
768
|
|
779
769
|
items = []
|
780
|
-
items << ["#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", @document.subtotal] \
|
770
|
+
items << [{ content: "#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", align: :right }, @document.subtotal] \
|
781
771
|
unless @document.subtotal.empty?
|
782
|
-
items << ["#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", @document.tax] \
|
772
|
+
items << [{ content: "#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", align: :right }, @document.tax] \
|
783
773
|
unless @document.tax.empty?
|
784
|
-
items << ["#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", @document.tax2] \
|
774
|
+
items << [{ content: "#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", align: :right }, @document.tax2] \
|
785
775
|
unless @document.tax2.empty?
|
786
|
-
items << ["#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", @document.tax3] \
|
776
|
+
items << [{ content: "#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", align: :right }, @document.tax3] \
|
787
777
|
unless @document.tax3.empty?
|
788
778
|
|
789
779
|
width = [
|
@@ -793,16 +783,14 @@ module InvoicePrinter
|
|
793
783
|
"#{@labels[:tax3]}#{@document.tax3}".size
|
794
784
|
].max * 8
|
795
785
|
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
0 => :right,
|
800
|
-
1 => :left
|
786
|
+
options = {
|
787
|
+
cell_style: {
|
788
|
+
borders: []
|
801
789
|
}
|
802
790
|
}
|
803
791
|
|
804
792
|
@pdf.span(x(width), position: :right) do
|
805
|
-
@pdf.table(items,
|
793
|
+
@pdf.table(items, options) unless items.empty?
|
806
794
|
end
|
807
795
|
|
808
796
|
@pdf.move_down(15)
|
@@ -841,7 +829,7 @@ module InvoicePrinter
|
|
841
829
|
# If a note is present, position it on top of it.
|
842
830
|
def build_logo
|
843
831
|
if @logo && !@logo.empty?
|
844
|
-
bottom = @document.note.empty? ? 75 :
|
832
|
+
bottom = @document.note.empty? ? 75 : (75 + note_height)
|
845
833
|
@pdf.image(@logo, at: [0, bottom], fit: [200, 50])
|
846
834
|
end
|
847
835
|
end
|
@@ -859,12 +847,19 @@ module InvoicePrinter
|
|
859
847
|
@pdf.text_box(
|
860
848
|
"#{@document.note}",
|
861
849
|
size: 10,
|
862
|
-
at: [0,
|
850
|
+
at: [0, note_height],
|
863
851
|
width: x(450),
|
864
852
|
align: :left
|
865
853
|
)
|
866
854
|
end
|
867
855
|
|
856
|
+
def note_height
|
857
|
+
@note_height ||= begin
|
858
|
+
num_of_lines = @document.note.lines.count
|
859
|
+
(num_of_lines * 11)
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
868
863
|
# Include page numbers if we got more than one page
|
869
864
|
def build_footer
|
870
865
|
@pdf.number_pages(
|
data/test/api_test.rb
CHANGED
@@ -31,7 +31,7 @@ class ApiTest < Minitest::Test
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_print_with_valid_document
|
34
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
34
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
35
35
|
|
36
36
|
json = {
|
37
37
|
'document' => invoice.to_h,
|
@@ -60,7 +60,7 @@ class ApiTest < Minitest::Test
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def test_render_with_valid_document
|
63
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
63
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
64
64
|
output = InvoicePrinter.render(document: invoice)
|
65
65
|
|
66
66
|
json = {
|
@@ -73,6 +73,6 @@ class ApiTest < Minitest::Test
|
|
73
73
|
body = JSON.parse last_response.body
|
74
74
|
|
75
75
|
assert last_response.ok?
|
76
|
-
assert_equal body, { 'result' => 'ok', 'data' => Base64.
|
76
|
+
assert_equal body, { 'result' => 'ok', 'data' => Base64.strict_encode64(output) }
|
77
77
|
end
|
78
78
|
end
|
data/test/background_test.rb
CHANGED
data/test/cli_test.rb
CHANGED
@@ -8,7 +8,7 @@ class CLITest < Minitest::Test
|
|
8
8
|
t = Time.now.strftime("%Y%m%d")
|
9
9
|
tmpname = "/tmp/invoice-#{t}-#{$$}-#{rand(0x100000000).to_s(36)}-fd"
|
10
10
|
|
11
|
-
@invoice = InvoicePrinter::Document.new(default_document_params)
|
11
|
+
@invoice = InvoicePrinter::Document.new(**default_document_params)
|
12
12
|
@invoice_as_json = @invoice.to_json
|
13
13
|
@output_path = tmpname
|
14
14
|
end
|
data/test/dates_box_test.rb
CHANGED
@@ -8,7 +8,7 @@ class DatesBoxTest < Minitest::Test
|
|
8
8
|
issue_date: '05/03/2016',
|
9
9
|
due_date: '14/03/2016'
|
10
10
|
)
|
11
|
-
invoice = InvoicePrinter::Document.new(params)
|
11
|
+
invoice = InvoicePrinter::Document.new(**params)
|
12
12
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
13
13
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
14
14
|
|
@@ -21,7 +21,7 @@ class DatesBoxTest < Minitest::Test
|
|
21
21
|
issue_date: '05/03/2016',
|
22
22
|
due_date: ''
|
23
23
|
)
|
24
|
-
invoice = InvoicePrinter::Document.new(params)
|
24
|
+
invoice = InvoicePrinter::Document.new(**params)
|
25
25
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
26
26
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
27
27
|
|
@@ -34,7 +34,7 @@ class DatesBoxTest < Minitest::Test
|
|
34
34
|
issue_date: nil,
|
35
35
|
due_date: '05/03/2016'
|
36
36
|
)
|
37
|
-
invoice = InvoicePrinter::Document.new(params)
|
37
|
+
invoice = InvoicePrinter::Document.new(**params)
|
38
38
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
39
39
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
40
40
|
|
@@ -47,7 +47,7 @@ class DatesBoxTest < Minitest::Test
|
|
47
47
|
issue_date: '',
|
48
48
|
due_date: nil
|
49
49
|
)
|
50
|
-
invoice = InvoicePrinter::Document.new(params)
|
50
|
+
invoice = InvoicePrinter::Document.new(**params)
|
51
51
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
52
52
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
53
53
|
|
data/test/examples_test.rb
CHANGED
data/test/inputs_test.rb
CHANGED
@@ -28,12 +28,12 @@ class InputsTest < Minitest::Test
|
|
28
28
|
)
|
29
29
|
|
30
30
|
# No exceptions should be raised
|
31
|
-
invoice = InvoicePrinter::Document.new(params)
|
31
|
+
invoice = InvoicePrinter::Document.new(**params)
|
32
32
|
InvoicePrinter.render(document: invoice)
|
33
33
|
end
|
34
34
|
|
35
35
|
def test_missing_font_raises_an_exception
|
36
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
36
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
37
37
|
|
38
38
|
assert_raises(InvoicePrinter::PDFDocument::FontFileNotFound) do
|
39
39
|
InvoicePrinter.render(document: invoice, font: 'missing.font')
|
@@ -41,7 +41,7 @@ class InputsTest < Minitest::Test
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def test_missing_logo_raises_an_exception
|
44
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
44
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
45
45
|
|
46
46
|
assert_raises(InvoicePrinter::PDFDocument::LogoFileNotFound) do
|
47
47
|
InvoicePrinter.render(document: invoice, logo: 'missing.png')
|
@@ -49,7 +49,7 @@ class InputsTest < Minitest::Test
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def test_missing_stamp_raises_an_exception
|
52
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
52
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
53
53
|
|
54
54
|
assert_raises(InvoicePrinter::PDFDocument::StampFileNotFound) do
|
55
55
|
InvoicePrinter.render(document: invoice, stamp: 'missing.png')
|
@@ -4,7 +4,7 @@ class InvoicePrinterTest < Minitest::Test
|
|
4
4
|
include InvoicePrinterHelpers
|
5
5
|
|
6
6
|
def test_render_document
|
7
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
7
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
8
8
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
9
9
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
10
10
|
strings = InvoicePrinter::PDFDocument.new(document: invoice).to_a
|
@@ -13,7 +13,7 @@ class InvoicePrinterTest < Minitest::Test
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_render_document_from_json
|
16
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
16
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
17
17
|
invoice_json = JSON.parse(invoice.to_json)
|
18
18
|
invoice_from_json = InvoicePrinter::Document.from_json(invoice_json)
|
19
19
|
rendered_pdf = InvoicePrinter.render(document: invoice_from_json)
|
data/test/items_table_test.rb
CHANGED
@@ -41,10 +41,10 @@ class ItemsTableTest < Minitest::Test
|
|
41
41
|
|
42
42
|
def invoice_without_item_column(column)
|
43
43
|
InvoicePrinter::Document.new(
|
44
|
-
default_document_params.merge(
|
44
|
+
**default_document_params.merge(
|
45
45
|
items: [
|
46
46
|
InvoicePrinter::Document::Item.new(
|
47
|
-
default_document_item_params.merge("#{column}": nil)
|
47
|
+
**default_document_item_params.merge("#{column}": nil)
|
48
48
|
)
|
49
49
|
]
|
50
50
|
)
|
data/test/labels_test.rb
CHANGED
@@ -6,7 +6,7 @@ class LabelsTest < Minitest::Test
|
|
6
6
|
def test_setting_global_labels
|
7
7
|
labels = { provider: 'Default Provider', purchaser: 'Default Purchaser' }
|
8
8
|
InvoicePrinter.labels = labels
|
9
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
9
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
10
10
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
11
11
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
12
12
|
|
@@ -16,7 +16,7 @@ class LabelsTest < Minitest::Test
|
|
16
16
|
|
17
17
|
def test_setting_instant_labels
|
18
18
|
labels = { provider: 'Current Provider', purchaser: 'Current Purchaser' }
|
19
|
-
invoice = InvoicePrinter::Document.new(default_document_params)
|
19
|
+
invoice = InvoicePrinter::Document.new(**default_document_params)
|
20
20
|
rendered_pdf = InvoicePrinter.render(document: invoice, labels: labels)
|
21
21
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
22
22
|
|
data/test/notes_test.rb
CHANGED
@@ -7,7 +7,7 @@ class NotesTest < Minitest::Test
|
|
7
7
|
params = default_document_params.merge(
|
8
8
|
note: 'ABC is a registered trademark.'
|
9
9
|
)
|
10
|
-
invoice = InvoicePrinter::Document.new(params)
|
10
|
+
invoice = InvoicePrinter::Document.new(**params)
|
11
11
|
rendered_pdf = InvoicePrinter.render(document: invoice)
|
12
12
|
pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
|
13
13
|
|