ubill 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e23f48847054bf7e4f64599585d697f2eb918f13cb080a21818cc27c6da88738
4
+ data.tar.gz: 5043034a212d8766fa4a0d1f400fbb92c7507656472e7ad40313165bfaddab7a
5
+ SHA512:
6
+ metadata.gz: b38c22365eebd461ed42f8ab2cc671abaa0f37bf821ad9ead7dd11645d7f9805b07a595aeabdab40fea01576ad2c066f7dd92c96685444ea9bdb3278da6b176b
7
+ data.tar.gz: f921dc75d70feae1d634c9f51625eceef7414d5e905a7fd3ee35e82ed45cc8e6c0b043fdc4a2fedc0627deeb7ba3d5a32b5cd9997cadca4678c4b913dfaf536e
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in ubill.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+ gem "rspec", "~> 3.0"
10
+ gem "ruby-debug-ide", require: false
11
+ gem "debase", "0.2.5.beta2", require: false
data/Gemfile.lock ADDED
@@ -0,0 +1,52 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ubill (0.1.0)
5
+ matrix (~> 0.4)
6
+ prawn (~> 2.4)
7
+ prawn-table (~> 0.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ debase (0.2.5.beta2)
13
+ debase-ruby_core_source (>= 0.10.12)
14
+ debase-ruby_core_source (3.2.0)
15
+ diff-lcs (1.5.0)
16
+ matrix (0.4.2)
17
+ pdf-core (0.9.0)
18
+ prawn (2.4.0)
19
+ pdf-core (~> 0.9.0)
20
+ ttfunk (~> 1.7)
21
+ prawn-table (0.2.2)
22
+ prawn (>= 1.3.0, < 3.0.0)
23
+ rake (13.0.6)
24
+ rspec (3.12.0)
25
+ rspec-core (~> 3.12.0)
26
+ rspec-expectations (~> 3.12.0)
27
+ rspec-mocks (~> 3.12.0)
28
+ rspec-core (3.12.2)
29
+ rspec-support (~> 3.12.0)
30
+ rspec-expectations (3.12.3)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.12.0)
33
+ rspec-mocks (3.12.5)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.12.0)
36
+ rspec-support (3.12.0)
37
+ ruby-debug-ide (0.7.3)
38
+ rake (>= 0.8.1)
39
+ ttfunk (1.7.0)
40
+
41
+ PLATFORMS
42
+ x86_64-linux
43
+
44
+ DEPENDENCIES
45
+ debase (= 0.2.5.beta2)
46
+ rake (~> 13.0)
47
+ rspec (~> 3.0)
48
+ ruby-debug-ide
49
+ ubill!
50
+
51
+ BUNDLED WITH
52
+ 2.4.10
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 couchbelag
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # Ubill
2
+
3
+ PDF Invoice generator.
4
+
5
+
6
+ ## Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ ```bash
11
+ $ bundle add ubill
12
+ ```
13
+
14
+ If bundler is not being used to manage dependencies, install the gem by executing:
15
+
16
+ ```bash
17
+ $ gem install ubill
18
+ ```
19
+
20
+
21
+ ## Configuration
22
+
23
+ Configuration must to be executed only once! Put it into a rails initializer if possible.
24
+
25
+ ```ruby
26
+ # configure pdf invoice generation
27
+ Ubill.configure do
28
+ page_size "A4"
29
+ footer.configure do
30
+ # add one or more lines to footer
31
+ add_line do
32
+ # add items to a line in the footer,
33
+ # items will be separated by dots
34
+ append "rechnung GmbH", styles: [:bold]
35
+ append "Mattermoststraße 23"
36
+ append "12345 Demoburg"
37
+ append "info@example.org"
38
+ append "www.example.org"
39
+ end
40
+ add_line do
41
+ append "Geschäftsführer Fried Hof, Holger Manen, Manfred Erike"
42
+ end
43
+ add_line do
44
+ append "HRB 4711"
45
+ append "Amtsgericht Jurahausen"
46
+ append "Steuernummer 123/456/78900"
47
+ end
48
+ end
49
+ header.configure do
50
+ # header's left should be set to company name
51
+ # header's right should contain sender address
52
+ left "rechnung GmbH"
53
+ right do
54
+ append "Mattermoststraße 23"
55
+ append "12345 Demoburg"
56
+ append "info@example.org"
57
+ end
58
+ end
59
+ account.configure do
60
+ # configure bank account to which payments
61
+ # should be sent
62
+ recipient "rechnung GmbH"
63
+ iban "DE081547114200"
64
+ bic "ACCOUNTXXX"
65
+ end
66
+ end
67
+ ```
68
+
69
+
70
+ ## Usage
71
+
72
+ ```ruby
73
+ # Instantiate a new Invoice, this will use the
74
+ # settings configured above.
75
+ doc = Ubill::Invoice.new do
76
+ # subject of the invoice, most probably that's
77
+ # the invoice number. an additional info can be
78
+ # provided which will be displayed just below subject
79
+ # in a smaller font size
80
+ subject("Rechnung R1234567890", "Rechnungsdatum 01.01.2100")
81
+ # recipient address
82
+ recipient(
83
+ company: "Spielvereinigung Demoburg e.V.",
84
+ name: "Tobi Ornottobi",
85
+ department: "Dept. Purchase",
86
+ street_1: "Highwaytohell 2",
87
+ street_2: "Room 3.12",
88
+ zip: "12345",
89
+ city: "Coruscant",
90
+ country: "Galactic Empire"
91
+ )
92
+ # add positions to invoice. prices, units or any other
93
+ # numbers should be provided as strings, as we do not
94
+ # interpret numbers with locale settings. There is also
95
+ # no summing up of positions to totals! you have to
96
+ # calculate and provide totals all by yourselves!
97
+ 4.times do |idx|
98
+ position(
99
+ # name, context and description are rendered into
100
+ # one cell in the table as consecutive lines
101
+ name: "Standard Abonnement",
102
+ context: "SpVgg Demoburg -- Platz #{idx+1}",
103
+ description: "Standard Abonnement für ein Jahr",
104
+ price_per_unit: "7,50 € / Monat",
105
+ units: "12",
106
+ price: "90,00 €"
107
+ )
108
+ end
109
+ # you have to calculate and provide totals all by yourselves!
110
+ total "180,00 €"
111
+ due "24.12.2100"
112
+ end
113
+
114
+ # save document
115
+ doc.save_as("invoice.pdf")
116
+ ```
117
+
118
+ ## License
119
+
120
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
9
+
10
+ desc "returns current version number as defined in lib/ubil/version.rb"
11
+ task :version do
12
+ puts Ubill::VERSION
13
+ end
data/lib/hash.rb ADDED
@@ -0,0 +1,19 @@
1
+ class Hash
2
+ def each_with_filter(*filter, &block)
3
+ filter.each do |key|
4
+ if key.is_a?(Array)
5
+ values = key.map do |k|
6
+ self.fetch(k) if has_key?(k)
7
+ end
8
+ values.compact!
9
+ block.call(key, values.join(" "))
10
+ else
11
+ with(key, &block)
12
+ end
13
+ end
14
+ end
15
+
16
+ def with(key)
17
+ yield(key, fetch(key)) if has_key?(key)
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "line"
2
+
3
+ module Ubill
4
+ class Account
5
+ include Ubill::Concerns::Configurable
6
+
7
+ def recipient(value=nil)
8
+ @recipient = value unless value.nil?
9
+ @recipient
10
+ end
11
+
12
+ def iban(value=nil)
13
+ @iban = value unless value.nil?
14
+ @iban
15
+ end
16
+
17
+ def bic(value=nil)
18
+ @bic = value unless value.nil?
19
+ @bic
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ module Ubill
2
+ module Concerns
3
+ module Configurable
4
+ def configure(&block)
5
+ self.instance_eval(&block)
6
+ self
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,49 @@
1
+ require_relative "header"
2
+ require_relative "footer"
3
+ require_relative "account"
4
+
5
+ module Ubill
6
+ def self.configure(&block)
7
+ @config ||= Configuration.new
8
+ @config.instance_eval(&block)
9
+ end
10
+
11
+ def self.config
12
+ @config ||= Configuration.new
13
+ end
14
+
15
+ class Configuration
16
+ attr_accessor :options
17
+
18
+ def initialize
19
+ self.options = {
20
+ page_size: "A4",
21
+ margin: [2.8.cm, 2.8.cm, 3.2.cm, 2.8.cm]
22
+ }
23
+ end
24
+
25
+ def page_size(value)
26
+ options[:page_size] = value
27
+ end
28
+
29
+ def footer
30
+ @footer ||= Footer.new
31
+ end
32
+
33
+ def header
34
+ @header ||= Header.new
35
+ end
36
+
37
+ def account
38
+ @account ||= Account.new
39
+ end
40
+
41
+ def debug_bounding_boxes
42
+ @debug_bounding_boxes = true
43
+ end
44
+
45
+ def debug_bounding_boxes?
46
+ @debug_bounding_boxes || false
47
+ end
48
+ end
49
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,19 @@
1
+ require_relative "line"
2
+
3
+ module Ubill
4
+ class Footer
5
+ include Ubill::Concerns::Configurable
6
+
7
+ attr_accessor :lines
8
+
9
+ def initialize
10
+ self.lines = []
11
+ end
12
+
13
+ def add_line(&block)
14
+ line = Line.new
15
+ line.instance_eval(&block)
16
+ self.lines << line
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ require_relative "line"
2
+
3
+ module Ubill
4
+ class Header
5
+ include Ubill::Concerns::Configurable
6
+
7
+ attr_accessor :left_text, :right_text
8
+
9
+ def initialize
10
+ self.left_text = ""
11
+ self.right_text = Line.new
12
+ end
13
+
14
+ def left(value)
15
+ self.left_text = value
16
+ end
17
+
18
+ def right(&block)
19
+ right_text.instance_eval(&block)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,242 @@
1
+ require "prawn"
2
+ require "prawn/table"
3
+ require "prawn/measurement_extensions"
4
+
5
+ require "json"
6
+
7
+ module Ubill
8
+ class Invoice
9
+ include Prawn::View
10
+ include Ubill::Concerns::Configurable
11
+
12
+ COLOR_SECONDARY = "777777"
13
+ EXTERNAL_FONTS_DIR = File.join(__dir__, "fonts")
14
+
15
+ def initialize(&block)
16
+ super
17
+ @recipient = {}
18
+ @subject = ""
19
+ @subject_info = ""
20
+ @positions = [["#", "Beschreibung", "Einzelpreis", "Menge", "Gesamt"]]
21
+ @total = ""
22
+ @due = ""
23
+
24
+ load_external_font_families
25
+
26
+ configure(&block) unless block.nil?
27
+ end
28
+
29
+ def recipient(**options)
30
+ @recipient.merge!(options)
31
+ end
32
+
33
+ def subject(title, subtitle=nil)
34
+ @subject = title
35
+ @subject_info = subtitle
36
+ end
37
+
38
+ def position(name:, context:, description:, price_per_unit:, units:, price:)
39
+ @positions << [
40
+ @positions.size,
41
+ "<b>#{name}</b><font size=\"9\">\n#{context}\n#{description}</font>",
42
+ price_per_unit,
43
+ units,
44
+ price
45
+ ]
46
+ end
47
+
48
+ def total(value)
49
+ @total = value
50
+ end
51
+
52
+ def due(value)
53
+ @due = value
54
+ end
55
+
56
+
57
+ def config
58
+ Ubill.config
59
+ end
60
+
61
+ def document
62
+ @doc ||= Prawn::Document.new(config.options)
63
+ end
64
+
65
+ def width
66
+ bounds.top_right[0]
67
+ end
68
+
69
+ def height
70
+ bounds.top_left[1]
71
+ end
72
+
73
+ def margin_top
74
+ config.options[:margin][0]
75
+ end
76
+
77
+ def margin_right
78
+ config.options[:margin][1]
79
+ end
80
+
81
+ def margin_bottom
82
+ config.options[:margin][2]
83
+ end
84
+
85
+ def margin_left
86
+ config.options[:margin][3]
87
+ end
88
+
89
+ def save_as(*args, **options)
90
+ describe
91
+ super
92
+ end
93
+
94
+ def render(*args, **options)
95
+ describe
96
+ super
97
+ end
98
+
99
+ private
100
+ def load_external_font_families
101
+ Dir.glob(File.join(EXTERNAL_FONTS_DIR, "*")) do |family_dir|
102
+ family = File.basename(family_dir)
103
+ files = {}
104
+ Dir.glob(File.join(family_dir, "*.ttf")) do |file|
105
+ style = File.basename(file, ".*")
106
+ files[style.to_sym] = file
107
+ end
108
+ font_families.update(family => files)
109
+ end
110
+ end
111
+
112
+ def describe
113
+ default_leading 0.mm
114
+ default_kerning true
115
+
116
+ font "OpenSans"
117
+
118
+ describe_header
119
+ move_down 9.mm
120
+ pad 9.mm do
121
+ describe_address
122
+ end
123
+ pad 9.mm do
124
+ describe_subject
125
+ end
126
+ pad 9.mm do
127
+ describe_positions
128
+ end
129
+ pad 2.mm do
130
+ describe_terms
131
+ end
132
+ pad 2.mm do
133
+ describe_payment
134
+ end
135
+ describe_footer
136
+ end
137
+
138
+ def describe_header
139
+ repeat(:all) do
140
+ bounding_box([0, height + margin_top], width: width/3, height: margin_top - 1.cm) do
141
+ stroke_bounds if config.debug_bounding_boxes?
142
+ text config.header.left_text, style: :bold, align: :left, valign: :bottom, size: 13, color: COLOR_SECONDARY
143
+ end
144
+ end
145
+ bounding_box([width/3, height + margin_top], width: width/3*2, height: margin_top - 1.cm) do
146
+ stroke_bounds if config.debug_bounding_boxes?
147
+ formatted_text config.header.right_text, align: :right, valign: :bottom, size: 8, color: COLOR_SECONDARY
148
+ end
149
+ end
150
+
151
+ def describe_address
152
+ @recipient.each_with_filter(
153
+ :company, :name, [:firstname, :lastname], :department, :street_1, :street_2, [:zip, :city], :country
154
+ ) do |key, value|
155
+ move_down 0.3.cm if key.is_a?(Array) && key.eql?([:zip, :city])
156
+ text value, size: 10
157
+ end
158
+ end
159
+
160
+ def describe_subject
161
+ text @subject, size: 11, style: :bold
162
+ text @subject_info, size: 8
163
+ end
164
+
165
+ def describe_positions
166
+ data = @positions + [[{content: "Gesamtbetrag:", colspan: 4}, @total]]
167
+ table(data,
168
+ width: width,
169
+ header: true,
170
+ cell_style: {inline_format: true, size: 10}
171
+ ) do
172
+ cells.borders = [:bottom]
173
+ cells.border_color = "555555"
174
+ cells.border_width = 0.3
175
+ row(0).border_width = 0.88
176
+ row(0).font_style = :bold
177
+ row(0).size = 11
178
+ row(data.size-1).borders = [:top]
179
+ row(data.size-1).border_width = 0.88
180
+ row(data.size-1).font_style = :bold
181
+ cells.style do |cell|
182
+ if cell.column == 2
183
+ cell.style width: 30.mm, align: :right
184
+ end
185
+
186
+ if cell.column == 3
187
+ cell.style width: 20.mm, align: :right
188
+ end
189
+
190
+ if cell.column == 4
191
+ cell.style width: 25.mm, align: :right
192
+ end
193
+
194
+ if cell.row == data.size-1
195
+ cell.style align: :right
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ def describe_terms
202
+ font_size 10
203
+ text "Es wird gemäß §19 Abs. 1 Umsatzsteuergesetz keine Umsatzsteuer erhoben. Der Gesamtbetrag der Rechnung ist zahlbar bis zum #{@due} ohne Abzug. Wenn nicht anders angegeben, entspricht das Leistungsdatum dem Rechnungsdatum."
204
+ end
205
+
206
+ def describe_payment
207
+ font_size 10
208
+ text "Bitte überweisen Sie den Gesamtbetrag an:"
209
+ move_down 1.mm
210
+ table(
211
+ [
212
+ ["Empfänger:", config.account.recipient],
213
+ ["IBAN:", config.account.iban],
214
+ ["BIC/SWIFT:", config.account.bic],
215
+ ["Verwendungszweck:", @subject]
216
+ ],
217
+ cell_style: {size: 10}
218
+ ) do
219
+ cells.borders = []
220
+ cells.padding = [0, 0, 0.75.mm, 0]
221
+ cells.style do |cell|
222
+ if cell.column == 0
223
+ cell.style padding_left: 12.mm
224
+ else
225
+ cell.style padding_left: 8.mm
226
+ end
227
+ end
228
+ end
229
+ end
230
+
231
+ def describe_footer
232
+ repeat(:all) do
233
+ bounding_box([0, -1.cm], width: width, height: margin_bottom - 1.cm) do
234
+ stroke_bounds if config.debug_bounding_boxes?
235
+ config.footer.lines.each do |line|
236
+ formatted_text line, align: :center, size: 8, color: COLOR_SECONDARY
237
+ end
238
+ end
239
+ end
240
+ end
241
+ end
242
+ end
data/lib/ubill/line.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Ubill
2
+ class Line < Array
3
+ def append(item, **options)
4
+ unless self.empty?
5
+ self << {text: " • ", character_spacing: 1.mm}
6
+ end
7
+
8
+ # don't know why, but sometimes there appears an additional
9
+ # space after the item. seems to be a certain combination of
10
+ # characters, maybe problems with UTF-8? However, if \0 is
11
+ # appended symptom vanishes.
12
+ options[:text] = "#{item}\0"
13
+ self << options
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ubill
4
+ VERSION = "0.1.0"
5
+ end
data/lib/ubill.rb ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ CONCERNS_PATH = File.join(__dir__, "ubill", "concerns", "**", "*.rb")
5
+ Dir.glob(CONCERNS_PATH) do |path|
6
+ require_relative path
7
+ end
8
+
9
+ require_relative "hash"
10
+ require_relative "ubill/configuration"
11
+ require_relative "ubill/invoice"
12
+ require_relative "ubill/version"
13
+
14
+ module Ubill
15
+ class Error < StandardError; end
16
+ # Your code goes here...
17
+ end
data/sig/ubill.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Ubill
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ubill
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - couchbelag
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: prawn
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: prawn-table
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: matrix
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.4'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.4'
55
+ description: PDF invoice generator by ubity UG (https://ubity.io).
56
+ email:
57
+ - ts@ubity.io
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".rspec"
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - lib/hash.rb
69
+ - lib/ubill.rb
70
+ - lib/ubill/account.rb
71
+ - lib/ubill/concerns/configurable.rb
72
+ - lib/ubill/configuration.rb
73
+ - lib/ubill/fonts/OpenSans/bold.ttf
74
+ - lib/ubill/fonts/OpenSans/bold_italic.ttf
75
+ - lib/ubill/fonts/OpenSans/italic.ttf
76
+ - lib/ubill/fonts/OpenSans/normal.ttf
77
+ - lib/ubill/footer.rb
78
+ - lib/ubill/header.rb
79
+ - lib/ubill/invoice.rb
80
+ - lib/ubill/line.rb
81
+ - lib/ubill/version.rb
82
+ - sig/ubill.rbs
83
+ homepage: https://gitlab.com/ubity/gems/ubill
84
+ licenses:
85
+ - MIT
86
+ metadata:
87
+ homepage_uri: https://gitlab.com/ubity/gems/ubill
88
+ source_code_uri: https://gitlab.com/ubity/gems/ubill
89
+ changelog_uri: https://gitlab.com/ubity/gems/ubill
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 3.1.3
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubygems_version: 3.3.26
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: PDF invoice generator.
109
+ test_files: []