spree_cm_commissioner 2.0.0 → 2.0.1.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 (215) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test_and_build_gem.yml +16 -2
  3. data/.gitignore +2 -1
  4. data/Gemfile.lock +32 -1
  5. data/Rakefile +33 -4
  6. data/app/assets/stylesheets/spree_cm_commissioner/backend/calendar.scss +8 -11
  7. data/app/controllers/spree/admin/inventory_items_controller.rb +83 -0
  8. data/app/controllers/spree/admin/stock_managements_controller.rb +63 -1
  9. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -1
  10. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +42 -0
  11. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +14 -31
  12. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +13 -13
  13. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  14. data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +81 -23
  15. data/app/finders/spree_cm_commissioner/accommodations/find.rb +37 -0
  16. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +32 -0
  17. data/app/interactors/spree_cm_commissioner/create_ticket.rb +5 -6
  18. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +40 -0
  19. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +25 -0
  20. data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +1 -0
  21. data/app/interactors/spree_cm_commissioner/sms.rb +1 -1
  22. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +44 -0
  23. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +13 -0
  24. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +15 -0
  25. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +75 -0
  26. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +32 -0
  27. data/app/interactors/spree_cm_commissioner/user_id_token_authenticator.rb +3 -7
  28. data/app/interactors/spree_cm_commissioner/user_id_token_checker.rb +3 -11
  29. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +6 -12
  30. data/app/interactors/spree_cm_commissioner/user_registration_with_id_token.rb +1 -7
  31. data/app/jobs/spree_cm_commissioner/application_job.rb +20 -0
  32. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +20 -0
  33. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +7 -0
  34. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +7 -0
  35. data/app/jobs/spree_cm_commissioner/sms_pin_code_job.rb +1 -1
  36. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +11 -0
  37. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +11 -0
  38. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +9 -0
  39. data/app/mailers/spree/order_mailer_decorator.rb +3 -18
  40. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +9 -15
  41. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +1 -12
  42. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +44 -0
  43. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +39 -0
  44. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +1 -3
  45. data/app/models/concerns/spree_cm_commissioner/product_type.rb +10 -0
  46. data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +1 -1
  47. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +0 -1
  48. data/app/models/spree_cm_commissioner/block.rb +23 -0
  49. data/app/models/spree_cm_commissioner/dynamic_field.rb +0 -20
  50. data/app/models/spree_cm_commissioner/guest.rb +18 -56
  51. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +1 -41
  52. data/app/models/spree_cm_commissioner/inventory.rb +11 -0
  53. data/app/models/spree_cm_commissioner/inventory_item.rb +69 -0
  54. data/app/models/spree_cm_commissioner/line_item_decorator.rb +46 -78
  55. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  56. data/app/models/spree_cm_commissioner/option_type_decorator.rb +1 -11
  57. data/app/models/spree_cm_commissioner/order_decorator.rb +30 -1
  58. data/app/models/spree_cm_commissioner/place.rb +1 -4
  59. data/app/models/spree_cm_commissioner/price_decorator.rb +9 -0
  60. data/app/models/spree_cm_commissioner/product_decorator.rb +10 -28
  61. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +41 -0
  62. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +126 -0
  63. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +36 -0
  64. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +25 -0
  65. data/app/models/spree_cm_commissioner/reserved_block.rb +30 -0
  66. data/app/models/spree_cm_commissioner/seat_layout.rb +20 -0
  67. data/app/models/spree_cm_commissioner/seat_section.rb +16 -0
  68. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +30 -0
  69. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +53 -0
  70. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +49 -0
  71. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +4 -0
  72. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +4 -0
  73. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +4 -0
  74. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +4 -0
  75. data/app/models/spree_cm_commissioner/service_calendar.rb +0 -2
  76. data/app/models/spree_cm_commissioner/state_decorator.rb +0 -1
  77. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +26 -25
  78. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +2 -1
  79. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  80. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +44 -0
  81. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +17 -0
  82. data/app/models/spree_cm_commissioner/taxon_decorator.rb +0 -1
  83. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +0 -6
  84. data/app/models/spree_cm_commissioner/trip.rb +8 -10
  85. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  86. data/app/models/spree_cm_commissioner/trip_stop.rb +6 -25
  87. data/app/models/spree_cm_commissioner/user_identity_provider.rb +4 -26
  88. data/app/models/spree_cm_commissioner/variant_block.rb +9 -0
  89. data/app/models/spree_cm_commissioner/variant_decorator.rb +37 -47
  90. data/app/models/spree_cm_commissioner/variant_options.rb +0 -23
  91. data/app/models/spree_cm_commissioner/vehicle.rb +9 -14
  92. data/app/models/spree_cm_commissioner/vendor_decorator.rb +11 -17
  93. data/app/models/spree_cm_commissioner/vendor_place.rb +9 -3
  94. data/app/queries/spree_cm_commissioner/trip_query.rb +70 -44
  95. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +3 -0
  96. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  97. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +19 -0
  98. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +2 -0
  99. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +1 -0
  100. data/app/serializers/spree/v2/tenant/user_serializer.rb +0 -1
  101. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -1
  102. data/app/services/spree_cm_commissioner/user_authenticator.rb +1 -1
  103. data/app/views/spree/admin/inventory_items/show.html.erb +72 -0
  104. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +7 -2
  105. data/app/views/spree/admin/stock_managements/calendar.html.erb +56 -0
  106. data/app/views/spree/admin/stock_managements/index.html.erb +55 -6
  107. data/app/views/spree/admin/tenant_vendors/index.html.erb +2 -9
  108. data/app/views/spree/admin/tenants/_form.html.erb +0 -9
  109. data/app/views/spree/admin/tenants/edit.html.erb +1 -2
  110. data/app/views/spree/admin/tenants/index.html.erb +1 -7
  111. data/app/views/spree/admin/vendors/_form.html.erb +0 -14
  112. data/app/views/spree/order_mailer/confirm_email.html.erb +16 -27
  113. data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +1 -5
  114. data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +4 -41
  115. data/config/initializers/paper_trail.rb +1 -0
  116. data/config/initializers/spree_permitted_attributes.rb +5 -0
  117. data/config/locales/en.yml +1 -5
  118. data/config/routes.rb +21 -2
  119. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +3 -1
  120. data/db/migrate/20250304293518_create_cm_inventory_items.rb +21 -0
  121. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +5 -0
  122. data/db/migrate/20250502025848_add_index_to_spree_products.rb +5 -0
  123. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +5 -0
  124. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +5 -0
  125. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +7 -0
  126. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +5 -0
  127. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +5 -0
  128. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +9 -0
  129. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +5 -0
  130. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +9 -0
  131. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +5 -0
  132. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +5 -0
  133. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +5 -0
  134. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +6 -0
  135. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +17 -0
  136. data/db/migrate/20250620090002_create_cm_seat_sections.rb +18 -0
  137. data/db/migrate/20250620090003_create_cm_blocks.rb +18 -0
  138. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +29 -0
  139. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +24 -0
  140. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +13 -0
  141. data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +5 -0
  142. data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +5 -0
  143. data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +5 -0
  144. data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +5 -0
  145. data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +7 -0
  146. data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +11 -0
  147. data/docker-compose.yml +1 -1
  148. data/lib/cm_app_logger.rb +11 -4
  149. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +14 -11
  150. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_cm_commissioner → spree_dashboard/spree_cm_commissioner}/utilities.js +4 -0
  151. data/lib/spree_cm_commissioner/cached_inventory_item.rb +23 -0
  152. data/lib/spree_cm_commissioner/calendar_event.rb +11 -1
  153. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +15 -0
  154. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +10 -0
  155. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  156. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +9 -0
  157. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  158. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +6 -30
  159. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +0 -36
  160. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +18 -34
  161. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +27 -0
  162. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +11 -0
  163. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +16 -0
  164. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  165. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
  166. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +11 -3
  167. data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +10 -0
  168. data/lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb +1 -1
  169. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +7 -0
  170. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +41 -19
  171. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  172. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +6 -1
  173. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +13 -1
  174. data/lib/spree_cm_commissioner/trip_query_result.rb +8 -0
  175. data/lib/spree_cm_commissioner/trip_result.rb +5 -3
  176. data/lib/spree_cm_commissioner/version.rb +1 -1
  177. data/lib/spree_cm_commissioner.rb +35 -1
  178. data/lib/tasks/create_default_non_permanent_inventory_items.rake +16 -0
  179. data/lib/tasks/ensure_correct_product_type.rake +7 -0
  180. data/lib/tasks/generate_inventory_items.rake +7 -0
  181. data/spree_cm_commissioner.gemspec +7 -0
  182. metadata +141 -38
  183. data/app/assets/images/mailer/mail.png +0 -0
  184. data/app/assets/images/mailer/tenant_phone.png +0 -0
  185. data/app/assets/images/mailer/tenant_user.png +0 -0
  186. data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +0 -44
  187. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +0 -20
  188. data/app/models/spree_cm_commissioner/branch.rb +0 -12
  189. data/app/models/spree_cm_commissioner/line_item_seat.rb +0 -10
  190. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +0 -8
  191. data/app/models/spree_cm_commissioner/stop.rb +0 -23
  192. data/app/models/spree_cm_commissioner/vehicle_seat.rb +0 -11
  193. data/app/models/spree_cm_commissioner/vehicle_type.rb +0 -76
  194. data/app/models/spree_cm_commissioner/vendor_stop.rb +0 -10
  195. data/app/queries/spree_cm_commissioner/trip_search_query.rb +0 -76
  196. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +0 -45
  197. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +0 -55
  198. data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +0 -54
  199. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +0 -11
  200. data/app/views/spree_cm_commissioner/order_mailer/tenant/_customer_info.html.erb +0 -42
  201. data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +0 -25
  202. data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +0 -19
  203. data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +0 -33
  204. data/db/migrate/20250709073455_add_email_fields_to_spree_vendors.rb +0 -6
  205. data/db/migrate/20250715103333_remove_indexes_from_cm_user_identity_providers.rb +0 -13
  206. data/db/migrate/20250718071620_add_data_fill_stage_to_dynamic_fields.rb +0 -5
  207. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +0 -12
  208. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +0 -8
  209. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +0 -8
  210. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +0 -7
  211. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +0 -14
  212. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +0 -8
  213. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +0 -8
  214. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +0 -96
  215. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +0 -11
