Module: LedgerAccountable::LedgerItem

Extended by:
ActiveSupport::Concern
Defined in:
lib/ledger_accountable/ledger_item.rb,
lib/ledger_accountable/ledger_item/entry_creator.rb,
lib/ledger_accountable/ledger_item/state_transition.rb

Defined Under Namespace

Classes: EntryCreator, InitializationError, InvalidLedgerOwnerError, StateTransition

Constant Summary collapse

@@require_successful_entries =
!Rails.env.production?
@@epoch =
Time.at(0)

Instance Method Summary collapse

Instance Method Details

#build_ledger_metadataObject



218
219
220
221
# File 'lib/ledger_accountable/ledger_item.rb', line 218

def 
  # can be overridden to return a hash of metadata values
  {}
end

#current_ownerObject



204
205
206
# File 'lib/ledger_accountable/ledger_item.rb', line 204

def current_owner
  send(self.class.ledger_owner)
end

#entries_for_current_owner?Boolean

Returns:

  • (Boolean)


248
249
250
# File 'lib/ledger_accountable/ledger_item.rb', line 248

def entries_for_current_owner?
  ledger_entries.reload.where(owner: current_owner).any?
end

#entries_for_previous_owner?Boolean

Returns:

  • (Boolean)


252
253
254
# File 'lib/ledger_accountable/ledger_item.rb', line 252

def entries_for_previous_owner?
  ledger_entries.reload.where(owner: previous_owner).any?
end

#last_entry_was?(entry_type) ⇒ Boolean

Returns:

  • (Boolean)


223
224
225
226
227
228
229
230
231
# File 'lib/ledger_accountable/ledger_item.rb', line 223

def last_entry_was?(entry_type)
  if current_owner.present?
    ledger_entries.reload.where(owner: current_owner).last&.entry_type == entry_type
  elsif previous_owner.present?
    ledger_entries.reload.where(owner: previous_owner).last&.entry_type == entry_type
  else
    false
  end
end

#ledger_amountObject

the amount to be recorded in the ledger entry on creation or deletion; typically the full amount on the LedgerAccountable object



163
164
165
166
167
168
169
170
# File 'lib/ledger_accountable/ledger_item.rb', line 163

def ledger_amount
  unless respond_to?(self.class.ledger_amount_attribute)
    raise NotImplementedError,
          "LedgerAccountable::LedgerItem model '#{model_name}' specified #{self.class.ledger_amount_attribute} for track_ledger :amount, but does not implement #{self.class.ledger_amount_attribute}"
  end

  ledger_amount_multiplier * (send(self.class.ledger_amount_attribute) || 0)
end

#ledger_attributes_changed?Boolean

Returns:

  • (Boolean)


193
194
195
196
197
198
# File 'lib/ledger_accountable/ledger_item.rb', line 193

def ledger_attributes_changed?
  # if no ledger attributes are specified, only trigger if the balance changed
  return false if ledger_attributes.blank?

  changed_attributes.keys.any? { |key| ledger_attributes.include?(key.to_sym) }
end

#net_ledger_amountObject

the amount to be recorded in the ledger entry on update; typically a net change to the dollar amount stored on the LedgerAccountable object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ledger_accountable/ledger_item.rb', line 174

def net_ledger_amount
  if self.class.ledger_net_amount_method
    net_amount_result = send(self.class.ledger_net_amount_method)
    ledger_amount_multiplier * net_amount_result
  else
    unless attribute_method?(self.class.ledger_amount_attribute.to_s)
      # if a method is provided to compute ledger_amount,
      logger.warn "
LedgerAccountable::LedgerItem model '#{model_name}' appears to use a method for track_ledger :amount, \
but did not provide an option for :net_amount. This can lead to unexpected ledger entry amounts when modifying #{model_name}.
"
    end

    previous_ledger_amount = ledger_amount_multiplier * attribute_was(self.class.ledger_amount_attribute)
    # p 'prev:', previous_ledger_amount, 'cur:', ledger_amount
    ledger_amount - (previous_ledger_amount || 0)
  end
end

#previous_ownerObject



208
209
210
211
212
213
214
215
216
# File 'lib/ledger_accountable/ledger_item.rb', line 208

def previous_owner
  if current_owner.nil?
    # if the owner was removed, get the owner of its last ledger entry
    ledger_entries.reload.last&.owner
  else
    # otherwise get the owner from the last entry NOT for its current owner
    ledger_entries.reload.where.not(owner: current_owner).last&.owner
  end
end

#should_persist_in_ledger?Boolean

An overrideable method to determine if the object should be persisted in the ledger

For example, payments should not be recorded in a ledger until they’re finalized by default, a LedgerAccountable should persist in a ledger if has a ledger_owner via track_ledger

Returns:

  • (Boolean)


238
239
240
241
242
243
244
245
246
# File 'lib/ledger_accountable/ledger_item.rb', line 238

def should_persist_in_ledger?
  # warning log if the ledger owner is not set - the LedgerAccountable model must
  # include track_ledger
  if self.class.ledger_owner.blank?
    Rails.logger.warn "LedgerAccountable::LedgerItem model #{model_name} must include track_ledger to use ledger functionality"
  end

  self.class.ledger_owner.present? && has_current_or_previous_ledger?
end

#to_be_destroyed?Boolean

Returns:

  • (Boolean)


256
257
258
# File 'lib/ledger_accountable/ledger_item.rb', line 256

def to_be_destroyed?
  @_destroy_callback_already_called ||= false
end

#would_change_ledger_balance?Boolean

Returns:

  • (Boolean)


200
201
202
# File 'lib/ledger_accountable/ledger_item.rb', line 200

def would_change_ledger_balance?
  net_ledger_amount != 0
end