Module: SpreeCmCommissioner::VariantOptionsConcern

Extended by:
ActiveSupport::Concern
Defined in:
app/models/concerns/spree_cm_commissioner/variant_options_concern.rb

Instance Method Summary collapse

Instance Method Details

#bib_required?Boolean

Returns:

  • (Boolean)


128
129
130
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 128

def bib_required?
  bib_prefix.present?
end

#end_date(start_date: nil) ⇒ Object



114
115
116
117
118
119
120
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 114

def end_date(start_date: nil)
  start_date = self.start_date if self.start_date.present?

  return start_date + options.total_duration_in_seconds.seconds if start_date.present? && options.total_duration_in_seconds.positive?

  options.end_date
end

#end_date_time(start_date: nil, end_date: nil) ⇒ Object

Determines the end date/time with priority:

  • Date priority: variant date > event date > user input date

  • Time: always uses variant time (if configured) or calculated from duration

Examples:

1. Explicit variant end_date:
   Variant: end_date = 2024-01-20, end_time = 18:00, Event: 2024-02-25
   → Returns "2024-01-20 18:00:00" (variant date + variant time)

2. Duration-based calculation (no explicit end_date):
   Variant: start_date = 2024-01-15, start_time = 14:00, duration = 3 hours
   → Returns "2024-01-15 17:00:00" (start + duration)

3. Event date when variant has no date but has time:
   Variant: only end_time (18:00), Event: 2024-02-20
   → Returns "2024-02-20 18:00:00" (event date + variant time)

Note: No need to fallback to event end date to avoid n+1. To get end_time duration of event, include event when needed instead.



103
104
105
106
107
108
109
110
111
112
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 103

def end_date_time(start_date: nil, end_date: nil)
  start_date = self.start_date if self.start_date.present?
  end_date = self.end_date(start_date: start_date) if self.end_date(start_date: start_date).present?

  return nil if end_date.blank? && end_time.blank?
  return end_date if end_time.blank?
  return end_time if end_date.blank?

  end_date.change(hour: end_time.hour, min: end_time.min, sec: end_time.sec)
end

#end_timeObject



122
123
124
125
126
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 122

def end_time
  return start_time + options.total_duration_in_seconds.seconds if start_time.present? && options.total_duration_in_seconds.positive?

  options.end_time
end

#find_option_value_name_for(option_type_name: nil) ⇒ Object



51
52
53
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 51

def find_option_value_name_for(option_type_name: nil)
  option_values.detect { |o| o.option_type.name.downcase.strip == option_type_name.downcase.strip }.try(:name)
end

#option_value_name_for(option_type_name: nil) ⇒ Object



45
46
47
48
49
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 45

def option_value_name_for(option_type_name: nil)
  return options_in_hash[option_type_name] if options_in_hash.present? # empty is not considered present?

  find_option_value_name_for(option_type_name: option_type_name)
end

#optionsObject



37
38
39
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 37

def options
  @options ||= VariantOptions.new(self)
end

#options_in_hashObject



41
42
43
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 41

def options_in_hash
  [:cm_options]
end

#post_paid?Boolean

Returns:

  • (Boolean)


132
133
134
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 132

def post_paid?
  options.payment_option == 'post-paid'
end

#set_options_to_public_metadataObject



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 136

def 
  self. ||= {}

  # Cache option values as a hash to avoid N+1 queries when accessing options.
  # Stores {option_type_name => option_value_name} pairs that can be retrieved
  # without loading option_types and option_values associations.
  # Example: "Red, 256GB" - formatted options for quick display
  self.[:cm_options] = option_values.each_with_object({}) do |option_value, hash|
    option_type_name = option_value.option_type.name
    hash[option_type_name] = find_option_value_name_for(option_type_name: option_type_name)
  end

  # Cache formatted options text for quick retrieval via #options_text.
  # Precomputes the human-readable format (e.g., "Red, 256GB") to avoid
  # repeated formatting and association queries.
  # Example: {"color" => "red", "storage" => "256GB"} - option_type_name => option_value_name pairs
  self.[:preload_options_text] = Spree::Variants::VisibleOptionsPresenter.new(self).to_sentence
end

#set_options_to_public_metadata!Object



155
156
157
158
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 155

def set_options_to_public_metadata!
  
  save!
end

#start_date_time(start_date: nil) ⇒ Object

Determines the start date/time with priority:

  • Date priority: variant date > event date > user input date

  • Time: always uses variant time (if configured)

Examples:

1. Variant date takes priority:
   Variant: 2024-01-15, Event: 2024-02-20, User: 2024-03-10, Variant time: 14:00
   → Returns "2024-01-15 14:00:00" (variant date + variant time)

2. Event date used when variant has no date:
   Variant: only time (14:00), Event: 2024-02-20, User: 2024-03-10
   → Returns "2024-02-20 14:00:00" (event date + variant time)

3. User date used when no variant/event date:
   Variant: only time (14:00), No event, User: 2024-03-10
   → Returns "2024-03-10 14:00:00" (user date + variant time)

Note: No need to fallback to event start date to avoid n+1. To get start_time duration of event, include event when needed instead.



74
75
76
77
78
79
80
81
82
# File 'app/models/concerns/spree_cm_commissioner/variant_options_concern.rb', line 74

def start_date_time(start_date: nil)
  start_date = self.start_date if self.start_date.present?

  return nil if start_date.blank? && start_time.blank?
  return start_date if start_time.blank?
  return start_time if start_date.blank?

  start_date.change(hour: start_time.hour, min: start_time.min, sec: start_time.sec)
end