spree_cm_commissioner 2.5.1.pre.pre3 → 2.5.1.pre.pre4
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/api/v2/tenant/popular_route_places_controller.rb +60 -0
- data/app/controllers/spree/api/v2/tenant/routes_controller.rb +50 -0
- data/app/controllers/spree/api/v2/tenant/transit/draft_orders_controller.rb +46 -0
- 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/route_metrics/find_popular.rb +44 -0
- data/app/finders/spree_cm_commissioner/routes/find.rb +94 -0
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +19 -35
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +11 -4
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +10 -1
- data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +4 -3
- data/app/interactors/spree_cm_commissioner/trip_stops_creator.rb +2 -2
- data/app/jobs/spree_cm_commissioner/route_metrics/decrease_trip_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_fulfilled_order_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_order_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/route_metrics/increase_trip_count_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +2 -2
- data/app/models/concerns/spree_cm_commissioner/route_order_countable.rb +2 -2
- data/app/models/spree_cm_commissioner/place.rb +5 -8
- data/app/models/spree_cm_commissioner/product_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/route.rb +45 -5
- data/app/models/spree_cm_commissioner/route_metric.rb +21 -0
- data/app/models/spree_cm_commissioner/route_photo.rb +12 -0
- data/app/models/spree_cm_commissioner/trip.rb +8 -33
- data/app/models/spree_cm_commissioner/trip_stop.rb +16 -2
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +3 -1
- data/app/queries/spree_cm_commissioner/trip_query.rb +2 -2
- data/app/serializers/spree/v2/tenant/transit_cart_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_metric_serializer.rb +13 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/route_serializer.rb +2 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/transit_line_item_serializer.rb +17 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/route_metrics/decrease_trip_count.rb +31 -0
- data/app/services/spree_cm_commissioner/{routes/increment_fulfilled_order_count.rb → route_metrics/increase_fulfilled_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/{routes/increment_order_count.rb → route_metrics/increase_order_count.rb} +3 -3
- data/app/services/spree_cm_commissioner/route_metrics/increase_trip_count.rb +31 -0
- data/app/services/spree_cm_commissioner/{routes/base_update_order_metrics.rb → route_metrics/update_route_metrics.rb} +11 -16
- data/app/services/spree_cm_commissioner/routes/create.rb +51 -0
- data/app/services/spree_cm_commissioner/routes/update.rb +25 -0
- data/app/{interactors/spree_cm_commissioner/transit/draft_order_creator.rb → services/spree_cm_commissioner/transit_order/create.rb} +13 -16
- data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +123 -0
- data/app/services/spree_cm_commissioner/trips/service_calendars/create_or_update.rb +54 -0
- data/app/services/spree_cm_commissioner/trips/update_single_leg.rb +88 -0
- data/app/services/spree_cm_commissioner/trips/variants/create.rb +103 -0
- data/app/views/spree/transit/trip_stops/index.html.erb +4 -2
- data/app/views/spree_cm_commissioner/guest_mailer/send_ticket_to_guest.html.erb +0 -1
- data/config/initializers/spree_permitted_attributes.rb +11 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20251224033103_migrate_cm_routes_to_cm_route_metrics.rb +17 -0
- data/db/migrate/20251224033910_migrate_cm_vendor_routes_to_cm_routes.rb +30 -0
- data/db/migrate/20260105072450_migrate_cm_trip_stops_to_support_trip_connection.rb +12 -0
- data/db/migrate/20260108101406_add_allow_booking_to_cm_trips.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/route_factory.rb +7 -6
- data/lib/spree_cm_commissioner/test_helper/factories/route_metric_factory.rb +12 -0
- data/lib/spree_cm_commissioner/test_helper/factories/route_photo_factory.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +4 -1
- data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +3 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +2 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +22 -0
- data/lib/spree_cm_commissioner/transit/route_stop.rb +61 -0
- data/lib/spree_cm_commissioner/transit/route_stop_collection.rb +175 -0
- data/lib/spree_cm_commissioner/transit/trip_form.rb +81 -0
- data/lib/spree_cm_commissioner/transit/trip_stop_form.rb +61 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +4 -0
- metadata +37 -17
- data/app/jobs/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/transit/route_order_count_incrementer_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_job.rb +0 -13
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_decrementer_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_incrementer_job.rb +0 -10
- data/app/models/concerns/spree_cm_commissioner/route_trip_count_callbacks.rb +0 -48
- data/app/models/spree_cm_commissioner/trip_connection.rb +0 -36
- data/app/models/spree_cm_commissioner/vendor_route.rb +0 -9
- data/app/services/spree_cm_commissioner/routes/decrement_previous_trip_count.rb +0 -30
- data/app/services/spree_cm_commissioner/routes/decrement_trip_count.rb +0 -33
- data/app/services/spree_cm_commissioner/routes/increment_trip_count.rb +0 -33
- data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40605f05e2eabdbbf47121bbbfde8d0662afe833e7fb91803cadf1977c88fc8d
|
|
4
|
+
data.tar.gz: 025106d9fa95be2de1f1347b42b243a548c81ccc61efb5abec369fac2dd4bab1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3c9d477987819fc303567b1320b5c9c6cf1653ede16caf754ae5a60f3795e2d977de9f57ca82d13cde43de9bddfece7815fcad6f330a656202f67458c501f17f
|
|
7
|
+
data.tar.gz: de1d93feeb60fc4ed36f11baf3f013a260c1c6d16a2322b4b7674f77d58844060b33b6b76d2e1d2698ffdfa1f28d47ee45c1863059f9fa7fd5e221fade8e414a
|
|
@@ -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 = /^Close\s+#\d+\s
|
|
48
|
+
const pattern = /^(Close flow|Close\s+#\d+\s.+|Merge.*)/;
|
|
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>" or "Merge pull request #<number>"`
|
|
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::RouteMetrics::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::RouteMetricSerializer
|
|
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
|
+
result = SpreeCmCommissioner::TransitOrder::Create.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 result.success?
|
|
27
|
+
render_serialized_payload { serialize_resource(result.value[:order]) }
|
|
28
28
|
else
|
|
29
|
-
render_error_payload(
|
|
29
|
+
render_error_payload(result.error)
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class PopularRoutePlacesController < BaseController
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# override
|
|
9
|
+
def collection
|
|
10
|
+
@collection ||= collection_finder.new(
|
|
11
|
+
tenant: @tenant,
|
|
12
|
+
route_type: params[:route_type]
|
|
13
|
+
).execute
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# override
|
|
17
|
+
def default_resource_includes
|
|
18
|
+
%w[origin_place destination_place]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# override
|
|
22
|
+
def collection_finder
|
|
23
|
+
SpreeCmCommissioner::Routes::FindPopular
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# override
|
|
27
|
+
def collection_serializer
|
|
28
|
+
resource_serializer
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# override
|
|
32
|
+
def resource_serializer
|
|
33
|
+
SpreeCmCommissioner::V2::Storefront::RouteSerializer
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# override
|
|
37
|
+
def serializer_params
|
|
38
|
+
super.merge(
|
|
39
|
+
include_vendors: include_vendors?,
|
|
40
|
+
include_nearby_places: include_nearby_places?
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# override
|
|
45
|
+
def required_schema
|
|
46
|
+
SpreeCmCommissioner::PopularRoutePlacesRequestSchema
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def include_vendors?
|
|
50
|
+
resource_includes.include?(:vendors) || false
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def include_nearby_places?
|
|
54
|
+
resource_includes.include?(:nearby_places) || false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class RoutesController < BaseController
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# override
|
|
9
|
+
def collection
|
|
10
|
+
@collection ||= collection_finder.new(
|
|
11
|
+
tenant: @tenant,
|
|
12
|
+
params: params
|
|
13
|
+
).execute
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# override
|
|
17
|
+
def collection_finder
|
|
18
|
+
SpreeCmCommissioner::Routes::Find
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# override
|
|
22
|
+
def collection_serializer
|
|
23
|
+
SpreeCmCommissioner::V2::Storefront::RouteSerializer
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# override
|
|
27
|
+
def serializer_params
|
|
28
|
+
super.merge(
|
|
29
|
+
include_vendors: include_vendors?,
|
|
30
|
+
include_nearby_places: include_nearby_places?
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# override
|
|
35
|
+
def required_schema
|
|
36
|
+
SpreeCmCommissioner::PopularRoutePlacesRequestSchema
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def include_vendors?
|
|
40
|
+
resource_includes.include?(:vendors) || false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def include_nearby_places?
|
|
44
|
+
resource_includes.include?(:nearby_places) || false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
module Transit
|
|
6
|
+
class DraftOrdersController < BaseController
|
|
7
|
+
# Creates a draft transit order for tenant.
|
|
8
|
+
# Endpoint: POST /api/v2/tenant/transit/draft_orders
|
|
9
|
+
# Params:
|
|
10
|
+
# - outbound_date: Date of outbound transit (optional)
|
|
11
|
+
# - inbound_date: Date of inbound transit (optional)
|
|
12
|
+
# - outbound_legs: Array of outbound leg details (required)
|
|
13
|
+
# - inbound_legs: Array of inbound leg details (optional)
|
|
14
|
+
def create
|
|
15
|
+
@outbound_legs = params[:outbound_legs].is_a?(Array) && params[:outbound_legs].any? ? build_legs(:outbound, params[:outbound_legs]) : []
|
|
16
|
+
@inbound_legs = params[:inbound_legs].is_a?(Array) && params[:inbound_legs].any? ? build_legs(:inbound, params[:inbound_legs]) : []
|
|
17
|
+
|
|
18
|
+
result = SpreeCmCommissioner::TransitOrder::Create.call(
|
|
19
|
+
outbound_date: params[:outbound_date]&.to_date,
|
|
20
|
+
inbound_date: params[:inbound_date]&.to_date,
|
|
21
|
+
outbound_legs: @outbound_legs,
|
|
22
|
+
inbound_legs: @inbound_legs,
|
|
23
|
+
user: spree_current_user
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
if result.success?
|
|
27
|
+
render_serialized_payload { serialize_resource(result.value[:order]) }
|
|
28
|
+
else
|
|
29
|
+
render_error_payload(result.error)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def build_legs(direction, legs_params)
|
|
34
|
+
SpreeCmCommissioner::Transit::LegsBuilderService.new(direction: direction, legs_params: legs_params).call
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# override
|
|
38
|
+
def resource_serializer
|
|
39
|
+
Spree::V2::Tenant::TransitCartSerializer
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -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, allow_boarding: true, 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, allow_drop_off: true, 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 allow_boarding allow_drop_off _destroy id]
|
|
78
78
|
)
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# Finds places connected via
|
|
1
|
+
# Finds places connected via route metrics 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 route metrics (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
|
|
13
|
+
# - route_type only: filters by route type on route metrics
|
|
14
14
|
# - combinations: connected places filtered by name and/or route type
|
|
15
|
-
# - neither: all origins/destinations in
|
|
15
|
+
# - neither: all origins/destinations in route metrics
|
|
16
16
|
#
|
|
17
|
-
# @example Origins with ferry
|
|
17
|
+
# @example Origins with ferry route metrics 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_route_metrics_as_origin : SpreeCmCommissioner::Place.with_route_metrics_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(route_metrics_as_origin: { destination_place_id: place_id })
|
|
55
55
|
else
|
|
56
|
-
base_scope.where(
|
|
56
|
+
base_scope.where(route_metrics_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
|
+
# Use the association name as the table alias in the WHERE clause
|
|
66
|
+
# This works whether the association is already joined or not
|
|
67
|
+
association_name = origin? ? :route_metrics_as_origin : :route_metrics_as_destination
|
|
68
|
+
result.where(association_name => { route_type: route_type.to_sym })
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def origin?
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Finds route metrics ordered by popularity based on order metrics.
|
|
2
|
+
#
|
|
3
|
+
# Route metrics 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 (e.g., :ferry, :bus)
|
|
8
|
+
#
|
|
9
|
+
# @return [ActiveRecord::Relation<SpreeCmCommissioner::RouteMetric>] Route metrics with origin and destination places loaded,
|
|
10
|
+
# ordered from most to least popular
|
|
11
|
+
#
|
|
12
|
+
# @example Get all popular route metrics
|
|
13
|
+
# finder = SpreeCmCommissioner::RouteMetrics::FindPopular.new
|
|
14
|
+
# finder.execute # => Returns all route metrics sorted by fulfillment and order counts
|
|
15
|
+
#
|
|
16
|
+
# @example Get popular ferry route metrics
|
|
17
|
+
# finder = SpreeCmCommissioner::RouteMetrics::FindPopular.new
|
|
18
|
+
# finder.execute(route_type: :ferry) # => Returns ferry route metrics sorted by popularity
|
|
19
|
+
#
|
|
20
|
+
# @example Get popular bus route metrics
|
|
21
|
+
# finder = SpreeCmCommissioner::RouteMetrics::FindPopular.new
|
|
22
|
+
# finder.execute(route_type: :bus) # => Returns bus route metrics sorted by popularity
|
|
23
|
+
|
|
24
|
+
module SpreeCmCommissioner
|
|
25
|
+
module RouteMetrics
|
|
26
|
+
class FindPopular
|
|
27
|
+
def execute(route_type: nil, query: nil)
|
|
28
|
+
scope(route_type: route_type, query: query)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def scope(route_type:, query:)
|
|
34
|
+
result = SpreeCmCommissioner::RouteMetric.all
|
|
35
|
+
|
|
36
|
+
result = result.where(route_type: route_type.to_sym) if route_type.present?
|
|
37
|
+
result = result.where('cm_route_metrics.route_name ILIKE ?', "%#{query}%") if query.present?
|
|
38
|
+
|
|
39
|
+
result.includes(:origin_place, :destination_place)
|
|
40
|
+
.order(fulfilled_order_count: :desc, order_count: :desc)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Finder for Route records with common filtering options.
|
|
2
|
+
# Usage:
|
|
3
|
+
# finder = SpreeCmCommissioner::Routes::Find.new(vendor: vendor, params: params)
|
|
4
|
+
# finder = SpreeCmCommissioner::Routes::Find.new(tenant: tenant, params: params)
|
|
5
|
+
# finder.execute
|
|
6
|
+
# returns ActiveRecord::Relation of SpreeCmCommissioner::Route
|
|
7
|
+
|
|
8
|
+
module SpreeCmCommissioner
|
|
9
|
+
module Routes
|
|
10
|
+
class Find
|
|
11
|
+
def initialize(vendor: nil, tenant: nil, params: {})
|
|
12
|
+
@vendor = vendor
|
|
13
|
+
@tenant = tenant
|
|
14
|
+
@params = params || {}
|
|
15
|
+
|
|
16
|
+
@ids = Array(@params[:ids]).map(&:to_s)
|
|
17
|
+
@name = @params.dig(:filter, :name) || @params[:name]
|
|
18
|
+
@route_type = @params.dig(:filter, :route_type) || @params[:route_type]
|
|
19
|
+
@origin_place_id = @params.dig(:filter, :origin_place_id)
|
|
20
|
+
@destination_place_id = @params.dig(:filter, :destination_place_id)
|
|
21
|
+
@query = @params.dig(:filter, :query) || @params[:query]
|
|
22
|
+
@limit = (@params[:limit] || @params.dig(:page, :limit) || 50).to_i
|
|
23
|
+
@order = @params[:order] || 'created_at DESC'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def execute
|
|
27
|
+
results = base_scope
|
|
28
|
+
results = by_ids(results) if ids?
|
|
29
|
+
results = by_name(results) if name?
|
|
30
|
+
results = by_route_type(results) if route_type?
|
|
31
|
+
results = by_origin_place(results) if origin_place_id.present?
|
|
32
|
+
results = by_destination_place(results) if destination_place_id.present?
|
|
33
|
+
results = by_query(results) if query?
|
|
34
|
+
|
|
35
|
+
results.order(order_clause).limit(limit)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
attr_reader :vendor, :tenant, :params, :ids, :name, :route_type, :origin_place_id, :destination_place_id, :query, :limit, :order
|
|
41
|
+
|
|
42
|
+
def base_scope
|
|
43
|
+
scope = SpreeCmCommissioner::Route.includes(:origin_place, :destination_place, :route_photos)
|
|
44
|
+
scope = scope.where(vendor_id: vendor.id) if vendor.present?
|
|
45
|
+
scope = scope.where(tenant_id: tenant.id) if tenant.present?
|
|
46
|
+
scope
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ids?
|
|
50
|
+
ids.present?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def name?
|
|
54
|
+
name.present?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def route_type?
|
|
58
|
+
route_type.present?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def query?
|
|
62
|
+
query.present?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def by_ids(scope)
|
|
66
|
+
scope.where(id: ids)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def by_name(scope)
|
|
70
|
+
scope.where('cm_routes.route_name ILIKE ?', "%#{name}%")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def by_route_type(scope)
|
|
74
|
+
scope.where(route_type: route_type.to_s)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def by_origin_place(scope)
|
|
78
|
+
scope.where(origin_place_id: origin_place_id)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def by_destination_place(scope)
|
|
82
|
+
scope.where(destination_place_id: destination_place_id)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def by_query(scope)
|
|
86
|
+
scope.where('cm_routes.route_name ILIKE :q OR cm_routes.short_name ILIKE :q', q: "%#{query}%")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def order_clause
|
|
90
|
+
order
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -1,46 +1,30 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
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
|
|
1
|
+
# Finder to get popular route metrics scoped to a vendor or tenant.
|
|
2
|
+
# Orders by fulfilled_order_count DESC, then order_count DESC.
|
|
3
|
+
# Usage:
|
|
4
|
+
# finder = SpreeCmCommissioner::Routes::FindPopular.new(vendor: vendor, route_type: :bus, limit: 10)
|
|
5
|
+
# finder.execute
|
|
23
6
|
|
|
24
7
|
module SpreeCmCommissioner
|
|
25
8
|
module Routes
|
|
26
9
|
class FindPopular
|
|
27
|
-
def
|
|
28
|
-
|
|
10
|
+
def initialize(vendor: nil, tenant: nil, route_type: nil, limit: 20)
|
|
11
|
+
@vendor = vendor
|
|
12
|
+
@tenant = tenant
|
|
13
|
+
@route_type = route_type
|
|
14
|
+
@limit = limit.to_i
|
|
29
15
|
end
|
|
30
16
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
result = result.joins(:trips).where(cm_trips: { route_type: route_type.to_sym }) if route_type.present?
|
|
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)
|
|
23
|
+
end
|
|
39
24
|
|
|
40
|
-
|
|
25
|
+
private
|
|
41
26
|
|
|
42
|
-
|
|
43
|
-
end
|
|
27
|
+
attr_reader :vendor, :tenant, :route_type, :limit
|
|
44
28
|
end
|
|
45
29
|
end
|
|
46
30
|
end
|
|
@@ -33,11 +33,18 @@ 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.
|
|
36
37
|
def inventory_dates_for(variant)
|
|
37
|
-
|
|
38
|
-
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
|
38
|
+
calendar = variant.product&.service_calendar
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
if calendar.present?
|
|
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
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
def inventory_exist?(variant, inventory_date)
|
|
@@ -68,7 +75,7 @@ module SpreeCmCommissioner
|
|
|
68
75
|
def variants
|
|
69
76
|
scope = Spree::Variant.active.with_permanent_stock.where(is_master: false)
|
|
70
77
|
scope = scope.where(id: variant_ids) if variant_ids.present?
|
|
71
|
-
scope
|
|
78
|
+
scope.includes(product: :service_calendar)
|
|
72
79
|
end
|
|
73
80
|
end
|
|
74
81
|
end
|
|
@@ -8,7 +8,8 @@ module SpreeCmCommissioner
|
|
|
8
8
|
|
|
9
9
|
return context.fail!(message: Spree.t(:doesnt_track_inventory)) unless variant.track_inventory?
|
|
10
10
|
|
|
11
|
-
stock_location =
|
|
11
|
+
stock_location = resolve_stock_location(variant, stock_location_id)
|
|
12
|
+
|
|
12
13
|
stock_movement = stock_location.stock_movements.build(stock_movement_params)
|
|
13
14
|
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
|
|
14
15
|
|
|
@@ -22,6 +23,14 @@ module SpreeCmCommissioner
|
|
|
22
23
|
|
|
23
24
|
private
|
|
24
25
|
|
|
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
|
+
|
|
25
34
|
def adjust_inventory_items_async(variant_id, quantity)
|
|
26
35
|
args = { variant_id: variant_id, quantity: quantity }
|
|
27
36
|
CmAppLogger.log(label: "#{self.class.name}#adjust_inventory_items_async", data: args) do
|
|
@@ -91,9 +91,10 @@ 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.
|
|
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.allow_boarding = stop_params[:allow_boarding] if stop_params.key?(:allow_boarding)
|
|
97
|
+
cloned_stop.allow_drop_off = stop_params[:allow_drop_off] if stop_params.key?(:allow_drop_off)
|
|
97
98
|
cloned_stop.location_place_id = stop_params[:location_place_id].presence
|
|
98
99
|
end
|
|
99
100
|
|
|
@@ -26,7 +26,7 @@ module SpreeCmCommissioner
|
|
|
26
26
|
trip: trip,
|
|
27
27
|
stop_place: origin_place,
|
|
28
28
|
location_place: origin_place,
|
|
29
|
-
|
|
29
|
+
allow_boarding: true
|
|
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
|
+
allow_drop_off: true
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
attributes[:arrival_time] = departure_time + duration_seconds.seconds
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module RouteMetrics
|
|
3
|
+
class DecreaseTripCountJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(options[:trip_id])
|
|
6
|
+
SpreeCmCommissioner::RouteMetrics::DecreaseTripCount.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module RouteMetrics
|
|
3
|
+
class IncreaseFulfilledOrderCountJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
order = Spree::Order.find(options[:order_id])
|
|
6
|
+
SpreeCmCommissioner::RouteMetrics::IncreaseFulfilledOrderCount.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module RouteMetrics
|
|
3
|
+
class IncreaseOrderCountJob < ApplicationUniqueJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
order = Spree::Order.find(options[:order_id])
|
|
6
|
+
SpreeCmCommissioner::RouteMetrics::IncreaseOrderCount.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|