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
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
33
33
  package_files = `git ls-files -z`.split("\x0")
34
34
  .reject{ |file| ONLY_SERVER_FILES.include?(file) }
35
35
  .reject{ |file| ONLY_FONTS_FILES.include?(file) }
36
+ .reject{ |file| file.match /.*\.png/ }
36
37
  .reject{ |file| file.match /.*\.pdf/ }
37
38
 
38
39
  spec.files = package_files
@@ -44,8 +45,8 @@ Gem::Specification.new do |spec|
44
45
  spec.required_ruby_version = '>= 2.4'
45
46
 
46
47
  spec.add_dependency 'json', '~> 2.1'
47
- spec.add_dependency 'prawn', '~> 2.1.0'
48
- spec.add_dependency 'prawn-layout', '~> 0.8.4'
48
+ spec.add_dependency 'prawn', '~> 2.2'
49
+ spec.add_dependency 'prawn-table', '~> 0.2.2'
49
50
 
50
51
  spec.add_development_dependency 'bundler', '>= 1.7'
51
52
  spec.add_development_dependency 'rake', '>= 10.0'
@@ -7,10 +7,13 @@ FONTS_FILES = [
7
7
  'FONTS_LICENSE.txt',
8
8
  'assets/fonts/overpass/OFL-1.1.txt',
9
9
  'assets/fonts/overpass/Overpass-Regular.ttf',
10
+ 'assets/fonts/overpass/Overpass-Bold.ttf',
10
11
  'assets/fonts/opensans/Apache-2.0.txt',
11
12
  'assets/fonts/opensans/OpenSans-Regular.ttf',
13
+ 'assets/fonts/opensans/OpenSans-Bold.ttf',
12
14
  'assets/fonts/roboto/Apache-2.0.txt',
13
15
  'assets/fonts/roboto/Roboto-Regular.ttf',
16
+ 'assets/fonts/roboto/Roboto-Bold.ttf',
14
17
  'lib/invoice_printer/fonts.rb'
15
18
  ]
16
19
 
@@ -22,7 +25,7 @@ Gem::Specification.new do |spec|
22
25
  spec.summary = 'Super simple PDF invoicing in pure Ruby'
23
26
  spec.description = 'Super simple and fast PDF invoicing in pure Ruby (based on Prawn library).'
24
27
  spec.homepage = 'https://github.com/strzibny/invoice_printer'
25
- spec.license = 'MIT'
28
+ spec.licenses = ['MIT', 'OFL 1.1', 'Apache 2.0']
26
29
 
27
30
  # Include only font files
28
31
  spec.files = FONTS_FILES
@@ -15,6 +15,7 @@ Prawn::Font::AFM.hide_m17n_warning = true
15
15
  # InvoicePrinter.print(
16
16
  # document: invoice,
17
17
  # font: 'path-to-font-file.ttf',
18
+ # bold_font: 'path-to-font-file.ttf',
18
19
  # stamp: 'stamp.jpg',
19
20
  # logo: 'logo.jpg',
20
21
  # file_name: 'invoice.pdf'
@@ -37,6 +38,7 @@ module InvoicePrinter
37
38
  # iban: 'IBAN:',
38
39
  # issue_date: 'Issue date:',
39
40
  # due_date: 'Due date:',
41
+ # variable_symbol: 'Variable symbol:'
40
42
  # item: 'Item',
41
43
  # quantity: 'Quantity',
42
44
  # unit: 'Unit',
@@ -64,16 +66,28 @@ module InvoicePrinter
64
66
  # document - InvoicePrinter::Document object
65
67
  # labels - labels to override
66
68
  # font - font file to use
69
+ # bold_font - bold font file to use
67
70
  # stamp - stamp & signature (image)
68
71
  # logo - logotype (image)
69
72
  # background - background (image)
70
73
  # page_size - :letter or :a4
71
74
  # file_name - output file
