Module: HhPackage::ModelConcerns::DynamicPricingsForPackage

Extended by:
ActiveSupport::Concern
Included in:
Package::Base
Defined in:
app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.pricing_type(class_name) ⇒ Object

we were hardcoding the pricing type in the past, we should remove this method once DynamicPricing is fully implemented and stable because the pricing type is dynamic now, not based on class name anymore



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 222

def self.pricing_type(class_name)
  case class_name.to_s
  when HhPackage::Package::Ayce.to_s
    :per_person
  when HhPackage::Package::PartyPack.to_s
    :per_pack
  when HhPackage::Package::SetMenu.to_s
    :per_person
  when HhPackage::Package::BuffetExtra.to_s
    :per_person
  when HhPackage::Package::HungryAtHome.to_s
    :per_set
  when HhPackage::Package::HungrySet.to_s
    :per_set
  when HhPackage::Package::Xperience.to_s
    :per_pack
  when HhPackage::Package::Diy.to_s
    :per_item
  else
    raise NotImplementedError, 'You must implement the pricing_type method'
  end
end

Instance Method Details

#ala_carte?Boolean

return true if pricing type is ala carte

Returns:

  • (Boolean)


196
197
198
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 196

def ala_carte?
  dynamic_price_pricing_model == 'ala_carte' && menu_type.to_s.include?('hh_menu')
end

#decide_max_seatInteger, HhPackage::Pricing::MAX_SEAT

to centralize the logic to get the package max seat

Returns:



73
74
75
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 73

def decide_max_seat
  package_attr.max_seat.presence || (respond_to?(:max_seat) ? max_seat : HhPackage::Pricing::MAX_SEAT)
end

#decide_min_seatInteger, 1

to centralize the logic to get the package min seat

Returns:

  • (Integer, 1)

    the minimum seat for the package or 1



67
68
69
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 67

def decide_min_seat
  package_attr.min_seat.presence || (respond_to?(:min_seat) ? min_seat : HhPackage::Pricing::MIN_SEAT)
end

#dynamic_price_comemore_payless?Boolean Also known as: dynamic_price_comemore_payless

Returns:

  • (Boolean)


77
78
79
80
81
82
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 77

def dynamic_price_comemore_payless?
  return false unless ['HhPackage::Package::Ayce', 'HhPackage::Package::PartyPack'].include?(self.class.name)
  return false if package_attr.blank?

  !!package_attr.comemore_payless
end

#dynamic_pricings_as_json(for_rules_attribute: false, for_dynamic_pricing_rules_attribute: false, for_pricings_attribute: false, for_pricing_attribute: false, support_dynamic_pricing_feature: false, time_zone: nil) ⇒ Object

in Serializer classes, it doesn't render the pricing in the same format as an example, in the `rules` attribute, it shows xxx attribute, but for the `pricing` attribute, it shows yyy attribute this method is provided to have DRY code so we just need to call this method in the Serializer classes with the correct attribute name, as an example, use `for_rules_attribute: true` to render the pricing for `rules` attribute

Parameters:

  • for_rules_attribute (Boolean) (defaults to: false)

    render the pricing for `rules` attribute

  • for_dynamic_pricing_rules_attribute (Boolean) (defaults to: false)

    render the pricing for `dynamic_pricing_rules` attribute

  • for_pricings_attribute (Boolean) (defaults to: false)

    render the pricing for `pricings` attribute

  • for_pricing_attribute (Boolean) (defaults to: false)

    render the pricing for `pricing` attribute

  • support_dynamic_pricing_feature (Boolean) (defaults to: false)

    if the value is false, then it will transform by_day pricing to normal pricing

Raises:

  • (NotImplementedError)


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 99

