Class: Reimbursement

Inherits:
ApplicationRecord show all
Includes:
HasComments, HasState
Defined in:
app/models/reimbursement.rb

Overview

Reimbursement for a given request

State Machines

This class contains 1 state machine(s).

state

Instance Attribute Summary collapse

Belongs to collapse

Has many collapse

Has one collapse

Delegated Instance Attributes collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from HasState

#active?, #assigned_roles, #can_be_destroyed?, #cancel, #editable?, #human_state_description, #human_state_guide, #in_final_state?, #in_initial_state?, #notify_state, #title, #with_transitions?

Methods inherited from ApplicationRecord

ransackable_attributes

Instance Attribute Details

#acceptance_fileString

Returns:

  • (String)

Validations (if => -> { acceptance_file_required? } ):



42
# File 'app/models/reimbursement.rb', line 42

validates :acceptance_file, presence: true, if: -> { acceptance_file_required? }

#created_atDateTime

Returns:

  • (DateTime)


170
# File 'db/schema.rb', line 170

t.datetime "created_at"

#descriptionText

Returns:

  • (Text)


169
# File 'db/schema.rb', line 169

t.text "description"

#stateString

Returns:

  • (String)


166
# File 'db/schema.rb', line 166

t.string "state"

#state_updated_atDateTime

Returns:

  • (DateTime)


172
# File 'db/schema.rb', line 172

t.datetime "state_updated_at"

#updated_atDateTime

Returns:

  • (DateTime)


171
# File 'db/schema.rb', line 171

t.datetime "updated_at"

Class Method Details

.expenses_sum(attr = :total, reimbursements) ⇒ Object

See Also:

  • Request.expenses_sum


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

def self.expenses_sum(attr = :total, reimbursements)
  r_ids = if reimbursements.is_a?(ActiveRecord::Relation)
            reimbursements.reorder('').pluck('reimbursements.request_id')
          else
            reimbursements.map(&:request_id)
          end
  ReimbursableRequest.expenses_sum(attr, r_ids)
end

.ransackable_associations(_auth_object) ⇒ Object



207
208
209
# File 'app/models/reimbursement.rb', line 207

def self.ransackable_associations(_auth_object)
  %w[request]
end

Instance Method Details

#acceptance_file_required?Boolean

Checks whether the acceptance file is required in order to be a valid reimbursement

Returns:

  • (Boolean)

    true if signed acceptance is required



149
150
151
# File 'app/models/reimbursement.rb', line 149

def acceptance_file_required?
  !(incomplete? || canceled?)
end

#attachmentsActiveRecord::Relation<ReimbursementAttachment>

Attachments for providing invoices and reports

Returns:

See Also:



20
# File 'app/models/reimbursement.rb', line 20

has_many :attachments, class_name: 'ReimbursementAttachment', inverse_of: :reimbursement, dependent: :destroy

#bank_accountBankAccount

Bank information goes to another model



27
# File 'app/models/reimbursement.rb', line 27

has_one :bank_account, inverse_of: :reimbursement, dependent: :destroy, autosave: true

#can_cancel?Boolean

Checks whether can have a transition to 'canceled' state

Overrides the HasState.can_cancel?, preventing cancelation of reimbursements that have already been processed return [Boolean] true if #cancel can be called

Returns:

  • (Boolean)

See Also:



141
142
143
# File 'app/models/reimbursement.rb', line 141

def can_cancel?
  !canceled? && !processed? && !payed?
end

#commentsActiveRecord::Relation<Comment>

Comments used to discuss decisions (private) or communicate with the requester (public)

Returns:

  • (ActiveRecord::Relation<Comment>)

See Also:



15
# File 'app/models/reimbursement.rb', line 15

has_many :comments, as: :machine, dependent: :destroy

#complete_profile_required?Boolean

Checks whether a complete user profile (with the required information filled) is required in order to be a valid reimbursement. A complete profile is not required if the reimbursement is being rolled back, only when trying to go further into the workflow.

Returns:

  • (Boolean)

    true if the profile have to be complete



159
160
161
162
# File 'app/models/reimbursement.rb', line 159

def complete_profile_required?
  ( && state_was == 'incomplete') ||
    (approved? && state_was == 'submitted')
end

#expensesActiveRecord::Relation<Expense>

The expenses of the associated request, total_amount and authorized_amount will be updated during reimbursement process

Returns:

  • (ActiveRecord::Relation<Expense>)

See Also:



18
# File 'app/models/reimbursement.rb', line 18

has_many :expenses, through: :request, autosave: false

#expenses_sum(*args) ⇒ Object

See Also:

  • Request#expenses_sum


120
121
122
# File 'app/models/reimbursement.rb', line 120

def expenses_sum(*args)
  request.expenses_sum(*args)
end

#false_eventObject

Alias for Request#event

Returns:

  • (Object)

    Request#false_event

See Also:



29
# File 'app/models/reimbursement.rb', line 29

delegate :event, to: :request, prefix: false

#labelString

Label to identify the reimbursement

Overrides the default method to use the request id instead of the internal reimbursement id.

Returns:

  • (String)

    label based in the id of the associated request



170
171
172
# File 'app/models/reimbursement.rb', line 170

def label
  "##{request_id}"
end

Links pointing to reports (ie., blog posts) regarding the requester participation in the event

Returns:

See Also:



23
# File 'app/models/reimbursement.rb', line 23

has_many :links, class_name: 'ReimbursementLink', inverse_of: :reimbursement, dependent: :destroy

#paymentsActiveRecord::Relation<Payment>

Can have several payments, not related to the number of expenses

Returns:

  • (ActiveRecord::Relation<Payment>)

See Also:



25
# File 'app/models/reimbursement.rb', line 25

has_many :payments, inverse_of: :reimbursement, dependent: :restrict_with_exception

#potential_error_full_messages(opts = {}) ⇒ Array<String>

Full error messages that would be caused by the next state transition

It returns the empty set if there are more than one possible transition

Parameters:

  • opts (Hash) (defaults to: {})

    Options to filter the message: :except [Array] fields for which the errors will be ignored

Returns:

  • (Array<String>)

    list of messages



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'app/models/reimbursement.rb', line 181

def potential_error_full_messages(opts = {})
  if state_events.size != 1
    # The next step is not obvious, so we cannot calculate the messages
    return []
  end

  except = Array(opts[:except])
  original_state = state
  event = state_events.first

  # Aggregate all the messages
  send(event)
  error_msgs = errors.messages
  error_msgs.delete_if { |key, _v| except.include?(key) }
  full_messages = []
  error_msgs.each_pair do |attrib, err|
    err.each { |msg| full_messages << errors.full_message(attrib, msg) }
  end

  # Reset state and errors
  self.state = original_state
  valid?

  full_messages
end

#requestReimbursableRequest

The associated request

Validations:



11
12
13
# File 'app/models/reimbursement.rb', line 11

belongs_to :request, inverse_of: :reimbursement,
class_name: 'ReimbursableRequest',
foreign_key: 'request_id'