spree_cm_commissioner 1.21.0 → 2.0.0.pre.pre

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 (241) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +0 -3
  3. data/.github/workflows/test_and_build_gem.yml +16 -2
  4. data/.gitignore +2 -1
  5. data/Gemfile.lock +28 -1
  6. data/Rakefile +33 -4
  7. data/app/assets/javascripts/spree_cm_commissioner/backend.js +0 -1
  8. data/app/assets/stylesheets/spree_cm_commissioner/backend/calendar.scss +8 -11
  9. data/app/assets/stylesheets/spree_cm_commissioner/backend/commissioner_admin.css.scss +0 -1
  10. data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +1 -2
  11. data/app/controllers/spree/admin/event_blazer_queries_controller.rb +4 -11
  12. data/app/controllers/spree/admin/inventory_items_controller.rb +83 -0
  13. data/app/controllers/spree/admin/stock_managements_controller.rb +63 -1
  14. data/app/controllers/spree/admin/tenants_controller.rb +0 -8
  15. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -1
  16. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +42 -0
  17. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +14 -31
  18. data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +1 -5
  19. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +5 -31
  20. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  21. data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +0 -2
  22. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
  23. data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +0 -11
  24. data/app/controllers/spree_cm_commissioner/well_known_controller.rb +17 -31
  25. data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +84 -37
  26. data/app/finders/spree_cm_commissioner/accommodations/find.rb +37 -0
  27. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +32 -0
  28. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +40 -0
  29. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +25 -0
  30. data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +1 -0
  31. data/app/interactors/spree_cm_commissioner/sms.rb +1 -1
  32. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +44 -0
  33. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +13 -0
  34. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +15 -0
  35. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +75 -0
  36. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +32 -0
  37. data/app/interactors/spree_cm_commissioner/user_id_token_authenticator.rb +3 -7
  38. data/app/interactors/spree_cm_commissioner/user_id_token_checker.rb +3 -11
  39. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +6 -12
  40. data/app/interactors/spree_cm_commissioner/user_registration_with_id_token.rb +1 -7
  41. data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +1 -5
  42. data/app/jobs/spree_cm_commissioner/application_job.rb +20 -0
  43. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +20 -0
  44. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +7 -0
  45. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +7 -0
  46. data/app/jobs/spree_cm_commissioner/sms_pin_code_job.rb +1 -1
  47. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +11 -0
  48. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +11 -0
  49. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +9 -0
  50. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +9 -15
  51. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +1 -13
  52. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +44 -0
  53. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +39 -0
  54. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +1 -3
  55. data/app/models/concerns/spree_cm_commissioner/product_type.rb +10 -0
  56. data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +1 -1
  57. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +0 -4
  58. data/app/models/spree_cm_commissioner/block.rb +23 -0
  59. data/app/models/spree_cm_commissioner/dynamic_field.rb +3 -17
  60. data/app/models/spree_cm_commissioner/dynamic_field_option.rb +1 -7
  61. data/app/models/spree_cm_commissioner/guest.rb +19 -1
  62. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +3 -21
  63. data/app/models/spree_cm_commissioner/inventory.rb +11 -0
  64. data/app/models/spree_cm_commissioner/inventory_item.rb +69 -0
  65. data/app/models/spree_cm_commissioner/invite.rb +6 -4
  66. data/app/models/spree_cm_commissioner/invite_team.rb +1 -3
  67. data/app/models/spree_cm_commissioner/line_item_decorator.rb +46 -78
  68. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  69. data/app/models/spree_cm_commissioner/option_type_decorator.rb +1 -11
  70. data/app/models/spree_cm_commissioner/order_decorator.rb +30 -1
  71. data/app/models/spree_cm_commissioner/pin_code.rb +2 -3
  72. data/app/models/spree_cm_commissioner/place.rb +1 -3
  73. data/app/models/spree_cm_commissioner/price_decorator.rb +9 -0
  74. data/app/models/spree_cm_commissioner/product_decorator.rb +10 -4
  75. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +41 -0
  76. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +126 -0
  77. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +36 -0
  78. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +25 -0
  79. data/app/models/spree_cm_commissioner/reserved_block.rb +30 -0
  80. data/app/models/spree_cm_commissioner/seat_layout.rb +20 -0
  81. data/app/models/spree_cm_commissioner/seat_section.rb +16 -0
  82. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +30 -0
  83. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +53 -0
  84. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +49 -0
  85. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +4 -0
  86. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +4 -0
  87. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +4 -0
  88. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +4 -0
  89. data/app/models/spree_cm_commissioner/service_calendar.rb +0 -2
  90. data/app/models/spree_cm_commissioner/state_decorator.rb +0 -1
  91. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +26 -25
  92. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +2 -1
  93. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  94. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +44 -0
  95. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +17 -0
  96. data/app/models/spree_cm_commissioner/taxon_blazer_query.rb +8 -0
  97. data/app/models/spree_cm_commissioner/taxon_decorator.rb +2 -6
  98. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +0 -6
  99. data/app/models/spree_cm_commissioner/trip.rb +12 -10
  100. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  101. data/app/models/spree_cm_commissioner/trip_stop.rb +2 -3
  102. data/app/models/spree_cm_commissioner/user_identity_provider.rb +4 -26
  103. data/app/models/spree_cm_commissioner/user_taxon.rb +0 -1
  104. data/app/models/spree_cm_commissioner/variant_block.rb +9 -0
  105. data/app/models/spree_cm_commissioner/variant_decorator.rb +36 -47
  106. data/app/models/spree_cm_commissioner/variant_options.rb +0 -23
  107. data/app/models/spree_cm_commissioner/vehicle.rb +9 -14
  108. data/app/models/spree_cm_commissioner/vendor_decorator.rb +7 -10
  109. data/app/models/spree_cm_commissioner/vendor_place.rb +6 -5
  110. data/app/models/spree_cm_commissioner/vendor_stop.rb +1 -2
  111. data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +2 -2
  112. data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +3 -45
  113. data/app/queries/spree_cm_commissioner/trip_query.rb +23 -26
  114. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +3 -0
  115. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  116. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +19 -0
  117. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +2 -0
  118. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +1 -0
  119. data/app/serializers/spree/v2/tenant/user_serializer.rb +0 -1
  120. data/app/serializers/spree_cm_commissioner/v2/operator/dashboard_crew_event_serializer.rb +1 -4
  121. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +3 -1
  122. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +3 -1
  123. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +1 -2
  124. data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +15 -23
  125. data/app/services/spree_cm_commissioner/user_authenticator.rb +1 -1
  126. data/app/views/blazer/queries/_content.html.erb +0 -8
  127. data/app/views/spree/admin/inventory_items/show.html.erb +72 -0
  128. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +7 -2
  129. data/app/views/spree/admin/stock_managements/calendar.html.erb +56 -0
  130. data/app/views/spree/admin/stock_managements/index.html.erb +55 -6
  131. data/app/views/spree/admin/tenants/_form.html.erb +42 -109
  132. data/config/initializers/paper_trail.rb +1 -0
  133. data/config/initializers/spree_permitted_attributes.rb +5 -2
  134. data/config/locales/en.yml +0 -5
  135. data/config/routes.rb +22 -6
  136. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +3 -1
  137. data/db/migrate/20250304293518_create_cm_inventory_items.rb +21 -0
  138. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +5 -0
  139. data/db/migrate/20250502025848_add_index_to_spree_products.rb +5 -0
  140. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +5 -0
  141. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +5 -0
  142. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +7 -0
  143. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +5 -0
  144. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +5 -0
  145. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +9 -0
  146. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +5 -0
  147. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +9 -0
  148. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +5 -0
  149. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +5 -0
  150. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +5 -0
  151. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +6 -0
  152. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +17 -0
  153. data/db/migrate/20250620090002_create_cm_seat_sections.rb +18 -0
  154. data/db/migrate/20250620090003_create_cm_blocks.rb +18 -0
  155. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +29 -0
  156. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +24 -0
  157. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +13 -0
  158. data/docker-compose.yml +1 -1
  159. data/lib/cm_app_logger.rb +11 -4
  160. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +14 -11
  161. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_cm_commissioner → spree_dashboard/spree_cm_commissioner}/utilities.js +4 -0
  162. data/lib/spree_cm_commissioner/cached_inventory_item.rb +23 -0
  163. data/lib/spree_cm_commissioner/calendar_event.rb +11 -1
  164. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +9 -0
  165. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +10 -0
  166. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  167. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +9 -0
  168. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  169. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +6 -30
  170. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +0 -36
  171. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +18 -34
  172. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +27 -0
  173. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +8 -0
  174. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +8 -0
  175. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  176. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
  177. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +10 -3
  178. data/lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb +1 -1
  179. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +7 -0
  180. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +41 -19
  181. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  182. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -1
  183. data/lib/spree_cm_commissioner/version.rb +1 -1
  184. data/lib/spree_cm_commissioner.rb +35 -1
  185. data/lib/tasks/create_default_non_permanent_inventory_items.rake +16 -0
  186. data/lib/tasks/ensure_correct_product_type.rake +7 -0
  187. data/lib/tasks/generate_inventory_items.rake +7 -0
  188. data/spree_cm_commissioner.gemspec +7 -0
  189. metadata +135 -57
  190. data/app/assets/images/cm-hangmeas-checkout_image.svg +0 -63
  191. data/app/assets/images/cm-hangmeas-failed.svg +0 -56
  192. data/app/assets/images/cm-hangmeas-loader.svg +0 -50
  193. data/app/assets/images/cm-hangmeas-success.svg +0 -51
  194. data/app/assets/javascripts/spree_cm_commissioner/tenant_payment_icon_fields.js +0 -65
  195. data/app/assets/stylesheets/spree_cm_commissioner/backend/tenant_payment_icon_fields.scss +0 -60
  196. data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +0 -44
  197. data/app/controllers/spree/admin/trip_blazer_queries_controller.rb +0 -35
  198. data/app/controllers/spree/api/v2/organizer/invite_crews_controller.rb +0 -33
  199. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +0 -20
  200. data/app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb +0 -27
  201. data/app/interactors/spree_cm_commissioner/asset_links_fetcher.rb +0 -27
  202. data/app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb +0 -48
  203. data/app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb +0 -144
  204. data/app/models/concerns/spree_cm_commissioner/event_check_in_flowable.rb +0 -30
  205. data/app/models/spree_cm_commissioner/blazer_queryable.rb +0 -8
  206. data/app/models/spree_cm_commissioner/branch.rb +0 -12
  207. data/app/models/spree_cm_commissioner/crew_invite_link.rb +0 -4
  208. data/app/models/spree_cm_commissioner/line_item_seat.rb +0 -10
  209. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +0 -8
  210. data/app/models/spree_cm_commissioner/pin_code_telegram.rb +0 -28
  211. data/app/models/spree_cm_commissioner/promotion_category_decorator.rb +0 -11
  212. data/app/models/spree_cm_commissioner/stop.rb +0 -23
  213. data/app/models/spree_cm_commissioner/telegram_chat.rb +0 -6
  214. data/app/models/spree_cm_commissioner/vehicle_seat.rb +0 -11
  215. data/app/models/spree_cm_commissioner/vehicle_type.rb +0 -76
  216. data/app/overrides/spree/admin/taxons/_form/check_in_flows.html.erb.deface +0 -18
  217. data/app/queries/spree_cm_commissioner/trip_search_query.rb +0 -76
  218. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +0 -45
  219. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +0 -55
  220. data/app/serializers/spree/v2/organizer/invite_crews_serializer.rb +0 -11
  221. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +0 -11
  222. data/db/migrate/20250616084219_add_description_to_cm_vendor_place.rb +0 -5
  223. data/db/migrate/20250630103536_create_cm_telegram_chats.rb +0 -13
  224. data/db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb +0 -6
  225. data/db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb +0 -5
  226. data/db/migrate/20250702091935_add_status_to_dynamic_field_option.rb +0 -5
  227. data/db/migrate/20250707032008_add_vendor_id_to_spree_category.rb +0 -7
  228. data/db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb +0 -11
  229. data/db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb +0 -11
  230. data/db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb +0 -7
  231. data/db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb +0 -19
  232. data/db/migrate/20250715103333_remove_indexes_from_cm_user_identity_providers.rb +0 -13
  233. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +0 -12
  234. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +0 -8
  235. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +0 -8
  236. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +0 -7
  237. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +0 -14
  238. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +0 -8
  239. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +0 -8
  240. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +0 -96
  241. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +0 -11