def dynamic_pricings_as_json(for_rules_attribute: false,
                             for_dynamic_pricing_rules_attribute: false,
                             for_pricings_attribute: false,
                             for_pricing_attribute: false,
                             support_dynamic_pricing_feature: false,
                             time_zone: nil)
  keys = %w[]

  if for_rules_attribute
    keys = %w[price_description price price_cents min_seat max_seat per_pack
              duration kids_price_rate id]
  elsif for_dynamic_pricing_rules_attribute
    keys = %w[title price min_seat max_seat category_name days duration
              kids_price start_date end_date dynamic_pricing_type
              price_cents kids_price_cents price_currency id per_pack
              promotion_badge_text]
  elsif for_pricings_attribute
    keys = %w[min_seat max_seat price_cents price_currency price_format
              per_pack pricing_type id]
  elsif for_pricing_attribute
    # this is for Reservation form in owner dashboard
    keys = %w[description price price_int currency_symbol min_seat
              max_seat kids_price_rate per_pack id]
  end

  raise NotImplementedError, 'You must implement the dynamic_pricings_as_json method' if keys.empty?

  flipper = DynamicPricingsFlipper.new(time_zone)
  filtered_dynamic_pricings = flipper.filter_by_package(dynamic_pricings,
                                                        self,
                                                        support_dynamic_pricing_feature)

  raise 'Filtered dynamic pricings is null' if filtered_dynamic_pricings.nil?

  # to make compatible with old way of pricing_tier
  if for_pricing_attribute
    if pricing_tier(old_way: true) == :multiple
      filtered_dynamic_pricings.map do |pricing|
        pricing.pricing_as_json(keys, for_dynamic_pricing_rules_attribute: true)
      end
    else
      filtered_dynamic_pricings.first&.pricing_as_json(keys, for_dynamic_pricing_rules_attribute: true)
    end
  else
    # add more pricing attributes, such as holiday or custom day
    filtered_dynamic_pricings.map do |pricing|
      pricing.pricing_as_json(keys, for_dynamic_pricing_rules_attribute: for_dynamic_pricing_rules_attribute)
    end
  end
end

#highest_pricingHhPackage::Pricing

Select highest price

Returns:



187
188
189
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 187

def highest_pricing
  dynamic_pricings.max_by(&:marketing_price)
end

#lowest_pricingHhPackage::Pricing

Select lowest price

Returns:



181
182
183
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 181

def lowest_pricing
  dynamic_pricings.min_by(&:marketing_price)
end

#price_currencyObject



191
192
193
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 191

def price_currency
  package_attr.price_currency.presence || HhPackage::Pricing::DEFAULT_CURRENCY
end

#pricing_model_and_dynamic_pricing_type(package_count: nil) ⇒ Object

then it means user use mix and match feature

Parameters:

  • package_count (Integer) (defaults to: nil)

    if it's more than 1,



167
168
169
170
171
172
173
174
175
176
177
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 167

def pricing_model_and_dynamic_pricing_type(package_count: nil)
  # override mix n match for AYCE
  if !package_count.nil? && package_count.is_a?(Integer) &&
      use_mix_and_match?(package_count) &&
      dynamic_price_pricing_model == 'per_person' &&
      dynamic_price_dynamic_pricing_type == 'normal'
    :per_pack_and_normal_price
  else
    :"#{dynamic_price_pricing_model}_and_#{dynamic_price_dynamic_pricing_type}_price"
  end
end

#pricing_tier(old_way: false) ⇒ Object

when old_way is true, it will return the old way of pricing_tier the old way is:

  • ayce is :multiple

  • party_pack is :single

while for the new way, it will return :multiple for all types because we are using dynamic pricing, each package has array of pricings TODO remove this method once all client apps are using dynamic pricing



157
158
159
160
161
162
163
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 157

def pricing_tier(old_way: false)
  if old_way
    HhPackage::PACKAGE_SHORT_LIST_AND_PRICING_TIER[type_short.to_sym]
  else
    :multiple
  end
end

#pricing_type_humanizeObject



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 200

def pricing_type_humanize
  case pricing_model_and_dynamic_pricing_type
  when :per_person_and_normal_price, :per_person_and_by_party_size_price, :per_person_and_by_day_price
    I18n.t('views.package.net_price_per_person')
  when :per_pack_and_normal_price, :per_pack_and_by_day_price
    I18n.t('views.package.net_price_per_pack')
  when :per_set_and_normal_price
    I18n.t('views.package.net_price_per_set')
  when :per_item_and_normal_price
    I18n.t('views.package.net_price_per_item')
  when :ala_carte_and_normal_price
    raise NotImplementedError,
          'You must implement the pricing_type_humanize method for ala_carte_and_normal_price'
  else
    raise NotImplementedError,
          "You must implement the pricing_type_humanize method for #{pricing_model_and_dynamic_pricing_type}"
  end
end

#validate_comemore_payless_promotionObject

Custom validation to ensure 'Come More Pay Less' promotion is valid only when pricing type is normal



53
54
55
56
57
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 53

def validate_comemore_payless_promotion
  if dynamic_price_comemore_payless? && dynamic_price_dynamic_pricing_type != 'normal'
    errors.add(:comemore_payless, 'Come More Pay Less promotion is only allowed for normal pricing.')
  end
end

#validate_menu_v3_diyObject



59
60
61
62
63
# File 'app/models/concerns/hh_package/model_concerns/dynamic_pricings_for_package.rb', line 59

def validate_menu_v3_diy
  return if menu_group_id.present?

  errors.add(:menu_group_id, 'must be present when menu_type is menu_v3 for DIY package.')
end