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)

Defined Under Namespace

Classes: IncompatibleCurrencies

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Ekylibre::Record::Base

#already_updated?, #check_if_destroyable?, #check_if_updateable?, columns_definition, customizable?, #customizable?, #customized?, #destroyable?, has_picture, #human_attribute_name, nomenclature_reflections, #old_record, #others, refers_to, #unsuppress, #updateable?

Methods included from Userstamp::Stampable

included

Methods included from Userstamp::Stamper

included

Class Method Details

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

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


135
136
137
138
139
140
141
142
143
# File 'app/models/journal_entry.rb', line 135

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


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'app/models/journal_entry.rb', line 146

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


124
125
126
127
128
129
130
131
132
# File 'app/models/journal_entry.rb', line 124

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


329
330
331
# File 'app/models/journal_entry.rb', line 329

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

.statesObject

Returns states names


180
181
182
# File 'app/models/journal_entry.rb', line 180

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

Instance Method Details

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


415
416
417
# File 'app/models/journal_entry.rb', line 415

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

410
411
412
# File 'app/models/journal_entry.rb', line 410

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

#balanced?Boolean

determines if the entry is balanced or not.

Returns:

  • (Boolean)

354
355
356
# File 'app/models/journal_entry.rb', line 354

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

#bank_statement_numberObject


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

def bank_statement_number
  bank_statements.first.number if bank_statements.first
end

#cancelObject

Add a entry which cancel the entry Create counter-entry_items


377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'app/models/journal_entry.rb', line 377

def cancel
  return nil unless useful_items.any?
  ActiveRecord::Base.transaction do
    reconcilable_accounts = []
    list = []
    useful_items.each do |item|
      list << JournalEntryItem.new_for(
        tc(:entry_cancel, number: self.number, name: item.name),
        item., (item.debit - item.credit).abs, credit: (item.debit > 0)
      )
      if item..reconcilable? && !reconcilable_accounts.include?(item.)
        reconcilable_accounts << item.
      end
    end
    entry = self.class.create!(
      journal: journal,
      resource: resource,
      real_currency: real_currency,
      real_currency_rate: real_currency_rate,
      printed_on: printed_on,
      items: list
    )
    # Mark accounts
    reconcilable_accounts.each do ||
      .mark_entries(self, entry)
    end
    entry
  end
end

#editable?Boolean

A journal generated by a resource is not editable!

Returns:

  • (Boolean)

304
305
306
# File 'app/models/journal_entry.rb', line 304

def editable?
  resource.nil?
end

#entities_bank_statement_numberObject


325
326
327
# File 'app/models/journal_entry.rb', line 325

def entities_bank_statement_number
  items.where.not(bank_statement_letter: nil).first&.bank_statement_letter
end

#entity_countryObject

FIXME: Nothing to do here. What's the meaning?


349
350
351
# File 'app/models/journal_entry.rb', line 349

def entity_country
  entity_country_code && resource.third.country.l
end

#entity_country_codeObject

FIXME: Nothing to do here. What's the meaning?


343
344
345
346
# File 'app/models/journal_entry.rb', line 343

def entity_country_code
  resource && resource.respond_to?(:third) &&
    resource.third && resource.third.country
end

#expected_financial_yearObject


320
321
322
323
# File 'app/models/journal_entry.rb', line 320

def expected_financial_year
  raise 'Missing printed_on' unless printed_on
  FinancialYear.on(printed_on)
end

#first_paymentObject

return the date of the first payment (incomming or outgoing)


171
172
173
174
175
176
177
# File 'app/models/journal_entry.rb', line 171

def first_payment
  if purchase_payments.any?
    purchase_payments.reorder(:paid_at).first
  elsif incoming_payments.any?
    incoming_payments.reorder(:paid_at).first
  end
end

#letterObject

return the letter if any on items


166
167
168
# File 'app/models/journal_entry.rb', line 166

def letter
  items.pluck(:letter).compact.uniq.first
end

#mark_for_exchange_import!Object

Flag the entry updatable and destroyable, used during financial year exchange import


420
421
422
# File 'app/models/journal_entry.rb', line 420

def mark_for_exchange_import!
  self.importing_from_exchange = true
end

#need_currency_change?Boolean

Returns:

  • (Boolean)

308
309
310
311
312
313
314
315
316
317
318
# File 'app/models/journal_entry.rb', line 308

def need_currency_change?
  return nil unless journal
  year_currency = if financial_year
                    financial_year.currency
                  elsif printed_on? && (year = FinancialYear.on(printed_on))
                    year.currency
                  else
                    Preference[:currency]
                  end
  year_currency != journal.currency
end

#refreshObject

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


359
360
361
362
# File 'app/models/journal_entry.rb', line 359

def refresh
  reload
  save!
end

#removeObject

Destroy or cancel journal depending on its current state


365
366
367
368
369
370
371
372
373
# File 'app/models/journal_entry.rb', line 365

def remove
  reverse_entry = nil
  if draft?
    destroy
  else
    reverse_entry = cancel
  end
  reverse_entry
end

#state_labelObject

Prints human name of current state


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

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