invoice_printer 2.2.0.alpha1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73bc8cc15f44b26e3208614d83ee31dbb385b804e7a248723b07d6c9b60e7238
4
- data.tar.gz: 5d2ab37a9051dba8ddd0018a4d7bc3d2f6a14949f131679f77ac7a0cd9069981
3
+ metadata.gz: 2f98cb9145f19c42e95490c56afbb156408c5049c766d9ddcb1c776ee112c5fe
4
+ data.tar.gz: 77c6280ab4566b41ad6b040113f3ccf99b0c4bf5e2bccce28c3d0740644a1e57
5
5
  SHA512:
6
- metadata.gz: 3fb1d1f236410e510f79c30b9c817d63285ae9dd49a579ec4930e6596f1ab3c06d8d480c7e4c3f11f14873c14aa9d6b62bbd6e91687cafc052e6387244a791f3
7
- data.tar.gz: 2819f38b58b55ec97517c5521cee21a70ab33ad64303d6c71f92ae41186f5c7136f66a88ef8aad9eaea0144c632cc96d71244cff04264a642f8f0cd13437b52a
6
+ metadata.gz: c1be305d2988483f0912598cbcd523b3f8f020667f61cb253e7b5c3f455ed188efebcec20fe4d1f77148ce984c9866c723c3e645a9e4515b50a67aceb85d45a5
7
+ data.tar.gz: f4764ce73b9c8f696cdd8bfa975ab1f3cbd8d85bb62a3b335a321eb7fb860b08a03835cc875c3dd774b670af3baeffc48f590e53d0c763ccece20e9e22b74657
data/Dockerfile CHANGED
@@ -26,10 +26,10 @@ RUN apk update && apk upgrade
26
26
  RUN apk add build-base bash ruby ruby-etc ruby-dev
27
27
 
28
28
  # Install builtin fonts
29
- RUN gem install invoice_printer_fonts --version 2.1.0 --no-document
29
+ RUN gem install invoice_printer_fonts --version 2.3.0 --no-document
30
30
 
31
31
  # Install the gem from RubyGems.org
32
- RUN gem install invoice_printer_server --version 2.1.0 --no-document
32
+ RUN gem install invoice_printer_server --version 2.3.0 --no-document
33
33
 
34
34
  # Clean APK cache
