Class: PhoneQueueRotation

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

Overview

A weekly ring-order rotation rule for one phone queue.

In Order queues ring their members in a fixed sequence, so without rotation
the same agent always takes the first call. RotatePhoneQueuesWorker applies
due rules once a day: the agent at one end of the order moves to the other
end and everyone else shifts one position.

+queue_account_id+ is the Switchvox queue account id (PhoneQueue::REGISTRY),
not a local FK — the PBX owns queue identity.

Constant Summary collapse

DIRECTIONS =

Allowed rotation directions.

%w[last_to_first first_to_last].freeze

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #creator, #should_not_save_version, #stamp_record, #updater

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#directionString

Returns Rotation direction.

Returns:

  • (String)

    Rotation direction.



28
# File 'app/models/phone_queue_rotation.rb', line 28

validates :direction, presence: true, inclusion: { in: DIRECTIONS }

#queue_account_idString

Returns Switchvox queue account id.

Returns:

  • (String)

    Switchvox queue account id.



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

validates :queue_account_id, presence: true, uniqueness: true, inclusion: { in: PhoneQueue::REGISTRY.keys }

#weekdayInteger

Returns Day of week (0-6).

Returns:

  • (Integer)

    Day of week (0-6).



31
# File 'app/models/phone_queue_rotation.rb', line 31

validates :weekday, presence: true, inclusion: { in: 0..6 }

Class Method Details

.due_todayActiveRecord::Relation<PhoneQueueRotation>

A relation of PhoneQueueRotations that are due today. Active Record Scope

Returns:

See Also:



38
39
40
41
# File 'app/models/phone_queue_rotation.rb', line 38

scope :due_today, lambda {
  where(active: true, weekday: Date.current.wday)
    .where('last_rotated_at IS NULL OR last_rotated_at < ?', Date.current.beginning_of_day)
}

Instance Method Details

#due_todayActiveRecord::Relation<PhoneQueueRotation>

Rules due for a rotation today: active, scheduled for this weekday, and
not yet rotated today. +last_rotated_at+ doubles as the idempotency
marker, so a worker re-run in the same day is a no-op.

Returns:



38
39
40
41
# File 'app/models/phone_queue_rotation.rb', line 38

scope :due_today, lambda {
  where(active: true, weekday: Date.current.wday)
    .where('last_rotated_at IS NULL OR last_rotated_at < ?', Date.current.beginning_of_day)
}

#rotated_order(member_ids) ⇒ Array

Returns the order after one rotation step.

Parameters:

  • member_ids (Array)

    member account ids in current ring order

Returns:

  • (Array)

    the order after one rotation step



45
46
47
# File 'app/models/phone_queue_rotation.rb', line 45

def rotated_order(member_ids)
  direction == 'first_to_last' ? member_ids.rotate(1) : member_ids.rotate(-1)
end

#to_sString

Returns the rule in plain English, e.g. "Every Monday: last
agent moves to position 1, everyone else shifts down one.".

Returns:

  • (String)

    the rule in plain English, e.g. "Every Monday: last
    agent moves to position 1, everyone else shifts down one."



51
52
53
54
55
56
57
# File 'app/models/phone_queue_rotation.rb', line 51

def to_s
  if direction == 'first_to_last'
    "Every #{Date::DAYNAMES[weekday]}: first agent moves to the end, everyone else shifts up one."
  else
    "Every #{Date::DAYNAMES[weekday]}: last agent moves to position 1, everyone else shifts down one."
  end
end