plutus 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +64 -41
- data/app/controllers/plutus/entries_controller.rb +44 -0
- data/app/models/plutus/account.rb +2 -2
- data/app/models/plutus/amount.rb +2 -2
- data/app/models/plutus/credit_amount.rb +2 -2
- data/app/models/plutus/debit_amount.rb +2 -2
- data/app/models/plutus/{transaction.rb → entry.rb} +16 -16
- data/app/views/plutus/accounts/index.html.erb +1 -1
- data/app/views/plutus/accounts/show.html.erb +8 -8
- data/app/views/plutus/{transactions → entries}/index.html.erb +8 -8
- data/app/views/plutus/{transactions → entries}/show.html.erb +6 -6
- data/config/routes.rb +1 -1
- data/lib/generators/plutus/USAGE +14 -3
- data/lib/generators/plutus/templates/migration.rb +6 -6
- data/lib/generators/plutus/templates/update_migration.rb +17 -0
- data/lib/generators/plutus/upgrade_plutus_generator.rb +28 -0
- data/lib/plutus/version.rb +1 -1
- data/spec/controllers/entries_controller_spec.rb +28 -0
- data/spec/factories/amount_factory.rb +3 -3
- data/spec/factories/entry_factory.rb +11 -0
- data/spec/models/account_spec.rb +7 -7
- data/spec/models/entry_spec.rb +91 -0
- data/spec/routing/{transactions_routing_spec.rb → entries_routing_spec.rb} +7 -7
- data/spec/support/account_shared_examples.rb +2 -2
- data/spec/support/amount_shared_examples.rb +2 -2
- metadata +17 -100
- data/app/assets/stylesheets/plutus/main.css.scss +0 -86
- data/app/controllers/plutus/transactions_controller.rb +0 -44
- data/spec/controllers/transactions_controller_spec.rb +0 -28
- data/spec/factories/transaction_factory.rb +0 -11
- data/spec/models/transaction_spec.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b7e154fa51d2feeed2fe1a92ee94404e93e0c4c
|
4
|
+
data.tar.gz: 4f930fb7a207a410155f5a3a78226bd9ae405255
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2d96b662e4333bf68214ab7686ee8fa11ceb981f815c905949c2ffa13effd75da42c8d64dafb7c597f707453d69ace8d05f3335e76beae854b372495e4d0fc7
|
7
|
+
data.tar.gz: a09ab9ba1b8793dfc96efde6e389828ef34019d6313676e7fc08e53ecc5771aac96cffb00c6fd6ed19b0950c9403bba2837e8791138c7a5b516ed1de183bdbba
|
data/README.markdown
CHANGED
@@ -7,7 +7,7 @@ The Plutus plugin is a Ruby on Rails Engine which provides a double entry accoun
|
|
7
7
|
Compatibility
|
8
8
|
=============
|
9
9
|
|
10
|
-
* Ruby versions: MRI 1.9.3, MRI 2.0, MRI 2.1
|
10
|
+
* Ruby versions: MRI 1.9.3, MRI 2.0, MRI 2.1, Rubinius 2.2, JRuby 1.7+,f
|
11
11
|
* Rails versions: ~> 4.0
|
12
12
|
|
13
13
|
For the rails 3 version, you can go here:
|
@@ -18,8 +18,9 @@ For the rails 2 version, you can go here:
|
|
18
18
|
|
19
19
|
[https://github.com/mbulat/plutus/tree/rails2](https://github.com/mbulat/plutus/tree/rails2)
|
20
20
|
|
21
|
-
Gems in RubyGems.org >= 0.5.0 support Rails 3
|
22
|
-
Gems in RubyGems.org >= 0.8.0 support Rails 4
|
21
|
+
* Gems in RubyGems.org >= 0.5.0 support Rails 3
|
22
|
+
* Gems in RubyGems.org >= 0.8.0 support Rails 4
|
23
|
+
* Gems in RubyGems.org >= 0.9.0 support Rails ~> 4.1
|
23
24
|
|
24
25
|
Installation
|
25
26
|
============
|
@@ -30,14 +31,25 @@ Installation
|
|
30
31
|
|
31
32
|
- run migrations `rake db:migrate`
|
32
33
|
|
34
|
+
Upgrading from < 0.9
|
35
|
+
=====================
|
36
|
+
|
37
|
+
Versions of Plutus prior to 0.9 used a "Transaction" class to keep track of entries. Rails 4.1 introduced a change that
|
38
|
+
raises an error with Plutus due to an ActiveRecord method conflict with "transaction". Therefore the Transaction class
|
39
|
+
has been renamed "Entry". To generate a migration which will update your database run the following:
|
40
|
+
|
41
|
+
- `rails g plutus:upgrade_plutus`
|
42
|
+
|
43
|
+
You only need to do this when upgrading a previously installed version of Plutus.
|
44
|
+
|
33
45
|
Overview
|
34
46
|
========
|
35
47
|
|
36
48
|
The plutus plugin provides a complete double entry accounting system for use in any Ruby on Rails application. The plugin follows general [Double Entry Bookkeeping](http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system) practices. All calculations are done using [BigDecimal](http://www.ensta.fr/~diam/ruby/online/ruby-doc-stdlib/libdoc/bigdecimal/rdoc/classes/BigDecimal.html) in order to prevent floating point rounding errors. The plugin requires a decimal type on your database as well.
|
37
49
|
|
38
|
-
The system consists of tables that maintains your accounts,
|
50
|
+
The system consists of tables that maintains your accounts, entries and debits and credits. Each entry can have many debits and credits. The entry table, which records your business transactions is, essentially, your accounting [Journal](http://en.wikipedia.org/wiki/Journal_entry).
|
39
51
|
|
40
|
-
Posting to a [Ledger](http://en.wikipedia.org/wiki/General_ledger) can be considered to happen automatically, since Accounts have the reverse `has_many` relationship to either its credit or debit
|
52
|
+
Posting to a [Ledger](http://en.wikipedia.org/wiki/General_ledger) can be considered to happen automatically, since Accounts have the reverse `has_many` relationship to either its credit or debit entries.
|
41
53
|
|
42
54
|
Accounts
|
43
55
|
--------
|
@@ -52,7 +64,7 @@ The Account class represents accounts in the system. The Account table uses sing
|
|
52
64
|
Revenue | Credit | Increases in owners equity
|
53
65
|
Expense | Debit | Assets or services consumed in the generation of revenue
|
54
66
|
|
55
|
-
Your Book of Accounts needs to be created prior to recording any
|
67
|
+
Your Book of Accounts needs to be created prior to recording any entries. The simplest method is to have a number of create methods in your db/seeds.rb file like so:
|
56
68
|
|
57
69
|
Plutus::Asset.create(:name => "Accounts Receivable")
|
58
70
|
Plutus::Asset.create(:name => "Cash")
|
@@ -72,24 +84,24 @@ Equation](http://en.wikipedia.org/wiki/Accounting_equation)
|
|
72
84
|
|
73
85
|
Assets = Liabilities + Owner's Equity
|
74
86
|
|
75
|
-
Every account object has a `has_many` association of credit and debit
|
87
|
+
Every account object has a `has_many` association of credit and debit entries, which means that each account object also acts as its own [Ledger](http://en.wikipedia.org/wiki/General_ledger), and exposes a method to calculate the balance of the account.
|
76
88
|
|
77
|
-
See the {Plutus::Account}, {Plutus::
|
89
|
+
See the {Plutus::Account}, {Plutus::Entry}, and {Plutus::Amount} classes for more information.
|
78
90
|
|
79
91
|
Examples
|
80
92
|
========
|
81
93
|
|
82
|
-
Recording
|
83
|
-
|
94
|
+
Recording an Entry
|
95
|
+
------------------
|
84
96
|
|
85
|
-
Let's assume we're accounting on an [Accrual basis](http://en.wikipedia.org/wiki/Accounting_methods#Accrual_basis). We've just taken a customer's order for some widgets, which we've also billed him for. At this point we've actually added a liability to the company until we deliver the goods. To record this
|
97
|
+
Let's assume we're accounting on an [Accrual basis](http://en.wikipedia.org/wiki/Accounting_methods#Accrual_basis). We've just taken a customer's order for some widgets, which we've also billed him for. At this point we've actually added a liability to the company until we deliver the goods. To record this entry we'd need two accounts:
|
86
98
|
|
87
99
|
>> Plutus::Asset.create(:name => "Cash")
|
88
100
|
>> Plutus::Liability.create(:name => "Unearned Revenue")
|
89
101
|
|
90
|
-
Next we'll build the
|
102
|
+
Next we'll build the entry we want to record. Plutus provides a simple interface to build the entry.
|
91
103
|
|
92
|
-
|
104
|
+
entry = Plutus::Entry.build(
|
93
105
|
:description => "Order placed for widgets",
|
94
106
|
:debits => [
|
95
107
|
{:account => "Cash", :amount => 100.00}],
|
@@ -98,44 +110,44 @@ Next we'll build the transaction we want to record. Plutus provides a simple int
|
|
98
110
|
|
99
111
|
The build method takes a hash consisting of a description, and an array of debits and credits. Each debit and credit item is a hash that specifies the amount, and the account to be debited or credited. Simply pass in the string name you used when you created the account.
|
100
112
|
|
101
|
-
Finally, save the
|
113
|
+
Finally, save the entry.
|
102
114
|
|
103
|
-
>>
|
115
|
+
>> entry.save
|
104
116
|
|
105
|
-
If there are any issues with your credit and debit amounts, the save will fail and return false. You can inspect the errors via `
|
117
|
+
If there are any issues with your credit and debit amounts, the save will fail and return false. You can inspect the errors via `entry.errors`. Because we are doing double-entry accounting, your credit and debit amounts must always cancel out to keep the accounts in balance.
|
106
118
|
|
107
|
-
Recording
|
108
|
-
|
119
|
+
Recording an Entry with multiple accounts
|
120
|
+
-----------------------------------------
|
109
121
|
|
110
|
-
Often times a single
|
122
|
+
Often times a single entry requires more than one type of account. A classic example would be a entry in which a tax is charged. We'll assume that we have not yet received payment for the order, so we'll need an "Accounts Receivable" Asset:
|
111
123
|
|
112
124
|
>> Plutus::Asset.create(:name => "Accounts Receivable")
|
113
125
|
>> Plutus::Revenue.create(:name => "Sales Revenue")
|
114
126
|
>> Plutus::Liability.create(:name => "Sales Tax Payable")
|
115
127
|
|
116
|
-
And here's the
|
128
|
+
And here's the entry:
|
117
129
|
|
118
|
-
|
130
|
+
entry = Plutus::Entry.build(
|
119
131
|
:description => "Sold some widgets",
|
120
132
|
:debits => [
|
121
133
|
{:account => "Accounts Receivable", :amount => 50}],
|
122
134
|
:credits => [
|
123
135
|
{:account => "Sales Revenue", :amount => 45},
|
124
136
|
{:account => "Sales Tax Payable", :amount => 5}])
|
125
|
-
|
137
|
+
entry.save
|
126
138
|
|
127
139
|
Associating Documents
|
128
140
|
---------------------
|
129
141
|
|
130
|
-
Although Plutus does not provide a mechanism for generating invoices or orders, it is possible to associate any such commercial document with a given
|
142
|
+
Although Plutus does not provide a mechanism for generating invoices or orders, it is possible to associate any such commercial document with a given entry.
|
131
143
|
|
132
|
-
Suppose we pull up our latest invoice in order to generate a
|
144
|
+
Suppose we pull up our latest invoice in order to generate a entry for plutus (we'll assume you already have an Invoice model):
|
133
145
|
|
134
146
|
>> invoice = Invoice.last
|
135
147
|
|
136
|
-
Let's assume we're using the same
|
148
|
+
Let's assume we're using the same entry from the last example
|
137
149
|
|
138
|
-
|
150
|
+
entry = Plutus::Entry.build(
|
139
151
|
:description => "Sold some widgets",
|
140
152
|
:commercial_document => invoice,
|
141
153
|
:debits => [
|
@@ -143,9 +155,9 @@ Let's assume we're using the same transaction from the last example
|
|
143
155
|
:credits => [
|
144
156
|
{:account => "Sales Revenue", :amount => invoice.sales_amount},
|
145
157
|
{:account => "Sales Tax Payable", :amount => invoice.tax_amount}])
|
146
|
-
|
158
|
+
entry.save
|
147
159
|
|
148
|
-
The commercial document attribute on the
|
160
|
+
The commercial document attribute on the entry is a polymorphic association allowing you to associate any record from your models with a entry (i.e. Bills, Invoices, Receipts, Returns, etc.)
|
149
161
|
|
150
162
|
Checking the Balance of an Individual Account
|
151
163
|
----------------------------------------------
|
@@ -173,42 +185,42 @@ The [Trial Balance](http://en.wikipedia.org/wiki/Trial_balance) for all accounts
|
|
173
185
|
>> Plutus::Account.trial_balance
|
174
186
|
=> #<BigDecimal:1031c0d28,'0.0',4(12)>
|
175
187
|
|
176
|
-
Contra Accounts and Complex
|
177
|
-
|
188
|
+
Contra Accounts and Complex Entries
|
189
|
+
-----------------------------------
|
178
190
|
|
179
|
-
For complex
|
191
|
+
For complex entries, you should always ensure that you are balancing your accounts via the [Accounting Equation](http://en.wikipedia.org/wiki/Accounting_equation).
|
180
192
|
|
181
193
|
Assets = Liabilities + Owner's Equity
|
182
194
|
|
183
|
-
For example, let's assume the owner of a business wants to withdraw cash. First we'll assume that we have an asset account for "Cash" which the funds will be drawn from. We'll then need an Equity account to record where the funds are going, however, in this case, we can't simply create a regular Equity account. The "Cash" account must be credited for the decrease in its balance since it's an Asset. Likewise, Equity accounts are typically credited when there is an increase in their balance. Equity is considered an owner's rights to Assets in the business. In this case however, we are not simply increasing the owner's rights to assets within the business; we are actually removing capital from the business altogether. Hence both sides of our accounting equation will see a decrease. In order to accomplish this, we need to create a Contra-Equity account we'll call "Drawings". Since Equity accounts normally have credit balances, a Contra-Equity account will have a debit balance, which is what we need for our
|
195
|
+
For example, let's assume the owner of a business wants to withdraw cash. First we'll assume that we have an asset account for "Cash" which the funds will be drawn from. We'll then need an Equity account to record where the funds are going, however, in this case, we can't simply create a regular Equity account. The "Cash" account must be credited for the decrease in its balance since it's an Asset. Likewise, Equity accounts are typically credited when there is an increase in their balance. Equity is considered an owner's rights to Assets in the business. In this case however, we are not simply increasing the owner's rights to assets within the business; we are actually removing capital from the business altogether. Hence both sides of our accounting equation will see a decrease. In order to accomplish this, we need to create a Contra-Equity account we'll call "Drawings". Since Equity accounts normally have credit balances, a Contra-Equity account will have a debit balance, which is what we need for our entry.
|
184
196
|
|
185
197
|
>> Plutus::Equity.create(:name => "Drawing", :contra => true)
|
186
198
|
>> Plutus::Asset.create(:name => "Cash")
|
187
199
|
|
188
|
-
We would then create the following
|
200
|
+
We would then create the following entry:
|
189
201
|
|
190
|
-
|
202
|
+
entry = Plutus::Entry.build(
|
191
203
|
:description => "Owner withdrawing cash",
|
192
204
|
:debits => [
|
193
205
|
{:account => "Drawing", :amount => 1000}],
|
194
206
|
:credits => [
|
195
207
|
{:account => "Cash", :amount => 1000}])
|
196
|
-
|
208
|
+
entry.save
|
197
209
|
|
198
210
|
To make the example clearer, imagine instead that the owner decides to invest his money into the business in exchange for some type of equity security. In this case we might have the following accounts:
|
199
211
|
|
200
212
|
>> Plutus::Equity.create(:name => "Common Stock")
|
201
213
|
>> Plutus::Asset.create(:name => "Cash")
|
202
214
|
|
203
|
-
And out
|
215
|
+
And out entry would be:
|
204
216
|
|
205
|
-
|
217
|
+
entry = Plutus::Entry.build(
|
206
218
|
:description => "Owner investing cash",
|
207
219
|
:debits => [
|
208
220
|
{:account => "Cash", :amount => 1000}],
|
209
221
|
:credits => [
|
210
222
|
{:account => "Common Stock", :amount => 1000}])
|
211
|
-
|
223
|
+
entry.save
|
212
224
|
|
213
225
|
In this case, we've increase our cash Asset, and simultaneously increased the other side of our accounting equation in
|
214
226
|
Equity, keeping everything balanced.
|
@@ -216,9 +228,9 @@ Equity, keeping everything balanced.
|
|
216
228
|
Access & Security
|
217
229
|
=================
|
218
230
|
|
219
|
-
The Engine provides controllers and views for viewing Accounts and
|
231
|
+
The Engine provides controllers and views for viewing Accounts and Entries via the {Plutus::AccountsController} and {Plutus::EntriesController} classes. The controllers will render HTML, XML and JSON, and are compatible with [ActiveResource](http://api.rubyonrails.org/classes/ActiveResource/Base.html)
|
220
232
|
|
221
|
-
These controllers are read-only for reporting purposes. It is assumed
|
233
|
+
These controllers are read-only for reporting purposes. It is assumed entry creation will occur within your applications code.
|
222
234
|
|
223
235
|
Routing is supplied via an engine mount point. Plutus can be mounted on a subpath in your existing Rails 3 app by adding the following to your routes.rb:
|
224
236
|
|
@@ -240,11 +252,22 @@ Community and where to get help
|
|
240
252
|
|
241
253
|
* Join the [mailing list](https://groups.google.com/d/forum/plutus-gem) (Google Group)
|
242
254
|
|
255
|
+
Bitcoins
|
256
|
+
========
|
257
|
+
|
258
|
+
Plutus is free software, but if you'd like to support development, feel free to send some bitcoins:
|
259
|
+
|
260
|
+
`1QFSdJheyFkLcsV8X428J8e3pYqX1nmW39`
|
261
|
+
|
262
|
+
![bitcoin](https://dl.dropboxusercontent.com/u/8428240/plutus_tip.png)
|
263
|
+
|
264
|
+
Also, if anyone is using Plutus for bitcoin related accounting, I'd love to hear about it! Drop me a line.
|
265
|
+
|
243
266
|
ToDo
|
244
267
|
====
|
245
268
|
|
246
269
|
* Better views, including paging and ledgers
|
247
|
-
* Reference for common accounting
|
270
|
+
* Reference for common accounting entries
|
248
271
|
|
249
272
|
Reference
|
250
273
|
=========
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Plutus
|
2
|
+
# This controller provides restful route handling for Entries.
|
3
|
+
#
|
4
|
+
# The controller supports ActiveResource, and provides for
|
5
|
+
# HMTL, XML, and JSON presentation.
|
6
|
+
#
|
7
|
+
# == Security:
|
8
|
+
# Only GET requests are supported. You should ensure that your application
|
9
|
+
# controller enforces its own authentication and authorization, which this
|
10
|
+
# controller will inherit.
|
11
|
+
#
|
12
|
+
# @author Michael Bulat
|
13
|
+
class EntriesController < ApplicationController
|
14
|
+
unloadable
|
15
|
+
# @example
|
16
|
+
# GET /entries
|
17
|
+
# GET /entries.xml
|
18
|
+
# GET /entries.json
|
19
|
+
def index
|
20
|
+
@entries = Entry.all
|
21
|
+
|
22
|
+
respond_to do |format|
|
23
|
+
format.html # index.html.erb
|
24
|
+
format.xml { render :xml => @entries }
|
25
|
+
format.json { render :json => @entries }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# @example
|
30
|
+
# GET /entries/1
|
31
|
+
# GET /entries/1.xml
|
32
|
+
# GET /entries/1.json
|
33
|
+
def show
|
34
|
+
@entry = Entry.find(params[:id])
|
35
|
+
|
36
|
+
respond_to do |format|
|
37
|
+
format.html # show.html.erb
|
38
|
+
format.xml { render :xml => @entry }
|
39
|
+
format.json { render :json => @entry }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -32,8 +32,8 @@ module Plutus
|
|
32
32
|
class Account < ActiveRecord::Base
|
33
33
|
has_many :credit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::CreditAmount'
|
34
34
|
has_many :debit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::DebitAmount'
|
35
|
-
has_many :
|
36
|
-
has_many :
|
35
|
+
has_many :credit_entries, :through => :credit_amounts, :source => :entry, :class_name => 'Plutus::Entry'
|
36
|
+
has_many :debit_entries, :through => :debit_amounts, :source => :entry, :class_name => 'Plutus::Entry'
|
37
37
|
|
38
38
|
validates_presence_of :type, :name
|
39
39
|
validates_uniqueness_of :name
|
data/app/models/plutus/amount.rb
CHANGED
@@ -6,9 +6,9 @@ module Plutus
|
|
6
6
|
#
|
7
7
|
# @author Michael Bulat
|
8
8
|
class Amount < ActiveRecord::Base
|
9
|
-
belongs_to :
|
9
|
+
belongs_to :entry, :class_name => 'Plutus::Entry'
|
10
10
|
belongs_to :account, :class_name => 'Plutus::Account'
|
11
11
|
|
12
|
-
validates_presence_of :type, :amount, :
|
12
|
+
validates_presence_of :type, :amount, :entry, :account
|
13
13
|
end
|
14
14
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Plutus
|
2
|
-
# The CreditAmount class represents credit entries in the
|
2
|
+
# The CreditAmount class represents credit entries in the entry journal.
|
3
3
|
#
|
4
4
|
# @example
|
5
5
|
# credit_amount = Plutus::CreditAmount.new(:account => revenue, :amount => 1000)
|
@@ -7,4 +7,4 @@ module Plutus
|
|
7
7
|
# @author Michael Bulat
|
8
8
|
class CreditAmount < Amount
|
9
9
|
end
|
10
|
-
end
|
10
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Plutus
|
2
|
-
# The DebitAmount class represents debit entries in the
|
2
|
+
# The DebitAmount class represents debit entries in the entry journal.
|
3
3
|
#
|
4
4
|
# @example
|
5
5
|
# debit_amount = Plutus::DebitAmount.new(:account => cash, :amount => 1000)
|
@@ -7,4 +7,4 @@ module Plutus
|
|
7
7
|
# @author Michael Bulat
|
8
8
|
class DebitAmount < Amount
|
9
9
|
end
|
10
|
-
end
|
10
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Plutus
|
2
|
-
#
|
2
|
+
# Entries are the recording of debits and credits to various accounts.
|
3
3
|
# This table can be thought of as a traditional accounting Journal.
|
4
4
|
#
|
5
5
|
# Posting to a Ledger can be considered to happen automatically, since
|
6
6
|
# Accounts have the reverse 'has_many' relationship to either it's credit or
|
7
|
-
# debit
|
7
|
+
# debit entries
|
8
8
|
#
|
9
9
|
# @example
|
10
10
|
# cash = Plutus::Asset.find_by_name('Cash')
|
@@ -13,15 +13,15 @@ module Plutus
|
|
13
13
|
# debit_amount = Plutus::DebitAmount.new(:account => cash, :amount => 1000)
|
14
14
|
# credit_amount = Plutus::CreditAmount.new(:account => accounts_receivable, :amount => 1000)
|
15
15
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
16
|
+
# entry = Plutus::Entry.new(:description => "Receiving payment on an invoice")
|
17
|
+
# entry.debit_amounts << debit_amount
|
18
|
+
# entry.credit_amounts << credit_amount
|
19
|
+
# entry.save
|
20
20
|
#
|
21
21
|
# @see http://en.wikipedia.org/wiki/Journal_entry Journal Entry
|
22
22
|
#
|
23
23
|
# @author Michael Bulat
|
24
|
-
class
|
24
|
+
class Entry < ActiveRecord::Base
|
25
25
|
belongs_to :commercial_document, :polymorphic => true
|
26
26
|
has_many :credit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::CreditAmount'
|
27
27
|
has_many :debit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::DebitAmount'
|
@@ -34,10 +34,10 @@ module Plutus
|
|
34
34
|
validate :amounts_cancel?
|
35
35
|
|
36
36
|
|
37
|
-
# Simple API for building a
|
37
|
+
# Simple API for building a entry and associated debit and credit amounts
|
38
38
|
#
|
39
39
|
# @example
|
40
|
-
#
|
40
|
+
# entry = Plutus::Entry.build(
|
41
41
|
# description: "Sold some widgets",
|
42
42
|
# debits: [
|
43
43
|
# {account: "Accounts Receivable", amount: 50}],
|
@@ -45,27 +45,27 @@ module Plutus
|
|
45
45
|
# {account: "Sales Revenue", amount: 45},
|
46
46
|
# {account: "Sales Tax Payable", amount: 5}])
|
47
47
|
#
|
48
|
-
# @return [Plutus::
|
48
|
+
# @return [Plutus::Entry] A Entry with built credit and debit objects ready for saving
|
49
49
|
def self.build(hash)
|
50
|
-
|
50
|
+
entry = Entry.new(:description => hash[:description], :commercial_document => hash[:commercial_document])
|
51
51
|
hash[:debits].each do |debit|
|
52
52
|
a = Account.find_by_name(debit[:account])
|
53
|
-
|
53
|
+
entry.debit_amounts << DebitAmount.new(:account => a, :amount => debit[:amount], :entry => entry)
|
54
54
|
end
|
55
55
|
hash[:credits].each do |credit|
|
56
56
|
a = Account.find_by_name(credit[:account])
|
57
|
-
|
57
|
+
entry.credit_amounts << CreditAmount.new(:account => a, :amount => credit[:amount], :entry => entry)
|
58
58
|
end
|
59
|
-
|
59
|
+
entry
|
60
60
|
end
|
61
61
|
|
62
62
|
private
|
63
63
|
def has_credit_amounts?
|
64
|
-
errors[:base] << "
|
64
|
+
errors[:base] << "Entry must have at least one credit amount" if self.credit_amounts.blank?
|
65
65
|
end
|
66
66
|
|
67
67
|
def has_debit_amounts?
|
68
|
-
errors[:base] << "
|
68
|
+
errors[:base] << "Entry must have at least one debit amount" if self.debit_amounts.blank?
|
69
69
|
end
|
70
70
|
|
71
71
|
def amounts_cancel?
|
@@ -21,7 +21,7 @@
|
|
21
21
|
</tr>
|
22
22
|
</table>
|
23
23
|
|
24
|
-
<h1>Credit
|
24
|
+
<h1>Credit Entries</h1>
|
25
25
|
|
26
26
|
<table>
|
27
27
|
<tr>
|
@@ -30,16 +30,16 @@
|
|
30
30
|
<th>Date</th>
|
31
31
|
</tr>
|
32
32
|
|
33
|
-
<% @account.
|
33
|
+
<% @account.credit_entries.each do |entry| %>
|
34
34
|
<tr class="<%= cycle("even", "odd") -%>">
|
35
|
-
<td><%=h
|
36
|
-
<td><%=h
|
37
|
-
<td><%=h
|
35
|
+
<td><%=h entry.id %></td>
|
36
|
+
<td><%=h entry.description %></td>
|
37
|
+
<td><%=h entry.created_at %></td>
|
38
38
|
</tr>
|
39
39
|
<% end %>
|
40
40
|
</table>
|
41
41
|
|
42
|
-
<h1>Debit
|
42
|
+
<h1>Debit Entries</h1>
|
43
43
|
|
44
44
|
<table>
|
45
45
|
<tr>
|
@@ -48,7 +48,7 @@
|
|
48
48
|
<th>Date</th>
|
49
49
|
</tr>
|
50
50
|
|
51
|
-
<% @account.
|
51
|
+
<% @account.debit_entries.each do |tr| %>
|
52
52
|
<tr class="<%= cycle("even", "odd") -%>">
|
53
53
|
<td><%=h tr.id %></td>
|
54
54
|
<td><%=h tr.description %></td>
|
@@ -56,4 +56,4 @@
|
|
56
56
|
</tr>
|
57
57
|
<% end %>
|
58
58
|
</table>
|
59
|
-
</div>
|
59
|
+
</div>
|