invoice_printer 2.2.0.alpha1 → 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.
- checksums.yaml +4 -4
- data/Dockerfile +2 -2
- data/Gemfile.lock +7 -7
- data/README.md +1 -1
- data/assets/fonts/opensans/OpenSans-Bold.ttf +0 -0
- data/assets/fonts/overpass/Overpass-Bold.ttf +0 -0
- data/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
- data/bin/invoice_printer +7 -0
- data/docs/COMMAND_LINE.md +2 -1
- data/docs/LIBRARY.md +1 -0
- data/docs/SERVER.md +2 -0
- data/examples/breakdown.rb +77 -0
- data/examples/long_invoice.rb +4 -4
- data/examples/promo.rb +2 -0
- data/invoice_printer_fonts.gemspec +3 -0
- data/lib/invoice_printer.rb +26 -2
- data/lib/invoice_printer/document/item.rb +34 -28
- data/lib/invoice_printer/pdf_document.rb +75 -52
- data/lib/invoice_printer/version.rb +1 -1
- data/test/examples_test.rb +2 -0
- data/test/test_ext.rb +2 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33a87300d4ff6a12080b758ea012b7c94a09521575c99579e300844dbfbf0e47
|
4
|
+
data.tar.gz: 33446dc1314512a7793ad95b73065dfb59abef1963e5c115fab5263e2dd53ecc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef29b3e26227c6cbeba87fca78154d55a7bb103472f77991fe1a4df24f30a36efa75db3f7f724ddd17a369713870db6d20bd93ea33d0812fb55501bbba9c7ea2
|
7
|
+
data.tar.gz: 6c93d97f040190c555dcbdaf742e05d904a00bd458e2f68009dd1191ec3bf190fe92e20033bb19e0ae3337f6e10686361922b05bcfcc6316e86f8bb46b7a0cbf
|
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.
|
29
|
+
RUN gem install invoice_printer_fonts --version 2.2.0 --no-document
|
30
30
|
|
31
31
|
# Install the gem from RubyGems.org
|
32
|
-
RUN gem install invoice_printer_server --version 2.
|
32
|
+
RUN gem install invoice_printer_server --version 2.2.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,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
invoice_printer (2.
|
4
|
+
invoice_printer (2.2.0)
|
5
5
|
json (~> 2.1)
|
6
6
|
prawn (~> 2.2)
|
7
7
|
prawn-table (~> 0.2.2)
|
8
|
-
invoice_printer_server (2.
|
9
|
-
invoice_printer (= 2.
|
8
|
+
invoice_printer_server (2.2.0)
|
9
|
+
invoice_printer (= 2.2.0)
|
10
10
|
json (~> 2.1)
|
11
11
|
puma (>= 3.9.0)
|
12
12
|
roda (~> 3.5)
|
@@ -25,9 +25,9 @@ GEM
|
|
25
25
|
rmagick
|
26
26
|
hashery (2.1.2)
|
27
27
|
histogram (0.2.4.1)
|
28
|
-
json (2.
|
28
|
+
json (2.5.1)
|
29
29
|
minitest (5.14.2)
|
30
|
-
nio4r (2.5.
|
30
|
+
nio4r (2.5.7)
|
31
31
|
pdf-core (0.9.0)
|
32
32
|
pdf-inspector (1.3.0)
|
33
33
|
pdf-reader (>= 1.0, < 3.0.a)
|
@@ -42,14 +42,14 @@ GEM
|
|
42
42
|
ttfunk (~> 1.7)
|
43
43
|
prawn-table (0.2.2)
|
44
44
|
prawn (>= 1.3.0, < 3.0.0)
|
45
|
-
puma (5.
|
45
|
+
puma (5.3.2)
|
46
46
|
nio4r (~> 2.0)
|
47
47
|
rack (2.2.3)
|
48
48
|
rack-test (1.1.0)
|
49
49
|
rack (>= 1.0, < 3)
|
50
50
|
rake (13.0.1)
|
51
51
|
rmagick (4.1.2)
|
52
|
-
roda (3.
|
52
|
+
roda (3.45.0)
|
53
53
|
rack
|
54
54
|
ruby-rc4 (0.1.5)
|
55
55
|
ttfunk (1.7.0)
|
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
|
Binary file
|
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
|
@@ -139,7 +140,7 @@ All labels:
|
|
139
140
|
|
140
141
|
## Built-in fonts
|
141
142
|
|
142
|
-
Supported builtin fonts are: `overpass`, `opensans`, and `roboto`.
|
143
|
+
Supported builtin fonts are: `overpass`, `opensans`, and `roboto`. They ship with bold versions.
|
143
144
|
|
144
145
|
## Examples
|
145
146
|
|
data/docs/LIBRARY.md
CHANGED
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
|
+
)
|
data/examples/long_invoice.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# This is an example of a
|
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: '
|
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: '
|
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: '
|
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
|
@@ -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
|
|
data/lib/invoice_printer.rb
CHANGED
@@ -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(
|
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(
|
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,
|
@@ -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:
|
35
|
+
name: json['name'],
|
36
|
+
breakdown: json['breakdown'],
|
34
37
|
variable: json['variable'],
|
35
38
|
quantity: json['quantity'],
|
36
|
-
unit:
|
37
|
-
price:
|
38
|
-
tax:
|
39
|
-
tax2:
|
40
|
-
tax3:
|
41
|
-
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:
|
49
|
+
def initialize(name: nil,
|
50
|
+
breakdown: nil,
|
47
51
|
variable: nil,
|
48
52
|
quantity: nil,
|
49
|
-
unit:
|
50
|
-
price:
|
51
|
-
tax:
|
52
|
-
tax2:
|
53
|
-
tax3:
|
54
|
-
amount:
|
53
|
+
unit: nil,
|
54
|
+
price: nil,
|
55
|
+
tax: nil,
|
56
|
+
tax2: nil,
|
57
|
+
tax3: nil,
|
58
|
+
amount: nil)
|
55
59
|
|
56
|
-
@name
|
60
|
+
@name = String(name)
|
61
|
+
@breakdown = String(breakdown)
|
57
62
|
@variable = String(variable)
|
58
63
|
@quantity = String(quantity)
|
59
|
-
@unit
|
60
|
-
@price
|
61
|
-
@tax
|
62
|
-
@tax2
|
63
|
-
@tax3
|
64
|
-
@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':
|
74
|
+
'name': @name,
|
75
|
+
'breakdown': @breakdown,
|
70
76
|
'variable': @variable,
|
71
77
|
'quantity': @quantity,
|
72
|
-
'unit':
|
73
|
-
'price':
|
74
|
-
'tax':
|
75
|
-
'tax2':
|
76
|
-
'tax3':
|
77
|
-
'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
|
|
@@ -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(
|
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? @
|
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?(
|
118
|
-
set_font_from_path(
|
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(
|
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:
|
144
|
-
bold_italic:
|
156
|
+
bold: bold_font,
|
157
|
+
bold_italic: bold_font
|
145
158
|
}
|
146
159
|
)
|
147
160
|
@pdf.font(font_name)
|
@@ -708,7 +721,8 @@ module InvoicePrinter
|
|
708
721
|
def build_items_data(items_params)
|
709
722
|
@document.items.map do |item|
|
710
723
|
line = []
|
711
|
-
line << { content: item
|
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]
|
712
726
|
line << { content: item.variable, align: :right } if items_params[:variables]
|
713
727
|
line << { content: item.quantity, align: :right } if items_params[:quantities]
|
714
728
|
line << { content: item.unit, align: :right } if items_params[:units]
|
@@ -721,6 +735,27 @@ module InvoicePrinter
|
|
721
735
|
end
|
722
736
|
end
|
723
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
|
+
|
724
759
|
# Include only relevant headers
|
725
760
|
def build_items_header(items_params)
|
726
761
|
headers = []
|
@@ -759,52 +794,40 @@ module InvoicePrinter
|
|
759
794
|
@pdf.move_down(25)
|
760
795
|
|
761
796
|
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
797
|
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
}
|
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?
|
783
802
|
|
784
|
-
|
785
|
-
@
|
786
|
-
|
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?
|
787
807
|
|
788
|
-
|
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?
|
789
812
|
|
790
|
-
|
791
|
-
@
|
792
|
-
|
793
|
-
|
794
|
-
align: :right,
|
795
|
-
style: :bold
|
796
|
-
)
|
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?
|
797
817
|
|
798
|
-
|
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?
|
799
822
|
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
823
|
+
options = {
|
824
|
+
cell_style: {
|
825
|
+
borders: []
|
826
|
+
},
|
827
|
+
position: :right
|
828
|
+
}
|
829
|
+
|
830
|
+
@pdf.table(items, options) unless items.empty?
|
808
831
|
end
|
809
832
|
|
810
833
|
# Return sublabel on a new line or empty string
|
data/test/examples_test.rb
CHANGED
@@ -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]}:
|
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
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josef Strzibny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -95,12 +95,16 @@ files:
|
|
95
95
|
- LICENSE.txt
|
96
96
|
- README.md
|
97
97
|
- Rakefile
|
98
|
+
- assets/fonts/opensans/OpenSans-Bold.ttf
|
99
|
+
- assets/fonts/overpass/Overpass-Bold.ttf
|
100
|
+
- assets/fonts/roboto/Roboto-Bold.ttf
|
98
101
|
- benchmarks/render.yml
|
99
102
|
- bin/invoice_printer
|
100
103
|
- docs/COMMAND_LINE.md
|
101
104
|
- docs/INSTALLATION.md
|
102
105
|
- docs/LIBRARY.md
|
103
106
|
- docs/SERVER.md
|
107
|
+
- examples/breakdown.rb
|
104
108
|
- examples/clients/node.js
|
105
109
|
- examples/complex_invoice.rb
|
106
110
|
- examples/czech_invoice.rb
|
@@ -149,11 +153,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
149
153
|
version: '2.4'
|
150
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
155
|
requirements:
|
152
|
-
- - "
|
156
|
+
- - ">="
|
153
157
|
- !ruby/object:Gem::Version
|
154
|
-
version:
|
158
|
+
version: '0'
|
155
159
|
requirements: []
|
156
|
-
rubygems_version: 3.2.
|
160
|
+
rubygems_version: 3.2.3
|
157
161
|
signing_key:
|
158
162
|
specification_version: 4
|
159
163
|
summary: Super simple PDF invoicing in pure Ruby
|