debitcredit 0.1.1 → 0.2.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/README.md +22 -14
- data/app/models/debitcredit/{transaction.rb → entry.rb} +9 -9
- data/app/models/debitcredit/entry/dsl.rb +36 -0
- data/app/models/debitcredit/extension.rb +2 -2
- data/app/models/debitcredit/item.rb +4 -4
- data/config/locales/en.yml +1 -1
- data/db/migrate/20150106165647_rename_transactions.rb +9 -0
- data/lib/debitcredit/version.rb +1 -1
- metadata +7 -6
- data/app/models/debitcredit/transaction/dsl.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d5bcf4938491d376adc5a00d2635bd1d3c7de59
|
4
|
+
data.tar.gz: cb1ec56618c56492739e6f283bd6df21b0789928
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d95a97ce0104513e21e0c354bf24d180b44727119fe738fe7b67ed0a508a48c2c6b9606463d6e7cd7cc737b26e5f0dd2a5b4e24519d57aed3f0aedb1e9c9ce15
|
7
|
+
data.tar.gz: ec3c2ac293655a912936f4455ea97212d57f28f95a42fa4a07a0a73fc95b09d6d73703d9fd5c192749d3b2ff05996166032894affc21360599cd035f609e75d9
|
data/README.md
CHANGED
@@ -7,15 +7,23 @@ Double Entry Accounting for Rails Applications
|
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
10
|
-
* add `
|
10
|
+
* add `gem 'debitcredit'` to your `Gemfile`
|
11
11
|
* and run `bundle install`
|
12
|
-
* run `rake debitcredit:install:migrations db:migrate`
|
12
|
+
* run `rake debitcredit:install:migrations db:migrate db:test:prepare`
|
13
13
|
|
14
|
-
##
|
14
|
+
## Upgrade
|
15
15
|
|
16
16
|
* and run `bundle update debitcredit`
|
17
17
|
* run `rake debitcredit:install:migrations db:migrate`
|
18
18
|
|
19
|
+
### IMPORTANT: version 0.2.0 introduced backwards incompatible changes:
|
20
|
+
|
21
|
+
Transactions were renamed to entries. You need to rename:
|
22
|
+
|
23
|
+
* Transaction to Entry
|
24
|
+
* transactions to entries
|
25
|
+
* has_transactions to has_entries
|
26
|
+
|
19
27
|
## Account Types, Debits and Credits
|
20
28
|
|
21
29
|
<http://en.wikipedia.org/wiki/Debits_and_credits>
|
@@ -27,7 +35,7 @@ Expense and Equity defined as follows:
|
|
27
35
|
from which future economic benefits are expected to flow to the entity
|
28
36
|
|
29
37
|
**Liability** is defined as an obligation of an entity arising from past
|
30
|
-
|
38
|
+
entries or events, the settlement of which may result in the transfer or
|
31
39
|
use of assets, provision of services or other yielding of economic benefits in
|
32
40
|
the future.
|
33
41
|
|
@@ -45,7 +53,7 @@ equity participants.
|
|
45
53
|
difference between the total assets of the entity and all its liabilities.
|
46
54
|
|
47
55
|
|
48
|
-
In each
|
56
|
+
In each entry, sources are credited and destinations are debited.
|
49
57
|
|
50
58
|
I repeat: credit is the **source** and debit is the **destination**.
|
51
59
|
|
@@ -97,7 +105,7 @@ Or better yet:
|
|
97
105
|
include Debitcredit::Extension
|
98
106
|
|
99
107
|
has_accounts
|
100
|
-
|
108
|
+
has_entries do
|
101
109
|
def pay!
|
102
110
|
...
|
103
111
|
end
|
@@ -123,11 +131,11 @@ You can pass a block to `has_accounts` and to define referenced accounts:
|
|
123
131
|
|
124
132
|
User.first.accounts.salary # will be created on first use
|
125
133
|
|
126
|
-
##
|
134
|
+
## Entries
|
127
135
|
|
128
|
-
You can prepare
|
136
|
+
You can prepare entries using DSL:
|
129
137
|
|
130
|
-
t =
|
138
|
+
t = Entry.prepare(description: 'rent payment') do
|
131
139
|
debit expense_account, 100, "you can also provide a comment"
|
132
140
|
credit bank_account, 50
|
133
141
|
credit creditcard, 50
|
@@ -137,21 +145,21 @@ You can prepare transactions using DSL:
|
|
137
145
|
Sum of the debits must be equal to the sum of the credits. Amounts can not be
|
138
146
|
negative.
|
139
147
|
|
140
|
-
You can create
|
148
|
+
You can create entries with a reference. For this case, and in case that
|
141
149
|
reference has 'accounts' association, you can use account names instead of objects:
|
142
150
|
|
143
|
-
t = user1.
|
151
|
+
t = user1.entries.prepare(description: 'sale') do
|
144
152
|
debit :checking, 100 # will use user1.accounts[:checking]
|
145
153
|
credit user2.accounts[:checking], 100
|
146
154
|
end
|
147
155
|
|
148
|
-
You can prepare an inverse
|
149
|
-
existing
|
156
|
+
You can prepare an inverse entry. For example if you want to rollback an
|
157
|
+
existing entry:
|
150
158
|
|
151
159
|
rollback = existing.inverse(kind: 'refund', description: 'item is out of stock')
|
152
160
|
rollback.save!
|
153
161
|
|
154
|
-
> Note: by inverse
|
162
|
+
> Note: by inverse entries are allowed to take accounts into overdraft. if
|
155
163
|
> this is undesirable, pass `enable_overdraft` to the `inverse` call.
|
156
164
|
|
157
165
|
## Contributing
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'docile'
|
2
2
|
module Debitcredit
|
3
|
-
class
|
3
|
+
class Entry < ActiveRecord::Base
|
4
4
|
belongs_to :reference, polymorphic: true
|
5
|
-
belongs_to :
|
6
|
-
has_many :
|
7
|
-
belongs_to :
|
8
|
-
has_many :items, dependent: :destroy, autosave: true
|
5
|
+
belongs_to :parent_entry, class_name: 'Debitcredit::Entry'
|
6
|
+
has_many :child_entries, class_name: 'Debitcredit::Entry', foreign_key: 'parent_entry_id'
|
7
|
+
belongs_to :inverse_entry, class_name: 'Debitcredit::Entry'
|
8
|
+
has_many :items, dependent: :destroy, autosave: true, inverse_of: :entry
|
9
9
|
|
10
10
|
validates :reference, :description, presence: true
|
11
11
|
validate :ensure_balanced
|
@@ -30,8 +30,8 @@ module Debitcredit
|
|
30
30
|
res.description ||= "reverse of tr ##{id}: #{description}"
|
31
31
|
res.kind ||= 'rollback'
|
32
32
|
res.reference ||= reference
|
33
|
-
res.
|
34
|
-
self.
|
33
|
+
res.parent_entry = self
|
34
|
+
self.inverse_entry ||= res
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -56,11 +56,11 @@ module Debitcredit
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def save_parent
|
59
|
-
|
59
|
+
parent_entry.save! if parent_entry.try(:inverse_entry) == self
|
60
60
|
end
|
61
61
|
|
62
62
|
def parent_not_inversed
|
63
|
-
errors.add(:base, :already_inversed) if
|
63
|
+
errors.add(:base, :already_inversed) if parent_entry.inverse_entry_id
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Debitcredit::Entry::Dsl
|
2
|
+
attr_accessor :entry
|
3
|
+
attr_accessor :accounts
|
4
|
+
|
5
|
+
def initialize(entry)
|
6
|
+
@entry = entry
|
7
|
+
end
|
8
|
+
|
9
|
+
def kind(kind)
|
10
|
+
@entry.kind = kind
|
11
|
+
end
|
12
|
+
|
13
|
+
def description(desc)
|
14
|
+
@entry.description = desc
|
15
|
+
end
|
16
|
+
alias desc description
|
17
|
+
|
18
|
+
def reference(ref)
|
19
|
+
@entry.reference = ref
|
20
|
+
end
|
21
|
+
alias ref reference
|
22
|
+
|
23
|
+
def debit(account, amount, comment = nil)
|
24
|
+
build_item true, account, amount, comment
|
25
|
+
end
|
26
|
+
|
27
|
+
def credit(account, amount, comment = nil)
|
28
|
+
build_item false, account, amount, comment
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def build_item(debit, account, amount, comment)
|
33
|
+
account = entry.reference.accounts[account] if account.is_a?(Symbol) && entry.reference.try(:respond_to?, :accounts)
|
34
|
+
entry.items.build debit: debit, account: account, amount: amount, comment: comment
|
35
|
+
end
|
36
|
+
end
|
@@ -18,8 +18,8 @@ module Debitcredit
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
has_many :
|
21
|
+
def has_entries(&block)
|
22
|
+
has_many :entries, as: :reference, class_name: 'Debitcredit::Entry' do
|
23
23
|
def [](kind)
|
24
24
|
find_by kind: kind
|
25
25
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Debitcredit
|
2
2
|
class Item < ActiveRecord::Base
|
3
|
-
belongs_to :
|
3
|
+
belongs_to :entry
|
4
4
|
belongs_to :account
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
validates :entry, :account, presence: true
|
7
|
+
validates :amount, numericality: {greater_than_or_equal_to: 0}
|
8
8
|
|
9
9
|
scope :debit, ->{where(debit: true)}
|
10
10
|
scope :credit, ->{where(debit: false)}
|
@@ -22,7 +22,7 @@ module Debitcredit
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def inverse
|
25
|
-
self.class.new account: account,
|
25
|
+
self.class.new account: account, entry: entry, amount: amount, debit: credit?
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
data/config/locales/en.yml
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
class RenameTransactions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
rename_table :debitcredit_transactions, :debitcredit_entries
|
4
|
+
rename_column :debitcredit_entries, :parent_transaction_id, :parent_entry_id
|
5
|
+
rename_column :debitcredit_entries, :inverse_transaction_id, :inverse_entry_id
|
6
|
+
|
7
|
+
rename_column :debitcredit_items, :transaction_id, :entry_id
|
8
|
+
end
|
9
|
+
end
|
data/lib/debitcredit/version.rb
CHANGED
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: debitcredit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vitaly Kushner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 4.0.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.0.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -189,14 +189,14 @@ files:
|
|
189
189
|
- app/models/debitcredit/asset_account.rb
|
190
190
|
- app/models/debitcredit/credit_account.rb
|
191
191
|
- app/models/debitcredit/debit_account.rb
|
192
|
+
- app/models/debitcredit/entry/dsl.rb
|
193
|
+
- app/models/debitcredit/entry.rb
|
192
194
|
- app/models/debitcredit/equity_account.rb
|
193
195
|
- app/models/debitcredit/expense_account.rb
|
194
196
|
- app/models/debitcredit/extension.rb
|
195
197
|
- app/models/debitcredit/income_account.rb
|
196
198
|
- app/models/debitcredit/item.rb
|
197
199
|
- app/models/debitcredit/liability_account.rb
|
198
|
-
- app/models/debitcredit/transaction/dsl.rb
|
199
|
-
- app/models/debitcredit/transaction.rb
|
200
200
|
- config/locales/en.yml
|
201
201
|
- db/migrate/20140121145455_create_debitcredit_accounts.rb
|
202
202
|
- db/migrate/20140121181304_create_debitcredit_transactions.rb
|
@@ -206,6 +206,7 @@ files:
|
|
206
206
|
- db/migrate/20140128153104_add_account_overdraft.rb
|
207
207
|
- db/migrate/20140130095257_no_overdraft_by_default.rb
|
208
208
|
- db/migrate/20140612113944_add_inverse_transaction_id.rb
|
209
|
+
- db/migrate/20150106165647_rename_transactions.rb
|
209
210
|
- lib/debitcredit/engine.rb
|
210
211
|
- lib/debitcredit/version.rb
|
211
212
|
- lib/debitcredit.rb
|
@@ -1,36 +0,0 @@
|
|
1
|
-
class Debitcredit::Transaction::Dsl
|
2
|
-
attr_accessor :transaction
|
3
|
-
attr_accessor :accounts
|
4
|
-
|
5
|
-
def initialize(transaction)
|
6
|
-
@transaction = transaction
|
7
|
-
end
|
8
|
-
|
9
|
-
def kind(kind)
|
10
|
-
@transaction.kind = kind
|
11
|
-
end
|
12
|
-
|
13
|
-
def description(desc)
|
14
|
-
@transaction.description = desc
|
15
|
-
end
|
16
|
-
alias desc description
|
17
|
-
|
18
|
-
def reference(ref)
|
19
|
-
@transaction.reference = ref
|
20
|
-
end
|
21
|
-
alias ref reference
|
22
|
-
|
23
|
-
def debit(account, amount, comment = nil)
|
24
|
-
build_item true, account, amount, comment
|
25
|
-
end
|
26
|
-
|
27
|
-
def credit(account, amount, comment = nil)
|
28
|
-
build_item false, account, amount, comment
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
def build_item(debit, account, amount, comment)
|
33
|
-
account = transaction.reference.accounts[account] if account.is_a?(Symbol) && transaction.reference.try(:respond_to?, :accounts)
|
34
|
-
transaction.items.build debit: debit, account: account, amount: amount, comment: comment
|
35
|
-
end
|
36
|
-
end
|