Class: Bscf::Core::DeliveryOrder

Inherits:
ApplicationRecord show all
Defined in:
app/models/bscf/core/delivery_order.rb

Instance Method Summary collapse

Instance Method Details

#delivery_durationObject



31
32
33
34
# File 'app/models/bscf/core/delivery_order.rb', line 31

def delivery_duration
  return nil unless delivery_start_time && delivery_end_time
  ((delivery_end_time - delivery_start_time) / 1.hour).round(2)
end

#dropoff_addressesObject

Add this method to the DeliveryOrder class



77
78
79
80
81
82
83
# File 'app/models/bscf/core/delivery_order.rb', line 77

def dropoff_addresses
  delivery_order_items.includes(:dropoff_address)
                      .where.not(dropoff_address: nil)
                      .map(&:dropoff_address)
                      .compact
                      .uniq
end

#reorder_items_by_route(positions = nil) ⇒ Object

Reorder delivery items based on optimized route or provided positions



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
# File 'app/models/bscf/core/delivery_order.rb', line 37

def reorder_items_by_route(positions = nil)
  if positions.is_a?(Hash)
    # Use provided positions
    positions.each do |item_id, position|
      if item = delivery_order_items.find_by(id: item_id)
        item.update(position: position)
      end
    end
    true
  else
    return false if positions && !positions.is_a?(Hash)

    # Use optimized route
    route_data = optimized_route

    return false unless route_data.present? && route_data["waypoints"].present?

    # Get the optimized order of waypoints
    waypoint_order = route_data["waypoints"].map { |wp| wp["waypoint_index"] }

    # Get all delivery order items with dropoff addresses
    items_with_dropoffs = delivery_order_items.includes(:dropoff_address)
                                              .where.not(dropoff_address: nil)
                                              .to_a

    # Skip if we don't have the same number of items as waypoints
    return false if items_with_dropoffs.size != waypoint_order.size

    # Reorder items based on waypoint order
    waypoint_order.each_with_index do |original_index, new_position|
      if item = items_with_dropoffs[original_index]
        item.update(position: new_position + 1)
      end
    end

    true
  end
end