spree_cm_commissioner 2.5.1.pre.pre5 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test_and_build_gem.yml +2 -2
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/transit/draft_orders_controller.rb +4 -4
- data/app/controllers/spree/transit/trips_controller.rb +3 -3
- data/app/finders/spree_cm_commissioner/places/find_with_route.rb +12 -12
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +35 -19
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +4 -11
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +1 -10
- data/app/{services/spree_cm_commissioner/transit_order/create.rb → interactors/spree_cm_commissioner/transit/draft_order_creator.rb} +16 -13
- data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +3 -4
- data/app/interactors/spree_cm_commissioner/trip_stops_creator.rb +2 -2
- data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +2 -2
- data/app/jobs/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_order_count_incrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_job.rb +13 -0
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_decrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_incrementer_job.rb +10 -0
- data/app/models/concerns/spree_cm_commissioner/route_order_countable.rb +2 -2
- data/app/models/concerns/spree_cm_commissioner/route_trip_count_callbacks.rb +48 -0
- data/app/models/spree_cm_commissioner/place.rb +8 -5
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/route.rb +5 -45
- data/app/models/spree_cm_commissioner/trip.rb +33 -8
- data/app/models/spree_cm_commissioner/trip_connection.rb +36 -0
- data/app/models/spree_cm_commissioner/trip_stop.rb +2 -16
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -3
- data/app/models/spree_cm_commissioner/vendor_route.rb +9 -0
- data/app/queries/spree_cm_commissioner/trip_query.rb +2 -2
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +1 -2
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/{route_metrics/update_route_metrics.rb → routes/base_update_order_metrics.rb} +16 -11
- data/app/services/spree_cm_commissioner/routes/decrement_previous_trip_count.rb +30 -0
- data/app/services/spree_cm_commissioner/routes/decrement_trip_count.rb +33 -0
- data/app/services/spree_cm_commissioner/{route_metrics/increase_fulfilled_order_count.rb → routes/increment_fulfilled_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/{route_metrics/increase_order_count.rb → routes/increment_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/routes/increment_trip_count.rb +33 -0
- data/app/views/spree/transit/trip_stops/index.html.erb +2 -4
- data/app/views/spree_cm_commissioner/guest_mailer/send_ticket_to_guest.html.erb +1 -0
- data/config/initializers/spree_permitted_attributes.rb +0 -11
- data/config/routes.rb +0 -6
- data/lib/spree_cm_commissioner/test_helper/factories/route_factory.rb +6 -7
- data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +1 -4
- data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +1 -3
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +0 -2
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +0 -22
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -4
- metadata +19 -39
- data/app/controllers/spree/api/v2/tenant/popular_route_places_controller.rb +0 -60
- data/app/controllers/spree/api/v2/tenant/routes_controller.rb +0 -50
- data/app/controllers/spree/api/v2/tenant/transit/draft_orders_controller.rb +0 -46
- data/app/finders/spree_cm_commissioner/route_metrics/find_popular.rb +0 -44
- data/app/finders/spree_cm_commissioner/routes/find.rb +0 -94
- data/app/jobs/spree_cm_commissioner/route_metrics/decrease_trip_count_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_fulfilled_order_count_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_order_count_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_trip_count_job.rb +0 -10
- data/app/models/spree_cm_commissioner/route_metric.rb +0 -21
- data/app/models/spree_cm_commissioner/route_photo.rb +0 -12
- data/app/serializers/spree/v2/tenant/transit_cart_serializer.rb +0 -11
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_metric_serializer.rb +0 -13
- data/app/serializers/spree_cm_commissioner/v2/storefront/transit_line_item_serializer.rb +0 -17
- data/app/services/spree_cm_commissioner/route_metrics/decrease_trip_count.rb +0 -31
- data/app/services/spree_cm_commissioner/route_metrics/increase_trip_count.rb +0 -31
- data/app/services/spree_cm_commissioner/routes/create.rb +0 -51
- data/app/services/spree_cm_commissioner/routes/update.rb +0 -25
- data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +0 -128
- data/app/services/spree_cm_commissioner/trips/service_calendars/create_or_update.rb +0 -54
- data/app/services/spree_cm_commissioner/trips/update_single_leg.rb +0 -88
- data/app/services/spree_cm_commissioner/trips/variants/create.rb +0 -103
- data/db/migrate/20251224033103_migrate_cm_routes_to_cm_route_metrics.rb +0 -17
- data/db/migrate/20251224033910_migrate_cm_vendor_routes_to_cm_routes.rb +0 -30
- data/db/migrate/20260105072450_migrate_cm_trip_stops_to_support_trip_connection.rb +0 -12
- data/db/migrate/20260108101406_add_allow_booking_to_cm_trips.rb +0 -5
- data/lib/spree_cm_commissioner/test_helper/factories/route_metric_factory.rb +0 -12
- data/lib/spree_cm_commissioner/test_helper/factories/route_photo_factory.rb +0 -5
- data/lib/spree_cm_commissioner/transit/route_stop.rb +0 -61
- data/lib/spree_cm_commissioner/transit/route_stop_collection.rb +0 -203
- data/lib/spree_cm_commissioner/transit/trip_form.rb +0 -105
- data/lib/spree_cm_commissioner/transit/trip_stop_form.rb +0 -67
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b7e70b6ad87db5a4bd6b3879754f7ce8a753e1323d07ac754adea1426ef74b4
|
|
4
|
+
data.tar.gz: 699aa89f466074b9d86b8b0ddf39a7a8bf41f6edb4dda640f647dd33651bc9eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f60f4b8646f3537f616fe2d15b4f49b0bfa335acd1f61d4a97c6d25dc4a891ced787c0d2983f0dc327b2a125f643adebdc1a9ce59025436d74c507761a773f1
|
|
7
|
+
data.tar.gz: 18584fa23c8784b390a5b076fd7a855fb101db7c6bd5ea60159e6fdf6072fcac9441a9daddb2f9bc3f89351faf03b2792b6ef7864b63b081429752ce98d1f11a
|
|
@@ -45,7 +45,7 @@ jobs:
|
|
|
45
45
|
const commits_url = pr.commits_url;
|
|
46
46
|
|
|
47
47
|
const commits = await github.request(commits_url);
|
|
48
|
-
const pattern = /^
|
|
48
|
+
const pattern = /^Close\s+#\d+\s.+/;
|
|
49
49
|
|
|
50
50
|
let invalidCommits = [];
|
|
51
51
|
|
|
@@ -63,7 +63,7 @@ jobs:
|
|
|
63
63
|
core.setFailed(
|
|
64
64
|
`The following commit messages are not in the correct format:\n\n${invalidCommits.join(
|
|
65
65
|
'\n'
|
|
66
|
-
)}\n\nEach commit message must start with "Close #<issue_number> <message>"
|
|
66
|
+
)}\n\nEach commit message must start with "Close #<issue_number> <message>"`
|
|
67
67
|
);
|
|
68
68
|
} else {
|
|
69
69
|
console.log("All commit messages are correctly formatted.");
|
data/Gemfile.lock
CHANGED
|
@@ -31,7 +31,7 @@ module Spree
|
|
|
31
31
|
|
|
32
32
|
# override
|
|
33
33
|
def collection_finder
|
|
34
|
-
SpreeCmCommissioner::
|
|
34
|
+
SpreeCmCommissioner::Routes::FindPopular
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# override
|
|
@@ -41,7 +41,7 @@ module Spree
|
|
|
41
41
|
|
|
42
42
|
# override
|
|
43
43
|
def resource_serializer
|
|
44
|
-
SpreeCmCommissioner::V2::Storefront::
|
|
44
|
+
SpreeCmCommissioner::V2::Storefront::RouteSerializer
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# override
|
|
@@ -15,7 +15,7 @@ module Spree
|
|
|
15
15
|
@outbound_legs = params[:outbound_legs].is_a?(Array) && params[:outbound_legs].any? ? build_legs(:outbound, params[:outbound_legs]) : []
|
|
16
16
|
@inbound_legs = params[:inbound_legs].is_a?(Array) && params[:inbound_legs].any? ? build_legs(:inbound, params[:inbound_legs]) : []
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
context = SpreeCmCommissioner::Transit::DraftOrderCreator.call(
|
|
19
19
|
outbound_date: params[:outbound_date]&.to_date,
|
|
20
20
|
inbound_date: params[:inbound_date]&.to_date,
|
|
21
21
|
outbound_legs: @outbound_legs,
|
|
@@ -23,10 +23,10 @@ module Spree
|
|
|
23
23
|
user: spree_current_user
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
-
if
|
|
27
|
-
render_serialized_payload { serialize_resource(
|
|
26
|
+
if context.success?
|
|
27
|
+
render_serialized_payload { serialize_resource(context.order) }
|
|
28
28
|
else
|
|
29
|
-
render_error_payload(
|
|
29
|
+
render_error_payload(context.message)
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -48,13 +48,13 @@ module Spree
|
|
|
48
48
|
boarding_points_attributes = (cm_params.delete('boarding_points') || []).compact_blank
|
|
49
49
|
.map do |point_id|
|
|
50
50
|
trip_stop = trip_stops.delete(point_id.to_i)
|
|
51
|
-
{ stop_id: point_id,
|
|
51
|
+
{ stop_id: point_id, stop_type: 'boarding', id: trip_stop.try(:id) }
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
drop_off_points_attributes = (cm_params.delete('drop_off_points') || []).compact_blank
|
|
55
55
|
.map do |point_id|
|
|
56
56
|
trip_stop = trip_stops.delete(point_id.to_i)
|
|
57
|
-
{ stop_id: point_id,
|
|
57
|
+
{ stop_id: point_id, stop_type: 'drop_off', id: trip_stop.try(:id) }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
trip_stops.each_value do |trip_stop|
|
|
@@ -74,7 +74,7 @@ module Spree
|
|
|
74
74
|
:origin_id, :destination_id, :vehicle_id, :hours, :minutes, :seconds,
|
|
75
75
|
'departure_time(1i)', 'departure_time(2i)', 'departure_time(3i)',
|
|
76
76
|
'departure_time(4i)', 'departure_time(5i)', :product_id,
|
|
77
|
-
trip_stops_attributes: %i[stop_id
|
|
77
|
+
trip_stops_attributes: %i[stop_id stop_type _destroy id]
|
|
78
78
|
)
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# Finds places connected via
|
|
1
|
+
# Finds places connected via routes with optional filtering.
|
|
2
2
|
#
|
|
3
3
|
# @param place_type [String] Required. 'origin' or 'destination'
|
|
4
4
|
# @param place_id [Integer] Optional. Filter by connected place ID
|
|
5
5
|
# @param query [String] Optional. Filter by place name (case-insensitive)
|
|
6
|
-
# @param route_type [Symbol, String] Optional. Filter by route type from
|
|
6
|
+
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
7
7
|
#
|
|
8
8
|
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Place>]
|
|
9
9
|
#
|
|
10
10
|
# Modes:
|
|
11
11
|
# - place_id only: returns connected places (origins TO or destinations FROM given place)
|
|
12
12
|
# - query only: filters by name
|
|
13
|
-
# - route_type only: filters by route
|
|
13
|
+
# - route_type only: filters by trip route types on those routes
|
|
14
14
|
# - combinations: connected places filtered by name and/or route type
|
|
15
|
-
# - neither: all origins/destinations in
|
|
15
|
+
# - neither: all origins/destinations in routes
|
|
16
16
|
#
|
|
17
|
-
# @example Origins with ferry
|
|
17
|
+
# @example Origins with ferry trips to place 123
|
|
18
18
|
# FindWithRoute.new(place_type: 'origin', place_id: 123, route_type: :ferry).execute
|
|
19
19
|
#
|
|
20
20
|
# @example Destinations filtered by query and route type
|
|
@@ -46,14 +46,14 @@ module SpreeCmCommissioner
|
|
|
46
46
|
def scope
|
|
47
47
|
return SpreeCmCommissioner::Place.none unless valid_place_type?
|
|
48
48
|
|
|
49
|
-
base_scope = origin? ? SpreeCmCommissioner::Place.
|
|
49
|
+
base_scope = origin? ? SpreeCmCommissioner::Place.with_routes_as_origin : SpreeCmCommissioner::Place.with_routes_as_destination
|
|
50
50
|
|
|
51
51
|
return base_scope if place_id.blank?
|
|
52
52
|
|
|
53
53
|
if origin?
|
|
54
|
-
base_scope.where(
|
|
54
|
+
base_scope.where(routes_as_origin: { destination_place_id: place_id })
|
|
55
55
|
else
|
|
56
|
-
base_scope.where(
|
|
56
|
+
base_scope.where(routes_as_destination: { origin_place_id: place_id })
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -62,10 +62,10 @@ module SpreeCmCommissioner
|
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def apply_route_type_filter(result)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
trips_association = origin? ? :trips_as_origin : :trips_as_destination
|
|
66
|
+
result.joins(trips_association)
|
|
67
|
+
.where(cm_trips: { route_type: route_type.to_sym })
|
|
68
|
+
.distinct
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def origin?
|
|
@@ -1,30 +1,46 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
1
|
+
# Finds routes ordered by popularity based on order metrics.
|
|
2
|
+
#
|
|
3
|
+
# Routes are sorted by:
|
|
4
|
+
# 1. fulfilled_order_count (completed orders) - DESC
|
|
5
|
+
# 2. order_count (total orders including incomplete) - DESC
|
|
6
|
+
#
|
|
7
|
+
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
8
|
+
#
|
|
9
|
+
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Route>] Routes with origin and destination places loaded,
|
|
10
|
+
# ordered from most to least popular
|
|
11
|
+
#
|
|
12
|
+
# @example Get all popular routes
|
|
13
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
14
|
+
# finder.execute # => Returns all routes sorted by fulfillment and order counts
|
|
15
|
+
#
|
|
16
|
+
# @example Get popular ferry routes
|
|
17
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
18
|
+
# finder.execute(route_type: :ferry) # => Returns ferry routes sorted by popularity
|
|
19
|
+
#
|
|
20
|
+
# @example Get popular bus routes
|
|
21
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
22
|
+
# finder.execute(route_type: :bus) # => Returns bus routes sorted by popularity
|
|
6
23
|
|
|
7
24
|
module SpreeCmCommissioner
|
|
8
25
|
module Routes
|
|
9
26
|
class FindPopular
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
@tenant = tenant
|
|
13
|
-
@route_type = route_type
|
|
14
|
-
@limit = limit.to_i
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def execute
|
|
18
|
-
scope = SpreeCmCommissioner::Route.includes(:origin_place, :destination_place, :route_photos)
|
|
19
|
-
scope = scope.where(vendor_id: vendor.id) if vendor.present?
|
|
20
|
-
scope = scope.where(tenant_id: tenant.id) if tenant.present?
|
|
21
|
-
scope = scope.where(route_type: route_type.to_s) if route_type.present?
|
|
22
|
-
scope.order(fulfilled_order_count: :desc, order_count: :desc).limit(limit)
|
|
27
|
+
def execute(route_type: nil, query: nil)
|
|
28
|
+
scope(route_type: route_type, query: query)
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
private
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
def scope(route_type:, query:)
|
|
34
|
+
includes_associations = %i[origin_place destination_place]
|
|
35
|
+
includes_associations << :trips if route_type.present?
|
|
36
|
+
result = SpreeCmCommissioner::Route.includes(*includes_associations)
|
|
37
|
+
|
|
38
|
+
result = result.joins(:trips).where(cm_trips: { route_type: route_type.to_sym }) if route_type.present?
|
|
39
|
+
|
|
40
|
+
result = result.where('cm_routes.route_name ILIKE ?', "%#{query}%") if query.present?
|
|
41
|
+
|
|
42
|
+
result.distinct.order(fulfilled_order_count: :desc, order_count: :desc)
|
|
43
|
+
end
|
|
28
44
|
end
|
|
29
45
|
end
|
|
30
46
|
end
|
|
@@ -33,18 +33,11 @@ module SpreeCmCommissioner
|
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
# Returns dates for which inventory should be generated, based on calendar or default period.
|
|
37
36
|
def inventory_dates_for(variant)
|
|
38
|
-
|
|
37
|
+
start_date = Time.zone.tomorrow
|
|
38
|
+
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
calendar.start_date.upto(calendar.end_date).select { |date| calendar.service_available?(date) }
|
|
42
|
-
else
|
|
43
|
-
start_date = Time.zone.tomorrow
|
|
44
|
-
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
|
45
|
-
|
|
46
|
-
start_date.upto(end_date).to_a
|
|
47
|
-
end
|
|
40
|
+
(start_date..end_date)
|
|
48
41
|
end
|
|
49
42
|
|
|
50
43
|
def inventory_exist?(variant, inventory_date)
|
|
@@ -75,7 +68,7 @@ module SpreeCmCommissioner
|
|
|
75
68
|
def variants
|
|
76
69
|
scope = Spree::Variant.active.with_permanent_stock.where(is_master: false)
|
|
77
70
|
scope = scope.where(id: variant_ids) if variant_ids.present?
|
|
78
|
-
scope
|
|
71
|
+
scope
|
|
79
72
|
end
|
|
80
73
|
end
|
|
81
74
|
end
|
|
@@ -8,8 +8,7 @@ module SpreeCmCommissioner
|
|
|
8
8
|
|
|
9
9
|
return context.fail!(message: Spree.t(:doesnt_track_inventory)) unless variant.track_inventory?
|
|
10
10
|
|
|
11
|
-
stock_location =
|
|
12
|
-
|
|
11
|
+
stock_location = Spree::StockLocation.find(stock_location_id)
|
|
13
12
|
stock_movement = stock_location.stock_movements.build(stock_movement_params)
|
|
14
13
|
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
|
|
15
14
|
|
|
@@ -23,14 +22,6 @@ module SpreeCmCommissioner
|
|
|
23
22
|
|
|
24
23
|
private
|
|
25
24
|
|
|
26
|
-
def resolve_stock_location(variant, stock_location_id = nil)
|
|
27
|
-
if stock_location_id.present?
|
|
28
|
-
Spree::StockLocation.find(stock_location_id)
|
|
29
|
-
else
|
|
30
|
-
variant.vendor.stock_locations.first || variant.vendor.send(:create_stock_location)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
25
|
def adjust_inventory_items_async(variant_id, quantity)
|
|
35
26
|
args = { variant_id: variant_id, quantity: quantity }
|
|
36
27
|
CmAppLogger.log(label: "#{self.class.name}#adjust_inventory_items_async", data: args) do
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# DraftOrderCreator creates a new order for a entire journey, including outbound and (if present) inbound directions.
|
|
2
2
|
#
|
|
3
3
|
# Attributes:
|
|
4
4
|
# - outbound_date: [Date] The date of outbound transit
|
|
@@ -12,22 +12,25 @@
|
|
|
12
12
|
#
|
|
13
13
|
# Note: inbound_legs and inbound_date are optional; the order may represent a one-way (outbound only) journey.
|
|
14
14
|
module SpreeCmCommissioner
|
|
15
|
-
module
|
|
16
|
-
class
|
|
17
|
-
|
|
15
|
+
module Transit
|
|
16
|
+
class DraftOrderCreator < BaseInteractor
|
|
17
|
+
delegate :outbound_date,
|
|
18
|
+
:inbound_date,
|
|
19
|
+
:outbound_legs,
|
|
20
|
+
:inbound_legs,
|
|
21
|
+
:user, to: :context
|
|
18
22
|
|
|
19
|
-
def call
|
|
20
|
-
return
|
|
23
|
+
def call
|
|
24
|
+
return context.fail!(message: 'Outbound legs are missing') if outbound_legs.blank?
|
|
21
25
|
|
|
22
26
|
begin
|
|
23
|
-
order = create_order!
|
|
24
|
-
success(order: order)
|
|
27
|
+
context.order = create_order!
|
|
25
28
|
rescue StandardError => e
|
|
26
|
-
|
|
29
|
+
context.fail!(message: e.message)
|
|
27
30
|
end
|
|
28
31
|
end
|
|
29
32
|
|
|
30
|
-
def create_order!
|
|
33
|
+
def create_order!
|
|
31
34
|
order = Spree::Order.new(state: 'cart', use_billing: true, user: user)
|
|
32
35
|
|
|
33
36
|
outbound_line_items = build_line_items_for_legs!(order: order, legs: outbound_legs, initial_date: outbound_date)
|
|
@@ -109,10 +112,10 @@ module SpreeCmCommissioner
|
|
|
109
112
|
|
|
110
113
|
def insert_saved_guests_per_line_items_leg(line_items)
|
|
111
114
|
line_items.flat_map(&:guests).each_with_index do |guest, index|
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
context.saved_guests ||= []
|
|
116
|
+
context.saved_guests << SpreeCmCommissioner::SavedGuest.new if context.saved_guests[index].blank?
|
|
114
117
|
|
|
115
|
-
guest.saved_guest =
|
|
118
|
+
guest.saved_guest = context.saved_guests[index]
|
|
116
119
|
end
|
|
117
120
|
|
|
118
121
|
line_items
|
|
@@ -91,10 +91,9 @@ module SpreeCmCommissioner
|
|
|
91
91
|
stop_params = params.dig(:trip_stops_attributes, index.to_s)
|
|
92
92
|
return unless stop_params
|
|
93
93
|
|
|
94
|
-
cloned_stop.departure_time
|
|
95
|
-
cloned_stop.arrival_time
|
|
96
|
-
cloned_stop.
|
|
97
|
-
cloned_stop.allow_drop_off = stop_params[:allow_drop_off] if stop_params.key?(:allow_drop_off)
|
|
94
|
+
cloned_stop.departure_time = parse_time(stop_params[:departure_time])
|
|
95
|
+
cloned_stop.arrival_time = parse_time(stop_params[:arrival_time])
|
|
96
|
+
cloned_stop.stop_type = stop_params[:stop_type].presence
|
|
98
97
|
cloned_stop.location_place_id = stop_params[:location_place_id].presence
|
|
99
98
|
end
|
|
100
99
|
|
|
@@ -26,7 +26,7 @@ module SpreeCmCommissioner
|
|
|
26
26
|
trip: trip,
|
|
27
27
|
stop_place: origin_place,
|
|
28
28
|
location_place: origin_place,
|
|
29
|
-
|
|
29
|
+
stop_type: :boarding
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
attributes[:departure_time] = departure_time
|
|
@@ -42,7 +42,7 @@ module SpreeCmCommissioner
|
|
|
42
42
|
trip: trip,
|
|
43
43
|
stop_place: destination_place,
|
|
44
44
|
location_place: destination_place,
|
|
45
|
-
|
|
45
|
+
stop_type: :drop_off
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
attributes[:arrival_time] = departure_time + duration_seconds.seconds
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
module Stock
|
|
3
3
|
class PermanentInventoryItemsGeneratorJob < ApplicationUniqueJob
|
|
4
|
-
def perform
|
|
5
|
-
SpreeCmCommissioner::Stock::PermanentInventoryItemsGenerator.call
|
|
4
|
+
def perform
|
|
5
|
+
SpreeCmCommissioner::Stock::PermanentInventoryItemsGenerator.call
|
|
6
6
|
end
|
|
7
7
|
end
|
|
8
8
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteFulfilledOrderCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
order = Spree::Order.find(options[:order_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::IncrementFulfilledOrderCount.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteOrderCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
order = Spree::Order.find(options[:order_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::IncrementOrderCount.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Perform the previous-route decrement outside the Trip transaction.
|
|
2
|
+
|
|
3
|
+
module SpreeCmCommissioner
|
|
4
|
+
module Transit
|
|
5
|
+
class RoutePreviousTripCountDecrementerJob < ApplicationUniqueJob
|
|
6
|
+
queue_as :default
|
|
7
|
+
|
|
8
|
+
def perform(options = {})
|
|
9
|
+
SpreeCmCommissioner::Routes::DecrementPreviousTripCount.call(previous_route_id: options[:previous_route_id])
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteTripCountDecrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(options[:trip_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::DecrementTripCount.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteTripCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(options[:trip_id])
|
|
6
|
+
SpreeCmCommissioner::Routes::IncrementTripCount.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -7,13 +7,13 @@ module SpreeCmCommissioner
|
|
|
7
7
|
def increment_route_fulfilled_order_count
|
|
8
8
|
return unless has_trip_ids?
|
|
9
9
|
|
|
10
|
-
SpreeCmCommissioner::
|
|
10
|
+
SpreeCmCommissioner::Transit::RouteFulfilledOrderCountIncrementerJob.perform_later(order_id: id)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def increment_route_order_count
|
|
14
14
|
return unless has_trip_ids?
|
|
15
15
|
|
|
16
|
-
SpreeCmCommissioner::
|
|
16
|
+
SpreeCmCommissioner::Transit::RouteOrderCountIncrementerJob.perform_later(order_id: id)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module RouteTripCountCallbacks
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
after_create :increase_trip_count
|
|
7
|
+
before_destroy :decrease_trip_count
|
|
8
|
+
|
|
9
|
+
# When route context may change, enqueue an async job after commit that
|
|
10
|
+
# reads the previous values from `previous_changes` to decrement counts
|
|
11
|
+
# on the old route/vendor. This avoids keeping in-memory state and keeps
|
|
12
|
+
# the Trip update fast.
|
|
13
|
+
after_commit :enqueue_decrement_previous_route_trip_counts, on: :update
|
|
14
|
+
|
|
15
|
+
after_commit :increment_new_route_trip_counts, on: :update, if: :changed_route_context?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def decrease_trip_count
|
|
21
|
+
SpreeCmCommissioner::Transit::RouteTripCountDecrementerJob.perform_now(trip_id: id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def increase_trip_count
|
|
25
|
+
SpreeCmCommissioner::Transit::RouteTripCountIncrementerJob.perform_later(trip_id: id)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Read previous_changes to find prior route context and enqueue the job.
|
|
29
|
+
def enqueue_decrement_previous_route_trip_counts
|
|
30
|
+
prev_route_id = previous_changes['route_id']&.first
|
|
31
|
+
prev_origin_id = previous_changes['origin_place_id']&.first
|
|
32
|
+
prev_destination_id = previous_changes['destination_place_id']&.first
|
|
33
|
+
|
|
34
|
+
return unless prev_route_id.present? && prev_origin_id.present? && prev_destination_id.present?
|
|
35
|
+
|
|
36
|
+
SpreeCmCommissioner::Transit::RoutePreviousTripCountDecrementerJob.perform_later(
|
|
37
|
+
previous_route_id: prev_route_id
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Safely increment the trip_count for the trip's (new) route after update.
|
|
42
|
+
def increment_new_route_trip_counts
|
|
43
|
+
return if origin_place_id.blank? || destination_place_id.blank? || route_id.blank?
|
|
44
|
+
|
|
45
|
+
SpreeCmCommissioner::Transit::RouteTripCountIncrementerJob.perform_later(trip_id: id)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -21,12 +21,15 @@ module SpreeCmCommissioner
|
|
|
21
21
|
has_many :taxon_places, class_name: 'SpreeCmCommissioner::TaxonPlace', dependent: :destroy
|
|
22
22
|
has_many :taxons, through: :taxon_places
|
|
23
23
|
|
|
24
|
-
has_many :
|
|
25
|
-
has_many :
|
|
24
|
+
has_many :routes_as_origin, class_name: 'SpreeCmCommissioner::Route', foreign_key: :origin_place_id
|
|
25
|
+
has_many :routes_as_destination, class_name: 'SpreeCmCommissioner::Route', foreign_key: :destination_place_id
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
has_many :trips_as_origin, through: :routes_as_origin, source: :trips
|
|
28
|
+
has_many :trips_as_destination, through: :routes_as_destination, source: :trips
|
|
29
|
+
|
|
30
|
+
# Scopes for route-based filtering
|
|
31
|
+
scope :with_routes_as_origin, -> { joins(:routes_as_origin).distinct }
|
|
32
|
+
scope :with_routes_as_destination, -> { joins(:routes_as_destination).distinct }
|
|
30
33
|
|
|
31
34
|
def self.ransackable_attributes(auth_object = nil)
|
|
32
35
|
super & %w[name code]
|
|
@@ -48,7 +48,6 @@ module SpreeCmCommissioner
|
|
|
48
48
|
base.accepts_nested_attributes_for :product_places, allow_destroy: true
|
|
49
49
|
|
|
50
50
|
base.has_one :trip, class_name: 'SpreeCmCommissioner::Trip', dependent: :destroy
|
|
51
|
-
base.has_one :service_calendar, as: :calendarable, class_name: 'SpreeCmCommissioner::ServiceCalendar', dependent: :destroy
|
|
52
51
|
|
|
53
52
|
base.belongs_to :event, class_name: 'Spree::Taxon', optional: true
|
|
54
53
|
|
|
@@ -1,52 +1,12 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
class Route < Base
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
|
|
6
|
-
belongs_to :tenant, class_name: 'SpreeCmCommissioner::Tenant', optional: true
|
|
7
|
-
|
|
8
|
-
belongs_to :origin_place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
|
9
|
-
belongs_to :destination_place, class_name: 'SpreeCmCommissioner::Place', optional: false
|
|
10
|
-
|
|
11
|
-
has_one :primary_photo, -> { order(position: :asc) }, class_name: 'SpreeCmCommissioner::RoutePhoto',
|
|
12
|
-
as: :viewable,
|
|
13
|
-
dependent: :destroy
|
|
14
|
-
has_many :route_photos, class_name: 'SpreeCmCommissioner::RoutePhoto', as: :viewable, dependent: :destroy
|
|
15
|
-
|
|
3
|
+
has_many :vendor_routes, class_name: 'SpreeCmCommissioner::VendorRoute', dependent: :destroy
|
|
4
|
+
has_many :vendors, through: :vendor_routes
|
|
16
5
|
has_many :trips, inverse_of: :route
|
|
17
6
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
validate :validate_route_stops
|
|
21
|
-
|
|
22
|
-
delegate :multi_leg?, to: :route_stops
|
|
23
|
-
|
|
24
|
-
def self.ransackable_attributes(_auth_object = nil)
|
|
25
|
-
%w[route_type short_name route_name]
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def route_stops
|
|
29
|
-
Transit::RouteStopCollection.from_hash(read_attribute(:route_stops))
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def route_stops=(value)
|
|
33
|
-
if value.is_a?(Transit::RouteStopCollection)
|
|
34
|
-
@route_stops = value
|
|
35
|
-
self[:route_stops] = value.to_h
|
|
36
|
-
elsif value.is_a?(Array)
|
|
37
|
-
@route_stops = Transit::RouteStopCollection.from_hash(value)
|
|
38
|
-
self[:route_stops] = @route_stops.to_h
|
|
39
|
-
else
|
|
40
|
-
raise ArgumentError, 'route_stops must be an Array or RouteStopCollection'
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
def validate_route_stops
|
|
47
|
-
return if route_stops.valid?
|
|
7
|
+
belongs_to :origin_place, class_name: 'SpreeCmCommissioner::Place'
|
|
8
|
+
belongs_to :destination_place, class_name: 'SpreeCmCommissioner::Place'
|
|
48
9
|
|
|
49
|
-
|
|
50
|
-
end
|
|
10
|
+
validates :origin_place_id, uniqueness: { scope: :destination_place_id }
|
|
51
11
|
end
|
|
52
12
|
end
|