keepr 0.2.0 → 0.3.0
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 +4 -4
- data/.travis.yml +0 -3
- data/README.md +3 -1
- data/ci/Gemfile-rails-4-1 +1 -1
- data/ci/Gemfile-rails-4-2 +1 -1
- data/ci/Gemfile-rails-5-0 +2 -2
- data/keepr.gemspec +2 -1
- data/lib/generators/keepr/migration/templates/migration.rb +13 -31
- data/lib/keepr.rb +4 -0
- data/lib/keepr/account_export.rb +35 -0
- data/lib/keepr/contact_export.rb +36 -0
- data/lib/keepr/journal.rb +0 -3
- data/lib/keepr/journal_export.rb +49 -0
- data/lib/keepr/version.rb +1 -1
- data/spec/keepr/account_export_spec.rb +77 -0
- data/spec/keepr/contact_export_spec.rb +61 -0
- data/spec/keepr/journal_export_spec.rb +177 -0
- data/spec/keepr/journal_spec.rb +0 -11
- metadata +27 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c36525234e1c745fd201672cbaa4148c8b024399
|
4
|
+
data.tar.gz: faaf32245ff13cad1025be66f1a6414c56d1cdaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac0e9adcd2ca80ad6e37d95886a06f23385f3dbc99d8a3d008178f0f1ff3cf3a1734016fe7cf033e5b992a0ccb860085c4f89f6bdc8c7beafcf5239ce65b66d1
|
7
|
+
data.tar.gz: 40f93e86f9fb4a259aee40a28d93876a9f6c7e7bc0285164ccf6474fcbdce8fb1337189a57beacb30ed669b81fb5c41e9391b7ef7328be3b96c8ff9e8cf43406
|
data/.travis.yml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 1.9.3
|
4
3
|
- 2.0.0
|
5
4
|
- 2.1.10
|
6
5
|
- 2.2.5
|
@@ -11,8 +10,6 @@ gemfile:
|
|
11
10
|
- ci/Gemfile-rails-5-0
|
12
11
|
matrix:
|
13
12
|
exclude:
|
14
|
-
- rvm: 1.9.3
|
15
|
-
gemfile: ci/Gemfile-rails-5-0
|
16
13
|
- rvm: 2.0.0
|
17
14
|
gemfile: ci/Gemfile-rails-5-0
|
18
15
|
- rvm: 2.1.10
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
This Ruby gem provides a double entry accounting system for use in any Rails application. It stores all the data via ActiveRecord in the SQL database.
|
4
4
|
|
5
5
|
[](https://travis-ci.org/ledermann/keepr)
|
6
|
+
[](https://codeclimate.com/github/ledermann/keepr)
|
6
7
|
[](https://coveralls.io/r/ledermann/keepr?branch=master)
|
7
8
|
|
8
9
|
## Features
|
@@ -13,11 +14,12 @@ This Ruby gem provides a double entry accounting system for use in any Rails app
|
|
13
14
|
* Cost center
|
14
15
|
* Balance sheet
|
15
16
|
* Profit and loss statement
|
17
|
+
* DATEV export
|
16
18
|
|
17
19
|
|
18
20
|
## Dependencies
|
19
21
|
|
20
|
-
* Ruby
|
22
|
+
* Ruby 2.0.0 or later
|
21
23
|
* Rails 4.1 or newer (including Rails 5)
|
22
24
|
|
23
25
|
|
data/ci/Gemfile-rails-4-1
CHANGED
data/ci/Gemfile-rails-4-2
CHANGED
data/ci/Gemfile-rails-5-0
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'activerecord', '5.0.0
|
3
|
+
gem 'activerecord', '~> 5.0.0'
|
4
4
|
gem 'ancestry'
|
5
5
|
gem 'sqlite3'
|
6
6
|
gem 'rake'
|
@@ -9,4 +9,4 @@ gem 'simplecov'
|
|
9
9
|
gem 'coveralls'
|
10
10
|
gem 'database_cleaner'
|
11
11
|
gem 'factory_girl'
|
12
|
-
gem '
|
12
|
+
gem 'datev'
|
data/keepr.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.summary = %q{Some basic ActiveRecord models to build a double entry bookkeeping application}
|
13
13
|
spec.homepage = 'https://github.com/ledermann/keepr'
|
14
14
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = '>=
|
15
|
+
spec.required_ruby_version = '>= 2.0.0'
|
16
16
|
|
17
17
|
spec.files = `git ls-files`.split($/)
|
18
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency 'activerecord', '>= 4.1'
|
23
23
|
spec.add_dependency 'ancestry'
|
24
|
+
spec.add_dependency 'datev', '>= 0.4.0'
|
24
25
|
|
25
26
|
spec.add_development_dependency 'bundler'
|
26
27
|
spec.add_development_dependency 'rake'
|
@@ -5,18 +5,14 @@ class KeeprMigration < ActiveRecord::Migration
|
|
5
5
|
t.string :number
|
6
6
|
t.string :name, :null => false
|
7
7
|
t.boolean :is_result, :null => false, :default => false
|
8
|
-
t.string :ancestry
|
9
|
-
|
10
|
-
t.index :ancestry
|
8
|
+
t.string :ancestry, :index => true
|
11
9
|
end
|
12
10
|
|
13
11
|
create_table Keepr::Tax, force: true do |t|
|
14
12
|
t.string :name, :null => false
|
15
13
|
t.string :description
|
16
14
|
t.decimal :value, :precision => 8, :scale => 2, :null => false
|
17
|
-
t.references :keepr_account, :null => false
|
18
|
-
|
19
|
-
t.index :keepr_account_id
|
15
|
+
t.references :keepr_account, :null => false, :index => true
|
20
16
|
end
|
21
17
|
|
22
18
|
create_table Keepr::CostCenter, force: true do |t|
|
@@ -26,48 +22,34 @@ class KeeprMigration < ActiveRecord::Migration
|
|
26
22
|
end
|
27
23
|
|
28
24
|
create_table Keepr::Account, force: true do |t|
|
29
|
-
t.integer :number, :null => false
|
30
|
-
t.string :ancestry
|
25
|
+
t.integer :number, :null => false, :index => true
|
26
|
+
t.string :ancestry, :index => true
|
31
27
|
t.string :name, :null => false
|
32
28
|
t.integer :kind, :null => false
|
33
|
-
t.references :keepr_group
|
34
|
-
t.references :accountable, :polymorphic => true
|
35
|
-
t.references :keepr_tax
|
29
|
+
t.references :keepr_group, :index => true
|
30
|
+
t.references :accountable, :polymorphic => true, :index => true
|
31
|
+
t.references :keepr_tax, :index => true
|
36
32
|
t.datetime :created_at
|
37
33
|
t.datetime :updated_at
|
38
|
-
|
39
|
-
t.index :number
|
40
|
-
t.index :ancestry
|
41
|
-
t.index [:accountable_type, :accountable_id]
|
42
|
-
t.index :keepr_group_id
|
43
|
-
t.index :keepr_tax_id
|
44
34
|
end
|
45
35
|
|
46
36
|
create_table Keepr::Journal, force: true do |t|
|
47
37
|
t.string :number
|
48
|
-
t.date :date, :null => false
|
38
|
+
t.date :date, :null => false, :index => true
|
49
39
|
t.string :subject
|
50
|
-
t.references :accountable, :polymorphic => true
|
40
|
+
t.references :accountable, :polymorphic => true, :index => true
|
51
41
|
t.text :note
|
52
42
|
t.boolean :permanent, :null => false, :default => false
|
53
43
|
t.datetime :created_at
|
54
44
|
t.datetime :updated_at
|
55
|
-
|
56
|
-
t.index :date
|
57
|
-
t.index [:accountable_type, :accountable_id], :name => 'index_keepr_journals_on_accountable'
|
58
45
|
end
|
59
46
|
|
60
47
|
create_table Keepr::Posting, force: true do |t|
|
61
|
-
t.references :keepr_account, :null => false
|
62
|
-
t.references :keepr_journal, :null => false
|
48
|
+
t.references :keepr_account, :null => false, :index => true
|
49
|
+
t.references :keepr_journal, :null => false, :index => true
|
63
50
|
t.decimal :amount, :precision => 8, :scale => 2, :null => false
|
64
|
-
t.references :keepr_cost_center
|
65
|
-
t.references :accountable, :polymorphic => true
|
66
|
-
|
67
|
-
t.index :keepr_account_id
|
68
|
-
t.index :keepr_journal_id
|
69
|
-
t.index :keepr_cost_center_id
|
70
|
-
t.index [:accountable_type, :accountable_id]
|
51
|
+
t.references :keepr_cost_center, :index => true
|
52
|
+
t.references :accountable, :polymorphic => true, :index => true
|
71
53
|
end
|
72
54
|
end
|
73
55
|
|
data/lib/keepr.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'ancestry'
|
2
|
+
require 'datev'
|
2
3
|
|
3
4
|
require 'keepr/version'
|
4
5
|
require 'keepr/group'
|
@@ -8,6 +9,9 @@ require 'keepr/tax'
|
|
8
9
|
require 'keepr/account'
|
9
10
|
require 'keepr/posting'
|
10
11
|
require 'keepr/journal'
|
12
|
+
require 'keepr/journal_export'
|
13
|
+
require 'keepr/account_export'
|
14
|
+
require 'keepr/contact_export'
|
11
15
|
require 'keepr/active_record_extension'
|
12
16
|
|
13
17
|
class ActiveRecord::Base
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Keepr::AccountExport
|
2
|
+
def initialize(accounts, header_options={}, &block)
|
3
|
+
@accounts = accounts
|
4
|
+
@header_options = header_options
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
export.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_file(filename)
|
13
|
+
export.to_file(filename)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def export
|
19
|
+
export = Datev::AccountExport.new(@header_options)
|
20
|
+
|
21
|
+
@accounts.reorder(:number).each do |account|
|
22
|
+
unless account.debtor? || account.creditor?
|
23
|
+
export << to_datev(account)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
export
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_datev(account)
|
31
|
+
{ 'Konto' => account.number,
|
32
|
+
'Kontenbeschriftung' => account.name.slice(0,40)
|
33
|
+
}.merge(@block ? @block.call(account) : {})
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Keepr::ContactExport
|
2
|
+
def initialize(accounts, header_options={}, &block)
|
3
|
+
raise ArgumentError unless block_given?
|
4
|
+
|
5
|
+
@accounts = accounts
|
6
|
+
@header_options = header_options
|
7
|
+
@block = block
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_s
|
11
|
+
export.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_file(filename)
|
15
|
+
export.to_file(filename)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def export
|
21
|
+
export = Datev::ContactExport.new(@header_options)
|
22
|
+
|
23
|
+
@accounts.reorder(:number).each do |account|
|
24
|
+
if account.debtor? || account.creditor?
|
25
|
+
export << to_datev(account)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
export
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_datev(account)
|
33
|
+
{ 'Konto' => account.number
|
34
|
+
}.merge(@block.call(account))
|
35
|
+
end
|
36
|
+
end
|
data/lib/keepr/journal.rb
CHANGED
@@ -44,9 +44,6 @@ private
|
|
44
44
|
if existing_postings.map(&:keepr_account_id).uniq.length < 2
|
45
45
|
# At least two accounts have to be booked
|
46
46
|
errors.add :base, :account_missing
|
47
|
-
elsif existing_postings.select(&:debit?).count > 1 && existing_postings.select(&:credit?).count > 1
|
48
|
-
# A split is allowed either on debit or credit, not both
|
49
|
-
errors.add :base, :split_on_both_sides
|
50
47
|
elsif existing_postings.map(&:raw_amount).compact.sum != 0
|
51
48
|
# Debit does not match credit
|
52
49
|
errors.add :base, :amount_mismatch
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class Keepr::JournalExport
|
2
|
+
def initialize(journals, header_options={}, &block)
|
3
|
+
@journals = journals
|
4
|
+
@header_options = header_options
|
5
|
+
@block = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
export.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_file(filename)
|
13
|
+
export.to_file(filename)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def export
|
19
|
+
export = Datev::BookingExport.new(@header_options)
|
20
|
+
|
21
|
+
@journals.includes(:keepr_postings => :keepr_account).reorder(:date, :id).each do |journal|
|
22
|
+
to_datev(journal).each do |hash|
|
23
|
+
export << hash
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
export
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_datev(journal)
|
31
|
+
main_posting = journal.keepr_postings.find { |p| p.keepr_account.debtor? || p.keepr_account.creditor? }
|
32
|
+
main_posting ||= journal.keepr_postings.sort_by(&:amount).last
|
33
|
+
|
34
|
+
journal.keepr_postings.sort_by { |p| [ p.side == main_posting.side ? 1 : 0, -p.amount ] }.map do |posting|
|
35
|
+
next if posting == main_posting
|
36
|
+
|
37
|
+
{ 'Umsatz (ohne Soll/Haben-Kz)' => posting.amount,
|
38
|
+
'Soll/Haben-Kennzeichen' => 'S',
|
39
|
+
'Konto' => posting.debit? ? posting.keepr_account.number : main_posting.keepr_account.number,
|
40
|
+
'Gegenkonto (ohne BU-Schlüssel)' => posting.credit? ? posting.keepr_account.number : main_posting.keepr_account.number,
|
41
|
+
'BU-Schlüssel' => '40', # Steuerautomatik deaktivieren
|
42
|
+
'Belegdatum' => journal.date,
|
43
|
+
'Belegfeld 1' => journal.number,
|
44
|
+
'Buchungstext' => journal.subject.slice(0,60),
|
45
|
+
'Festschreibung' => journal.permanent
|
46
|
+
}.merge(@block ? @block.call(posting) : {})
|
47
|
+
end.compact
|
48
|
+
end
|
49
|
+
end
|
data/lib/keepr/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Keepr::AccountExport do
|
4
|
+
let!(:account_1000) { FactoryGirl.create :account, :kind => :asset, :number => 1000, :name => 'Kasse' }
|
5
|
+
let!(:account_1776) { FactoryGirl.create :account, :kind => :liability, :number => 1776, :name => 'Umsatzsteuer 19 %' }
|
6
|
+
let!(:account_4920) { FactoryGirl.create :account, :kind => :expense, :number => 4920, :name => 'Telefon' }
|
7
|
+
let!(:account_8400) { FactoryGirl.create :account, :kind => :revenue, :number => 8400, :name => 'Erlöse 19 %' }
|
8
|
+
let!(:account_9000) { FactoryGirl.create :account, :kind => :neutral, :number => 9000, :name => 'Saldenvorträge Sachkonten' }
|
9
|
+
let!(:account_10000) { FactoryGirl.create :account, :kind => :creditor, :number => 10000, :name => 'Diverse Kreditoren' }
|
10
|
+
let!(:account_70000) { FactoryGirl.create :account, :kind => :debtor, :number => 70000, :name => 'Diverse Debitoren' }
|
11
|
+
|
12
|
+
let(:scope) { Keepr::Account.all }
|
13
|
+
|
14
|
+
let(:export) {
|
15
|
+
Keepr::AccountExport.new(scope,
|
16
|
+
'Berater' => 1234567,
|
17
|
+
'Mandant' => 78901,
|
18
|
+
'WJ-Beginn' => Date.new(2016,1,1),
|
19
|
+
'Bezeichnung' => 'Keepr-Konten'
|
20
|
+
) do |account|
|
21
|
+
{ 'Sprach-ID' => 'de-DE' }
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
describe :to_s do
|
26
|
+
subject { export.to_s }
|
27
|
+
|
28
|
+
def account_lines
|
29
|
+
subject.lines[2..-1].map { |line| line.encode(Encoding::UTF_8) }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return CSV lines" do
|
33
|
+
subject.lines.each { |line| expect(line).to include(';') }
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should include header data" do
|
37
|
+
expect(subject.lines[0]).to include('1234567;')
|
38
|
+
expect(subject.lines[0]).to include('78901;')
|
39
|
+
expect(subject.lines[0]).to include('Keepr-Konten;')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should include all accounts except debtor/creditor" do
|
43
|
+
expect(account_lines.count).to eq(5)
|
44
|
+
|
45
|
+
expect(account_lines[0]).to include('1000;')
|
46
|
+
expect(account_lines[0]).to include('Kasse;')
|
47
|
+
|
48
|
+
expect(account_lines[1]).to include('1776;')
|
49
|
+
expect(account_lines[1]).to include('Umsatzsteuer 19 %;')
|
50
|
+
|
51
|
+
expect(account_lines[2]).to include('4920;')
|
52
|
+
expect(account_lines[2]).to include('Telefon;')
|
53
|
+
|
54
|
+
expect(account_lines[3]).to include('8400;')
|
55
|
+
expect(account_lines[3]).to include('Erlöse 19 %;')
|
56
|
+
|
57
|
+
expect(account_lines[4]).to include('9000;')
|
58
|
+
expect(account_lines[4]).to include('Saldenvorträge Sachkonten;')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should include data from block" do
|
62
|
+
expect(account_lines[0]).to include(';de-DE')
|
63
|
+
expect(account_lines[1]).to include(';de-DE')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe :to_file do
|
68
|
+
it "should create CSV file" do
|
69
|
+
Dir.mktmpdir do |dir|
|
70
|
+
filename = "#{dir}/EXTF_Kontenbeschriftungen.csv"
|
71
|
+
export.to_file(filename)
|
72
|
+
|
73
|
+
expect(File).to exist(filename)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Keepr::ContactExport do
|
4
|
+
let!(:account_1000) { FactoryGirl.create :account, :kind => :asset, :number => 1000, :name => 'Kasse' }
|
5
|
+
let!(:account_10000) { FactoryGirl.create :account, :kind => :creditor, :number => 10000, :name => 'Meyer GmbH' }
|
6
|
+
let!(:account_70000) { FactoryGirl.create :account, :kind => :debtor, :number => 70000, :name => 'Schulze AG' }
|
7
|
+
|
8
|
+
let(:scope) { Keepr::Account.all }
|
9
|
+
|
10
|
+
let(:export) {
|
11
|
+
Keepr::ContactExport.new(scope,
|
12
|
+
'Berater' => 1234567,
|
13
|
+
'Mandant' => 78901,
|
14
|
+
'WJ-Beginn' => Date.new(2016,1,1),
|
15
|
+
'Bezeichnung' => 'Keepr-Kontakte'
|
16
|
+
) do |account|
|
17
|
+
{ 'Kurzbezeichnung' => account.name }
|
18
|
+
end
|
19
|
+
}
|
20
|
+
|
21
|
+
describe :to_s do
|
22
|
+
subject { export.to_s }
|
23
|
+
|
24
|
+
def account_lines
|
25
|
+
subject.lines[2..-1]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return CSV lines" do
|
29
|
+
subject.lines.each { |line| expect(line).to include(';') }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should include header data" do
|
33
|
+
expect(subject.lines[0]).to include('1234567;')
|
34
|
+
expect(subject.lines[0]).to include('78901;')
|
35
|
+
expect(subject.lines[0]).to include('Keepr-Kontakte;')
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should include debtor/creditor accounts only" do
|
39
|
+
expect(account_lines.count).to eq(2)
|
40
|
+
|
41
|
+
expect(account_lines[0]).to include('10000;')
|
42
|
+
expect(account_lines[1]).to include('70000;')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should include data from block" do
|
46
|
+
expect(account_lines[0]).to include('Meyer GmbH;')
|
47
|
+
expect(account_lines[1]).to include('Schulze AG;')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe :to_file do
|
52
|
+
it "should create CSV file" do
|
53
|
+
Dir.mktmpdir do |dir|
|
54
|
+
filename = "#{dir}/EXTF_Stammdaten.csv"
|
55
|
+
export.to_file(filename)
|
56
|
+
|
57
|
+
expect(File).to exist(filename)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Keepr::JournalExport do
|
4
|
+
let(:ust) { Keepr::Tax.create! :name => 'USt19', :value => 19.0, :keepr_account => account_1776 }
|
5
|
+
let(:vst) { Keepr::Tax.create! :name => 'VSt19', :value => 19.0, :keepr_account => account_1576 }
|
6
|
+
|
7
|
+
let(:account_1000) { FactoryGirl.create :account, :number => 1000, :kind => :asset }
|
8
|
+
let(:account_1200) { FactoryGirl.create :account, :number => 1200, :kind => :asset }
|
9
|
+
let(:account_1576) { FactoryGirl.create :account, :number => 1576, :kind => :asset }
|
10
|
+
let(:account_1776) { FactoryGirl.create :account, :number => 1776, :kind => :liability }
|
11
|
+
let(:account_1600) { FactoryGirl.create :account, :number => 1600, :kind => :liability }
|
12
|
+
let(:account_1718) { FactoryGirl.create :account, :number => 1718, :kind => :liability, :keepr_tax => ust }
|
13
|
+
let(:account_4920) { FactoryGirl.create :account, :number => 4920, :kind => :expense, :keepr_tax => vst }
|
14
|
+
let(:account_8400) { FactoryGirl.create :account, :number => 8400, :kind => :revenue, :keepr_tax => ust }
|
15
|
+
|
16
|
+
let(:account_10000) { FactoryGirl.create :account, :number => 10000, :kind => :debtor }
|
17
|
+
|
18
|
+
let(:scope) { Keepr::Journal.reorder(:number) }
|
19
|
+
|
20
|
+
let(:export) {
|
21
|
+
Keepr::JournalExport.new(scope,
|
22
|
+
'Berater' => 1234567,
|
23
|
+
'Mandant' => 78901,
|
24
|
+
'Datum vom' => Date.new(2016,6,1),
|
25
|
+
'Datum bis' => Date.new(2016,6,30),
|
26
|
+
'WJ-Beginn' => Date.new(2016,1,1),
|
27
|
+
'Bezeichnung' => 'Keepr-Buchungen'
|
28
|
+
) do |posting|
|
29
|
+
{ 'Identifikationsnummer' => "ID:#{posting.id}" }
|
30
|
+
end
|
31
|
+
}
|
32
|
+
|
33
|
+
describe :to_s do
|
34
|
+
subject { export.to_s }
|
35
|
+
|
36
|
+
def booking_lines
|
37
|
+
subject.lines[2..-1]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return CSV lines" do
|
41
|
+
expect(subject.lines.count).to eq(2)
|
42
|
+
subject.lines.each { |line| expect(line).to include(';') }
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should include header data" do
|
46
|
+
expect(subject.lines[0]).to include('1234567;')
|
47
|
+
expect(subject.lines[0]).to include('78901;')
|
48
|
+
expect(subject.lines[0]).to include('20160601;20160630;')
|
49
|
+
expect(subject.lines[0]).to include('Keepr-Buchungen;')
|
50
|
+
end
|
51
|
+
|
52
|
+
context "Journal without tax" do
|
53
|
+
let!(:journal_without_tax) do
|
54
|
+
Keepr::Journal.create! :number => 'BELEG-1',
|
55
|
+
:subject => 'Geldautomat',
|
56
|
+
:date => Date.new(2016,06,23),
|
57
|
+
:keepr_postings_attributes => [
|
58
|
+
{ :keepr_account => account_1000, :amount => 105, :side => 'debit' },
|
59
|
+
{ :keepr_account => account_1200, :amount => 105, :side => 'credit' }
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should include data" do
|
64
|
+
expect(booking_lines.count).to eq(1)
|
65
|
+
|
66
|
+
expect(booking_lines[0]).to include('Geldautomat;')
|
67
|
+
expect(booking_lines[0]).to include('1000;1200;')
|
68
|
+
expect(booking_lines[0]).to include('105,00;')
|
69
|
+
expect(booking_lines[0]).to include(';S;')
|
70
|
+
expect(booking_lines[0]).to include('2306;')
|
71
|
+
expect(booking_lines[0]).to include('BELEG-1;')
|
72
|
+
expect(booking_lines[0]).to include(';0;')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "Journal with tax" do
|
77
|
+
let!(:journal_with_tax) do
|
78
|
+
Keepr::Journal.create! :number => 'BELEG-2',
|
79
|
+
:subject => 'Telefonrechnung',
|
80
|
+
:date => Date.new(2016,06,24),
|
81
|
+
:keepr_postings_attributes => [
|
82
|
+
{ :keepr_account => account_4920, :amount => 8.40, :side => 'debit' },
|
83
|
+
{ :keepr_account => account_1576, :amount => 1.60, :side => 'debit' },
|
84
|
+
{ :keepr_account => account_1600, :amount => 10.00, :side => 'credit' }
|
85
|
+
]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should include data" do
|
89
|
+
expect(booking_lines.count).to eq(2)
|
90
|
+
|
91
|
+
expect(booking_lines[0]).to include('Telefonrechnung;')
|
92
|
+
expect(booking_lines[0]).to include('4920;1600;')
|
93
|
+
expect(booking_lines[0]).to include('8,40;')
|
94
|
+
expect(booking_lines[0]).to include(';S;')
|
95
|
+
expect(booking_lines[0]).to include('2406;')
|
96
|
+
expect(booking_lines[0]).to include('BELEG-2;')
|
97
|
+
expect(booking_lines[0]).to include(';0;')
|
98
|
+
|
99
|
+
expect(booking_lines[1]).to include('Telefonrechnung;')
|
100
|
+
expect(booking_lines[1]).to include('1576;1600;')
|
101
|
+
expect(booking_lines[1]).to include('1,60;')
|
102
|
+
expect(booking_lines[1]).to include(';S;')
|
103
|
+
expect(booking_lines[1]).to include('2406;')
|
104
|
+
expect(booking_lines[1]).to include('BELEG-2;')
|
105
|
+
expect(booking_lines[1]).to include(';0;')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "Journal with debtor" do
|
110
|
+
let!(:journal_with_debtor) do
|
111
|
+
Keepr::Journal.create! :number => 'BELEG-3',
|
112
|
+
:subject => 'Warenverkauf mit Anzahlung',
|
113
|
+
:date => Date.new(2016,06,25),
|
114
|
+
:keepr_postings_attributes => [
|
115
|
+
{ :keepr_account => account_10000, :amount => 4760.00, :side => 'debit' },
|
116
|
+
{ :keepr_account => account_1718, :amount => 1000.00, :side => 'debit' },
|
117
|
+
{ :keepr_account => account_1776, :amount => 190.00, :side => 'debit' },
|
118
|
+
|
119
|
+
{ :keepr_account => account_8400, :amount => 5000.00, :side => 'credit' },
|
120
|
+
{ :keepr_account => account_1776, :amount => 950.00, :side => 'credit' }
|
121
|
+
]
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should include data" do
|
125
|
+
expect(booking_lines.count).to eq(4)
|
126
|
+
|
127
|
+
expect(booking_lines[0]).to include('Warenverkauf mit Anzahlung;')
|
128
|
+
expect(booking_lines[0]).to include('10000;8400;')
|
129
|
+
expect(booking_lines[0]).to include('5000,00;')
|
130
|
+
expect(booking_lines[0]).to include(';S;')
|
131
|
+
expect(booking_lines[0]).to include('2506;')
|
132
|
+
expect(booking_lines[0]).to include('BELEG-3;')
|
133
|
+
expect(booking_lines[0]).to include(';0;')
|
134
|
+
|
135
|
+
expect(booking_lines[1]).to include('Warenverkauf mit Anzahlung;')
|
136
|
+
expect(booking_lines[1]).to include('10000;1776;')
|
137
|
+
expect(booking_lines[1]).to include('950,00;')
|
138
|
+
expect(booking_lines[1]).to include(';S;')
|
139
|
+
expect(booking_lines[1]).to include('2506;')
|
140
|
+
expect(booking_lines[1]).to include('BELEG-3;')
|
141
|
+
expect(booking_lines[1]).to include(';0;')
|
142
|
+
|
143
|
+
expect(booking_lines[2]).to include('Warenverkauf mit Anzahlung;')
|
144
|
+
expect(booking_lines[2]).to include('1718;10000;')
|
145
|
+
expect(booking_lines[2]).to include('1000,00;')
|
146
|
+
expect(booking_lines[2]).to include(';S;')
|
147
|
+
expect(booking_lines[2]).to include('2506;')
|
148
|
+
expect(booking_lines[2]).to include('BELEG-3;')
|
149
|
+
expect(booking_lines[2]).to include(';0;')
|
150
|
+
|
151
|
+
expect(booking_lines[3]).to include('Warenverkauf mit Anzahlung;')
|
152
|
+
expect(booking_lines[3]).to include('1776;10000;')
|
153
|
+
expect(booking_lines[3]).to include('190,00;')
|
154
|
+
expect(booking_lines[3]).to include(';S;')
|
155
|
+
expect(booking_lines[3]).to include('2506;')
|
156
|
+
expect(booking_lines[3]).to include('BELEG-3;')
|
157
|
+
expect(booking_lines[3]).to include(';0;')
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should include data from block" do
|
161
|
+
expect(booking_lines[0]).to include('ID:')
|
162
|
+
expect(booking_lines[1]).to include('ID:')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe :to_file do
|
168
|
+
it "should create CSV file" do
|
169
|
+
Dir.mktmpdir do |dir|
|
170
|
+
filename = "#{dir}/EXTF_Buchungsstapel.csv"
|
171
|
+
export.to_file(filename)
|
172
|
+
|
173
|
+
expect(File).to exist(filename)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/spec/keepr/journal_spec.rb
CHANGED
@@ -60,17 +60,6 @@ describe Keepr::Journal do
|
|
60
60
|
expect(journal.errors.added? :base, :account_missing).to eq(true)
|
61
61
|
end
|
62
62
|
|
63
|
-
it 'should fail for journal with multiple postings on both sides' do
|
64
|
-
journal = Keepr::Journal.create :keepr_postings_attributes => [
|
65
|
-
{ :keepr_account => account_1000, :amount => 5.00, :side => 'debit' },
|
66
|
-
{ :keepr_account => account_1200, :amount => 5.00, :side => 'debit' },
|
67
|
-
{ :keepr_account => account_4910, :amount => 7.00, :side => 'credit' },
|
68
|
-
{ :keepr_account => account_4920, :amount => 3.00, :side => 'credit' }
|
69
|
-
]
|
70
|
-
expect(journal).not_to be_valid
|
71
|
-
expect(journal.errors.added? :base, :split_on_both_sides).to eq(true)
|
72
|
-
end
|
73
|
-
|
74
63
|
it 'should fail for booking the same account twice' do
|
75
64
|
journal = Keepr::Journal.create :keepr_postings_attributes => [
|
76
65
|
{ :keepr_account => account_1000, :amount => 10, :side => 'debit' },
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keepr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Georg Ledermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: datev
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.4.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,7 +184,9 @@ files:
|
|
170
184
|
- lib/generators/keepr/migration/templates/migration.rb
|
171
185
|
- lib/keepr.rb
|
172
186
|
- lib/keepr/account.rb
|
187
|
+
- lib/keepr/account_export.rb
|
173
188
|
- lib/keepr/active_record_extension.rb
|
189
|
+
- lib/keepr/contact_export.rb
|
174
190
|
- lib/keepr/cost_center.rb
|
175
191
|
- lib/keepr/group.rb
|
176
192
|
- lib/keepr/groups_creator.rb
|
@@ -178,6 +194,7 @@ files:
|
|
178
194
|
- lib/keepr/groups_creator/liability.txt
|
179
195
|
- lib/keepr/groups_creator/profit_and_loss.txt
|
180
196
|
- lib/keepr/journal.rb
|
197
|
+
- lib/keepr/journal_export.rb
|
181
198
|
- lib/keepr/posting.rb
|
182
199
|
- lib/keepr/tax.rb
|
183
200
|
- lib/keepr/version.rb
|
@@ -186,11 +203,14 @@ files:
|
|
186
203
|
- spec/factories/cost_center.rb
|
187
204
|
- spec/factories/group.rb
|
188
205
|
- spec/factories/tax.rb
|
206
|
+
- spec/keepr/account_export_spec.rb
|
189
207
|
- spec/keepr/account_spec.rb
|
190
208
|
- spec/keepr/active_record_extension_spec.rb
|
209
|
+
- spec/keepr/contact_export_spec.rb
|
191
210
|
- spec/keepr/cost_center_spec.rb
|
192
211
|
- spec/keepr/group_spec.rb
|
193
212
|
- spec/keepr/groups_creator_spec.rb
|
213
|
+
- spec/keepr/journal_export_spec.rb
|
194
214
|
- spec/keepr/journal_spec.rb
|
195
215
|
- spec/keepr/posting_spec.rb
|
196
216
|
- spec/keepr/tax_spec.rb
|
@@ -211,7 +231,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
211
231
|
requirements:
|
212
232
|
- - ">="
|
213
233
|
- !ruby/object:Gem::Version
|
214
|
-
version:
|
234
|
+
version: 2.0.0
|
215
235
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
236
|
requirements:
|
217
237
|
- - ">="
|
@@ -219,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
219
239
|
version: '0'
|
220
240
|
requirements: []
|
221
241
|
rubyforge_project:
|
222
|
-
rubygems_version: 2.6.
|
242
|
+
rubygems_version: 2.6.6
|
223
243
|
signing_key:
|
224
244
|
specification_version: 4
|
225
245
|
summary: Some basic ActiveRecord models to build a double entry bookkeeping application
|
@@ -229,11 +249,14 @@ test_files:
|
|
229
249
|
- spec/factories/cost_center.rb
|
230
250
|
- spec/factories/group.rb
|
231
251
|
- spec/factories/tax.rb
|
252
|
+
- spec/keepr/account_export_spec.rb
|
232
253
|
- spec/keepr/account_spec.rb
|
233
254
|
- spec/keepr/active_record_extension_spec.rb
|
255
|
+
- spec/keepr/contact_export_spec.rb
|
234
256
|
- spec/keepr/cost_center_spec.rb
|
235
257
|
- spec/keepr/group_spec.rb
|
236
258
|
- spec/keepr/groups_creator_spec.rb
|
259
|
+
- spec/keepr/journal_export_spec.rb
|
237
260
|
- spec/keepr/journal_spec.rb
|
238
261
|
- spec/keepr/posting_spec.rb
|
239
262
|
- spec/keepr/tax_spec.rb
|