pacioli 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,10 +9,11 @@ class CreatePacioliTables < ActiveRecord::Migration
9
9
  t.timestamps
10
10
  end
11
11
 
12
- create_table :pacioli_customers, :force => true do |t|
12
+ create_table :pacioli_parties, :force => true do |t|
13
13
  t.references :pacioli_company
14
- t.integer :customerable_id
15
- t.string :customerable_type
14
+ t.integer :partyable_id
15
+ t.string :partyable_type
16
+ t.string :type
16
17
  t.string :name
17
18
 
18
19
  t.timestamps
@@ -44,7 +45,7 @@ class CreatePacioliTables < ActiveRecord::Migration
44
45
  create_table :pacioli_transactions, :force => true do |t|
45
46
  t.references :pacioli_journal_entry
46
47
  t.references :pacioli_account
47
- t.references :pacioli_customer
48
+ t.references :pacioli_party
48
49
 
49
50
  t.string :type
50
51
  t.decimal :amount, :precision => 20, :scale => 10
@@ -5,7 +5,7 @@ module Pacioli
5
5
  has_many :chart_of_accounts, through: :accounts
6
6
  has_many :journal_entries, foreign_key: :pacioli_company_id, dependent: :destroy
7
7
  has_many :posting_rules, foreign_key: :pacioli_company_id, dependent: :destroy
8
- has_many :customers, foreign_key: :pacioli_company_id, dependent: :destroy
8
+ has_many :parties, foreign_key: :pacioli_company_id, dependent: :destroy
9
9
 
10
10
  def self.for(company)
11
11
  Company.where(companyable_type: company.class.name, companyable_id: company.id).first
@@ -102,13 +102,23 @@ module Pacioli
102
102
  end
103
103
  end
104
104
 
105
- def register_customer(&block)
105
+ def register_debtor(&block)
106
106
  self.transaction do
107
- customer = Customer.new
108
- self.customers << customer
109
- customer.instance_eval(&block)
110
- customer.save!
111
- customer
107
+ debtor = Debtor.new
108
+ self.parties << debtor
109
+ debtor.instance_eval(&block)
110
+ debtor.save!
111
+ debtor
112
+ end
113
+ end
114
+
115
+ def register_creditor(&block)
116
+ self.transaction do
117
+ creditor = Creditor.new
118
+ self.parties << creditor
119
+ creditor.instance_eval(&block)
120
+ creditor.save!
121
+ creditor
112
122
  end
113
123
  end
114
124
  end
@@ -5,5 +5,9 @@ module Pacioli
5
5
  true
6
6
  end
7
7
 
8
+ def to_hash
9
+ {description: self.journal_entry.description, date: self.dated, credit_amount: self.amount, debit_amount: "", balance: self.party.balance_at(self.dated)}
10
+ end
11
+
8
12
  end
9
13
  end
@@ -0,0 +1,5 @@
1
+ module Pacioli
2
+ class Creditor < Party
3
+
4
+ end
5
+ end
data/lib/pacioli/debit.rb CHANGED
@@ -5,5 +5,9 @@ module Pacioli
5
5
  true
6
6
  end
7
7
 
8
+ def to_hash
9
+ {description: self.journal_entry.description, date: self.dated, credit_amount: "", debit_amount: self.amount, balance: self.party.balance_at(self.dated)}
10
+ end
11
+
8
12
  end
9
13
  end
@@ -0,0 +1,5 @@
1
+ module Pacioli
2
+ class Debtor < Party
3
+
4
+ end
5
+ end
@@ -27,14 +27,14 @@ module Pacioli
27
27
  def debit(options={})
28
28
  account = self.company.accounts.where(name: options[:account]).first
29
29
  debit = Debit.new(journal_entry: self, account: account, amount: options[:amount], dated: self.dated)
30
- debit.customer = options[:against_customer] if options.has_key? :against_customer
30
+ debit.party = options[:against_party] if options.has_key? :against_party
31
31
  self.transactions << debit
32
32
  end
33
33
 
34
34
  def credit(options={})
35
35
  account = self.company.accounts.where(name: options[:account]).first
36
36
  credit = Credit.new(journal_entry: self, account: account, amount: options[:amount], dated: self.dated)
37
- credit.customer = options[:against_customer] if options.has_key? :against_customer
37
+ credit.party = options[:against_party] if options.has_key? :against_party
38
38
  self.transactions << credit
39
39
  end
40
40
 
@@ -75,7 +75,7 @@ module Pacioli
75
75
  # Could be used to update a journal entry and affect other accounts
76
76
  # eg. a payment into our bank would result in a journal entry but
77
77
  # we may not know where it came from. At a later stage we could allocate
78
- # the payment to a customer/invoice etc.
78
+ # the payment to a debtor/invoice etc.
79
79
 
80
80
  def record(&block)
81
81
  self.transaction do
@@ -0,0 +1,49 @@
1
+ module Pacioli
2
+ class Party < ActiveRecord::Base
3
+ belongs_to :partyable, polymorphic: true
4
+ belongs_to :company, foreign_key: :pacioli_company_id
5
+ has_many :transactions, foreign_key: :pacioli_party_id
6
+
7
+ def self.for(party)
8
+ Party.where(partyable_type: party.class.name, partyable_id: party.id) #.first || Customer.create!(customerable_type: customer.class.name, customerable_id: customer.id)
9
+ end
10
+
11
+ def with_name(party_name)
12
+ self.name = party_name
13
+ end
14
+
15
+ def with_source(partyable_object)
16
+ self.partyable = partyable_object
17
+ end
18
+
19
+ def debits
20
+ transactions.where(type: 'Pacioli::Debit')
21
+ end
22
+
23
+ def credits
24
+ transactions.where(type: 'Pacioli::Credit')
25
+ end
26
+
27
+ def balance
28
+ debits.sum(&:amount) - credits.sum(&:amount)
29
+ end
30
+
31
+ def balance_at(date=Time.now)
32
+ debits.before(date).sum(&:amount) - credits.before(date).sum(&:amount)
33
+ end
34
+
35
+ def statement_between_dates(start_date, end_date=Time.now)
36
+ start_date ||= (Date.today - 1.month).to_time
37
+
38
+ temp_array = []
39
+
40
+ temp_array << {description: "Opening Balance", date: start_date, credit_amount: "", debit_amount: "", balance: balance_at(start_date)}
41
+
42
+ temp_array << transactions.between(start_date, end_date).map(&:to_hash)
43
+
44
+ temp_array << {description: "Closing Balance", date: end_date, credit_amount: "", debit_amount: "", balance: balance_at(end_date)}
45
+
46
+ temp_array.flatten
47
+ end
48
+ end
49
+ end
@@ -2,7 +2,15 @@ module Pacioli
2
2
  class Transaction < ActiveRecord::Base
3
3
  belongs_to :journal_entry, foreign_key: :pacioli_journal_entry_id
4
4
  belongs_to :account, foreign_key: :pacioli_account_id
5
- belongs_to :customer, foreign_key: :pacioli_customer_id
5
+ belongs_to :party, foreign_key: :pacioli_party_id
6
+
7
+ def self.before(date=Time.now)
8
+ where("dated < :q", q: date.to_time.beginning_of_day)
9
+ end
10
+
11
+ def self.between(start_date, end_date)
12
+ where("dated >= :s AND dated <= :e", {s: start_date.to_time.beginning_of_day, e: end_date.to_time.end_of_day}).order(:dated)
13
+ end
6
14
 
7
15
  def debit?
8
16
  false
@@ -1,3 +1,3 @@
1
1
  module Pacioli
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.11"
3
3
  end
data/lib/pacioli.rb CHANGED
@@ -16,7 +16,9 @@ module Pacioli
16
16
  end
17
17
 
18
18
  require "pacioli/company"
19
- require "pacioli/customer"
19
+ require "pacioli/party"
20
+ require "pacioli/creditor"
21
+ require "pacioli/debtor"
20
22
  require "pacioli/account"
21
23
  require "pacioli/asset_account"
22
24
  require "pacioli/liability_account"
Binary file
@@ -8,10 +8,11 @@ ActiveRecord::Schema.define do
8
8
  t.timestamps
9
9
  end
10
10
 
11
- create_table :pacioli_customers, :force => true do |t|
11
+ create_table :pacioli_parties, :force => true do |t|
12
12
  t.references :pacioli_company
13
- t.integer :customerable_id
14
- t.string :customerable_type
13
+ t.integer :partyable_id
14
+ t.string :partyable_type
15
+ t.string :type
15
16
  t.string :name
16
17
 
17
18
  t.timestamps
@@ -43,7 +44,7 @@ ActiveRecord::Schema.define do
43
44
  create_table :pacioli_transactions, :force => true do |t|
44
45
  t.references :pacioli_journal_entry
45
46
  t.references :pacioli_account
46
- t.references :pacioli_customer
47
+ t.references :pacioli_party
47
48
 
48
49
  t.string :type
49
50
  t.decimal :amount, :precision => 20, :scale => 10
@@ -203,7 +203,7 @@ describe Pacioli::Account do
203
203
 
204
204
  context "Recording against a customer with a source document" do
205
205
  before(:each) do
206
- @customer = @company.register_customer do
206
+ @customer = @company.register_debtor do
207
207
  with_name "Leonardo da Vinci"
208
208
  end
209
209
  end
@@ -215,7 +215,7 @@ describe Pacioli::Account do
215
215
  @company.record_journal_entry do
216
216
  with_description "Invoice 123 for November Rent"
217
217
  with_source_document customer # source should be the invoice!
218
- debit account: "Accounts Receivable", amount: 4500.00, against_customer: customer
218
+ debit account: "Accounts Receivable", amount: 4500.00, against_party: customer
219
219
  credit account: "Sales", amount: 4500.00
220
220
  end
221
221
  end
@@ -236,7 +236,7 @@ describe Pacioli::Account do
236
236
  @company.record_journal_entry do
237
237
  with_description "PMT Received"
238
238
  debit account: "Cash in Bank", amount: 4500.00
239
- credit account: "Accounts Receivable", amount: 4500.00, against_customer: customer
239
+ credit account: "Accounts Receivable", amount: 4500.00, against_party: customer
240
240
  end
241
241
  end
242
242
 
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Pacioli::Party do
4
+ include Helpers
5
+
6
+ before(:each) do
7
+ tear_it_down
8
+
9
+ @company = Pacioli::register_company do
10
+ with_name "Coca-Cola"
11
+
12
+ add_asset_account name: "Accounts Receivable", code: "100"
13
+ add_asset_account name: "Cash in Bank", code: "101"
14
+ add_income_account name: "Sales", code: "301"
15
+ add_liability_account name: "Sales Tax", code: "401"
16
+ end
17
+
18
+ @debtor = @company.register_debtor do
19
+ with_name "Leonardo da Vinci"
20
+ end
21
+ end
22
+
23
+ it "should create a debtor" do
24
+ Pacioli::Debtor.all.count.should == 1
25
+ @debtor.name.should == "Leonardo da Vinci"
26
+ @debtor.company.should == @company
27
+ end
28
+
29
+ context "Debtors Statement for past 11 weeks" do
30
+
31
+ before(:each) do
32
+ debtor = @debtor
33
+
34
+ debit_entries = [
35
+ {description: "Invoice 123 for Rent #{Date.today - 12.weeks}", dated: Date.today - 12.weeks, source: debtor, amt: 5000.00, against: debtor},
36
+ {description: "Invoice 124 for Rent #{Date.today - 8.weeks}", dated: Date.today - 8.weeks, source: debtor, amt: 2000.00, against: debtor},
37
+ {description: "Invoice 125 for Rent #{Date.today - 4.weeks}", dated: Date.today - 4.weeks, source: debtor, amt: 3000.00, against: debtor},
38
+ {description: "Invoice 126 for Fee #{Date.today - 2.weeks}", dated: Date.today - 2.weeks, source: debtor, amt: 4000.00, against: debtor}
39
+ ]
40
+
41
+ credit_entries = [
42
+ {description: "PMT Received for Invoice 123 #{Date.today - 7.weeks}", dated: Date.today - 7.weeks, source: debtor, amt: 5000.00, against: debtor},
43
+ {description: "PMT Received for Invoice 123 #{Date.today - 3.weeks}", source: debtor, dated: Date.today - 3.weeks, amt: 2000.00, against: debtor},
44
+ ]
45
+
46
+ credit_entries.each do |credit_entry|
47
+ @company.record_journal_entry do
48
+ with_description credit_entry[:description]
49
+ with_source_document credit_entry[:source]
50
+ with_date credit_entry[:dated]
51
+
52
+ debit account: "Cash in Bank", amount: credit_entry[:amt]
53
+ credit account: "Accounts Receivable", amount: credit_entry[:amt], against_party: credit_entry[:against]
54
+ end
55
+ end
56
+
57
+ debit_entries.each do |debit_entry|
58
+ @company.record_journal_entry do
59
+ with_description debit_entry[:description]
60
+ with_source_document debit_entry[:source]
61
+ with_date debit_entry[:dated]
62
+
63
+ debit account: "Accounts Receivable", amount: debit_entry[:amt], against_party: debit_entry[:against]
64
+ credit account: "Sales", amount: debit_entry[:amt]
65
+ end
66
+ end
67
+
68
+ @statement = @debtor.statement_between_dates(Date.today - 11.weeks, Date.today)
69
+ end
70
+
71
+ it "should have an opening balance of 5000.00" do
72
+ @statement.first[:balance].should == 5000.00
73
+ end
74
+
75
+ it "should have 3 debit entries to the value of 9000.00" do
76
+ @statement.select {|entry| !entry[:debit_amount].blank?}.count.should == 3
77
+ @statement.select {|entry| !entry[:debit_amount].blank?}.map {|i| i[:debit_amount]}.sum().should == 9000.00
78
+ end
79
+
80
+ it "should have a closing balance of 7000.00" do
81
+ @statement.last[:balance].should == 7000.00
82
+ end
83
+
84
+ end
85
+ end
@@ -5,7 +5,7 @@ module Helpers
5
5
  Pacioli::JournalEntry.delete_all
6
6
  Pacioli::Transaction.delete_all
7
7
  Pacioli::PostingRule.destroy_all
8
- Pacioli::Customer.destroy_all
8
+ Pacioli::Party.destroy_all
9
9
  end
10
10
  end
11
11
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pacioli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2013-02-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70249036092760 !ruby/object:Gem::Requirement
16
+ requirement: &70280538886600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70249036092760
24
+ version_requirements: *70280538886600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activerecord
27
- requirement: &70249036092260 !ruby/object:Gem::Requirement
27
+ requirement: &70280538886100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70249036092260
35
+ version_requirements: *70280538886100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: i18n
38
- requirement: &70249036091840 !ruby/object:Gem::Requirement
38
+ requirement: &70280538885680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70249036091840
46
+ version_requirements: *70280538885680
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: combustion
49
- requirement: &70249036091300 !ruby/object:Gem::Requirement
49
+ requirement: &70280538885140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 0.3.1
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70249036091300
57
+ version_requirements: *70280538885140
58
58
  description: A double-entry bookkeeping system for Ruby on Rails
59
59
  email:
60
60
  - jeffmess@gmail.com
@@ -77,14 +77,16 @@ files:
77
77
  - lib/pacioli/asset_account.rb
78
78
  - lib/pacioli/company.rb
79
79
  - lib/pacioli/credit.rb
80
- - lib/pacioli/customer.rb
80
+ - lib/pacioli/creditor.rb
81
81
  - lib/pacioli/debit.rb
82
+ - lib/pacioli/debtor.rb
82
83
  - lib/pacioli/equity_account.rb
83
84
  - lib/pacioli/exception.rb
84
85
  - lib/pacioli/expense_account.rb
85
86
  - lib/pacioli/income_account.rb
86
87
  - lib/pacioli/journal_entry.rb
87
88
  - lib/pacioli/liability_account.rb
89
+ - lib/pacioli/party.rb
88
90
  - lib/pacioli/posting_rule.rb
89
91
  - lib/pacioli/transaction.rb
90
92
  - lib/pacioli/validations/company_validator.rb
@@ -101,8 +103,8 @@ files:
101
103
  - spec/internal/public/favicon.ico
102
104
  - spec/lib/pacioli/account_spec.rb
103
105
  - spec/lib/pacioli/company_spec.rb
104
- - spec/lib/pacioli/customer_spec.rb
105
106
  - spec/lib/pacioli/journal_entry_spec.rb
107
+ - spec/lib/pacioli/party_spec.rb
106
108
  - spec/lib/pacioli/posting_rule_spec.rb
107
109
  - spec/spec_helper.rb
108
110
  - spec/support/helpers.rb
@@ -140,8 +142,8 @@ test_files:
140
142
  - spec/internal/public/favicon.ico
141
143
  - spec/lib/pacioli/account_spec.rb
142
144
  - spec/lib/pacioli/company_spec.rb
143
- - spec/lib/pacioli/customer_spec.rb
144
145
  - spec/lib/pacioli/journal_entry_spec.rb
146
+ - spec/lib/pacioli/party_spec.rb
145
147
  - spec/lib/pacioli/posting_rule_spec.rb
146
148
  - spec/spec_helper.rb
147
149
  - spec/support/helpers.rb
@@ -1,31 +0,0 @@
1
- module Pacioli
2
- class Customer < ActiveRecord::Base
3
- belongs_to :customerable, polymorphic: true
4
- belongs_to :company, foreign_key: :pacioli_company_id
5
- has_many :transactions, foreign_key: :pacioli_customer_id
6
-
7
- def self.for(customer)
8
- Customer.where(customerable_type: customer.class.name, customerable_id: customer.id).first || Customer.create!(customerable_type: customer.class.name, customerable_id: customer.id)
9
- end
10
-
11
- def with_name(customer_name)
12
- self.name = customer_name
13
- end
14
-
15
- def with_source(customerable_object)
16
- self.customerable = customerable_object
17
- end
18
-
19
- def debits
20
- transactions.where(type: 'Pacioli::Debit')
21
- end
22
-
23
- def credits
24
- transactions.where(type: 'Pacioli::Credit')
25
- end
26
-
27
- def balance
28
- debits.sum(&:amount) - credits.sum(&:amount)
29
- end
30
- end
31
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Pacioli::Customer do
4
- include Helpers
5
-
6
- before(:each) do
7
- tear_it_down
8
-
9
- @company = Pacioli::register_company do
10
- with_name "Coca-Cola"
11
- end
12
-
13
- @customer = @company.register_customer do
14
- with_name "Leonardo da Vinci"
15
- end
16
- end
17
-
18
- it "should create a customer" do
19
- Pacioli::Customer.all.count.should == 1
20
- @customer.name.should == "Leonardo da Vinci"
21
- @customer.company.should == @company
22
- end
23
- end