forked from betterplace/mt940_parser
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* show reference on postings page * added cheque model for tests in acts_as_account * MT940 bank statements can now get imported into betterplace * add mt940 gem * add field 21 added two regressions: * missing \n\r at end of file * empty lines an beginning of file * encode bank statement strings in utf8 * added currency in field #25 (Account) * new gem version (acts_as_account) * cleanup * funds_code is now kept in bank_statement_lines * added valuta to postings * add bank_statement_lines to accounting controller * refactored dorting * 100 bank_lines per page * all booking is now done in the same transaction context as the frontend. this mean, that when a donation is committed, the Bookkeeper will book it. This simplifies things greatly. * moved bookkeeper code into the domain-objects * tiny html cleanup * fix recently_confirmed in Donation * all features now explicitly tell whet transfers they expect * Bookkeeper can now destroy donations (used in API) * external donations are now booked * If a feature does not either read the generated postings or ignores them an exception will be thrown in the global After block.
- Loading branch information
Thies C. Arntzen
committed
Mar 29, 2010
0 parents
commit fdaea44
Showing
24 changed files
with
4,140 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
README.rdoc | ||
lib/**/*.rb | ||
bin/* | ||
features/**/*.feature | ||
LICENSE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- !ruby/object:Gem::Specification | ||
name: mt940 | ||
version: !ruby/object:Gem::Version | ||
version: 1.0.0 | ||
platform: ruby | ||
authors: [] | ||
|
||
autorequire: | ||
bindir: bin | ||
cert_chain: [] | ||
|
||
date: 2010-03-24 00:00:00 +01:00 | ||
default_executable: | ||
dependencies: [] | ||
|
||
description: | ||
email: | ||
executables: [] | ||
|
||
extensions: [] | ||
|
||
extra_rdoc_files: [] | ||
|
||
files: | ||
- lib | ||
- lib/mt940.rb | ||
has_rdoc: true | ||
homepage: | ||
licenses: [] | ||
|
||
post_install_message: | ||
rdoc_options: [] | ||
|
||
require_paths: | ||
- lib | ||
required_ruby_version: !ruby/object:Gem::Requirement | ||
requirements: | ||
- - ">=" | ||
- !ruby/object:Gem::Version | ||
version: "0" | ||
version: | ||
required_rubygems_version: !ruby/object:Gem::Requirement | ||
requirements: | ||
- - ">=" | ||
- !ruby/object:Gem::Version | ||
version: "0" | ||
version: | ||
requirements: [] | ||
|
||
rubyforge_project: | ||
rubygems_version: 1.3.5 | ||
signing_key: | ||
specification_version: 3 | ||
summary: | ||
test_files: [] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2010 betterplace | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
= mt940 | ||
|
||
Description goes here. | ||
|
||
== Note on Patches/Pull Requests | ||
|
||
* Fork the project. | ||
* Make your feature addition or bug fix. | ||
* Add tests for it. This is important so I don't break it in a | ||
future version unintentionally. | ||
* Commit, do not mess with rakefile, version, or history. | ||
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) | ||
* Send me a pull request. Bonus points for topic branches. | ||
|
||
== Copyright | ||
|
||
Copyright (c) 2010 Thies C. Arntzen. See LICENSE for details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
require 'rubygems' | ||
require 'rake' | ||
|
||
begin | ||
require 'jeweler' | ||
Jeweler::Tasks.new do |gem| | ||
gem.name = "mt940" | ||
gem.summary = %Q{TODO: one-line summary of your gem} | ||
gem.description = %Q{TODO: longer description of your gem} | ||
gem.email = "[email protected]" | ||
gem.homepage = "http://github.com/thieso2/mt940" | ||
gem.authors = ["Thies C. Arntzen"] | ||
gem.add_development_dependency "thoughtbot-shoulda", ">= 0" | ||
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings | ||
end | ||
Jeweler::GemcutterTasks.new | ||
rescue LoadError | ||
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" | ||
end | ||
|
||
require 'rake/testtask' | ||
Rake::TestTask.new(:test) do |test| | ||
test.libs << 'lib' << 'test' | ||
test.pattern = 'test/**/test_*.rb' | ||
test.verbose = true | ||
end | ||
|
||
begin | ||
require 'rcov/rcovtask' | ||
Rcov::RcovTask.new do |test| | ||
test.libs << 'test' | ||
test.pattern = 'test/**/test_*.rb' | ||
test.verbose = true | ||
end | ||
rescue LoadError | ||
task :rcov do | ||
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov" | ||
end | ||
end | ||
|
||
task :test => :check_dependencies | ||
|
||
task :default => :test | ||
|
||
require 'rake/rdoctask' | ||
Rake::RDocTask.new do |rdoc| | ||
version = File.exist?('VERSION') ? File.read('VERSION') : "" | ||
|
||
rdoc.rdoc_dir = 'rdoc' | ||
rdoc.title = "mt940 #{version}" | ||
rdoc.rdoc_files.include('README*') | ||
rdoc.rdoc_files.include('lib/**/*.rb') | ||
end |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added
BIN
+72.9 KB
docs/uebersicht_der_geschaeftsvorfallcodes_und_buchungs_textschluessel.pdf
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
class MT940 | ||
class Field | ||
attr_reader :modifier, :content | ||
|
||
DATE = /(\d{2})(\d{2})(\d{2})/ | ||
SHORT_DATE = /(\d{2})(\d{2})/ | ||
|
||
class << self | ||
|
||
def for(line) | ||
if line.match(/^:(\d{2,2})(\w)?:(.*)$/) | ||
number, modifier, content = $1, $2, $3 | ||
klass = { | ||
'20' => Job, | ||
'21' => Reference, | ||
'25' => Account, | ||
'28' => Statement, | ||
'60' => AccountBalance, | ||
'61' => StatementLine, | ||
'62' => ClosingBalance, | ||
'64' => ValutaBalance, | ||
'65' => FutureValutaBalance, | ||
'86' => StatementLineInformation | ||
}[number] | ||
|
||
raise StandardError, "Field #{number} is not implemented" unless klass | ||
|
||
klass.new(modifier, content) | ||
else | ||
raise StandardError, "Wrong line format: #{line.dump}" | ||
end | ||
end | ||
end | ||
|
||
def initialize(modifier, content) | ||
@modifier = modifier | ||
parse_content(content) | ||
end | ||
|
||
private | ||
def parse_amount_in_cents(amount) | ||
Integer(amount.gsub(',', '')) | ||
end | ||
|
||
def parse_date(date) | ||
date.match(DATE) | ||
Date.new("20#{$1}".to_i, $2.to_i, $3.to_i) | ||
end | ||
|
||
def parse_short_date(year, date) | ||
date.match(SHORT_DATE) | ||
Date.new(year, $1.to_i, $2.to_i) | ||
end | ||
end | ||
|
||
# 20 | ||
class Job < Field | ||
attr_reader :reference | ||
|
||
def parse_content(content) | ||
@reference = content | ||
end | ||
end | ||
|
||
# 21 | ||
class Reference < Job | ||
end | ||
|
||
# 25 | ||
class Account < Field | ||
attr_reader :bank_code, :account_number, :account_currency | ||
|
||
def parse_content(content) | ||
content.match(/^(.{8,11})\/(\d{0,23})([A-Z]{3})?$/) | ||
@bank_code, @account_number, @account_currency = $1, $2, $3 | ||
end | ||
end | ||
|
||
# 28 | ||
class Statement < Field | ||
attr_reader :number, :sheet | ||
|
||
def parse_content(content) | ||
content.match(/^(0|(\d{5,5})\/(\d{2,5}))$/) | ||
if $1 == '0' | ||
@number = @sheet = 0 | ||
else | ||
@number, @sheet = $2.to_i, $3.to_i | ||
end | ||
end | ||
end | ||
|
||
# 60 | ||
class AccountBalance < Field | ||
attr_reader :balance_type, :sign, :currency, :amount, :date | ||
|
||
def parse_content(content) | ||
content.match(/^(C|D)(\w{6})(\w{3})(\d{1,12},\d{0,2})$/) | ||
|
||
@balance_type = case @modifier | ||
when 'F' | ||
:start | ||
when 'M' | ||
:intermediate | ||
end | ||
|
||
@sign = case $1 | ||
when 'C' | ||
:credit | ||
when 'D' | ||
:debit | ||
end | ||
|
||
raw_date = $2 | ||
@currency = $3 | ||
@amount = parse_amount_in_cents($4) | ||
|
||
@date = case raw_date | ||
when 'ALT', '0' | ||
nil | ||
when DATE | ||
Date.new("20#{$1}".to_i, $2.to_i, $3.to_i) | ||
end | ||
end | ||
end | ||
|
||
# 61 | ||
class StatementLine < Field | ||
attr_reader :date, :entry_date, :funds_code, :amount, :swift_code, :reference, :transaction_description | ||
|
||
def parse_content(content) | ||
content.match(/^(\d{6})(\d{4})?(C|D|RC|RD)\D?(\d{1,12},\d{0,2})((?:N|F).{3})(NONREF|.{0,16})(?:$|\/\/)(.*)/).to_a | ||
|
||
raw_date = $1 | ||
raw_entry_date = $2 | ||
@funds_code = case $3 | ||
when 'C' | ||
:credit | ||
when 'D' | ||
:debit | ||
when 'RC' | ||
:return_credit | ||
when 'RD' | ||
:return_debit | ||
end | ||
|
||
@amount = parse_amount_in_cents($4) | ||
@swift_code = $5 | ||
@reference = $6 | ||
@transaction_description = $7 | ||
|
||
@date = parse_date(raw_date) | ||
@entry_date = parse_short_date(@date.year, raw_entry_date) | ||
end | ||
end | ||
|
||
# 62 | ||
class ClosingBalance < AccountBalance | ||
end | ||
|
||
# 64 | ||
class ValutaBalance < AccountBalance | ||
end | ||
|
||
# 65 | ||
class FutureValutaBalance < AccountBalance | ||
end | ||
|
||
# 86 | ||
class StatementLineInformation < Field | ||
attr_reader :code, :transaction_description, :prima_nota, :details, :bank_code, :account_number, | ||
:account_holder, :text_key_extension, :not_implemented_fields | ||
|
||
def parse_content(content) | ||
content.match(/^(\d{3})((.).*)$/) | ||
@code = $1.to_i | ||
|
||
seperator = $3 | ||
sub_fields = $2.scan(/#{Regexp.escape(seperator)}(\d{2})([^#{Regexp.escape(seperator)}]*)/) | ||
|
||
details = [] | ||
account_holder = [] | ||
|
||
sub_fields.each do |(code, content)| | ||
case code.to_i | ||
when 0 | ||
@transaction_description = content | ||
when 10 | ||
@prima_nota = content | ||
when 20..29, 60..63 | ||
details << content | ||
when 30 | ||
@bank_code = content | ||
when 31 | ||
@account_number = content | ||
when 32..33 | ||
account_holder << content | ||
when 34 | ||
@text_key_extension = content | ||
else | ||
@not_implemented_fields ||= [] | ||
@not_implemented_fields << [code, content] | ||
$stderr << "code not implemented: code:#{code} content:»#{content}«\n" if $DEBUG | ||
end | ||
end | ||
|
||
@details = details.join("\n") | ||
@account_holder = account_holder.join("\n") | ||
end | ||
end | ||
|
||
class << self | ||
def parse(text) | ||
text << "\r\n" if text[-1,1] == '-' | ||
raw_sheets = text.split(/^-\r\n/).map { |sheet| sheet.gsub(/\r\n(?!:)/, '') } | ||
sheets = raw_sheets.map { |raw_sheet| parse_sheet(raw_sheet) } | ||
end | ||
|
||
private | ||
def parse_sheet(sheet) | ||
lines = sheet.split("\r\n") | ||
fields = lines.reject { |line| line.empty? }.map { |line| Field.for(line) } | ||
fields | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
:25:51210600/9223382012EUR |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
- - !ruby/object:MT940::Account | ||
account_currency: EUR | ||
account_number: "9223382012" | ||
bank_code: "51210600" | ||
modifier: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
:20:TELEREPORTING |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
- - !ruby/object:MT940::Job | ||
modifier: | ||
reference: TELEREPORTING |
Oops, something went wrong.