total_in 0.5.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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +9 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +22 -0
  8. data/README.md +21 -0
  9. data/Rakefile +1 -0
  10. data/lib/total_in/attribute_methods.rb +62 -0
  11. data/lib/total_in/contexts.rb +54 -0
  12. data/lib/total_in/document.rb +114 -0
  13. data/lib/total_in/line_handlers.rb +35 -0
  14. data/lib/total_in/line_parser.rb +42 -0
  15. data/lib/total_in/line_parsers.rb +80 -0
  16. data/lib/total_in/line_processors.rb +138 -0
  17. data/lib/total_in/parser.rb +48 -0
  18. data/lib/total_in/string_helpers.rb +10 -0
  19. data/lib/total_in/typecaster.rb +18 -0
  20. data/lib/total_in/version.rb +3 -0
  21. data/lib/total_in.rb +8 -0
  22. data/spec/fixtures/total_in_full.txt +61 -0
  23. data/spec/full_file_parse_spec.rb +501 -0
  24. data/spec/spec_helper.rb +20 -0
  25. data/spec/support/shared_examples_for_values_line_parsers.rb +15 -0
  26. data/spec/total_in/line_parsers/account_end_spec.rb +23 -0
  27. data/spec/total_in/line_parsers/account_start_spec.rb +24 -0
  28. data/spec/total_in/line_parsers/addresses_spec.rb +10 -0
  29. data/spec/total_in/line_parsers/deduction_start_spec.rb +50 -0
  30. data/spec/total_in/line_parsers/document_end_spec.rb +15 -0
  31. data/spec/total_in/line_parsers/document_start_spec.rb +32 -0
  32. data/spec/total_in/line_parsers/international_spec.rb +32 -0
  33. data/spec/total_in/line_parsers/locality_spec.rb +23 -0
  34. data/spec/total_in/line_parsers/messages_spec.rb +10 -0
  35. data/spec/total_in/line_parsers/names_spec.rb +11 -0
  36. data/spec/total_in/line_parsers/payment_start_spec.rb +45 -0
  37. data/spec/total_in/line_parsers/reference_numbers_spec.rb +11 -0
  38. data/spec/total_in/line_parsers/sender_account_spec.rb +23 -0
  39. data/spec/total_in/line_processors/account_end_spec.rb +35 -0
  40. data/spec/total_in/line_processors/account_start_spec.rb +50 -0
  41. data/spec/total_in/line_processors/addresses_spec.rb +44 -0
  42. data/spec/total_in/line_processors/deduction_start_spec.rb +54 -0
  43. data/spec/total_in/line_processors/document_end_spec.rb +32 -0
  44. data/spec/total_in/line_processors/document_start_spec.rb +29 -0
  45. data/spec/total_in/line_processors/international_spec.rb +46 -0
  46. data/spec/total_in/line_processors/locality_spec.rb +46 -0
  47. data/spec/total_in/line_processors/messages_spec.rb +25 -0
  48. data/spec/total_in/line_processors/names_spec.rb +45 -0
  49. data/spec/total_in/line_processors/payment_start_spec.rb +53 -0
  50. data/spec/total_in/line_processors/reference_numbers_spec.rb +24 -0
  51. data/spec/total_in/line_processors/sender_account_spec.rb +46 -0
  52. data/spec/total_in_spec.rb +13 -0
  53. data/total-in.gemspec +25 -0
  54. metadata +169 -0
