spree_cm_commissioner 2.9.1.pre.pre3 → 2.9.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/Gemfile.lock +1 -1
- data/app/models/spree_cm_commissioner/pricing_model_route.rb +8 -0
- data/app/models/spree_cm_commissioner/trip.rb +3 -0
- data/app/services/spree_cm_commissioner/pricing_models/create_with_rule_groups.rb +9 -3
- data/app/services/spree_cm_commissioner/pricing_models/preview.rb +49 -6
- data/app/services/spree_cm_commissioner/pricing_models/update_with_rule_groups.rb +10 -7
- data/db/migrate/20260630000001_add_trip_to_cm_pricing_model_routes.rb +7 -0
- data/lib/spree_cm_commissioner/test_helper/factories/pricing_model_trip_factory.rb +11 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ebefceb78297eb71b4dcb417b47de1c9440786f17942f341aa5cff394558b2aa
|
|
4
|
+
data.tar.gz: 4fae27019658db8352dd7001445b331355d7b20f321b079c211e4e87889789eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed1b54c40e5288bc4e04e467c978b531f80b49985e387e4ed5a65908dd9b8152fe024fd4dcfdadba2f279b385fc8250588b3cd674125abf4a4ddd4d0306560b1
|
|
7
|
+
data.tar.gz: 283fa4cceb6e50ef28eba6e0eb4ecbdba5ca2984a377009934d057606840ce101db088d4f766c8d37b623bff61fe5b030867c99540ea00e33ed3067c20a4c243
|
data/Gemfile.lock
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
|
+
# A pricing-model assignment. A row is either:
|
|
3
|
+
# - route-scoped: trip_id NULL, keyed by route + O-D (unchanged legacy behaviour), or
|
|
4
|
+
# - trip-scoped: trip_id set, keyed by that specific trip + its own O-D (overrides route pricing
|
|
5
|
+
# for that trip only).
|
|
2
6
|
class PricingModelRoute < Base
|
|
3
7
|
belongs_to :route, class_name: 'SpreeCmCommissioner::Route'
|
|
8
|
+
belongs_to :trip, class_name: 'SpreeCmCommissioner::Trip', optional: true
|
|
4
9
|
belongs_to :pricing_model, class_name: 'SpreeCmCommissioner::PricingModel'
|
|
5
10
|
belongs_to :origin_place, class_name: 'SpreeCmCommissioner::Place'
|
|
6
11
|
belongs_to :destination_place, class_name: 'SpreeCmCommissioner::Place'
|
|
7
12
|
|
|
13
|
+
scope :route_scoped, -> { where(trip_id: nil) }
|
|
14
|
+
scope :trip_scoped, -> { where.not(trip_id: nil) }
|
|
15
|
+
|
|
8
16
|
scope :for_origin_destination, lambda { |origin_place_id, destination_place_id|
|
|
9
17
|
where(origin_place_id: origin_place_id, destination_place_id: destination_place_id)
|
|
10
18
|
}
|
|
@@ -52,6 +52,9 @@ module SpreeCmCommissioner
|
|
|
52
52
|
has_many :trip_blazer_queries, as: :queryable, class_name: 'SpreeCmCommissioner::BlazerQueryable'
|
|
53
53
|
has_many :blazer_queries, through: :trip_blazer_queries, source: :blazer_query, class_name: 'Blazer::Query'
|
|
54
54
|
|
|
55
|
+
has_many :pricing_model_routes, class_name: 'SpreeCmCommissioner::PricingModelRoute', dependent: :destroy
|
|
56
|
+
has_many :pricing_models, through: :pricing_model_routes, class_name: 'SpreeCmCommissioner::PricingModel'
|
|
57
|
+
|
|
55
58
|
has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', dependent: :destroy
|
|
56
59
|
has_many :boarding_trip_stops, -> { boarding.order('departure_time ASC NULLS LAST, id ASC') }, class_name: 'SpreeCmCommissioner::TripStop'
|
|
57
60
|
has_many :drop_off_trip_stops, -> { drop_off.order('arrival_time ASC NULLS LAST') }, class_name: 'SpreeCmCommissioner::TripStop'
|
|
@@ -3,13 +3,13 @@ module SpreeCmCommissioner
|
|
|
3
3
|
class CreateWithRuleGroups
|
|
4
4
|
prepend ::Spree::ServiceModule::Base
|
|
5
5
|
|
|
6
|
-
def call(vendor:, params:, route: nil, origin_place_id: nil, destination_place_id: nil)
|
|
6
|
+
def call(vendor:, params:, route: nil, trip: nil, origin_place_id: nil, destination_place_id: nil) # rubocop:disable Metrics/ParameterLists
|
|
7
7
|
pricing_model = vendor.pricing_models.new(model_params(params))
|
|
8
8
|
|
|
9
9
|
ApplicationRecord.transaction do
|
|
10
10
|
pricing_model.save!
|
|
11
11
|
build_rule_groups(pricing_model, params[:rule_groups])
|
|
12
|
-
create_route_assignment(pricing_model, route, origin_place_id, destination_place_id) if route.present?
|
|
12
|
+
create_route_assignment(pricing_model, route, trip, origin_place_id, destination_place_id) if route.present?
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
success(pricing_model)
|
|
@@ -41,11 +41,17 @@ module SpreeCmCommissioner
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
# A row is trip-scoped when a trip is given (overrides route pricing for that trip);
|
|
45
|
+
# otherwise route-scoped (unchanged legacy behaviour). Trip-scoped rows take their O-D from
|
|
46
|
+
# the trip so they match the trip's own journey at resolution time.
|
|
47
|
+
def create_route_assignment(pricing_model, route, trip, origin_place_id, destination_place_id)
|
|
48
|
+
origin_place_id = trip.origin_place_id if trip.present?
|
|
49
|
+
destination_place_id = trip.destination_place_id if trip.present?
|
|
45
50
|
return unless origin_place_id.present? && destination_place_id.present?
|
|
46
51
|
|
|
47
52
|
PricingModelRoute.create!(
|
|
48
53
|
route: route,
|
|
54
|
+
trip: trip,
|
|
49
55
|
pricing_model: pricing_model,
|
|
50
56
|
origin_place_id: origin_place_id,
|
|
51
57
|
destination_place_id: destination_place_id
|
|
@@ -39,29 +39,72 @@ module SpreeCmCommissioner
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def find_pricing_models(group_contexts)
|
|
42
|
-
|
|
42
|
+
transit_pricing_models(group_contexts) + variant_pricing_models(group_contexts)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
# Trip-level pricing overrides route-level pricing for the same journey; route pricing
|
|
46
|
+
# is the fallback when the trip (or connected journey's parent trip) has none assigned.
|
|
47
|
+
def transit_pricing_models(group_contexts)
|
|
46
48
|
transit_contexts = group_contexts.select { |ctx| ctx.trip_id.present? }
|
|
47
49
|
return [] if transit_contexts.blank?
|
|
48
50
|
|
|
49
51
|
origin_place_id, destination_place_id = determine_origin_destination(transit_contexts)
|
|
50
52
|
return [] if origin_place_id.blank? || destination_place_id.blank?
|
|
51
53
|
|
|
52
|
-
vendor_ids = transit_contexts
|
|
54
|
+
vendor_ids = transit_vendor_ids(transit_contexts)
|
|
53
55
|
return [] if vendor_ids.blank?
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
trip_level_pricing_models(
|
|
58
|
+
trip_ids: trip_candidate_ids(transit_contexts),
|
|
59
|
+
origin_place_id: origin_place_id,
|
|
60
|
+
destination_place_id: destination_place_id,
|
|
61
|
+
vendor_ids: vendor_ids
|
|
62
|
+
).presence || route_level_pricing_models(
|
|
63
|
+
route_ids: trip_route_ids(transit_contexts),
|
|
64
|
+
origin_place_id: origin_place_id,
|
|
65
|
+
destination_place_id: destination_place_id,
|
|
66
|
+
vendor_ids: vendor_ids
|
|
67
|
+
)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def trip_level_pricing_models(trip_ids:, origin_place_id:, destination_place_id:, vendor_ids:)
|
|
71
|
+
return [] if trip_ids.empty?
|
|
56
72
|
|
|
57
73
|
scope = SpreeCmCommissioner::PricingModelRoute
|
|
58
74
|
.active
|
|
75
|
+
.trip_scoped
|
|
76
|
+
.where(trip_id: trip_ids)
|
|
59
77
|
.for_origin_destination(origin_place_id, destination_place_id)
|
|
60
|
-
.includes(:pricing_model)
|
|
61
78
|
|
|
79
|
+
pricing_models_for(scope, vendor_ids)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def route_level_pricing_models(route_ids:, origin_place_id:, destination_place_id:, vendor_ids:)
|
|
83
|
+
scope = SpreeCmCommissioner::PricingModelRoute
|
|
84
|
+
.active
|
|
85
|
+
.route_scoped
|
|
86
|
+
.for_origin_destination(origin_place_id, destination_place_id)
|
|
62
87
|
scope = scope.where(route_id: route_ids) if route_ids.any?
|
|
63
88
|
|
|
64
|
-
scope
|
|
89
|
+
pricing_models_for(scope, vendor_ids)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Resolves a PricingModelRoute scope into its pricing models, restricted to vendors
|
|
93
|
+
# actually present among the line items being priced.
|
|
94
|
+
def pricing_models_for(scope, vendor_ids)
|
|
95
|
+
scope.includes(:pricing_model).map(&:pricing_model).select { |pm| vendor_ids.include?(pm.vendor_id) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# A booking's legs can each have their own trip-level price, and a connected journey
|
|
99
|
+
# (multiple legs sharing connected_trip_id) can also have its own price on the shared
|
|
100
|
+
# parent trip. This returns every trip id worth checking for either case.
|
|
101
|
+
def trip_candidate_ids(transit_contexts)
|
|
102
|
+
connected_trip_id = Integer(transit_contexts.first&.connected_trip_id.to_s, exception: false)
|
|
103
|
+
(transit_contexts.map(&:trip_id) + [connected_trip_id]).compact.uniq
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def transit_vendor_ids(transit_contexts)
|
|
107
|
+
transit_contexts.map { |ctx| variant_vendor_id(ctx.variant_id) }.compact.uniq
|
|
65
108
|
end
|
|
66
109
|
|
|
67
110
|
def variant_pricing_models(group_contexts)
|
|
@@ -3,11 +3,11 @@ module SpreeCmCommissioner
|
|
|
3
3
|
class UpdateWithRuleGroups
|
|
4
4
|
prepend ::Spree::ServiceModule::Base
|
|
5
5
|
|
|
6
|
-
def call(pricing_model:, params:, route: nil, origin_place_id: nil, destination_place_id: nil)
|
|
6
|
+
def call(pricing_model:, params:, route: nil, trip: nil, origin_place_id: nil, destination_place_id: nil) # rubocop:disable Metrics/ParameterLists
|
|
7
7
|
ApplicationRecord.transaction do
|
|
8
8
|
pricing_model.update!(model_params(params))
|
|
9
9
|
sync_rule_groups(pricing_model, params[:rule_groups])
|
|
10
|
-
update_route_assignment(pricing_model, route, origin_place_id, destination_place_id) if route.present?
|
|
10
|
+
update_route_assignment(pricing_model, route, trip, origin_place_id, destination_place_id) if route.present?
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
success(pricing_model)
|
|
@@ -47,14 +47,17 @@ module SpreeCmCommissioner
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
# Each pricing model created via this flow has a single assignment row; update it in place so
|
|
51
|
+
# the assigned trip (and O-D) can be changed on edit. Trip-scoped rows take O-D from the trip.
|
|
52
|
+
def update_route_assignment(pricing_model, route, trip, origin_place_id, destination_place_id)
|
|
53
|
+
origin_place_id = trip.origin_place_id if trip.present?
|
|
54
|
+
destination_place_id = trip.destination_place_id if trip.present?
|
|
51
55
|
return unless origin_place_id.present? && destination_place_id.present?
|
|
52
56
|
|
|
53
|
-
route_assignment = PricingModelRoute.find_or_initialize_by(
|
|
54
|
-
route: route,
|
|
55
|
-
pricing_model: pricing_model
|
|
56
|
-
)
|
|
57
|
+
route_assignment = PricingModelRoute.find_or_initialize_by(pricing_model: pricing_model)
|
|
57
58
|
route_assignment.update!(
|
|
59
|
+
route: route,
|
|
60
|
+
trip: trip,
|
|
58
61
|
origin_place_id: origin_place_id,
|
|
59
62
|
destination_place_id: destination_place_id
|
|
60
63
|
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
FactoryBot.define do
|
|
2
|
+
# A trip-scoped PricingModelRoute row — overrides route pricing for one specific trip.
|
|
3
|
+
# origin/destination default to the trip's own O-D (mirrors how trip pricing is resolved).
|
|
4
|
+
factory :cm_pricing_model_trip, class: 'SpreeCmCommissioner::PricingModelRoute' do
|
|
5
|
+
association :pricing_model, factory: :cm_pricing_model
|
|
6
|
+
association :trip, factory: :cm_trip
|
|
7
|
+
route { trip.route || create(:cm_route, origin_place: trip.origin_place, destination_place: trip.destination_place) }
|
|
8
|
+
origin_place { trip.origin_place }
|
|
9
|
+
destination_place { trip.destination_place }
|
|
10
|
+
end
|
|
11
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_cm_commissioner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.9.1.pre.
|
|
4
|
+
version: 2.9.1.pre.pre4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- You
|
|
@@ -3410,6 +3410,7 @@ files:
|
|
|
3410
3410
|
- db/migrate/20260623082233_create_cm_claims.rb
|
|
3411
3411
|
- db/migrate/20260624175658_add_unique_index_to_cm_claims.rb
|
|
3412
3412
|
- db/migrate/20260629000001_add_term_of_use_to_spree_vendors.rb
|
|
3413
|
+
- db/migrate/20260630000001_add_trip_to_cm_pricing_model_routes.rb
|
|
3413
3414
|
- db/migrate/20260701000001_add_device_info_to_cm_waiting_room_sessions.rb
|
|
3414
3415
|
- db/migrate/20260703065239_add_position_to_cm_voting_contestants.rb
|
|
3415
3416
|
- docker-compose.yml
|
|
@@ -3510,6 +3511,7 @@ files:
|
|
|
3510
3511
|
- lib/spree_cm_commissioner/test_helper/factories/pricing_action_factory.rb
|
|
3511
3512
|
- lib/spree_cm_commissioner/test_helper/factories/pricing_model_factory.rb
|
|
3512
3513
|
- lib/spree_cm_commissioner/test_helper/factories/pricing_model_route_factory.rb
|
|
3514
|
+
- lib/spree_cm_commissioner/test_helper/factories/pricing_model_trip_factory.rb
|
|
3513
3515
|
- lib/spree_cm_commissioner/test_helper/factories/pricing_model_variant_factory.rb
|
|
3514
3516
|
- lib/spree_cm_commissioner/test_helper/factories/pricing_rule_factory.rb
|
|
3515
3517
|
- lib/spree_cm_commissioner/test_helper/factories/pricing_rule_group_factory.rb
|