Class: TravelExpenseReport
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- TravelExpenseReport
- Defined in:
- app/models/travel_expense_report.rb
Overview
This model is used to encapsulate the queries involved in the expenses report using the ActiveRecord query interface. It's a read-only model offering a more convenient way of reading information from the request_expenses table, so it's not intended for creating or updating records. Please, use the RequestExpense model for that purpose.
Constant Summary collapse
- BY =
{ event: [ { field: :event_id, sql: 'event_id', hidden: true }, { field: :event_name, sql: 'events.name' }, { field: :event_country, sql: 'events.country_code' }, { field: :event_start_date, sql: 'events.start_date' }, { field: :event_end_date, sql: 'events.end_date' } ], event_country: [{ field: :event_country, sql: 'events.country_code' }], user: [ { field: :user_id, sql: 'requests.user_id', hidden: true }, { field: :user_nickname, sql: 'users.nickname' }, { field: :user_fullname, sql: 'user_profiles.full_name' }, { field: :user_country, sql: 'user_profiles.country_code' } ], user_country: [{ field: :user_country, sql: 'user_profiles.country_code' }], subject: [{ field: :subject, sql: 'request_expenses.subject' }], request: [ { field: :request_id, sql: 'requests.id' }, { field: :request_state, sql: 'requests.state' }, { field: :reimbursement_state, sql: 'reimbursements.state' }, { field: :user_id, sql: 'requests.user_id', hidden: true }, { field: :user_nickname, sql: 'users.nickname' }, { field: :user_fullname, sql: 'user_profiles.full_name' }, { field: :event_id, sql: 'event_id', hidden: true }, { field: :event_name, sql: 'events.name' } ], expense: [ { field: :expense_id, sql: 'request_expenses.id', hidden: true }, { field: :request_id, sql: 'requests.id' }, { field: :request_state, sql: 'requests.state' }, { field: :reimbursement_state, sql: 'reimbursements.state' }, { field: :user_id, sql: 'requests.user_id', hidden: true }, { field: :user_nickname, sql: 'users.nickname' }, { field: :user_fullname, sql: 'user_profiles.full_name' }, { field: :event_id, sql: 'event_id', hidden: true }, { field: :event_name, sql: 'events.name' }, { field: :subject, sql: 'request_expenses.subject' } ] }.freeze
Belongs to collapse
Delegated Instance Attributes collapse
-
#false_event ⇒ Object
Alias for Request#event.
-
#false_reimbursement ⇒ Object
Alias for Request#reimbursement.
-
#false_user ⇒ Object
Alias for Request#user.
Class Method Summary collapse
-
.by ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are by.
-
.count(exp) ⇒ Integer
Total number of records for a given report.
-
.event_country_code_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event country code eq.
-
.event_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event eq.
-
.event_name_contains ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event name contains.
-
.event_start_gte ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event start gte.
-
.event_start_lte ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event start lte.
-
.fields_for(group) ⇒ array
Ordered list of field names for a given call to the 'by' scope.
-
.groups ⇒ array
Available group options for calling the 'by' scope.
-
.reimbursement_state_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are reimbursement state eq.
-
.related_to ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are related to.
-
.request_state_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are request state eq.
-
.user_country_code_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are user country code eq.
-
.user_name_contains ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are user name contains.
Instance Method Summary collapse
-
#related_to?(user) ⇒ Boolean
Checks if the report is related to a given user.
-
#value_for(name) ⇒ Object
Casted value of a given attribute.
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes
Class Method Details
.by ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are by. Active Record Scope
75 76 77 78 79 80 81 82 |
# File 'app/models/travel_expense_report.rb', line 75 scope :by, lambda { |type, g| currency = RequestExpense.currency_field_for(type.to_sym) r = joins(request: [{ user: :profile }, :event]) r = r.joins('LEFT JOIN reimbursements ON reimbursements.request_id = requests.id') r = r.select("sum(#{type}_amount) AS sum_amount, #{currency} AS sum_currency, #{TravelExpenseReport::BY[g.to_sym].map { |f| "#{f[:sql]} AS #{f[:field]}" }.join(', ')}") r = r.where("#{type}_amount IS NOT NULL") r = r.group("#{currency}, #{TravelExpenseReport::BY[g.to_sym].map { |f| f[:sql] }.join(', ')}") } |
.count(exp) ⇒ Integer
Total number of records for a given report
192 193 194 195 196 197 198 199 200 201 |
# File 'app/models/travel_expense_report.rb', line 192 def self.count(exp) count = connection.execute("select count(*) as c from (#{exp.except(:limit, :offset, :order).to_sql}) query") result = count.first # Most adapters return a hash, but the MySQL one returns an array if result.is_a?(Array) result.first.to_i else result['c'].to_i end end |
.event_country_code_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event country code eq. Active Record Scope
105 106 107 |
# File 'app/models/travel_expense_report.rb', line 105 scope :event_country_code_eq, lambda { |country| where('events.country_code' => country) } |
.event_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event eq. Active Record Scope
95 96 97 |
# File 'app/models/travel_expense_report.rb', line 95 scope :event_eq, lambda { |event_id| where('events.id' => event_id) } |
.event_name_contains ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event name contains. Active Record Scope
100 101 102 |
# File 'app/models/travel_expense_report.rb', line 100 scope :event_name_contains, lambda { |name| where(['lower(events.name) like ?', "%#{name}%"]) } |
.event_start_gte ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event start gte. Active Record Scope
90 91 92 |
# File 'app/models/travel_expense_report.rb', line 90 scope :event_start_gte, lambda { |date| where(['events.start_date >= ?', date]) } |
.event_start_lte ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are event start lte. Active Record Scope
85 86 87 |
# File 'app/models/travel_expense_report.rb', line 85 scope :event_start_lte, lambda { |date| where(['events.start_date <= ?', date]) } |
.fields_for(group) ⇒ array
Ordered list of field names for a given call to the 'by' scope
138 139 140 |
# File 'app/models/travel_expense_report.rb', line 138 def self.fields_for(group) TravelExpenseReport::BY[group.to_sym].reject { |f| f[:hidden] }.map { |i| i[:field] } + %i[sum_amount sum_currency] end |
.groups ⇒ array
Available group options for calling the 'by' scope
145 146 147 |
# File 'app/models/travel_expense_report.rb', line 145 def self.groups TravelExpenseReport::BY.keys end |
.reimbursement_state_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are reimbursement state eq. Active Record Scope
125 126 127 |
# File 'app/models/travel_expense_report.rb', line 125 scope :reimbursement_state_eq, lambda { |state| where('reimbursements.state' => state.to_s) } |
.related_to ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are related to. Active Record Scope
130 131 132 |
# File 'app/models/travel_expense_report.rb', line 130 scope :related_to, lambda { |user| joins(:request).where('requests.user_id' => user) } |
.request_state_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are request state eq. Active Record Scope
120 121 122 |
# File 'app/models/travel_expense_report.rb', line 120 scope :request_state_eq, lambda { |state| where('requests.state' => state.to_s) } |
.user_country_code_eq ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are user country code eq. Active Record Scope
115 116 117 |
# File 'app/models/travel_expense_report.rb', line 115 scope :user_country_code_eq, lambda { |country| where('user_profiles.country_code' => country) } |
.user_name_contains ⇒ ActiveRecord::Relation<TravelExpenseReport>
A relation of TravelExpenseReports that are user name contains. Active Record Scope
110 111 112 |
# File 'app/models/travel_expense_report.rb', line 110 scope :user_name_contains, lambda { |name| where(['lower(user_profiles.full_name) like ? or lower(users.nickname) like ?'] + ["%#{name}%"] * 2) } |
Instance Method Details
#false_event ⇒ Object
Alias for Request#event
17 |
# File 'app/models/travel_expense_report.rb', line 17 delegate :event, to: :request, prefix: false |
#false_reimbursement ⇒ Object
Alias for Request#reimbursement
15 |
# File 'app/models/travel_expense_report.rb', line 15 delegate :reimbursement, to: :request, prefix: false |
#false_user ⇒ Object
Alias for Request#user
16 |
# File 'app/models/travel_expense_report.rb', line 16 delegate :user, to: :request, prefix: false |
#related_to?(user) ⇒ Boolean
Checks if the report is related to a given user.
Used during access control.
184 185 186 |
# File 'app/models/travel_expense_report.rb', line 184 def (user) request.user == user end |
#request ⇒ Request
14 |
# File 'app/models/travel_expense_report.rb', line 14 belongs_to :request, -> { where 'requests.type' => 'TravelSponsorship' } |
#value_for(name) ⇒ Object
Casted value of a given attribute.
Needed because ActiveRecord always return the attributes as strings when ActiveRelation#select is used. This method casts the attributes back to its correct type. Intended to be used on records resulting from a call to the 'by' scope.
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'app/models/travel_expense_report.rb', line 158 def value_for(name) # At this point creating a more generic solution is not worthy, we simply # check explicitly for one of the three special cases if name.to_sym == :sum_amount # to_f.to_s to ensure that it has a decimal part (with any db engine) BigDecimal(sum_amount.to_f.to_s || '0.0') elsif %i[event_start_date event_end_date].include? name.to_sym d = send(name) if d.blank? nil elsif d.is_a?(Date) d else Date.parse(d) end else send(name) end end |