spree_cm_commissioner 2.5.0.pre.pre13 → 2.5.0

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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +4 -0
  3. data/Gemfile.lock +1 -1
  4. data/app/assets/images/mailer/call.png +0 -0
  5. data/app/assets/images/mailer/email.png +0 -0
  6. data/app/assets/images/mailer/user-tenant.png +0 -0
  7. data/app/controllers/spree/admin/base_controller_decorator.rb +7 -33
  8. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +7 -51
  9. data/app/controllers/spree/api/v2/storefront/intercity_taxi/distance_calculator_controller.rb +47 -0
  10. data/app/controllers/spree/api/v2/storefront/intercity_taxi/draft_orders_controller.rb +7 -5
  11. data/app/controllers/spree/api/v2/storefront/trip_search_controller.rb +2 -2
  12. data/app/controllers/spree/api/v2/tenant/intercity_taxi/distance_calculator_controller.rb +47 -0
  13. data/app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb +7 -5
  14. data/app/controllers/spree/api/v2/tenant/trip_search_controller.rb +2 -2
  15. data/app/controllers/spree_cm_commissioner/admin/orders_controller_decorator.rb +9 -1
  16. data/app/interactors/spree_cm_commissioner/google_routes_distance_calculator.rb +0 -13
  17. data/app/interactors/spree_cm_commissioner/invalidate_cache_request.rb +3 -3
  18. data/app/interactors/spree_cm_commissioner/vehicle_type_updater.rb +41 -0
  19. data/app/jobs/spree_cm_commissioner/invalidate_cache_request_job.rb +1 -1
  20. data/app/mailers/spree/order_mailer_decorator.rb +22 -1
  21. data/app/models/concerns/spree_cm_commissioner/line_item_seat_selection.rb +40 -0
  22. data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +1 -1
  23. data/app/models/concerns/spree_cm_commissioner/vehicle_kind.rb +21 -0
  24. data/app/models/spree_cm_commissioner/adjustable/adjuster/pricing_action.rb +25 -0
  25. data/app/models/spree_cm_commissioner/guest.rb +1 -1
  26. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +3 -0
  27. data/app/models/spree_cm_commissioner/homepage_background_app_image.rb +1 -1
  28. data/app/models/spree_cm_commissioner/invite_guest.rb +2 -5
  29. data/app/models/spree_cm_commissioner/line_item_decorator.rb +2 -2
  30. data/app/models/spree_cm_commissioner/option_type_decorator.rb +4 -1
  31. data/app/models/spree_cm_commissioner/option_value_decorator.rb +4 -1
  32. data/app/models/spree_cm_commissioner/{option_value_vehicle.rb → option_value_vehicle_type.rb} +2 -2
  33. data/app/models/spree_cm_commissioner/order_decorator.rb +14 -1
  34. data/app/models/spree_cm_commissioner/saved_guest.rb +2 -0
  35. data/app/models/spree_cm_commissioner/trip.rb +7 -6
  36. data/app/models/spree_cm_commissioner/vehicle.rb +8 -20
  37. data/app/models/spree_cm_commissioner/vehicle_type.rb +28 -0
  38. data/app/models/spree_cm_commissioner/vehicle_type_option_type.rb +6 -0
  39. data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
  40. data/app/overrides/spree/admin/orders/_order_actions/actions.html.erb.deface +36 -1
  41. data/app/overrides/spree/admin/products/edit/clear_cache_button.html.erb.deface +1 -1
  42. data/app/overrides/spree/admin/taxons/edit/clear_cache_button.html.erb.deface +3 -2
  43. data/app/queries/spree_cm_commissioner/trip_query.rb +5 -5
  44. data/app/request_schemas/spree_cm_commissioner/intercity_taxi_draft_order_update_schema.rb +2 -0
  45. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +12 -0
  46. data/app/serializers/spree/v2/tenant/line_item_serializer.rb +14 -1
  47. data/app/serializers/spree_cm_commissioner/v2/storefront/distance_serializer.rb +26 -0
  48. data/app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_line_item_serializer.rb +3 -3
  49. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +2 -2
  50. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb +1 -1
  51. data/app/serializers/spree_cm_commissioner/v2/storefront/{trip_vehicle_serializer.rb → trip_vehicle_type_serializer.rb} +2 -4
  52. data/app/services/spree_cm_commissioner/api_caches/invalidate.rb +98 -0
  53. data/app/services/spree_cm_commissioner/calculate_distance.rb +279 -0
  54. data/app/services/spree_cm_commissioner/cart/recalculate_decorator.rb +28 -1
  55. data/app/services/spree_cm_commissioner/guests/claim_invite_guest_service.rb +65 -0
  56. data/app/services/spree_cm_commissioner/intercity_taxi_order/calculate_distance.rb +224 -0
  57. data/app/services/spree_cm_commissioner/intercity_taxi_order/update.rb +30 -3
  58. data/app/services/spree_cm_commissioner/line_items/apply_pricing_models.rb +27 -0
  59. data/app/services/spree_cm_commissioner/pricing_models/apply.rb +4 -12
  60. data/app/services/spree_cm_commissioner/signing/sign_data.rb +42 -0
  61. data/app/services/spree_cm_commissioner/signing/verify_signature.rb +52 -0
  62. data/app/services/spree_cm_commissioner/transit/export_order.rb +146 -0
  63. data/app/services/spree_cm_commissioner/update_guest_service.rb +129 -0
  64. data/app/services/spree_cm_commissioner/vendor_places/create_with_google_map_data.rb +24 -7
  65. data/app/services/spree_cm_commissioner/vendor_places/update.rb +4 -2
  66. data/app/views/spree/admin/homepage_section/edit.html.erb +7 -2
  67. data/app/views/spree/order_mailer/cancel_email.html.erb +17 -0
  68. data/app/views/spree/order_mailer/confirm_email.html.erb +2 -2
  69. data/app/views/spree_cm_commissioner/cancel_order_mailer/_cancel_email.html.erb +13 -0
  70. data/app/views/spree_cm_commissioner/cancel_order_mailer/_footer.html.erb +8 -0
  71. data/app/views/spree_cm_commissioner/cancel_order_mailer/_header.html.erb +3 -0
  72. data/app/views/spree_cm_commissioner/cancel_order_mailer/_mailer_stylesheets.html.erb +88 -0
  73. data/app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_cancel_email.html.erb +13 -0
  74. data/app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_footer.html.erb +8 -0
  75. data/app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_header.html.erb +15 -0
  76. data/app/views/spree_cm_commissioner/layouts/cancel_order_mailer.html.erb +16 -0
  77. data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +1 -1
  78. data/app/views/spree_cm_commissioner/order_mailer/_customer_info.html.erb +2 -8
  79. data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +51 -23
  80. data/app/views/spree_cm_commissioner/order_mailer/_support_contact.html.erb +2 -7
  81. data/app/views/spree_cm_commissioner/order_mailer/purchased_items/_items.html.erb +76 -42
  82. data/app/views/spree_cm_commissioner/order_mailer/tenant/_customer_info.html.erb +4 -10
  83. data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +3 -8
  84. data/config/locales/en.yml +14 -0
  85. data/config/locales/km.yml +26 -2
  86. data/config/routes.rb +2 -0
  87. data/db/migrate/20251127074809_change_guest_dynamic_fields_value_from_jsonb_to_text.rb +40 -0
  88. data/db/migrate/20251219035243_add_migrations_to_support_vehicle_types.rb +36 -0
  89. data/db/migrate/20260105072146_add_nationality_group_and_age_group_to_cm_saved_guests.rb +6 -0
  90. data/db/migrate/20260106093359_add_contact_phone_to_cm_vendor_places.rb +5 -0
  91. data/lib/spree_cm_commissioner/distance.rb +88 -0
  92. data/lib/spree_cm_commissioner/engine.rb +3 -0
  93. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +2 -2
  94. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +3 -3
  95. data/lib/spree_cm_commissioner/test_helper/factories/pricing_model_variant_factory.rb +6 -0
  96. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +1 -1
  97. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +1 -0
  98. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +4 -1
  99. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +7 -0
  100. data/lib/spree_cm_commissioner/trip_query_result.rb +1 -1
  101. data/lib/spree_cm_commissioner/trip_result.rb +7 -1
  102. data/lib/spree_cm_commissioner/version.rb +1 -1
  103. data/lib/spree_cm_commissioner.rb +1 -1
  104. metadata +43 -12
  105. data/app/interactors/spree_cm_commissioner/trip_distance_calculator.rb +0 -165
  106. data/app/interactors/spree_cm_commissioner/vehicle_updater.rb +0 -41
  107. data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +0 -11
  108. data/app/models/spree_cm_commissioner/vehicle_option_type.rb +0 -6
  109. data/lib/spree_cm_commissioner/intercity_taxi/distance.rb +0 -38
  110. data/lib/spree_cm_commissioner/test_helper/factories/vendor_route_factory.rb +0 -7
@@ -0,0 +1,5 @@
1
+ class AddContactPhoneToCmVendorPlaces < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :cm_vendor_places, :contact_phone, :string, if_not_exists: true
4
+ end
5
+ end
@@ -0,0 +1,88 @@
1
+ module SpreeCmCommissioner
2
+ # Generic value object representing a computed trip distance and detours.
3
+ # This is the canonical class used by distance calculation services
4
+ # and line item metadata (see LineItemTransitable concern).
5
+ class Distance
6
+ attr_accessor :id,
7
+ :distance_km,
8
+ :ordered_points,
9
+ :estimated_time_minutes,
10
+ :base_km,
11
+ :detour_pickup_km,
12
+ :detour_dropoff_km,
13
+ :extra_pickup_km,
14
+ :extra_dropoff_km
15
+
16
+ def initialize(options = {})
17
+ options = options.stringify_keys if options.is_a?(Hash)
18
+
19
+ @id = SecureRandom.hex
20
+ @distance_km = options['distance_km']&.to_f
21
+ @ordered_points = options['ordered_points']
22
+ @estimated_time_minutes = options['estimated_time_minutes']&.to_i
23
+ @base_km = options['base_km']&.to_f
24
+ @detour_pickup_km = options['detour_pickup_km']&.to_f
25
+ @detour_dropoff_km = options['detour_dropoff_km']&.to_f
26
+ @extra_pickup_km = options['extra_pickup_km']&.to_f
27
+ @extra_dropoff_km = options['extra_dropoff_km']&.to_f
28
+ end
29
+
30
+ def self.from_hash(hash)
31
+ new(hash || {})
32
+ end
33
+
34
+ # Build a Distance from a signed hash (used for request-time verification).
35
+ def self.from_signed_hash(hash)
36
+ return nil unless valid_signature?(hash)
37
+
38
+ new(hash || {})
39
+ end
40
+
41
+ def self.valid_signature?(signed_hash)
42
+ return false if signed_hash.nil?
43
+
44
+ verify_result = SpreeCmCommissioner::Signing::VerifySignature.call(
45
+ signed_hash: signed_hash,
46
+ signing_key: ENV.fetch('DISTANCE_SIGNING_KEY')
47
+ )
48
+
49
+ verify_result.success? && verify_result.value == true
50
+ end
51
+
52
+ def to_h
53
+ {
54
+ 'distance_km' => @distance_km,
55
+ 'ordered_points' => @ordered_points,
56
+ 'estimated_time_minutes' => @estimated_time_minutes,
57
+ 'base_km' => @base_km,
58
+ 'detour_pickup_km' => @detour_pickup_km,
59
+ 'detour_dropoff_km' => @detour_dropoff_km,
60
+ 'extra_pickup_km' => @extra_pickup_km,
61
+ 'extra_dropoff_km' => @extra_dropoff_km
62
+ }.compact
63
+ end
64
+
65
+ def to_signed_h
66
+ hash = {
67
+ 'distance_km' => @distance_km,
68
+ 'ordered_points' => @ordered_points,
69
+ 'estimated_time_minutes' => @estimated_time_minutes,
70
+ 'base_km' => @base_km,
71
+ 'detour_pickup_km' => @detour_pickup_km,
72
+ 'detour_dropoff_km' => @detour_dropoff_km,
73
+ 'extra_pickup_km' => @extra_pickup_km,
74
+ 'extra_dropoff_km' => @extra_dropoff_km,
75
+ 'signed_at' => Time.current.utc.iso8601
76
+ }.compact
77
+
78
+ sign_result = SpreeCmCommissioner::Signing::SignData.call(
79
+ hash: hash,
80
+ signing_key: ENV.fetch('DISTANCE_SIGNING_KEY')
81
+ )
82
+
83
+ return hash unless sign_result.success?
84
+
85
+ hash.merge('signature' => sign_result.value)
86
+ end
87
+ end
88
+ end
@@ -38,6 +38,9 @@ module SpreeCmCommissioner
38
38
  SpreeCmCommissioner::Promotion::Actions::CreateDateSpecificItemAdjustments,
39
39
  SpreeCmCommissioner::Promotion::Actions::CreateGuestItemAdjustments,
40
40
  ]
41
+
42
+ # Register PricingAction adjuster to include pricing_action adjustments in totals
43
+ Rails.application.config.spree.adjusters << SpreeCmCommissioner::Adjustable::Adjuster::PricingAction
41
44
  end
42
45
 
43
46
  config.to_prepare(&method(:activate).to_proc)
@@ -1,7 +1,7 @@
1
1
  FactoryBot.define do
2
2
  # use cm_guest instead for consistency
3
3
  factory :guest, class: SpreeCmCommissioner::Guest do
4
- line_item { |a| a.association(:line_item) }
4
+ line_item { |a| a.association(:cm_line_item) }
5
5
  first_name { FFaker::Name.name }
6
6
  last_name { FFaker::Name.name }
7
7
  gender { 1 }
@@ -10,7 +10,7 @@ FactoryBot.define do
10
10
  end
11
11
 
12
12
  factory :cm_guest, class: SpreeCmCommissioner::Guest do
13
- line_item { |a| a.association(:line_item) }
13
+ line_item { |a| a.association(:cm_line_item) }
14
14
  first_name { FFaker::Name.name }
15
15
  last_name { FFaker::Name.name }
16
16
  gender { 1 }
@@ -7,13 +7,13 @@ FactoryBot.define do
7
7
 
8
8
  product do
9
9
  if order&.store&.present?
10
- create(:cm_product_with_product_kind_option_types, stores: [order.store])
10
+ create(:cm_product, stores: [order.store])
11
11
  else
12
- create(:cm_product_with_product_kind_option_types)
12
+ create(:cm_product)
13
13
  end
14
14
  end
15
15
 
16
- variant { product.master }
16
+ variant { create(:cm_variant, product: product, track_inventory: false) }
17
17
 
18
18
  factory :cm_need_confirmation_line_item do
19
19
  product { create(:cm_product, need_confirmation: true) }
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :cm_pricing_model_variant, class: 'SpreeCmCommissioner::PricingModelVariant' do
3
+ association :pricing_model, factory: :cm_pricing_model
4
+ association :variant, factory: :cm_variant
5
+ end
6
+ end
@@ -1,6 +1,6 @@
1
1
  FactoryBot.define do
2
2
  factory :cm_seat_layout, class: SpreeCmCommissioner::SeatLayout do
3
- association :layoutable, factory: :cm_vehicle
3
+ association :layoutable, factory: :cm_vehicle_type
4
4
 
5
5
  name { "Layout #{rand(1.0..50.0)}" }
6
6
  status { :active }
@@ -7,6 +7,7 @@ FactoryBot.define do
7
7
  product { create(:cm_product, product_type: :transit) }
8
8
 
9
9
  association :vendor, factory: :cm_transit_vendor
10
+ association :vehicle_type, factory: :cm_vehicle_type
10
11
  association :vehicle, factory: :cm_vehicle
11
12
  association :origin_place, factory: :cm_place
12
13
  association :destination_place, factory: :cm_place
@@ -1,6 +1,9 @@
1
1
  FactoryBot.define do
2
2
  factory :cm_vehicle, class: SpreeCmCommissioner::Vehicle do
3
- sequence(:code) { |n| "vehicle_#{n}" }
3
+ sequence(:name) { |n| "vehicle_#{n}" }
4
4
  sequence(:license_plate) { |n| "2KH-#{'%04d' % (n % 10000)}" }
5
+ kind { :air_bus }
6
+ association :vendor, factory: :vendor
7
+ association :vehicle_type, factory: :cm_vehicle_type
5
8
  end
6
9
  end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :cm_vehicle_type, class: SpreeCmCommissioner::VehicleType do
3
+ sequence(:name) { |n| "vehicle_type_#{n}" }
4
+ kind { :air_bus }
5
+ association :vendor, factory: :vendor
6
+ end
7
+ end
@@ -58,7 +58,7 @@ module SpreeCmCommissioner
58
58
  end
59
59
 
60
60
  def vehicle_types
61
- @trips.map(&:vehicle).map(&:vehicle_type).uniq
61
+ @trips.map(&:vehicle_type).uniq
62
62
  end
63
63
  end
64
64
  end
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  class TripResult
3
3
  attr_accessor :id, :origin_place, :destination_place, :allow_seat_selection,
4
4
  :departure_time, :duration, :route_type,
5
- :vehicle_id, :vehicle, :vendor_id, :vendor,
5
+ :vehicle_type_id, :vehicle_type, :vendor_id, :vendor,
6
6
  :quantity_available, :max_capacity, :boarding, :drop_off,
7
7
  :product_id, :amenities, :price, :compare_at_amount, :currency, :distance
8
8
 
@@ -37,6 +37,12 @@ module SpreeCmCommissioner
37
37
  departure_time + duration.seconds
38
38
  end
39
39
 
40
+ def display_price
41
+ return nil if price.nil? || currency.nil?
42
+
43
+ Spree::Money.new(price, currency: currency).to_s
44
+ end
45
+
40
46
  # Enable serializer-level caching (like ActiveRecord's cache_key_with_version)
41
47
  # Create a version hash based on attributes that matter for caching
42
48
  def cache_key_with_version
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '2.5.0.pre.pre13'.freeze
2
+ VERSION = '2.5.0'.freeze
3
3
 
4
4
  module_function
5
5
 
@@ -24,7 +24,7 @@ require 'spree_cm_commissioner/cached_inventory_item'
24
24
  require 'spree_cm_commissioner/transit/leg'
25
25
  require 'spree_cm_commissioner/transit/seat_selection'
26
26
  require 'spree_cm_commissioner/intercity_taxi/map_place'
27
- require 'spree_cm_commissioner/intercity_taxi/distance'
27
+ require 'spree_cm_commissioner/distance'
28
28
 
29
29
  require 'activerecord_multi_tenant'
30
30
  require 'google/cloud/recaptcha_enterprise'
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.5.0.pre.pre13
4
+ version: 2.5.0
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-18 00:00:00.000000000 Z
11
+ date: 2026-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -731,6 +731,8 @@ files:
731
731
  - app/assets/images/mailer/bookme-plus.png
732
732
  - app/assets/images/mailer/bookme-plus_light.svg
733
733
  - app/assets/images/mailer/calendar.png
734
+ - app/assets/images/mailer/call.png
735
+ - app/assets/images/mailer/email.png
734
736
  - app/assets/images/mailer/envelope.png
735
737
  - app/assets/images/mailer/event-mailer-bg.png
736
738
  - app/assets/images/mailer/facebook.png
@@ -742,6 +744,7 @@ files:
742
744
  - app/assets/images/mailer/tenant_phone.png
743
745
  - app/assets/images/mailer/tenant_user.png
744
746
  - app/assets/images/mailer/twitter.png
747
+ - app/assets/images/mailer/user-tenant.png
745
748
  - app/assets/images/mailer/user.png
746
749
  - app/assets/images/payment_methods/cm-payment-affirm.svg
747
750
  - app/assets/images/payment_methods/cm-payment-alipay.svg
@@ -957,6 +960,7 @@ files:
957
960
  - app/controllers/spree/api/v2/storefront/homepage_data_controller.rb
958
961
  - app/controllers/spree/api/v2/storefront/homepage_sections_controller.rb
959
962
  - app/controllers/spree/api/v2/storefront/id_cards_controller.rb
963
+ - app/controllers/spree/api/v2/storefront/intercity_taxi/distance_calculator_controller.rb
960
964
  - app/controllers/spree/api/v2/storefront/intercity_taxi/draft_orders_controller.rb
961
965
  - app/controllers/spree/api/v2/storefront/inventory_items_controller.rb
962
966
  - app/controllers/spree/api/v2/storefront/line_item_qrs_controller.rb
@@ -1020,6 +1024,7 @@ files:
1020
1024
  - app/controllers/spree/api/v2/tenant/guests_controller.rb
1021
1025
  - app/controllers/spree/api/v2/tenant/homepage_sections_controller.rb
1022
1026
  - app/controllers/spree/api/v2/tenant/id_cards_controller.rb
1027
+ - app/controllers/spree/api/v2/tenant/intercity_taxi/distance_calculator_controller.rb
1023
1028
  - app/controllers/spree/api/v2/tenant/intercity_taxi/draft_orders_controller.rb
1024
1029
  - app/controllers/spree/api/v2/tenant/line_items_controller.rb
1025
1030
  - app/controllers/spree/api/v2/tenant/notifications_controller.rb
@@ -1270,7 +1275,6 @@ files:
1270
1275
  - app/interactors/spree_cm_commissioner/transactional_email_sender.rb
1271
1276
  - app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb
1272
1277
  - app/interactors/spree_cm_commissioner/trip_clone_creator.rb
1273
- - app/interactors/spree_cm_commissioner/trip_distance_calculator.rb
1274
1278
  - app/interactors/spree_cm_commissioner/trip_stops_creator.rb
1275
1279
  - app/interactors/spree_cm_commissioner/unique_device_token_cron_executor.rb
1276
1280
  - app/interactors/spree_cm_commissioner/update_payment_gateway_status.rb
@@ -1293,7 +1297,7 @@ files:
1293
1297
  - app/interactors/spree_cm_commissioner/user_vendor_assigner.rb
1294
1298
  - app/interactors/spree_cm_commissioner/variant_block_updater.rb
1295
1299
  - app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb
1296
- - app/interactors/spree_cm_commissioner/vehicle_updater.rb
1300
+ - app/interactors/spree_cm_commissioner/vehicle_type_updater.rb
1297
1301
  - app/interactors/spree_cm_commissioner/vendor_creation_telegram_alert_sender.rb
1298
1302
  - app/interactors/spree_cm_commissioner/vendor_nearby_place_builder.rb
1299
1303
  - app/interactors/spree_cm_commissioner/vendor_updater.rb
@@ -1379,6 +1383,7 @@ files:
1379
1383
  - app/models/concerns/spree_cm_commissioner/line_item_durationable.rb
1380
1384
  - app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb
1381
1385
  - app/models/concerns/spree_cm_commissioner/line_item_integration.rb
1386
+ - app/models/concerns/spree_cm_commissioner/line_item_seat_selection.rb
1382
1387
  - app/models/concerns/spree_cm_commissioner/line_item_transitable.rb
1383
1388
  - app/models/concerns/spree_cm_commissioner/line_items_filter_scope.rb
1384
1389
  - app/models/concerns/spree_cm_commissioner/metafield.rb
@@ -1408,7 +1413,7 @@ files:
1408
1413
  - app/models/concerns/spree_cm_commissioner/user_notification.rb
1409
1414
  - app/models/concerns/spree_cm_commissioner/user_preference.rb
1410
1415
  - app/models/concerns/spree_cm_commissioner/variant_options_concern.rb
1411
- - app/models/concerns/spree_cm_commissioner/vehicle_type.rb
1416
+ - app/models/concerns/spree_cm_commissioner/vehicle_kind.rb
1412
1417
  - app/models/concerns/spree_cm_commissioner/vendor_preference.rb
1413
1418
  - app/models/concerns/spree_cm_commissioner/vendor_promotable.rb
1414
1419
  - app/models/concerns/spree_cm_commissioner/video_on_demand_bitwise.rb
@@ -1416,6 +1421,7 @@ files:
1416
1421
  - app/models/spree_cm_commissioner.rb
1417
1422
  - app/models/spree_cm_commissioner/ability_decorator.rb
1418
1423
  - app/models/spree_cm_commissioner/address_decorator.rb
1424
+ - app/models/spree_cm_commissioner/adjustable/adjuster/pricing_action.rb
1419
1425
  - app/models/spree_cm_commissioner/adjustment_decorator.rb
1420
1426
  - app/models/spree_cm_commissioner/asset.rb
1421
1427
  - app/models/spree_cm_commissioner/back_image.rb
@@ -1493,7 +1499,7 @@ files:
1493
1499
  - app/models/spree_cm_commissioner/oauth_application_decorator.rb
1494
1500
  - app/models/spree_cm_commissioner/option_type_decorator.rb
1495
1501
  - app/models/spree_cm_commissioner/option_value_decorator.rb
1496
- - app/models/spree_cm_commissioner/option_value_vehicle.rb
1502
+ - app/models/spree_cm_commissioner/option_value_vehicle_type.rb
1497
1503
  - app/models/spree_cm_commissioner/option_value_vendor.rb
1498
1504
  - app/models/spree_cm_commissioner/order/address_book_decorator.rb
1499
1505
  - app/models/spree_cm_commissioner/order_decorator.rb
@@ -1605,8 +1611,9 @@ files:
1605
1611
  - app/models/spree_cm_commissioner/variant_options.rb
1606
1612
  - app/models/spree_cm_commissioner/vector_icon.rb
1607
1613
  - app/models/spree_cm_commissioner/vehicle.rb
1608
- - app/models/spree_cm_commissioner/vehicle_option_type.rb
1609
1614
  - app/models/spree_cm_commissioner/vehicle_photo.rb
1615
+ - app/models/spree_cm_commissioner/vehicle_type.rb
1616
+ - app/models/spree_cm_commissioner/vehicle_type_option_type.rb
1610
1617
  - app/models/spree_cm_commissioner/vendor_app_promotion_banner.rb
1611
1618
  - app/models/spree_cm_commissioner/vendor_decorator.rb
1612
1619
  - app/models/spree_cm_commissioner/vendor_logo.rb
@@ -1922,6 +1929,7 @@ files:
1922
1929
  - app/serializers/spree_cm_commissioner/v2/storefront/calculator_serializer.rb
1923
1930
  - app/serializers/spree_cm_commissioner/v2/storefront/category_taxon_serializer.rb
1924
1931
  - app/serializers/spree_cm_commissioner/v2/storefront/check_in_serializer.rb
1932
+ - app/serializers/spree_cm_commissioner/v2/storefront/distance_serializer.rb
1925
1933
  - app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb
1926
1934
  - app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb
1927
1935
  - app/serializers/spree_cm_commissioner/v2/storefront/event_option_value_serializer.rb
@@ -1961,7 +1969,7 @@ files:
1961
1969
  - app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb
1962
1970
  - app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb
1963
1971
  - app/serializers/spree_cm_commissioner/v2/storefront/trip_variant_serializer.rb
1964
- - app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_serializer.rb
1972
+ - app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_type_serializer.rb
1965
1973
  - app/serializers/spree_cm_commissioner/v2/storefront/trip_vendor_serializer.rb
1966
1974
  - app/serializers/spree_cm_commissioner/v2/storefront/user_contact_serializer.rb
1967
1975
  - app/serializers/spree_cm_commissioner/v2/storefront/user_identity_provider_serializer.rb
@@ -1973,6 +1981,8 @@ files:
1973
1981
  - app/services/sms_adapter/plasgate.rb
1974
1982
  - app/services/sms_adapter/twillio.rb
1975
1983
  - app/services/spree_cm_commissioner/aes_encryption_service.rb
1984
+ - app/services/spree_cm_commissioner/api_caches/invalidate.rb
1985
+ - app/services/spree_cm_commissioner/calculate_distance.rb
1976
1986
  - app/services/spree_cm_commissioner/cart/add_guest.rb
1977
1987
  - app/services/spree_cm_commissioner/cart/destroy_decorator.rb
1978
1988
  - app/services/spree_cm_commissioner/cart/recalculate_decorator.rb
@@ -1999,6 +2009,7 @@ files:
1999
2009
  - app/services/spree_cm_commissioner/google_wallets/hotel_class_creator.rb
2000
2010
  - app/services/spree_cm_commissioner/google_wallets/hotel_class_updater.rb
2001
2011
  - app/services/spree_cm_commissioner/google_wallets/hotel_object_builder.rb
2012
+ - app/services/spree_cm_commissioner/guests/claim_invite_guest_service.rb
2002
2013
  - app/services/spree_cm_commissioner/homepage_data_loader.rb
2003
2014
  - app/services/spree_cm_commissioner/imports/base_import_order_service.rb
2004
2015
  - app/services/spree_cm_commissioner/imports/create_order_service.rb
@@ -2021,8 +2032,10 @@ files:
2021
2032
  - app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/full_sync_strategy.rb
2022
2033
  - app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/incremental_sync_strategy.rb
2023
2034
  - app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/webhook_sync_strategy.rb
2035
+ - app/services/spree_cm_commissioner/intercity_taxi_order/calculate_distance.rb
2024
2036
  - app/services/spree_cm_commissioner/intercity_taxi_order/create.rb
2025
2037
  - app/services/spree_cm_commissioner/intercity_taxi_order/update.rb
2038
+ - app/services/spree_cm_commissioner/line_items/apply_pricing_models.rb
2026
2039
  - app/services/spree_cm_commissioner/metafields/product_metadata_service.rb
2027
2040
  - app/services/spree_cm_commissioner/order_params_checker.rb
2028
2041
  - app/services/spree_cm_commissioner/orders/bulk_archive_inactive_orders.rb
@@ -2049,9 +2062,13 @@ files:
2049
2062
  - app/services/spree_cm_commissioner/seats/bulk_release_on_hold_blocks.rb
2050
2063
  - app/services/spree_cm_commissioner/seats/release_expired_blocks.rb
2051
2064
  - app/services/spree_cm_commissioner/seeds/roles_decorator.rb
2065
+ - app/services/spree_cm_commissioner/signing/sign_data.rb
2066
+ - app/services/spree_cm_commissioner/signing/verify_signature.rb
2052
2067
  - app/services/spree_cm_commissioner/telegram_alerts/integration_sync_failure.rb
2068
+ - app/services/spree_cm_commissioner/transit/export_order.rb
2053
2069
  - app/services/spree_cm_commissioner/transit/legs_builder_service.rb
2054
2070
  - app/services/spree_cm_commissioner/trips/search.rb
2071
+ - app/services/spree_cm_commissioner/update_guest_service.rb
2055
2072
  - app/services/spree_cm_commissioner/user_authenticator.rb
2056
2073
  - app/services/spree_cm_commissioner/user_roles_assigner.rb
2057
2074
  - app/services/spree_cm_commissioner/users/incomplete_guest_checker_service.rb
@@ -2410,6 +2427,7 @@ files:
2410
2427
  - app/views/spree/layouts/event.html.erb
2411
2428
  - app/views/spree/layouts/transit.html.erb
2412
2429
  - app/views/spree/order_mailer/_adjustment.html.erb
2430
+ - app/views/spree/order_mailer/cancel_email.html.erb
2413
2431
  - app/views/spree/order_mailer/confirm_email.html.erb
2414
2432
  - app/views/spree/order_mailer/ticket_email.html.erb
2415
2433
  - app/views/spree/order_mailer/ticket_email.text.erb
@@ -2488,6 +2506,13 @@ files:
2488
2506
  - app/views/spree/transit/vendors/_form.html.erb
2489
2507
  - app/views/spree/transit/vendors/_tabs.html.erb
2490
2508
  - app/views/spree/transit/vendors/edit.html.erb
2509
+ - app/views/spree_cm_commissioner/cancel_order_mailer/_cancel_email.html.erb
2510
+ - app/views/spree_cm_commissioner/cancel_order_mailer/_footer.html.erb
2511
+ - app/views/spree_cm_commissioner/cancel_order_mailer/_header.html.erb
2512
+ - app/views/spree_cm_commissioner/cancel_order_mailer/_mailer_stylesheets.html.erb
2513
+ - app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_cancel_email.html.erb
2514
+ - app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_footer.html.erb
2515
+ - app/views/spree_cm_commissioner/cancel_order_mailer/tenant/_header.html.erb
2491
2516
  - app/views/spree_cm_commissioner/crew_invite_mailer/_mailer_stylesheets.html.erb
2492
2517
  - app/views/spree_cm_commissioner/crew_invite_mailer/send_crew_invite_email.html.erb
2493
2518
  - app/views/spree_cm_commissioner/event_transactional_mailer/_event_banner.html.erb
@@ -2501,6 +2526,7 @@ files:
2501
2526
  - app/views/spree_cm_commissioner/guest_mailer/_mailer_stylesheets.html.erb
2502
2527
  - app/views/spree_cm_commissioner/guest_mailer/_terms_and_conditions.html.erb
2503
2528
  - app/views/spree_cm_commissioner/guest_mailer/send_ticket_to_guest.html.erb
2529
+ - app/views/spree_cm_commissioner/layouts/cancel_order_mailer.html.erb
2504
2530
  - app/views/spree_cm_commissioner/layouts/crew_invite_mailer.html.erb
2505
2531
  - app/views/spree_cm_commissioner/layouts/event_transactional_mailer.html.erb
2506
2532
  - app/views/spree_cm_commissioner/layouts/guest_mailer.html.erb
@@ -2950,7 +2976,11 @@ files:
2950
2976
  - db/migrate/20251017101605_create_cm_integration_mappings.rb
2951
2977
  - db/migrate/20251113081853_add_index_to_spree_orders_updated_at.rb
2952
2978
  - db/migrate/20251119093000_add_tenant_id_to_cm_vendor_places.rb
2979
+ - db/migrate/20251127074809_change_guest_dynamic_fields_value_from_jsonb_to_text.rb
2953
2980
  - db/migrate/20251209022924_add_contact_fields_to_cm_tenants.rb
2981
+ - db/migrate/20251219035243_add_migrations_to_support_vehicle_types.rb
2982
+ - db/migrate/20260105072146_add_nationality_group_and_age_group_to_cm_saved_guests.rb
2983
+ - db/migrate/20260106093359_add_contact_phone_to_cm_vendor_places.rb
2954
2984
  - docker-compose.yml
2955
2985
  - docs/api/scoped-access-token-endpoints.md
2956
2986
  - docs/option_types/attr_types.md
@@ -2973,9 +3003,9 @@ files:
2973
3003
  - lib/spree_cm_commissioner.rb
2974
3004
  - lib/spree_cm_commissioner/cached_inventory_item.rb
2975
3005
  - lib/spree_cm_commissioner/calendar_event.rb
3006
+ - lib/spree_cm_commissioner/distance.rb
2976
3007
  - lib/spree_cm_commissioner/engine.rb
2977
3008
  - lib/spree_cm_commissioner/factories.rb
2978
- - lib/spree_cm_commissioner/intercity_taxi/distance.rb
2979
3009
  - lib/spree_cm_commissioner/intercity_taxi/map_place.rb
2980
3010
  - lib/spree_cm_commissioner/jwt_token.rb
2981
3011
  - lib/spree_cm_commissioner/line_item_jwt_token.rb
@@ -3030,6 +3060,7 @@ files:
3030
3060
  - lib/spree_cm_commissioner/test_helper/factories/place_factory.rb
3031
3061
  - lib/spree_cm_commissioner/test_helper/factories/pricing_action_factory.rb
3032
3062
  - lib/spree_cm_commissioner/test_helper/factories/pricing_model_factory.rb
3063
+ - lib/spree_cm_commissioner/test_helper/factories/pricing_model_variant_factory.rb
3033
3064
  - lib/spree_cm_commissioner/test_helper/factories/pricing_rule_factory.rb
3034
3065
  - lib/spree_cm_commissioner/test_helper/factories/pricing_rule_group_factory.rb
3035
3066
  - lib/spree_cm_commissioner/test_helper/factories/product_completion_step_banner_factory.rb
@@ -3066,11 +3097,11 @@ files:
3066
3097
  - lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb
3067
3098
  - lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb
3068
3099
  - lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb
3100
+ - lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb
3069
3101
  - lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb
3070
3102
  - lib/spree_cm_commissioner/test_helper/factories/vendor_logo_factory.rb
3071
3103
  - lib/spree_cm_commissioner/test_helper/factories/vendor_photo_factory.rb
3072
3104
  - lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb
3073
- - lib/spree_cm_commissioner/test_helper/factories/vendor_route_factory.rb
3074
3105
  - lib/spree_cm_commissioner/test_helper/factories/video_on_demand_factory.rb
3075
3106
  - lib/spree_cm_commissioner/test_helper/factories/webhook_subscriber_factory.rb
3076
3107
  - lib/spree_cm_commissioner/test_helper/factories/webhook_subscriber_rule_factory.rb
@@ -3124,9 +3155,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
3124
3155
  version: '2.7'
3125
3156
  required_rubygems_version: !ruby/object:Gem::Requirement
3126
3157
  requirements:
3127
- - - ">"
3158
+ - - ">="
3128
3159
  - !ruby/object:Gem::Version
3129
- version: 1.3.1
3160
+ version: '0'
3130
3161
  requirements:
3131
3162
  - none
3132
3163
  rubygems_version: 3.4.1
@@ -1,165 +0,0 @@
1
- module SpreeCmCommissioner
2
- # Computes trip distance details and pricing payload.
3
- #
4
- # Inputs via context:
5
- # - origin: { lat:, lng: }
6
- # - configured_destination: { lat:, lng: }
7
- # - pickups: Array<{ lat:, lng: }> (optional)
8
- # - dropoffs: Array<{ lat:, lng: }> (optional)
9
- # - pickup_oob_confirmed: Boolean (optional)
10
- # - dropoff_oob_confirmed: Boolean (optional)
11
- # - base_price_usd: Numeric
12
- # - boundary_km: Numeric (optional, default 0)
13
- #
14
- # Outputs via context on success:
15
- # - payload: Hash (compatible with previous controller response)
16
- # - base_km, detour_pickup_km, detour_dropoff_km: Floats or nil
17
- # - distance_km, directions_url, ordered_points, estimated_time_minutes (when optimize true)
18
- class TripDistanceCalculator < BaseInteractor
19
- delegate :origin,
20
- :configured_destination,
21
- :pickups,
22
- :dropoffs,
23
- :pickup_oob_confirmed,
24
- :dropoff_oob_confirmed,
25
- :base_price_usd,
26
- :boundary_km,
27
- to: :context
28
-
29
- def call
30
- validate_inputs
31
-
32
- pickups_points, dropoffs_points, final_destination = prepare_points
33
- base_km, detour_pickup_km, detour_dropoff_km = compute_route_kms(pickups_points, dropoffs_points, final_destination)
34
- details_ctx = fetch_details(final_destination, pickups_points, dropoffs_points)
35
- extra_data = compute_extra_data(base_km, detour_pickup_km, detour_dropoff_km)
36
- payload = build_payload(details_ctx, base_km, detour_pickup_km, detour_dropoff_km, extra_data)
37
- assign_context(details_ctx, base_km, detour_pickup_km, detour_dropoff_km, payload)
38
- end
39
-
40
- private
41
-
42
- def validate_inputs
43
- context.fail!(message: 'origin is required') if origin.blank?
44
- context.fail!(message: 'configured_destination is required') if configured_destination.blank?
45
- end
46
-
47
- def compute_km(origin:, destination:, pickups: nil, dropoffs: nil, optimize: nil)
48
- ctx = SpreeCmCommissioner::GoogleRoutesDistanceCalculator.call(
49
- origin: origin,
50
- destination: destination,
51
- pickups: pickups,
52
- dropoffs: dropoffs,
53
- optimize: optimize
54
- )
55
- return nil unless ctx.success?
56
-
57
- ctx.distance_km
58
- end
59
-
60
- def prepare_points
61
- pickups_points = Array(pickups).compact
62
- dropoffs_points = Array(dropoffs).compact
63
- final_destination = dropoffs_points.last || configured_destination
64
- [pickups_points, dropoffs_points, final_destination]
65
- end
66
-
67
- def compute_route_kms(pickups_points, dropoffs_points, final_destination)
68
- base_km = compute_km(origin: origin, destination: configured_destination)
69
- detour_pickup_km =
70
- if pickups_points.any?
71
- compute_km(
72
- origin: origin,
73
- destination: configured_destination,
74
- pickups: pickups_points,
75
- optimize: false
76
- )
77
- end
78
- detour_dropoff_km =
79
- if dropoffs_points.any?
80
- compute_km(
81
- origin: origin,
82
- destination: final_destination,
83
- dropoffs: dropoffs_points,
84
- optimize: false
85
- )
86
- end
87
- [base_km, detour_pickup_km, detour_dropoff_km]
88
- end
89
-
90
- def fetch_details(final_destination, pickups_points, dropoffs_points)
91
- ctx = SpreeCmCommissioner::GoogleRoutesDistanceCalculator.call(
92
- origin: origin,
93
- destination: final_destination,
94
- pickups: pickups_points,
95
- dropoffs: dropoffs_points,
96
- optimize: true
97
- )
98
- context.fail!(message: ctx.message || 'Unable to calculate') unless ctx.success?
99
- ctx
100
- end
101
-
102
- def compute_extra_data(base_km, detour_pickup_km, detour_dropoff_km)
103
- extra_pickup_km = compute_extra_km(detour_pickup_km, base_km, pickup_oob_confirmed)
104
- extra_dropoff_km = compute_extra_km(detour_dropoff_km, base_km, dropoff_oob_confirmed)
105
- extra_pickup_charge_usd = charge_for_extra_km(extra_pickup_km)
106
- extra_dropoff_charge_usd = charge_for_extra_km(extra_dropoff_km)
107
- extra_charge_usd = (extra_pickup_charge_usd + extra_dropoff_charge_usd).round(2)
108
- total_price_usd = (base_price_usd.to_f + extra_charge_usd).round(2)
109
-
110
- {
111
- extra_pickup_km: extra_pickup_km,
112
- extra_dropoff_km: extra_dropoff_km,
113
- extra_pickup_charge_usd: extra_pickup_charge_usd,
114
- extra_dropoff_charge_usd: extra_dropoff_charge_usd,
115
- total_price_usd: total_price_usd
116
- }
117
- end
118
-
119
- def build_payload(details_ctx, base_km, detour_pickup_km, detour_dropoff_km, data)
120
- {
121
- distance_km: details_ctx.distance_km,
122
- directions_url: details_ctx.directions_url,
123
- ordered_points: details_ctx.ordered_points,
124
- estimated_time_minutes: details_ctx.estimated_time_minutes,
125
- base_price_usd: base_price_usd.to_f,
126
- total_price_usd: data[:total_price_usd],
127
- extra_pickup_km: data[:extra_pickup_km],
128
- extra_dropoff_km: data[:extra_dropoff_km],
129
- extra_pickup_charge_usd: data[:extra_pickup_charge_usd],
130
- extra_dropoff_charge_usd: data[:extra_dropoff_charge_usd],
131
- extra_charge_usd: data[:extra_charge_usd],
132
- base_km: base_km,
133
- detour_pickup_km: detour_pickup_km,
134
- detour_dropoff_km: detour_dropoff_km
135
- }
136
- end
137
-
138
- def assign_context(details_ctx, base_km, detour_pickup_km, detour_dropoff_km, payload)
139
- context.payload = payload
140
- context.distance_km = details_ctx.distance_km
141
- context.directions_url = details_ctx.directions_url
142
- context.ordered_points = details_ctx.ordered_points
143
- context.estimated_time_minutes = details_ctx.estimated_time_minutes
144
- context.base_km = base_km
145
- context.detour_pickup_km = detour_pickup_km
146
- context.detour_dropoff_km = detour_dropoff_km
147
- end
148
-
149
- def compute_extra_km(detour_km, base_km, confirmed)
150
- return 0.0 unless confirmed && detour_km && base_km
151
-
152
- [(detour_km - base_km - boundary_km), 0.0].max
153
- end
154
-
155
- def charge_for_extra_km(extra_km)
156
- x = extra_km.to_f
157
- return 0.0 if x <= 0
158
- return 2.0 if x <= 5.0
159
- return 5.0 if x <= 10.0
160
- return 10.0 if x <= 20.0
161
-
162
- (10.0 + ((x - 20.0) * 0.5)).round(2)
163
- end
164
- end
165
- end