invoice_printer 2.0.0.beta3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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