plutus 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9fcc5366c07c941520dd02ae4766c2f3a66bc86b
4
- data.tar.gz: e65271810a8320451378f8ab75d4ac03ed14d4ba
3
+ metadata.gz: 800c3e46c1d9b6590ede005950a962326ba72f62
4
+ data.tar.gz: 0264281c8d603c01e045ec91fe1ecb0137be1e6f
5
5
  SHA512:
6
- metadata.gz: bd9b9c732a986b477cd82777bfbf571303b41274f1a49f35fd9f0205c942ed037d330ebdab6cd764e1c2f32848cbd511e3322db99432bb2641edc41a16fec7ac
7
- data.tar.gz: 6913884a7ca65b31f98abe1c978a585f3e8c212d0074a2dce4e7755b09163560e93c296b457659c3ca4c422832f845a148efd8ac78a03c7e625540bc211107e2
6
+ metadata.gz: d363104d103fc0d409b55d435c215299b2ca74e72f431fc49c83ff9fbf2a405c50c2a9ed767189739247b8ea4705539bd20216b4570ff33d8154861ee1e2785f
7
+ data.tar.gz: c5ade1d75490927b5926e175a7e8180a7f9cdd2bc33c90e351f438d0e2e8eca44eddae8c7ae24662634a05822caa9471138c6993cb0c7e9aac3cb9d6d87bf32e
@@ -45,18 +45,21 @@ The Account class represents accounts in the system. The Account table uses sing
45
45
 
46
46
  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:
47
47
 
48
- Plutus::Asset.create(:name => "Accounts Receivable")
49
- Plutus::Asset.create(:name => "Cash")
50
- Plutus::Revenue.create(:name => "Sales Revenue")
51
- Plutus::Liability.create(:name => "Unearned Revenue")
52
- Plutus::Liability.create(:name => "Sales Tax Payable")
53
- etc...
48
+ ```ruby
49
+ Plutus::Asset.create(:name => "Accounts Receivable")
50
+ Plutus::Asset.create(:name => "Cash")
51
+ Plutus::Revenue.create(:name => "Sales Revenue")
52
+ Plutus::Liability.create(:name => "Unearned Revenue")
53
+ Plutus::Liability.create(:name => "Sales Tax Payable")
54
+ ```
54
55
 
55
56
  Then simply run `rake db:seed`
56
57
 
57
58
  Each account can also be marked as a "Contra Account". A contra account will have its normal balance swapped. For example, to remove equity, a "Drawing" account may be created as a contra equity account as follows:
58
59
 
59
- Plutus::Equity.create(:name => "Drawing", :contra => true)
60
+ ```ruby
61
+ Plutus::Equity.create(:name => "Drawing", :contra => true)
62
+ ```
60
63
 
61
64
  At all times the balance of all accounts should conform to the [Accounting
62
65
  Equation](http://en.wikipedia.org/wiki/Accounting_equation)
@@ -75,23 +78,27 @@ Recording an Entry
75
78
 
76
79
  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:
77
80
 
78
- >> Plutus::Asset.create(:name => "Cash")
79
- >> Plutus::Liability.create(:name => "Unearned Revenue")
81
+ ```ruby
82
+ >> Plutus::Asset.create(:name => "Cash")
83
+ >> Plutus::Liability.create(:name => "Unearned Revenue")
84
+ ```
80
85
 
81
- Next we'll build the entry we want to record. Plutus provides a simple interface to build the entry.
86
+ Next we'll build the entry we want to record. Plutus uses ActiveRecord conventions to build the transaction and its associated amounts.
82
87
 
83
- entry = Plutus::Entry.build(
88
+ entry = Plutus::Entry.new(
84
89
  :description => "Order placed for widgets",
85
90
  :debits => [
86
- {:account => "Cash", :amount => 100.00}],
91
+ {:account_name => "Cash", :amount => 100.00}],
87
92
  :credits => [
88
- {:account => "Unearned Revenue", :amount => 100.00}])
93
+ {:account_name => "Unearned Revenue", :amount => 100.00}])
89
94
 
90
- 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.
95
+ Entries must specify a description, as well as at least one credit and debit amount. `Amount`s must specify an amount value as well as an account, either by providing a `Plutus::Account` to `account` or by passing in an `account_name` string.
91
96
 
92
97
  Finally, save the entry.
93
98
 
94
- >> entry.save
99
+ ```ruby
100
+ >> entry.save
101
+ ```
95
102
 
96
103
  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.
97
104
 
@@ -100,20 +107,24 @@ Recording an Entry with multiple accounts
100
107
 
101
108
  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:
102
109
 
103
- >> Plutus::Asset.create(:name => "Accounts Receivable")
104
- >> Plutus::Revenue.create(:name => "Sales Revenue")
105
- >> Plutus::Liability.create(:name => "Sales Tax Payable")
110
+ ```ruby
111
+ >> Plutus::Asset.create(:name => "Accounts Receivable")
112
+ >> Plutus::Revenue.create(:name => "Sales Revenue")
113
+ >> Plutus::Liability.create(:name => "Sales Tax Payable")
114
+ ```
106
115
 
107
116
  And here's the entry:
108
117
 
109
- entry = Plutus::Entry.build(
110
- :description => "Sold some widgets",
111
- :debits => [
112
- {:account => "Accounts Receivable", :amount => 50}],
113
- :credits => [
114
- {:account => "Sales Revenue", :amount => 45},
115
- {:account => "Sales Tax Payable", :amount => 5}])
116
- entry.save
118
+ ```ruby
119
+ entry = Plutus::Entry.build(
120
+ :description => "Sold some widgets",
121
+ :debits => [
122
+ {:account => "Accounts Receivable", :amount => 50}],
123
+ :credits => [
124
+ {:account => "Sales Revenue", :amount => 45},
125
+ {:account => "Sales Tax Payable", :amount => 5}])
126
+ entry.save
127
+ ```
117
128
 
118
129
  Associating Documents
119
130
  ---------------------
@@ -122,19 +133,23 @@ Although Plutus does not provide a mechanism for generating invoices or orders,
122
133
 
123
134
  Suppose we pull up our latest invoice in order to generate a entry for plutus (we'll assume you already have an Invoice model):
124
135
 
125
- >> invoice = Invoice.last
136
+ ```ruby
137
+ >> invoice = Invoice.last
138
+ ```
126
139
 
127
140
  Let's assume we're using the same entry from the last example
128
141
 
129
- entry = Plutus::Entry.build(
130
- :description => "Sold some widgets",
131
- :commercial_document => invoice,
132
- :debits => [
133
- {:account => "Accounts Receivable", :amount => invoice.total_amount}],
134
- :credits => [
135
- {:account => "Sales Revenue", :amount => invoice.sales_amount},
136
- {:account => "Sales Tax Payable", :amount => invoice.tax_amount}])
137
- entry.save
142
+ ```ruby
143
+ entry = Plutus::Entry.new(
144
+ :description => "Sold some widgets",
145
+ :commercial_document => invoice,
146
+ :debits => [
147
+ {:account_name => "Accounts Receivable", :amount => invoice.total_amount}],
148
+ :credits => [
149
+ {:account_name => "Sales Revenue", :amount => invoice.sales_amount},
150
+ {:account_name => "Sales Tax Payable", :amount => invoice.tax_amount}])
151
+ entry.save
152
+ ```
138
153
 
139
154
  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.)
140
155
 
@@ -143,9 +158,11 @@ Checking the Balance of an Individual Account
143
158
 
144
159
  Each account can report on its own balance. This number should normally be positive. If the number is negative, you may have a problem.
145
160
 
146
- >> cash = Plutus::Asset.find_by_name("Cash")
147
- >> cash.balance
148
- => #<BigDecimal:103259bb8,'0.2E4',4(12)>
161
+ ```ruby
162
+ >> cash = Plutus::Asset.find_by_name("Cash")
163
+ >> cash.balance
164
+ => #<BigDecimal:103259bb8,'0.2E4',4(12)>
165
+ ```
149
166
 
150
167
 
151
168
  Checking the Balance of an Account Type
@@ -153,16 +170,20 @@ Checking the Balance of an Account Type
153
170
 
154
171
  Each subclass of accounts can report on the total balance of all the accounts of that type. This number should normally be positive. If the number is negative, you may have a problem.
155
172
 
156
- >> Plutus::Asset.balance
157
- => #<BigDecimal:103259bb8,'0.2E4',4(12)>
173
+ ```ruby
174
+ >> Plutus::Asset.balance
175
+ => #<BigDecimal:103259bb8,'0.2E4',4(12)>
176
+ ```
158
177
 
159
178
  Calculating the Trial Balance
160
179
  -----------------------------
161
180
 
162
181
  The [Trial Balance](http://en.wikipedia.org/wiki/Trial_balance) for all accounts on the system can be found through the abstract Account class. This value should be 0 unless there is an error in the system.
163
182
 
164
- >> Plutus::Account.trial_balance
165
- => #<BigDecimal:1031c0d28,'0.0',4(12)>
183
+ ```ruby
184
+ >> Plutus::Account.trial_balance
185
+ => #<BigDecimal:1031c0d28,'0.0',4(12)>
186
+ ```
166
187
 
167
188
  Contra Accounts and Complex Entries
168
189
  -----------------------------------
@@ -173,37 +194,61 @@ For complex entries, you should always ensure that you are balancing your accoun
173
194
 
174
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.
175
196
 
176
- >> Plutus::Equity.create(:name => "Drawing", :contra => true)
177
- >> Plutus::Asset.create(:name => "Cash")
197
+ ```ruby
198
+ >> Plutus::Equity.create(:name => "Drawing", :contra => true)
199
+ >> Plutus::Asset.create(:name => "Cash")
200
+ ```
178
201
 
179
202
  We would then create the following entry:
180
203
 
181
- entry = Plutus::Entry.build(
182
- :description => "Owner withdrawing cash",
183
- :debits => [
184
- {:account => "Drawing", :amount => 1000}],
185
- :credits => [
186
- {:account => "Cash", :amount => 1000}])
187
- entry.save
204
+ ```ruby
205
+ entry = Plutus::Entry.new(
206
+ :description => "Owner withdrawing cash",
207
+ :debits => [
208
+ {:account_name => "Drawing", :amount => 1000}],
209
+ :credits => [
210
+ {:account_name => "Cash", :amount => 1000}])
211
+ entry.save
212
+ ```
188
213
 
189
214
  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:
190
215
 
191
- >> Plutus::Equity.create(:name => "Common Stock")
192
- >> Plutus::Asset.create(:name => "Cash")
216
+ ```ruby
217
+ >> Plutus::Equity.create(:name => "Common Stock")
218
+ >> Plutus::Asset.create(:name => "Cash")
219
+ ```
193
220
 
194
221
  And out entry would be:
195
222
 
196
- entry = Plutus::Entry.build(
197
- :description => "Owner investing cash",
198
- :debits => [
199
- {:account => "Cash", :amount => 1000}],
200
- :credits => [
201
- {:account => "Common Stock", :amount => 1000}])
202
- entry.save
223
+ ```ruby
224
+ entry = Plutus::Entry.new(
225
+ :description => "Owner investing cash",
226
+ :debits => [
227
+ {:account_name => "Cash", :amount => 1000}],
228
+ :credits => [
229
+ {:account_name => "Common Stock", :amount => 1000}])
230
+ entry.save
231
+ ```
203
232
 
204
233
  In this case, we've increase our cash Asset, and simultaneously increased the other side of our accounting equation in
205
234
  Equity, keeping everything balanced.
206
235
 
236
+ Money & Currency Support
237
+ ========================
238
+
239
+ Plutus aims to be agnostic about the values used for amounts. All fields are maintained as BigDecimal values, with `:precision => 20, :scale => 10`, which means that any currency can be safely stored in the tables.
240
+
241
+ Plutus is also compatible with the [Money](https://github.com/RubyMoney/money) gem. With Money versions greater than 6.0, the `money.amount` will returns a BigDecimal which you can use with plutus as follows:
242
+
243
+ ```ruby
244
+ entry = Plutus::Entry.build(
245
+ :description => "Order placed for widgets",
246
+ :debits => [
247
+ {:account => "Cash", :amount => money.amount}],
248
+ :credits => [
249
+ {:account => "Unearned Revenue", :amount => money.amount}])
250
+ ```
251
+
207
252
  Multitenancy Support
208
253
  =====================
209
254
 
@@ -212,22 +257,22 @@ Plutus supports multitenant applications. Multitenancy is acheived by associatin
212
257
  - Generate the migration which will add `tenant_id` to the plutus accounts table
213
258
 
214
259
  ```sh
215
- bundle exec rails g plutus:tenancy
260
+ bundle exec rails g plutus:tenancy
216
261
  ```
217
262
 
218
263
  - Run the migration
219
264
 
220
265
  ```sh
221
- rake db:migrate
266
+ rake db:migrate
222
267
  ```
223
268
 
224
269
  - Add an initializer to your Rails application, i.e. `config/initializers/plutus.rb`
225
270
 
226
271
  ```ruby
227
- Plutus.config do |config|
228
- config.enable_tenancy = true
229
- config.tenant_class = 'Tenant'
230
- end
272
+ Plutus.config do |config|
273
+ config.enable_tenancy = true
274
+ config.tenant_class = 'Tenant'
275
+ end
231
276
  ```
232
277
 
233
278
  Access & Security
@@ -239,7 +284,9 @@ These controllers are read-only for reporting purposes. It is assumed entry crea
239
284
 
240
285
  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:
241
286
 
242
- mount Plutus::Engine => "/plutus", :as => "plutus"
287
+ ```ruby
288
+ mount Plutus::Engine => "/plutus", :as => "plutus"
289
+ ```
243
290
 
244
291
  *NOTE: If you enable routing, you should ensure that your ApplicationController enforces its own authentication and authorization, which this controller will inherit.*
245
292
 
@@ -2,7 +2,7 @@ module Plutus
2
2
  # The Amount class represents debit and credit amounts in the system.
3
3
  #
4
4
  # @abstract
5
- # An amount must be a subclass as either a debit or a credit to be saved to the database.
5
+ # An amount must be a subclass as either a debit or a credit to be saved to the database.
6
6
  #
7
7
  # @author Michael Bulat
8
8
  class Amount < ActiveRecord::Base
@@ -10,5 +10,24 @@ module Plutus
10
10
  belongs_to :account, :class_name => 'Plutus::Account'
11
11
 
12
12
  validates_presence_of :type, :amount, :entry, :account
13
+ # attr_accessible :account, :account_name, :amount, :entry
14
+
15
+ # Assign an account by name
16
+ def account_name=(name)
17
+ self.account = Account.find_by_name!(name)
18
+ end
19
+
20
+ protected
21
+
22
+ # Support constructing amounts with account = "name" syntax
23
+ def account_with_name_lookup=(v)
24
+ if v.kind_of?(String)
25
+ ActiveSupport::Deprecation.warn('Plutus was given an :account String (use account_name instead)', caller)
26
+ self.account_name = v
27
+ else
28
+ self.account_without_name_lookup = v
29
+ end
30
+ end
31
+ alias_method_chain :account=, :name_lookup
13
32
  end
14
33
  end
@@ -14,4 +14,4 @@ module Plutus
14
14
  return balance
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -23,8 +23,8 @@ module Plutus
23
23
  # @author Michael Bulat
24
24
  class Entry < ActiveRecord::Base
25
25
  belongs_to :commercial_document, :polymorphic => true
26
- has_many :credit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::CreditAmount'
27
- has_many :debit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::DebitAmount'
26
+ has_many :credit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::CreditAmount', :inverse_of => :entry
27
+ has_many :debit_amounts, :extend => AmountsExtension, :class_name => 'Plutus::DebitAmount', :inverse_of => :entry
28
28
  has_many :credit_accounts, :through => :credit_amounts, :source => :account, :class_name => 'Plutus::Account'
29
29
  has_many :debit_accounts, :through => :debit_amounts, :source => :account, :class_name => 'Plutus::Account'
30
30
 
@@ -33,30 +33,20 @@ module Plutus
33
33
  validate :has_debit_amounts?
34
34
  validate :amounts_cancel?
35
35
 
36
+ # Support construction using 'credits' and 'debits' keys
37
+ accepts_nested_attributes_for :credit_amounts, :debit_amounts
38
+ alias_method :credits=, :credit_amounts_attributes=
39
+ alias_method :debits=, :debit_amounts_attributes=
40
+ # attr_accessible :credits, :debits
36
41
 
37
- # Simple API for building a entry and associated debit and credit amounts
38
- #
39
- # @example
40
- # entry = Plutus::Entry.build(
41
- # description: "Sold some widgets",
42
- # debits: [
43
- # {account: "Accounts Receivable", amount: 50}],
44
- # credits: [
45
- # {account: "Sales Revenue", amount: 45},
46
- # {account: "Sales Tax Payable", amount: 5}])
47
- #
48
- # @return [Plutus::Entry] A Entry with built credit and debit objects ready for saving
42
+ # Support the deprecated .build method
49
43
  def self.build(hash)
50
- entry = Plutus::Entry.new(:description => hash[:description], :commercial_document => hash[:commercial_document])
51
- hash[:debits].each do |debit|
52
- a = Plutus::Account.find_by_name(debit[:account])
53
- entry.debit_amounts << Plutus::DebitAmount.new(:account => a, :amount => debit[:amount], :entry => entry)
54
- end
55
- hash[:credits].each do |credit|
56
- a = Plutus::Account.find_by_name(credit[:account])
57
- entry.credit_amounts << Plutus::CreditAmount.new(:account => a, :amount => credit[:amount], :entry => entry)
58
- end
59
- entry
44
+ ActiveSupport::Deprecation.warn('Plutus::Transaction.build() is deprecated (use new instead)', caller)
45
+ new(hash)
46
+ end
47
+
48
+ def initialize(*args)
49
+ super
60
50
  end
61
51
 
62
52
  private
@@ -1,3 +1,3 @@
1
1
  module Plutus
2
- VERSION = "0.10.1"
2
+ VERSION = "0.11.0"
3
3
  end
@@ -4,30 +4,30 @@ module Plutus
4
4
  describe Account do
5
5
  let(:account) { FactoryGirl.build(:account) }
6
6
  subject { account }
7
-
7
+
8
8
  it { should_not be_valid } # must construct a child type instead
9
9
 
10
10
  describe "when using a child type" do
11
11
  let(:account) { FactoryGirl.create(:account, type: "Finance::Asset") }
12
12
  it { should be_valid }
13
-
13
+
14
14
  it "should be unique per name" do
15
15
  conflict = FactoryGirl.build(:account, name: account.name, type: account.type)
16
16
  conflict.should_not be_valid
17
17
  conflict.errors[:name].should == ["has already been taken"]
18
18
  end
19
19
  end
20
-
20
+
21
21
  it { should_not respond_to(:balance) }
22
-
22
+
23
23
  describe ".trial_balance" do
24
24
  subject { Account.trial_balance }
25
25
  it { should be_kind_of BigDecimal }
26
-
26
+
27
27
  context "when given no entries" do
28
28
  it { should == 0 }
29
29
  end
30
-
30
+
31
31
  context "when given correct entries" do
32
32
  before {
33
33
  # credit accounts
@@ -57,12 +57,12 @@ module Plutus
57
57
  da5 = FactoryGirl.build(:debit_amount, :account => contra_revenue, :amount => 333)
58
58
 
59
59
  FactoryGirl.create(:entry, :credit_amounts => [ca1], :debit_amounts => [da1])
60
- FactoryGirl.create(:entry, :credit_amounts => [ca2], :debit_amounts => [da2])
60
+ FactoryGirl.create(:entry, :credit_amounts => [ca2], :debit_amounts => [da2])
61
61
  FactoryGirl.create(:entry, :credit_amounts => [ca3], :debit_amounts => [da3])
62
62
  FactoryGirl.create(:entry, :credit_amounts => [ca4], :debit_amounts => [da4])
63
63
  FactoryGirl.create(:entry, :credit_amounts => [ca5], :debit_amounts => [da5])
64
64
  }
65
-
65
+
66
66
  it { should == 0 }
67
67
  end
68
68
  end
@@ -4,4 +4,4 @@ module Plutus
4
4
  describe DebitAmount do
5
5
  it_behaves_like 'a Plutus::Amount subtype', kind: :debit_amount
6
6
  end
7
- end
7
+ end
@@ -10,7 +10,7 @@ module Plutus
10
10
  context "with credit and debit" do
11
11
  let(:entry) { FactoryGirl.build(:entry_with_credit_and_debit) }
12
12
  it { should be_valid }
13
-
13
+
14
14
  it "should require a description" do
15
15
  entry.description = nil
16
16
  entry.should_not be_valid
@@ -68,23 +68,130 @@ module Plutus
68
68
  saved_entry.commercial_document.should == mock_document
69
69
  end
70
70
 
71
- it "should allow building an entry and credit and debits with a hash" do
72
- FactoryGirl.create(:asset, name: "Accounts Receivable")
73
- FactoryGirl.create(:revenue, name: "Sales Revenue")
74
- FactoryGirl.create(:liability, name: "Sales Tax Payable")
75
- mock_document = FactoryGirl.create(:asset)
76
- entry = Entry.build(
77
- description: "Sold some widgets",
78
- commercial_document: mock_document,
79
- debits: [
80
- {account: "Accounts Receivable", amount: 50}],
81
- credits: [
82
- {account: "Sales Revenue", amount: 45},
83
- {account: "Sales Tax Payable", amount: 5}])
84
- entry.save!
71
+ context "given a set of accounts" do
72
+ let(:mock_document) { FactoryGirl.create(:asset) }
73
+ let!(:accounts_receivable) { FactoryGirl.create(:asset, name: "Accounts Receivable") }
74
+ let!(:sales_revenue) { FactoryGirl.create(:revenue, name: "Sales Revenue") }
75
+ let!(:sales_tax_payable) { FactoryGirl.create(:liability, name: "Sales Tax Payable") }
85
76
 
86
- saved_entry = Entry.find(entry.id)
87
- saved_entry.commercial_document.should == mock_document
77
+ shared_examples_for 'a built-from-hash Plutus::Entry' do
78
+ its(:credit_amounts) { should_not be_empty }
79
+ its(:debit_amounts) { should_not be_empty }
80
+ it { should be_valid }
81
+
82
+ context "when saved" do
83
+ before { entry.save! }
84
+ its(:id) { should_not be_nil }
85
+
86
+ context "when reloaded" do
87
+ let(:saved_transaction) { Entry.find(entry.id) }
88
+ subject { saved_transaction }
89
+ it("should have the correct commercial document") {
90
+ saved_transaction.commercial_document == mock_document
91
+ }
92
+ end
93
+ end
94
+ end
95
+
96
+ describe ".new" do
97
+ let(:entry) { Entry.new(hash) }
98
+ subject { entry }
99
+
100
+ context "when given a credit/debits hash with :account => Account" do
101
+ let(:hash) {
102
+ {
103
+ description: "Sold some widgets",
104
+ commercial_document: mock_document,
105
+ debits: [{account: accounts_receivable, amount: 50}],
106
+ credits: [
107
+ {account: sales_revenue, amount: 45},
108
+ {account: sales_tax_payable, amount: 5}
109
+ ]
110
+ }
111
+ }
112
+ include_examples 'a built-from-hash Plutus::Entry'
113
+ end
114
+
115
+ context "when given a credit/debits hash with :account_name => String" do
116
+ let(:hash) {
117
+ {
118
+ description: "Sold some widgets",
119
+ commercial_document: mock_document,
120
+ debits: [{account_name: accounts_receivable.name, amount: 50}],
121
+ credits: [
122
+ {account_name: sales_revenue.name, amount: 45},
123
+ {account_name: sales_tax_payable.name, amount: 5}
124
+ ]
125
+ }
126
+ }
127
+ include_examples 'a built-from-hash Plutus::Entry'
128
+ end
129
+
130
+ context "when given a credit/debits hash with :account => String" do
131
+ let(:hash) {
132
+ {
133
+ description: "Sold some widgets",
134
+ commercial_document: mock_document,
135
+ debits: [{account: accounts_receivable.name, amount: 50}],
136
+ credits: [
137
+ {account: sales_revenue.name, amount: 45},
138
+ {account: sales_tax_payable.name, amount: 5}
139
+ ]
140
+ }
141
+ }
142
+
143
+ before { ::ActiveSupport::Deprecation.silenced = true }
144
+ after { ::ActiveSupport::Deprecation.silenced = false }
145
+
146
+ it("should be deprecated") {
147
+ # one deprecation per account looked up
148
+ ::ActiveSupport::Deprecation.should_receive(:warn).exactly(3).times
149
+ entry
150
+ }
151
+
152
+ include_examples 'a built-from-hash Plutus::Entry'
153
+ end
154
+ end
155
+
156
+ describe ".build" do
157
+ let(:entry) { Entry.build(hash) }
158
+ subject { entry }
159
+
160
+ before { ::ActiveSupport::Deprecation.silenced = true }
161
+ after { ::ActiveSupport::Deprecation.silenced = false }
162
+
163
+ context "when used at all" do
164
+ let(:hash) { Hash.new }
165
+
166
+ it("should be deprecated") {
167
+ # .build is the only thing deprecated
168
+ ::ActiveSupport::Deprecation.should_receive(:warn).once
169
+ entry
170
+ }
171
+ end
172
+
173
+ context "when given a credit/debits hash with :account => String" do
174
+ let(:hash) {
175
+ {
176
+ description: "Sold some widgets",
177
+ commercial_document: mock_document,
178
+ debits: [{account: accounts_receivable.name, amount: 50}],
179
+ credits: [
180
+ {account: sales_revenue.name, amount: 45},
181
+ {account: sales_tax_payable.name, amount: 5}
182
+ ]
183
+ }
184
+ }
185
+
186
+ it("should be deprecated") {
187
+ # one deprecation for build, plus three for accounts as strings
188
+ ::ActiveSupport::Deprecation.should_receive(:warn).exactly(4).times
189
+ entry
190
+ }
191
+
192
+ include_examples 'a built-from-hash Plutus::Entry'
193
+ end
194
+ end
88
195
  end
89
196
 
90
197
  end
@@ -1,3 +1,6 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
1
4
  ENV["RAILS_ENV"] ||= 'test'
2
5
  require File.expand_path(File.dirname(__FILE__) + "/../fixture_rails_root/config/environment")
3
6
 
@@ -1,9 +1,9 @@
1
1
  shared_examples_for 'a Plutus::Amount subtype' do |elements|
2
2
  let(:amount) { FactoryGirl.build(elements[:kind]) }
3
3
  subject { amount }
4
-
4
+
5
5
  it { should be_valid }
6
-
6
+
7
7
  it "should require an amount" do
8
8
  amount.amount = nil
9
9
  amount.should_not be_valid
@@ -13,7 +13,7 @@ shared_examples_for 'a Plutus::Amount subtype' do |elements|
13
13
  amount.entry = nil
14
14
  amount.should_not be_valid
15
15
  end
16
-
16
+
17
17
  it "should require an account" do
18
18
  amount.account = nil
19
19
  amount.should_not be_valid
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plutus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bulat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails