Module: ModelExt::Restaurants::InstanceMethods

Included in:
Restaurant
Defined in:
lib/model_ext/restaurants/instance_methods.rb

Instance Method Summary collapse

Instance Method Details

#active_add_ons_with_auto_extendActiveRecord::Relation

Returns all active add-ons that have auto-extend enabled for the restaurant.

Returns:

  • (ActiveRecord::Relation)

    A collection of active add-ons with auto-extend enabled.



287
288
289
# File 'lib/model_ext/restaurants/instance_methods.rb', line 287

def active_add_ons_with_auto_extend
  restaurant_add_ons.where(active: true, auto_extend: true)
end

#active_and_not_expired?Boolean

Returns:

  • (Boolean)


138
139
140
141
142
143
144
145
146
# File 'lib/model_ext/restaurants/instance_methods.rb', line 138

def active_and_not_expired?
  # Not expired means the expiry date of the restaurant is greater than or equal to today's date
  # or if has restaurant packages, it is considered as not expired
  return false if expiry_date.blank?

  not_expired = expiry_date >= today_in_tz || restaurant_packages.present?

  active && not_expired
end

#active_packages_with_auto_extendActiveRecord::Relation

Returns all active restaurant packages that have auto-extend enabled. The packages are filtered to include only those that are either active or active for third-party

Returns:

  • (ActiveRecord::Relation)

    A collection of active restaurant packages with auto-extend enabled.



295
296
297
298
299
300
# File 'lib/model_ext/restaurants/instance_methods.rb', line 295

def active_packages_with_auto_extend
  restaurant_packages.where(auto_extend: true).where(
    "#{HhPackage::RestaurantPackage.table_name}.active = ? OR #{HhPackage::RestaurantPackage.table_name}.active_for_third_party_only = ?",
    true, true
  )
end

#active_staff_emailsObject

Returns emails of active staff members



334
335
336
# File 'lib/model_ext/restaurants/instance_methods.rb', line 334

def active_staff_emails
  staffs.where(status: 'active').pluck(:email).compact
end

#availability_statusString

Determine the availability status of the restaurant.

The availability status can be one of the following:

  • Restaurant::AVAILABILITY_PREORDER: if the restaurant is active and the start date is in the future.

  • Restaurant::AVAILABILITY_IN_STOCK: if the restaurant is active and the current date is within the offer period.

  • Restaurant::AVAILABILITY_OUT_OF_STOCK: if the restaurant is inactive or the offer period has expired.

Returns:

  • (String)

    One of the Restaurant::AVAILABILITY_* constants representing the availability status of the restaurant.



309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/model_ext/restaurants/instance_methods.rb', line 309

def availability_status
  if active?
    if start_date && start_date > today_in_tz
      Restaurant::AVAILABILITY_PREORDER
    elsif !date_offer_expired?(today_in_tz)
      Restaurant::AVAILABILITY_IN_STOCK
    else
      Restaurant::AVAILABILITY_OUT_OF_STOCK
    end
  else
    Restaurant::AVAILABILITY_OUT_OF_STOCK
  end
end

#bookable_and_not_expired?Boolean

Returns:

  • (Boolean)


148
149
150
151
152
# File 'lib/model_ext/restaurants/instance_methods.rb', line 148

def bookable_and_not_expired?
  # Check if restaurant allows booking (with packages) OR allows booking without packages
  # AND restaurant is not expired (but can be inactive)
  (allow_booking? || allow_booking_without_package?) && !date_offer_expired?(today_in_tz)
end

#default_max_dine_in_booking_cutoff_timeObject



233
234
235
# File 'lib/model_ext/restaurants/instance_methods.rb', line 233

def default_max_dine_in_booking_cutoff_time
  AdminSetting.default_max_dine_in_booking_cutoff_time.to_i
end

#default_min_booking_time(reservation = nil, package_type_code = nil, service_type = nil) ⇒ Object



218
219
220
221
222
223
224
225
226
227
# File 'lib/model_ext/restaurants/instance_methods.rb', line 218

def default_min_booking_time(reservation = nil, package_type_code = nil, service_type = nil)
  reservation_dine_in = reservation.present? && reservation.dine_in_type?
  package_code_dine_in = package_type_code != 'hah'
  service_type_dine_in = service_type == 'dine_in'

  return default_min_booking_time_admin_level_for_dine_in.to_i if reservation_dine_in || package_code_dine_in || service_type_dine_in
  return default_min_booking_time_admin_level_for_delivery if !reservation_dine_in || !package_code_dine_in || !service_type_dine_in

  default_min_booking_time_admin_level_for_dine_in