@@ -1,11 +0,0 @@
1
- module SpreeCmCommissioner
2
- class VehicleSeat < SpreeCmCommissioner::Base
3
- belongs_to :vehicle_type, class_name: 'SpreeCmCommissioner::VehicleType', dependent: :destroy
4
- has_many :line_item_seats, class_name: 'SpreeCmCommissioner::LineItemSeat', dependent: :destroy
5
- counter_culture :vehicle_type, column_name: proc { |model|
6
- model.seat_type.in?(%w[normal vip]) && model.vehicle_type.allow_seat_selection == true ? 'vehicle_seats_count' : nil # rubocop:disable Layout/LineLength
7
- },
8
- column_names: { ['cm_vehicle_seats.seat_type IN (?)', %i[0 2]] => 'vehicle_seats_count' }
9
- enum seat_type: %i[normal empty vip driver].freeze
10
- end
11
- end
@@ -1,76 +0,0 @@
1
- module SpreeCmCommissioner
2
- class VehicleType < SpreeCmCommissioner::Base
3
- include SpreeCmCommissioner::RouteType
4
-
5
- after_commit :recalculate_vehicle_seats_count, if: -> { saved_change_to_allow_seat_selection? && allow_seat_selection }
6
- after_commit :set_vehicles_attributes
7
-
8
- has_many :vehicle_seats, class_name: 'SpreeCmCommissioner::VehicleSeat', dependent: :destroy
9
- has_many :option_value_vehicle_types, class_name: 'SpreeCmCommissioner::OptionValueVehicleType'
10
- has_many :option_values, through: :option_value_vehicle_types, class_name: 'Spree::OptionValue'
11
- has_many :vehicles, class_name: 'SpreeCmCommissioner::Vehicle', dependent: :destroy
12
- belongs_to :vendor, class_name: 'Spree::Vendor'
13
-
14
- validates :code, presence: true
15
- validates :code, uniqueness: true
16
- validates :name, presence: true
17
- validates :name, uniqueness: true
18
- accepts_nested_attributes_for :vehicle_seats, allow_destroy: true
19
-
20
- state_machine :status, initial: :draft do
21
- event :draft do
22
- transition to: :draft
23
- end
24
- after_transition to: :draft, do: :after_draft
25
-
26
- event :activate do
27
- transition to: :active
28
- end
29
- after_transition to: :active, do: :after_activate
30
-
31
- event :archive do
32
- transition to: :archived
33
- end
34
- after_transition to: :archived, do: :after_archive
35
- end
36
-
37
- self.whitelisted_ransackable_attributes = %w[name code route_type id status]
38
-
39
- def after_activate; end
40
- def after_archive; end
41
- def after_draft; end
42
-
43
- def set_vehicles_attributes
44
- vehicles.each(&:set_attributes)
45
- vehicles.each(&:save)
46
- end
47
-
48
- def recalculate_vehicle_seats_count
49
- self.vehicle_seats_count = vehicle_seats.where(seat_type: %w[normal vip]).count
50
- save
51
- end
52
-
53
- def seat_layers
54
- grouped_seats = SpreeCmCommissioner::VehicleSeat.where(vehicle_type_id: id).group_by(&:layer).transform_values do |seats|
55
- seats.group_by(&:row).transform_values do |row_seats|
56
- row_seats.sort_by(&:column).map do |seat|
57
- {
58
- row: seat.row,
59
- column: seat.column,
60
- label: seat.label,
61
- layer: seat.layer,
62
- seat_type: seat.seat_type,
63
- created_at: seat.created_at,
64
- vehicle_type_id: seat.vehicle_type_id
65
- }
66
- end
67
- end
68
- end
69
- grouped_seats.map do |_layer, layer_seats|
70
- layer_seats.map do |_row, row_seats|
71
- row_seats
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,10 +0,0 @@
1
- require_dependency 'spree_cm_commissioner'
2
- module SpreeCmCommissioner
3
- class VendorStop < ApplicationRecord
4
- belongs_to :vendor, class_name: 'Spree::Vendor'
5
- belongs_to :stop, class_name: 'SpreeCmCommissioner::Place'
6
-
7
- validates :trip_count, numericality: { greater_than_or_equal_to: 0 }
8
- enum :stop_type, { boarding: 0, drop_off: 1 }
9
- end
10
- end
@@ -1,76 +0,0 @@
1
- module SpreeCmCommissioner
2
- class TripSearchQuery
3
- attr_reader :origin_id, :destination_id, :vendor_id, :date
4
-
5
- def initialize(origin_id:, destination_id:, date:, vendor_id: nil)
6
- @origin_id = origin_id
7
- @destination_id = destination_id
8
- @vendor_id = vendor_id
9
- @date = date
10
- end
11
-
12
- def call
13
- trips_info.map do |trip|
14
- trip_result_options = {
15
- trip_id: trip.trip_id,
16
- vendor_id: trip.vendor_id,
17
- vendor_name: trip.vendor_name,
18
- route_name: trip.route_name,
19
- short_name: trip.short_name,
20
- detail: trip.trip_id,
21
- origin_id: trip.origin_id,
22
- origin: trip.origin,
23
- destination_id: trip.destination_id,
24
- destination: trip.destination,
25
- total_sold: trip.total_sold,
26
- total_seats: trip.total_seats,
27
- vehicle_id: trip.vehicle_id,
28
- departure_time: trip.departure_time.strftime('%H:%M'),
29
- duration: trip.duration
30
- }
31
- SpreeCmCommissioner::TripResult.new(trip_result_options)
32
- end
33
- end
34
-
35
- def trips_info
36
- result = Spree::Variant.select('spree_variants.id as trip_id,
37
- spree_vendors.id as vendor_id,
38
- spree_vendors.name as vendor_name,
39
- routes.name as route_name,
40
- routes.short_name as short_name,
41
- details.id as detail_id,
42
- boarding.stop_id as origin_id,
43
- drop_off.stop_id as destination_id,
44
- details.departure_time as departure_time,
45
- details.duration as duration,
46
- boarding.stop_name as origin,
47
- drop_off.stop_name as destination,
48
- COALESCE(ts.total_sold, 0) as total_sold,
49
- cm_vehicles.number_of_seats as total_seats,
50
- cm_vehicles.id as vehicle_id
51
- '
52
- )
53
- .joins('INNER JOIN spree_products routes ON routes.id = spree_variants.product_id')
54
- .joins('INNER JOIN cm_trips details on details.product_id = routes.id')
55
- .joins('INNER JOIN cm_vehicles ON cm_vehicles.id = details.vehicle_id')
56
- .joins("INNER JOIN cm_trip_stops boarding ON boarding.trip_id = details.id AND boarding.stop_type = '0'")
57
- .joins("INNER JOIN cm_trip_stops drop_off ON drop_off.trip_id = details.id AND drop_off.stop_type = '1'")
58
- .joins('INNER JOIN spree_vendors ON spree_vendors.id = spree_variants.vendor_id')
59
- .joins("LEFT JOIN (#{total_sold.to_sql}) ts ON spree_variants.id = ts.trip_id")
60
-
61
- # TODO: migrat to new table: vehicle, orign and destination
62
- result = result.where(boarding: { stop_id: origin_id }, drop_off: { stop_id: destination_id })
63
- result = result.where(vendor_id: vendor_id) if vendor_id.present?
64
- result
65
- end
66
-
67
- def total_sold
68
- Spree::Variant.select('spree_variants.id as trip_id, SUM(spree_line_items.quantity) as total_sold')
69
- .joins('INNER JOIN spree_line_items ON spree_line_items.variant_id = spree_variants.id')
70
- .joins('INNER JOIN spree_orders ON spree_orders.id = spree_line_items.order_id')
71
- .where(spree_orders: { state: 'complete' })
72
- .where(spree_line_items: { date: date })
73
- .group('spree_variants.id')
74
- end
75
- end
76
- end
@@ -1,45 +0,0 @@
1
- module SpreeCmCommissioner
2
- module VariantAvailability
3
- class NonPermanentStockQuery
4
- attr_reader :variant, :except_line_item_id, :error_message
5
-
6
- def initialize(variant:, except_line_item_id: nil)
7
- @variant = variant
8
- @except_line_item_id = except_line_item_id
9
- @error_message = nil
10
- end
11
-
12
- def available?(quantity)
13
- reserve_variants =
14
- Spree::LineItem
15
- .complete
16
- .select('(SUM(DISTINCT spree_stock_items.count_on_hand) - SUM(spree_line_items.quantity)) AS available_quantity')
17
- .joins(variant: :stock_items)
18
- .where(variant_id: variant.id)
19
- .where.not(id: except_line_item_id)
20
- .group(:variant_id)
21
-
22
- # there is a case when variant does not have any purchaces yet, it will return empty & always available true.
23
- # in this case, we check with stock items directly.
24
-
25
- available_quantity = if reserve_variants.any?
26
- reserve_variants.sum(&:available_quantity)
27
- else
28
- variant.stock_items.sum(:count_on_hand)
29
- end
30
- if available_quantity >= quantity
31
- true
32
- elsif available_quantity == 1
33
- @error_message = I18n.t('variant_availability.item_available_instock')
34
- false
35
- elsif available_quantity <= 0
36
- @error_message = I18n.t('variant_availability.items_out_of_stock')
37
- false
38
- else
39
- @error_message = I18n.t('variant_availability.items_available_instock', available_quantity: available_quantity)
40
- false
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,55 +0,0 @@
1
- module SpreeCmCommissioner
2
- module VariantAvailability
3
- class PermanentStockQuery
4
- attr_reader :variant, :from_date, :to_date, :except_line_item_id
5
-
6
- def initialize(variant:, from_date:, to_date:, except_line_item_id: nil)
7
- @variant = variant
8
- @from_date = from_date
9
- @to_date = to_date
10
- @except_line_item_id = except_line_item_id
11
- end
12
-
13
- def available?(quantity)
14
- (from_date..from_date).all? do |booking_date|
15
- booked_date_quantity[booking_date].nil? ||
16
- (booked_date_quantity[booking_date] - quantity) >= 0
17
- end
18
- end
19
-
20
- def booked_date_quantity
21
- dates_sql = ApplicationRecord.sanitize_sql_array(
22
- [
23
- 'SELECT date FROM generate_series(?::date, ?::date, ?) AS date',
24
- from_date,
25
- to_date,
26
- date_interval
27
- ]
28
- )
29
-
30
- @booked_variants ||=
31
- Spree::LineItem
32
- .complete
33
- .select(
34
- '(SUM(DISTINCT spree_stock_items.count_on_hand) - SUM(spree_line_items.quantity)) AS available_quantity',
35
- 'dates.date AS reservation_date'
36
- )
37
- .joins(variant: :stock_items)
38
- .where(variant_id: variant.id)
39
- .where.not(id: except_line_item_id)
40
- .joins("INNER JOIN (#{dates_sql}) dates ON dates.date >= spree_line_items.from_date AND dates.date < spree_line_items.to_date")
41
- .group(:variant_id, :reservation_date)
42
- .order(:reservation_date)
43
- .each_with_object({}) do |record, hash|
44
- hash[record.reservation_date.to_date] = record.available_quantity
45
- end
46
- end
47
-
48
- # override this for product that have
49
- # different date time interval than 1 day.
50
- def date_interval
51
- '1 day'
52
- end
53
- end
54
- end
55
- end
@@ -1,54 +0,0 @@
1
- module SpreeCmCommissioner
2
- class VendorStopPlaceQuery
3
- attr_reader :query, :vendor_id, :stop_type, :reference_stop_id
4
-
5
- def initialize(query:, vendor_id:, stop_type: :boarding, reference_stop_id: nil)
6
- @query = query.to_s.strip
7
- @vendor_id = vendor_id
8
- @stop_type = stop_type
9
- @reference_stop_id = reference_stop_id
10
- end
11
-
12
- def call
13
- results = vendor_stops
14
- return [] if results.empty?
15
-
16
- places = results.includes(:stop).map(&:stop).compact.uniq
17
-
18
- format_places(places)
19
- end
20
-
21
- private
22
-
23
- def vendor_stops
24
- scope = base_scope
25
- return scope if query.blank?
26
-
27
- scope = scope.where.not(stop_id: reference_stop_id) if reference_stop_id.present?
28
- scope.where('cm_places.name ILIKE ?', "%#{query}%")
29
- end
30
-
31
- def base_scope
32
- SpreeCmCommissioner::VendorStop
33
- .joins(:stop)
34
- .where(vendor_id: vendor_id)
35
- .where(stop_type: stop_type)
36
- .order(trip_count: :desc)
37
- .where.not(trip_count: 0)
38
- end
39
-
40
- def format_places(places)
41
- places
42
- .sort_by { |p| [-p.depth, -p.lft] }
43
- .filter_map do |place|
44
- next if place.depth.zero?
45
-
46
- {
47
- id: place.id,
48
- parent_id: place.parent_id,
49
- name: place.self_and_ancestors.map(&:name).reverse.join(', ')
50
- }
51
- end
52
- end
53
- end
54
- end
@@ -1,11 +0,0 @@
1
- module SpreeCmCommissioner
2
- class VehicleOptionValueCreator
3
- def self.call(vehicle)
4
- vehicle_option_type = Spree::OptionType.vehicle
5
-
6
- value = vehicle_option_type.option_values.where(name: vehicle.id).first_or_initialize
7
- value.presentation = vehicle.code
8
- value.save
9
- end
10
- end
11
- end
@@ -1,42 +0,0 @@
1
- <div class="content-cell">
2
- <div class="container">
3
- <h2><%= I18n.t('mail.order_mailer.customer_info') %></h2>
4
- <div class="flex two-columns">
5
- <div class="two-columns-item">
6
- <div class="flex two-columns-item_detail">
7
- <div class="two-columns_icon"><%= image_tag "mailer/tenant_user.png", class: "mail-icon" %></div>
8
- <div class="two-columns_text-container">
9
- <p class="two-columns_title">Name</p>
10
- <p class="two-columns_description"><%= user_full_name(order) %></p>
11
- </div>
12
- </div>
13
- <div class="flex two-columns-item_detail">
14
- <div class="two-columns_icon"><%= image_tag "mailer/mail.png", class: "mail-icon" %></div>
15
- <div class="two-columns_text-container">
16
- <p class="two-columns_title">Email</p>
17
- <% if order.email.present? %>
18
- <p class="two-columns_description"><%= link_to order.email, "mailto:#{order.email}" %></p>
19
- <% end %>
20
- </div>
21
- </div>
22
- </div>
23
- <div class="vertical-separater"></div>
24
- <div class="two-columns-item">
25
- <div class="flex two-columns-item_detail">
26
- <div class="two-columns_icon"><%= image_tag "mailer/tenant_phone.png", class: "mail-icon" %></div>
27
- <div class="two-columns_text-container">
28
- <p class="two-columns_title">Contact</p>
29
- <% if order.phone_number.present? || order.intel_phone_number.present? %>
30
- <p class="two-columns_description">
31
- <%= link_to(
32
- order.phone_number || order.intel_phone_number,
33
- "tel:#{order.phone_number || order.intel_phone_number}") %>
34
- </p>
35
- <% end %>
36
- </div>
37
- </div>
38
- </div>
39
- </div>
40
- <hr>
41
- </div>
42
- </div>
@@ -1,25 +0,0 @@
1
- <div class="email-footer_inner">
2
- <div class="mb-24"><%= store.description%></div>
3
- <div class="mb-24 f-14"><%= store.address%></div>
4
- <h2 class="mb-24">Connect with us</h2>
5
- <table class="mb-24 social_icons">
6
- <tbody>
7
- <tr>
8
- <% if store.facebook? %>
9
- <td class="social_icon">
10
- <%= link_to store.facebook, target: :_blank do %>
11
- <%= image_tag "mailer/facebook.png", class: "mail-icon"%>
12
- <% end %>
13
- </td>
14
- <% end %>
15
- <% if store.instagram?%>
16
- <td class="social_icon">
17
- <%= link_to store.instagram, target: :_blank do %>
18
- <%= image_tag "mailer/instagram.png", class: "mail-icon"%>
19
- <% end %>
20
- </td>
21
- <% end %>
22
- </tr>
23
- </tbody>
24
- </table>
25
- </div>
@@ -1,19 +0,0 @@
1
- <div id="greeting-card-1">
2
- <div>
3
- <div class="header">
4
- <h1><%=@order.store.name %></h1>
5
- <% if @vendor_logo_url.present? %>
6
- <img src="<%= @vendor_logo_url %>" alt="Vendor Logo" class="icon-hang-meas">
7
- <% end %>
8
- </div>
9
- <div class="booking-confirm">
10
- <%= I18n.t('mail.order_mailer.booking_confirm') %>
11
- </div>
12
- <div class="hello">
13
- <%= I18n.t('mail.order_mailer.hello', full_name: user_full_name(order)) %>
14
- </div>
15
- <div class="description">
16
- <%= I18n.t('mail.order_mailer.booking_event', order_number: @order.number || 'NA') %>
17
- </div>
18
- </div>
19
- </div>
@@ -1,33 +0,0 @@
1
- <div class="content-cell">
2
- <div class="container">
3
- <h2><%= I18n.t('mail.order_mailer.bookmeplus_support')%></h2>
4
- <div class="flex two-columns">
5
- <div class="two-columns-item">
6
- <div class="flex two-columns-item_detail">
7
- <div class="two-columns_icon"><%= image_tag "mailer/tenant_phone.png", class: "mail-icon"%></div>
8
- <div class="two-columns_text-container">
9
- <p class="two-columns_title">Contact</p>
10
- <% if current_store.contact_phone.present? %>
11
- <p class="two-columns_description">
12
- <%= link_to current_store.contact_phone, "tel:#{current_store.contact_phone}" %>
13
- </p>
14
- <% end %>
15
- </div>
16
- </div>
17
- </div>
18
- <div class="vertical-separater"></div>
19
- <div class="two-columns-item">
20
- <div class="flex two-columns-item_detail">
21
- <div class="two-columns_icon"><%= image_tag "mailer/mail.png", class: "mail-icon"%></div>
22
- <div class="two-columns_text-container">
23
- <p class="two-columns_title">Email</p>
24
- <p class="two-columns_description">
25
- <%= @vendor&.support_email.present? ? link_to(@vendor.support_email, "mailto:#{@vendor.support_email}") : "N/A" %>
26
- </p>
27
-
28
- </div>
29
- </div>
30
- </div>
31
- </div>
32
- </div>
33
- </div>
@@ -1,6 +0,0 @@
1
- class AddEmailFieldsToSpreeVendors < ActiveRecord::Migration[7.0]
2
- def change
3
- add_column :spree_vendors, :from_email, :string, if_not_exists: true
4
- add_column :spree_vendors, :support_email, :string, if_not_exists: true
5
- end
6
- end
@@ -1,13 +0,0 @@
1
- class RemoveIndexesFromCmUserIdentityProviders < ActiveRecord::Migration[7.0]
2
- def change
3
- execute <<-SQL
4
- ALTER TABLE cm_user_identity_providers
5
- DROP CONSTRAINT IF EXISTS index_cm_user_identity_providers_on_identity_type_and_sub;
6
- SQL
7
-
8
- execute <<-SQL
9
- ALTER TABLE cm_user_identity_providers
10
- DROP CONSTRAINT IF EXISTS index_cm_user_identity_providers_on_user_id_and_identity_type;
11
- SQL
12
- end
13
- end
@@ -1,5 +0,0 @@
1
- class AddDataFillStageToDynamicFields < ActiveRecord::Migration[7.0]
2
- def change
3
- add_column :cm_dynamic_fields, :data_fill_stage, :integer, default: 0, null: false, if_not_exists: true
4
- end
5
- end
@@ -1,12 +0,0 @@
1
- FactoryBot.define do
2
-
3
- factory :cm_branch , class: SpreeCmCommissioner::Branch do
4
- name { 'testBranch'}
5
- lat { 11.11 }
6
- lon { 11.11}
7
- formatted_phone_number { generate(:phone_number) }
8
- formatted_address { "test_address" }
9
- state
10
- vendor
11
- end
12
- end
@@ -1,8 +0,0 @@
1
- FactoryBot.define do
2
- factory :departure_time, class: Spree::OptionType do
3
- name { 'departure_time' }
4
- attr_type { 'departure_time' }
5
- kind {'variant'}
6
- presentation { '' }
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- FactoryBot.define do
2
- factory :duration, class: Spree::OptionType do
3
- name { 'duration' }
4
- attr_type { 'duration' }
5
- kind {'variant'}
6
- presentation { '' }
7
- end
8
- end
@@ -1,7 +0,0 @@
1
- FactoryBot.define do
2
- factory :line_item_seat, class: SpreeCmCommissioner::LineItemSeat do
3
- line_item_id {}
4
- seat_id {}
5
- date { Date.today }
6
- end
7
- end
@@ -1,14 +0,0 @@
1
- FactoryBot.define do
2
-
3
- factory :cm_stop , class: SpreeCmCommissioner::Stop do
4
- code { 'TS'}
5
- name { 'testStop'}
6
- formatted_phone_number { generate(:phone_number) }
7
- formatted_address { "test_address" }
8
- lat { 11.11 }
9
- lon { 11.11}
10
- branch { create(:cm_branch) }
11
- state
12
- vendor
13
- end
14
- end
@@ -1,8 +0,0 @@
1
- FactoryBot.define do
2
- factory :transit_place, class: Spree::Taxon do
3
- transient do
4
- taxonomy { Spree::Taxonomy.place}
5
- end
6
- parent{ taxonomy.root }
7
- end
8
- end
@@ -1,8 +0,0 @@
1
- FactoryBot.define do
2
- factory :vehicle_option_type, class: Spree::OptionType do
3
- name { 'vehicle_option_type' }
4
- attr_type { 'vehicle' }
5
- kind {'variant'}
6
- presentation { '' }
7
- end
8
- end
@@ -1,96 +0,0 @@
1
- FactoryBot.define do
2
- factory :vehicle_type, class: SpreeCmCommissioner::VehicleType do
3
- name { FFaker::Name.name }
4
- route_type {"automobile"}
5
- status {"active"}
6
- end
7
-
8
- trait :with_layers do
9
- transient do
10
- layers {[
11
- {row: 1, column: 1, empty: [[]], label: 'F', layer_name: "First Layer"},
12
- {row: 1, column: 1, empty: [[]], label: 'S', layer_name: "Second Layer"}
13
- ]}
14
- end
15
- after(:create) do |vehicle_type, evaluator|
16
- layers = evaluator.layers || [{}]
17
- layers.each_with_index do |layer, index|
18
-
19
- row = layer[:row]
20
- column = layer[:column]
21
- empty_seats = layer[:empty] || []
22
- label_counter = 1
23
- layer_name = layer[:layer_name]
24
- row.times do |r|
25
- column.times do |c|
26
- label = "#{layer[:label]}#{label_counter}"
27
- seat_type = 0
28
- if empty_seats.include?([r, c])
29
- seat_type = 1
30
- label = "NA"
31
- label_counter -= 1
32
- end
33
- if (r == 0 && c == 0 && index == 0)
34
- seat_type = 3
35
- label = "NA"
36
- label_counter -= 1
37
- end
38
- seat = {
39
- "row": r + 1,
40
- "column": c + 1,
41
- "label": label,
42
- "layer": layer_name,
43
- "seat_type": seat_type,
44
- "vehicle_type_id": vehicle_type.id
45
- }
46
-
47
- label_counter += 1
48
- SpreeCmCommissioner::VehicleSeat.create(seat)
49
- end
50
- end
51
- vehicle_type.reload
52
- end
53
- end
54
- end
55
-
56
- trait :with_seats do
57
- transient do
58
- row { 1 }
59
- column { 1 }
60
- empty { [[]] }
61
- end
62
-
63
- after(:create) do |vehicle_type, evaluator|
64
- label_counter = 1
65
- empty_seats = evaluator.empty || []
66
- evaluator.row.times do |r|
67
- evaluator.column.times do |c|
68
- seat_type = 0
69
- label = "F#{label_counter}"
70
- if empty_seats.include?([r, c])
71
- seat_type = 1
72
- label = "NA"
73
- label_counter -= 1
74
- end
75
- if (r == 0 && c == 0)
76
- seat_type = 3
77
- label = "NA"
78
- label_counter -= 1
79
- end
80
- seat = {
81
- "row": r + 1,
82
- "column": c + 1,
83
- "label": label,
84
- "layer": "First Layer",
85
- "seat_type": seat_type,
86
- "vehicle_type_id": vehicle_type.id
87
- }
88
-
89
- label_counter += 1
90
- SpreeCmCommissioner::VehicleSeat.create(seat)
91
- end
92
- end
93
- vehicle_type.reload
94
- end
95
- end
96
- end