Class: EmployeeEvent

Inherits:
ApplicationRecord show all
Includes:
Models::Auditable
Defined in:
app/models/employee_event.rb

Overview

== Schema Information

Table name: employee_events
Database name: primary

id :integer not null, primary key
accumulated :integer
authorized :boolean default(FALSE)
avoid_lunch :boolean default(FALSE)
backup :string
broken_down :boolean default(FALSE)
broken_down_time :integer
date :date
day_block_departments :text
description :string(750)
event_time :integer
from_hour :time
from_hour_legacy :time
over_budget_alert :boolean default(FALSE)
status :enum default("working")
sub_status :integer
time_to_add :integer
to_hour :time
to_hour_legacy :time
created_at :datetime
updated_at :datetime
backup_employee_id :integer
employee_id :integer

Indexes

employee_events_backup_employee_id_idx (backup_employee_id)
index_employee_events_on_date (date)
index_employee_events_on_employee_id (employee_id)

Foreign Keys

fk_rails_... (backup_employee_id => parties.id) ON DELETE => nullify
fk_rails_... (employee_id => parties.id) ON DELETE => restrict

Constant Summary collapse

STATES_FOR_GOOGLE_CALENDAR =

States for google calendar.

%w[working_no_calls not_working_timeoff partial_timeoff not_working_unpaid_timeoff short_term_disability jury_duty bereavement birthday company_holiday community_service
working_on_service parental_leave].freeze
STATUS_COLOR =

Status color.

{ working_no_calls: "#f0ad4e", not_working_closed: "#d7d7d7", not_working_timeoff: "#d9534f",
partial_timeoff: "#94E994",
not_working_unpaid_timeoff: "#d9534f", short_term_disability: "#337ab7", jury_duty: "#337ab7",
bereavement: "#337ab7", birthday: "#5bc0de", community_service: "#5bc0de", parental_leave: "#5bc0de" }.freeze

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Schedulable

Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Methods included from Models::Auditable

#creator, #updater

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#dateObject (readonly)

TODO: implement a validation that does not allow overlapping of time event of same status for a given time range/employee
validates_uniqueness_of :employee_id, :scope => :date

Validations:



52
# File 'app/models/employee_event.rb', line 52

validates :employee_id, :status, :date, presence: true

#employee_idObject (readonly)

TODO: implement a validation that does not allow overlapping of time event of same status for a given time range/employee
validates_uniqueness_of :employee_id, :scope => :date

Validations:



52
# File 'app/models/employee_event.rb', line 52

validates :employee_id, :status, :date, presence: true

#statusObject (readonly)

TODO: implement a validation that does not allow overlapping of time event of same status for a given time range/employee
validates_uniqueness_of :employee_id, :scope => :date

Validations:



52
# File 'app/models/employee_event.rb', line 52

validates :employee_id, :status, :date, presence: true

Class Method Details

.banked_time_select_optionsObject



114
115
116
117
# File 'app/models/employee_event.rb', line 114

def self.banked_time_select_options
  # (0..8).to_a.map{|i| [STATUS[i],i]}
  banked_times.map { |n, v| [n.to_s.humanize, v] } if CurrentScope.user&.is_manager?
end

.by_monthActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are by month. Active Record Scope

Returns:

See Also:



74
# File 'app/models/employee_event.rb', line 74

scope :by_month, ->(d) { where(date: d.all_month) }

.dates_blockedActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are dates blocked. Active Record Scope

Returns:

See Also:



84
# File 'app/models/employee_event.rb', line 84

scope :dates_blocked, -> { where(status: 'block_a_day') }

.events_needing_attentionActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are events needing attention. Active Record Scope

Returns:

See Also:



80
# File 'app/models/employee_event.rb', line 80

scope :events_needing_attention, ->(date = Date.current) { where('date = ? OR authorized = ?', date, false).where.not(status: %w[add_banked_time block_a_day]) }

.from_active_employeesActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are from active employees. Active Record Scope

Returns:

See Also:



81
# File 'app/models/employee_event.rb', line 81

scope :from_active_employees, -> { where(employee_id: Employee.active_employees.pluck(:id)) }

.full_day_requestsActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are full day requests. Active Record Scope

Returns:

See Also:



75
# File 'app/models/employee_event.rb', line 75

scope :full_day_requests, -> { where(from_hour: '00:00:00') }

.future_eventsActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are future events. Active Record Scope

Returns:

See Also:



82
# File 'app/models/employee_event.rb', line 82

scope :future_events, -> { where("date > (?)", Date.current) }

.partial_day_requestsActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are partial day requests. Active Record Scope

Returns:

See Also:



76
# File 'app/models/employee_event.rb', line 76

scope :partial_day_requests, -> { where.not(from_hour: '00:00:00') }

.status_report_optionsObject



109
110
111
112
# File 'app/models/employee_event.rb', line 109

def self.status_report_options
  [['Time Off', 'not_working_timeoff'], ['Unpaid Time Off', 'not_working_unpaid_timeoff'], ['Short Term Disability', 'short_term_disability'], ['Jury Duty', 'jury_duty'], ['Bereavement', 'bereavement'], ['Birthday', 'birthday'],
   ['Parental Leave', 'parental_leave']]
end

.status_select_options(options = {}) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/models/employee_event.rb', line 92

def self.status_select_options(options = {})
  admin_options = statuses.reject { |n, _v| n.to_s != "add_banked_time" && n.to_s != "block_a_day" }.map { |n, v| [n.to_s.humanize, v] }
  employee_options = statuses.reject do |n, _v|
    %w[add_banked_time working not_working_closed partial_timeoff block_a_day company_holiday].include?(n.to_s)
  end.map { |n, v| [n.to_s.humanize, v] }
  if options[:current_user]&.is_manager? || options[:include_all_options]
    [
      ['Time Off types', employee_options],
      ['Admin only', admin_options]
    ]
  else
    [
      ['Time Off types', employee_options]
    ]
  end
end

.time_off_eventsActiveRecord::Relation<EmployeeEvent>

A relation of EmployeeEvents that are time off events. Active Record Scope

Returns:

See Also:



83
# File 'app/models/employee_event.rb', line 83

scope :time_off_events, -> { where.not(status: 'block_a_day') }

Instance Method Details

#backup_employeeEmployee

Returns:

See Also:



48
# File 'app/models/employee_event.rb', line 48

belongs_to :backup_employee, class_name: 'Employee', optional: true

#employeeEmployee

Returns:

See Also:



47
# File 'app/models/employee_event.rb', line 47

belongs_to :employee, optional: true

#full_day?Boolean

Returns:

  • (Boolean)


119
120
121
# File 'app/models/employee_event.rb', line 119

def full_day?
  from_hour == to_hour
end

#is_partial?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'app/models/employee_event.rb', line 123

def is_partial?
  status == "not_working_timeoff" && from_hour != to_hour
end

#pto_takenObject



127
128
129
130
131
# File 'app/models/employee_event.rb', line 127

def pto_taken
  taken = 0
  taken = (event_time || 0) - (broken_down_time || 0) if status.in?(%w[not_working_timeoff partial_timeoff])
  taken
end

#send_to_google_calendar(action) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'app/models/employee_event.rb', line 133

def send_to_google_calendar(action)
  # First let's get a calendar service

  client = Signet::OAuth2::Client.new(
                                      client_id: Heatwave::Configuration.fetch(:omniauth, :google_oauth2_id),
                                      client_secret: Heatwave::Configuration.fetch(:omniauth, :google_oauth2_secret),
                                      access_token: employee..authentications.google_auth&.first&.google_auth_access_token,
                                      refresh_token: employee..authentications.google_auth&.first&.google_auth_refresh_token,
                                      authorization_uri: 'https://accounts.google.com/o/oauth2/auth',
                                      token_credential_uri: 'https://accounts.google.com/o/oauth2/token'
                                    )
  service = Google::Apis::CalendarV3::CalendarService.new
  service.authorization = client
  # Now lets use it
  case action
  when 'create'
    if status.in?(STATES_FOR_GOOGLE_CALENDAR)
      define_event_times

      event = Google::Apis::CalendarV3::Event.new(
        id: "ee#{id}",
        summary: status.titleize,
        description: description,
        start: @start_time,
        end: @end_time
      )
      service.insert_event(employee.email, event)
    end
  when 'update'
    if status.in?(STATES_FOR_GOOGLE_CALENDAR)
      define_event_times

      event = service.get_event(employee.email, "ee#{id}")
      event.summary = status.titleize
      event.description = description
      event.start = @start_time
      event.end = @end_time

      service.update_event(employee.email, "ee#{id}", event)
    end
  when 'destroy'
    begin
      service.delete_event(employee.email, "ee#{id}")
    rescue StandardError
      nil
    end
  end
rescue Google::Apis::AuthorizationError
  begin
    response = client.refresh!
    employee..authentications.google_auth.first.update(google_auth_access_token: response['access_token'])
    retry
  rescue StandardError => e
    ErrorReporting.error e
  end
rescue Google::Apis::ClientError => e
  if e.status_code == 409
    # The event already exists, so we update it.
    service.update_event(employee.email, "ee#{id}", event)
  end
end