Class: DeliveryChannels::CreateOrderWorker

Inherits:
ApplicationWorker
  • Object
show all
Includes:
DeliveryChannel::CourierDriverHelper, ProgressStatus
Defined in:
app/workers/delivery_channels/create_order_worker.rb

Overview

typed: ignore

Defined Under Namespace

Classes: MyError

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DeliveryChannel::CourierDriverHelper

#can_wait_for_driver, #valid_time_to_call_driver?, #valid_to_call_driver?

Methods included from ProgressStatus

#available_delivery_status, #convert_from_grab_as_symbol, #convert_from_lalamove, #convert_from_lalamove_as_symbol, #convert_from_reservation, #owner_delivery_progress

Class Method Details

.cache_lockerObject



112
113
114
# File 'app/workers/delivery_channels/create_order_worker.rb', line 112

def self.cache_locker
  Redlock::Client.new([ENV['REDIS_LRU_URL']], retry_count: 0)
end

Instance Method Details

#lock_managerObject



116
117
118
# File 'app/workers/delivery_channels/create_order_worker.rb', line 116

def lock_manager
  @lock_manager ||= DeliveryChannels::CreateOrderWorker.cache_locker
end

#perform(reservation_id, config_param = {}) ⇒ Object



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
# File 'app/workers/delivery_channels/create_order_worker.rb', line 19

def perform(reservation_id, config_param = {})
  config = config_param.with_indifferent_access
  status = false

  reservation = Reservation.find reservation_id
  delivery_order = DeliveryChannel::OrderManager.new(reservation_id, config)

  return false unless delivery_order.valid_delivery_channel?
  return false unless delivery_order.valid_to_assign_driver?

  resource = "resource_key:#{reservation_id}"

  first_try_lock_info = lock_manager.lock(resource, HhPackage::Pricing::MAX_SEAT)

  return unless first_try_lock_info
  return if lock_manager.locked?(first_try_lock_info)

  begin
    Retriable.retriable(on: MyError,
                        tries: 10,
                        base_interval: 2,
                        on_retry: APMErrorHandler.report_retriable_event('delivery.order_courier')) do
      BUSINESS_LOGGER.info('delivery: order driver to third party', note: 'By create order worker',
                                                                    reservation_id: reservation_id)

      ActiveRecord::Base.transaction do
        order = delivery_order.order_driver
        if order
          delivery_order.update_driver
          reservation.driver_called = true
          reservation.save!
          status = true
        else
          status = false
          MyPusher::ReservationDriver.broadcast_reservation(reservation, :alert)
          raise ActiveRecord::Rollback
        end
      end
      raise MyError unless status
    end

    if status
      MyPusher::ReservationDriver.broadcast_reservation(reservation, :create)
      # MyMsgBus::ReservationDriver.broadcast_info(reservation)

      x_limit_duration = reservation.restaurant.call_driver_time_limit_duration
      check_driver_at = Time.zone.now + x_limit_duration.to_i.minutes

      note = "scheduled at #{(check_driver_at + 7.hours).strftime('%H:%M')}, will alert our staff if Lalamove still can not find driver within scheduled time"
      BUSINESS_LOGGER.info('delivery: scheduled to check driver availability',
                           reservation_id: reservation_id,
                           note: note)
      ::CheckDriverAvailabilityWorker.perform_at(check_driver_at, reservation.id)

      # @TODO need to activate when other courier option is active
      # service_type = config[:service_type]
      # change_order_courier_at = Time.now_in_tz(reservation.restaurant.time_zone) + 5.minutes
      # DeliveryChannels::ChangeOrderWorker.perform_at(change_order_courier_at, reservation_id, delivery_order.order_data['order_id'], service_type)
      reservation.touch
    end

    status
  rescue StandardError => e
    reservation.reload
    if reservation&.delivery_channel.present?
      reservation&.delivery_channel.courier.force_cancel_order(reservation,
                                                               skip_reorder: true)
    end

    BUSINESS_LOGGER.info('delivery: something went wrong when ordering a driver',
                         reservation_id: reservation_id,
                         note: 'system sending an email to staff')

    courier_error_msg = delivery_order.courier.errors.full_messages.reduce(:merge)
    courier_name = delivery_order.send(:courier_name)
    delivery_order.report_to_rollbar 'DeliveryChannels::CreateOrderWorker failed request driver ', :error, {
      reservation_id: reservation.id,
      errors: e.message,
      courier_errors: courier_error_msg,
      backtrace: e.backtrace,
      courier_name: courier_name,
    }
    subject = "Alert! failed request #{courier_name} driver. Reservation ID: #{reservation.id}"
    body = "Reservation ID: #{reservation.id}. error message: #{courier_error_msg}"
    StaffMailer.notify_error_staff(subject, body).deliver_later!

    reservation.errors.add :base, courier_error_msg.presence || 'Something went wrong!'
    MyPusher::ReservationDriver.broadcast_reservation(reservation, :update)
  ensure
    lock_manager.unlock(first_try_lock_info)
  end
end