end

#default_min_booking_time_admin_level_for_deliveryObject



237
238
239
# File 'lib/model_ext/restaurants/instance_methods.rb', line 237

def default_min_booking_time_admin_level_for_delivery
  AdminSetting.default_delivery_min_booking_time_in_advance.to_i
end

#default_min_booking_time_admin_level_for_dine_inObject



229
230
231
# File 'lib/model_ext/restaurants/instance_methods.rb', line 229

def default_min_booking_time_admin_level_for_dine_in
  AdminSetting.default_dine_in_min_booking_time_in_advance.to_i
end

#default_provider_for(type) ⇒ Object



280
281
282
# File 'lib/model_ext/restaurants/instance_methods.rb', line 280

def default_provider_for(type)
  provider_for(type, :th)
end

#determine_max_availability_dateDate

Determines the maximum availability date on search page (hh-search) for a restaurant.

This method calculates the maximum date a restaurant can be search-able on search page based on a predefined number of days in advance and the restaurant's expiry date. The maximum availability date cannot exceed the restaurant's expiry date.

Returns:

  • (Date)

    the maximum availability date, which is either the calculated date based on days in advance or the restaurant's expiry date, whichever is earlier.



182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/model_ext/restaurants/instance_methods.rb', line 182

def determine_max_availability_date
  max_end_date = EventDrivenClient::Constants::DAYS_IN_ADVANCE_FOR_AVAILABILITY.
    days.from_now.in_time_zone(time_zone).to_date
  expiry_date = self.expiry_date.to_date

  # Max end date cannot be greater than restaurant expiry date
  if max_end_date > expiry_date
    return expiry_date
  end

  max_end_date
end

#determine_min_booking_time(reservation: nil, slug: nil, restaurant_package: nil, service_type: nil) ⇒ Object

There are several minimum booking times in advance, namely:

  1. admin setting dine in default min booking time in advance

  2. admin setting delivery default min booking time in advance

  3. dine in min booking time in advance at the restaurant level

  4. delivery min booking time in advance at the restaurant level

  5. booking time in advance at the package level

The highest priority is at the package level, then at the restaurant level, and finally at the AdminSetting level if the package and restaurant levels are not set, then the default value from the AdminSetting will be used minimum booking time in minutes as integer

The minimum booking time could be negative to allow booking in the past

Returns:

  • Integer



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/model_ext/restaurants/instance_methods.rb', line 32

def determine_min_booking_time(reservation: nil, slug: nil, restaurant_package: nil, service_type: nil)
  package_type_code = nil

  min_booking_time_restaurant_level_for_dine_in = dine_in_min_booking_time_in_advance.to_i
  min_booking_time_restaurant_level_for_delivery = delivery_min_booking_time_in_advance.to_i

  # min booking time restaurant level cannot be less than the default max dine in booking cutoff time
  if min_booking_time_restaurant_level_for_dine_in < default_max_dine_in_booking_cutoff_time
    min_booking_time_restaurant_level_for_dine_in = default_max_dine_in_booking_cutoff_time
  end

  # sometimes client app need to send inactive restaurant package id to render a menu preview
  # that's why on this step we use find_by, not find_by!
  restaurant_package = restaurant_packages.find_by(slug: slug) if slug && restaurant_package.nil?

  if restaurant_package
    min_booking_time_package_level = restaurant_package.package&.package_attr&.minimum_booking_time_in_advance.to_i

    package_code = restaurant_package.package_type.split('::').last
    package_type_code = HhPackage::PACKAGE_LIST_TO_SHORT[package_code.to_sym]

    if min_booking_time_package_level == 0 && min_booking_time_restaurant_level_for_dine_in.negative? &&
        package_code != 'hah' && %w[delivery pick_up].exclude?(service_type)

      Rails.logger.debug do
        "Restaurant: #{id} - Package: #{restaurant_package.slug} - Package level min booking time is 0, " \
        'restaurant level min booking time for dine in is negative, and service type is not delivery or pick up. ' \
        'Setting min booking time to default dine in min booking time in advance.'
      end

      return min_booking_time_restaurant_level_for_dine_in
    end

    if min_booking_time_package_level.positive?

      Rails.logger.debug do
        "Restaurant: #{id} - Package: #{restaurant_package.slug} - Package level min booking time is positive. " \
        'Setting min booking time to package level min booking time.'
      end

      return min_booking_time_package_level
    end
  end

  # inactivate restaurant could have packages too
  # so we ignore restaurant active status, just focus on `any_offers?`
  # `any_offers?` will return true if there are any active packages
  # or if the restaurant accept booking without package then check the override conditions
  # for dine in and delivery min booking time
  if any_offers? || allow_booking_without_package?
    if override_dine_in_min_booking?(reservation, package_type_code, service_type)

      Rails.logger.debug do
        "Restaurant: #{id} - Active restaurant with offers. Override dine in min booking time." \
          'Setting min booking time to default dine in min booking time in advance.'
      end

      return min_booking_time_restaurant_level_for_dine_in
    end
    if override_delivery_min_booking?(reservation, package_type_code, service_type)

      Rails.logger.debug do
        "Restaurant: #{id} - Active restaurant with offers. Override delivery min booking time." \
          'Setting min booking time to default delivery min booking time in advance.'
      end

      return min_booking_time_restaurant_level_for_delivery
    end

    Rails.logger.debug do
      "Restaurant: #{id} - Active restaurant with offers. Setting min booking time to default dine in min booking time in advance."
    end
    return default_min_booking_time(reservation, package_type_code, service_type)
  end

  Rails.logger.debug do
    "Restaurant: #{id} - Setting min booking time to default dine in min booking time in advance."
  end
  default_min_booking_time_admin_level_for_dine_in
