keepr 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/ledermann/keepr.svg?branch=master)](https://travis-ci.org/ledermann/keepr)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/ledermann/keepr/badges/gpa.svg)](https://codeclimate.com/github/ledermann/keepr)
|
6
7
|
[![Coverage Status](https://coveralls.io/repos/ledermann/keepr/badge.svg?branch=master)](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
|