Class: Restaurants::UpdateAttributesWorker

Inherits:
ApplicationWorker show all
Defined in:
app/workers/restaurants/update_attributes_worker.rb

Overview

update restaurant attributes that related to RestaurantTag and RestaurantPackage

Instance Method Summary collapse

Methods inherited from ApplicationWorker

unlimited_retry

Instance Method Details

#perform(restaurant_id) ⇒ Object

This method will do

  1. Update lowest and highest price

  2. Update any_offers value

  3. Update restaurant tag's restaurant

TODO: validate lowest & highest pricing of app/workers/restaurants/update_attributes_worker.rb



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'app/workers/restaurants/update_attributes_worker.rb', line 11

def perform(restaurant_id)
  restaurant = Restaurant.find_by(id: restaurant_id)
  return if restaurant.blank?

  # Update any offers to be false if restaurant has no packages
  # And just return the worker because the rest of the operations is need restaurant packages data
  if restaurant.restaurant_packages.blank?
    restaurant.any_offers = false
    return restaurant.save! validate: false
  end

  today = Time.now_in_tz(restaurant.time_zone).to_date

  restaurant_packages = restaurant.restaurant_packages.visible_for_user

  packages = if restaurant_packages.present?
               restaurant_packages.map(&:package).select do |package|
                 if package.respond_to?(:is_add_on)
                   package.is_add_on == false
                 else
                   true
                 end
               end
             else
               []
             end

  pricing_fallback = HhPackage::Pricing.new(price_cents: 0, kids_price_cents: 0, price_currency: 'THB')
  lowest = packages.map(&:dynamic_pricings).flatten.compact.min_by(&:net_price_cents_per_person).presence || pricing_fallback
  restaurant.package_lowest_price_cents = lowest.price_cents

  highest = packages.map(&:dynamic_pricings).flatten.compact.max_by(&:net_price_cents_per_person).presence || pricing_fallback
  restaurant.package_highest_price_cents = highest.price_cents

  class_names = packages.map(&:class).map(&:name).uniq
  # generate price summaries
  price_summaries = []
  HhPackage::PACKAGE_LIST.each do |package_type|
    class_package_type = "HhPackage::Package::#{package_type}"
    next unless class_names.include?(class_package_type)

    specific_packages = packages.select { |p| p.class.name == class_package_type }

    short_package_type = HhPackage::PACKAGE_LIST_TO_SHORT[package_type.to_sym]
    specific_lowest = specific_packages.map(&:dynamic_pricings).flatten.min_by(&:price_cents).presence || pricing_fallback
    specific_highest = specific_packages.map(&:dynamic_pricings).flatten.max_by(&:price_cents).presence || pricing_fallback

    pricing_type = specific_packages.last.dynamic_price_pricing_model
    case pricing_type
    when :per_pack
      marketing_price = [specific_lowest.marketing_price, specific_highest.marketing_price]
      price_summary = RestaurantPriceSummary.new(restaurant_id: restaurant_id,
                                                 product_type: 'package',
                                                 pricing_type: :per_pack,
                                                 package_type: short_package_type,
                                                 lowest_price_cents: marketing_price.min,
                                                 highest_price_cents: marketing_price.max)

      price_summaries << price_summary

    when :per_person
      price_summary = RestaurantPriceSummary.new(restaurant_id: restaurant_id,
                                                 product_type: 'package',
                                                 pricing_type: :per_person,
                                                 package_type: short_package_type,
                                                 lowest_price_cents: specific_lowest.price_cents,
                                                 highest_price_cents: specific_highest.price_cents)

      price_summaries << price_summary
    when :per_set
      %i[per_person per_pack].each do |price_type|
        price_summary = RestaurantPriceSummary.new(restaurant_id: restaurant_id,
                                                   product_type: 'package',
                                                   pricing_type: price_type,
                                                   package_type: short_package_type,
                                                   lowest_price_cents: specific_lowest.price_cents,
                                                   highest_price_cents: specific_highest.price_cents)

        price_summaries << price_summary
      end
    end

    price_summary = RestaurantPriceSummary.new(restaurant_id: restaurant_id,
                                               product_type: 'package',
                                               pricing_type: pricing_type,
                                               package_type: short_package_type,
                                               lowest_price_cents: specific_lowest.price_cents,
                                               highest_price_cents: specific_highest.price_cents)
    price_summaries << price_summary
  end

  # get ticket group price
  if restaurant.ticket_groups.present?
    HhPackage::PACKAGE_LIST_TO_SHORT.each_value do |package_type_code|
      package_type = PackageType.find_by(package_type_code: package_type_code)

      today = Date.today
      vim_specific_package = restaurant.ticket_groups.not_expired.where(package_type_id: package_type.id).where(visibility: 'show')

      next if vim_specific_package.blank?

      lowest_ticket_groups = vim_specific_package.min_by(&:price_cents).presence || pricing_fallback
      highest_ticket_groups = vim_specific_package.max_by(&:price_cents).presence || pricing_fallback

      lowest_pp_ticket_groups = vim_specific_package.min_by(&:price_per_person_cents)
      highest_pp_ticket_groups = vim_specific_package.max_by(&:price_per_person_cents)

      [:per_pack, :per_person].each do |pricing_type|
        lowest_ticket_group_price = if pricing_type == :per_pack || lowest_pp_ticket_groups.party_size.to_i.zero?
                                      lowest_ticket_groups.price_cents
                                    else
                                      lowest_pp_ticket_groups.price_per_person_cents
                                    end
        highest_ticket_group_price = if pricing_type == :per_pack || highest_pp_ticket_groups.party_size.to_i.zero?
                                       highest_ticket_groups.price_cents
                                     else
                                       highest_pp_ticket_groups.price_per_person_cents
                                     end

        ticket_offer_date = if pricing_type == :per_pack
                              lowest_ticket_groups.selling_end_date
                            else
                              lowest_pp_ticket_groups.selling_end_date
                            end

        price_summary = RestaurantPriceSummary.new(restaurant_id: restaurant_id,
                                                   pricing_type: pricing_type,
                                                   product_type: 'ticket',
                                                   ticket_offer_date: ticket_offer_date,
                                                   package_type: package_type.package_type_code,
                                                   lowest_price_cents: lowest_ticket_group_price,
                                                   highest_price_cents: highest_ticket_group_price)

        price_summaries << price_summary
      end
    end
  end

  ActiveRecord::Base.transaction do
    RestaurantPriceSummary.where(restaurant_id: restaurant_id).destroy_all
    RestaurantPriceSummary.bulk_import!(
      price_summaries,
      on_duplicate_key_update: %i[
        restaurant_id
        pricing_type
        package_type
        lowest_price_cents
        highest_price_cents
      ],
      raise_error: true,
    )
  end

  any_offers = false
  HhPackage::PACKAGE_SHORT_LIST.map do |type|
    tag = RestaurantTag.send("tagged_as_#{type}")

    tag_packages = restaurant_packages.select do |rp|
      rp.package.type_short == type
    end

    if tag_packages.blank?
      tag.restaurants.delete restaurant if tag.restaurants.include? restaurant
    else
      restaurant.save! validate: false # required to make `tag.restaurants << restaurant` code work
      tag.restaurants << restaurant unless tag.restaurants.include? restaurant
      any_offers = true
    end
  end

  package_class = restaurant_packages.map(&:package_type)
  restaurant.is_dine_in = package_class.reject { |klass| klass == 'HhPackage::Package::HungryAtHome' }.present?
  restaurant.is_take_away = package_class.select { |klass| klass == 'HhPackage::Package::HungryAtHome' }.present?

  restaurant.any_offers = any_offers
  restaurant.expiry_date = restaurant_packages.map(&:end_date).max if restaurant_packages.present?

  # check multiple pricing type
  # multiple_pricing = packages.select do |p|
  #   p.pricing_tier == :multiple && p.pricing.present? && p.pricing.count > 1
  # end
  # restaurant.has_multiple_pricing = multiple_pricing.present?
  restaurant.save! validate: false

  tag_restaurant(restaurant)
  # GoogleScrapeRequestWorker.perform_async restaurant_id
  Restaurants::GenerateRestaurantMenusWorker.perform_async restaurant_id
  compact_restaurant_worker = GenerateCompactRestaurantsWorker.new
  compact_restaurant_worker.skip_cache = true
  compact_restaurant_worker.perform restaurant_id
end

#tag_restaurant(restaurant) ⇒ Object



203
204
205
206
207
208
209
210
# File 'app/workers/restaurants/update_attributes_worker.rb', line 203

def tag_restaurant(restaurant)
  tag_with_solo_dining(restaurant)
  tag_with_nearby_place(restaurant, 'MRT')
  tag_with_nearby_place(restaurant, 'BTS')
  tag_with_gift_card(restaurant)
  tag_with_restaurant_packages(restaurant)
  tag_with_voucher(restaurant)
end

#tag_restaurant_by_package_types(restaurant, package_types, prefix) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
# File 'app/workers/restaurants/update_attributes_worker.rb', line 251

def tag_restaurant_by_package_types(restaurant, package_types, prefix)
  offer_tag_titles = HhPackage::PACKAGE_CONSTANT_AND_LONG_NAME.
    select { |package_type, _| package_types.include?("HhPackage::Package::#{package_type}") }.
    values.
    map { |title| "#{prefix}:#{title}" }

  if offer_tag_titles.present?
    existing_tags = RestaurantTag.where(title_en: offer_tag_titles)
    tag_restaurant_by_tags(restaurant, existing_tags) if existing_tags.exists?
  end
end

#tag_restaurant_by_tags(restaurant, tags) ⇒ Object



