Class: SpreeCmCommissioner::Transit::DraftOrderCreator
- Inherits:
-
BaseInteractor
- Object
- BaseInteractor
- SpreeCmCommissioner::Transit::DraftOrderCreator
- Defined in:
- app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb
Instance Method Summary collapse
- #build_guests_for!(line_item, seat_selections) ⇒ Object
- #build_line_items_for!(leg, order, date) ⇒ 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 ⇒ Object
- #create_order! ⇒ Object
- #insert_saved_guests_per_line_items_leg(line_items) ⇒ Object
Instance Method Details
#build_guests_for!(line_item, seat_selections) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 95 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) ⇒ Object
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 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 66 def build_line_items_for!(leg, order, date) trip = SpreeCmCommissioner::Trip.find(leg.trip_id) trip_stops = trip.trip_stops.where(id: [leg.boarding_trip_stop_id, leg.drop_off_trip_stop_id]).index_by(&:id) from_date, to_date = 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 ) leg.seat_selections.group_by(&:variant_id).map do |variant_id, seat_selections| 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), private_metadata: { 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 } ) 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.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 51 def build_line_items_for_legs!(order:, legs:, initial_date:) all_line_items = [] current_leg_date = initial_date legs.each do |leg| leg_line_items = build_line_items_for!(leg, order, current_leg_date) 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
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 120 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 ⇒ Object
23 24 25 26 27 28 29 30 31 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 23 def call return context.fail!(message: 'Outbound legs are missing') if outbound_legs.blank? begin context.order = create_order! rescue StandardError => e context.fail!(message: e.) end end |
#create_order! ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 33 def create_order! 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) outbound_qty = outbound_line_items.sum(&:quantity) inbound_qty = inbound_line_items.sum(&:quantity) raise StandardError, 'Outbound & inbound line item quantities do not match' if inbound_line_items.any? && outbound_qty != inbound_qty 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
109 110 111 112 113 114 115 116 117 118 |
# File 'app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb', line 109 def insert_saved_guests_per_line_items_leg(line_items) line_items.flat_map(&:guests).each_with_index do |guest, index| context.saved_guests ||= [] context.saved_guests << SpreeCmCommissioner::SavedGuest.new if context.saved_guests[index].blank? guest.saved_guest = context.saved_guests[index] end line_items end |