@@ -0,0 +1,36 @@
1
+ module SpreeCmCommissioner
2
+ module RedisStock
3
+ class LineItemsCachedInventoryItemsBuilder
4
+ attr_reader :line_item_ids
5
+
6
+ def initialize(line_item_ids:)
7
+ @line_item_ids = line_item_ids
8
+ end
9
+
10
+ # return list of inventory items group by :line_item_id:
11
+ # {
12
+ # 1: [ CachedInventoryItem(...), CachedInventoryItem(...) ],
13
+ # 2: [ CachedInventoryItem(...), CachedInventoryItem(...) ],
14
+ # }
15
+ def call
16
+ cached_inventory_items.group_by do |cached_inventory_item|
17
+ line_item = line_items.find { |item| item.variant_id == cached_inventory_item.variant_id }
18
+ line_item.id
19
+ end
20
+ end
21
+
22
+ def cached_inventory_items
23
+ @cached_inventory_items ||= SpreeCmCommissioner::RedisStock::CachedInventoryItemsBuilder.new(inventory_items)
24
+ .call
25
+ end
26
+
27
+ def inventory_items
28
+ @inventory_items ||= line_items.flat_map(&:inventory_items)
29
+ end
30
+
31
+ def line_items
32
+ @line_items ||= Spree::LineItem.where(id: line_item_ids).includes(:inventory_items)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,25 @@
1
+ module SpreeCmCommissioner
2
+ module RedisStock
3
+ class VariantCachedInventoryItemsBuilder
4
+ attr_reader :variant_id, :dates
5
+
6
+ def initialize(variant_id:, dates: [])
7
+ @variant_id = variant_id
8
+ @dates = dates
9
+ end
10
+
11
+ # output: [ CachedInventoryItem(...), CachedInventoryItem(...) ]
12
+ def call
13
+ ::SpreeCmCommissioner::RedisStock::CachedInventoryItemsBuilder.new(inventory_items).call
14
+ end
15
+
16
+ def inventory_items
17
+ variant = Spree::Variant.find(variant_id)
18
+
19
+ inventory_items = variant.inventory_items
20
+ inventory_items = inventory_items.where(inventory_date: dates) if variant.permanent_stock?
21
+ inventory_items
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ module SpreeCmCommissioner
2
+ class ReservedBlock < Base
3
+ has_paper_trail
4
+
5
+ belongs_to :updated_by, optional: true, class_name: 'Spree::User'
6
+ belongs_to :guest, optional: true, class_name: 'SpreeCmCommissioner::Guest'
7
+ belongs_to :inventory_item, class_name: 'SpreeCmCommissioner::InventoryItem'
8
+ belongs_to :block, class_name: 'SpreeCmCommissioner::Block'
9
+
10
+ enum status: {
11
+ reserved: 0, # confirmed reservation
12
+ on_hold: 1, # temporary hold
13
+ canceled: 2
14
+ }
15
+
16
+ validates :status, presence: true
17
+ validates :expired_at, presence: true, if: -> { on_hold? }
18
+
19
+ scope :active_on_hold, -> { on_hold.where('expired_at IS NULL OR expired_at > ?', Time.current) }
20
+ scope :active, -> { where('expired_at IS NULL OR expired_at > ?', Time.current) }
21
+
22
+ def expired?
23
+ expired_at.present? && expired_at <= Time.current
24
+ end
25
+
26
+ def active_on_hold?
27
+ on_hold? && !expired?
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ module SpreeCmCommissioner
2
+ class SeatLayout < Base
3
+ has_many :seat_sections, class_name: 'SpreeCmCommissioner::SeatSection', dependent: :destroy
4
+
5
+ has_many :top_level_blocks, -> { where(seat_section_id: nil) }, class_name: 'SpreeCmCommissioner::Block', dependent: :destroy
6
+ has_many :section_blocks, -> { where.not(seat_section_id: nil) }, class_name: 'SpreeCmCommissioner::Block', dependent: :destroy
7
+
8
+ belongs_to :layoutable, polymorphic: true
9
+
10
+ enum status: {
11
+ inactive: 0,
12
+ active: 1,
13
+ archived: 2
14
+ }
15
+
16
+ validates :name, presence: true
17
+
18
+ accepts_nested_attributes_for :seat_sections, :top_level_blocks
19
+ end
20
+ end
@@ -0,0 +1,16 @@
1
+ module SpreeCmCommissioner
2
+ class SeatSection < Base
3
+ belongs_to :seat_layout, class_name: 'SpreeCmCommissioner::SeatLayout', optional: false
4
+
5
+ has_many :blocks, class_name: 'SpreeCmCommissioner::Block', dependent: :destroy
6
+
7
+ validates :name, presence: true
8
+ validates :width, presence: true, numericality: { greater_than: 0 }
9
+ validates :height, presence: true, numericality: { greater_than: 0 }
10
+ validates :x, presence: true, numericality: true
11
+ validates :y, presence: true, numericality: true
12
+ validates :rotation, presence: true, numericality: { greater_than_or_equal_to: -360, less_than_or_equal_to: 360 }
13
+
14
+ accepts_nested_attributes_for :blocks
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ module SpreeCmCommissioner
2
+ module Seats
3
+ class BlocksCanceler
4
+ def initialize(order_id:, cancel_by: nil)
5
+ @order_id = order_id
6
+ @cancel_by = cancel_by
7
+ end
8
+
9
+ # Cancels all reserved blocks associated with a given order.
10
+ #
11
+ # Typically used when:
12
+ # - The order is canceled.
13
+ # - The user abandons the order before completing checkout.
14
+ def cancel_blocks!
15
+ order = Spree::Order.find(@order_id)
16
+
17
+ ActiveRecord::Base.transaction do
18
+ order.reserved_blocks.each do |reserved_block|
19
+ reserved_block.assign_attributes(
20
+ status: :canceled,
21
+ expired_at: nil,
22
+ updated_by: @cancel_by
23
+ )
24
+ raise Errors::UnableToSaveReservedBlockRecord unless reserved_block.save
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,53 @@
1
+ module SpreeCmCommissioner
2
+ module Seats
3
+ class BlocksHolder
4
+ HOLD_DURATION = 8.minutes
5
+
6
+ def initialize(line_item_ids:, hold_by: nil)
7
+ @line_item_ids = line_item_ids
8
+ @hold_by = hold_by
9
+ end
10
+
11
+ # Hold blocks for the given line items, preventing dublicate block selection.
12
+ #
13
+ # It ensures:
14
+ # - Raises an error if already reserved.
15
+ # - Raises an error if currently on_hold by someone else.
16
+ # - Allows re-locking if already on_hold by the same guest.
17
+ # - Otherwise, proceeds to lock the given blocks.
18
+ def hold_blocks!
19
+ line_items = Spree::LineItem.where(id: @line_item_ids).includes(:inventory_items, guests_with_blocks: :block)
20
+ guests_with_blocks = line_items.flat_map(&:guests_with_blocks).compact
21
+ inventory_items = line_items.flat_map(&:inventory_items).compact
22
+
23
+ ActiveRecord::Base.transaction do
24
+ guests_with_blocks.each do |guest|
25
+ inventory_items.each do |inventory_item|
26
+ hold_specific_block!(inventory_item, guest)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def hold_specific_block!(inventory_item, guest)
35
+ reserved_block = SpreeCmCommissioner::ReservedBlock.find_or_initialize_by(inventory_item: inventory_item, block: guest.block)
36
+
37
+ raise Errors::BlocksAreReservedByOtherGuest if reserved_block.reserved? && reserved_block.guest_id != guest.id
38
+ raise Errors::BlocksAreReservedBySameGuest if reserved_block.reserved? && reserved_block.guest_id == guest.id
39
+ raise Errors::BlocksAreOnHoldByOtherGuest if reserved_block.active_on_hold? && reserved_block.guest_id != guest.id
40
+
41
+ reserved_block.assign_attributes(
42
+ status: :on_hold,
43
+ guest: guest,
44
+ expired_at: HOLD_DURATION.from_now,
45
+ inventory_date: inventory_item.inventory_date,
46
+ updated_by: @hold_by
47
+ )
48
+
49
+ raise Errors::UnableToSaveReservedBlockRecord unless reserved_block.save
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,49 @@
1
+ module SpreeCmCommissioner
2
+ module Seats
3
+ class BlocksReserver
4
+ def initialize(line_item_ids:, reserve_by: nil)
5
+ @line_item_ids = line_item_ids
6
+ @reserve_by = reserve_by
7
+ end
8
+
9
+ # Mark blocks as reserved for the given line items.
10
+ #
11
+ # It ensures:
12
+ # - Raises an error if already reserved by same guest or other guest.
13
+ # - Raises an error if currently on_hold by someone else.
14
+ # - Otherwise, proceeds to reserve the given blocks.
15
+ def reserve_blocks!
16
+ line_items = Spree::LineItem.where(id: @line_item_ids).includes(:inventory_items, guests_with_blocks: :block)
17
+ guests_with_blocks = line_items.flat_map(&:guests_with_blocks).compact
18
+ inventory_items = line_items.flat_map(&:inventory_items).compact
19
+
20
+ ActiveRecord::Base.transaction do
21
+ guests_with_blocks.each do |guest|
22
+ inventory_items.each do |inventory_item|
23
+ reserve_specific_block!(inventory_item, guest)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def reserve_specific_block!(inventory_item, guest)
30
+ reserved_block = SpreeCmCommissioner::ReservedBlock.find_or_initialize_by(inventory_item_id: inventory_item.id, block_id: guest.block_id)
31
+
32
+ raise Errors::BlocksAreReservedByOtherGuest if reserved_block.reserved? && reserved_block.guest_id != guest.id
33
+ raise Errors::BlocksAreReservedBySameGuest if reserved_block.reserved? && reserved_block.guest_id == guest.id
34
+ raise Errors::BlocksAreOnHoldByOtherGuest if reserved_block.active_on_hold? && reserved_block.guest_id != guest.id
35
+
36
+ # mark the block as reserved if not on_hold or lock by anyone but already expired
37
+ reserved_block.assign_attributes(
38
+ guest: guest,
39
+ status: :reserved,
40
+ expired_at: nil,
41
+ inventory_date: inventory_item.inventory_date,
42
+ updated_by: @reserve_by
43
+ )
44
+
45
+ raise Errors::UnableToSaveReservedBlockRecord unless reserved_block.save
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,4 @@
1
+ module SpreeCmCommissioner
2
+ class Seats::Errors::BlocksAreOnHoldByOtherGuest < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SpreeCmCommissioner
2
+ class Seats::Errors::BlocksAreReservedByOtherGuest < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SpreeCmCommissioner
2
+ class Seats::Errors::BlocksAreReservedBySameGuest < StandardError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module SpreeCmCommissioner
2
+ class Seats::Errors::UnableToSaveReservedBlockRecord < StandardError
3
+ end
4
+ end
@@ -1,5 +1,3 @@
1
- require_dependency 'spree_cm_commissioner'
2
-
3
1
  module SpreeCmCommissioner
4
2
  class ServiceCalendar < SpreeCmCommissioner::Base
5
3
  # exception_rules = [
@@ -3,7 +3,6 @@ module SpreeCmCommissioner
3
3
  def self.prepended(base)
4
4
  base.whitelisted_ransackable_attributes |= %w[name abbr country_id]
5
5
  base.has_many :vendors, foreign_key: 'default_state_id', class_name: 'Spree::Vendor', inverse_of: :default_state, dependent: :nullify
6
- base.has_many :stops, class_name: 'SpreeCmCommissioner::Place'
7
6
 
8
7
  def update_total_inventory
9
8
  update(total_inventory: vendors.pluck(:total_inventory).compact.sum)
@@ -1,47 +1,48 @@
1
1
  module SpreeCmCommissioner
2
2
  module Stock
3
3
  class AvailabilityChecker
4
- attr_reader :variant, :error_message
4
+ attr_reader :variant, :options, :error_message
5
5
 
6
- def initialize(variant)
6
+ def initialize(variant, options = {})
7
7
  @variant = variant
8
+ @options = options
8
9
  @error_message = nil
9
10
  end
10
11
 
11
- def can_supply?(quantity = 1, options = {})
12
+ def can_supply?(quantity = 1)
12
13
  return false unless variant.available?
13
14
  return true unless variant.should_track_inventory?
14
15
  return true if variant.backorderable?
15
16
  return true if variant.need_confirmation?
16
17
 
17
- # when delivery required, shipment will dynamically add / remove unit from stock item.
18
- # so we can directly check can_supply with stock items directly.
19
- return variant.stock_items.sum(:count_on_hand) >= quantity if variant.delivery_required?
18
+ variant_available?(quantity)
19
+ end
20
20
 
21
- if variant.permanent_stock?
22
- permanent_stock_variant_available?(quantity, options)
23
- else
24
- variant_available?(quantity, options)
21
+ def variant_available?(quantity = 1)
22
+ return false if cached_inventory_items.empty?
23
+
24
+ cached_inventory_items.all? do |cached_inventory_item|
25
+ cached_inventory_item.active? && cached_inventory_item.quantity_available >= quantity
25
26
  end
26
27
  end
27
28
 
28
- def variant_available?(quantity = 1, options = {})
29
- query = SpreeCmCommissioner::VariantAvailability::NonPermanentStockQuery.new(
30
- variant: variant,
31
- except_line_item_id: options[:except_line_item_id]
32
- )
33
- result = query.available?(quantity)
34
- @error_message = query.error_message unless result
35
- result
29
+ def cached_inventory_items
30
+ return @cached_inventory_items if defined?(@cached_inventory_items)
31
+
32
+ if variant.permanent_stock?
33
+ return [] if options[:from_date].blank? || options[:to_date].blank?
34
+
35
+ dates = options[:from_date].to_date..options[:to_date].to_date
36
+ @cached_inventory_items = builder_klass.new(variant_id: variant.id, dates: dates).call
37
+ @cached_inventory_items = [] if @cached_inventory_items.size != dates.count
38
+ @cached_inventory_items
39
+ else
40
+ @cached_inventory_items = builder_klass.new(variant_id: variant.id).call
41
+ end
36
42
  end