72
- def self.print(document:, labels: {}, font: nil, stamp: nil, logo: nil, background: nil, page_size: :letter, file_name:)
75
+ def self.print(
76
+ document:,
77
+ labels: {},
78
+ font: nil,
79
+ bold_font: nil,
80
+ stamp: nil,
81
+ logo: nil,
82
+ background: nil,
83
+ page_size: :letter,
84
+ file_name:
85
+ )
73
86
  PDFDocument.new(
74
87
  document: document,
75
88
  labels: labels,
76
89
  font: font,
90
+ bold_font: bold_font,
77
91
  stamp: stamp,
78
92
  logo: logo,
79
93
  background: background,
@@ -86,15 +100,26 @@ module InvoicePrinter
86
100
  # document - InvoicePrinter::Document object
87
101
  # labels - labels to override
88
102
  # font - font file to use
103
+ # bold_font - bold font file to use
89
104
  # stamp - stamp & signature (image)
90
105
  # logo - logotype (image)
91
106
  # background - background (image)
92
107
  # page_size - :letter or :a4
93
- def self.render(document:, labels: {}, font: nil, stamp: nil, logo: nil, background: nil, page_size: :letter)
108
+ def self.render(
109
+ document:,
110
+ labels: {},
111
+ font: nil,
112
+ bold_font: nil,
113
+ stamp: nil,
114
+ logo: nil,
115
+ background: nil,
116
+ page_size: :letter
117
+ )
94
118
  PDFDocument.new(
95
119
  document: document,
96
120
  labels: labels,
97
121
  font: font,
122
+ bold_font: bold_font,
98
123
  stamp: stamp,
99
124
  logo: logo,
100
125
  background: background,
@@ -15,6 +15,7 @@ module InvoicePrinter
15
15
  # purchaser_lines: "Ostravska 2\n747 05 Opava",
16
16
  # issue_date: '19/03/3939',
17
17
  # due_date: '19/03/3939',
18
+ # variable_symbol: '198900000001',
18
19
  # subtotal: '$ 150',
19
20
  # tax: '$ 50',
20
21
  # total: '$ 200',
@@ -39,27 +40,14 @@ module InvoicePrinter
39
40
  :provider_tax_id,
40
41
  :provider_tax_id2,
41
42
  :provider_lines,
42
- # Provider address fields
43
- :provider_street,
44
- :provider_street_number,
45
- :provider_postcode,
46
- :provider_city,
47
- :provider_city_part,
48
- :provider_extra_address_line,
49
43
  # Purchaser fields
50
44
  :purchaser_name,
51
45
  :purchaser_tax_id,
52
46
  :purchaser_tax_id2,
53
47
  :purchaser_lines,
54
- # Purchaser address fields
55
- :purchaser_street,
56
- :purchaser_street_number,
57
- :purchaser_postcode,
58
- :purchaser_city,
59
- :purchaser_city_part,
60
- :purchaser_extra_address_line,
61
48
  :issue_date,
62
49
  :due_date,
50
+ :variable_symbol,
63
51
  # Account details
64
52
  :subtotal,
65
53
  :tax,
@@ -76,113 +64,78 @@ module InvoicePrinter
76
64
  class << self
77
65
  def from_json(json)
78
66
  new(
79
- number: json['number'],
80
- provider_name: json['provider_name'],
81
- provider_tax_id: json['provider_tax_id'],
82
- provider_tax_id2: json['provider_tax_id2'],
83
- provider_street: json['provider_street'],
84
- provider_street_number: json['provider_street_number'],
85
- provider_postcode: json['provider_postcode'],
86
- provider_city: json['provider_city'],
87
- provider_city_part: json['provider_city_part'],
88
- provider_extra_address_line: json['provider_extra_address_line'],
89
- provider_lines: json['provider_lines'],
90
- purchaser_name: json['purchaser_name'],
91
- purchaser_tax_id: json['purchaser_tax_id'],
92
- purchaser_tax_id2: json['purchaser_tax_id2'],
93
- purchaser_street: json['purchaser_street'],
94
- purchaser_street_number: json['purchaser_street_number'],
95
- purchaser_postcode: json['purchaser_postcode'],
96
- purchaser_city: json['purchaser_city'],
97
- purchaser_city_part: json['purchaser_city_part'],
98
- purchaser_extra_address_line: json['purchaser_extra_address_line'],
99
- purchaser_lines: json['purchaser_lines'],
100
- issue_date: json['issue_date'],
101
- due_date: json['due_date'],
102
- subtotal: json['subtotal'],
103
- tax: json['tax'],
104
- tax2: json['tax2'],
105
- tax3: json['tax3'],
106
- total: json['total'],
107
- bank_account_number: json['bank_account_number'],
108
- account_iban: json['account_iban'],
109
- account_swift: json['account_swift'],
110
- note: json['note'],
67
+ number: json['number'],
68
+ provider_name: json['provider_name'],
69
+ provider_tax_id: json['provider_tax_id'],
70
+ provider_tax_id2: json['provider_tax_id2'],
71
+ provider_lines: json['provider_lines'],
72
+ purchaser_name: json['purchaser_name'],
73
+ purchaser_tax_id: json['purchaser_tax_id'],
74
+ purchaser_tax_id2: json['purchaser_tax_id2'],
75
+ purchaser_lines: json['purchaser_lines'],
76
+ issue_date: json['issue_date'],
77
+ due_date: json['due_date'],
78
+ variable_symbol: json['variable_symbol'],
79
+ subtotal: json['subtotal'],
80
+ tax: json['tax'],
81
+ tax2: json['tax2'],
82
+ tax3: json['tax3'],
83
+ total: json['total'],
84
+ bank_account_number: json['bank_account_number'],
85
+ account_iban: json['account_iban'],
86
+ account_swift: json['account_swift'],
87
+ note: json['note'],
111
88
 
112
- items: (json['items'] || []).map { |item_json| Item.from_json(item_json) }
89
+ items: (json['items'] || []).map { |item_json| Item.from_json(item_json) }
113
90
  )
114
91
  end
115
92
  end
116
93
 
117
- def initialize(number: nil,
118
- provider_name: nil,
119
- provider_tax_id: nil,
120
- provider_tax_id2: nil,
121
- provider_street: nil,
122
- provider_street_number: nil,
123
- provider_postcode: nil,
124
- provider_city: nil,
125
- provider_city_part: nil,
126
- provider_extra_address_line: nil,
127
- provider_lines: nil,
128
- purchaser_name: nil,
129
- purchaser_tax_id: nil,
130
- purchaser_tax_id2: nil,
131
- purchaser_street: nil,
132
- purchaser_street_number: nil,
133
- purchaser_postcode: nil,
134
- purchaser_city: nil,
135
- purchaser_city_part: nil,
136
- purchaser_extra_address_line: nil,
137
- purchaser_lines: nil,
138
- issue_date: nil,
139
- due_date: nil,
140
- subtotal: nil,
141
- tax: nil,
142
- tax2: nil,
143
- tax3: nil,
144
- total: nil,
145
- bank_account_number: nil,
146
- account_iban: nil,
147
- account_swift: nil,
148
- items: nil,
149
- note: nil)
150
-
151
- @number = String(number)
152
- @provider_name = String(provider_name)
153
- @provider_tax_id = String(provider_tax_id)
154
- @provider_tax_id2 = String(provider_tax_id2)
155
- @provider_street = String(provider_street)
156
- @provider_street_number = String(provider_street_number)
157
- @provider_postcode = String(provider_postcode)
158
- @provider_city = String(provider_city)
159
- @provider_city_part = String(provider_city_part)
160
- @provider_extra_address_line = String(provider_extra_address_line)
161
- @provider_lines = String(provider_lines)
162
- @purchaser_name = String(purchaser_name)
163
- @purchaser_tax_id = String(purchaser_tax_id)
164
- @purchaser_tax_id2 = String(purchaser_tax_id2)
165
- @purchaser_street = String(purchaser_street)
166
- @purchaser_street_number = String(purchaser_street_number)
167
- @purchaser_postcode = String(purchaser_postcode)
168
- @purchaser_city = String(purchaser_city)
169
- @purchaser_city_part = String(purchaser_city_part)
170
- @purchaser_extra_address_line = String(purchaser_extra_address_line)
171
- @purchaser_lines = String(purchaser_lines)
172
- @issue_date = String(issue_date)
173
- @due_date = String(due_date)
174
- @subtotal = String(subtotal)
175
- @tax = String(tax)
176
- @tax2 = String(tax2)
177
- @tax3 = String(tax3)
178
- @total = String(total)
179
- @bank_account_number = String(bank_account_number)
180
- @account_iban = String(account_iban)
181
- @account_swift = String(account_swift)
182
- @items = items
183
- @note = String(note)
184
-
94
+ def initialize(number: nil,
95
+ provider_name: nil,
96
+ provider_tax_id: nil,
97
+ provider_tax_id2: nil,
98
+ provider_lines: nil,
99
+ purchaser_name: nil,
100
+ purchaser_tax_id: nil,
101
+ purchaser_tax_id2: nil,
102
+ purchaser_lines: nil,
103
+ issue_date: nil,
104
+ due_date: nil,
105
+ variable_symbol: nil,
106
+ subtotal: nil,
107
+ tax: nil,
108
+ tax2: nil,
109
+ tax3: nil,
110
+ total: nil,
111
+ bank_account_number: nil,
112
+ account_iban: nil,
113
+ account_swift: nil,
114
+ items: nil,
115
+ note: nil)
185
116
 
117
+ @number = String(number)
118
+ @provider_name = String(provider_name)
119
+ @provider_tax_id = String(provider_tax_id)
120
+ @provider_tax_id2 = String(provider_tax_id2)
121
+ @provider_lines = String(provider_lines)
122
+ @purchaser_name = String(purchaser_name)
123
+ @purchaser_tax_id = String(purchaser_tax_id)
124
+ @purchaser_tax_id2 = String(purchaser_tax_id2)
125
+ @purchaser_lines = String(purchaser_lines)
126
+ @issue_date = String(issue_date)
127
+ @due_date = String(due_date)
128
+ @variable_symbol = String(variable_symbol)
129
+ @subtotal = String(subtotal)
130
+ @tax = String(tax)
131
+ @tax2 = String(tax2)
132
+ @tax3 = String(tax3)
133
+ @total = String(total)
134
+ @bank_account_number = String(bank_account_number)
135
+ @account_iban = String(account_iban)
136
+ @account_swift = String(account_swift)
137
+ @items = items
138
+ @note = String(note)
186
139
 
187
140
  raise InvalidInput, 'items are not only a type of InvoicePrinter::Document::Item' \
188
141
  unless @items.select{ |i| !i.is_a?(InvoicePrinter::Document::Item) }.empty?
@@ -190,39 +143,28 @@ module InvoicePrinter
190
143
 
191
144
  def to_h
192
145
  {
193
- 'number': @number,
194
- 'provider_name': @provider_name,
195
- 'provider_tax_id': @provider_tax_id,
196
- 'provider_tax_id2': @provider_tax_id2,
197
- 'provider_street': @provider_street,
198
- 'provider_street_number': @provider_street_number,
199
- 'provider_postcode': @provider_postcode,
200
- 'provider_city': @provider_city,
201
- 'provider_city_part': @provider_city_part,
202
- 'provider_extra_address_line': @provider_extra_address_line,
203
- 'provider_lines': @provider_lines,
204
- 'purchaser_name': @purchaser_name,
205
- 'purchaser_tax_id': @purchaser_tax_id,
206
- 'purchaser_tax_id2': @purchaser_tax_id2,
207
- 'purchaser_street': @purchaser_street,
208
- 'purchaser_street_number': @purchaser_street_number,
209
- 'purchaser_postcode': @purchaser_postcode,
210
- 'purchaser_city': @purchaser_city,
211
- 'purchaser_city_part': @purchaser_city_part,
212
- 'purchaser_extra_address_line': @purchaser_extra_address_line,
213
- 'purchaser_lines': @purchaser_lines,
214
- 'issue_date': @issue_date,
215
- 'due_date': @due_date,
216
- 'subtotal': @subtotal,
217
- 'tax': @tax,
218
- 'tax2': @tax2,
219
- 'tax3': @tax3,
220
- 'total': @total,
221
- 'bank_account_number': @bank_account_number,
222
- 'account_iban': @account_iban,
223
- 'account_swift': @account_swift,
224
- 'items': @items.map(&:to_h),
225
- 'note': @note
146
+ 'number': @number,
147
+ 'provider_name': @provider_name,
148
+ 'provider_tax_id': @provider_tax_id,
149
+ 'provider_tax_id2': @provider_tax_id2,
150
+ 'provider_lines': @provider_lines,
151
+ 'purchaser_name': @purchaser_name,
152
+ 'purchaser_tax_id': @purchaser_tax_id,
153
+ 'purchaser_tax_id2': @purchaser_tax_id2,
154
+ 'purchaser_lines': @purchaser_lines,
155
+ 'issue_date': @issue_date,
156
+ 'due_date': @due_date,
157
+ 'variable_symbol': @variable_symbol,
158
+ 'subtotal': @subtotal,
159
+ 'tax': @tax,
160
+ 'tax2': @tax2,
161
+ 'tax3': @tax3,
162
+ 'total': @total,
163
+ 'bank_account_number': @bank_account_number,
164
+ 'account_iban': @account_iban,
165
+ 'account_swift': @account_swift,
166
+ 'items': @items.map(&:to_h),
167
+ 'note': @note
226
168
  }
227
169
  end
228
170
 
@@ -6,6 +6,7 @@ module InvoicePrinter
6
6
  #
7
7
  # item = InvoicePrinter::Document::Item.new(
8
8
  # name: 'UX consultation',
9
+ # breakdown: "Monday 3h\nTuesday 1h"
9
10
  # variable: 'June 2008',
10
11
  # quantity: '4',
11
12
  # unit: 'hours',
@@ -18,6 +19,7 @@ module InvoicePrinter
18
19
  # but this is not enforced.
19
20
  class Item
20
21
  attr_reader :name,
22
+ :breakdown,
21
23
  :variable, # for anything required
22
24
  :quantity,
23
25
  :unit,
@@ -30,51 +32,55 @@ module InvoicePrinter
30
32
  class << self
31
33
  def from_json(json)
32
34
  new(
33
- name: json['name'],
35
+ name: json['name'],
36
+ breakdown: json['breakdown'],
34
37
  variable: json['variable'],
35
38
  quantity: json['quantity'],
36
- unit: json['unit'],
37
- price: json['price'],
38
- tax: json['tax'],
39
- tax2: json['tax2'],
40
- tax3: json['tax3'],
41
- amount: json['amount']
39
+ unit: json['unit'],
40
+ price: json['price'],
41
+ tax: json['tax'],
42
+ tax2: json['tax2'],
43
+ tax3: json['tax3'],
44
+ amount: json['amount']
42
45
  )
43
46
  end
44
47
  end
45
48
 
46
- def initialize(name: nil,
49
+ def initialize(name: nil,
50
+ breakdown: nil,
47
51
  variable: nil,
48
52
  quantity: nil,
49
- unit: nil,
50
- price: nil,
51
- tax: nil,
52
- tax2: nil,
53
- tax3: nil,
54
- amount: nil)
53
+ unit: nil,
54
+ price: nil,
55
+ tax: nil,
56
+ tax2: nil,
57
+ tax3: nil,
58
+ amount: nil)
55
59
 
56
- @name = String(name)
60
+ @name = String(name)
61
+ @breakdown = String(breakdown)
57
62
  @variable = String(variable)
58
63
  @quantity = String(quantity)
59
- @unit = String(unit)
60
- @price = String(price)
61
- @tax = String(tax)
62
- @tax2 = String(tax2)
63
- @tax3 = String(tax3)
64
- @amount = String(amount)
64
+ @unit = String(unit)
65
+ @price = String(price)
66
+ @tax = String(tax)
67
+ @tax2 = String(tax2)
68
+ @tax3 = String(tax3)
69
+ @amount = String(amount)
65
70
  end
66
71
 
67
72
  def to_h
68
73
  {
69
- 'name': @name,
74
+ 'name': @name,
75
+ 'breakdown': @breakdown,
70
76
  'variable': @variable,
71
77
  'quantity': @quantity,
72
- 'unit': @unit,
73
- 'price': @price,
74
- 'tax': @tax,
75
- 'tax2': @tax2,
76
- 'tax3': @tax3,
77
- 'amount': @amount,
78
+ 'unit': @unit,
79
+ 'price': @price,
80
+ 'tax': @tax,
81
+ 'tax2': @tax2,
82
+ 'tax3': @tax3,
83
+ 'amount': @amount,
78
84
  }
79
85
  end
80
86