Class: Channel
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Channel
- Includes:
- IdentityCache
- Defined in:
- app/models/channel.rb
Constant Summary collapse
- DEFAULT =
'default'- AUTO_ACK =
'auto_ack'- CHARGE_CC_DIRECTLY =
'charge_cc_directly'- HOLD_CC =
'credit_card'- EXTERNAL_BOOKING =
'external_booking'- MANUAL =
'manual'- ACCEPT_BIG_GROUP =
'big_group'- SHOW_IN_OWNER_DASHBOARD =
'show_in_owner_dashboard'- PHONE_TYPE =
%w[restaurant custom default].freeze
- VENDOR_CHANNEL_URI_LIST =
ApiVendorV1::Constants.constants.select do |constant| constant.to_s.include?('_CHANNEL_URI') end.map do |constant| ApiVendorV1::Constants.const_get(constant) end.freeze
- VENDOR_NAME_LIST =
ApiVendorV1::Constants.constants.select do |constant| constant.to_s.include?('_VENDOR_NAME') end.map do |constant| ApiVendorV1::Constants.const_get(constant) end.freeze
- VENDOR_NAME_LIST_COMPLETE_INTEGRATIONS =
Always update this constant when new vendor has been integrated with HungryHub with end to end integration
[ ApiVendorV1::Constants::OPEN_RICE_VENDOR_NAME, ApiVendorV1::Constants::TAG_THAI_VENDOR_NAME, ApiVendorV1::Constants::GOOGLE_RESERVE_VENDOR_NAME, ].freeze
Class Method Summary collapse
- .[](channel_id) ⇒ Object
- .accept_big_group ⇒ Object
- .adjust_package_qty_for_vendor?(vendor_name) ⇒ Boolean
- .adjust_pax_to_max_per_pack_qty?(vendor_name) ⇒ Boolean
-
.assign_footer_ad(ad_channel_params) ⇒ Object
Used by external web booking Currently it is for footer banner only.
- .auto_ack ⇒ Object
- .charge_credit_card_directly ⇒ Object
- .chatbot ⇒ Object
- .credit_card ⇒ Object
-
.default_channel ⇒ Channel
Channel instance.
- .default_vendor_email_if_skippable?(vendor_name) ⇒ Boolean
- .default_vendor_phone_if_skippable?(vendor_name) ⇒ Boolean
- .external_booking ⇒ Object
- .external_booking_with_name ⇒ Object
- .grouped_channel ⇒ Object
- .hh_android_app ⇒ Object
- .hh_ios_app ⇒ Object
- .ids ⇒ Object
- .manual ⇒ Array
-
.manual_package ⇒ Object
reservation created by owner dashboard uses this channel.
- .manual_record_id ⇒ Object
- .manual_to_sql ⇒ Object
- .names_to_reservation_report_by_channel ⇒ Object
- .names_to_reservation_report_by_restaurant ⇒ Object
- .names_to_xls_report ⇒ Object
- .require_cc?(channel_id) ⇒ Boolean
Instance Method Summary collapse
- #aoa? ⇒ Boolean
- #cached_tag_list ⇒ Object
- #cc_charge_type ⇒ Object
- #hide_edit_booking_link_for_vendor_customer_email? ⇒ Boolean
- #payment_handled_by_vendor?(vendor_payment: nil, vendor_name: nil) ⇒ Boolean
- #show_in_owner_dashboard? ⇒ Boolean
- #skip_give_rewards? ⇒ Boolean
- #skip_run_tier_qualification? ⇒ Boolean
-
#skip_send_notifications?(actor:) ⇒ Boolean
Skip send notifications to spesific actor (user, admin, or owner) also responsible to skip review requests Based on channel uri_name.
- #skip_vendor_phone_validation? ⇒ Boolean
- #using_custom_phone? ⇒ Boolean
- #using_default_phone? ⇒ Boolean
- #using_restaurant_phone? ⇒ Boolean
- #vendor_reservations_cancellation_allowed?(vendor_name) ⇒ Boolean
- #vendor_skips_payment_check_for_multiple_bookings?(vendor_name) ⇒ Boolean
Methods inherited from ApplicationRecord
Class Method Details
.[](channel_id) ⇒ Object
177 178 179 |
# File 'app/models/channel.rb', line 177 def self.[](channel_id) fetch_by_channel_id(channel_id) end |
.accept_big_group ⇒ Object
164 165 166 |
# File 'app/models/channel.rb', line 164 def self.accept_big_group Channel.tagged_with(ACCEPT_BIG_GROUP).pluck(:channel_id) end |
.adjust_package_qty_for_vendor?(vendor_name) ⇒ Boolean
419 420 421 422 423 424 425 426 427 |
# File 'app/models/channel.rb', line 419 def self.adjust_package_qty_for_vendor?(vendor_name) # need to adjust package qty if vendor requires package qty to be adjusted as per pax [ ApiVendorV1::Constants::GLOBALTIX_VENDOR_NAME, ApiVendorV1::Constants::ROYAL_ORCHID_PLUS_VENDOR_NAME, ApiVendorV1::Constants::SPARK_LOVE_VENDOR_NAME, ApiVendorV1::Constants::GOOGLE_RESERVE_VENDOR_NAME, ].include?(vendor_name) end |
.adjust_pax_to_max_per_pack_qty?(vendor_name) ⇒ Boolean
429 430 431 432 433 434 435 436 437 438 439 |
# File 'app/models/channel.rb', line 429 def self.adjust_pax_to_max_per_pack_qty?(vendor_name) # need to adjust pax qty if vendor do not send correct adult/kids, # so we need to block restaurant inventory as per max per_pack qty for package [ ApiVendorV1::Constants::GET_YOUR_GUIDE_VENDOR_NAME, ApiVendorV1::Constants::ROYAL_ORCHID_PLUS_VENDOR_NAME, ApiVendorV1::Constants::KLOOK_VENDOR_NAME, ApiVendorV1::Constants::KKDAY_VENDOR_NAME, ApiVendorV1::Constants::DIANPING_VENDOR_NAME, ].include?(vendor_name) end |
.assign_footer_ad(ad_channel_params) ⇒ Object
Used by external web booking Currently it is for footer banner only
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'app/models/channel.rb', line 232 def self.(ad_channel_params) ad_channel_params[:footer_banner].each do |ad| ad = ad.last channel = Channel.find_by channel_id: ad[:channel_id] channel_ad = ChannelAd.find_by id: ad[:ad_id] if channel_ad.nil? manager = ChannelAdManager.find_by ad_type: :footer_banner, channel_id: channel.id next if manager.nil? return false unless manager.destroy else manager = ChannelAdManager.create ad_type: :footer_banner, channel_id: channel.id, channel_ad_id: channel_ad.id unless manager.save dup_manager = ChannelAdManager.where ad_type: :footer_banner, channel_id: channel.id dup_manager.each(&:destroy) return false unless manager.save! end end end true rescue ActiveRecord::ActiveRecordError => e APMErrorHandler.report e false end |
.auto_ack ⇒ Object
141 142 143 |
# File 'app/models/channel.rb', line 141 def self.auto_ack Channel.tagged_with(AUTO_ACK).pluck(:channel_id) end |
.charge_credit_card_directly ⇒ Object
124 125 126 |
# File 'app/models/channel.rb', line 124 def self.charge_credit_card_directly Channel.tagged_with(CHARGE_CC_DIRECTLY).pluck(:channel_id) end |
.chatbot ⇒ Object
271 272 273 274 275 276 277 278 279 280 281 282 283 |
# File 'app/models/channel.rb', line 271 def self.chatbot Rails.cache.fetch 'Channel:chatbot:instance', expires_in: CACHEFLOW.generate_expiry do instance = Channel.find_or_initialize_by name: 'Chatbot', group_name: 'hungry_hub', uri_name: 'chatbot' if instance.new_record? instance.tag_list.add('auto_ack') instance.channel_id = 101 instance.save! end instance end end |
.credit_card ⇒ Object
120 121 122 |
# File 'app/models/channel.rb', line 120 def self.credit_card Channel.tagged_with(HOLD_CC).pluck(:channel_id) end |
.default_channel ⇒ Channel
Returns channel instance.
146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'app/models/channel.rb', line 146 def self.default_channel default = Channel.tagged_with(Channel::DEFAULT) if default.present? default.first else channel = Channel.find_or_initialize_by(name: 'Hungry Hub', group_name: 'hungry_hub', channel_id: 0) return channel if channel.persisted? channel.tag_list.add(DEFAULT) channel.save! channel end end |
.default_vendor_email_if_skippable?(vendor_name) ⇒ Boolean
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
# File 'app/models/channel.rb', line 370 def self.default_vendor_email_if_skippable?(vendor_name) return '' if vendor_name.blank? # Add new vendor names here if there is a new vendor that skips the email for CREATE reservation vendors_skipping_email = [ ApiVendorV1::Constants::OPEN_RICE_VENDOR_NAME, ] return '' unless vendors_skipping_email.include?(vendor_name) # Use each vendor support email so when restaurant reply back, it goes to them and they know which one to handle if vendor_name == ApiVendorV1::Constants::OPEN_RICE_VENDOR_NAME return ApiVendorV1::Constants::OPEN_RICE_SUPPORT_EMAIL end "#{vendor_name.strip.downcase.gsub(' ', '')}-booking-#{Time.thai_time.to_i}@hungryhub.com" end |
.default_vendor_phone_if_skippable?(vendor_name) ⇒ Boolean
395 396 397 398 |
# File 'app/models/channel.rb', line 395 def self.default_vendor_phone_if_skippable?(vendor_name) # Vendors that are allowed to skip sending phone number in reservation params VENDOR_NAME_LIST.include?(vendor_name) ? AdminSetting.support_phone : '' end |
.external_booking ⇒ Object
160 161 162 |
# File 'app/models/channel.rb', line 160 def self.external_booking Channel.tagged_with(EXTERNAL_BOOKING).pluck(:channel_id) end |
.external_booking_with_name ⇒ Object
168 169 170 171 |
# File 'app/models/channel.rb', line 168 def self.external_booking_with_name names = Channel.tagged_with(EXTERNAL_BOOKING).pluck(:uri_name) HashWithIndifferentAccess.new(names.zip(external_booking).to_h) end |
.grouped_channel ⇒ Object
181 182 183 |
# File 'app/models/channel.rb', line 181 def self.grouped_channel all.group_by(&:group_name) end |
.hh_android_app ⇒ Object
298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'app/models/channel.rb', line 298 def self.hh_android_app Rails.cache.fetch 'Channel:hh_android_app:instance', expires_in: CACHEFLOW.generate_expiry do instance = Channel.find_or_initialize_by name: 'HH Android app', group_name: 'hungry_hub' if instance.new_record? instance.tag_list.add('auto_ack') instance.channel_id = 301 instance.save! end instance end end |
.hh_ios_app ⇒ Object
285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'app/models/channel.rb', line 285 def self.hh_ios_app Rails.cache.fetch 'Channel:hh_ios_app:instance', expires_in: CACHEFLOW.generate_expiry do instance = Channel.find_or_initialize_by name: 'HH iOS app', group_name: 'hungry_hub' if instance.new_record? instance.tag_list.add('auto_ack') instance.channel_id = 302 instance.save! end instance end end |
.ids ⇒ Object
173 174 175 |
# File 'app/models/channel.rb', line 173 def self.ids pluck(:channel_id) end |
.manual ⇒ Array
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/models/channel.rb', line 95 def self.manual manual_channel = Rails.cache.fetch(MANUAL_CHANNEL_CACHE_KEY, expires_in: CACHEFLOW.generate_expiry) do Channel.tagged_with('manual').pluck(:channel_id) end return manual_channel if manual_channel.present? manual_channel = Channel.find_by(name: 'Manual', channel_id: 5, group_name: 'manual') return [manual_channel.channel_id] if manual_channel.present? if manual_channel.blank? manual_channel = Channel.new(name: 'Manual', channel_id: 5, group_name: 'manual', phone_type: 'default') manual_channel.tag_list.add('manual') manual_channel.save! return [manual_channel.channel_id] end raise 'Manual channel is empty' end |
.manual_package ⇒ Object
reservation created by owner dashboard uses this channel
257 258 259 260 261 262 263 264 265 266 267 268 269 |
# File 'app/models/channel.rb', line 257 def self.manual_package Rails.cache.fetch 'Channel:manual_package:instance', expires_in: CACHEFLOW.generate_expiry do instance = Channel.find_or_initialize_by name: 'Manual package by Owner', group_name: 'hungry_hub', uri_name: 'ownerdashboard' if instance.new_record? instance.tag_list.add('auto_ack') instance.channel_id = 100 instance.save! end instance end end |
.manual_record_id ⇒ Object
193 194 195 |
# File 'app/models/channel.rb', line 193 def self.manual_record_id Channel.tagged_with(MANUAL).pluck(:id).join(', ') end |
.manual_to_sql ⇒ Object
137 138 139 |
# File 'app/models/channel.rb', line 137 def self.manual_to_sql '(' + manual.join(', ') + ')' end |
.names_to_reservation_report_by_channel ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'app/models/channel.rb', line 213 def self.names_to_reservation_report_by_channel sql = '' grouped_channel.each do |group| group[1].each_with_index do |channel, index| sql += "SUM(channel = #{channel.channel_id}) AS #{channel.group_name}_#{index}, " end end sql += 'SUM(' ids.each do |id| sql += "(channel = #{id})" sql += ' + ' unless id == ids.last end sql += ') AS grand_total' sql end |
.names_to_reservation_report_by_restaurant ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'app/models/channel.rb', line 197 def self.names_to_reservation_report_by_restaurant sql = '' grouped_channel.each do |group| group[1].each_with_index do |channel, index| sql += "SUM(#{Reservation.table_name}.channel = #{channel.channel_id}) AS #{channel.group_name}_#{index}, " end end sql += 'SUM(' ids.each do |id| sql += "(#{Reservation.table_name}.channel = #{id})" sql += ' + ' unless id == ids.last end sql += ') AS grand_total' sql end |
.names_to_xls_report ⇒ Object
185 186 187 188 189 190 191 |
# File 'app/models/channel.rb', line 185 def self.names_to_xls_report sql = '' all.find_each do |channel| sql += " when #{channel.channel_id} THEN '#{channel.name}' " end sql end |
.require_cc?(channel_id) ⇒ Boolean
128 129 130 131 132 133 134 135 |
# File 'app/models/channel.rb', line 128 def self.require_cc?(channel_id) channel = Channel.fetch_by_channel_id(channel_id) [HOLD_CC, CHARGE_CC_DIRECTLY].each do |cc_tag| return false unless channel return true if channel.cached_tag_list.include? cc_tag end false end |
Instance Method Details
#aoa? ⇒ Boolean
68 69 70 |
# File 'app/models/channel.rb', line 68 def aoa? uri_name == 'aoa' end |
#cached_tag_list ⇒ Object
76 77 78 79 80 |
# File 'app/models/channel.rb', line 76 def cached_tag_list @cached_tag_list ||= Rails.cache.fetch cache_key, expires_in: CACHEFLOW.generate_expiry do ActsAsTaggableOn::GenericParser.new(self[:cached_tag_list].to_s).parse end end |
#cc_charge_type ⇒ Object
113 114 115 116 117 118 |
# File 'app/models/channel.rb', line 113 def cc_charge_type return HOLD_CC if cached_tag_list.include? HOLD_CC return CHARGE_CC_DIRECTLY if cached_tag_list.include? CHARGE_CC_DIRECTLY nil end |
#hide_edit_booking_link_for_vendor_customer_email? ⇒ Boolean
388 389 390 391 392 393 |
# File 'app/models/channel.rb', line 388 def hide_edit_booking_link_for_vendor_customer_email? # use only if return false from skip_send_notifications? for vendor # we remove modify button for google reserve postpaid bookings only to avoid kids mismatch qty [ApiVendorV1::Constants::GOOGLE_RESERVE_CHANNEL_URI].include?(uri_name) end |
#payment_handled_by_vendor?(vendor_payment: nil, vendor_name: nil) ⇒ Boolean
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'app/models/channel.rb', line 343 def payment_handled_by_vendor?(vendor_payment: nil, vendor_name: nil) # Add new vendor names in the list if there is a new vendor that handles the payment from the vendor side. # We only allow 100% prepaid bookings for these vendors # however some vendors like Openrice also send pay-at-restaurant reservations for postpaid packages vendor_name = vendor_payment&.oauth_application&.name if vendor_payment.present? return true if [ApiVendorV1::Constants::OPEN_RICE_VENDOR_NAME, ApiVendorV1::Constants::GLOBALTIX_VENDOR_NAME, ApiVendorV1::Constants::KKDAY_VENDOR_NAME, ApiVendorV1::Constants::GET_YOUR_GUIDE_VENDOR_NAME, ApiVendorV1::Constants::ROYAL_ORCHID_PLUS_VENDOR_NAME, ApiVendorV1::Constants::SPARK_LOVE_VENDOR_NAME, ApiVendorV1::Constants::LINKTIVITY_VENDOR_NAME, ApiVendorV1::Constants::DIANPING_VENDOR_NAME, ApiVendorV1::Constants::KLOOK_VENDOR_NAME, ApiVendorV1::Constants::ONE_WALLET_VENDOR_NAME, ApiVendorV1::Constants::TRIP_VENDOR_NAME, ApiVendorV1::Constants::POINTX_VENDOR_NAME].include?(vendor_name) false end |
#show_in_owner_dashboard? ⇒ Boolean
72 73 74 |
# File 'app/models/channel.rb', line 72 def show_in_owner_dashboard? cached_tag_list.include? SHOW_IN_OWNER_DASHBOARD end |
#skip_give_rewards? ⇒ Boolean
311 312 313 |
# File 'app/models/channel.rb', line 311 def skip_give_rewards? VENDOR_CHANNEL_URI_LIST.include?(uri_name) end |
#skip_run_tier_qualification? ⇒ Boolean
339 340 341 |
# File 'app/models/channel.rb', line 339 def skip_run_tier_qualification? VENDOR_CHANNEL_URI_LIST.include?(uri_name) end |
#skip_send_notifications?(actor:) ⇒ Boolean
Skip send notifications to spesific actor (user, admin, or owner) also responsible to skip review requests Based on channel uri_name
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'app/models/channel.rb', line 321 def skip_send_notifications?(actor:) return false if actor.blank? case actor.to_s when 'user' return false if [ApiVendorV1::Constants::GOOGLE_RESERVE_CHANNEL_URI].include?(uri_name) # even if admin is manually creating reservation for any vendor, we skip emails or else user can cancel paid bookings VENDOR_CHANNEL_URI_LIST.include?(uri_name) when 'owner' false when 'admin' false else raise NotImplementedError, "Unsupported actor type: #{actor}" end end |
#skip_vendor_phone_validation? ⇒ Boolean
400 401 402 403 |
# File 'app/models/channel.rb', line 400 def skip_vendor_phone_validation? # Vendors for which we don't validate phone numbers provided in reservation params group_name == 'vendor' end |
#using_custom_phone? ⇒ Boolean
86 87 88 |
# File 'app/models/channel.rb', line 86 def using_custom_phone? phone_type == PHONE_TYPE[1].to_s end |
#using_default_phone? ⇒ Boolean
90 91 92 |
# File 'app/models/channel.rb', line 90 def using_default_phone? phone_type == PHONE_TYPE[2].to_s end |
#using_restaurant_phone? ⇒ Boolean
82 83 84 |
# File 'app/models/channel.rb', line 82 def using_restaurant_phone? phone_type == PHONE_TYPE[0].to_s end |
#vendor_reservations_cancellation_allowed?(vendor_name) ⇒ Boolean
405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'app/models/channel.rb', line 405 def vendor_reservations_cancellation_allowed?(vendor_name) # Currently for all bookings that are prepaid, HungryHub doesn't allow cancellation. # Customers have to contact HungryHub Customer Service for cancellation # and the only case we accept cancellation is if there is severe sickness # or any special case that the Merchant/Restaurant has to approve first vendors_allowed_cancellation = [ # GYG Team will restrict reservation cancellations from their Backend for restaurants that don't allow cancellations of prepaid reservations. # ApiVendorV1::Constants::GET_YOUR_GUIDE_VENDOR_NAME, ApiVendorV1::Constants::DIANPING_VENDOR_NAME, ] vendors_allowed_cancellation.include?(vendor_name) end |
#vendor_skips_payment_check_for_multiple_bookings?(vendor_name) ⇒ Boolean
364 365 366 367 368 |
# File 'app/models/channel.rb', line 364 def vendor_skips_payment_check_for_multiple_bookings?(vendor_name) return true if [ApiVendorV1::Constants::GOOGLE_RESERVE_VENDOR_NAME].include?(vendor_name) false end |