spree_cm_commissioner 2.8.1.pre.3 → 2.8.2.pre.pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +1 -0
  3. data/Gemfile.lock +1 -1
  4. data/app/controllers/spree/api/v2/storefront/trip_search_controller.rb +0 -1
  5. data/app/controllers/spree/api/v2/tenant/show_contestants_controller.rb +1 -0
  6. data/app/controllers/spree/api/v2/tenant/show_elimination_sessions_controller.rb +57 -0
  7. data/app/factory/spree_cm_commissioner/event_telegram_message_factory.rb +68 -0
  8. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +2 -2
  9. data/app/jobs/spree_cm_commissioner/event_creation_telegram_alert_sender_job.rb +10 -0
  10. data/app/jobs/spree_cm_commissioner/oauth_access_tokens/cleanup_expired_job.rb +11 -0
  11. data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +8 -0
  12. data/app/models/concerns/spree_cm_commissioner/service_origin.rb +22 -0
  13. data/app/models/concerns/spree_cm_commissioner/store_preference.rb +1 -0
  14. data/app/models/concerns/spree_cm_commissioner/vehicle_kind.rb +1 -1
  15. data/app/models/spree_cm_commissioner/integration.rb +0 -31
  16. data/app/models/spree_cm_commissioner/integrations/stadium_x_v1.rb +10 -4
  17. data/app/models/spree_cm_commissioner/inventory_item.rb +17 -8
  18. data/app/models/spree_cm_commissioner/maintenance_tasks/cache_invalidation.rb +2 -0
  19. data/app/models/spree_cm_commissioner/maintenance_tasks/voting_session.rb +2 -0
  20. data/app/models/spree_cm_commissioner/order_decorator.rb +0 -1
  21. data/app/models/spree_cm_commissioner/place.rb +0 -2
  22. data/app/models/spree_cm_commissioner/route.rb +6 -2
  23. data/app/models/spree_cm_commissioner/seat_layout.rb +0 -2
  24. data/app/models/spree_cm_commissioner/show.rb +3 -1
  25. data/app/models/spree_cm_commissioner/show_contestant.rb +5 -0
  26. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +0 -7
  27. data/app/models/spree_cm_commissioner/taxon_decorator.rb +7 -0
  28. data/app/models/spree_cm_commissioner/trip.rb +6 -2
  29. data/app/models/spree_cm_commissioner/trip_stop.rb +0 -2
  30. data/app/models/spree_cm_commissioner/variant_decorator.rb +0 -1
  31. data/app/models/spree_cm_commissioner/vehicle.rb +0 -3
  32. data/app/models/spree_cm_commissioner/vehicle_type.rb +0 -1
  33. data/app/models/spree_cm_commissioner/vendor_decorator.rb +0 -17
  34. data/app/models/spree_cm_commissioner/vendor_place.rb +0 -2
  35. data/app/models/spree_cm_commissioner/voting_contestant.rb +13 -1
  36. data/app/models/spree_cm_commissioner/voting_session.rb +38 -9
  37. data/app/models/spree_cm_commissioner/voting_session_stat.rb +8 -0
  38. data/app/overrides/spree/admin/stores/_form/store_preferences.html.erb.deface +9 -0
  39. data/app/queries/spree_cm_commissioner/multi_leg_trips_query.rb +26 -44
  40. data/app/queries/spree_cm_commissioner/single_leg_trips_query.rb +36 -31
  41. data/app/queries/spree_cm_commissioner/trip_query.rb +2 -4
  42. data/app/serializers/spree/v2/tenant/show_contestant_serializer.rb +1 -1
  43. data/app/serializers/spree/v2/tenant/voting_contestant_serializer.rb +5 -1
  44. data/app/serializers/spree/v2/tenant/voting_session_serializer.rb +4 -1
  45. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +7 -2
  46. data/app/services/spree_cm_commissioner/integrations/base/sync_manager.rb +2 -1
  47. data/app/services/spree_cm_commissioner/integrations/base/sync_result.rb +0 -11
  48. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/external_client/client.rb +15 -14
  49. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb +4 -7
  50. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_zones.rb +3 -6
  51. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_manager.rb +3 -0
  52. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/full_sync_strategy.rb +3 -1
  53. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/incremental_sync_strategy.rb +3 -1
  54. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/webhook_sync_strategy.rb +2 -1
  55. data/app/services/spree_cm_commissioner/oauth_access_tokens/cleanup_expired.rb +53 -0
  56. data/app/services/spree_cm_commissioner/order_holds/hold.rb +0 -17
  57. data/app/services/spree_cm_commissioner/order_holds/release.rb +0 -17
  58. data/app/services/spree_cm_commissioner/pricing_models/preview.rb +15 -6
  59. data/app/services/spree_cm_commissioner/routes/create.rb +0 -5
  60. data/app/services/spree_cm_commissioner/show_contestants/normalize_video_highlights.rb +2 -1
  61. data/app/services/spree_cm_commissioner/telegram_alerts/event_creation.rb +35 -0
  62. data/app/services/spree_cm_commissioner/trips/create_multi_leg.rb +5 -16
  63. data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +0 -1
  64. data/app/services/spree_cm_commissioner/url_embed/youtube_embed.rb +30 -35
  65. data/app/services/spree_cm_commissioner/vote_counters/per_contestant_counter.rb +2 -0
  66. data/app/services/spree_cm_commissioner/vote_counters/snapshot_to_db.rb +113 -0
  67. data/app/services/spree_cm_commissioner/voting_contestants/bulk_updater.rb +3 -1
  68. data/app/services/spree_cm_commissioner/voting_leaderboards/calculate_score.rb +74 -0
  69. data/app/services/spree_cm_commissioner/voting_sessions/finalize.rb +66 -0
  70. data/app/views/spree/admin/integrations/_form.html.erb +0 -12
  71. data/app/views/spree/admin/integrations/index.html.erb +1 -1
  72. data/config/initializers/spree_permitted_attributes.rb +1 -0
  73. data/config/locales/en.yml +2 -1
  74. data/config/locales/km.yml +4 -1
  75. data/config/routes.rb +1 -1
  76. data/db/migrate/20260518090920_add_unique_voter_count_to_voting_contestants.rb +5 -0
  77. data/db/migrate/20260518094322_create_cm_voting_session_stats.rb +17 -0
  78. data/db/migrate/20260520000001_add_scoring_model_to_cm_voting_sessions.rb +5 -0
  79. data/db/migrate/20260525042257_add_vote_number_to_cm_voting_contestants.rb +18 -0
  80. data/db/migrate/20260527035430_add_confirmed_rank_to_cm_voting_contestants.rb +5 -0
  81. data/db/migrate/20260527062005_add_eliminated_at_to_cm_show_contestants.rb +5 -0
  82. data/lib/spree_cm_commissioner/test_helper/factories/integration_factory.rb +0 -11
  83. data/lib/spree_cm_commissioner/test_helper/factories/show_factory.rb +24 -0
  84. data/lib/spree_cm_commissioner/trip_result.rb +48 -21
  85. data/lib/spree_cm_commissioner/version.rb +1 -1
  86. data/spree_cm_commissioner.gemspec +1 -1
  87. metadata +20 -118
  88. data/app/controllers/spree/api/v2/storefront/transit/item_availabilities_controller.rb +0 -66
  89. data/app/jobs/spree_cm_commissioner/audit_event_job.rb +0 -29
  90. data/app/jobs/spree_cm_commissioner/cleanup_expired_access_tokens_job.rb +0 -9
  91. data/app/models/concerns/spree_cm_commissioner/audit_wrapper.rb +0 -139
  92. data/app/models/concerns/spree_cm_commissioner/integrations/inventory_sync_cachable.rb +0 -9
  93. data/app/models/concerns/spree_cm_commissioner/variant_metadata.rb +0 -24
  94. data/app/models/spree_cm_commissioner/audit_event.rb +0 -11
  95. data/app/models/spree_cm_commissioner/currency_rate.rb +0 -15
  96. data/app/models/spree_cm_commissioner/integrations/book_me_bus_v1.rb +0 -56
  97. data/app/models/spree_cm_commissioner/integrations/larryta.rb +0 -81
  98. data/app/models/spree_cm_commissioner/integrations/vireak_buntham.rb +0 -82
  99. data/app/serializables/spree_cm_commissioner/item_availability_sync.rb +0 -10
  100. data/app/serializers/spree_cm_commissioner/v2/storefront/item_availability_sync_serializer.rb +0 -10
  101. data/app/services/spree_cm_commissioner/audit_logger.rb +0 -59
  102. data/app/services/spree_cm_commissioner/cleanup_expired_access_tokens.rb +0 -52
  103. data/app/services/spree_cm_commissioner/currency_converter/create.rb +0 -27
  104. data/app/services/spree_cm_commissioner/currency_rates/manage.rb +0 -99
  105. data/app/services/spree_cm_commissioner/google_maps_geocoder.rb +0 -41
  106. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/external_client/client.rb +0 -261
  107. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/external_client/connection.rb +0 -147
  108. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/inventory/external_inventory_item_status.rb +0 -52
  109. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/inventory/external_inventory_items.rb +0 -91
  110. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/inventory/unstock_inventory.rb +0 -140
  111. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_inventory.rb +0 -52
  112. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_item_availability.rb +0 -249
  113. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_locations.rb +0 -103
  114. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_product.rb +0 -66
  115. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_route_stops.rb +0 -113
  116. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_routes.rb +0 -128
  117. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_seat_layout.rb +0 -342
  118. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_service_calendars.rb +0 -59
  119. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_trip_stop.rb +0 -179
  120. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_trips.rb +0 -597
  121. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_variant.rb +0 -58
  122. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/sync_vehicle_types.rb +0 -87
  123. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/polling/time_parser.rb +0 -19
  124. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/base.rb +0 -40
  125. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/branch.rb +0 -65
  126. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/direction.rb +0 -51
  127. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/inventory_item_status.rb +0 -148
  128. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/location.rb +0 -55
  129. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/operator.rb +0 -17
  130. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/reservation_cart.rb +0 -85
  131. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/seat.rb +0 -128
  132. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/seat_layout.rb +0 -363
  133. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/stop.rb +0 -84
  134. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/trip.rb +0 -199
  135. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/resources/wallet_payment.rb +0 -40
  136. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/sync_manager.rb +0 -22
  137. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/sync_strategies/full_sync_strategy.rb +0 -117
  138. data/app/services/spree_cm_commissioner/integrations/book_me_bus_v1/sync_strategies/incremental_sync_strategy.rb +0 -64
  139. data/app/services/spree_cm_commissioner/integrations/larryta/external_client/client.rb +0 -344
  140. data/app/services/spree_cm_commissioner/integrations/larryta/external_client/connection.rb +0 -74
  141. data/app/services/spree_cm_commissioner/integrations/larryta/inventory/external_inventory_item_status.rb +0 -53
  142. data/app/services/spree_cm_commissioner/integrations/larryta/inventory/external_inventory_items.rb +0 -106
  143. data/app/services/spree_cm_commissioner/integrations/larryta/inventory/hold_seats.rb +0 -143
  144. data/app/services/spree_cm_commissioner/integrations/larryta/inventory/release_seats.rb +0 -90
  145. data/app/services/spree_cm_commissioner/integrations/larryta/inventory/unstock_inventory.rb +0 -113
  146. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_item_availability.rb +0 -261
  147. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_product.rb +0 -72
  148. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_routes.rb +0 -142
  149. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_seat_layout.rb +0 -255
  150. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_stock_item.rb +0 -55
  151. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_trip_stop.rb +0 -167
  152. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_trips.rb +0 -320
  153. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_variant.rb +0 -63
  154. data/app/services/spree_cm_commissioner/integrations/larryta/polling/sync_vehicle_type.rb +0 -79
  155. data/app/services/spree_cm_commissioner/integrations/larryta/resources/base.rb +0 -39
  156. data/app/services/spree_cm_commissioner/integrations/larryta/resources/booking.rb +0 -113
  157. data/app/services/spree_cm_commissioner/integrations/larryta/resources/booking_session.rb +0 -43
  158. data/app/services/spree_cm_commissioner/integrations/larryta/resources/booking_transaction.rb +0 -236
  159. data/app/services/spree_cm_commissioner/integrations/larryta/resources/direction.rb +0 -71
  160. data/app/services/spree_cm_commissioner/integrations/larryta/resources/passenger.rb +0 -48
  161. data/app/services/spree_cm_commissioner/integrations/larryta/resources/schedule.rb +0 -150
  162. data/app/services/spree_cm_commissioner/integrations/larryta/resources/seat.rb +0 -31
  163. data/app/services/spree_cm_commissioner/integrations/larryta/resources/seat_availability.rb +0 -49
  164. data/app/services/spree_cm_commissioner/integrations/larryta/resources/seat_layout.rb +0 -211
  165. data/app/services/spree_cm_commissioner/integrations/larryta/sync_manager.rb +0 -17
  166. data/app/services/spree_cm_commissioner/integrations/larryta/sync_strategies/full_sync_strategy.rb +0 -79
  167. data/app/services/spree_cm_commissioner/integrations/larryta/sync_strategies/incremental_sync_strategy.rb +0 -58
  168. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/external_client/client.rb +0 -206
  169. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/external_client/connection.rb +0 -59
  170. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/inventory/external_inventory_item_status.rb +0 -48
  171. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/inventory/external_inventory_items.rb +0 -97
  172. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/inventory/unstock_inventory.rb +0 -208
  173. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_item_availability.rb +0 -270
  174. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_locations.rb +0 -96
  175. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_nationality_pricing.rb +0 -76
  176. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_product.rb +0 -69
  177. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_routes.rb +0 -110
  178. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_seat_layout.rb +0 -207
  179. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_stock_item.rb +0 -43
  180. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_trip_stop.rb +0 -185
  181. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_trips.rb +0 -300
  182. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_variant.rb +0 -56
  183. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/polling/sync_vehicle_type.rb +0 -51
  184. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/base.rb +0 -32
  185. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/booking.rb +0 -48
  186. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/booking_transaction.rb +0 -46
  187. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/cell.rb +0 -53
  188. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/confirm_booking_request.rb +0 -43
  189. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/location.rb +0 -37
  190. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/schedule.rb +0 -138
  191. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/seat.rb +0 -48
  192. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/resources/seat_layout.rb +0 -79
  193. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/sync_manager.rb +0 -17
  194. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/sync_strategies/full_sync_strategy.rb +0 -87
  195. data/app/services/spree_cm_commissioner/integrations/vireak_buntham/sync_strategies/incremental_sync_strategy.rb +0 -53
  196. data/app/services/spree_cm_commissioner/inventory_items/generate_permanent_item.rb +0 -48
  197. data/app/services/spree_cm_commissioner/place_resolver.rb +0 -95
  198. data/app/views/spree/admin/integrations/_book_me_bus_v1_fields.html.erb +0 -47
  199. data/app/views/spree/admin/integrations/_larryta_fields.html.erb +0 -58
  200. data/app/views/spree/admin/integrations/_vireak_buntham_fields.html.erb +0 -75
  201. data/db/migrate/20260327143200_create_cm_audit_events.rb +0 -21
  202. data/db/migrate/20260410045815_create_cm_currency_rates.rb +0 -23
  203. data/db/migrate/20260411102139_add_metadata_to_cm_inventory_items.rb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8250d9a96dcceb058991c416ad4b91380fa42f5d43e301c366e74bfe9eb0e27b
