Class: JournalEntry

Inherits:
Ekylibre::Record::Base show all
Includes:
Attachable
Defined in:
app/models/journal_entry.rb

Overview

There is 3 types of set of values (debit, credit…). These types corresponds to the 3 currency we always add in accountancy:

- *          in journal currency
- real_*     in financial year currency
- absolute_* in global currency (the same as current financial year's theoretically)

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Ekylibre::Record::Base

#already_updated?, attr_readonly_with_conditions, #check_if_destroyable?, #check_if_updateable?, columns_definition, complex_scopes, customizable?, #customizable?, #customized?, #destroyable?, #editable?, has_picture, #human_attribute_name, human_attribute_name_with_id, nomenclature_reflections, #old_record, #others, refers_to, scope_with_registration, simple_scopes, #updateable?

Class Method Details

.journal_condition(journals = {}, table_name = nil) ⇒ Object

Build an SQL condition based on options which should contains acceptable states


118
119
120
121
122
123
124
125
126
# File 'app/models/journal_entry.rb', line 118

def self.journal_condition(journals = {}, table_name = nil)
  table = table_name || self.table_name
  journals = {} unless journals.is_a? Hash
  if journals.empty?
    return JournalEntry.connection.quoted_false
  else
    return "#{table}.journal_id IN (#{journals.collect { |s, _v| JournalEntry.connection.quote(s.to_i) }.join(',')})"
  end
end

.period_condition(period, started_on, stopped_on, table_name = nil) ⇒ Object

Build a condition for filter journal entries on period


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'app/models/journal_entry.rb', line 129

def self.period_condition(period, started_on, stopped_on, table_name = nil)
  table = table_name || self.table_name
  if period.to_s == 'all'
    return connection.quoted_true
  else
    conditions = []
    started_on, stopped_on = period.to_s.split('_')[0..1] unless period.to_s == 'interval'
    if started_on.present? && (started_on.is_a?(Date) || started_on =~ /^\d\d\d\d\-\d\d\-\d\d$/)
      conditions << "#{table}.printed_on >= #{connection.quote(started_on.to_date)}"
    end
    if stopped_on.present? && (stopped_on.is_a?(Date) || stopped_on =~ /^\d\d\d\d\-\d\d\-\d\d$/)
      conditions << "#{table}.printed_on <= #{connection.quote(stopped_on.to_date)}"
    end
    return connection.quoted_false if conditions.empty?
    return '(' + conditions.join(' AND ') + ')'
  end
end

.state_condition(states = {}, table_name = nil) ⇒ Object

Build an SQL condition based on options which should contains acceptable states


107
108
109
110
111
112
113
114
115
# File 'app/models/journal_entry.rb', line 107

def self.state_condition(states = {}, table_name = nil)
  table = table_name || self.table_name
  states = {} unless states.is_a? Hash
  if states.empty?
    return JournalEntry.connection.quoted_false
  else
    return "#{table}.state IN (#{states.collect { |s, _v| JournalEntry.connection.quote(s) }.join(',')})"
  end
end

.state_label(state) ⇒ Object


252
253
254
# File 'app/models/journal_entry.rb', line 252

def self.state_label(state)
  tc('states.' + state.to_s)
end

.statesObject

Returns states names


148
149
150
# File 'app/models/journal_entry.rb', line 148

def self.states
  state_machine.states.collect(&:name)
end

Instance Method Details

#add_credit(name, account, amount, options = {}) ⇒ Object


339
340
341
# File 'app/models/journal_entry.rb', line 339

def add_credit(name, , amount, options = {})
  add!(name, , amount, options.merge(credit: true))
end

#add_debit(name, account, amount, options = {}) ⇒ Object

Adds an entry_item with the minimum informations. It computes debit and credit with the “amount”. If the amount is negative, the amount is put in the other column (debit or credit). Example:

entry.add_debit("blabla", , -65) # will put +65 in +credit+ column

334
335
336
# File 'app/models/journal_entry.rb', line 334

def add_debit(name, , amount, options = {})
  add!(name, , amount, options)
end

#balanced?Boolean

determines if the entry is balanced or not.

Returns:

  • (Boolean)

266
267
268
# File 'app/models/journal_entry.rb', line 266

def balanced?
  balance.zero? # and self.items.count > 0
end

#cancelObject

Add a entry which cancel the entry Create counter-entry_items


278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'app/models/journal_entry.rb', line 278

def cancel
  reconcilable_accounts = []
  entry = self.class.new(journal: journal, resource: resource, real_currency: real_currency, real_currency_rate: real_currency_rate, printed_on: printed_on)
  ActiveRecord::Base.transaction do
    entry.save!
    for item in useful_items
      entry.send(:add!, tc(:entry_cancel, number: self.number, name: item.name), item., (item.debit - item.credit).abs, credit: (item.debit > 0))
      reconcilable_accounts << item. if item..reconcilable? && !reconcilable_accounts.include?(item.)
    end
  end
  # Mark accounts
  for  in reconcilable_accounts
    .mark_entries(self, entry)
  end
  entry
end

#main_bank_statement_numberObject


261
262
263
# File 'app/models/journal_entry.rb', line 261

def main_bank_statement_number
  bank_statement.first.number if bank_statement.count > 0
end

#refreshObject

this method computes the debit and the credit of the entry.


271
272
273
274
# File 'app/models/journal_entry.rb', line 271

def refresh
  reload
  save!
end

#save_with_items(entry_items) ⇒ Object


295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'app/models/journal_entry.rb', line 295

def save_with_items(entry_items)
  ActiveRecord::Base.transaction do
    saved = save

    # Remove removed items and keep existings
    items.where.not(id: entry_items.map { |i| i[:id] }).find_each(&:destroy)

    entry_items.each_with_index do |entry_item, _index|
      item = items.detect { |i| i.id == entry_item[:id].to_i }
      if item
        item.attributes = entry_item.except(:id)
      else
        item = items.build(entry_item.except(:id))
      end
      saved = false unless item.save
    end
    if saved
      reload
      unless items.any?
        errors.add(:items, :empty)
        saved = false
      end
      unless balanced?
        errors.add(:debit, :unbalanced)
        saved = false
      end
    end
    if saved
      return true
    else
      raise ActiveRecord::Rollback
    end
  end
  false
end

#state_labelObject

Prints human name of current state


257
258
259
# File 'app/models/journal_entry.rb', line 257

def state_label
  self.class.state_label(self.state)
end