Class: Tagging::RestaurantBasedOnGeoWorker

Inherits:
ApplicationWorker show all
Includes:
DistanceHelper
Defined in:
app/workers/tagging/restaurant_based_on_geo_worker.rb

Instance Method Summary collapse

Methods included from DistanceHelper

#decide_primary_tag, #find_distance_between

Methods inherited from ApplicationWorker

unlimited_retry

Instance Method Details

#perform(restaurant_id) ⇒ Object

This worker will tag all restaurant tags within defined distance from Restaurant Coordinates



8
9
10
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
# File 'app/workers/tagging/restaurant_based_on_geo_worker.rb', line 8

def perform(restaurant_id)
  restaurant = Restaurant.find(restaurant_id)

  return if restaurant.lat.blank? || restaurant.lng.blank?

  # check is restaurant skip the auto tag location
  return if restaurant.is_skip_auto_tag_location

  # stop if expired
  today = Time.now_in_tz(restaurant.time_zone).to_date
  return if !(restaurant.active && !restaurant.date_offer_expired?(today))

  tags_with_location = RestaurantTag.where.not(lat: nil, lng: nil).pluck(:id, :lat, :lng).to_h do |id, lat, lng|
    [id, [lat, lng]]
  end

  return if tags_with_location.blank?

  ActiveRecord::Base.transaction do
    restaurant.lock!

    # step 1
    # find another location and popular zone
    # store the distance data
    # if within the radius, then add current restaurant to the tag
    restaurant_tags = RestaurantTag.geo_tags_scope
    valid_tags = restaurant_tags.map do |restaurant_tag|
      distance = find_distance_between(restaurant: restaurant, restaurant_tag: restaurant_tag)
      {
        restaurant_tag: restaurant_tag,
        distance: distance,
      }
    end.select do |data|
      data[:distance].present? && data[:distance] <= data[:restaurant_tag].radius
    end

    # use any tag that is available in the city
    # this one for Restaurant with location = Phuket or Pattaya
    # currently there is no valid tag for all of them because in our DB, the lat long is not valid
    # so we use any tag with the same city to the restaurant
    # to make search page works
    if valid_tags.blank?
      restaurant_tags = RestaurantTag.where(city: restaurant.city)
      return if restaurant_tags.count > 1

      # use the default tag as primary location
      restaurant_tag = restaurant_tags.last
      distance = find_distance_between(restaurant: restaurant, restaurant_tag: restaurant_tag)
      if distance
        restaurant_tags_restaurants = [RestaurantTagsRestaurant.new(restaurant_id: restaurant.id,
                                                                    restaurant_tag_id: restaurant_tag&.id, distance_to_restaurant: distance)]
        RestaurantTagsRestaurant.import! restaurant_tags_restaurants, raise_error: true,
                                         on_duplicate_key_update: %i[restaurant_id restaurant_tag_id]
      end
    else
      restaurant_tags_restaurants = valid_tags.map do |data|
        restaurant_tag = data[:restaurant_tag]
        distance = data[:distance]
        RestaurantTagsRestaurant.new restaurant_id: restaurant.id, restaurant_tag_id: restaurant_tag.id,
                                     distance_to_restaurant: distance
      end

      # delete all existing restaurant's location and popular zone
      restaurant.restaurant_tags_restaurants.where(restaurant_tag_id: restaurant.restaurant_tags.geo_tags_scope.pluck(:id)).delete_all
      RestaurantTagsRestaurant.import! restaurant_tags_restaurants, raise_error: true,
                                       on_duplicate_key_update: %i[restaurant_id restaurant_tag_id]
    end
  end

  # step 2
  # find primary zone based on the nearest distance
  decide_primary_tag(restaurant.id)
  CleanCompactRestaurantCacheWorker.perform_async(restaurant.id)
end