norma43 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README +11 -0
- data/Rakefile +2 -0
- data/autotest/discover.rb +1 -0
- data/doc/descripcion_ficheros_n43.txt +93 -0
- data/doc/norma_43.pdf +0 -0
- data/lib/norma43.rb +60 -0
- data/lib/norma43/version.rb +3 -0
- data/norma43.gemspec +23 -0
- data/spec/spec_helper.rb +20 -0
- metadata +90 -0
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Parser for NORMA43 Files. (a standard from the spanish banking industry for account movements)
|
2
|
+
|
3
|
+
Usage
|
4
|
+
=====
|
5
|
+
|
6
|
+
require 'lib/norma43'
|
7
|
+
data = Norma43.read(PATH_TO_FILE)
|
8
|
+
|
9
|
+
Until we write a better documentation, check what is being read with:
|
10
|
+
|
11
|
+
puts data.to_yaml
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
@@ -0,0 +1,93 @@
|
|
1
|
+
2. Contenido de Registros
|
2
|
+
|
3
|
+
- Cabecera de cuenta.
|
4
|
+
- Principal de movimientos.
|
5
|
+
- En su caso, complementarios de conceptos, hasta un máximo de 5 registros opcionales.
|
6
|
+
- Final de cuenta.
|
7
|
+
- Final de fichero
|
8
|
+
|
9
|
+
Dentro de un mismo soporte magnético puede venir contenida información de más de una cuenta (esto es, se pueden repetir los cuatro primeros bloques)
|
10
|
+
|
11
|
+
Los registros opcionales "Complementarios de concepto", hasta un máximo de 5, contienen dos campos con una longitud de 38 posiciones cada uno de ellos. En su caso de no ser necesarios los dos campos, el no utilizado irá en blanco.
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
00-REGISTRO CABECERA DE ARCHIVO
|
16
|
+
|
17
|
+
DESCRIPCION CAMPO POS LONGITUD TIPO
|
18
|
+
Código de Registro, 2 posiciones 00 1 2 NUM
|
19
|
+
Clave de Banco que constituye el fichero 3 4 NUM
|
20
|
+
Fecha Contable del periodo al que corresponde la información AAMMDD 7 6 NUM
|
21
|
+
Libre: 68 posiciones 13 68 ---
|
22
|
+
|
23
|
+
|
24
|
+
11-REGISTRO DE CABECERA DE CUENTA
|
25
|
+
|
26
|
+
DESCRIPCION CAMPO POS LONGITUD TIPO
|
27
|
+
Código de Registro, 2 posiciones (11) 1 2 NUM
|
28
|
+
Clave de Banco que constituye el fichero 3 4 NUM
|
29
|
+
Clave de Oficina donde está la cuenta 7 4 NUM
|
30
|
+
No de Cuenta 11 10 NUM
|
31
|
+
Fecha Inicial del periodo AAMMDD 21 6 NUM
|
32
|
+
Fecha Final del periodo AAMMDD 27 6 NUM
|
33
|
+
Código de saldo inicial, signo del campo inicial: 1deudor, 2 acreedor 33 1 NUM
|
34
|
+
Importe del saldo inicial de la cuenta, 2 decimales 34 14 NUM
|
35
|
+
Clase de Divisa, clave numérica 48 3 NUM
|
36
|
+
Código de la Modalidad de Información (en este caso es:3) 51 1 NUM
|
37
|
+
Nombre abreviado (del Cliente Propietario de la Cuenta) 52 26 ALFANUM
|
38
|
+
Código del Cliente 78 3 NUM
|
39
|
+
|
40
|
+
|
41
|
+
22 REGISTRO PRINCIPAL DE MOVIMIENTOS
|
42
|
+
|
43
|
+
DESCRIPCION CAMPO POS LONGITUD TIPO
|
44
|
+
Código de Registro, 22 1 2 NUM
|
45
|
+
Libre (relleno a espacios. excepcionalmente la clave de banco) 3 4 ---
|
46
|
+
Clave de Oficina de origen( donde se formaliza el apunte ) 7 4 NUM
|
47
|
+
Fecha de Operación AAMMDD 11 6 NUM
|
48
|
+
Fecha de Valor AAMMDD 17 6 NUM
|
49
|
+
Concepto común 23 2 NUM
|
50
|
+
Concepto Propio (el de cada Banco para sus operaciones) 25 3 NUM
|
51
|
+
Clave Debe o Haber: 1= Apuntes Debe, 2= Apuntes Haber 28 1 NUM
|
52
|
+
Importe(del Apunte, 12 posiciones para enteros y 2 para decimales) 29 14 NUM
|
53
|
+
No de Documento 43 10 NUM
|
54
|
+
Referencia 1 53 12 NUM
|
55
|
+
Referencia 2 65 16 ALFANUM
|
56
|
+
|
57
|
+
|
58
|
+
23-REGISTROS COMPLEMENTARIOS DE CONCEPTOS OPCIONALES (5 máximo)
|
59
|
+
|
60
|
+
DESCRIPCION CAMPO POS LONGITUD TIPO
|
61
|
+
Código de Registro, 23 1 2 NUM
|
62
|
+
Código de Dato: 01 para el primer registro complementario, 3 2 NUM
|
63
|
+
02 para el segundo, 03 para el tercero, 04 para el cuarto,
|
64
|
+
05 para el quinto
|
65
|
+
Concepto (Primer Campo complementario de Concepto) 5 38 ALFANUM
|
66
|
+
Concepto (Segundo Campo complementario de Concepto) 43 38 ALFANUM
|
67
|
+
|
68
|
+
|
69
|
+
33-REGISTRO FINAL DE CUENTA
|
70
|
+
|
71
|
+
DESCRIPCION CAMPO POS LONGITUD TIPO
|
72
|
+
Código de Registro, 2 posiciones (33) 1 2 NUM
|
73
|
+
Clave de Banco que constituye el fichero 3 4 NUM
|
74
|
+
Clave de Oficina donde está la cuenta 7 4 NUM
|
75
|
+
No de Cuenta 11 10 NUM
|
76
|
+
No de Apunte Debe 21 5 NUM
|
77
|
+
Total Importes Debe 26 14 NUM
|
78
|
+
No Apuntes Haber 40 5 NUM
|
79
|
+
Total Importes Haber 45 14 NUM
|
80
|
+
Código de Saldo Final: 1= Deudor, 2= Acreedor 59 1 NUM
|
81
|
+
Importe de Saldo Final 60 14 NUM
|
82
|
+
Clave de Divisa 74 3 NUM
|
83
|
+
Libre 77 4 ---
|
84
|
+
|
85
|
+
88-REGISTRO FIN DE FICHERO
|
86
|
+
|
87
|
+
DESCRIPCION CAMPO POS LONGITUD TIPO
|
88
|
+
Código de Registro, 2 posiciones (88) 1 2 NUM
|
89
|
+
Nueves (relleno a Nueves) 3 18 NUM
|
90
|
+
No de Registro (No Total de Registros que contiene el Fichero, 21 6 NUM
|
91
|
+
excluyéndose a si mismo y al registro 00 Cabecera de Archivo)
|
92
|
+
Libre 27 54 ---
|
93
|
+
|
data/doc/norma_43.pdf
ADDED
Binary file
|
data/lib/norma43.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Norma43
|
2
|
+
|
3
|
+
DATE_FORMAT = '%y%m%d'
|
4
|
+
|
5
|
+
def self.read(path_to_file)
|
6
|
+
data = Hash.new
|
7
|
+
data[:movements] = Array.new
|
8
|
+
File.open(path_to_file, "r").each_line do |line|
|
9
|
+
code = line[0..1]
|
10
|
+
data[:info] = self.parse_header(line) if code == '11'
|
11
|
+
data[:movements] << self.parse_movement_main(line) if code == '22'
|
12
|
+
#TODO support multiple '23' lines (there may be up to 5)
|
13
|
+
data[:movements].last.merge!(self.parse_movement_optional(line)) if code == '23'
|
14
|
+
#TODO check amount values against those on record 33
|
15
|
+
data[:info].merge!(self.parse_end(line)) if code == '33'
|
16
|
+
#TODO parse record 88, end of file
|
17
|
+
end
|
18
|
+
data
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def self.parse_header(line)
|
24
|
+
account = {:bank => line[2..5].to_s, :office => line[6..9].to_s,
|
25
|
+
:number => line[10..19].to_s, :control => "??"}
|
26
|
+
{
|
27
|
+
:account => account,
|
28
|
+
:begin_date => Date.strptime(line[20..25], DATE_FORMAT), #Date.from_nor43(line[20..25])
|
29
|
+
:end_date => Date.strptime(line[26..31], DATE_FORMAT),
|
30
|
+
:initial_balance => parse_amount(line[33..46], line[32]),
|
31
|
+
:account_owner => line[51..76].strip,
|
32
|
+
:currency => line[47..49]
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.parse_movement_main(line)
|
37
|
+
{
|
38
|
+
:operation_date => Date.strptime(line[10..15], DATE_FORMAT),
|
39
|
+
:value_date => Date.strptime(line[16..21], DATE_FORMAT),
|
40
|
+
:operation => line[42..51],
|
41
|
+
:reference_1 => line[52..63],
|
42
|
+
:reference_2 => line[64..79].strip,
|
43
|
+
:amount => parse_amount(line[28..41], line[27]),
|
44
|
+
:office => line[6..9]
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.parse_movement_optional(line)
|
49
|
+
{:concept => line[4, 79].strip}
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.parse_end(line)
|
53
|
+
{:final_balance => parse_amount(line[59..72], line[28])}
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.parse_amount(value, sign)
|
57
|
+
value.to_f / 100 * (sign == 1 ? -1 : 1)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/norma43.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "norma43/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "norma43"
|
7
|
+
s.version = Norma43::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Linking Paths"]
|
10
|
+
s.email = ["hello@linkingpaths.com"]
|
11
|
+
s.homepage = "https://github.com/linkingpaths/norma43"
|
12
|
+
s.summary = %q{A parser for norma43 files, a standard from the spanish banking industry for account movements)}
|
13
|
+
s.description = %q{A parser for norma43 files, a standard from the spanish banking industry for account movements)}
|
14
|
+
|
15
|
+
s.rubyforge_project = "norma43"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
3
|
+
#require File.expand_path("../../config/environment", __FILE__)
|
4
|
+
require File.expand_path("../../spec/factories", __FILE__)
|
5
|
+
|
6
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
7
|
+
# in spec/support/ and its subdirectories.
|
8
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
# == Mock Framework
|
12
|
+
#
|
13
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
14
|
+
#
|
15
|
+
# config.mock_with :mocha
|
16
|
+
# config.mock_with :flexmock
|
17
|
+
# config.mock_with :rr
|
18
|
+
config.mock_with :rspec
|
19
|
+
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: norma43
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Linking Paths
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-06-16 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: A parser for norma43 files, a standard from the spanish banking industry for account movements)
|
35
|
+
email:
|
36
|
+
- hello@linkingpaths.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- README
|
47
|
+
- Rakefile
|
48
|
+
- autotest/discover.rb
|
49
|
+
- doc/descripcion_ficheros_n43.txt
|
50
|
+
- doc/norma_43.pdf
|
51
|
+
- lib/norma43.rb
|
52
|
+
- lib/norma43/version.rb
|
53
|
+
- norma43.gemspec
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: https://github.com/linkingpaths/norma43
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: norma43
|
85
|
+
rubygems_version: 1.3.7
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: A parser for norma43 files, a standard from the spanish banking industry for account movements)
|
89
|
+
test_files:
|
90
|
+
- spec/spec_helper.rb
|