4
- data.tar.gz: a8c9301047c15f6ef760bdda1cc9087ac4f7a3539cd6aa86b43a99ab97fc6f16
3
+ metadata.gz: 595e82de2ef3a0ab170476a3ad96ab5d25d3d501916fa7b740d4d3d50f11193f
4
+ data.tar.gz: fb43eb4f67c1dc65ea1833f90f51624595122a6555c5099ac153a6abf20a1d3b
5
5
  SHA512:
6
- metadata.gz: 87bba18fe41a801abf62fc7a83c444452f5b3780b23edaa44bbf86b98271b06877bc8c52bddfc5761b5fdee5953226201c52556cfba30405c1e1f95af2067861
7
- data.tar.gz: 2a7fd81827d6be81291146d17f46ff54a61a59aa4194a552f89ccc59463dc93a4ccc742c0534fd5c18354136314b2e9db571e97b6e8822fff3bbc6c116f3114d
6
+ metadata.gz: a63ca4741ece801cadde290f28f810bcc7143a320201af0d1a074b2a9ae380b7307807d06eac856d01d062eb27b149efaf9e70e87c6853008d2bf667d852d3d1
7
+ data.tar.gz: d6cbf032196337ad97649cc72a4f2d1a7a0426224498cd0e2df492e4251a67ed00a7876e9719a66296b8ff9f168be7fa4c991e91a7d318f71eeab08802ae377f
data/.env.example CHANGED
@@ -34,6 +34,7 @@ DISTANCE_SIGNING_KEY=hei********************VY
34
34
 
35
35
  # Cache durations (in seconds) for different content types
36
36
  # See: app/controllers/concerns/spree_cm_commissioner/content_cachable.rb
37
+ CACHE_AUTO_INVALIDATION_DISABLED="" # Set to yes to disable CDN cache invalidation entirely (kill switch)
37
38
  CACHE_CDN_MAX_AGE=86400 # CDN/server-side cache duration for all responses
38
39
  CACHE_STATIC_MAX_AGE=86400 # Static content (countries, provinces, seat layouts, CMS pages) - 1 day
39
40
  CACHE_SEMI_STATIC_MAX_AGE=3600 # Semi-static content (menus, homepage backgrounds, routes) - 1 hour
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (2.8.1.pre.3)
37
+ spree_cm_commissioner (2.8.2.pre.pre.1)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -39,7 +39,6 @@ module Spree
39
39
  params[:date],
40
40
  params[:route_type],
41
41
  params[:vendor_id],
42
- params[:featured],
43
42
  params[:number_of_guests],
44
43
  resource_includes&.sort&.join(','),
45
44
  sparse_fields&.sort&.join(','),
@@ -18,6 +18,7 @@ module Spree
18
18
  .where(show_id: current_show.id)
19
19
  .includes(
20
20
  :show_contestant_images,
21
+ :show_contestant_videos,
21
22
  :current_voting_session,
22
23
  :voting_contestants,
23
24
  assigned_show_person: :show_person_images,
@@ -0,0 +1,57 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class ShowEliminationSessionsController < BaseController
6
+ # override
7
+ def collection
8
+ @collection ||= scope
9
+ .includes(
10
+ :episode,
11
+ :show,
12
+ eliminated_voting_contestants: [
13
+ :show_contestant,
14
+ { show_contestant: %i[show_contestant_images show_contestant_videos] }
15
+ ]
16
+ )
17
+ .order('cm_voting_sessions.closes_at DESC')
18
+ end
19
+
20
+ # override
21
+ def collection_serializer
22
+ Spree::V2::Tenant::VotingSessionSerializer
23
+ end
24
+
25
+ private
26
+
27
+ # override
28
+ def model_class
29
+ SpreeCmCommissioner::VotingSession
30
+ end
31
+
32
+ # override
33
+ def scope
34
+ return model_class.none unless current_show
35
+
36
+ current_show.voting_sessions
37
+ .joins(:episode)
38
+ .joins(:voting_contestants)
39
+ .where(voting_contestants: { eliminated: true })
40
+ .distinct
41
+ end
42
+
43
+ def current_show
44
+ @current_show ||= show_scope.find_by!(slug: params[:show_id])
45
+ end
46
+
47
+ def show_scope
48
+ vendor_ids = @tenant.vendors.select(:id)
49
+ return SpreeCmCommissioner::Show.none if vendor_ids.blank?
50
+
51
+ SpreeCmCommissioner::Show.where(vendor_id: vendor_ids)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,68 @@
1
+ # 🎉 ---[Event]---
2
+ #
3
+ # 📋 Event: {{event.name}}
4
+ #
5
+ # 👤 Organizer: {{vendor.name}}
6
+ #
7
+ # 🗓️ Start Date: {{from_date}}
8
+ # 🗓️ End Date: {{to_date}}
9
+ # 🔗 URL: ......
10
+ #
11
+ module SpreeCmCommissioner
12
+ class EventTelegramMessageFactory < TelegramMessageFactory
13
+ attr_reader :event
14
+
15
+ def initialize(event:)
16
+ @event = event
17
+
18
+ title = "✨ #{event.name} ✨"
19
+
20
+ super(title: title)
21
+ end
22
+
23
+ def body
24
+ [
25
+ event_name_line,
26
+ organizer_line,
27
+ [start_date_line, end_date_line].compact.join("\n"),
28
+ event_url_line
29
+ ].compact_blank.join("\n\n")
30
+ end
31
+
32
+ private
33
+
34
+ def event_name_line
35
+ "📋 Event: #{event.name}" if event.name.present?
36
+ end
37
+
38
+ def organizer_line
39
+ return if event.vendor&.name.blank?
40
+
41
+ "👤 Organizer: #{bold(event.vendor.name)}"
42
+ end
43
+
44
+ def start_date_line
45
+ return if event.from_date.blank?
46
+
47
+ "🗓️ Start Date: #{pretty_datetime(event.from_date)}"
48
+ end
49
+
50
+ def end_date_line
51
+ return if event.to_date.blank?
52
+
53
+ "🗓️ End Date: #{pretty_datetime(event.to_date)}"
54
+ end
55
+
56
+ def pretty_datetime(date)
57
+ return '' if date.blank?
58
+
59
+ date.strftime('%b %d, %Y · %H:%M')
60
+ end
61
+
62
+ def event_url_line
63
+ return if event.event_url.blank?
64
+
65
+ "🔗 URL: #{event.event_url}"
66
+ end
67
+ end
68
+ end
@@ -15,8 +15,8 @@ module SpreeCmCommissioner
15
15
  .joins(:inventory_items)
16
16
  .where(vendor_id: vendor_id)
17
17
  .where(inventory_items: { inventory_date: stay_dates })
18
- .where('CAST(spree_variants.public_metadata->\'cm_options\'->>\'number-of-adults\' AS INTEGER) +
19
- CAST(spree_variants.public_metadata->\'cm_options\'->>\'number-of-kids\' AS INTEGER) >= ?', number_of_guests
18
+ .where('CAST(public_metadata->\'cm_options\'->>\'number-of-adults\' AS INTEGER) +
19
+ CAST(public_metadata->\'cm_options\'->>\'number-of-kids\' AS INTEGER) >= ?', number_of_guests
20
20
  )
21
21
  .where('inventory_items.quantity_available > 0')
22
22
  .distinct
@@ -0,0 +1,10 @@
1
+ module SpreeCmCommissioner
2
+ class EventCreationTelegramAlertSenderJob < ApplicationUniqueJob
3
+ queue_as :telegram_bot
4
+
5
+ def perform(options = {})
6
+ event = Spree::Taxon.find(options[:event_id])
7
+ SpreeCmCommissioner::TelegramAlerts::EventCreation.call(event: event)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ module OauthAccessTokens
3
+ class CleanupExpiredJob < SpreeCmCommissioner::ApplicationJob
4
+ queue_as :default
5
+
6
+ def perform
7
+ SpreeCmCommissioner::OauthAccessTokens::CleanupExpired.new.call
8
+ end
9
+ end
10
+ end
11
+ end
@@ -23,6 +23,8 @@ module SpreeCmCommissioner
23
23
  TripKey = Struct.new(:trip_id, :direction, :boarding_trip_stop_id, :drop_off_trip_stop_id)
24
24
 
25
25
  included do
26
+ include SpreeCmCommissioner::ServiceOrigin
27
+
26
28
  validates :direction, inclusion: { in: DIRECTION }, allow_nil: true
27
29
  validates :trip_id, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
28
30
  validates :service_origin_id, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
@@ -125,6 +127,12 @@ module SpreeCmCommissioner
125
127
 
126
128
  private
127
129
 
130
+ def resolve_service_origin_id
131
+ return nil if trip_id.blank?
132
+
133
+ SpreeCmCommissioner::Trip.find_by(id: trip_id)&.service_origin_id
134
+ end
135
+
128
136
  def validate_trip_stops_for_scheduled_trips
129
137
  return if trip_id.blank? || trip_id.zero?
130
138
 
@@ -0,0 +1,22 @@
1
+ module SpreeCmCommissioner
2
+ # Defaults service_origin (nationality) from parent associations during validation (on create).
3
+ # Vendor → Route → Trip → LineItem.
4
+ # Pricing rules use this to determine local vs foreigner rates.
5
+ module ServiceOrigin
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ before_validation :assign_service_origin_id, on: :create
10
+ end
11
+
12
+ private
13
+
14
+ def assign_service_origin_id
15
+ self.service_origin_id ||= resolve_service_origin_id
16
+ end
17
+
18
+ def resolve_service_origin_id
19
+ nil
20
+ end
21
+ end
22
+ end
@@ -7,6 +7,7 @@ module SpreeCmCommissioner
7
7
  preference :telegram_order_alert_chat_id, :string
8
8
  preference :telegram_order_request_alert_chat_id, :string
9
9
  preference :telegram_new_vendor_alert_chat_id, :string
10
+ preference :telegram_new_event_alert_chat_id, :string
10
11
  preference :assetlinks, :string, default: ''
11
12
  preference :apple_app_site_association, :string, default: ''
12
13
  end
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  module VehicleKind
3
3
  extend ActiveSupport::Concern
4
4
 
5
- VEHICLE_KINDS = %i[suv sedan minivan van sleeping_bus luxury_van air_bus bus ferry boat].freeze
5
+ VEHICLE_KINDS = %i[suv sedan minivan van sleeping_bus luxury_van air_bus bus ferry].freeze
6
6
 
7
7
  included do
8
8
  enum kind: VEHICLE_KINDS if table_exists? && column_names.include?('kind')
@@ -25,36 +25,5 @@ module SpreeCmCommissioner
25
25
  def unstock_external_inventory!(_order, _line_items)
26
26
  raise NotImplementedError, 'Subclasses must implement the unstock_external_inventory! method'
27
27
  end
28
-
29
- def sync_item_availability!(_options = {})
30
- raise NotImplementedError, 'Subclasses must implement the sync_item_availability! method'
31
- end
32
-
33
- def hold_inventory!(_order, _line_items)
34
- raise NotImplementedError, 'Subclasses must implement the hold_inventory! method'
35
- end
36
-
37
- # Integrations that manage external inventory reservations should override this to return true
38
- def supports_external_inventory_holding?
39
- false
40
- end
41
-
42
- # Integrations that support automatically releasing external inventory
43
- # after reservation expiration or order cancellation should override this to return true
44
- def supports_auto_release_inventory?
45
- false
46
- end
47
-
48
- def release_inventory!(_order, _line_items)
49
- raise NotImplementedError, 'Subclasses must implement the release_inventory! method'
50
- end
51
-
52
- def external_inventory_items(_order)
53
- raise NotImplementedError, 'Subclasses must implement the external_inventory_items method'
54
- end
55
-
56
- def external_inventory_item_status(_order, _options)
57
- raise NotImplementedError, 'Subclasses must implement the external_inventory_item_status method'
58
- end
59
28
  end
60
29
  end
@@ -5,7 +5,10 @@ class SpreeCmCommissioner::Integrations::StadiumXV1 < SpreeCmCommissioner::Integ
5
5
 
6
6
  # override
7
7
  def sync_manager
8
- SpreeCmCommissioner::Integrations::StadiumXV1::SyncManager.new(integration: self)
8
+ SpreeCmCommissioner::Integrations::StadiumXV1::SyncManager.new(
9
+ integration: self,
10
+ client: client
11
+ )
9
12
  end
10
13
 
11
14
  # override
@@ -15,6 +18,7 @@ class SpreeCmCommissioner::Integrations::StadiumXV1 < SpreeCmCommissioner::Integ
15
18
  order: order,
16
19
  line_items: line_items
17
20
  )
21
+
18
22
  raise SpreeCmCommissioner::Integrations::SyncError, result.error unless result.success?
19
23
  end
20
24
 
@@ -23,9 +27,11 @@ class SpreeCmCommissioner::Integrations::StadiumXV1 < SpreeCmCommissioner::Integ
23
27
  raise SpreeCmCommissioner::Integrations::SyncError, 'Ticket cannot be cancelled'
24
28
  end
25
29
 
26
- def sync_item_availability!(_options = {}); end
27
-
28
30
  def client
29
- @client ||= SpreeCmCommissioner::Integrations::StadiumXV1::ExternalClient::Client.new(integration: self)
31
+ SpreeCmCommissioner::Integrations::StadiumXV1::ExternalClient::Client.new(
32
+ public_key: public_key,
33
+ private_key: private_key,
34
+ base_url: base_url
35
+ )
30
36
  end
31
37
  end
@@ -1,15 +1,9 @@
1
1
  module SpreeCmCommissioner
2
2
  class InventoryItem < Base
3
3
  include SpreeCmCommissioner::ProductType
4
- include SpreeCmCommissioner::StoreMetadata
5
- include SpreeCmCommissioner::Integrations::IntegrationMappable
6
4
 
7
5
  MAX_DISPLAY_STOCK = 20
8
6
 
9
- store_public_metadata :last_synced_at, :datetime
10
- store_public_metadata :original_price, :integer
11
- store_public_metadata :currency, :string
12
-
13
7
  # Association
14
8
  belongs_to :variant, class_name: 'Spree::Variant', optional: false
15
9
 
@@ -29,8 +23,23 @@ module SpreeCmCommissioner
29
23
 
30
24
  before_save -> { self.product_type = variant.product_type }, if: -> { product_type.nil? }
31
25
 
32
- # Create maintaining task to purge product related caches
33
- after_commit { SpreeCmCommissioner::MaintenanceTasks::CacheInvalidation.pending.create_or_find_by(maintainable: variant.product) }
26
+ after_commit :schedule_product_cache_invalidation
27
+
28
+ # Only for ecommerce: the app uses product.in_stock? (derived from quantity_available) for product cards.
29
+ # Other types (e.g. accommodation, bus) have many inventory items (including daily-generated ones),
30
+ # so invalidating per item would flood the task queue.
31
+ #
32
+ # This is temporary until we have a more robust cache invalidation strategy in place.
33
+ def schedule_product_cache_invalidation
34
+ return unless ecommerce?
35
+ return unless saved_change_to_quantity_available?
36
+
37
+ # Only fires on in_stock status transition (0 ↔ N); non-zero to non-zero changes are skipped.
38
+ old_val, new_val = saved_change_to_quantity_available
39
+ return if old_val.to_i.positive? && new_val.to_i.positive?
40
+
41
+ SpreeCmCommissioner::MaintenanceTasks::CacheInvalidation.pending.create_or_find_by(maintainable: variant.product)
42
+ end
34
43
 
35
44
  def public_quantity_available
36
45
  [quantity_available, MAX_DISPLAY_STOCK].min
@@ -3,6 +3,8 @@ module SpreeCmCommissioner
3
3
  module MaintenanceTasks
4
4
  class CacheInvalidation < MaintenanceTask
5
5
  def maintain
6
+ return if ENV['CACHE_AUTO_INVALIDATION_DISABLED'] == 'yes'
7
+
6
8
  if maintainable.is_a?(SpreeCmCommissioner::HomepageBackground) || maintainable.is_a?(Spree::Menu)
7
9
  SpreeCmCommissioner::HomepageDataLoader.clear_cache
8
10
  end
@@ -7,6 +7,7 @@
7
7
  # `maintain` runs three steps in order:
8
8
  # 1. RebuildFromDb — overwrites Redis counters with DB totals (source of truth)
9
9
  # 2. AuditCounters — logs any remaining mismatches between Redis and DB
10
+ # 3. SnapshotToDb — writes final aggregates to cm_voting_contestants and cm_voting_session_stats
10
11
  #
11
12
  # maintainable: SpreeCmCommissioner::VotingSession
12
13
  #
@@ -19,6 +20,7 @@ module SpreeCmCommissioner
19
20
  ttl = rebuild_ttl
20
21
  SpreeCmCommissioner::VoteCounters::RebuildFromDb.call(voting_session_id: maintainable.id, ttl: ttl)
21
22
  SpreeCmCommissioner::VoteCounters::AuditCounters.call(voting_session_id: maintainable.id)
23
+ SpreeCmCommissioner::VoteCounters::SnapshotToDb.call(voting_session_id: maintainable.id)
22
24
  end
23
25
 
24
26
  # For closed sessions use the fixed 24h constant — closes_at is in the past
@@ -42,7 +42,6 @@ module SpreeCmCommissioner
42
42
  base.has_many :reserved_blocks, through: :guests, class_name: 'SpreeCmCommissioner::ReservedBlock'
43
43
  base.has_many :guest_card_classes, class_name: 'SpreeCmCommissioner::GuestCardClass', through: :variants
44
44
  base.has_many :product_completion_steps, class_name: 'SpreeCmCommissioner::ProductCompletionStep', through: :line_items
45
- base.has_many :audit_events, class_name: 'SpreeCmCommissioner::AuditEvent', as: :auditable
46
45
 
47
46
  base.delegate :customer, to: :user, allow_nil: true
48
47
 
@@ -1,7 +1,5 @@
1
1
  module SpreeCmCommissioner
2
2
  class Place < Base
3
- include SpreeCmCommissioner::Integrations::IntegrationMappable
4
-
5
3
  acts_as_nested_set
6
4
 
7
5
  validates :reference, presence: true, if: :validate_reference?
@@ -1,10 +1,10 @@
1
1
  module SpreeCmCommissioner
2
2
  class Route < Base
3
3
  include SpreeCmCommissioner::RouteType
4
- include SpreeCmCommissioner::Integrations::IntegrationMappable
5
4
  include SpreeCmCommissioner::StoreMetadata
5
+ include SpreeCmCommissioner::ServiceOrigin
6
6
 
7
- belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
7
+ belongs_to :vendor, class_name: 'Spree::Vendor', inverse_of: :routes, optional: false
8
8
  belongs_to :tenant, class_name: 'SpreeCmCommissioner::Tenant', optional: true
9
9
 
10
10
  belongs_to :service_origin, class_name: 'Spree::Taxon', optional: true
@@ -67,6 +67,10 @@ module SpreeCmCommissioner
67
67
 
68
68
  private
69
69
 
70
+ def resolve_service_origin_id
71
+ vendor&.service_origin_id
72
+ end
73
+
70
74
  def validate_route_stops
71
75
  return if route_stops.valid?
72
76
 
@@ -1,7 +1,5 @@
1
1
  module SpreeCmCommissioner
2
2
  class SeatLayout < Base
3
- include SpreeCmCommissioner::Integrations::IntegrationMappable
4
-
5
3
  has_many :seat_sections, class_name: 'SpreeCmCommissioner::SeatSection', dependent: :destroy
6
4
 
7
5
  has_many :blocks, class_name: 'SpreeCmCommissioner::Block'
@@ -28,7 +28,9 @@ module SpreeCmCommissioner
28
28
  :max_paid_votes_per_session,
29
29
  :sms_vote_enabled,
30
30
  :sms_vote_cost_usd,
31
- :operator_vote_enabled
31
+ :operator_vote_enabled,
32
+ :votes_weight,
33
+ :voters_weight
32
34
 
33
35
  # voting_credit_scope determines how purchased vote credits are grouped (scoped).
34
36
  # Changing this after credits have been allocated will cause inconsistencies:
@@ -29,6 +29,11 @@ module SpreeCmCommissioner
29
29
 
30
30
  scope :ordered, -> { order(:position, :id) }
31
31
 
32
+ def eliminate
33
+ self.status = :eliminated
34
+ self.eliminated_at = Time.current
35
+ end
36
+
32
37
  self.whitelisted_ransackable_attributes = %w[name contestant_number status gender category origin]
33
38
  end
34
39
  end
@@ -6,9 +6,6 @@ module SpreeCmCommissioner
6
6
 
7
7
  base.after_commit :create_inventory_items, on: :create
8
8
  base.after_commit :adjust_inventory_items_async, on: :destroy
9
-
10
- # Create maintaining task to purge product related caches
11
- base.after_commit { SpreeCmCommissioner::MaintenanceTasks::CacheInvalidation.pending.create_or_find_by(maintainable: variant.product) }
12
9
  end
13
10
 
14
11
  def update_vendor_total_inventory
@@ -18,10 +15,6 @@ module SpreeCmCommissioner
18
15
  private
19
16
 
20
17
  def create_inventory_items
21
- # Skip automatic inventory generation when variant has manual_generate_inventory_items set to true
22
- # Use case: For variants where inventory items need to be manually created/managed (e.g., external integrations)
23
- return if variant.manual_generate_inventory_items?
24
-
25
18
  SpreeCmCommissioner::InventoryItems::GenerateInventoryItemsJob.perform_later(variant_id: variant.id)
26
19
  end
27
20
 
@@ -74,6 +74,7 @@ module SpreeCmCommissioner
74
74
  base.has_many :taxon_option_values, class_name: 'SpreeCmCommissioner::TaxonOptionValue'
75
75
 
76
76
  base.after_commit :send_transaction_email_to_organizers, on: :create
77
+ base.after_commit :send_event_creation_telegram_alert, on: :create
77
78
 
78
79
  base.has_many :taxon_places, class_name: 'SpreeCmCommissioner::TaxonPlace', dependent: :destroy
79
80
  base.has_many :places, through: :taxon_places
@@ -154,6 +155,12 @@ module SpreeCmCommissioner
154
155
  SpreeCmCommissioner::OrganizersTransactionalEmailNotifier.call(event_id: id)
155
156
  end
156
157
 
158
+ def send_event_creation_telegram_alert
159
+ return unless kind == 'event' && depth == 1
160
+
161
+ SpreeCmCommissioner::EventCreationTelegramAlertSenderJob.perform_later(event_id: id)
162
+ end
163
+
157
164
  def sync_event_dates_to_line_items
158
165
  return unless event? && depth == 1
159
166
 
@@ -2,7 +2,7 @@ module SpreeCmCommissioner
2
2
  class Trip < Base
3
3
  include SpreeCmCommissioner::StoreMetadata
4
4
  include SpreeCmCommissioner::RouteType
5
- include SpreeCmCommissioner::Integrations::IntegrationMappable
5
+ include SpreeCmCommissioner::ServiceOrigin
6
6
 
7
7
  attr_accessor :hours, :minutes, :seconds
8
8
 
@@ -26,7 +26,7 @@ module SpreeCmCommissioner
26
26
  after_commit :update_route_price_range, on: %i[create update]
27
27
 
28
28
  belongs_to :vendor, class_name: 'Spree::Vendor', inverse_of: :trips, optional: false
29
- belongs_to :product, class_name: 'Spree::Product', inverse_of: :trip, optional: true
29
+ belongs_to :product, class_name: 'Spree::Product', inverse_of: :trip, optional: false
30
30
 
31
31
  belongs_to :service_origin, class_name: 'Spree::Taxon', optional: true
32
32
 
@@ -134,6 +134,10 @@ module SpreeCmCommissioner
134
134
 
135
135
  private
136
136
 
137
+ def resolve_service_origin_id
138
+ route&.service_origin_id || vendor&.service_origin_id
139
+ end
140
+
137
141
  def duplicate_seat_layout_from_vehicle
138
142
  # Duplicate the vehicle's seat layout into this trip. Copies nested
139
143
  # seat sections and blocks while excluding identifying columns and
@@ -1,7 +1,5 @@
1
1
  module SpreeCmCommissioner
2
2
  class TripStop < Base
3
- include SpreeCmCommissioner::Integrations::IntegrationMappable
4
-
5
3
  acts_as_list column: :sequence, scope: :trip_id
6
4
 
7
5
  belongs_to :trip, class_name: 'SpreeCmCommissioner::Trip', optional: false
@@ -6,7 +6,6 @@ module SpreeCmCommissioner
6
6
  base.include SpreeCmCommissioner::VariantOptionsConcern
7
7
  base.include SpreeCmCommissioner::KycBitwise
8
8
  base.include SpreeCmCommissioner::Integrations::IntegrationMappable
9
- base.include SpreeCmCommissioner::VariantMetadata
10
9
 
11
10
  base.after_commit :update_vendor_price
12
11
  base.validate :validate_option_types
@@ -1,7 +1,6 @@
1
1
  module SpreeCmCommissioner
2
2
  class Vehicle < Base
3
3
  include SpreeCmCommissioner::VehicleKind
4
- include SpreeCmCommissioner::Integrations::IntegrationMappable
5
4
 
6
5
  belongs_to :vendor, class_name: 'Spree::Vendor'
7
6
  belongs_to :vehicle_type, class_name: 'SpreeCmCommissioner::VehicleType'
@@ -14,8 +13,6 @@ module SpreeCmCommissioner
14
13
  validates :name, presence: true
15
14
  validates :license_plate, uniqueness: true, allow_blank: true
16
15
 
17
- has_one :seat_layout, through: :vehicle_type
18
-
19
16
  self.whitelisted_ransackable_attributes = %w[name license_plate kind]
20
17
 
21
18
  def display_name
@@ -2,7 +2,6 @@ module SpreeCmCommissioner
2
2
  class VehicleType < Base
3
3
  include SpreeCmCommissioner::StoreMetadata
4
4
  include SpreeCmCommissioner::VehicleKind
5
- include SpreeCmCommissioner::Integrations::IntegrationMappable
6
5
 
7
6
  # This model has no seat_layout column (polymorphic association), so we store the preload_seat_layout_id ID in public_metadata.
8
7
  # This lets us check if a seat layout exists without triggering a database query.
@@ -30,7 +30,6 @@ module SpreeCmCommissioner
30
30
  base.has_many :nearby_places, -> { order(position: :asc) }, class_name: 'SpreeCmCommissioner::VendorPlace', dependent: :destroy
31
31
 
32
32
  base.has_many :stock_items, through: :variants, class_name: 'Spree::StockItem'
33
- base.has_many :currency_rates, class_name: 'SpreeCmCommissioner::CurrencyRate', dependent: :destroy
34
33
 
35
34
  base.has_many :taxon_vendors, class_name: 'SpreeCmCommissioner::TaxonVendor'
36
35
  base.has_many :taxons, through: :taxon_vendors
@@ -102,7 +101,6 @@ module SpreeCmCommissioner
102
101
  base.has_many :boarding_trip_stops, through: :trips, class_name: 'SpreeCmCommissioner::TripStop', source: :boarding_trip_stops
103
102
  base.has_many :drop_off_trip_stops, through: :trips, class_name: 'SpreeCmCommissioner::TripStop', source: :drop_off_trip_stops
104
103
  base.has_many :pricing_models, class_name: 'SpreeCmCommissioner::PricingModel', foreign_key: :vendor_id, dependent: :destroy
105
- base.has_many :orders, -> { distinct }, through: :variants, source: :orders
106
104
 
107
105
  base.has_many :agency_categories, -> { where(kind: :agency_category) }, class_name: 'Spree::Taxon', foreign_key: :vendor_id
108
106
 
@@ -245,21 +243,6 @@ module SpreeCmCommissioner
245
243
  end
246
244
 
247
245
  delegate :present?, to: :tenant, prefix: true
248
-
249
- # Returns the exchange rate between two currencies
250
- # If no direct rate exists, calculates the inverse rate from the reverse pair
251
- # Returns 1.0 for identical currencies, nil if no rate is found
252
- def exchange_rate(from_currency, to_currency)
253
- return 1.0 if from_currency == to_currency
254
-
255
- pair = currency_rates.by_pair(from_currency, to_currency).first
256
- return pair.rate if pair.present?
257
-
258
- reverse_pair = currency_rates.by_pair(to_currency, from_currency).first
259
- return (1.0 / reverse_pair.rate).round(6) if reverse_pair.present?
260
-
261
- nil
262
- end
263
246
  end
264
247
  end
265
248
 
@@ -1,7 +1,5 @@
1
1
  module SpreeCmCommissioner
2
2
  class VendorPlace < Base
3
- include SpreeCmCommissioner::Integrations::IntegrationMappable
4
-
5
3
  enum place_type: { venue: 0, branch: 1, stop: 2, location: 3 }
6
4
  acts_as_list scope: :vendor
7
5