pacioli 0.0.10 → 0.0.11

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.
@@ -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