invoice_printer 0.0.1

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.
@@ -0,0 +1,3 @@
1
+ module InvoicePrinter
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+
3
+ class DatesBoxTest < Minitest::Test
4
+ include InvoicePrinterHelpers
5
+
6
+ def test_setting_issue_date_and_due_date
7
+ params = default_document_params.merge(
8
+ issue_date: '05/03/2016',
9
+ due_date: '14/03/2016'
10
+ )
11
+ invoice = InvoicePrinter::Document.new(params)
12
+ rendered_pdf = InvoicePrinter.render(document: invoice)
13
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
14
+ assert_equal true, pdf_analysis.strings.include?('Issue date:')
15
+ assert_equal true, pdf_analysis.strings.include?('Due date:')
16
+ end
17
+
18
+ def test_setting_only_issue_date
19
+ params = default_document_params.merge(
20
+ issue_date: '05/03/2016',
21
+ due_date: ''
22
+ )
23
+ invoice = InvoicePrinter::Document.new(params)
24
+ rendered_pdf = InvoicePrinter.render(document: invoice)
25
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
26
+ assert_equal true, pdf_analysis.strings.include?('Issue date:')
27
+ assert_equal false, pdf_analysis.strings.include?('Due date:')
28
+ end
29
+
30
+ def test_setting_only_due_date
31
+ params = default_document_params.merge(
32
+ issue_date: nil,
33
+ due_date: '05/03/2016'
34
+ )
35
+ invoice = InvoicePrinter::Document.new(params)
36
+ rendered_pdf = InvoicePrinter.render(document: invoice)
37
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
38
+ assert_equal false, pdf_analysis.strings.include?('Issue date:')
39
+ assert_equal true, pdf_analysis.strings.include?('Due date:')
40
+ end
41
+
42
+ def test_setting_no_dates
43
+ params = default_document_params.merge(
44
+ issue_date: '',
45
+ due_date: nil
46
+ )
47
+ invoice = InvoicePrinter::Document.new(params)
48
+ rendered_pdf = InvoicePrinter.render(document: invoice)
49
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
50
+ assert_equal false, pdf_analysis.strings.include?('Issue date:')
51
+ assert_equal false, pdf_analysis.strings.include?('Due date:')
52
+ end
53
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class InvoicePrinterTest < Minitest::Test
4
+ include InvoicePrinterHelpers
5
+
6
+ def test_render_document
7
+ invoice = InvoicePrinter::Document.new(default_document_params)
8
+ rendered_pdf = InvoicePrinter.render(document: invoice)
9
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
10
+
11
+ strings = InvoicePrinter::PDFDocument.new(document: invoice).to_a
12
+ assert_equal strings, pdf_analysis.strings
13
+ end
14
+ end
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+
3
+ class ItemsTableTest < Minitest::Test
4
+ include InvoicePrinterHelpers
5
+
6
+ def test_omitting_name_column
7
+ test_ommiting_column(column: 'name', label: :item)
8
+ end
9
+
10
+ def test_omitting_quantity_column
11
+ test_ommiting_column(column: 'quantity', label: :quantity)
12
+ end
13
+
14
+ def test_omitting_unit_column
15
+ test_ommiting_column(column: 'unit', label: :unit)
16
+ end
17
+
18
+ def test_omitting_price_column
19
+ test_ommiting_column(column: 'price', label: :price_per_item)
20
+ end
21
+
22
+ # TODO: We need to distinguish between items' taxes and document taxes
23
+ #
24
+ #def test_omitting_tax_column
25
+ # test_ommiting_column(column: 'tax', label: :tax)
26
+ #end
27
+
28
+ def test_omitting_amount_column
29
+ test_ommiting_column(column: 'amount', label: :amount)
30
+ end
31
+
32
+ private
33
+
34
+ def test_ommiting_column(column:, label:)
35
+ invoice = invoice_without_item_column(column)
36
+ rendered_pdf = InvoicePrinter.render(document: invoice)
37
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
38
+ assert_equal false, pdf_analysis.strings.include?(InvoicePrinter.labels[label])
39
+
40
+ strings = InvoicePrinter::PDFDocument.new(document: invoice).to_a
41
+ assert_equal strings, pdf_analysis.strings
42
+ end
43
+
44
+ def invoice_without_item_column(column)
45
+ InvoicePrinter::Document.new(
46
+ default_document_params.merge(
47
+ items: [
48
+ InvoicePrinter::Document::Item.new(
49
+ default_document_item_params.merge("#{column}": nil)
50
+ )
51
+ ]
52
+ )
53
+ )
54
+ end
55
+ end
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ class LabelsTest < Minitest::Test
4
+ include InvoicePrinterHelpers
5
+
6
+ def test_setting_global_labels
7
+ labels = { provider: 'Default Provider', purchaser: 'Default Purchaser' }
8
+ InvoicePrinter.labels = labels
9
+
10
+ invoice = InvoicePrinter::Document.new(default_document_params)
11
+ rendered_pdf = InvoicePrinter.render(document: invoice)
12
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
13
+
14
+ assert_equal true, pdf_analysis.strings.include?('Default Provider')
15
+ assert_equal true, pdf_analysis.strings.include?('Default Purchaser')
16
+ end
17
+
18
+ def test_setting_instant_labels
19
+ labels = { provider: 'Current Provider', purchaser: 'Current Purchaser' }
20
+
21
+ invoice = InvoicePrinter::Document.new(default_document_params)
22
+ rendered_pdf = InvoicePrinter.render(document: invoice, labels: labels)
23
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
24
+
25
+ assert_equal true, pdf_analysis.strings.include?('Current Provider')
26
+ assert_equal true, pdf_analysis.strings.include?('Current Purchaser')
27
+ end
28
+ end
@@ -0,0 +1,92 @@
1
+ require 'test_helper'
2
+
3
+ class PaymentBoxTest < Minitest::Test
4
+ include InvoicePrinterHelpers
5
+
6
+ def test_setting_no_bank_account_number
7
+ params = default_document_params.merge(
8
+ bank_account_number: nil,
9
+ account_iban: 'IBAN'
10
+ )
11
+ invoice = InvoicePrinter::Document.new(params)
12
+ rendered_pdf = InvoicePrinter.render(document: invoice)
13
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
14
+
15
+ assert_equal true, pdf_analysis.strings.include?('Payment in cash')
16
+ assert_equal false, pdf_analysis.strings.include?('Payment by bank transfer on the account below:')
17
+ assert_equal false, pdf_analysis.strings.include?('SWIFT:')
18
+ assert_equal false, pdf_analysis.strings.include?('IBAN:')
19
+ end
20
+
21
+ def test_setting_only_local_bank_account_number
22
+ params = default_document_params.merge(
23
+ bank_account_number: '218291829/0100',
24
+ account_iban: nil,
25
+ account_swift: nil
26
+ )
27
+ invoice = InvoicePrinter::Document.new(params)
28
+ rendered_pdf = InvoicePrinter.render(document: invoice)
29
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
30
+
31
+ assert_equal false, pdf_analysis.strings.include?('Payment in cash')
32
+ assert_equal true, pdf_analysis.strings.include?('Payment by bank transfer on the account below:')
33
+ assert_equal true, pdf_analysis.strings.include?('218291829/0100')
34
+ assert_equal false, pdf_analysis.strings.include?('SWIFT:')
35
+ assert_equal false, pdf_analysis.strings.include?('IBAN:')
36
+ end
37
+
38
+ def test_setting_bank_account_number_and_iban
39
+ params = default_document_params.merge(
40
+ bank_account_number: '218291829/0100',
41
+ account_iban: 'SAMPLE_IBAN',
42
+ account_swift: nil
43
+ )
44
+ invoice = InvoicePrinter::Document.new(params)
45
+ rendered_pdf = InvoicePrinter.render(document: invoice)
46
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
47
+
48
+ assert_equal false, pdf_analysis.strings.include?('Payment in cash')
49
+ assert_equal true, pdf_analysis.strings.include?('Payment by bank transfer on the account below:')
50
+ assert_equal true, pdf_analysis.strings.include?('218291829/0100')
51
+ assert_equal false, pdf_analysis.strings.include?('SWIFT:')
52
+ assert_equal true, pdf_analysis.strings.include?('IBAN:')
53
+ assert_equal true, pdf_analysis.strings.include?('SAMPLE_IBAN')
54
+ end
55
+
56
+ def test_setting_bank_account_number_and_iban
57
+ params = default_document_params.merge(
58
+ bank_account_number: '218291829/0100',
59
+ account_iban: nil,
60
+ account_swift: 'SAMPLE_SWIFT'
61
+ )
62
+ invoice = InvoicePrinter::Document.new(params)
63
+ rendered_pdf = InvoicePrinter.render(document: invoice)
64
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
65
+
66
+ assert_equal false, pdf_analysis.strings.include?('Payment in cash')
67
+ assert_equal true, pdf_analysis.strings.include?('Payment by bank transfer on the account below:')
68
+ assert_equal true, pdf_analysis.strings.include?('218291829/0100')
69
+ assert_equal true, pdf_analysis.strings.include?('SWIFT:')
70
+ assert_equal true, pdf_analysis.strings.include?('SAMPLE_SWIFT')
71
+ assert_equal false, pdf_analysis.strings.include?('IBAN:')
72
+ end
73
+
74
+ def test_setting_bank_account_number_iban_and_swift
75
+ params = default_document_params.merge(
76
+ bank_account_number: '218291829/0100',
77
+ account_iban: 'SAMPLE_IBAN',
78
+ account_swift: 'SAMPLE_SWIFT'
79
+ )
80
+ invoice = InvoicePrinter::Document.new(params)
81
+ rendered_pdf = InvoicePrinter.render(document: invoice)
82
+ pdf_analysis = PDF::Inspector::Text.analyze(rendered_pdf)
83
+
84
+ assert_equal false, pdf_analysis.strings.include?('Payment in cash')
85
+ assert_equal true, pdf_analysis.strings.include?('Payment by bank transfer on the account below:')
86
+ assert_equal true, pdf_analysis.strings.include?('218291829/0100')
87
+ assert_equal true, pdf_analysis.strings.include?('SWIFT:')
88
+ assert_equal true, pdf_analysis.strings.include?('SAMPLE_SWIFT')
89
+ assert_equal true, pdf_analysis.strings.include?('IBAN:')
90
+ assert_equal true, pdf_analysis.strings.include?('SAMPLE_IBAN')
91
+ end
92
+ end
data/test/test_ext.rb ADDED
@@ -0,0 +1,102 @@
1
+ module InvoicePrinter
2
+ class PDFDocument
3
+ # Expose the document as an array of attributes in order as their
4
+ # appear on PDF
5
+ def to_a
6
+ strings = []
7
+
8
+ strings << @labels[:name]
9
+ strings << @document.number
10
+
11
+ strings << @labels[:provider]
12
+ strings << @document.provider_name
13
+ strings << "#{@document.provider_street} #{@document.provider_street_number}".strip
14
+ strings << @document.provider_postcode
15
+ strings << @document.provider_city
16
+ strings << @document.provider_city_part
17
+ strings << @document.provider_extra_address_line
18
+
19
+ strings << "#{@labels[:ic]}: #{@document.provider_ic}" unless @document.provider_ic.nil?
20
+ strings << "#{@labels[:dic]}: #{@document.provider_dic}" unless @document.provider_dic.nil?
21
+
22
+ strings << @labels[:purchaser]
23
+ strings << @document.purchaser_name
24
+ strings << "#{@document.purchaser_street} #{@document.purchaser_street_number}".strip
25
+ strings << @document.purchaser_postcode
26
+ strings << @document.purchaser_city
27
+ strings << @document.purchaser_city_part
28
+ strings << @document.purchaser_extra_address_line
29
+
30
+ strings << "#{@labels[:ic]}: #{@document.purchaser_ic}" unless @document.purchaser_ic.nil?
31
+ strings << "#{@labels[:dic]}: #{@document.purchaser_dic}" unless @document.purchaser_dic.nil?
32
+
33
+ # Account
34
+ if @document.bank_account_number.nil?
35
+ strings << @labels[:payment_in_cash]
36
+ else
37
+ strings << @labels[:payment_by_transfer]
38
+ end
39
+
40
+ strings << "#{@labels[:account_number]}:"
41
+ strings << @document.bank_account_number
42
+ strings << "#{@labels[:swift]}:"
43
+ strings << @document.account_swift
44
+ strings << "#{@labels[:iban]}:"
45
+ strings << @document.account_iban
46
+
47
+ # Dates
48
+ strings << "#{@labels[:issue_date]}:"
49
+ strings << @document.issue_date
50
+ strings << "#{@labels[:due_date]}:"
51
+ strings << @document.due_date
52
+
53
+ # Items table
54
+ strings << @labels[:item] if determine_items_structure[:names]
55
+ strings << @labels[:quantity] if determine_items_structure[:quantities]
56
+ strings << @labels[:unit] if determine_items_structure[:units]
57
+ strings << @labels[:price_per_item] if determine_items_structure[:prices]
58
+ strings << @labels[:tax] if determine_items_structure[:taxes]
59
+ strings << @labels[:amount] if determine_items_structure[:amounts]
60
+ strings << items_to_a(@document.items)
61
+
62
+ # Total table
63
+ strings << "#{@labels[:subtotal]}:"
64
+ strings << @document.subtotal
65
+ strings << "#{@labels[:tax]}:"
66
+ strings << @document.tax
67
+ strings << "#{@labels[:tax2]}:"
68
+ strings << @document.tax2
69
+ strings << "#{@labels[:tax3]}:"
70
+ strings << @document.tax3
71
+ strings << "#{@labels[:total]}: #{@document.total}"
72
+
73
+ # TODO: dynamically test page numbers
74
+ strings << '1 / 1'
75
+
76
+ strings.flatten.reject(&:empty?)
77
+ end
78
+
79
+ private
80
+
81
+ def items_to_a(items)
82
+ ary = []
83
+ items.each do |item|
84
+ ary << item_to_a(item)
85
+ end
86
+ ary.flatten
87
+ end
88
+
89
+ def item_to_a(item)
90
+ ary = []
91
+ ary << item.name
92
+ ary << item.quantity
93
+ ary << item.unit
94
+ ary << item.price
95
+ ary << item.tax
96
+ ary << item.tax2
97
+ ary << item.tax3
98
+ ary << item.amount
99
+ ary.compact
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,57 @@
1
+ require 'pdf/inspector'
2
+ require 'invoice_printer'
3
+ require 'test_ext'
4
+ require 'minitest/autorun'
5
+
6
+ # Helpers for easy-to-build documents
7
+ module InvoicePrinterHelpers
8
+ def default_document_params
9
+ {
10
+ number: '198900000001',
11
+ provider_name: 'Business s.r.o.',
12
+ provider_ic: '56565656',
13
+ provider_dic: '465454',
14
+ provider_street: 'Rolnicka',
15
+ provider_street_number: '1',
16
+ provider_postcode: '747 05',
17
+ provider_city: 'Opava',
18
+ provider_city_part: 'Katerinky',
19
+ provider_extra_address_line: 'Czech Republic',
20
+ purchaser_name: 'Adam',
21
+ purchaser_ic: nil,
22
+ purchaser_dic: nil,
23
+ purchaser_street: 'Ostravska',
24
+ purchaser_street_number: '1',
25
+ purchaser_postcode: '747 70',
26
+ purchaser_city: 'Opava',
27
+ purchaser_city_part: '',
28
+ purchaser_extra_address_line: '',
29
+ issue_date: '19/03/3939',
30
+ due_date: '19/03/3939',
31
+ subtotal: '175',
32
+ tax: '5',
33
+ tax2: '10',
34
+ tax3: '20',
35
+ total: '$ 200',
36
+ bank_account_number: '156546546465',
37
+ account_iban: 'IBAN464545645',
38
+ account_swift: 'SWIFT5456',
39
+ items: [
40
+ InvoicePrinter::Document::Item.new(
41
+ default_document_item_params
42
+ )
43
+ ]
44
+ }
45
+ end
46
+
47
+ def default_document_item_params
48
+ {
49
+ name: 'Web consultation',
50
+ quantity: '2',
51
+ unit: 'hours',
52
+ price: '$ 25',
53
+ tax: '$ 1',
54
+ amount: '$ 100'
55
+ }
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: invoice_printer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Josef Strzibny
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-10 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: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
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'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Super simple PDF invoicing in pure Ruby (based on Prawn library).
70
+ email:
71
+ - strzibny@strzibny.name
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - examples/czech_invoice.pdf
82
+ - examples/czech_invoice.rb
83
+ - examples/example.jpg
84
+ - invoice_printer.gemspec
85
+ - lib/invoice_printer.rb
86
+ - lib/invoice_printer/document.rb
87
+ - lib/invoice_printer/document/item.rb
88
+ - lib/invoice_printer/pdf_document.rb
89
+ - lib/invoice_printer/version.rb
90
+ - test/dates_box_test.rb
91
+ - test/invoice_printer_test.rb
92
+ - test/items_table_test.rb
93
+ - test/labels_test.rb
94
+ - test/payment_box_test.rb
95
+ - test/test_ext.rb
96
+ - test/test_helper.rb
97
+ homepage: https://github.com/strzibny/invoice_printer
98
+ licenses:
99
+ - MIT
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.4.8
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: Super simple PDF invoicing in pure Ruby
121
+ test_files:
122
+ - test/dates_box_test.rb
123
+ - test/invoice_printer_test.rb
124
+ - test/items_table_test.rb
125
+ - test/labels_test.rb
126
+ - test/payment_box_test.rb
127
+ - test/test_ext.rb
128
+ - test/test_helper.rb
129
+ has_rdoc: