norma43_parser 1.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.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +85 -0
  5. data/Rakefile +1 -0
  6. data/doc/classes.jpg +0 -0
  7. data/doc/cuaderno_43_-_junio_2012.pdf +800 -1
  8. data/lib/norma43/line_handlers.rb +54 -0
  9. data/lib/norma43/line_parsers/file_format_validator.rb +19 -0
  10. data/lib/norma43/line_parsers/line_parser.rb +42 -0
  11. data/lib/norma43/line_parsers/line_parsers.rb +69 -0
  12. data/lib/norma43/line_processors.rb +60 -0
  13. data/lib/norma43/models.rb +85 -0
  14. data/lib/norma43/parser.rb +79 -0
  15. data/lib/norma43/utils/contexts.rb +54 -0
  16. data/lib/norma43/utils/string_helpers.rb +10 -0
  17. data/lib/norma43/utils/typecaster.rb +19 -0
  18. data/lib/norma43/version.rb +3 -0
  19. data/lib/norma43.rb +8 -0
  20. data/norma43_parser.gemspec +27 -0
  21. data/spec/example1_parse_spec.rb +91 -0
  22. data/spec/fixtures/example1.n43 +10 -0
  23. data/spec/norma43/line_parsers/account_end_spec.rb +51 -0
  24. data/spec/norma43/line_parsers/account_start_spec.rb +55 -0
  25. data/spec/norma43/line_parsers/additional_currency_spec.rb +27 -0
  26. data/spec/norma43/line_parsers/additional_items_spec.rb +23 -0
  27. data/spec/norma43/line_parsers/document_end_spec.rb +16 -0
  28. data/spec/norma43/line_parsers/document_start_spec.rb +32 -0
  29. data/spec/norma43/line_parsers/transaction_spec.rb +55 -0
  30. data/spec/norma43/line_processors/account_end_spec.rb +34 -0
  31. data/spec/norma43/line_processors/account_start_spec.rb +40 -0
  32. data/spec/norma43/line_processors/additional_currency_spec.rb +42 -0
  33. data/spec/norma43/line_processors/additional_items_spec.rb +42 -0
  34. data/spec/norma43/line_processors/document_end_spec.rb +30 -0
  35. data/spec/norma43/line_processors/document_start_spec.rb +27 -0
  36. data/spec/norma43/line_processors/transaction_spec.rb +42 -0
  37. data/spec/norma43/parser_spec.rb +23 -0
  38. data/spec/norma43_spec.rb +13 -0
  39. data/spec/spec_helper.rb +20 -0
  40. data/spec/support/shared_examples_for_values_line_parsers.rb +15 -0
  41. metadata +173 -0
@@ -0,0 +1,54 @@
1
+ require "norma43/line_parsers/line_parsers"
2
+ require "norma43/line_processors"
3
+
4
+ module Norma43
5
+ module LineHandlers
6
+ def self.mapping
7
+ {
8
+ "00" => self.document_start,
9
+ "88" => self.document_end,
10
+ "11" => self.account_start,
11
+ "33" => self.account_end,
12
+ "22" => self.transaction,
13
+ "23" => self.additional_item,
14
+ "24" => self.additional_currency
15
+ }
16
+ end
17
+
18
+ def self.document_start
19
+ Handler.new LineParsers::DocumentStart, LineProcessors::DocumentStart
20
+ end
21
+
22
+ def self.document_end
23
+ Handler.new LineParsers::DocumentEnd, LineProcessors::DocumentEnd
24
+ end
25
+
26
+ def self.account_start
27
+ Handler.new LineParsers::AccountStart, LineProcessors::AccountStart
28
+ end
29
+
30
+ def self.account_end
31
+ Handler.new LineParsers::AccountEnd, LineProcessors::AccountEnd
32
+ end
33
+
34
+ def self.transaction
35
+ Handler.new LineParsers::Transaction, LineProcessors::Transaction
36
+ end
37
+
38
+ def self.additional_item
39
+ Handler.new LineParsers::AdditionalItem, LineProcessors::AdditionalItem
40
+ end
41
+
42
+ def self.additional_currency
43
+ Handler.new LineParsers::AdditionalCurrency, LineProcessors::AdditionalCurrency
44
+ end
45
+
46
+ Handler = Struct.new :parser, :processor do
47
+ def process line, contexts
48
+ line_parser = self.parser.new(line)
49
+
50
+ processor.call line_parser, contexts
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,19 @@
1
+ require "norma43/line_parsers/line_parser"
2
+ module Norma43
3
+ class FileFormatValidator < LineParser
4
+ field :record_type, 0..1, :raw
5
+ field :file_type, 36..38
6
+
7
+ def has_document?; file_type=="00" end
8
+
9
+ def valid?
10
+ errors.empty?
11
+ end
12
+
13
+ def errors
14
+ errors = []
15
+ %w(11 00).include? record_type or errors << "Must start with 00 (was ”#{record_type}”)"
16
+ errors
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,42 @@
1
+ require "norma43/utils/typecaster"
2
+
3
+ module Norma43
4
+ class LineParser
5
+ attr_reader :line
6
+ def initialize line
7
+ @line = line
8
+ end
9
+
10
+ def attributes
11
+ self.class.field_names.each_with_object({}) do |field, attrs|
12
+ attrs[field] = self.public_send(field)
13
+ end
14
+ end
15
+
16
+ def self.field name, range, type = :string
17
+ self.field_names.push name
18
+
19
+ define_method name do
20
+ if range.is_a?(Array) # let multivalued attribute
21
+ range.map { |r| value_at_position(r, type) }.compact
22
+ else
23
+ value_at_position range, type
24
+ end
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def self.field_names
31
+ @field_names ||= []
32
+ end
33
+
34
+ def value_at_position range, type
35
+ typecast line[range].to_s.strip, type
36
+ end
37
+
38
+ def typecast value, type
39
+ Typecaster.cast value, type
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,69 @@
1
+ require "norma43/line_parsers/line_parser"
2
+
3
+ module Norma43
4
+ module LineParsers
5
+ class DocumentStart < LineParser
6
+ field :id, 2..13
7
+ field :created_at, 14..33, :time
8
+ field :delivery_number, 34..35, :integer
9
+ field :file_type, 36..38
10
+ field :name, 39..48
11
+ end
12
+
13
+ class DocumentEnd < LineParser
14
+ field :record_number, 20..25, :integer
15
+ end
16
+
17
+ class AccountStart < LineParser
18
+ field :bank_code, 2..5, :integer
19
+ field :branch_code, 6..9, :integer
20
+ field :account_number, 10..19, :integer
21
+ field :start_date, 20..25, :date
22
+ field :end_date, 26..31, :date
23
+ field :balance_code, 32, :integer
24
+ field :balance_amount, 33..46, :integer
25
+ field :currency_code, 47..49, :integer
26
+ field :information_mode_code, 50, :integer
27
+ field :abbreviated_name, 51..76
28
+ end
29
+
30
+ class AccountEnd < LineParser
31
+ field :bank_code, 2..5, :integer
32
+ field :branch_code, 6..9, :integer
33
+ field :account_number, 10..19, :integer
34
+ field :debit_entries, 20..24, :integer
35
+ field :debit_amount, 25..38, :integer
36
+ field :credit_entries, 39..43, :integer
37
+ field :credit_amount, 44..57, :integer
38
+ field :balance_code, 58, :integer
39
+ field :balance_amount, 59..72, :integer
40
+ field :currency_code, 73..75, :integer
41
+ end
42
+
43
+ class Transaction < LineParser
44
+ field :origin_branch_code, 6..9, :integer
45
+ field :transaction_date, 10..15, :date
46
+ field :value_date, 16..21, :date
47
+ field :shared_item, 22..23, :integer
48
+ field :own_item, 24..26, :integer
49
+ field :amount_code, 27, :integer
50
+ field :amount, 28..41, :integer
51
+ field :document_number, 42..51, :integer
52
+ field :reference_1, 52..63, :integer
53
+ field :reference_2, 64..79
54
+ end
55
+
56
+ class AdditionalItem < LineParser
57
+ field :data_code, 2..3, :integer
58
+ field :item_1, 4..41
59
+ field :item_2, 42..79
60
+ end
61
+
62
+ class AdditionalCurrency < LineParser
63
+ field :data_code, 2..3, :integer
64
+ field :currency_code, 4..6, :integer
65
+ field :amount, 7..20, :integer
66
+ field :free, 21..79
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ require "norma43/models"
2
+ module Norma43
3
+ module LineProcessors
4
+ DocumentStart = ->(line, contexts) {
5
+ document = Models::Document.new line.attributes
6
+
7
+ contexts.add document
8
+
9
+ contexts
10
+ }
11
+
12
+ DocumentEnd = ->(line, contexts) {
13
+ contexts.move_to Models::Document
14
+ contexts.current.number_of_lines = line.record_number
15
+ contexts
16
+ }
17
+
18
+ AccountStart = ->(line, contexts) {
19
+ contexts.move_to Models::Document
20
+ account = Models::Account.new line.attributes
21
+ contexts.current.accounts << account
22
+ contexts.add account
23
+
24
+ contexts
25
+ }
26
+
27
+ AccountEnd = ->(line, contexts) {
28
+ contexts.move_to Models::Account
29
+ contexts.current.attributes = line.attributes
30
+ contexts
31
+ }
32
+
33
+ Transaction = ->(line, contexts) {
34
+ contexts.move_to Models::Account
35
+
36
+ transaction = Models::Transaction.new line.attributes
37
+
38
+ contexts.current.transactions << transaction
39
+
40
+ contexts.add transaction
41
+
42
+ contexts
43
+ }
44
+
45
+ AdditionalItem = ->(line, contexts) {
46
+ contexts.move_to Models::Transaction
47
+ additional_item = Models::AdditionalItem.new line.attributes
48
+ contexts.current.additional_items << additional_item
49
+ contexts
50
+ }
51
+
52
+ AdditionalCurrency = ->(line, contexts) {
53
+ contexts.move_to Models::Transaction
54
+ additional_currency = Models::AdditionalCurrency.new line.attributes
55
+ contexts.current.additional_currency = additional_currency
56
+ contexts
57
+ }
58
+
59
+ end
60
+ end
@@ -0,0 +1,85 @@
1
+ require "norma43/utils/string_helpers"
2
+ require 'virtus'
3
+
4
+ module Norma43
5
+ module Models
6
+ #forward declarations
7
+ class Account; end
8
+ class Transaction; end
9
+ class AdditionalItem; end
10
+ class AdditionalCurrency; end
11
+ DEBIT_CODE = 1
12
+ CREDIT_CODE = 2
13
+
14
+ class Document
15
+ include Virtus.model
16
+
17
+ attribute :id
18
+ attribute :created_at
19
+ attribute :delivery_number
20
+ attribute :file_type
21
+ attribute :name
22
+ attribute :number_of_lines
23
+ attribute :accounts, Array[Account]
24
+
25
+ def transaction_date
26
+ accounts.map(&:date).compact.first
27
+ end
28
+ end
29
+
30
+ class Account
31
+ include Virtus.model
32
+
33
+ attribute :bank_code
34
+ attribute :branch_code
35
+ attribute :account_number
36
+ attribute :start_date
37
+ attribute :end_date
38
+ attribute :balance_code
39
+ attribute :balance_amount
40
+ attribute :currency_code
41
+ attribute :information_mode_code
42
+ attribute :abbreviated_name
43
+ attribute :debit_entries
44
+ attribute :debit_amount
45
+ attribute :credit_entries
46
+ attribute :credit_amount
47
+ attribute :transactions, Array[Transaction]
48
+ end
49
+
50
+ class Transaction
51
+ include Virtus.model
52
+
53
+ attribute :origin_branch_code
54
+ attribute :transaction_date
55
+ attribute :value_date
56
+ attribute :shared_item
57
+ attribute :own_item
58
+ attribute :amount_code
59
+ attribute :amount
60
+ attribute :document_number
61
+ attribute :reference_1
62
+ attribute :reference_2
63
+ attribute :additional_items, Array[AdditionalItem]
64
+ attribute :additional_currency, AdditionalCurrency
65
+ def debit?; self.amount_code==DEBIT_CODE end
66
+ end
67
+
68
+ class AdditionalItem
69
+ include Virtus.model
70
+
71
+ attribute :data_code
72
+ attribute :item_1
73
+ attribute :item_2
74
+ end
75
+
76
+ class AdditionalCurrency
77
+ include Virtus.model
78
+
79
+ attribute :data_code
80
+ attribute :currency_code
81
+ attribute :amount
82
+ attribute :free
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,79 @@
1
+ require "norma43/line_parsers/file_format_validator"
2
+ require "norma43/line_handlers"
3
+ require "norma43/utils/contexts"
4
+
5
+ module Norma43
6
+ class InvalidFileFormatError < ArgumentError; end;
7
+
8
+ class Parser
9
+ attr_reader :file
10
+
11
+ # Parser.new accepts a File instance or a String
12
+ # A InvalidFileFormatError will be raised if file isn't in the Norma43 format
13
+ def initialize file
14
+ @file = file
15
+ validator = validate_file_format
16
+ @contexts = if validator.has_document?
17
+ Contexts.new
18
+ else
19
+ # in theory Norma43 says that files should start with DocumentStart but
20
+ # practically doesn't happen, so that we create one artificially
21
+ # to avoid corner cases in the processors
22
+ Contexts.new().tap { |ctx| ctx.add Models::Document.new }
23
+ end
24
+ end
25
+
26
+ def result
27
+ parse_lines(@contexts).result
28
+ end
29
+
30
+ protected
31
+
32
+ def lines
33
+ @lines ||= file.each_line
34
+ end
35
+
36
+ private
37
+
38
+ def validate_file_format
39
+ validator = FileFormatValidator.new first_line
40
+ raise InvalidFileFormatError.new(validator.errors.join(", ")) unless validator.valid?
41
+ validator
42
+ end
43
+
44
+ def parse_lines contexts
45
+ parse_lines parse_line(self.lines.next, contexts)
46
+
47
+ rescue StopIteration# because lines is an enumerator raises StopIteration on end
48
+ self.lines.rewind # Ensure we do not bomb out when calling result multiple times
49
+ contexts
50
+ end
51
+
52
+ # Look up a matching handler for the line and process it
53
+ # The process method on a handler always returns a Contexts object
54
+ def parse_line line, contexts
55
+ line = line.encode Encoding::UTF_8 if encode_lines?
56
+
57
+ handler = handler_for_line line
58
+
59
+ handler.process line, contexts
60
+ end
61
+
62
+ def handler_for_line line
63
+ LineHandlers.mapping.fetch line[0..1]
64
+ end
65
+
66
+ def encode_lines?
67
+ first_line.encoding != Encoding::UTF_8
68
+ end
69
+
70
+ def first_line
71
+ @first_line ||= begin
72
+ line = self.lines.peek
73
+ self.lines.rewind # peek seems to move the pointer when file is an actual File object
74
+
75
+ line
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,54 @@
1
+ module Norma43
2
+ class Contexts
3
+ def initialize containers = nil
4
+ Array(containers).compact.each do |container|
5
+ add container
6
+ end
7
+ end
8
+
9
+ def result
10
+ contexts.first
11
+ end
12
+
13
+ def current
14
+ contexts.last
15
+ end
16
+
17
+ def add container
18
+ contexts.push container
19
+ end
20
+
21
+ def move_up
22
+ contexts.pop
23
+ end
24
+
25
+ def move_to container_class
26
+ until current.is_a?(container_class) or current.nil?
27
+ move_up
28
+ end if contexts.any?
29
+ end
30
+
31
+ def move_to_or_add_to_parent container_class, parent_container_class
32
+ return self if current.is_a?(container_class)
33
+
34
+ until current.kind_of?(parent_container_class)
35
+ move_up
36
+ end
37
+
38
+ entity = container_class.new
39
+
40
+ setter_name = StringHelpers.underscore container_class.name.split("::").last
41
+ current.public_send "#{setter_name}=", entity
42
+
43
+ add entity
44
+
45
+ self
46
+ end
47
+
48
+ private
49
+
50
+ def contexts
51
+ @contexts ||= []
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,10 @@
1
+ module Norma43
2
+ module StringHelpers
3
+ def self.underscore word
4
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
5
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
6
+ word.tr!("-", "_")
7
+ word.downcase
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ require "time"
2
+
3
+ module Norma43
4
+ module Typecaster
5
+ def self.cast value, type
6
+ casters.fetch(type).call(value) unless value == ""
7
+ end
8
+
9
+ def self.casters
10
+ {
11
+ integer: ->(value) { value.to_i },
12
+ time: ->(value) { Time.strptime(value, "%Y%m%d%H%M%S%N") },
13
+ date: ->(value) { Date.strptime(value, "%y%m%d") },
14
+ string: ->(value) { value unless value.match(/\A0+\Z/) },
15
+ raw: ->(value) { value }
16
+ }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Norma43
2
+ VERSION = "1.0.1"
3
+ end
data/lib/norma43.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "norma43/version"
2
+ require "norma43/parser"
3
+
4
+ module Norma43
5
+ def self.parse text
6
+ Parser.new(text).result
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "norma43/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "norma43_parser"
8
+ spec.version = Norma43::VERSION
9
+ spec.authors = ["Sequra engineering"]
10
+ spec.email = ["dev@sequra.es"]
11
+ spec.summary = %q{Parses banks transactions files specified in rule 43}
12
+ spec.homepage = "https://github.com/sequra/norma43_parser"
13
+ spec.license = "MIT"
14
+
15
+ spec.required_ruby_version = "~> 2.0"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.5"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "byebug"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_runtime_dependency "virtus"
27
+ end
@@ -0,0 +1,91 @@
1
+ require "norma43"
2
+
3
+ RSpec.describe Norma43 do
4
+ describe "parse" do
5
+
6
+ let(:document) do
7
+ file = File.open( File.join(__dir__, "fixtures/example1.n43"),
8
+ encoding: "iso-8859-1")
9
+ Norma43.parse file
10
+ end
11
+
12
+ it "finds one account" do
13
+ expect(document.accounts.size).to eq 1
14
+ end
15
+
16
+ describe "first account" do
17
+ let(:account) { document.accounts.first }
18
+
19
+ it "stores expected attributes from AccountStart parser" do
20
+ expect(account).to have_attributes({
21
+ "bank_code" => 9999,
22
+ "branch_code" => 1111,
23
+ "account_number" => 123456789,
24
+ "start_date" => Date.parse("2004-08-04"),
25
+ "end_date" => Date.parse("2004-09-05"),
26
+ "currency_code" => 1,
27
+ "information_mode_code" => 3,
28
+ "abbreviated_name" => "MY ACCOUNT"
29
+ })
30
+ end
31
+
32
+ it "stores expected attributes from AccountEnd parser" do
33
+ expect(account).to have_attributes({
34
+ "balance_code" => 2,
35
+ "balance_amount" => 78889999999999,
36
+ "debit_entries" => 4,
37
+ "debit_amount" => 4936,
38
+ "credit_entries" => 2,
39
+ "credit_amount" => 999999,
40
+ })
41
+ end
42
+
43
+ describe "transactions" do
44
+ it "finds all transactions" do
45
+ expect(account.transactions.size).to eq 4
46
+ end
47
+
48
+ describe "first transaction" do
49
+ let(:transaction) { account.transactions[0] }
50
+ it "stores expected attributes" do
51
+ expect(transaction).to have_attributes({
52
+ "origin_branch_code" => 6700,
53
+ "transaction_date" => Date.parse("2004-04-08"),
54
+ "value_date" => Date.parse("2004-04-08"),
55
+ "shared_item" => 4,
56
+ "own_item" => 7,
57
+ "amount_code" => 2,
58
+ "amount" => 1234,
59
+ "document_number" => 0,
60
+ "reference_1" => 0,
61
+ "reference_2" => nil,
62
+ })
63
+ end
64
+ end
65
+
66
+ it "each transaction has 5 additional_items as a maximum" do
67
+ account.transactions.each do |transaction|
68
+ expect(transaction.additional_items.size).to be <= 5
69
+ end
70
+ end
71
+
72
+ describe "first additional item" do
73
+ let(:additional_item) { account.transactions[0].additional_items[0]}
74
+ it "stores expected attributes" do
75
+ expect(additional_item).to have_attributes({
76
+ "data_code" => 1,
77
+ "item_1" => "XXXXXXXXX",
78
+ "item_2" => nil
79
+ })
80
+ end
81
+ end
82
+
83
+ describe "first additional currency" do
84
+ xit "stores expected attributes" do
85
+ # We don't have exaples to write test write when have
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,10 @@
1
+ 119999111101234567890408040409052000000001234569783MY ACCOUNT
2
+ 2212346700040408040408040072000000000012340000000000000000000000
3
+ 2301XXXXXXXXX
4
+ 2212346700040408040408040072000000000012340000000000000000000000
5
+ 2301A28152585
6
+ 2256781128040405040405040072000000000012340000000000000000000000
7
+ 2301XXXXXXXXX
8
+ 2256781127040805040805020092000000000012340000000000000000000000
9
+ 2301REF XXXXXXXXX
10
+ 3399991111012345678900004000000000049360000200000000999999278889999999999001
@@ -0,0 +1,51 @@
1
+ require "norma43/line_parsers/line_parsers"
2
+
3
+ module Norma43
4
+ module LineParsers
5
+ RSpec.describe AccountEnd do
6
+ let :account_end do
7
+ AccountEnd.new "3399991111012345678900004000000000049360000200000000999999278889999999999001 "
8
+ end
9
+
10
+ it "parses the bank code" do
11
+ expect(account_end.bank_code).to eq 9999
12
+ end
13
+
14
+ it "parses the branch code" do
15
+ expect(account_end.branch_code).to eq 1111
16
+ end
17
+
18
+ it "parses the account number" do
19
+ expect(account_end.account_number).to eq 123456789
20
+ end
21
+
22
+ it "parses the number of debit entries" do
23
+ expect(account_end.debit_entries).to eq 4
24
+ end
25
+
26
+ it "parses the total of debit amounts" do
27
+ expect(account_end.debit_amount).to eq 4936
28
+ end
29
+
30
+ it "parses the number of credit entries" do
31
+ expect(account_end.credit_entries).to eq 2
32
+ end
33
+
34
+ it "parses the total of credit amounts" do
35
+ expect(account_end.credit_amount).to eq 999999
36
+ end
37
+
38
+ it "parses the final balance code" do
39
+ expect(account_end.balance_code).to eq 2
40
+ end
41
+
42
+ it "parses the final balance amount" do
43
+ expect(account_end.balance_amount).to eq 78889999999999
44
+ end
45
+
46
+ it "parses the currency code" do
47
+ expect(account_end.currency_code).to eq 1
48
+ end
49
+ end
50
+ end
51
+ end