Class: PresetJob

Inherits:
ServiceJob show all
Defined in:
app/models/preset_job.rb

Overview

== Schema Information

Table name: service_jobs
Database name: primary

id :integer not null, primary key
adaptive_start :boolean default(TRUE), not null
completed_on :date
cross_street1 :string(255)
cross_street1_direction :string(255)
cross_street2 :string(255)
cross_street2_direction :string(255)
display_format_celsius :boolean default(FALSE), not null
display_language :string
estimated_size_sqft :float
floor_load :float
floor_protection_mode :string default("laminate")
floor_temperature_max :integer default(82), not null
floor_temperature_min :integer default(41), not null
friday_periods :string default(["6:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
friday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
friday_periods_inactive :boolean default([FALSE, FALSE, TRUE, TRUE, FALSE, FALSE]), is an Array
friday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
is_specified :boolean default(FALSE), not null
job_comments :string(255)
job_date :datetime
measurecomp_job_number :string(255)
measurecomp_order_number :string(255)
monday_periods :string default(["6:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
monday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
monday_periods_inactive :boolean default([FALSE, FALSE, TRUE, TRUE, FALSE, FALSE]), is an Array
monday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
reference_number :string(255) not null
saturday_periods :string default(["8:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
saturday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
saturday_periods_inactive :boolean default([FALSE, TRUE, TRUE, TRUE, TRUE, FALSE]), is an Array
saturday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
serial_number :string(255)
state :string(255)
sunday_periods :string default(["8:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
sunday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
sunday_periods_inactive :boolean default([FALSE, TRUE, TRUE, TRUE, TRUE, FALSE]), is an Array
sunday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
temperature_control_mode :string default("AF"), not null
thursday_periods :string default(["6:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
thursday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
thursday_periods_inactive :boolean default([FALSE, FALSE, TRUE, TRUE, FALSE, FALSE]), is an Array
thursday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
tstat_count :integer
tstat_sku :string
tuesday_periods :string default(["6:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
tuesday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
tuesday_periods_inactive :boolean default([FALSE, FALSE, TRUE, TRUE, FALSE, FALSE]), is an Array
tuesday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
wednesday_periods :string default(["6:00", "9:00", "12:00", "13:00", "17:00", "23:00"]), is an Array
wednesday_periods_floor_temperature :integer default([82, 74, 82, 74, 82, 74]), is an Array
wednesday_periods_inactive :boolean default([FALSE, FALSE, TRUE, TRUE, FALSE, FALSE]), is an Array
wednesday_periods_room_temperature :integer default([70, 62, 70, 62, 70, 62]), is an Array
created_at :datetime
updated_at :datetime
address_id :integer
business_phone_contact_point_id :integer
cell_phone_contact_point_id :integer
contact_id :integer
creator_id :integer
customer_id :integer
delivery_id :integer
email_contact_point_id :integer
home_phone_contact_point_id :integer
line_item_id :integer
order_id :integer
tstat_line_item_id :integer
updater_id :integer

Indexes

index_measurecomp_jobs_on_address_id (address_id)
index_measurecomp_jobs_on_business_phone_contact_point_id (business_phone_contact_point_id)
index_measurecomp_jobs_on_cell_phone_contact_point_id (cell_phone_contact_point_id)
index_measurecomp_jobs_on_customer_id (customer_id)
index_measurecomp_jobs_on_delivery_id (delivery_id)
index_measurecomp_jobs_on_email_contact_point_id (email_contact_point_id)
index_measurecomp_jobs_on_home_phone_contact_point_id (home_phone_contact_point_id)
index_measurecomp_jobs_on_measurecomp_job_number (measurecomp_job_number)
index_measurecomp_jobs_on_order_id (order_id)
index_measurecomp_jobs_on_serial_number (serial_number)
index_service_jobs_on_contact_id (contact_id)
index_service_jobs_on_is_specified (is_specified)
index_service_jobs_on_job_date (job_date)
index_service_jobs_on_line_item_id (line_item_id)
index_service_jobs_on_state (state)

Constant Summary collapse

OJ_LANGUAGES_HASH =

validates :order, :presence => true
validates :delivery, :presence => true, if: Proc.new{|pj| pj.created_at.blank?}
validates :tstat_count, :presence => true
validates_numericality_of :tstat_count, :greater_than_or_equal_to => 1
validate :warming_periods

{ en: 'English', fr: 'Français', es: 'Español' }.freeze
FLOOR_PROTECTION_MODES_HASH =

Floor protection modes hash.

{ laminate: 'Laminate (82 F / 28 C)', tile: 'Tile (104 F / 40 C)', custom: 'Custom', disabled: 'Disabled' }.freeze
DAYS_OF_THE_WEEK =

Days of the week.

%w[monday tuesday wednesday thursday friday saturday sunday].freeze
ICON_FOR_PERIOD =

Icon for period.

['smartpreset-icon-period-1.png', 'smartpreset-icon-period-2.png', 'smartpreset-icon-period-3.png', 'smartpreset-icon-period-4.png'].freeze
ICON_FOR_TEMPERATURE =

Icon for temperature.

%w[fa-sun fa-moon fa-sun fa-moon].freeze
LEGACY_HONEYWELL_PERIOD_DEFAULTS =

Legacy honeywell period defaults.

['06:00', '08:30', '17:00', '23:00'].freeze
LEGACY_HONEYWELL_TEMP_BY_MODE_DEFAULTS_HASH =

Legacy honeywell temp by mode defaults hash.

{ F: [82, 68, 82, 68], AF: [70, 63, 70, 63], A: [70, 63, 70, 63] }.freeze
LEGACY_HONEYWELL_WEEKEND_PERIOD_DEFAULTS =

Legacy honeywell weekend period defaults.

['06:00', '08:30', '17:00', '23:00'].freeze
LEGACY_HONEYWELL_WEEKEND_TEMP_DEFAULTS_HASH =

Legacy honeywell weekend temp defaults hash.

{ F: [82, 68, 82, 68], AF: [70, 63, 70, 63], A: [70, 63, 70, 63] }.freeze
LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN =

Legacy temperature control mode human.

{ A: 'Ambient Temperature (A)', F: 'Floor Temperature (F)', AF: 'Ambient/Floor Temperature (AF)' }.freeze
TEMPERATURE_CONTROL_MODE_HUMAN =

Temperature control mode human.

{ A: 'Room Temperature', F: 'Floor Temperature', AF: 'Room/Floor Limited Temperature' }.freeze
TEMPERATURE_LABEL =

Temperature label.

{ A: 'room', F: 'floor', AF: 'room' }.freeze
DISPLAY_FORMAT =

Display format.

['Celsius/24 Hour Clock', 'Fahrenheit/12 Hour Clock'].freeze
TEMPERATURE_RANGE =

Temperature range.

{ A: [40, 86], F: [41, 104], AF: [40, 86] }.freeze
TEMPERATURE_MODE_KINDS =

Temperature mode kinds.

%w[temperature_comfort temperature_economy temperature_vacation].freeze
TEMPERATURE_MODE_ADJUSTMENTS =

Temperature mode adjustments.

[12, 5, 0].freeze
LEGACY_AMBIENT_TEMPERATURE_MODE_WARNING =

Legacy ambient temperature mode warning.

"For carpet, laminate and other engineered floors, please ensure compliance with the floor covering manufacturer's required minimum and maximum temperature limits.".freeze
AMBIENT_TEMPERATURE_MODE_WARNING =

Ambient temperature mode warning.

"For carpet, laminate and other engineered floors, you need to ensure compliance with the floor covering manufacturer's required minimum and maximum temperature limits to avoid damaging the surface.".freeze
LEGACY_TEMPERATURE_MODE_WARNINGS =

Legacy temperature mode warnings.

{
A: "WarmlyYours STRONGLY recommends using the floor temperature mode of F. If you choose this ambient temperature mode A, please ensure that the remote floor temperature sensor is NOT connected to the thermostat.  #{LEGACY_AMBIENT_TEMPERATURE_MODE_WARNING}", F: 'WarmlyYours recommends using this mode. Please ensure that the remote temperature sensor is connected to the thermostat', AF: "WarmlyYours STRONGLY recommends using the floor temperature mode of F. If you choose this ambient/floor temperature mode AF, please ensure that the remote floor temperature sensor is connected to the thermostat. #{LEGACY_AMBIENT_TEMPERATURE_MODE_WARNING}"
}.freeze
OJ_TEMPERATURE_MODE_WARNINGS =

Oj temperature mode warnings.

{
A: "WarmlyYours recommends using the floor temperature sensor application. If you want to use the room temperature sensor application with carpet, laminate and other engineered floors, please consider the room/floor limited temperature sensor application.  #{AMBIENT_TEMPERATURE_MODE_WARNING}", F: 'WarmlyYours recommends using this sensor application. Please ensure that the remote temperature sensor is connected to the thermostat', AF: "WarmlyYours recommends using the floor temperature sensor application. If you choose this room/floor limited temperature application, please ensure that the remote floor temperature sensor is connected to the thermostat. #{AMBIENT_TEMPERATURE_MODE_WARNING}"
}.freeze
WEEKDAY_TEMP_BY_MODE_DEFAULTS_HASH =

Weekday temp by mode defaults hash.

{
  'UDG4-4999' => { F: [82, 74, 82, 74, 82, 74], AF: [70, 62, 70, 62, 70, 62], A: [70, 62, 70, 62, 70, 62] },
  'UDG4-4999-WY' => { F: [82, 74, 82, 74, 82, 74], AF: [70, 62, 70, 62, 70, 62], A: [70, 62, 70, 62, 70, 62] },
  'UWG4-4999' => { F: [82, 74, 82, 74, 82, 74], AF: [70, 62, 70, 62, 70, 62], A: [70, 62, 70, 62, 70, 62] }
}.freeze
WEEKEND_TEMP_BY_MODE_DEFAULTS_HASH =

OJ Thermostat weekend temp defaults (static, no DB query needed)

{
  'UDG4-4999' => { F: [82, 74, 82, 74, 82, 74], AF: [70, 62, 70, 62, 70, 62], A: [70, 62, 70, 62, 70, 62] },
  'UWG4-4999' => { F: [82, 74, 82, 74, 82, 74], AF: [70, 62, 70, 62, 70, 62], A: [70, 62, 70, 62, 70, 62] }
}.freeze

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary

Attributes inherited from ServiceJob

#job_comments

Belongs to collapse

Methods inherited from ServiceJob

#address, #business_phone_contact_point, #cell_phone_contact_point, #email_contact_point, #home_phone_contact_point

Methods included from Models::Auditable

#creator, #updater

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ServiceJob

active, #business_phone, #business_phone=, #cell_phone, #cell_phone=, complete, #email, #email=, #home_phone, #home_phone=, open_jobs, #primary_phone, #search_text, #set_best_guess_email_contact_point, #set_best_guess_home_phone_contact_point, #set_reference_number, #set_serial_number, #uploads

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 Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Class Method Details

.celsius_to_fahrenheit(c) ⇒ Integer

Converts Celsius to Fahrenheit, rounded to a whole degree.

Parameters:

  • c (Numeric)

    Celsius temperature

Returns:

  • (Integer)


502
503
504
# File 'app/models/preset_job.rb', line 502

def self.celsius_to_fahrenheit(c)
  ((1.8 * c.to_f) + 32.0).round
end

.default_floor_prot_mode_sym_hashHash

Default floor protection mode per thermostat SKU.

Returns:

  • (Hash)


199
200
201
202
# File 'app/models/preset_job.rb', line 199

def default_floor_prot_mode_sym_hash
  build_thermostat_defaults unless @defaults_built
  @default_floor_prot_mode_sym_hash
end

.default_period_temps_hashHash

Default period temperatures per thermostat SKU.

Returns:

  • (Hash)


269
270
271
272
# File 'app/models/preset_job.rb', line 269

def default_period_temps_hash
  build_thermostat_defaults unless @defaults_built
  @default_period_temps_hash
end

.default_period_times_hashHash

Default period times per thermostat SKU.

Returns:

  • (Hash)


262
263
264
265
# File 'app/models/preset_job.rb', line 262

def default_period_times_hash
  build_thermostat_defaults unless @defaults_built
  @default_period_times_hash
end

.default_temp_mode_sym_hashHash

Default temperature mode per thermostat SKU.

Returns:

  • (Hash)


192
193
194
195
# File 'app/models/preset_job.rb', line 192

def default_temp_mode_sym_hash
  build_thermostat_defaults unless @defaults_built
  @default_temp_mode_sym_hash
end

.default_weekday_period_inact_hashHash

Default weekday period inactivity flags per thermostat SKU.

Returns:

  • (Hash)


220
221
222
223
# File 'app/models/preset_job.rb', line 220

def default_weekday_period_inact_hash
  build_thermostat_defaults unless @defaults_built
  @default_weekday_period_inact_hash
end

.default_weekday_period_temps_hashHash

Default weekday period temperatures per thermostat SKU.

Returns:

  • (Hash)


213
214
215
216
# File 'app/models/preset_job.rb', line 213

def default_weekday_period_temps_hash
  build_thermostat_defaults unless @defaults_built
  @default_weekday_period_temps_hash
end

.default_weekday_period_times_hashHash

Default weekday period times per thermostat SKU.

Returns:

  • (Hash)


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

def default_weekday_period_times_hash
  build_thermostat_defaults unless @defaults_built
  @default_weekday_period_times_hash
end

.default_weekend_period_inact_hashHash

Default weekend period inactivity flags per thermostat SKU.

Returns:

  • (Hash)


255
256
257
258
# File 'app/models/preset_job.rb', line 255

def default_weekend_period_inact_hash
  build_thermostat_defaults unless @defaults_built
  @default_weekend_period_inact_hash
end

.default_weekend_period_temps_hashHash

Default weekend period temperatures per thermostat SKU.

Returns:

  • (Hash)


248
249
250
251
# File 'app/models/preset_job.rb', line 248

def default_weekend_period_temps_hash
  build_thermostat_defaults unless @defaults_built
  @default_weekend_period_temps_hash
end

.default_weekend_period_times_hashHash

Default weekend period times per thermostat SKU.

Returns:

  • (Hash)


241
242
243
244
# File 'app/models/preset_job.rb', line 241

def default_weekend_period_times_hash
  build_thermostat_defaults unless @defaults_built
  @default_weekend_period_times_hash
end

.display_format_celsius_options_for_selectArray<Array(String, Boolean)>

Display format choices as [label, celsius_flag] pairs for select boxes.

Returns:

  • (Array<Array(String, Boolean)>)


482
483
484
# File 'app/models/preset_job.rb', line 482

def self.display_format_celsius_options_for_select
  [[DISPLAY_FORMAT[1].to_s, false], [DISPLAY_FORMAT[0].to_s, true]]
end

.display_language_options_for_selectArray<Array(String, String)>

Display languages as [label, locale] pairs for select boxes.

Returns:

  • (Array<Array(String, String)>)


470
471
472
# File 'app/models/preset_job.rb', line 470

def self.display_language_options_for_select
  OJ_LANGUAGES_HASH.map { |locale, label| [label, locale.to_s] }
end

.fahrenheit_to_celsius(f) ⇒ Float

Converts Fahrenheit to Celsius, rounded to the nearest 0.5.

Parameters:

  • f (Numeric)

    Fahrenheit temperature

Returns:

  • (Float)


509
510
511
# File 'app/models/preset_job.rb', line 509

def self.fahrenheit_to_celsius(f)
  PresetJob.round_point5((f.to_f - 32.0) / 1.8).to_f
end

.floor_protection_mode_options_for_selectArray<Array(String, String)>

Floor protection modes as [label, mode] pairs for select boxes.

Returns:

  • (Array<Array(String, String)>)


476
477
478
# File 'app/models/preset_job.rb', line 476

def self.floor_protection_mode_options_for_select
  FLOOR_PROTECTION_MODES_HASH.map { |mode, label| [label, mode.to_s] }
end

.legacy_temperature_control_mode_options_for_selectArray<Array(String, String)>

Legacy (SmartStat) temperature control modes as select options.

Returns:

  • (Array<Array(String, String)>)


488
489
490
491
# File 'app/models/preset_job.rb', line 488

def self.legacy_temperature_control_mode_options_for_select
  [["A: #{LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[:A]} (#{LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[:A]})", 'A'], ["F: #{LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[:F]} (#{LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[:F]})", 'F'],
   ["AF: #{LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[:AF]} (#{LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[:AF]})", 'AF']]
end

.round_point5(n) ⇒ Float

Rounds to the nearest 0.5.

Parameters:

  • n (Numeric)

    value to round

Returns:

  • (Float)


516
517
518
# File 'app/models/preset_job.rb', line 516

def self.round_point5(n)
  (n * 2).round / 2.0
end

.states_for_selectArray<Array(String, String)>

States as [human name, value] pairs for select boxes.

Returns:

  • (Array<Array(String, String)>)


366
367
368
# File 'app/models/preset_job.rb', line 366

def self.states_for_select
  state_machines[:state].states.map { |s| [s.human_name, s.value] }
end

.supported_smartstat_skusArray<String>

SKUs of supported SmartStat thermostats (memoized).

Returns:

  • (Array<String>)


174
175
176
# File 'app/models/preset_job.rb', line 174

def supported_smartstat_skus
  @supported_smartstat_skus ||= Item.smartstats.pluck(:sku).uniq.sort
end

.supported_thermostat_skusArray<String>

SKUs of all supported programmable thermostats (memoized).

Returns:

  • (Array<String>)


180
181
182
# File 'app/models/preset_job.rb', line 180

def supported_thermostat_skus
  @supported_thermostat_skus ||= (supported_smartstat_skus + Item.oj_programmable_tstats.active.available_to_public.pluck(:sku)).uniq.sort
end

.temperature_control_mode_options_for_selectArray<Array(String, String)>

Temperature control modes as select options.

Returns:

  • (Array<Array(String, String)>)


495
496
497
# File 'app/models/preset_job.rb', line 495

def self.temperature_control_mode_options_for_select
  [[TEMPERATURE_CONTROL_MODE_HUMAN[:A].to_s, 'A'], [TEMPERATURE_CONTROL_MODE_HUMAN[:F].to_s, 'F'], [TEMPERATURE_CONTROL_MODE_HUMAN[:AF].to_s, 'AF']]
end

.temperature_mode_warnings_hashHash

Warning messages per temperature mode.

Returns:

  • (Hash)


227
228
229
230
# File 'app/models/preset_job.rb', line 227

def temperature_mode_warnings_hash
  build_thermostat_defaults unless @defaults_built
  @temperature_mode_warnings_hash
end

.temperature_options_for_select(mode = :F) ⇒ Array<Array(String, Integer)>

Temperatures in the valid range as [label, value] select options.

Parameters:

  • mode (Symbol) (defaults to: :F)

    temperature unit mode (:F or :C)

Returns:

  • (Array<Array(String, Integer)>)


523
524
525
# File 'app/models/preset_job.rb', line 523

def self.temperature_options_for_select(mode = :F)
  (TEMPERATURE_RANGE[mode][0]..TEMPERATURE_RANGE[mode][1]).map { |t| ["#{t} F / #{PresetJob.fahrenheit_to_celsius(t)} C", t] }
end

.tstat_skusArray<String>

SKUs of all thermostats, active or not (memoized).

Returns:

  • (Array<String>)


186
187
188
# File 'app/models/preset_job.rb', line 186

def tstat_skus
  @tstat_skus ||= Item.smartstats.pluck(:sku) + Item.oj_programmable_tstats.pluck(:sku)
end

.weekday_temp_by_mode_defaults_hashHash

Default weekday temperatures keyed by mode per thermostat SKU.

Returns:

  • (Hash)


234
235
236
237
# File 'app/models/preset_job.rb', line 234

def weekday_temp_by_mode_defaults_hash
  build_thermostat_defaults unless @defaults_built
  @weekday_temp_by_mode_defaults_hash
end

Instance Method Details

#contactContact

Contact the preset job belongs to.

Returns:

See Also:



98
# File 'app/models/preset_job.rb', line 98

belongs_to :contact, inverse_of: :preset_jobs, optional: true

#customerCustomer

Customer the preset job belongs to.

Returns:

See Also:



96
# File 'app/models/preset_job.rb', line 96

belongs_to :customer, inverse_of: :preset_jobs, optional: true

#deliveryDelivery

Delivery the preset job belongs to.

Returns:

See Also:



102
# File 'app/models/preset_job.rb', line 102

belongs_to :delivery, inverse_of: :preset_jobs, optional: true

#display_formatString

Display format label (Celsius or Fahrenheit).

Returns:

  • (String)


437
438
439
# File 'app/models/preset_job.rb', line 437

def display_format
  display_format_celsius? ? DISPLAY_FORMAT[0] : DISPLAY_FORMAT[1]
end

#display_language_labelString

Label for the thermostat display language.

Returns:

  • (String)


411
412
413
414
415
# File 'app/models/preset_job.rb', line 411

def display_language_label
  locale = :en
  locale = display_language.to_sym if display_language
  OJ_LANGUAGES_HASH[locale]
end

#file_nameString

File name for the generated smart-preset form PDF.

Returns:

  • (String)


529
530
531
# File 'app/models/preset_job.rb', line 529

def file_name
  "smartpreset_form_#{reference_number}.pdf"
end

#floor_protection_mode_labelString

Label for the floor protection mode.

Returns:

  • (String)


419
420
421
422
423
# File 'app/models/preset_job.rb', line 419

def floor_protection_mode_label
  mode = :custom
  mode = floor_protection_mode.to_sym if floor_protection_mode
  FLOOR_PROTECTION_MODES_HASH[mode]
end

#for_smartstat?Boolean

Whether the selected thermostat is a SmartStat model.

Returns:

  • (Boolean)


541
542
543
# File 'app/models/preset_job.rb', line 541

def for_smartstat?
  self.class.supported_smartstat_skus.include?(tstat_sku)
end

#friday_periods_temperatureArray<Numeric>

Friday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


651
652
653
# File 'app/models/preset_job.rb', line 651

def friday_periods_temperature
  periods_temperature('friday')
end

#friday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Friday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



706
707
708
# File 'app/models/preset_job.rb', line 706

def friday_periods_temperature=(temp)
  set_periods_temperature('friday', temp)
end

#guess_best_floor_loadFloat

Best-guess floor load in kilowatts from the room configuration or order.

Returns:

  • (Float)


564
565
566
567
568
569
# File 'app/models/preset_job.rb', line 564

def guess_best_floor_load
  rc = line_item.room_configuration
  return rc.calculate_total_kilowatts if rc

  order.line_items.heating_elements.to_a.sum { |he| he.quantity * he.item.watts.to_f } / 1000.0
end

#guess_best_tstat_skuString?

Best-guess thermostat SKU based on the container's thermostat line items.

Returns:

  • (String, nil)


547
548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'app/models/preset_job.rb', line 547

def guess_best_tstat_sku
  # build list of all supported tstat skus in the order, exploding out array when some line items have more than a single quantity

  tstat_skus = []
  container = line_item.room_configuration || order
  tstat_lis = container.line_items.goods.select { |li| self.class.supported_thermostat_skus.include?(li.item.sku) }
  tstat_lis.each do |tstat_li|
    tstat_li.quantity.times do
      tstat_skus << tstat_li.sku
    end
  end
  # use index to choose tstat sku
  tstat_skus[index - 1]
end

#indexInteger

1-based position of this preset among its container's presets.

Returns:

  • (Integer)


378
379
380
381
# File 'app/models/preset_job.rb', line 378

def index
  container = line_item.room_configuration || order
  ((container.line_items.smartpresets.map(&:id).sort.index(line_item.id) || 0) + 1)
end

#labelString

Human label combining room/plan or project/order context with the
thermostat model and preset index.

Returns:

  • (String)


386
387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'app/models/preset_job.rb', line 386

def label
  rc = line_item.room_configuration
  str = if rc
          "#{rc.name}, Plan # #{rc.reference_number}"
        elsif (opp = order.opportunity)
          "Project: #{opp.name}"
        else
          "Order # #{order.reference_number}"
        end
  number_str = ''
  number_str = " # #{index}" if index > 1
  str += ", #{thermostat_model_name}#{number_str}"
  str
end

#line_itemLineItem

Line item the preset job is for.

Returns:

See Also:



104
# File 'app/models/preset_job.rb', line 104

belongs_to :line_item, optional: true

#monday_periods_temperatureArray<Numeric>

Monday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


627
628
629
# File 'app/models/preset_job.rb', line 627

def monday_periods_temperature
  periods_temperature('monday')
end

#monday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Monday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



678
679
680
# File 'app/models/preset_job.rb', line 678

def monday_periods_temperature=(temp)
  set_periods_temperature('monday', temp)
end

#nameString

Display name (reference number or placeholder).

Returns:

  • (String)


372
373
374
# File 'app/models/preset_job.rb', line 372

def name
  reference_number || 'Not set yet'
end

#ok_to_deletevoid

This method returns an undefined value.

No-op: preset jobs are always safe to delete.



433
# File 'app/models/preset_job.rb', line 433

def ok_to_delete; end

#orderOrder

Order the preset job belongs to.

Returns:

See Also:



100
# File 'app/models/preset_job.rb', line 100

belongs_to :order, inverse_of: :preset_jobs, optional: true

#periods_temperature(day_label) ⇒ Array<Numeric>

Period temperatures for a weekday, routed by control mode.

Parameters:

  • day_label (String)

    weekday name

Returns:

  • (Array<Numeric>)


670
671
672
673
# File 'app/models/preset_job.rb', line 670

def periods_temperature(day_label)
  temp_label = TEMPERATURE_LABEL[temperature_control_mode.to_sym]
  send("#{day_label}_periods_#{temp_label}_temperature")
end

#public_pathString

Public URL path for this preset job.

Returns:

  • (String)


535
536
537
# File 'app/models/preset_job.rb', line 535

def public_path
  UrlHelper.instance.preset_job_path(self)
end

#saturday_periods_temperatureArray<Numeric>

Saturday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


657
658
659
# File 'app/models/preset_job.rb', line 657

def saturday_periods_temperature
  periods_temperature('saturday')
end

#saturday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Saturday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



713
714
715
# File 'app/models/preset_job.rb', line 713

def saturday_periods_temperature=(temp)
  set_periods_temperature('saturday', temp)
end

#set_after_create_defaultsvoid (protected)

This method returns an undefined value.

Populates defaults after create: address, contact points, serial number,
thermostat SKU and programming defaults, and floor load.



738
739
740
741
742
743
744
745
746
747
# File 'app/models/preset_job.rb', line 738

def set_after_create_defaults
  self.address = order.shipping_address
  set_best_guess_email_contact_point
  set_best_guess_home_phone_contact_point
  set_serial_number
  self.tstat_sku = guess_best_tstat_sku
  set_thermostat_default_periods_and_temperatures
  self.floor_load = guess_best_floor_load
  save
end

#set_defaultsvoid (protected)

This method returns an undefined value.

Defaults the contact from the order when unset.



751
752
753
# File 'app/models/preset_job.rb', line 751

def set_defaults
  self.contact_id ||= order.contact_id
end

#set_periods_temperature(day_label, temp) ⇒ void

This method returns an undefined value.

Sets period temperatures for a weekday, routed by control mode.

Parameters:

  • day_label (String)

    weekday name

  • temp (Array<Numeric>)

    period temperatures



728
729
730
731
# File 'app/models/preset_job.rb', line 728

def set_periods_temperature(day_label, temp)
  temp_label = TEMPERATURE_LABEL[temperature_control_mode.to_sym]
  send("#{day_label}_periods_#{temp_label}_temperature=(#{temp})")
end

#set_thermostat_default_periods_and_temperaturesvoid

This method returns an undefined value.

Populates all period times/temperatures/inactivity flags with the
defaults for the selected thermostat SKU.



588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
# File 'app/models/preset_job.rb', line 588

def set_thermostat_default_periods_and_temperatures
  self.temperature_control_mode = self.class.default_temp_mode_sym_hash[tstat_sku].to_s
  self.floor_protection_mode = self.class.default_floor_prot_mode_sym_hash[tstat_sku].to_s
  self.monday_periods = self.class.default_weekday_period_times_hash[tstat_sku]
  self.tuesday_periods = self.class.default_weekday_period_times_hash[tstat_sku]
  self.wednesday_periods = self.class.default_weekday_period_times_hash[tstat_sku]
  self.thursday_periods = self.class.default_weekday_period_times_hash[tstat_sku]
  self.friday_periods = self.class.default_weekday_period_times_hash[tstat_sku]
  self.saturday_periods = self.class.default_weekend_period_times_hash[tstat_sku]
  self.sunday_periods = self.class.default_weekend_period_times_hash[tstat_sku]
  weekday_floor_temps = self.class.weekday_temp_by_mode_defaults_hash[tstat_sku][:F]
  WEEKEND_TEMP_BY_MODE_DEFAULTS_HASH[tstat_sku][:F]
  self.monday_periods_floor_temperature = weekday_floor_temps
  self.tuesday_periods_floor_temperature = weekday_floor_temps
  self.wednesday_periods_floor_temperature = weekday_floor_temps
  self.thursday_periods_floor_temperature = weekday_floor_temps
  self.friday_periods_floor_temperature = weekday_floor_temps
  self.saturday_periods_floor_temperature = weekday_floor_temps
  self.sunday_periods_floor_temperature = weekday_floor_temps
  weekday_room_temps = self.class.weekday_temp_by_mode_defaults_hash[tstat_sku][:AF]
  weekend_room_temps = WEEKEND_TEMP_BY_MODE_DEFAULTS_HASH[tstat_sku][:AF]
  self.monday_periods_room_temperature = weekday_room_temps
  self.tuesday_periods_room_temperature = weekday_room_temps
  self.wednesday_periods_room_temperature = weekday_room_temps
  self.thursday_periods_room_temperature = weekday_room_temps
  self.friday_periods_room_temperature = weekday_room_temps
  self.saturday_periods_room_temperature = weekend_room_temps
  self.sunday_periods_room_temperature = weekend_room_temps
  self.monday_periods_inactive = self.class.default_weekday_period_inact_hash[tstat_sku]
  self.tuesday_periods_inactive = self.class.default_weekday_period_inact_hash[tstat_sku]
  self.wednesday_periods_inactive = self.class.default_weekday_period_inact_hash[tstat_sku]
  self.thursday_periods_inactive = self.class.default_weekday_period_inact_hash[tstat_sku]
  self.friday_periods_inactive = self.class.default_weekday_period_inact_hash[tstat_sku]
  self.saturday_periods_inactive = self.class.default_weekend_period_inact_hash[tstat_sku]
  self.sunday_periods_inactive = self.class.default_weekend_period_inact_hash[tstat_sku]
end

#sunday_periods_temperatureArray<Numeric>

Sunday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


663
664
665
# File 'app/models/preset_job.rb', line 663

def sunday_periods_temperature
  periods_temperature('sunday')
end

#sunday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Sunday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



720
721
722
# File 'app/models/preset_job.rb', line 720

def sunday_periods_temperature=(temp)
  set_periods_temperature('sunday', temp)
end

#supports_programming?(sym) ⇒ Boolean?

Whether the selected thermostat supports programming the given field.

Parameters:

  • sym (Symbol)

    field name (e.g. :display_language, :floor_load)

Returns:

  • (Boolean, nil)


574
575
576
577
578
579
580
581
582
583
# File 'app/models/preset_job.rb', line 574

def supports_programming?(sym)
  case sym
  when :display_language, :floor_load
    false if %w[UDG4-4999 UDG4-4999-WY UWG4-4999].include?(tstat_sku)
  when :floor_protection_mode
    false unless %w[UDG4-4999 UDG4-4999-WY UWG4-4999].include?(tstat_sku) && (temperature_control_mode != 'A')
  else
    true
  end
end

#temperature_control_mode_humanString

Human-readable temperature control mode.

Returns:

  • (String)


443
444
445
# File 'app/models/preset_job.rb', line 443

def temperature_control_mode_human
  for_smartstat? ? LEGACY_TEMPERATURE_CONTROL_MODE_HUMAN[temperature_control_mode.to_sym] : TEMPERATURE_CONTROL_MODE_HUMAN[temperature_control_mode.to_sym]
end

#temperature_human(temp) ⇒ String

Human label for the temperature held in the named attribute.

Parameters:

  • temp (Symbol)

    attribute name holding a Fahrenheit temperature

Returns:

  • (String)


450
451
452
453
# File 'app/models/preset_job.rb', line 450

def temperature_human(temp)
  t = send(temp)
  temperature_label(t)
end

#temperature_label(t) ⇒ String

Fahrenheit temperature with its Celsius conversion.

Parameters:

  • t (Numeric)

    temperature in Fahrenheit

Returns:

  • (String)


458
459
460
# File 'app/models/preset_job.rb', line 458

def temperature_label(t)
  "#{t} F / #{PresetJob.fahrenheit_to_celsius(t)} C"
end

#temperature_mode_warningString?

Warning message for the current temperature control mode.

Returns:

  • (String, nil)


427
428
429
# File 'app/models/preset_job.rb', line 427

def temperature_mode_warning
  self.class.temperature_mode_warnings_hash[tstat_sku][temperature_control_mode.to_sym]
end

#thermostat_model_nameString

Public name of the selected thermostat model.

Returns:

  • (String)


403
404
405
406
407
# File 'app/models/preset_job.rb', line 403

def thermostat_model_name
  res = 'Thermostat'
  res = Item.find_by(sku: tstat_sku).public_name if tstat_sku
  res
end

#thermostat_model_options_for_selectArray<Array(String, String)>

Single-option select list for the current thermostat model.

Returns:

  • (Array<Array(String, String)>)


464
465
466
# File 'app/models/preset_job.rb', line 464

def thermostat_model_options_for_select
  [[Item.find_by(sku: tstat_sku).public_name, tstat_sku]]
end

#thursday_periods_temperatureArray<Numeric>

Thursday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


645
646
647
# File 'app/models/preset_job.rb', line 645

def thursday_periods_temperature
  periods_temperature('thursday')
end

#thursday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Thursday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



699
700
701
# File 'app/models/preset_job.rb', line 699

def thursday_periods_temperature=(temp)
  set_periods_temperature('thursday', temp)
end

#tuesday_periods_temperatureArray<Numeric>

Tuesday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


633
634
635
# File 'app/models/preset_job.rb', line 633

def tuesday_periods_temperature
  periods_temperature('tuesday')
end

#tuesday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Tuesday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



685
686
687
# File 'app/models/preset_job.rb', line 685

def tuesday_periods_temperature=(temp)
  set_periods_temperature('tuesday', temp)
end

#warming_periodsvoid (protected)

This method returns an undefined value.

Validates warming period schedules: no 1- or 3-skip days, SmartStat
early-start compatibility, and ascending period times.



758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
# File 'app/models/preset_job.rb', line 758

def warming_periods
  skips_issue_days = []
  early_start_issue_days = []
  non_ascend_issue_days = []
  PresetJob::DAYS_OF_THE_WEEK.each do |day|
    skips_in_day = []
    periods_in_day = []
    monday_periods.length.times do |i|
      if (pt = send("#{day}_periods")[i]).present?
        skips_in_day << false
        periods_in_day << Time.zone.parse(pt)
      else
        skips_in_day << true
      end
    end
    num_skips_in_day = skips_in_day.sum { |p| p == true ? 1 : 0 }
    skips_issue_days << day if [1, 3].include?(num_skips_in_day)
    # From SmartStat guide: NOTE: If you intend to use only 2 periods, set periods '1 and 4' or periods '2 and 3'. Early Start will not work if you set periods '1 and 2' or periods '3 and 4'
    if for_smartstat? && adaptive_start && (num_skips_in_day == 2)
      early_start_issue_days << day unless [[false, true, true, false], [true, false, false, true]].include?(skips_in_day)
    end
    next if periods_in_day.empty?

    all_periods_ascend = true
    (periods_in_day.length - 1).times.each do |j|
      all_periods_ascend = false if periods_in_day[j + 1] <= periods_in_day[j]
    end
    non_ascend_issue_days << day unless all_periods_ascend
  end
  error_fields = []
  error_msgs = []
  skips_issue_days.each do |day|
    error_fields << :"#{day}_periods"
    error_msgs << "you can't skip only one or three periods on any given day"
  end
  early_start_issue_days.each do |day|
    error_fields << :"#{day}_periods"
    error_msgs << 'if you intend to use only 2 periods, set periods 1 and 4 or periods 2 and 3, early start mode will not work if you set periods 1 and 2 or periods 3 and 4'
  end
  non_ascend_issue_days.each do |day|
    error_fields << :"#{day}_periods"
    error_msgs << 'start time must be earlier than the end time, please correct and adjust your warming time selections'
  end
  error_msgs.each_with_index do |error_msg, i|
    errors.add(error_fields[i], error_msg)
  end
end

#wednesday_periods_temperatureArray<Numeric>

Wednesday period temperatures for the active control mode.

Returns:

  • (Array<Numeric>)


639
640
641
# File 'app/models/preset_job.rb', line 639

def wednesday_periods_temperature
  periods_temperature('wednesday')
end

#wednesday_periods_temperature=(temp) ⇒ void

This method returns an undefined value.

Sets Wednesday period temperatures for the active control mode.

Parameters:

  • temp (Array<Numeric>)

    period temperatures



692
693
694
# File 'app/models/preset_job.rb', line 692

def wednesday_periods_temperature=(temp)
  set_periods_temperature('wednesday', temp)
end