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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +7 -6
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +29 -16
  5. data/README.md +9 -3
  6. data/assets/fonts/opensans/OpenSans-Bold.ttf +0 -0
  7. data/assets/fonts/overpass/Overpass-Bold.ttf +0 -0
  8. data/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
  9. data/benchmarks/render.yml +19 -13
  10. data/bin/invoice_printer +7 -0
  11. data/docs/COMMAND_LINE.md +122 -0
  12. data/docs/LIBRARY.md +16 -12
  13. data/docs/SERVER.md +8 -2
  14. data/examples/breakdown.rb +77 -0
  15. data/examples/international_invoice.rb +2 -2
  16. data/examples/long_invoice.rb +8 -8
  17. data/examples/picture.jpg +0 -0
  18. data/examples/promo.rb +19 -13
  19. data/examples/provider_purchaser_lines.rb +6 -15
  20. data/examples/simple_invoice.rb +15 -16
  21. data/examples/variable_field_invoice.rb +96 -0
  22. data/invoice_printer.gemspec +3 -2
  23. data/invoice_printer_fonts.gemspec +4 -1
  24. data/lib/invoice_printer.rb +27 -2
  25. data/lib/invoice_printer/document.rb +90 -148
  26. data/lib/invoice_printer/document/item.rb +34 -28
  27. data/lib/invoice_printer/pdf_document.rb +201 -208
  28. data/lib/invoice_printer/version.rb +1 -1
  29. data/test/api_test.rb +2 -2
  30. data/test/background_test.rb +1 -1
  31. data/test/cli_test.rb +1 -1
  32. data/test/dates_box_test.rb +4 -4
  33. data/test/examples_test.rb +2 -0
  34. data/test/inputs_test.rb +4 -4
  35. data/test/invoice_printer_test.rb +2 -2
  36. data/test/items_table_test.rb +2 -2
  37. data/test/labels_test.rb +2 -2
  38. data/test/notes_test.rb +1 -1
  39. data/test/page_numbers_test.rb +4 -4
  40. data/test/payment_box_test.rb +5 -5
  41. data/test/test_ext.rb +2 -1
  42. data/test/test_helper.rb +1 -1
  43. metadata +15 -15
  44. data/assets/logo.png +0 -0
  45. data/examples/background.png +0 -0
  46. data/examples/logo.png +0 -0
  47. data/examples/prawn.png +0 -0
  48. 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(document: Document.new, labels: {}, font: nil, stamp: nil, logo: nil, background: nil, page_size: :letter)
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? @font
97
- use_font(@font)
98
- end
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?(@font)
147
- set_font_from_path(@font)
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(@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: font,
173
- bold_italic: font
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
- if used? @labels[:sublabels][:issue_date]
625
- position = issue_date_present ? 483 : 498
545
+ if used? @labels[:sublabels][:issue_date]
546
+ position = issue_date_present ? 483 : 498
626
547
 
627
- @pdf.text_box(
628
- @labels[:sublabels][:issue_date],
629
- size: 10,
630
- at: [x(284), y(position) - @push_down],
631
- width: x(240)
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
- if used? @labels[:sublabels][:due_date]
657
- position = issue_date_present ? 463 : 478
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[:sublabels][:due_date],
662
- size: 10,
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 += 12 if @push_items_table <= 18
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
- styles = {
705
- headers: headers,
706
- row_colors: ['F5F5F5', nil],
681
+ options = {
682
+ header: true,
683
+ row_colors: [nil, 'ededed'],
707
684
  width: x(540, 2),
708
- align: {
709
- 0 => :left,
710
- 1 => :right,
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
- @pdf.table(items, styles) unless items.empty?
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.name if items_params[:names]
747
- line << item.variable if items_params[:variables]
748
- line << item.quantity if items_params[:quantities]
749
- line << item.unit if items_params[:units]
750
- line << item.price if items_params[:prices]
751
- line << item.tax if items_params[:taxes]
752
- line << item.tax2 if items_params[:taxes2]
753
- line << item.tax3 if items_params[:taxes3]
754
- line << item.amount if items_params[:amounts]
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 << { text: label_with_sublabel(:item) } if items_params[:names]
763
- headers << { text: label_with_sublabel(:variable) } if items_params[:variables]
764
- headers << { text: label_with_sublabel(:quantity) } if items_params[:quantities]
765
- headers << { text: label_with_sublabel(:unit) } if items_params[:units]
766
- headers << { text: label_with_sublabel(:price_per_item) } if items_params[:prices]
767
- headers << { text: label_with_sublabel(:tax) } if items_params[:taxes]
768
- headers << { text: label_with_sublabel(:tax2) } if items_params[:taxes2]
769
- headers << { text: label_with_sublabel(:tax3) } if items_params[:taxes3]
770
- headers << { text: label_with_sublabel(:amount) } if items_params[:amounts]
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
- unless @document.total.empty?
828
- @pdf.text(
829
- "#{@labels[:total]}: #{@document.total}",
830
- size: 16,
831
- align: :right,
832
- style: :bold
833
- )
834
-
835
- @pdf.move_down(5)
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
- if used? @labels[:sublabels][:total]
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 : 85
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, 10],
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(