Class: SpreeCmCommissioner::TransitOrder::Create
- Inherits:
-
Object
- Object
- SpreeCmCommissioner::TransitOrder::Create
- Includes:
- Spree::ServiceModule::Base
- Defined in:
- app/services/spree_cm_commissioner/transit_order/create.rb
Instance Method Summary collapse
- #build_guests_for!(line_item, seat_selections) ⇒ Object
- #build_line_items_for!(leg, order, date, connected_trip_id = nil) ⇒ Object
-
#build_line_items_for_legs!(order:, legs:, initial_date:) ⇒ Object
Build line items for each leg, using the previous leg’s to_date as the next leg’s date, or the initial date for the first leg.
- #calculate_line_item_duration!(date:, departure_time:, arrival_time:) ⇒ Object
-
#call(outbound_date:, inbound_date:, outbound_legs:, inbound_legs: [], user: nil, order_options: []) ⇒ Object
rubocop:disable Metrics/ParameterLists.
-
#create_order!(outbound_date, inbound_date, outbound_legs, inbound_legs, user, order_options = []) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/ParameterLists.
- #insert_saved_guests_per_line_items_leg(line_items) ⇒ Object
- #open_dated_leg_dates(trip, _leg, date) ⇒ Object
- #resolve_leg_dates(trip, leg, date) ⇒ Object
Instance Method Details
#build_guests_for!(line_item, seat_selections) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 122 def build_guests_for!(line_item, seat_selections) block_ids = seat_selections.flat_map(&:block_ids) if block_ids.any? && block_ids.size != line_item.quantity raise StandardError, "Number of blocks (#{block_ids.size}) does not match quantity (#{line_item.quantity})" end Array.new(line_item.quantity) do |index| line_item.guests.new(block_id: block_ids[index]) end line_item end |
#build_line_items_for!(leg, order, date, connected_trip_id = nil) ⇒ Object
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 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 75 def build_line_items_for!(leg, order, date, connected_trip_id = nil) trip = SpreeCmCommissioner::Trip.find(leg.trip_id) from_date, to_date = resolve_leg_dates(trip, leg, date) leg.seat_selections.group_by(&:variant_id).map do |variant_id, seat_selections| = { direction: leg.direction, trip_id: leg.trip_id.to_s, boarding_trip_stop_id: leg.boarding_trip_stop_id&.to_s, drop_off_trip_stop_id: leg.drop_off_trip_stop_id&.to_s, connected_trip_id: connected_trip_id.presence&.to_s, service_origin_id: trip.service_origin_id.presence&.to_s }.compact line_item = order.line_items.new( product_type: :transit, from_date: from_date, to_date: to_date, variant_id: variant_id, quantity: seat_selections.sum(&:quantity), public_metadata: { is_open_dated: trip.open_dated? }, private_metadata: ) build_guests_for!(line_item, seat_selections) end end |
#build_line_items_for_legs!(order:, legs:, initial_date:) ⇒ Object
Build line items for each leg, using the previous leg’s to_date as the next leg’s date, or the initial date for the first leg.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 57 def build_line_items_for_legs!(order:, legs:, initial_date:) all_line_items = [] current_leg_date = initial_date # Use main_trip_id for connected trips (when legs have multiple trips) connected_trip_id = legs.size > 1 ? legs.first.main_trip_id&.to_s : nil legs.each do |leg| leg_line_items = build_line_items_for!(leg, order, current_leg_date, connected_trip_id) leg_line_items = insert_saved_guests_per_line_items_leg(leg_line_items) all_line_items.concat(leg_line_items) current_leg_date = leg_line_items.last.to_date.to_date if leg_line_items.any? end all_line_items end |
#calculate_line_item_duration!(date:, departure_time:, arrival_time:) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 147 def calculate_line_item_duration!(date:, departure_time:, arrival_time:) raise StandardError, 'Departure or arrival time in trip stop is missing' if departure_time.blank? || arrival_time.blank? raise StandardError, 'Arrival time cannot be before departure time' if arrival_time < departure_time trip_duration_in_seconds = arrival_time - departure_time # The input `date` is in local time (e.g., 10-10-2022). # Combine it with the departure_time in Rails default timezone so that # the resulting from_date stays on the intended local calendar day when stored in UTC. from_date = Time.zone.local(date.year, date.month, date.day, departure_time.hour, departure_time.min, departure_time.sec) to_date = from_date + trip_duration_in_seconds.seconds [from_date, to_date] end |
#call(outbound_date:, inbound_date:, outbound_legs:, inbound_legs: [], user: nil, order_options: []) ⇒ Object
rubocop:disable Metrics/ParameterLists
19 20 21 22 23 24 25 26 27 28 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 19 def call(outbound_date:, inbound_date:, outbound_legs:, inbound_legs: [], user: nil, order_options: []) # rubocop:disable Metrics/ParameterLists return failure(nil, 'Outbound legs are missing') if outbound_legs.blank? begin order = create_order!(outbound_date, inbound_date, outbound_legs, inbound_legs, user, ) success(order: order) rescue StandardError => e failure(nil, e.) end end |
#create_order!(outbound_date, inbound_date, outbound_legs, inbound_legs, user, order_options = []) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/ParameterLists
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 30 def create_order!(outbound_date, inbound_date, outbound_legs, inbound_legs, user, = []) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/ParameterLists order = Spree::Order.new(state: 'cart', use_billing: true, user: user) outbound_line_items = build_line_items_for_legs!(order: order, legs: outbound_legs, initial_date: outbound_date) inbound_line_items = inbound_legs.blank? ? [] : build_line_items_for_legs!(order: order, legs: inbound_legs, initial_date: inbound_date) # For connected trips, sum of quantities will be (passengers * legs). # We need to ensure the number of passengers per leg matching between outbound and inbound. outbound_qty_per_leg = outbound_legs.any? ? outbound_line_items.sum(&:quantity) / outbound_legs.size : 0 inbound_qty_per_leg = inbound_legs.any? ? inbound_line_items.sum(&:quantity) / inbound_legs.size : 0 if inbound_line_items.any? && outbound_qty_per_leg != inbound_qty_per_leg raise StandardError, "Outbound & inbound passenger counts do not match (#{outbound_qty_per_leg} vs #{inbound_qty_per_leg})" end trip_ids = (outbound_legs.map(&:trip_id) + inbound_legs.map(&:trip_id)).uniq order.preload_trip_ids = trip_ids order. = if .present? raise StandardError, order.errors..to_sentence unless order.save order.update_with_updater! order end |
#insert_saved_guests_per_line_items_leg(line_items) ⇒ Object
136 137 138 139 140 141 142 143 144 145 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 136 def insert_saved_guests_per_line_items_leg(line_items) line_items.flat_map(&:guests).each_with_index do |guest, index| @saved_guests ||= [] @saved_guests << SpreeCmCommissioner::SavedGuest.new if @saved_guests[index].blank? guest.saved_guest = @saved_guests[index] end line_items end |
#open_dated_leg_dates(trip, _leg, date) ⇒ Object
115 116 117 118 119 120 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 115 def open_dated_leg_dates(trip, _leg, date) validity_days = trip.product.open_dated_validity_days from_date = date.in_time_zone.beginning_of_day to_date = from_date + validity_days.days [from_date, to_date] end |
#resolve_leg_dates(trip, leg, date) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 |
# File 'app/services/spree_cm_commissioner/transit_order/create.rb', line 103 def resolve_leg_dates(trip, leg, date) return open_dated_leg_dates(trip, leg, date) if trip.open_dated? trip_stops = trip.trip_stops.where(id: [leg.boarding_trip_stop_id, leg.drop_off_trip_stop_id]).index_by(&:id) calculate_line_item_duration!( date: date, departure_time: trip_stops[leg.boarding_trip_stop_id]&.departure_time, arrival_time: trip_stops[leg.drop_off_trip_stop_id]&.arrival_time ) end |