cfonb 0.0.2 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1666b9858511859d77ab8b3c14a11ee214548b5da5154ee927cf7e51b14eca95
4
- data.tar.gz: 292ed95e4250414dc82ef2967df62663cdadf529d72d8229d5609eee0fb3f0b1
3
+ metadata.gz: 45c55ed710afa4873c8d7cbb73412d9255ad5992c619e4a00918429b691517ce
4
+ data.tar.gz: 82075981bcd15526501ebf5fd965b97a0e09fdc7ace490c48c3de4cbbd2c7662
5
5
  SHA512:
6
- metadata.gz: 9c74e319b7448e79163010bea1efeb5a5c5391bd0352b3c38d3145fd41f27ae60b0fe562d25b65698d207418288fb61dc4d49231be968f7dead6905bbc854132
7
- data.tar.gz: a568a83590cfd3666d9ac96ba4dd6c09a39e73aa3a8136904cc24fe25df7d6b5b2f6d3fac74aee01e4ad57bf4455f9d4cf9e55ed993ca8f07f4b440eb103dc8d
6
+ metadata.gz: a985ece7273a2f4a06c5915c30d65e873d624b0be138ea141fc18237316ce248740ee6b5c384e3a3da021bffc918273f19abe4b27e8b161974838b105f1587ae
7
+ data.tar.gz: '0185ec1ef15211cd9dafa449d968a67a43e736083de9648761e054959ddb0485a7cf14aa45e2e83f64edc9bff6b9732779cec059abb9dc560a47e22a866ed31e'
data/lib/cfonb/error.rb CHANGED
@@ -12,4 +12,8 @@ module CFONB
12
12
  class UnstartedOperationError < ParserError; end
13
13
 
14
14
  class UnfinishedStatementError < ParserError; end
15
+
16
+ class AlreadyDefinedOperationError < ParserError; end
17
+
18
+ class UnhandledLineCodeError < ParserError; end
15
19
  end
@@ -3,13 +3,15 @@
3
3
  module CFONB
4
4
  module OperationDetail
5
5
  class RCN
6
+ using CFONB::Refinements::Strings
7
+
6
8
  ATTRIBUTES = %i[reference purpose].freeze
7
9
 
8
10
  def self.apply(operation, line)
9
11
  operation.reference = [
10
12
  operation.reference,
11
- line.detail[0..34].strip
12
- ].compact.join(' - ')
13
+ line.detail[0..34].strip,
14
+ ].filter_map(&:presence).join(' - ')
13
15
 
14
16
  operation.purpose = line.detail[35..-1]&.strip
15
17
  end
@@ -3,13 +3,15 @@
3
3
  module CFONB
4
4
  module OperationDetail
5
5
  class REF
6
+ using CFONB::Refinements::Strings
7
+
6
8
  ATTRIBUTES = %i[reference].freeze
7
9
 
8
10
  def self.apply(operation, line)
9
11
  operation.reference = [
10
12
  operation.reference,
11
13
  line.detail.strip
12
- ].compact.join(' - ')
14
+ ].filter_map(&:presence).join(' - ')
13
15
  end
14
16
 
15
17
  CFONB::OperationDetail.register('REF', self)
data/lib/cfonb/parser.rb CHANGED
@@ -26,6 +26,15 @@ module CFONB
26
26
  statements
27
27
  end
28
28
 
29
+ def parse_operation(optimistic: false)
30
+ @current_operation = nil
31
+ @optimistic = optimistic
32
+
33
+ each_line { parse_operation_line(_1) }
34
+
35
+ current_operation
36
+ end
37
+
29
38
  private
30
39
 
31
40
  attr_reader :input, :statements, :current_statement, :current_operation, :optimistic
@@ -75,6 +84,23 @@ module CFONB
75
84
  handle_error(e)
76
85
  end
77
86
 
87
+ def parse_operation_line(line)
88
+ line = CFONB::LineParser.parse(line)
89
+
90
+ case line.code
91
+ when OPERATION_CODE
92
+ return handle_error(AlreadyDefinedOperationError) if current_operation
93
+
94
+ @current_operation = CFONB::Operation.new(line)
95
+ when OPERATION_DETAIL_CODE
96
+ return handle_error(UnstartedOperationError) unless current_operation
97
+
98
+ current_operation.merge_detail(line)
99
+ else
100
+ return handle_error(UnhandledLineCodeError)
101
+ end
102
+ end
103
+
78
104
  def handle_error(error)
79
105
  raise error unless optimistic
80
106
  end
@@ -4,7 +4,6 @@ module CFONB
4
4
  module Refinements
5
5
  module Strings
6
6
  refine String do
7
-
8
7
  def first(count = 1)
9
8
  self[..(count - 1)]
10
9
  end
@@ -12,6 +11,10 @@ module CFONB
12
11
  def last(count = 1)
13
12
  self[-count..]
14
13
  end
14
+
15
+ def presence
16
+ strip.empty? ? nil : self
17
+ end
15
18
  end
16
19
  end
17
20
  end
data/lib/cfonb.rb CHANGED
@@ -30,4 +30,8 @@ module CFONB
30
30
  def self.parse(input, optimistic: false)
31
31
  Parser.new(input).parse(optimistic: optimistic)
32
32
  end
33
+
34
+ def self.parse_operation(input, optimistic: false)
35
+ Parser.new(input).parse_operation(optimistic: optimistic)
36
+ end
33
37
  end
@@ -37,7 +37,8 @@ describe CFONB::Parser do
37
37
  internal_code: '9162',
38
38
  label: "PRLV SEPA TEST CABINET\nMENSUEAUHTR13133",
39
39
  number: 0,
40
- reference: '',
40
+ reference: 'REFERENCE - OTHER REFERENCE',
41
+ purpose: 'PURPOSE',
41
42
  rejection_code: '',
42
43
  unavailability_code: '0',
43
44
  value_date: Date.new(2019, 5, 16),
@@ -55,7 +56,7 @@ describe CFONB::Parser do
55
56
  internal_code: '9162',
56
57
  label: 'VIR SEPA DEMONSTRATION',
57
58
  number: 0,
58
- reference: '',
59
+ reference: 'REFERENCE',
59
60
  rejection_code: '',
60
61
  unavailability_code: '0',
61
62
  value_date: Date.new(2019, 5, 16),
@@ -227,7 +228,7 @@ describe CFONB::Parser do
227
228
  internal_code: '9162',
228
229
  label: "PRLV SEPA TEST CABINET\nMENSUEAUHTR13133",
229
230
  number: 0,
230
- reference: '',
231
+ reference: 'REFERENCE - OTHER REFERENCE',
231
232
  rejection_code: '',
232
233
  unavailability_code: '0',
233
234
  value_date: Date.new(2019, 5, 16),
@@ -245,7 +246,7 @@ describe CFONB::Parser do
245
246
  internal_code: '9162',
246
247
  label: 'VIR SEPA DEMONSTRATION',
247
248
  number: 0,
248
- reference: '',
249
+ reference: 'REFERENCE',
249
250
  rejection_code: '',
250
251
  unavailability_code: '0',
251
252
  value_date: Date.new(2019, 5, 16),
@@ -466,4 +467,152 @@ describe CFONB::Parser do
466
467
  end
467
468
  end
468
469
  end
470
+
471
+ describe '.parse_operation' do
472
+ subject(:operation) { described_class.new(input).parse_operation }
473
+
474
+ let(:input) { File.read('spec/files/operation.txt') }
475
+
476
+ context 'with a valid input' do
477
+ it 'returns CFONB::Operation' do
478
+ expect(operation).to be_an_instance_of(CFONB::Operation)
479
+ end
480
+
481
+ it 'parses correctly' do
482
+ expect(operation).to have_attributes(
483
+ amount: -32.21,
484
+ currency: 'EUR',
485
+ date: Date.new(2019, 5, 16),
486
+ exoneration_code: '0',
487
+ interbank_code: 'B1',
488
+ internal_code: '9162',
489
+ label: "PRLV SEPA TEST CABINET\nMENSUEAUHTR13133",
490
+ number: 0,
491
+ reference: 'REFERENCE - OTHER REFERENCE',
492
+ rejection_code: '',
493
+ unavailability_code: '0',
494
+ value_date: Date.new(2019, 5, 16),
495
+ original_currency: nil,
496
+ original_amount: nil,
497
+ debtor: 'INTERNET SFR'
498
+ )
499
+ end
500
+ end
501
+
502
+ context 'with an already defined operation' do
503
+ let(:input) { File.read('spec/files/operation_already_defined.txt') }
504
+
505
+ it 'raises AlreadyDefinedOperationError' do
506
+ expect do
507
+ operation
508
+ end.to raise_error(CFONB::AlreadyDefinedOperationError)
509
+ end
510
+ end
511
+
512
+ context 'with an unstarted operation' do
513
+ let(:input) { File.read('spec/files/operation_unstarted.txt') }
514
+
515
+ it 'raises UnstartedOperationError' do
516
+ expect do
517
+ operation
518
+ end.to raise_error(CFONB::UnstartedOperationError)
519
+ end
520
+ end
521
+
522
+ context 'with an unhandled line code' do
523
+ let(:input) { File.read('spec/files/example.txt') }
524
+
525
+ it 'raises UnhandledLineCodeError' do
526
+ expect do
527
+ operation
528
+ end.to raise_error(CFONB::UnhandledLineCodeError)
529
+ end
530
+ end
531
+
532
+ context 'with an optimistic parse' do
533
+ subject(:operation) { described_class.new(input).parse_operation(optimistic: true) }
534
+
535
+ context 'with a valid input' do
536
+ it 'returns CFONB::Operation' do
537
+ expect(operation).to be_an_instance_of(CFONB::Operation)
538
+ end
539
+
540
+ it 'parses correctly' do
541
+ expect(operation).to have_attributes(
542
+ amount: -32.21,
543
+ currency: 'EUR',
544
+ date: Date.new(2019, 5, 16),
545
+ exoneration_code: '0',
546
+ interbank_code: 'B1',
547
+ internal_code: '9162',
548
+ label: "PRLV SEPA TEST CABINET\nMENSUEAUHTR13133",
549
+ number: 0,
550
+ reference: 'REFERENCE - OTHER REFERENCE',
551
+ rejection_code: '',
552
+ unavailability_code: '0',
553
+ value_date: Date.new(2019, 5, 16),
554
+ original_currency: nil,
555
+ original_amount: nil,
556
+ debtor: 'INTERNET SFR'
557
+ )
558
+ end
559
+ end
560
+
561
+ context 'with an already defined operation' do
562
+ let(:input) { File.read('spec/files/operation_already_defined.txt') }
563
+
564
+ it 'ignores the second operation' do
565
+ expect(operation).to have_attributes(
566
+ amount: -32.21,
567
+ currency: 'EUR',
568
+ date: Date.new(2019, 5, 16),
569
+ exoneration_code: '0',
570
+ interbank_code: 'B1',
571
+ internal_code: '9162',
572
+ label: "PRLV SEPA TEST CABINET\nMENSUEAUHTR13133",
573
+ number: 0,
574
+ reference: 'REFERENCE - OTHER REFERENCE',
575
+ rejection_code: '',
576
+ unavailability_code: '0',
577
+ value_date: Date.new(2019, 5, 16),
578
+ original_currency: nil,
579
+ original_amount: nil,
580
+ debtor: 'INTERNET SFR'
581
+ )
582
+ end
583
+ end
584
+
585
+ context 'with an unstarted operation' do
586
+ let(:input) { File.read('spec/files/operation_unstarted.txt') }
587
+
588
+ it 'returns no operation' do
589
+ expect(operation).to be_nil
590
+ end
591
+ end
592
+
593
+ context 'with an unhandled line code' do
594
+ let(:input) { File.read('spec/files/example.txt') }
595
+
596
+ it 'ignores the unhandled lines' do
597
+ expect(operation).to have_attributes(
598
+ amount: -32.21,
599
+ currency: 'EUR',
600
+ date: Date.new(2019, 5, 16),
601
+ exoneration_code: '0',
602
+ interbank_code: 'B1',
603
+ internal_code: '9162',
604
+ label: "PRLV SEPA TEST CABINET\nMENSUEAUHTR13133\nP051928612 22793301700040",
605
+ number: 0,
606
+ reference: 'REFERENCE - OTHER REFERENCE',
607
+ rejection_code: '',
608
+ unavailability_code: '0',
609
+ value_date: Date.new(2019, 5, 16),
610
+ original_currency: nil,
611
+ original_amount: nil,
612
+ debtor: 'ELEC ERDF'
613
+ )
614
+ end
615
+ end
616
+ end
617
+ end
469
618
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfonb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johan Le Bray
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-09-25 00:00:00.000000000 Z
12
+ date: 2023-09-28 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: An easy to use CFONB format parser
15
15
  email: ''
@@ -66,7 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
68
  requirements: []
69
- rubygems_version: 3.4.10
69
+ rubygems_version: 3.3.26
70
70
  signing_key:
71
71
  specification_version: 4
72
72
  summary: CFONB parser