total_in 0.5.0

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