Class: DailyFocus::RunPolicy

Inherits:
Object
  • Object
show all
Defined in:
app/services/daily_focus/run_policy.rb

Overview

Decides which sales reps receive an automated Daily Focus job for a calendar day,
using schedule capacity (Employee#working_on_day? / capacity_ratio) and backup pairing
(EmployeeRecord#backup_rep) to roll covered reps into their working backup's briefing.

Reps who are not working that day do not get their own job; if they have a backup who
is working and is also an active sales rep, their scope is merged into the backup's run.

Defined Under Namespace

Classes: Target

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(date: Date.current, employee_scope: nil, working_predicate: nil) ⇒ RunPolicy

Returns a new instance of RunPolicy.

Parameters:

  • date (Date) (defaults to: Date.current)
  • employee_scope (ActiveRecord::Relation, nil) (defaults to: nil)

    Optional subset of employees (e.g. tests).

  • working_predicate (Proc, nil) (defaults to: nil)

    Optional +call(employee)+ override for schedule (true = working that day).



83
84
85
86
87
# File 'app/services/daily_focus/run_policy.rb', line 83

def initialize(date: Date.current, employee_scope: nil, working_predicate: nil)
  @date = date
  @employee_scope = employee_scope
  @working_predicate = working_predicate
end

Class Method Details

.covering_conversation_for(date:, employee_id:) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'app/services/daily_focus/run_policy.rb', line 13

def self.covering_conversation_for(date:, employee_id:)
  eid = employee_id.to_i
  return nil if eid <= 0

  AssistantConversation
    .for_daily_focus_date(date)
    .where("COALESCE((metadata->'daily_focus_covered_employee_ids')::jsonb, '[]'::jsonb) @> ?", [eid].to_json)
    .order(updated_at: :desc)
    .first
end

.covering_rows_for_review(date:, rep_ids:) ⇒ Hash

One query for all "covered" reps on the review page instead of N calls to +covering_conversation_for+.

Returns:

  • (Hash)

    rep_id (Integer) => { conversation:, covering_rep: }



26
27
28
29
30
31
32
33
34
35
36
37
# File 'app/services/daily_focus/run_policy.rb', line 26

def self.covering_rows_for_review(date:, rep_ids:)
  rep_id_set = rep_ids.to_set(&:to_i)
  return {} if rep_id_set.empty?

  convs = conversations_with_covered_reps(date)
  rep_to_conv = index_covering_conversation_by_rep(convs, rep_id_set)
  primary_by_conv_id = index_covering_primary_by_conversation(rep_to_conv.values.uniq)

  rep_to_conv.transform_values do |conv|
    { conversation: conv, covering_rep: primary_by_conv_id[conv.id] }
  end
end

Instance Method Details

#automation_targetsArray<Target>

Returns One target per working sales rep (may include covered_employee_ids).

Returns:

  • (Array<Target>)

    One target per working sales rep (may include covered_employee_ids).



90
91
92
# File 'app/services/daily_focus/run_policy.rb', line 90

def automation_targets
  @automation_targets ||= compute_automation_targets
end

#covered_rep_idsObject

Rep ids whose briefing is folded into another rep's run (no standalone job).



95
96
97
# File 'app/services/daily_focus/run_policy.rb', line 95

def covered_rep_ids
  automation_targets.flat_map(&:covered_employee_ids).uniq
end