invoice_printer 0.0.1

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