spree_cm_commissioner 2.4.1 → 2.4.2
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/Gemfile.lock +1 -1
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +3 -1
- data/app/controllers/spree/api/v2/storefront/route_places_controller.rb +4 -3
- data/app/finders/spree_cm_commissioner/places/find_with_route.rb +48 -18
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +32 -7
- data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +1 -1
- data/app/models/spree_cm_commissioner/place.rb +3 -0
- data/app/request_schemas/spree_cm_commissioner/route_places_request_schema.rb +1 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41a0cae2693223db96d5e06211c36bfccd036a7661b2b65dcf8aa96a51ec66a1
|
|
4
|
+
data.tar.gz: 8c64ffd38289f261b85873082b90b7295dd9d8e72157d48941d21d506f21b84d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 935aa1894a546795e42928ff46c13b55b95043f3419dde0d842ad5f7a684eb71bcb8e52b1624e9a56766018cdf531e8e92305e4fcf0f1b805974508aa3012759
|
|
7
|
+
data.tar.gz: d91d61dfb4c16a1c4e5b5e31622c37a9b60e17f3c591e6f2e02f3c2a9b932012b3250e9d2f688af74126ce79c0bbecd3962d0b484d961bc5c9290ac7148b2874
|
data/Gemfile.lock
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# GET /api/v2/storefront/route_places
|
|
4
4
|
#
|
|
5
5
|
# Finds places (origins or destinations) that are connected to a given place through existing routes.
|
|
6
|
-
# Optionally filters results by keyword. Supports two modes:
|
|
6
|
+
# Optionally filters results by keyword or route_type. Supports two modes:
|
|
7
7
|
#
|
|
8
8
|
# Usage 1: Connected places (requires place_id)
|
|
9
9
|
# - Finds places connected to a specific place via routes
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
# - Returns empty collection if place_type is invalid
|
|
28
28
|
# - If place_id provided: returns places connected to that place
|
|
29
29
|
# - If place_id blank: returns all origins/destinations
|
|
30
|
-
# - Filters results by keyword if provided
|
|
30
|
+
# - Filters results by keyword or route_type if provided
|
|
31
31
|
#
|
|
32
32
|
# @example Mode 1: Find destinations connected to origin place ID 123
|
|
33
33
|
# GET /api/v2/storefront/route_places?place_id=123&place_type=destination
|
|
@@ -49,7 +49,8 @@ module Spree
|
|
|
49
49
|
@collection ||= collection_finder.new(
|
|
50
50
|
place_type: params[:place_type],
|
|
51
51
|
place_id: params[:place_id],
|
|
52
|
-
keyword: params[:query]
|
|
52
|
+
keyword: params[:query],
|
|
53
|
+
route_type: params[:route_type]
|
|
53
54
|
).execute
|
|
54
55
|
end
|
|
55
56
|
|
|
@@ -3,48 +3,78 @@
|
|
|
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 keyword [String] Optional. Filter by place name (case-insensitive)
|
|
6
|
+
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
6
7
|
#
|
|
7
8
|
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Place>]
|
|
8
9
|
#
|
|
9
10
|
# Modes:
|
|
10
11
|
# - place_id only: returns connected places (origins TO or destinations FROM given place)
|
|
11
12
|
# - keyword only: filters by name
|
|
12
|
-
# -
|
|
13
|
+
# - route_type only: filters by trip route types on those routes
|
|
14
|
+
# - combinations: connected places filtered by name and/or route type
|
|
13
15
|
# - neither: all origins/destinations in routes
|
|
14
16
|
#
|
|
15
|
-
# @example Origins with
|
|
16
|
-
# FindWithRoute.new(place_type: 'origin', place_id: 123).execute
|
|
17
|
+
# @example Origins with ferry trips to place 123
|
|
18
|
+
# FindWithRoute.new(place_type: 'origin', place_id: 123, route_type: :ferry).execute
|
|
17
19
|
#
|
|
18
|
-
# @example Destinations filtered by keyword
|
|
19
|
-
# FindWithRoute.new(place_type: 'destination', keyword: 'Phnom').execute
|
|
20
|
+
# @example Destinations filtered by keyword and route type
|
|
21
|
+
# FindWithRoute.new(place_type: 'destination', keyword: 'Phnom', route_type: :bus).execute
|
|
20
22
|
module SpreeCmCommissioner
|
|
21
23
|
module Places
|
|
22
24
|
class FindWithRoute
|
|
23
|
-
attr_reader :place_type, :place_id, :keyword
|
|
25
|
+
attr_reader :place_type, :place_id, :keyword, :route_type
|
|
24
26
|
|
|
25
|
-
def initialize(place_type:, place_id: nil, keyword: nil)
|
|
27
|
+
def initialize(place_type:, place_id: nil, keyword: nil, route_type: nil)
|
|
26
28
|
@place_type = place_type
|
|
27
29
|
@place_id = place_id
|
|
28
30
|
@keyword = keyword
|
|
31
|
+
@route_type = route_type
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
def execute
|
|
32
35
|
return SpreeCmCommissioner::Place.none if place_type.blank?
|
|
33
|
-
|
|
34
|
-
result = if place_type == 'origin'
|
|
35
|
-
scope = SpreeCmCommissioner::Place.with_routes_as_origin
|
|
36
|
-
place_id.present? ? scope.where(cm_routes: { destination_place_id: place_id }) : scope
|
|
37
|
-
else
|
|
38
|
-
scope = SpreeCmCommissioner::Place.with_routes_as_destination
|
|
39
|
-
place_id.present? ? scope.where(cm_routes: { origin_place_id: place_id }) : scope
|
|
40
|
-
end
|
|
41
|
-
|
|
42
36
|
return SpreeCmCommissioner::Place.none if place_id.present? && !SpreeCmCommissioner::Place.exists?(place_id)
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
result = result
|
|
38
|
+
result = scope
|
|
39
|
+
result = apply_keyword_filter(result) if keyword.present?
|
|
40
|
+
result = apply_route_type_filter(result) if route_type.present?
|
|
46
41
|
result
|
|
47
42
|
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def scope
|
|
47
|
+
return SpreeCmCommissioner::Place.none unless valid_place_type?
|
|
48
|
+
|
|
49
|
+
base_scope = origin? ? SpreeCmCommissioner::Place.with_routes_as_origin : SpreeCmCommissioner::Place.with_routes_as_destination
|
|
50
|
+
|
|
51
|
+
return base_scope if place_id.blank?
|
|
52
|
+
|
|
53
|
+
if origin?
|
|
54
|
+
base_scope.where(routes_as_origin: { destination_place_id: place_id })
|
|
55
|
+
else
|
|
56
|
+
base_scope.where(routes_as_destination: { origin_place_id: place_id })
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def apply_keyword_filter(result)
|
|
61
|
+
result.where('cm_places.name ILIKE ?', "%#{keyword}%")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def apply_route_type_filter(result)
|
|
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
|
+
end
|
|
70
|
+
|
|
71
|
+
def origin?
|
|
72
|
+
place_type == 'origin'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def valid_place_type?
|
|
76
|
+
%w[origin destination].include?(place_type)
|
|
77
|
+
end
|
|
48
78
|
end
|
|
49
79
|
end
|
|
50
80
|
end
|
|
@@ -4,21 +4,46 @@
|
|
|
4
4
|
# 1. fulfilled_order_count (completed orders) - DESC
|
|
5
5
|
# 2. order_count (total orders including incomplete) - DESC
|
|
6
6
|
#
|
|
7
|
+
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
8
|
+
#
|
|
7
9
|
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Route>] Routes with origin and destination places loaded,
|
|
8
10
|
# ordered from most to least popular
|
|
9
11
|
#
|
|
10
|
-
# @example
|
|
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
|
|
11
21
|
# finder = SpreeCmCommissioner::Routes::FindPopular.new
|
|
12
|
-
# finder.execute # => Returns routes sorted by
|
|
22
|
+
# finder.execute(route_type: :bus) # => Returns bus routes sorted by popularity
|
|
13
23
|
|
|
14
24
|
module SpreeCmCommissioner
|
|
15
25
|
module Routes
|
|
16
26
|
class FindPopular
|
|
17
|
-
def execute
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
def execute(route_type: nil)
|
|
28
|
+
scope(route_type: route_type)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def scope(route_type: nil)
|
|
34
|
+
result = SpreeCmCommissioner::Route
|
|
35
|
+
.includes(:origin_place, :destination_place)
|
|
36
|
+
|
|
37
|
+
if route_type.present?
|
|
38
|
+
# Filter routes that have trips with the specified route_type
|
|
39
|
+
route_scope = SpreeCmCommissioner::Route
|
|
40
|
+
.joins(:trips)
|
|
41
|
+
.where(cm_trips: { route_type: route_type.to_sym })
|
|
42
|
+
result = result.where(id: route_scope.select(:id))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
result.order(Arel.sql('COALESCE(fulfilled_order_count, 0) DESC'))
|
|
46
|
+
.order(Arel.sql('COALESCE(order_count, 0) DESC'))
|
|
22
47
|
end
|
|
23
48
|
end
|
|
24
49
|
end
|
|
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
|
|
|
2
2
|
module VehicleType
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
4
|
|
|
5
|
-
VEHICLE_TYPES = %i[suv sedan minivan van sleeping_bus luxury_van air_bus bus].freeze
|
|
5
|
+
VEHICLE_TYPES = %i[suv sedan minivan van sleeping_bus luxury_van air_bus bus ferry].freeze
|
|
6
6
|
|
|
7
7
|
included do
|
|
8
8
|
enum vehicle_type: VEHICLE_TYPES if table_exists? && column_names.include?('vehicle_type')
|
|
@@ -24,6 +24,9 @@ module SpreeCmCommissioner
|
|
|
24
24
|
has_many :routes_as_origin, class_name: 'SpreeCmCommissioner::Route', foreign_key: :origin_place_id
|
|
25
25
|
has_many :routes_as_destination, class_name: 'SpreeCmCommissioner::Route', foreign_key: :destination_place_id
|
|
26
26
|
|
|
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
|
+
|
|
27
30
|
# Scopes for route-based filtering
|
|
28
31
|
scope :with_routes_as_origin, -> { joins(:routes_as_origin).distinct }
|
|
29
32
|
scope :with_routes_as_destination, -> { joins(:routes_as_destination).distinct }
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_cm_commissioner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.4.
|
|
4
|
+
version: 2.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- You
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-12-
|
|
11
|
+
date: 2025-12-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: spree
|