35
35
  RUN rm -rf /var/cache/apk/*
data/Gemfile.lock CHANGED
@@ -1,12 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- invoice_printer (2.1.0.rc1)
4
+ invoice_printer (2.2.0)
5
+ e2mmap
5
6
  json (~> 2.1)
6
- prawn (~> 2.2)
7
+ matrix
8
+ prawn (~> 2.4)
7
9
  prawn-table (~> 0.2.2)
8
- invoice_printer_server (2.1.0.rc1)
9
- invoice_printer (= 2.1.0.rc1)
10
+ invoice_printer_server (2.2.0)
11
+ invoice_printer (= 2.2.0)
10
12
  json (~> 2.1)
11
13
  puma (>= 3.9.0)
12
14
  roda (~> 3.5)
@@ -14,48 +16,52 @@ PATH
14
16
  GEM
15
17
  remote: https://rubygems.org/
16
18
  specs:
17
- Ascii85 (1.0.3)
19
+ Ascii85 (1.1.0)
18
20
  afm (0.2.2)
19
21
  benchmark_driver (0.15.17)
20
22
  benchmark_driver-output-gruff (0.3.1)
21
23
  benchmark_driver (>= 0.12.0)
22
24
  gruff
23
- gruff (0.11.0)
25
+ e2mmap (0.1.0)
26
+ gruff (0.14.0)
24
27
  histogram
25
28
  rmagick
26
29
  hashery (2.1.2)
27
30
  histogram (0.2.4.1)
28
- json (2.3.1)
29
- minitest (5.14.2)
30
- nio4r (2.5.4)
31
+ json (2.6.3)
32
+ matrix (0.1.0)
33
+ minitest (5.15.0)
34
+ nio4r (2.5.8)
31
35
  pdf-core (0.9.0)
32
36
  pdf-inspector (1.3.0)
33
37
  pdf-reader (>= 1.0, < 3.0.a)
34
- pdf-reader (2.4.1)
35
- Ascii85 (~> 1.0.0)
38
+ pdf-reader (2.11.0)
39
+ Ascii85 (~> 1.0)
36
40
  afm (~> 0.2.1)
37
41
  hashery (~> 2.0)
38
42
  ruby-rc4
39
43
  ttfunk
44
+ pkg-config (1.5.1)
40
45
  prawn (2.4.0)
41
46
  pdf-core (~> 0.9.0)
42
47
  ttfunk (~> 1.7)
43
48
  prawn-table (0.2.2)
44
49
  prawn (>= 1.3.0, < 3.0.0)
45
- puma (5.0.2)
50
+ puma (6.0.2)
46
51
  nio4r (~> 2.0)
47
- rack (2.2.3)
48
- rack-test (1.1.0)
49
- rack (>= 1.0, < 3)
50
- rake (13.0.1)
51
- rmagick (4.1.2)
52
- roda (3.36.0)
52
+ rack (3.0.4.1)
53
+ rack-test (2.0.2)
54
+ rack (>= 1.3)
55
+ rake (13.0.6)
56
+ rmagick (5.1.0)
57
+ pkg-config (~> 1.4)
58
+ roda (3.64.0)
53
59
  rack
54
60
  ruby-rc4 (0.1.5)
55
61
  ttfunk (1.7.0)
56
62
 
57
63
  PLATFORMS
58
- ruby
64
+ x86_64-linux
59
65
 
60
66
  DEPENDENCIES
61
67
  benchmark_driver (= 0.15.17)
@@ -68,4 +74,4 @@ DEPENDENCIES
68
74
  rake (>= 10.0)
69
75
 
70
76
  BUNDLED WITH
71
- 2.1.4
77
+ 2.4.3
data/README.md CHANGED
@@ -25,7 +25,7 @@ See more usecases in the `examples/` directory.
25
25
  - Purchaser and provider boxes with addresses and identificaton numbers
26
26
  - Payment method box showing banking details including SWIFT and IBAN fields
27
27
  - Issue/due dates box
28
- - Configurable items' table with item description, quantity, unit, price per unit, tax and item's total amount fields
28
+ - Configurable items' table with item description, breakdown, quantity, unit, price per unit, tax and item's total amount fields
29
29
  - Final subtotal/tax/total info box
30
30
  - Page numbers
31
31
  - Configurable field labels & sublabels (optional little labels)
Binary file
data/bin/invoice_printer CHANGED
@@ -19,6 +19,7 @@ def show_help
19
19
  -d, --document document as JSON
20
20
  -l, --labels labels as JSON
21
21
  --font path to font or builtin font name
22
+ --bold-font path to bold font or builtin font name
22
23
  -s, --stamp path to stamp
23
24
  --logo path to logotype
24
25
  --background path to background image
@@ -47,6 +48,10 @@ parser = OptionParser.new do|opts|
47
48
  options[:font] = path
48
49
  end
49
50
 
51
+ opts.on('--bold-font PATH') do |path|
52
+ options[:bold_font] = path
53
+ end
54
+
50
55
  opts.on('-s', '--stamp PATH') do |path|
51
56
  options[:stamp] = path
52
57
  end
@@ -116,6 +121,7 @@ begin
116
121
  document: document,
117
122
  labels: labels,
118
123
  font: options[:font],
124
+ bold_font: options[:bold_font],
119
125
  stamp: options[:stamp],
120
126
  logo: options[:logo],
121
127
  background: options[:background],
@@ -130,6 +136,7 @@ begin
130
136
  document: document,
131
137
  labels: labels,
132
138
  font: options[:font],
139
+ bold_font: options[:bold_font],
133
140
  stamp: options[:stamp],
134
141
  logo: options[:logo],
135
142
  file_name: options[:filename],
data/docs/COMMAND_LINE.md CHANGED
@@ -13,6 +13,7 @@ Options:
13
13
  -d, --document document as JSON
14
14
  -l, --labels labels as JSON
15
15
  --font path to font or builtin font name
16
+ --bold-font path to bold font or builtin font name
16
17
  -s, --stamp path to stamp
17
18
  --logo path to logotype
18
19
  --background path to background image
@@ -48,6 +49,7 @@ JSON document with all possible fields filled:
48
49
  "bank_account_number":"156546546465",
49
50
  "account_iban":"IBAN464545645",
50
51
  "account_swift":"SWIFT5456",
52
+ "description": "We are invoicing the following items:",
51
53
  "items":[
52
54
  {
53
55
  "name":"Konzultace",
@@ -139,7 +141,7 @@ All labels:
139
141
 
140
142
  ## Built-in fonts
141
143
 
142
- Supported builtin fonts are: `overpass`, `opensans`, and `roboto`.
144
+ Supported builtin fonts are: `overpass`, `opensans`, and `roboto`. They ship with bold versions.
143
145
 
144
146
  ## Examples
145
147
 
data/docs/LIBRARY.md CHANGED
@@ -31,6 +31,7 @@ Here is an full example for creating the document object:
31
31
  ```ruby
32
32
  item = InvoicePrinter::Document::Item.new(
33
33
  name: 'Web consultation',
34
+ breakdown: 'Excludes 1h free consultation',
34
35
  quantity: nil,
35
36
  unit: 'hours',
36
37
  price: '$ 25',
@@ -64,6 +65,7 @@ invoice = InvoicePrinter::Document.new(
64
65
  bank_account_number: '156546546465',
65
66
  account_iban: 'IBAN464545645',
66
67
  account_swift: 'SWIFT5456',
68
+ description: 'We are invoicing the following items:',
67
69
  items: [item],
68
70
  note: 'A note...'
69
71
  )
data/docs/SERVER.md CHANGED
@@ -61,6 +61,7 @@ Options:
61
61
  - `document` - JSON representation of the document
62
62
  - `labels` - JSON for labels
63
63
  - `font` - path to font file or builtin font name
64
+ - `bold_font` - path to bold font file or builtin font name
64
65
  - `stamp` - path to stamp file
65
66
  - `logo` - path to logotype file
66
67
  - `background` - path to background file
@@ -103,6 +104,7 @@ Options:
103
104
  - `document` - JSON representation of the document
104
105
  - `labels` - JSON for labels
105
106
  - `font` - path to font file or builtin font name
107
+ - `bold_font` - path to bold font file or builtin font name
106
108
  - `stamp` - path to stamp file
107
109
  - `logo` - path to logotype file
108
110
  - `background` - path to background file
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+ # This is an example of a longer invoice.
3
+
4
+ lib = File.expand_path('../../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'invoice_printer'
7
+
8
+ labels = {
9
+ tax: '10% VAT'
10
+ }
11
+
12
+ item = InvoicePrinter::Document::Item.new(
13
+ name: 'Programming',
14
+ quantity: '10',
15
+ unit: 'h',
16
+ price: '$ 60',
17
+ tax: '$ 60',
18
+ amount: '$ 600'
19
+ )
20
+
21
+ item2 = InvoicePrinter::Document::Item.new(
22
+ name: 'Consulting',
23
+ breakdown: "Excludes 1 hour free consultation",
24
+ quantity: '10',
25
+ unit: 'h',
26
+ price: '$ 30',
27
+ tax: '$ 30',
28
+ amount: '$ 300'
29
+ )
30
+
31
+ breakdown = <<BREAKDOWN
32
+ Issue 404: 15h
33
+ Issue 505: 5h
34
+ BREAKDOWN
35
+
36
+ item3 = InvoicePrinter::Document::Item.new(
37
+ name: 'Support',
38
+ breakdown: breakdown,
39
+ quantity: '20',
40
+ unit: 'h',
41
+ price: '$ 15',
42
+ tax: '$ 30',
43
+ amount: '$ 330'
44
+ )
45
+
46
+ invoice = InvoicePrinter::Document.new(
47
+ number: 'NO. 198900000001',
48
+ provider_name: 'John White',
49
+ provider_lines: "79 Stonybrook St.\nBronx, NY 10457",
50
+ purchaser_name: 'Will Black',
51
+ purchaser_lines: "8648 Acacia Rd.\nBrooklyn, NY 11203",
52
+ issue_date: '05/03/2016',
53
+ due_date: '19/03/2016',
54
+ subtotal: '$ 1,000',
55
+ tax: '$ 100',
56
+ total: '$ 1,100',
57
+ bank_account_number: '156546546465',
58
+ items: [item, item2, item3],
59
+ note: 'This is a note at the end.'
60
+ )
61
+
62
+ InvoicePrinter.print(
63
+ document: invoice,
64
+ labels: labels,
65
+ stamp: File.expand_path('../stamp.png', __FILE__),
66
+ logo: File.expand_path('../prawn.png', __FILE__),
67
+ file_name: 'breakdown.pdf'
68
+ )
69
+
70
+ InvoicePrinter.print(
71
+ document: invoice,
72
+ labels: labels,
73
+ stamp: File.expand_path('../stamp.png', __FILE__),
74
+ logo: File.expand_path('../prawn.png', __FILE__),
75
+ file_name: 'breakdown_a4.pdf',
76
+ page_size: :a4
77
+ )
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # This is an example of a very simple invoice.
2
+ # This is an example of a longer invoice.
3
3
 
4
4
  lib = File.expand_path('../../lib', __FILE__)
5
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
@@ -12,7 +12,7 @@ labels = {
12
12
  item = InvoicePrinter::Document::Item.new(
13
13
  name: 'Programming',
14
14
  quantity: '10',
15
- unit: 'hr',
15
+ unit: 'h',
16
16
  price: '$ 60',
17
17
  tax: '$ 60',
18
18
  amount: '$ 600'
@@ -21,7 +21,7 @@ item = InvoicePrinter::Document::Item.new(
21
21
  item2 = InvoicePrinter::Document::Item.new(
22
22
  name: 'Consulting',
23
23
  quantity: '10',
24
- unit: 'hr',
24
+ unit: 'h',
25
25
  price: '$ 30',
26
26
  tax: '$ 30',
27
27
  amount: '$ 300'
@@ -30,7 +30,7 @@ item2 = InvoicePrinter::Document::Item.new(
30
30
  item3 = InvoicePrinter::Document::Item.new(
31
31
  name: 'Support',
32
32
  quantity: '20',
33
- unit: 'hr',
33
+ unit: 'h',
34
34
  price: '$ 15',
35
35
  tax: '$ 30',
36
36
  amount: '$ 330'
data/examples/promo.rb CHANGED
@@ -80,6 +80,7 @@ InvoicePrinter.print(
80
80
  document: invoice,
81
81
  labels: labels,
82
82
  font: File.expand_path('../../assets/fonts/overpass/Overpass-Regular.ttf', __FILE__),
83
+ bold_font: File.expand_path('../../assets/fonts/overpass/Overpass-Bold.ttf', __FILE__),
83
84
  logo: File.expand_path('../logo.png', __FILE__),
84
85
  file_name: 'promo.pdf'
85
86
  )
@@ -88,6 +89,7 @@ InvoicePrinter.print(
88
89
  document: invoice,
89
90
  labels: labels,
90
91
  font: File.expand_path('../../assets/fonts/overpass/Overpass-Regular.ttf', __FILE__),
92
+ bold_font: File.expand_path('../../assets/fonts/overpass/Overpass-Bold.ttf', __FILE__),
91
93
  logo: File.expand_path('../logo.png', __FILE__),
92
94
  file_name: 'promo_a4.pdf',
93
95
  page_size: :a4
@@ -27,11 +27,13 @@ invoice = InvoicePrinter::Document.new(
27
27
  number: 'NO. 198900000001',
28
28
  provider_name: 'John White',
29
29
  provider_lines: provider_address,
30
+ purchaser_name: 'Will Black',
30
31
  purchaser_lines: purchaser_address,
31
32
  issue_date: '05/03/2016',
32
33
  due_date: '19/03/2016',
33
34
  total: '$ 900',
34
35
  bank_account_number: '156546546465',
36
+ description: "You can use 20% discount for the next order with the code:\nDISCOUNT",
35
37
  items: [item],
36
38
  note: "This is a note at the end.\nA note with two lines."
37
39
  )
@@ -45,8 +45,10 @@ Gem::Specification.new do |spec|
45
45
  spec.required_ruby_version = '>= 2.4'
46
46
 
47
47
  spec.add_dependency 'json', '~> 2.1'
48
- spec.add_dependency 'prawn', '~> 2.2'
48
+ spec.add_dependency 'prawn', '~> 2.4'
49
49
  spec.add_dependency 'prawn-table', '~> 0.2.2'
50
+ spec.add_dependency 'matrix'
51
+ spec.add_dependency 'e2mmap'
50
52
 
51
53
  spec.add_development_dependency 'bundler', '>= 1.7'
52
54
  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
 
@@ -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
 
@@ -22,6 +22,7 @@ module InvoicePrinter
22
22
  # bank_account_number: '156546546465',
23
23
  # account_iban: 'IBAN464545645',
24
24
  # account_swift: 'SWIFT5456',
25
+ # description: "We are invoicing you the following items:",
25
26
  # items: [
26
27
  # InvoicePrinter::Document::Item.new,
27
28
  # InvoicePrinter::Document::Item.new
@@ -57,6 +58,7 @@ module InvoicePrinter
57
58
  :bank_account_number,
58
59
  :account_iban,
59
60
  :account_swift,
61
+ :description,
60
62
  # Collection of InvoicePrinter::Invoice::Items
61
63
  :items,
62
64
  :note
@@ -84,6 +86,7 @@ module InvoicePrinter
84
86
  bank_account_number: json['bank_account_number'],
85
87
  account_iban: json['account_iban'],
86
88
  account_swift: json['account_swift'],
89
+ description: json['description'],
87
90
  note: json['note'],
88
91
 
89
92
  items: (json['items'] || []).map { |item_json| Item.from_json(item_json) }
@@ -111,6 +114,7 @@ module InvoicePrinter
111
114
  bank_account_number: nil,
112
115
  account_iban: nil,
113
116
  account_swift: nil,
117
+ description: nil,
114
118
  items: nil,
115
119
  note: nil)
116
120
 
@@ -134,6 +138,7 @@ module InvoicePrinter
134
138
  @bank_account_number = String(bank_account_number)
135
139
  @account_iban = String(account_iban)
136
140
  @account_swift = String(account_swift)
141
+ @description = String(description)
137
142
  @items = items
138
143
  @note = String(note)
139
144
 
@@ -163,6 +168,7 @@ module InvoicePrinter
163
168
  'bank_account_number': @bank_account_number,
164
169
  'account_iban': @account_iban,
165
170
  'account_swift': @account_swift,
171
+ 'description': @description,
166
172
  'items': @items.map(&:to_h),
167
173
  'note': @note
168
174
  }
@@ -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',
@@ -66,10 +67,20 @@ module InvoicePrinter
66
67
  @@labels = DEFAULT_LABELS.merge(labels)
67
68
  end
68
69
 
69
- 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
+ )
70
80
  @document = document
71
81
  @labels = merge_custom_labels(labels)
72
82
  @font = font
83
+ @bold_font = bold_font
73
84
  @stamp = stamp
74
85
  @logo = logo
75
86
  @page_size = page_size ? PAGE_SIZES[page_size.to_sym] : PAGE_SIZES[:letter]
@@ -94,8 +105,10 @@ module InvoicePrinter
94
105
  end
95
106
  end
96
107
 
97
- if used? @font
98
- use_font(@font)
108
+ if used?(@font) && used?(@bold_font)
109
+ use_font(@font, @bold_font)
110
+ elsif used?(@font)
111
+ use_font(@font, @font)
99
112
  end
100
113
 
101
114
  build_pdf
@@ -113,11 +126,11 @@ module InvoicePrinter
113
126
 
114
127
  private
115
128
 
116
- def use_font(font)
117
- if File.exist?(@font)
118
- 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)
119
132
  else
120
- set_builtin_font(@font)
133
+ set_builtin_font(font)
121
134
  end
122
135
  end
123
136
 
@@ -134,14 +147,14 @@ module InvoicePrinter
134
147
  end
135
148
 
136
149
  # Add font family in Prawn for a given +font+ file
137
- def set_font_from_path(font)
150
+ def set_font_from_path(font, bold_font)
138
151
  font_name = Pathname.new(font).basename
139
152
  @pdf.font_families.update(
140
153
  "#{font_name}" => {
141
154
  normal: font,
142
155
  italic: font,
143
- bold: font,
144
- bold_italic: font
156
+ bold: bold_font,
157
+ bold_italic: bold_font
145
158
  }
146
159
  )
147
160
  @pdf.font(font_name)
@@ -158,6 +171,7 @@ module InvoicePrinter
158
171
  build_purchaser_box
159
172
  build_payment_method_box
160
173
  build_info_box
174
+ build_description
161
175
  build_items
162
176
  build_total
163
177
  build_stamp
@@ -241,18 +255,14 @@ module InvoicePrinter
241
255
  end
242
256
  # Render provider_lines if present
243
257
  if !@document.provider_lines.empty?
244
- lines = @document.provider_lines.split("\n")
245
- line_y = 618
246
- lines.each_with_index do |line, index|
247
- next if index > 3
248
-
249
- @pdf.text_box(
250
- "#{line}",
251
- size: 10,
252
- at: [10, y(line_y - index*15) - @push_down],
253
- width: x(240)
254
- )
255
- end
258
+ @pdf.text_box(
259
+ @document.provider_lines,
260
+ size: 10,
261
+ at: [x(10), y(618) - @push_down],
262
+ width: x(246),
263
+ height: y(68),
264
+ leading: 3,
265
+ )
256
266
  end
257
267
  unless @document.provider_tax_id.empty?
258
268
  @pdf.text_box(
@@ -311,18 +321,14 @@ module InvoicePrinter
311
321
  end
312
322
  # Render purchaser_lines if present
313
323
  if !@document.purchaser_lines.empty?
314
- lines = @document.purchaser_lines.split("\n")
315
- line_y = 618
316
- lines.each_with_index do |line, index|
317
- next if index > 3
318
-
319
- @pdf.text_box(
320
- "#{line}",
321
- size: 10,
322
- at: [x(284), y(line_y - index*15) - @push_down],
323
- width: x(240)
324
- )
325
- end
324
+ @pdf.text_box(
325
+ @document.purchaser_lines,
326
+ size: 10,
327
+ at: [x(284), y(618) - @push_down],
328
+ width: x(246),
329
+ height: y(68),
330
+ leading: 3,
331
+ )
326
332
  end
327
333
  unless @document.purchaser_tax_id.empty?
328
334
  @pdf.text_box(
@@ -637,6 +643,25 @@ module InvoicePrinter
637
643
  used?(@labels[:sublabels][:variable_symbol])
638
644
  end
639
645
 
646
+ def build_description
647
+ unless @document.description.empty?
648
+ @pdf.text_box(
649
+ @document.description,
650
+ size: 11,
651
+ align: :left,
652
+ at: [0, y(450) - @push_down - 26]
653
+ )
654
+ @push_items_table += description_height + 8
655
+ end
656
+ end
657
+
658
+ def description_height
659
+ @description_height ||= begin
660
+ num_of_lines = @document.description.lines.count
661
+ (num_of_lines * 13)
662
+ end
663
+ end
664
+
640
665
  # Build the following table for document items:
641
666
  #
642
667
  # =================================================================
@@ -708,7 +733,8 @@ module InvoicePrinter
708
733
  def build_items_data(items_params)
709
734
  @document.items.map do |item|
710
735
  line = []
711
- line << { content: item.name, borders: [:bottom], align: :left } if items_params[:names]
736
+ line << { content: name_cell(item), borders: [:bottom] } if items_params[:names]
737
+ #line << { content: item.name, borders: [:bottom], align: :left } if items_params[:names]
712
738
  line << { content: item.variable, align: :right } if items_params[:variables]
713
739
  line << { content: item.quantity, align: :right } if items_params[:quantities]
714
740
  line << { content: item.unit, align: :right } if items_params[:units]
@@ -721,6 +747,27 @@ module InvoicePrinter
721
747
  end
722
748
  end
723
749
 
750
+ # Display item's name and breakdown if present
751
+ def name_cell(item)
752
+ data = if used?(item.breakdown)
753
+ data = [
754
+ [{ content: item.name, padding: [5, 0, 0, 5] }],
755
+ [{ content: item.breakdown, size: 8, padding: [2, 0, 5, 5] }]
756
+ ]
757
+
758
+ options = {
759
+ cell_style: {
760
+ borders: []
761
+ },
762
+ position: :left
763
+ }
764
+
765
+ @pdf.make_table(data, options)
766
+ else
767
+ item.name
768
+ end
769
+ end
770
+
724
771
  # Include only relevant headers
725
772
  def build_items_header(items_params)
726
773
  headers = []
@@ -759,52 +806,40 @@ module InvoicePrinter
759
806
  @pdf.move_down(25)
760
807
 
761
808
  items = []
762
- items << [{ content: "#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", align: :right }, @document.subtotal] \
763
- unless @document.subtotal.empty?
764
- items << [{ content: "#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", align: :right }, @document.tax] \
765
- unless @document.tax.empty?
766
- items << [{ content: "#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", align: :right }, @document.tax2] \
767
- unless @document.tax2.empty?
768
- items << [{ content: "#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", align: :right }, @document.tax3] \
769
- unless @document.tax3.empty?
770
-
771
- width = [
772
- "#{@labels[:subtotal]}#{@document.subtotal}".size,
773
- "#{@labels[:tax]}#{@document.tax}".size,
774
- "#{@labels[:tax2]}#{@document.tax2}".size,
775
- "#{@labels[:tax3]}#{@document.tax3}".size
776
- ].max * 8
777
809
 
778
- options = {
779
- cell_style: {
780
- borders: []
781
- }
782
- }
810
+ items << [
811
+ { content: "#{@labels[:subtotal]}:#{build_sublabel_for_total_table(:subtotal)}", align: :left },
812
+ { content: @document.subtotal, align: :right }
813
+ ] unless @document.subtotal.empty?
783
814
 
784
- @pdf.span(x(width), position: :right) do
785
- @pdf.table(items, options) unless items.empty?
786
- end
815
+ items << [
816
+ { content: "#{@labels[:tax]}:#{build_sublabel_for_total_table(:tax)}", align: :left },
817
+ { content: @document.tax, align: :right }
818
+ ] unless @document.tax.empty?
787
819
 
788
- @pdf.move_down(15)
820
+ items << [
821
+ { content: "#{@labels[:tax2]}:#{build_sublabel_for_total_table(:tax2)}", align: :left },
822
+ { content: @document.tax2, align: :right }
823
+ ] unless @document.tax2.empty?
789
824
 
790
- unless @document.total.empty?
791
- @pdf.text(
792
- "#{@labels[:total]}: #{@document.total}",
793
- size: 16,
794
- align: :right,
795
- style: :bold
796
- )
825
+ items << [
826
+ { content: "#{@labels[:tax3]}:#{build_sublabel_for_total_table(:tax3)}", align: :left },
827
+ { content: @document.tax3, align: :right }
828
+ ] unless @document.tax3.empty?
797
829
 
798
- @pdf.move_down(5)
830
+ items << [
831
+ { content: "\n#{@labels[:total]}:#{build_sublabel_for_total_table(:total)}", align: :left, font_style: :bold, size: 16 },
832
+ { content: "\n#{@document.total}", align: :right, font_style: :bold, size: 16 }
833
+ ] unless @document.total.empty?
799
834
 
800
- if used? @labels[:sublabels][:total]
801
- @pdf.text(
802
- "#{@labels[:sublabels][:total]}: #{@document.total}",
803
- size: 12,
804
- align: :right
805
- )
806
- end
807
- end
835
+ options = {
836
+ cell_style: {
837
+ borders: []
838
+ },
839
+ position: :right
840
+ }
841
+
842
+ @pdf.table(items, options) unless items.empty?
808
843
  end
809
844
 
810
845
  # Return sublabel on a new line or empty string
@@ -822,7 +857,7 @@ module InvoicePrinter
822
857
  def build_logo
823
858
  if @logo && !@logo.empty?
824
859
  bottom = @document.note.empty? ? 75 : (75 + note_height)
825
- @pdf.image(@logo, at: [0, bottom], fit: [200, 50])
860
+ @pdf.image(@logo, at: [0, bottom], fit: [x(200), y(50)])
826
861
  end
827
862
  end
828
863
 
@@ -830,7 +865,7 @@ module InvoicePrinter
830
865
  def build_stamp
831
866
  if @stamp && !@stamp.empty?
832
867
  @pdf.move_down(15)
833
- @pdf.image(@stamp, position: :right)
868
+ @pdf.image(@stamp, position: :right, fit: [x(200), y(40)])
834
869
  end
835
870
  end
836
871
 
@@ -1,3 +1,3 @@
1
1
  module InvoicePrinter
2
- VERSION = '2.2.0.alpha1'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -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'
@@ -65,16 +66,28 @@ module InvoicePrinter
65
66
  # document - InvoicePrinter::Document object
66
67
  # labels - labels to override
67
68
  # font - font file to use
69
+ # bold_font - bold font file to use
68
70
  # stamp - stamp & signature (image)
69
71
  # logo - logotype (image)
70
72
  # background - background (image)
71
73
  # page_size - :letter or :a4
72
74
  # file_name - output file
73
- 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
+ )
74
86
  PDFDocument.new(
75
87
  document: document,
76
88
  labels: labels,
77
89
  font: font,
90
+ bold_font: bold_font,
78
91
  stamp: stamp,
79
92
  logo: logo,
80
93
  background: background,
@@ -87,15 +100,26 @@ module InvoicePrinter
87
100
  # document - InvoicePrinter::Document object
88
101
  # labels - labels to override
89
102
  # font - font file to use
103
+ # bold_font - bold font file to use
90
104
  # stamp - stamp & signature (image)
91
105
  # logo - logotype (image)
92
106
  # background - background (image)
93
107
  # page_size - :letter or :a4
94
- 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
+ )
95
118
  PDFDocument.new(
96
119
  document: document,
97
120
  labels: labels,
98
121
  font: font,
122
+ bold_font: bold_font,
99
123
  stamp: stamp,
100
124
  logo: logo,
101
125
  background: background,
data/regenerate.rb ADDED
@@ -0,0 +1,10 @@
1
+ # Script to regenerate all examples
2
+ examples_directory = File.expand_path('../examples', __FILE__)
3
+ @examples = Dir.glob("#{examples_directory}/*.rb")
4
+
5
+ @examples.each do |example|
6
+ puts "Running #{example}"
7
+ Dir.chdir(examples_directory) do
8
+ `ruby #{example}`
9
+ end
10
+ end
@@ -4,10 +4,12 @@ require 'test_helper'
4
4
  class ExamplesTest < Minitest::Test
5
5
  def setup
6
6
  examples_directory = File.expand_path('../../examples', __FILE__)
7
+ assets_directory = File.expand_path('../../assets', __FILE__)
7
8
  @examples = Dir.glob("#{examples_directory}/*.rb")
8
9
  @test_dir = File.absolute_path('./tmp/invoice_printer_examples')
9
10
  FileUtils.mkdir_p @test_dir
10
11
  FileUtils.copy_entry examples_directory, @test_dir
12
+ FileUtils.cp_r assets_directory, File.absolute_path('./tmp/')
11
13
  end
12
14
 
13
15
  def teardown
data/test/test_ext.rb CHANGED
@@ -101,7 +101,8 @@ module InvoicePrinter
101
101
  strings << @document.tax2
102
102
  strings << "#{@labels[:tax3]}:"
103
103
  strings << @document.tax3
104
- strings << "#{@labels[:total]}: #{@document.total}"
104
+ strings << "#{@labels[:total]}:"
105
+ strings << @document.total
105
106
  strings
106
107
  end
107
108
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: invoice_printer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0.alpha1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josef Strzibny
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-16 00:00:00.000000000 Z
11
+ date: 2023-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.2'
33
+ version: '2.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.2'
40
+ version: '2.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: prawn-table
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.2.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: matrix
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: e2mmap
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
55
83
  - !ruby/object:Gem::Dependency
56
84
  name: bundler
57
85
  requirement: !ruby/object:Gem::Requirement
@@ -95,12 +123,16 @@ files:
95
123
  - LICENSE.txt
96
124
  - README.md
97
125
  - Rakefile
126
+ - assets/fonts/opensans/OpenSans-Bold.ttf
127
+ - assets/fonts/overpass/Overpass-Bold.ttf
128
+ - assets/fonts/roboto/Roboto-Bold.ttf
98
129
  - benchmarks/render.yml
99
130
  - bin/invoice_printer
100
131
  - docs/COMMAND_LINE.md
101
132
  - docs/INSTALLATION.md
102
133
  - docs/LIBRARY.md
103
134
  - docs/SERVER.md
135
+ - examples/breakdown.rb
104
136
  - examples/clients/node.js
105
137
  - examples/complex_invoice.rb
106
138
  - examples/czech_invoice.rb
@@ -120,6 +152,7 @@ files:
120
152
  - lib/invoice_printer/document/item.rb
121
153
  - lib/invoice_printer/pdf_document.rb
122
154
  - lib/invoice_printer/version.rb
155
+ - regenerate.rb
123
156
  - test/api_test.rb
124
157
  - test/background_test.rb
125
158
  - test/cli_test.rb
@@ -138,7 +171,7 @@ homepage: https://github.com/strzibny/invoice_printer
138
171
  licenses:
139
172
  - MIT
140
173
  metadata: {}
141
- post_install_message:
174
+ post_install_message:
142
175
  rdoc_options: []
143
176
  require_paths:
144
177
  - lib
@@ -149,12 +182,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
182
  version: '2.4'
150
183
  required_rubygems_version: !ruby/object:Gem::Requirement
151
184
  requirements:
152
- - - ">"
185
+ - - ">="
153
186
  - !ruby/object:Gem::Version
154
- version: 1.3.1
187
+ version: '0'
155
188
  requirements: []
156
- rubygems_version: 3.2.0.rc.1
157
- signing_key:
189
+ rubygems_version: 3.3.3
190
+ signing_key:
158
191
  specification_version: 4
159
192
  summary: Super simple PDF invoicing in pure Ruby
160
193
  test_files: