Class: AddOns::Restaurant

Inherits:
ApplicationRecord show all
Includes:
IdentityCache
Defined in:
app/models/add_ons/restaurant.rb

Overview

Schema Information

Table name: restaurant_add_ons

id                       :bigint           not null, primary key
active                   :boolean          default(FALSE)
auto_extend              :boolean          default(FALSE)
end_date                 :date
is_visible_for_staff     :boolean          default(FALSE)
last_booking_was_made    :datetime
rank_in_restaurant_scope :integer          default(0)
start_date               :date
created_at               :datetime         not null
updated_at               :datetime         not null
add_on_id                :bigint
restaurant_id            :integer

Indexes

index_restaurant_add_ons_on_add_on_id      (add_on_id)
index_restaurant_add_ons_on_end_date       (end_date)
index_restaurant_add_ons_on_restaurant_id  (restaurant_id)
index_restaurant_add_ons_on_start_date     (start_date)
restaurant_add_on_start_end_date           (start_date,end_date)

Foreign Keys

fk_rails_...  (add_on_id => add_ons.id)
fk_rails_...  (restaurant_id => restaurants.id)

Constant Summary collapse

SHOW_TO_ALL_USERS_MODE =
'Show to all users'.freeze
PREVIEW_MODE =
'Preview Mode'.freeze
HIDDEN_MODE =
'Hidden'.freeze

Instance Method Summary collapse

Methods inherited from ApplicationRecord

sync_carrierwave_url

Instance Method Details

#active_and_not_expired?Boolean

Returns:

  • (Boolean)


95
96
97
# File 'app/models/add_ons/restaurant.rb', line 95

def active_and_not_expired?
  active? && end_date >= Time.thai_time.to_date
end

#available_at?(date, time, time_zone) ⇒ Boolean

Returns:

  • (Boolean)


188
189
190
191
192
193
# File 'app/models/add_ons/restaurant.rb', line 188

def available_at?(date, time, time_zone)
  requested_time = Time.use_zone(time_zone) { Time.zone.parse("#{date} #{time}") }
  fetch_addon.agendas.select do |agenda|
    agenda.available_at?(start_date, end_date, time_zone, requested_time)
  end.present?
end

#available_times(date, time_zone) ⇒ Object



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
# File 'app/models/add_ons/restaurant.rb', line 112

def available_times(date, time_zone)
  unless date.is_a?(Date)
    date = Time.use_zone(time_zone) { Time.zone.parse(date) }.to_date
  end

  start_time = date.to_time.beginning_of_day.to_i
  end_time = date.to_time.end_of_day.to_i

  available_times = []
  $inv_redis.with do |redis|
    cache_key = inventory_cache_key(time_zone)

    write_available_times(time_zone) if redis.zcard(cache_key).zero?

    # Retrieve indices of available times for the given date range
    indices = redis.zrangebyscore(cache_key, start_time, end_time)

    # Retrieve the actual available times from the indices using redis pipeline
    redis.pipelined do
      indices.each do |index|
        available_times.push(redis.zscore(cache_key, index))
      end
    end

    available_times.map { |time| Time.at(time.value.to_i).in_time_zone(time_zone).strftime('%H:%M') }
  end
end

#determine_inventory_class(restaurant) ⇒ Object



103
104
105
106
107
108
109
110
# File 'app/models/add_ons/restaurant.rb', line 103

def determine_inventory_class(restaurant)
  is_dine_in = if restaurant.use_third_party_inventory?
                 nil
               else
                 restaurant.is_dine_in?
               end
  InventoryWrapper.new(restaurant_id: restaurant.id, is_dine_in: is_dine_in).inv_model
end

#determine_min_booking_timeObject



195
196
197
# File 'app/models/add_ons/restaurant.rb', line 195

def determine_min_booking_time
  fetch_addon.minimum_booking_time_in_advance.presence || 0
end

#fetch_addonObject

Instance Methods



78
79
80
81
82
83
84
85
86
# File 'app/models/add_ons/restaurant.rb', line 78

def fetch_addon
  @fetch_addon ||= begin
    Rails.cache.fetch "#{cache_key}/fetch_addon", expires_in: CACHEFLOW.generate_expiry do
      add_on
    end
  rescue TypeError
    add_on
  end
end

#inventory_cache_key(time_zone) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'app/models/add_ons/restaurant.rb', line 140

def inventory_cache_key(time_zone)
  data = fetch_addon.agendas.flat_map do |agenda|
    attributes = agenda.attributes.slice('start_time', 'end_time', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun',
                                         'exception_occurrences', 'single_occurrences')

    attributes['exception_occurrences'].map! do |exception_occurrence|
      if exception_occurrence.respond_to?(:[]) && exception_occurrence['start_date'].present?
        exception_occurrence['start_date'] = exception_occurrence['start_date'].to_date
      end
      if exception_occurrence.respond_to?(:[]) && exception_occurrence['end_date'].present?
        exception_occurrence['end_date'] = exception_occurrence['end_date'].to_date
      end
      exception_occurrence
    end

    attributes['single_occurrences'].map! do |single_occurrence|
      if single_occurrence['start_date'].present?
        single_occurrence['start_date'] = single_occurrence['start_date'].to_date
      end
      if single_occurrence['end_date'].present?
        single_occurrence['end_date'] = single_occurrence['end_date'].to_date
      end
      single_occurrence
    end
    attributes
  end
  agenda_model_file_last_modified_time = File.mtime(Rails.root.join('app', 'models', 'add_ons', 'agenda.rb')).to_i
  "restaurant-add-on-inv-#{CityHash.hash32([time_zone, data, end_date])}-#{agenda_model_file_last_modified_time}"
end

#preview?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'app/models/add_ons/restaurant.rb', line 99

def preview?
  is_visible_for_staff?
end

#statusObject



88
89
90
91
92
93
# File 'app/models/add_ons/restaurant.rb', line 88

def status
  return PREVIEW_MODE if active? && is_visible_for_staff?
  return SHOW_TO_ALL_USERS_MODE if active? && !is_visible_for_staff?

  HIDDEN_MODE
end

#write_available_times(time_zone) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'app/models/add_ons/restaurant.rb', line 170

def write_available_times(time_zone)
  data = fetch_addon.agendas.flat_map do |agenda|
    agenda.schedule_obj(start_date, end_date, time_zone)&.all_occurrences
  end

  $inv_redis.with do |redis|
    redis.pipelined do
      # Assuming your data is in the format: "Wed, 15 Jan 2025 19:30:00 +07 +07:00"
      cache_key = inventory_cache_key(time_zone)
      data.each_with_index do |available_time, index|
        redis.zadd(cache_key, available_time.to_i, index)
      end
      # Expire myzset after end_date + 1 day
      redis.expire(cache_key, (end_date + 1.day).to_time.to_i)
    end
  end
end