Class: DoubleEntry::Line
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- DoubleEntry::Line
- Defined in:
- lib/double_entry/line.rb
Overview
This is the table to end all tables!
Every financial transaction gets two entries in here: one for the source account, and one for the destination account. Normal double-entry accounting principles are followed.
This is a log table, and should (ideally) never be updated.
## Indexes
The indexes on this table are carefully chosen, as it’s both big and heavily loaded.
### lines_scope_account_id_idx
“‘sql ADD INDEX `lines_scope_account_id_idx` (scope, account, id) “`
This is the important one. It’s used primarily for querying the current balance of an account. eg:
“‘sql SELECT * FROM `lines` WHERE scope = ? AND account = ? ORDER BY id DESC LIMIT 1 “`
### lines_scope_account_created_at_idx
“‘sql ADD INDEX `lines_scope_account_created_at_idx` (scope, account, created_at) “`
Used for querying historic balances:
“‘sql SELECT * FROM `lines` WHERE scope = ? AND account = ? AND created_at < ? ORDER BY id DESC LIMIT 1 “`
And for reporting on account changes over a time period:
“‘sql SELECT SUM(amount) FROM `lines` WHERE scope = ? AND account = ? AND created_at BETWEEN ? AND ? “`
### lines_account_created_at_idx and lines_account_code_created_at_idx
“‘sql ADD INDEX `lines_account_created_at_idx` (account, created_at); ADD INDEX `lines_account_code_created_at_idx` (account, code, created_at); “`
These two are used for generating reports, which need to sum things by account, or account and code, over a particular period.
Class Method Summary collapse
-
.find_id_and_created_at(options) ⇒ Object
Query out just the id and created_at fields for lines, without instantiating any ActiveRecord objects.
Instance Method Summary collapse
- #account ⇒ Object
- #account=(account) ⇒ Object
- #amount ⇒ Object
- #amount=(money) ⇒ Object
- #balance ⇒ Object
- #balance=(money) ⇒ Object
- #code ⇒ Object
- #code=(code) ⇒ Object
- #currency ⇒ Object
- #decrease? ⇒ Boolean
- #increase? ⇒ Boolean
- #pair ⇒ Object
- #partner ⇒ Object
- #partner_account ⇒ Object
- #partner_account=(partner_account) ⇒ Object
- #save ⇒ Object
- #save! ⇒ Object
Class Method Details
.find_id_and_created_at(options) ⇒ Object
Query out just the id and created_at fields for lines, without instantiating any ActiveRecord objects.
147 148 149 150 151 152 |
# File 'lib/double_entry/line.rb', line 147 def self.find_id_and_created_at() connection.select_rows <<-SQL SELECT id, created_at FROM #{Line.quoted_table_name} #{[:joins]} WHERE #{sanitize_sql_for_conditions([:conditions])} SQL end |
Instance Method Details
#account ⇒ Object
106 107 108 |
# File 'lib/double_entry/line.rb', line 106 def account DoubleEntry.account(self[:account].to_sym, scope_identity: scope) end |
#account=(account) ⇒ Object
99 100 101 102 103 104 |
# File 'lib/double_entry/line.rb', line 99 def account=(account) self[:account] = account.identifier.to_s self.scope = account.scope_identity fail 'Missing Account' unless self.account account end |
#amount ⇒ Object
64 65 66 |
# File 'lib/double_entry/line.rb', line 64 def amount self[:amount] && Money.new(self[:amount], currency) end |
#amount=(money) ⇒ Object
68 69 70 |
# File 'lib/double_entry/line.rb', line 68 def amount=(money) self[:amount] = (money && money.fractional) end |
#balance ⇒ Object
72 73 74 |
# File 'lib/double_entry/line.rb', line 72 def balance self[:balance] && Money.new(self[:balance], currency) end |
#balance=(money) ⇒ Object
76 77 78 |
# File 'lib/double_entry/line.rb', line 76 def balance=(money) self[:balance] = (money && money.fractional) end |
#code ⇒ Object
95 96 97 |
# File 'lib/double_entry/line.rb', line 95 def code self[:code].try(:to_sym) end |
#code=(code) ⇒ Object
90 91 92 93 |
# File 'lib/double_entry/line.rb', line 90 def code=(code) self[:code] = code.try(:to_s) code end |
#currency ⇒ Object
110 111 112 |
# File 'lib/double_entry/line.rb', line 110 def currency account.currency if self[:account] end |
#decrease? ⇒ Boolean
137 138 139 |
# File 'lib/double_entry/line.rb', line 137 def decrease? amount.negative? end |
#increase? ⇒ Boolean
141 142 143 |
# File 'lib/double_entry/line.rb', line 141 def increase? amount.positive? end |
#pair ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/double_entry/line.rb', line 129 def pair if decrease? [self, partner] else [partner, self] end end |
#partner ⇒ Object
125 126 127 |
# File 'lib/double_entry/line.rb', line 125 def partner self.class.find(partner_id) end |
#partner_account ⇒ Object
121 122 123 |
# File 'lib/double_entry/line.rb', line 121 def partner_account DoubleEntry.account(self[:partner_account].to_sym, scope_identity: partner_scope) end |
#partner_account=(partner_account) ⇒ Object
114 115 116 117 118 119 |
# File 'lib/double_entry/line.rb', line 114 def partner_account=(partner_account) self[:partner_account] = partner_account.identifier.to_s self.partner_scope = partner_account.scope_identity fail 'Missing Partner Account' unless self.partner_account partner_account end |
#save ⇒ Object
80 81 82 83 |
# File 'lib/double_entry/line.rb', line 80 def save(**) check_balance_will_remain_valid super end |
#save! ⇒ Object
85 86 87 88 |
# File 'lib/double_entry/line.rb', line 85 def save!(**) check_balance_will_remain_valid super end |