245
246
247
248
249
# File 'app/workers/restaurants/update_attributes_worker.rb', line 245

def tag_restaurant_by_tags(restaurant, tags)
  tags.each do |tag|
    tag.restaurant_tags_restaurants.find_or_create_by(restaurant_id: restaurant.id)
  end
end

#tag_with_gift_card(restaurant) ⇒ Object



231
232
233
234
# File 'app/workers/restaurants/update_attributes_worker.rb', line 231

def tag_with_gift_card(restaurant)
  tag = RestaurantTag.where('title_en LIKE ?', '%Accept Gift Card%')
  tag_restaurant_by_tags(restaurant, tag) if restaurant.accept_voucher?
end

#tag_with_nearby_place(restaurant, place) ⇒ Object



226
227
228
229
# File 'app/workers/restaurants/update_attributes_worker.rb', line 226

def tag_with_nearby_place(restaurant, place)
  tags = RestaurantTag.where('title_en LIKE ?', "%Admin:Near #{place}%")
  tag_restaurant_by_tags(restaurant, tags) if tags.exists?
end

#tag_with_restaurant_packages(restaurant) ⇒ Object



236
237
238
239
240
241
242
243
# File 'app/workers/restaurants/update_attributes_worker.rb', line 236

def tag_with_restaurant_packages(restaurant)
  package_types = restaurant.restaurant_packages.
    where('hh_package_restaurant_packages.end_date >= ? AND hh_package_restaurant_packages.active = ?', Time.zone.today, true).
    distinct.
    pluck(:package_type)

  tag_restaurant_by_package_types(restaurant, package_types, 'Offer')
end

#tag_with_solo_dining(restaurant) ⇒ Object



216
217
218
219
220
221
222
223
224
# File 'app/workers/restaurants/update_attributes_worker.rb', line 216

def tag_with_solo_dining(restaurant)
  package_types = restaurant.restaurant_packages.
    joins('INNER JOIN hh_package_package_attrs ON hh_package_package_attrs.package_id = hh_package_restaurant_packages.package_id').
    where('hh_package_package_attrs.max_seat = 1').
    distinct.
    pluck(:package_type)

  tag_restaurant_by_package_types(restaurant, package_types, 'Admin')
end

#tag_with_voucher(restaurant) ⇒ Object



212
213
214
# File 'app/workers/restaurants/update_attributes_worker.rb', line 212

def tag_with_voucher(restaurant)
  Tagging::AcceptVoucherTagWorker.new.perform(restaurant.id)
end