@@ -0,0 +1,50 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe DeductionStart do
6
+ let :deduction_start do
7
+ DeductionStart.new "25987654123 000000000052550222223333344444572 "
8
+ end
9
+
10
+ describe "#reference_number" do
11
+ it "is nil if unfound (only zeros) or blank" do
12
+ deduction_start = DeductionStart.new "200000000000000000000000000 0000000002109002222233333444446734523455 "
13
+ expect(deduction_start.reference_number).to be nil
14
+
15
+ deduction_start = DeductionStart.new "20 0000000002109002222233333444446734523455 "
16
+ expect(deduction_start.reference_number).to be nil
17
+ end
18
+
19
+ it "is parsed if non blank" do
20
+ expect(deduction_start.reference_number).to eq "987654123"
21
+ end
22
+ end
23
+
24
+ it "parses the amount" do
25
+ expect(deduction_start.amount).to eq 52550
26
+ end
27
+
28
+ it "parses the serial number" do
29
+ expect(deduction_start.serial_number).to eq 22222333334444457
30
+ end
31
+
32
+ it "parses the code" do
33
+ expect(deduction_start.code).to eq 2
34
+ end
35
+
36
+ describe "receiving bankgiro number" do
37
+ it "is nil if missing" do
38
+ expect(deduction_start.receiving_bankgiro_number).to be nil
39
+ end
40
+
41
+ it "is parsed if non blank" do
42
+ deduction_start = DeductionStart.new "25987654123 00000000005255022222333334444457 654321 "
43
+ expect(deduction_start.receiving_bankgiro_number).to eq "654321"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+
@@ -0,0 +1,15 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe DocumentEnd do
6
+ let :document_end do
7
+ DocumentEnd.new "99000000000000061"
8
+ end
9
+
10
+ it "parses the number of lines" do
11
+ expect(document_end.number_of_lines).to eq 61
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe DocumentStart do
6
+ let :document_start do
7
+ DocumentStart.new "00TI222222 2011102504133012345601TL1TOTALIN"
8
+ end
9
+
10
+ it "extracts the id" do
11
+ expect(document_start.id).to eq "TI222222"
12
+ end
13
+
14
+ it "extracts the created at timestamp" do
15
+ expect(document_start.created_at).to be_a Time
16
+ expect(document_start.created_at.strftime("%Y-%m-%d %H:%M:%S")).to eq "2011-10-25 12:34:56"
17
+ end
18
+
19
+ it "parses the deliver number" do
20
+ expect(document_start.delivery_number).to eq 1
21
+ end
22
+
23
+ it "parses the file type" do
24
+ expect(document_start.file_type).to eq "TL1"
25
+ end
26
+
27
+ it "parses file name" do
28
+ expect(document_start.name).to eq "TOTALIN"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe International do
6
+ let :international do
7
+ International.new "7010000000000000 EUR 000000000105000EUR000000088000 "
8
+ end
9
+
10
+ it "parses the cost" do
11
+ expect(international.cost).to eq 10000000000000
12
+ end
13
+
14
+ it "parses the cost currency" do
15
+ expect(international.cost_currency).to eq "EUR"
16
+ end
17
+
18
+ it "parses the amount" do
19
+ expect(international.amount).to eq 105000
20
+ end
21
+
22
+ it "parses the amount currency" do
23
+ expect(international.amount_currency).to eq "EUR"
24
+ end
25
+
26
+ it "parses the exchange rate" do
27
+ expect(international.exchange_rate).to eq 88000
28
+ end
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,23 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe Locality do
6
+ let :locality do
7
+ Locality.new "5211111 TESTVIKEN SE "
8
+ end
9
+
10
+ it "parses the postal code" do
11
+ expect(locality.postal_code).to eq "11111"
12
+ end
13
+
14
+ it "parses the city" do
15
+ expect(locality.city).to eq "TESTVIKEN"
16
+ end
17
+
18
+ it "parses the country code" do
19
+ expect(locality.country_code).to eq "SE"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ require "support/shared_examples_for_values_line_parsers"
2
+ require "total_in/line_parsers"
3
+
4
+ module TotalIn
5
+ module LineParsers
6
+ RSpec.describe Messages do
7
+ it_behaves_like "a values line parser"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require "support/shared_examples_for_values_line_parsers"
2
+ require "total_in/line_parsers"
3
+
4
+ module TotalIn
5
+ module LineParsers
6
+ RSpec.describe Names do
7
+ it_behaves_like "a values line parser"
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,45 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe PaymentStart do
6
+ let :payment_start do
7
+ PaymentStart.new "2038952678900 00000000001050022222333334444477 "
8
+ end
9
+
10
+ describe "#reference_number" do
11
+ it "is nil if unfound (only zeros) or blank" do
12
+ payment_start = PaymentStart.new "200000000000000000000000000 0000000002109002222233333444446734523455 "
13
+ expect(payment_start.reference_number).to be nil
14
+
15
+ payment_start = PaymentStart.new "20 0000000002109002222233333444446734523455 "
16
+ expect(payment_start.reference_number).to be nil
17
+ end
18
+
19
+ it "is parsed if non blank" do
20
+ expect(payment_start.reference_number).to eq "38952678900"
21
+ end
22
+ end
23
+
24
+ it "parses the amount" do
25
+ expect(payment_start.amount).to eq 10500
26
+ end
27
+
28
+ it "parses the serial number" do
29
+ expect(payment_start.serial_number).to eq 22222333334444477
30
+ end
31
+
32
+ describe "receiving bankgiro number" do
33
+ it "is nil if missing" do
34
+ expect(payment_start.receiving_bankgiro_number).to be nil
35
+ end
36
+
37
+ it "is parsed if non blank" do
38
+ payment_start = PaymentStart.new "2038952678900 0000000000105002222233333444447712345678 "
39
+ expect(payment_start.receiving_bankgiro_number).to eq "12345678"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,11 @@
1
+ require "support/shared_examples_for_values_line_parsers"
2
+ require "total_in/line_parsers"
3
+
4
+ module TotalIn
5
+ module LineParsers
6
+ RSpec.describe ReferenceNumbers do
7
+ it_behaves_like "a values line parser"
8
+ end
9
+ end
10
+ end
11
+
@@ -0,0 +1,23 @@
1
+ require "total_in/line_parsers"
2
+
3
+ module TotalIn
4
+ module LineParsers
5
+ RSpec.describe SenderAccount do
6
+ let :sender_account do
7
+ SenderAccount.new "6098765433 29999999999 "
8
+ end
9
+
10
+ it "parses the account number" do
11
+ expect(sender_account.account_number).to eq "98765433"
12
+ end
13
+
14
+ it "parses the city" do
15
+ expect(sender_account.origin_code).to eq 2
16
+ end
17
+
18
+ it "parses the organization number code" do
19
+ expect(sender_account.company_organization_number).to eq "9999999999"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "AccountEnd" do
7
+ let :line do
8
+ double "Line", attributes: {}
9
+ end
10
+
11
+ let :account do
12
+ Document::Account.new
13
+ end
14
+
15
+ let :contexts do
16
+ Contexts.new [Document.new, account, Document::Payment.new]
17
+ end
18
+
19
+ it "moves to the nearest account and assigns the line attributes" do
20
+ allow(account).to receive :assign_attributes
21
+
22
+ AccountEnd.call line, contexts
23
+
24
+ expect(account).to have_received(:assign_attributes).with line.attributes
25
+ end
26
+
27
+ it "sets the account as the current context" do
28
+ new_contexts = AccountEnd.call line, contexts
29
+
30
+ expect(new_contexts.current).to be account
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,50 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "AccountStart" do
7
+ let :line do
8
+ double "Line", attributes: {}
9
+ end
10
+
11
+ let :document do
12
+ Document.new
13
+ end
14
+
15
+ let :contexts do
16
+ Contexts.new
17
+ end
18
+
19
+ before do
20
+ contexts.add document
21
+ end
22
+
23
+ it "instantiates a new account with the line attributes" do
24
+ allow(Document::Account).to receive :new
25
+
26
+ AccountStart.call line, contexts
27
+
28
+ expect(Document::Account).to have_received(:new).with line.attributes
29
+ end
30
+
31
+ it "adds the account to the document" do
32
+ fake_account = double "Document::Account"
33
+ allow(Document::Account).to receive(:new) { fake_account }
34
+
35
+ AccountStart.call line, contexts
36
+
37
+ expect(document.accounts).to include fake_account
38
+ end
39
+
40
+ it "sets the account as the current context" do
41
+ fake_account = double "Document::Account"
42
+ allow(Document::Account).to receive(:new) { fake_account }
43
+
44
+ new_contexts = AccountStart.call line, contexts
45
+
46
+ expect(new_contexts.current).to be fake_account
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,44 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe Addresses do
7
+ let :line do
8
+ double "Line", values: ["one", "two"]
9
+ end
10
+
11
+ describe "when the current context is a Document::Sender" do
12
+ it "sets the address to the sender" do
13
+ sender = Document::Sender.new
14
+ contexts = Contexts.new sender
15
+
16
+ Addresses.new(Document::Sender).call line, contexts
17
+
18
+ expect(sender.address).to eq "one two"
19
+ end
20
+ end
21
+
22
+ describe "when the current context is something else" do
23
+ let! :sender do
24
+ Document::Sender.new
25
+ end
26
+
27
+ before do
28
+ allow(Document::Sender).to receive(:new) { sender }
29
+ end
30
+
31
+ it "adds a new Document::Sender to the nearest transaction and appends it to the contexts" do
32
+ transaction = Document::Transaction.new
33
+ contexts = Contexts.new transaction
34
+
35
+ new_contexts = Addresses.new(Document::Sender).call line, contexts
36
+
37
+ expect(sender.address).to eq "one two"
38
+ expect(transaction.sender).to eq sender
39
+ expect(new_contexts.current).to be sender
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,54 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "DeductionStart" do
7
+ let :line do
8
+ double "Line", attributes: {}, reference_number: "1234567890"
9
+ end
10
+
11
+ let :account do
12
+ Document::Account.new
13
+ end
14
+
15
+ let! :contexts do
16
+ Contexts.new [Document.new, account, Document::Deduction.new]
17
+ end
18
+
19
+ it "adds a new deduction to the nearest account" do
20
+ deduction = Document::Deduction.new
21
+ allow(Document::Deduction).to receive(:new) { deduction }
22
+
23
+ DeductionStart.call line, contexts
24
+
25
+ expect(account.deductions).to include deduction
26
+ end
27
+
28
+ it "sets the deduction as the current context" do
29
+ deduction = Document::Deduction.new
30
+ allow(Document::Deduction).to receive(:new) { deduction }
31
+
32
+ new_contexts = DeductionStart.call line, contexts
33
+
34
+ expect(new_contexts.current).to be deduction
35
+ end
36
+
37
+ it "assigns the line attributes to the account" do
38
+ deduction = Document::Deduction.new
39
+ allow(Document::Deduction).to receive(:new) { deduction }
40
+
41
+ DeductionStart.call line, contexts
42
+
43
+ expect(Document::Deduction).to have_received(:new).with(line.attributes)
44
+ end
45
+
46
+ it "adds the line reference number to the deduction" do
47
+ new_contexts = DeductionStart.call line, contexts
48
+
49
+ expect(new_contexts.current.reference_numbers).to include "1234567890"
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,32 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "DocumentEnd" do
7
+ class Thing
8
+ end
9
+
10
+ let :line do
11
+ double "Line", number_of_lines: 35
12
+ end
13
+
14
+ it "moves to the nearest document context" do
15
+ document = Document.new
16
+ contexts = Contexts.new [Thing.new, document, Thing.new, Thing.new]
17
+
18
+ DocumentEnd.call line, contexts
19
+
20
+ expect(contexts.current).to eq document
21
+ end
22
+
23
+ it "sets the number of lines on the document" do
24
+ document = Document.new
25
+
26
+ DocumentEnd.call line, Contexts.new(document)
27
+
28
+ expect(document.number_of_lines).to eq 35
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "DocumentStart" do
7
+ let :line do
8
+ double "Line", attributes: {}
9
+ end
10
+
11
+ it "instantiates a new document with the line attributes" do
12
+ allow(Document).to receive :new
13
+
14
+ DocumentStart.call line, Contexts.new
15
+
16
+ expect(Document).to have_received(:new).with line.attributes
17
+ end
18
+
19
+ it "sets the document as the current context" do
20
+ fake_document = double "Document"
21
+ allow(Document).to receive(:new) { fake_document }
22
+
23
+ contexts = DocumentStart.call line, Contexts.new
24
+
25
+ expect(contexts.current).to be fake_document
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "International" do
7
+ let :line do
8
+ double "Line", attributes: {}
9
+ end
10
+
11
+ let :transaction do
12
+ Document::Transaction.new
13
+ end
14
+
15
+ let :contexts do
16
+ Contexts.new transaction
17
+ end
18
+
19
+ it "instantiates a new International with the line attributes" do
20
+ international = double "Document::International"
21
+ allow(Document::International).to receive(:new) { international }
22
+
23
+ International.call line, contexts
24
+
25
+ expect(Document::International).to have_received(:new).with line.attributes
26
+ end
27
+
28
+ it "assigns the international instance to the transaction" do
29
+ international = double "Document::International"
30
+ allow(Document::International).to receive(:new) { international }
31
+
32
+ International.call line, contexts
33
+
34
+ expect(transaction.international).to be international
35
+ end
36
+
37
+ it "moves to the nearest transaction" do
38
+ contexts.add Document::Sender.new
39
+
40
+ new_contexts = International.call line, contexts
41
+
42
+ expect(new_contexts.current).to be transaction
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe Locality do
7
+ let :line do
8
+ double "Line", attributes: {}
9
+ end
10
+
11
+ describe "when the current context is a Document::Sender" do
12
+ it "adds the line values to the sender as name" do
13
+ sender = Document::Sender.new
14
+ contexts = Contexts.new sender
15
+ allow(sender).to receive(:assign_attributes)
16
+
17
+ Locality.new(Document::Sender).call line, contexts
18
+
19
+ expect(sender).to have_received(:assign_attributes).with line.attributes
20
+ end
21
+ end
22
+
23
+ describe "when the current context is something else" do
24
+ let! :sender do
25
+ Document::Sender.new
26
+ end
27
+
28
+ before do
29
+ allow(Document::Sender).to receive(:new) { sender }
30
+ end
31
+
32
+ it "adds a new Document::Sender to the nearest transaction and appends it to the contexts" do
33
+ transaction = Document::Transaction.new
34
+ contexts = Contexts.new transaction
35
+ allow(sender).to receive(:assign_attributes)
36
+
37
+ new_contexts = Locality.new(Document::Sender).call line, contexts
38
+
39
+ expect(transaction.sender).to eq sender
40
+ expect(new_contexts.current).to be sender
41
+ expect(sender).to have_received(:assign_attributes).with line.attributes
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe "Names" do
7
+ let :line do
8
+ double "Line", values: ["one", "two"]
9
+ end
10
+
11
+ let :current_context do
12
+ double "SomeContext", add_message: nil
13
+ end
14
+
15
+ it "adds the line values to the current context's reference_numbers" do
16
+ contexts = Contexts.new current_context
17
+
18
+ Messages.call line, contexts
19
+
20
+ expect(current_context).to have_received(:add_message).with "one"
21
+ expect(current_context).to have_received(:add_message).with "two"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,45 @@
1
+ require "total_in/contexts"
2
+ require "total_in/line_processors"
3
+
4
+ module TotalIn
5
+ module LineProcessors
6
+ RSpec.describe Names do
7
+ let :line do
8
+ double "Line", values: ["one", "two"]
9
+ end
10
+
11
+ describe "when the current context is a Document::Sender" do
12
+ it "adds the line values to the sender as name" do
13
+ sender = Document::Sender.new
14
+ contexts = Contexts.new sender
15
+
16
+ Names.new(Document::Sender).call line, contexts
17
+
18
+ expect(sender.name).to eq "one two"
19
+ end
20
+ end
21
+
22
+ describe "when the current context is something else" do
23
+ let! :sender do
24
+ Document::Sender.new
25
+ end
26
+
27
+ before do
28
+ allow(Document::Sender).to receive(:new) { sender }
29
+ end
30
+
31
+ it "adds a new Document::Sender to the nearest transaction and appends it to the contexts" do
32
+ transaction = Document::Transaction.new
33
+ contexts = Contexts.new transaction
34
+
35
+ new_contexts = Names.new(Document::Sender).call line, contexts
36
+
37
+ expect(sender.name).to eq "one two"
38
+ expect(transaction.sender).to eq sender
39
+ expect(new_contexts.current).to be sender
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+