37
43
 
38
- def permanent_stock_variant_available?(quantity = 1, options = {})
39
- SpreeCmCommissioner::VariantAvailability::PermanentStockQuery.new(
40
- variant: variant,
41
- from_date: options[:from_date].to_date,
42
- to_date: options[:to_date].to_date,
43
- except_line_item_id: options[:except_line_item_id]
44
- ).available?(quantity)
44
+ def builder_klass
45
+ ::SpreeCmCommissioner::RedisStock::VariantCachedInventoryItemsBuilder
45
46
  end
46
47
  end
47
48
  end
@@ -3,7 +3,8 @@ module SpreeCmCommissioner
3
3
  module AvailabilityValidatorDecorator
4
4
  # override
5
5
  def item_available?(line_item, quantity)
6
- SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(line_item).can_supply?(quantity)
6
+ SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(line_item)
7
+ .can_supply?(quantity)
7
8
  end
8
9
  end
9
10
  end
@@ -8,14 +8,14 @@ module SpreeCmCommissioner
8
8
  end
9
9
 
10
10
  def can_supply?(quantity)
11
- AvailabilityChecker.new(line_item.variant).can_supply?(quantity, options)
11
+ ::SpreeCmCommissioner::Stock::AvailabilityChecker.new(line_item.variant, options)
12
+ .can_supply?(quantity)
12
13
  end