end

#eligible_for_rewards?Boolean

Returns:

  • (Boolean)


170
171
172
# File 'lib/model_ext/restaurants/instance_methods.rb', line 170

def eligible_for_rewards?
  ApiV5::Constants::COUNTRY_CODES.include?(country.alpha3)
end

#inv_cache_keyObject



14
15
16
17
# File 'lib/model_ext/restaurants/instance_methods.rb', line 14

def inv_cache_key
  inv_checker = InvCheckerFactory.new(id, time_zone).create_inv_checker_service
  @inv_cache_key ||= inv_checker.cache_key
end

#inventory_bistrochat?Boolean

Returns:

  • (Boolean)


128
129
130
131
# File 'lib/model_ext/restaurants/instance_methods.rb', line 128

def inventory_bistrochat?
  inventory_source&.inv_source.to_s == ApiVendorV1::Constants::BISTROCHAT_INV_SOURCE_NAME &&
    bistrochat_restaurant.present?
end

#inventory_my_menu?Boolean

Returns:

  • (Boolean)


133
134
135
136
# File 'lib/model_ext/restaurants/instance_methods.rb', line 133

def inventory_my_menu?
  inventory_source&.inv_source.to_s == ApiVendorV1::Constants::MYMENU_INV_SOURCE_NAME &&
    my_menu_restaurant.present?
end

#inventory_seven_rooms?Boolean

Returns:

  • (Boolean)


118
119
120
121
# File 'lib/model_ext/restaurants/instance_methods.rb', line 118

def inventory_seven_rooms?
  inventory_source&.inv_source.to_s == ApiVendorV1::Constants::SEVEN_ROOMS_INV_SOURCE_NAME &&
    seven_rooms_restaurant.present?
end

#inventory_tablecheck?Boolean

Returns:

  • (Boolean)


113
114
115
116
# File 'lib/model_ext/restaurants/instance_methods.rb', line 113

def inventory_tablecheck?
  inventory_source&.inv_source.to_s == ApiVendorV1::Constants::TABLECHECK_INV_SOURCE_NAME &&
    tablecheck_restaurant.present?
end

#inventory_weeloy?Boolean

Returns:

  • (Boolean)


123
124
125
126
# File 'lib/model_ext/restaurants/instance_methods.rb', line 123

def inventory_weeloy?
  inventory_source&.inv_source.to_s == ApiVendorV1::Constants::WEELOY_INV_SOURCE_NAME &&
    weeloy_restaurant.present?
end

#override_delivery_min_booking?(reservation = nil, package_type_code = nil, service_type = nil) ⇒ Boolean

Returns:

  • (Boolean)


208
209
210
211
212
213
214
215
216
# File 'lib/model_ext/restaurants/instance_methods.rb', line 208

def override_delivery_min_booking?(reservation = nil, package_type_code = nil, service_type = nil)
  return false if reservation.nil? && package_type_code.nil? && service_type.nil?
  return false if delivery_min_booking_time_in_advance.negative?
  return true if reservation.present? && reservation.delivery_type?
  return true if package_type_code.present? && package_type_code == 'hah'
  return true if %w[delivery pick_up].include?(service_type)

  false
end

#override_dine_in_min_booking?(reservation = nil, package_type_code = nil, service_type = nil) ⇒ Boolean

Returns:

  • (Boolean)


199
200
201
202
203
204
205
206
# File 'lib/model_ext/restaurants/instance_methods.rb', line 199

def override_dine_in_min_booking?(reservation = nil, package_type_code = nil, service_type = nil)
  return false if reservation.nil? && package_type_code.nil? && service_type.nil?
  return true if reservation.present? && reservation.dine_in_type?
  return true if package_type_code.present? && package_type_code != 'hah'
  return true if service_type == 'dine_in'

  false
end

#provider_for(type, country) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/model_ext/restaurants/instance_methods.rb', line 267

def provider_for(type, country)
  case type
  when :promptpay
    AdminSetting.send("selected_promptpay_payment_provider_for_#{country}")
  when :cc
    AdminSetting.send("selected_cc_payment_provider_for_#{country}")
  when :alipay
    AdminSetting.send("selected_alipay_payment_provider_for_#{country}")
  when :wechat
    AdminSetting.send("selected_wechat_pay_payment_provider_for_#{country}")
  end
end

#selected_alipay_payment_providerObject



162
163
164
# File 'lib/model_ext/restaurants/instance_methods.rb', line 162

def selected_alipay_payment_provider
  selected_payment_provider(:alipay)
end

#selected_cc_payment_providerObject



158
159
160
# File 'lib/model_ext/restaurants/instance_methods.rb', line 158

def selected_cc_payment_provider
  selected_payment_provider(:cc)
end

#selected_payment_provider(type) ⇒ Object



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/model_ext/restaurants/instance_methods.rb', line 241

def selected_payment_provider(type)
  # If merchant is present (gb_primepay key), then use the merchant's payment provider
  if merchant.present?
    return Externals::Omise::Source::GB_PRIMEPAY_SOURCE_ID
  end

  # this code for get provider from restaurant level
  # but currently restaurant have multiple payment type with multiple provider
  # so need to disable this code for temporary
  # return payment_provider if payment_provider.present?

  return default_provider_for(type) if country.blank?

  provider_mapping = {
    thailand: provider_for(type, :th),
    singapore: provider_for(type, :sg),
    malaysia: provider_for(type, :my),
  }

  # Fetch the appropriate provider based on the country or fall back to Thailand's provider
  provider_mapping.fetch(
    country.name.downcase.to_sym,
    default_provider_for(type),
  )
end

#selected_promptpay_payment_providerObject



154
155
156
# File 'lib/model_ext/restaurants/instance_methods.rb', line 154

def selected_promptpay_payment_provider
  selected_payment_provider(:promptpay)
end

#selected_wechat_pay_payment_providerObject



166
167
168
# File 'lib/model_ext/restaurants/instance_methods.rb', line 166

def selected_wechat_pay_payment_provider
  selected_payment_provider(:wechat)
end

#today_in_tzDate

Determine today's date for the restaurant in the restaurant's time zone If the restaurant does not have a time zone set, it defaults to 'Asia/Bangkok'

Returns:

  • (Date)

    today's date in restaurant's time zone



327
328
329
330
331
# File 'lib/model_ext/restaurants/instance_methods.rb', line 327

def today_in_tz
  return Time.now_in_tz(time_zone).to_date if time_zone.present?

  Time.now_in_tz(HungryHub::Time::DEFAULT_ZONE).to_date
end

#view_cache_keyObject

Rails cache key use updated_at restaurant.cache_key # => “restaurants/1-20171206165938000000” currently restaurant has many attributes, if admin change `commision` we don't need to invalidate cache, because our client doesn't use `commision` data so view_cache_key will be refreshed if attributes that used by client changed



9
10
11
12
# File 'lib/model_ext/restaurants/instance_methods.rb', line 9

def view_cache_key
  key = Rails.cache.fetch(view_cache_key_redis_key) { Time.zone.now }
  "Restaurant/#{id}/#{key}/#{I18n.locale}"
end

#view_cache_key_redis_keyObject



195
196
197
# File 'lib/model_ext/restaurants/instance_methods.rb', line 195

def view_cache_key_redis_key
  "Restaurant:#{id}:view_cache_key"
end