13
14
 
14
15
  def options
15
16
  {
16
17
  from_date: line_item.from_date,
17
- to_date: line_item.to_date,
18
- except_line_item_id: line_item.id
18
+ to_date: line_item.to_date
19
19
  }
20
20
  end
21
21
  end
@@ -0,0 +1,44 @@
1
+ # On top of SpreeCmCommissioner::Stock::AvailabilityChecker, this class does the same thing but in bulk check with redis.
2
+ # Which mean, it check basic condition with db first, once pass, it check with redis.
3
+ module SpreeCmCommissioner
4
+ module Stock
5
+ class OrderAvailabilityChecker
6
+ attr_reader :order
7
+
8
+ def initialize(order)
9
+ @order = order
10
+ end
11
+
12
+ def can_supply_all?
13
+ insufficient_stock_lines.empty?
14
+ end
15
+
16
+ def insufficient_stock_lines
17
+ cached_inventory_items_group_by_line_item_id.map do |line_item_id, cached_inventory_items|
18
+ line_item = order.line_items.find { |item| item.id == line_item_id }
19
+ line_item unless sufficient_stock_for?(line_item, cached_inventory_items)
20
+ end.compact
21
+ end
22
+
23
+ # {
24
+ # 1: [ {inventory_key: "inventory:1", active: true, quantity_available: 5, inventory_item_id: 1, variant_id: 1}],
25
+ # 2: [ {inventory_key: "inventory:2", active: true, quantity_available: 5, inventory_item_id: 2, variant_id: 2}],
26
+ # }
27
+ def cached_inventory_items_group_by_line_item_id
28
+ @cached_inventory_items_group_by_line_item_id ||=
29
+ ::SpreeCmCommissioner::RedisStock::LineItemsCachedInventoryItemsBuilder.new(
30
+ line_item_ids: order.line_items.pluck(:id)
31
+ ).call
32
+ end
33
+
34
+ def sufficient_stock_for?(line_item, cached_inventory_items)
35
+ return false unless line_item.variant.available?
36
+ return true unless line_item.variant.should_track_inventory?
37
+ return true if line_item.variant.backorderable?
38
+ return true if line_item.variant.need_confirmation?
39
+
40
+ cached_inventory_items.all? { |item| item.active? && item.quantity_available >= line_item.quantity }
41
+ end
42
+ end
43
+ end
44
+ end
@@ -3,11 +3,28 @@ module SpreeCmCommissioner
3
3
  def self.prepended(base)
4
4
  base.has_one :vendor, through: :variant
5
5
  base.after_save :update_vendor_total_inventory, if: :saved_change_to_count_on_hand?
6
+
7
+ base.after_commit :create_inventory_items, on: :create
8
+ base.after_commit :adjust_inventory_items_async, on: :destroy
6
9
  end
7
10
 
8
11
  def update_vendor_total_inventory
9
12
  SpreeCmCommissioner::VendorJob.perform_later(vendor.id) if vendor.present?
10
13
  end
14
+
15
+ private
16
+
17
+ def create_inventory_items
18
+ SpreeCmCommissioner::Stock::InventoryItemsGeneratorJob.perform_later(variant_id: variant.id)
19
+ end
20
+
21
+ # When admin delete stock item, it will deduct stock from inventory item
22
+ def adjust_inventory_items_async
23
+ params = { variant_id: variant.id, quantity: -count_on_hand }
24
+ CmAppLogger.log(label: "#{self.class.name}#adjust_inventory_items_async", data: params) do
25
+ SpreeCmCommissioner::Stock::InventoryItemsAdjusterJob.perform_later(**params)
26
+ end
27
+ end
11
28
  end
12
29
  end
13
30
 
@@ -0,0 +1,8 @@
1
+ module SpreeCmCommissioner
2
+ class TaxonBlazerQuery < SpreeCmCommissioner::Base
3
+ belongs_to :taxon, class_name: 'Spree::Taxon'
4
+ belongs_to :blazer_query, class_name: 'Blazer::Query'
5
+
6
+ validates :taxon_id, uniqueness: { scope: :blazer_query_id, message: I18n.t('event_blazer_queries.fail') }
7
+ end
8
+ end
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
2
2
  module TaxonDecorator
3
3
  def self.prepended(base) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
4
4
  base.include SpreeCmCommissioner::TaxonKind
5
- base.include SpreeCmCommissioner::Transit::TaxonBitwise
6
5
  base.include SpreeCmCommissioner::ParticipationTypeBitwise
7
- base.include SpreeCmCommissioner::EventCheckInFlowable
8
6
 
9
7
  base.preference :background_color, :string
10
8
  base.preference :foreground_color, :string
@@ -57,16 +55,14 @@ module SpreeCmCommissioner
57
55
  base.has_many :crew_invites, class_name: 'SpreeCmCommissioner::CrewInvite', dependent: :destroy
58
56
  base.has_many :invite_user_events, through: :user_events, class_name: 'SpreeCmCommissioner::InviteUserEvent'
59
57
 
60
- base.has_many :crew_invite_links, class_name: 'SpreeCmCommissioner::CrewInviteLink', dependent: :destroy
61
-
62
58
  base.has_many :invite_guests, class_name: 'SpreeCmCommissioner::InviteGuest', foreign_key: :event_id
63
59
 
64
60
  base.has_many :line_items, through: :products
65
61
  base.has_many :event_line_items, class_name: 'Spree::LineItem', foreign_key: :event_id
66
62
  base.has_many :event_products, class_name: 'Spree::Product', foreign_key: :event_id
67
63
 
68
- base.has_many :event_blazer_queries, as: :queryable, class_name: 'SpreeCmCommissioner::BlazerQueryable'
69
- base.has_many :blazer_queries, through: :event_blazer_queries, source: :blazer_query, class_name: 'Blazer::Query'
64
+ base.has_many :event_blazer_queries, class_name: 'SpreeCmCommissioner::TaxonBlazerQuery'
65
+ base.has_many :blazer_queries, through: :event_blazer_queries, class_name: 'Blazer::Query'
70
66
 
71
67
  base.has_many :taxon_option_types, class_name: 'SpreeCmCommissioner::TaxonOptionType'
72
68
  base.has_many :taxon_option_values, class_name: 'SpreeCmCommissioner::TaxonOptionValue'
@@ -8,12 +8,6 @@ module SpreeCmCommissioner
8
8
  Spree::Taxonomy.find_or_create_by(name: 'Businesses', kind: 'category', store: Spree::Store.default)
9
9
  end
10
10
  end
11
-
12
- def base.place
13
- ActiveRecord::Base.connected_to(role: :writing) do
14
- Spree::Taxonomy.find_or_create_by(name: 'Place', kind: 'transit', store: Spree::Store.default)
15
- end
16
- end
17
11
  end
18
12
  end
19
13
  end
@@ -1,6 +1,7 @@
1
- require_dependency 'spree_cm_commissioner'
2
1
  module SpreeCmCommissioner
3
- class Trip < SpreeCmCommissioner::Base
2
+ class Trip < Base
3
+ include SpreeCmCommissioner::RouteType
4
+
4
5
  attr_accessor :hours, :minutes, :seconds
5
6
 
6
7
  before_validation :convert_duration_to_seconds
@@ -10,28 +11,29 @@ module SpreeCmCommissioner
10
11
  belongs_to :origin, class_name: 'SpreeCmCommissioner::Place', optional: true
11
12
  belongs_to :destination, class_name: 'SpreeCmCommissioner::Place', optional: true
12
13
 
13
- has_many :trip_blazer_queries, as: :queryable, class_name: 'SpreeCmCommissioner::BlazerQueryable'
14
- has_many :blazer_queries, through: :trip_blazer_queries, source: :blazer_query, class_name: 'Blazer::Query'
15
-
16
14
  has_many :trip_stops, class_name: 'SpreeCmCommissioner::TripStop', dependent: :destroy
17
15
  has_many :variants, through: :product
18
16
  has_many :inventory_items, through: :variants
19
- belongs_to :variant, class_name: 'Spree::Variant'
20
-
21
- belongs_to :route, class_name: 'Spree::Product'
22
- belongs_to :vehicle, class_name: 'SpreeCmCommissioner::Vehicle'
23
- validates :departure_time, presence: true
24
17
 
25
18
  validates :departure_time, presence: true
26
19
  validates :duration, numericality: { greater_than: 0 }
27
20
  validate :origin_and_destination_cannot_be_the_same
28
21
 
22
+ accepts_nested_attributes_for :trip_stops, allow_destroy: true
23
+
24
+ after_create :create_trip_stops
25
+
29
26
  def convert_duration_to_seconds
30
27
  return if hours.blank? && minutes.blank? && seconds.blank?
31
28
 
32
29
  self.duration = (hours.to_i * 3600) + (minutes.to_i * 60) + seconds.to_i
33
30
  end
34
31
 
32
+ def create_trip_stops
33
+ trip_stops.find_or_create_by(stop_type: :boarding, stop_id: origin_id)
34
+ trip_stops.find_or_create_by(stop_type: :drop_off, stop_id: destination_id)
35
+ end
36
+
35
37
  def duration_in_hms
36
38
  return { hours: 0, minutes: 0, seconds: 0 } if duration.nil?
37
39
 
@@ -1,7 +1,7 @@
1
1
  module SpreeCmCommissioner
2
- class TripConnection < ApplicationRecord
3
- belongs_to :from_trip, class_name: 'Spree::Variant'
4
- belongs_to :to_trip, class_name: 'Spree::Variant'
2
+ class TripConnection < Base
3
+ belongs_to :from_trip, class_name: 'SpreeCmCommissioner::Trip'
4
+ belongs_to :to_trip, class_name: 'SpreeCmCommissioner::Trip'
5
5
 
6
6
  validate :both_trip_cannot_be_the_same
7
7
  before_validation :calculate_connection_time_minutes
@@ -12,8 +12,8 @@ module SpreeCmCommissioner
12
12
  def calculate_connection_time_minutes
13
13
  return if from_trip.nil? || to_trip.nil?
14
14
 
15
- arrival_seconds = from_trip.trip.arrival_time.seconds_since_midnight
16
- departure_seconds = to_trip.trip.departure_time.seconds_since_midnight
15
+ arrival_seconds = from_trip.arrival_time.seconds_since_midnight
16
+ departure_seconds = to_trip.departure_time.seconds_since_midnight
17
17
 
18
18
  layover_seconds = departure_seconds - arrival_seconds
19
19
  layover_seconds += 86_400 if layover_seconds.negative?
@@ -1,10 +1,9 @@
1
- require_dependency 'spree_cm_commissioner'
2
1
  module SpreeCmCommissioner
3
- class TripStop < SpreeCmCommissioner::Base
2
+ class TripStop < Base
4
3
  acts_as_list column: :sequence, scope: :trip_id
5
4
  enum :stop_type, { boarding: 0, drop_off: 1 }
6
5
 
7
- belongs_to :trip, class_name: 'Spree::Variant'
6
+ belongs_to :trip, class_name: 'SpreeCmCommissioner::Trip'
8
7
  belongs_to :stop, class_name: 'SpreeCmCommissioner::Place'
9
8
 
10
9
  before_validation :set_stop_name