spree_cm_commissioner 2.0.0.pre.pre → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +3 -0
  3. data/.github/workflows/test_and_build_gem.yml +2 -16
  4. data/.gitignore +1 -2
  5. data/Gemfile.lock +1 -32
  6. data/Rakefile +4 -33
  7. data/app/assets/images/cm-hangmeas-checkout_image.svg +63 -0
  8. data/app/assets/images/cm-hangmeas-failed.svg +56 -0
  9. data/app/assets/images/cm-hangmeas-loader.svg +50 -0
  10. data/app/assets/images/cm-hangmeas-success.svg +51 -0
  11. data/app/assets/images/mailer/mail.png +0 -0
  12. data/app/assets/images/mailer/tenant_phone.png +0 -0
  13. data/app/assets/images/mailer/tenant_user.png +0 -0
  14. data/app/assets/javascripts/spree_cm_commissioner/backend.js +1 -0
  15. data/app/assets/javascripts/spree_cm_commissioner/tenant_payment_icon_fields.js +65 -0
  16. data/app/assets/stylesheets/spree_cm_commissioner/backend/calendar.scss +11 -8
  17. data/app/assets/stylesheets/spree_cm_commissioner/backend/commissioner_admin.css.scss +1 -0
  18. data/app/assets/stylesheets/spree_cm_commissioner/backend/tenant_payment_icon_fields.scss +60 -0
  19. data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +2 -1
  20. data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +44 -0
  21. data/app/controllers/spree/admin/event_blazer_queries_controller.rb +11 -4
  22. data/app/controllers/spree/admin/stock_managements_controller.rb +1 -63
  23. data/app/controllers/spree/admin/tenants_controller.rb +8 -0
  24. data/app/controllers/spree/admin/trip_blazer_queries_controller.rb +35 -0
  25. data/app/controllers/spree/api/v2/organizer/invite_crews_controller.rb +33 -0
  26. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -1
  27. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +31 -14
  28. data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +5 -1
  29. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +30 -4
  30. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  31. data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +2 -0
  32. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
  33. data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +11 -0
  34. data/app/controllers/spree_cm_commissioner/well_known_controller.rb +31 -17
  35. data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +23 -81
  36. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +20 -0
  37. data/app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb +27 -0
  38. data/app/interactors/spree_cm_commissioner/asset_links_fetcher.rb +27 -0
  39. data/app/interactors/spree_cm_commissioner/create_ticket.rb +6 -5
  40. data/app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb +48 -0
  41. data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +0 -1
  42. data/app/interactors/spree_cm_commissioner/sms.rb +1 -1
  43. data/app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb +144 -0
  44. data/app/interactors/spree_cm_commissioner/user_id_token_authenticator.rb +7 -3
  45. data/app/interactors/spree_cm_commissioner/user_id_token_checker.rb +11 -3
  46. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +12 -6
  47. data/app/interactors/spree_cm_commissioner/user_registration_with_id_token.rb +7 -1
  48. data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +5 -1
  49. data/app/jobs/spree_cm_commissioner/application_job.rb +0 -20
  50. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +0 -20
  51. data/app/jobs/spree_cm_commissioner/sms_pin_code_job.rb +1 -1
  52. data/app/mailers/spree/order_mailer_decorator.rb +18 -3
  53. data/app/models/concerns/spree_cm_commissioner/event_check_in_flowable.rb +30 -0
  54. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +15 -9
  55. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +13 -1
  56. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -39
  57. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +3 -1
  58. data/app/models/concerns/spree_cm_commissioner/product_type.rb +0 -10
  59. data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +1 -1
  60. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +5 -0
  61. data/app/models/spree_cm_commissioner/blazer_queryable.rb +8 -0
  62. data/app/models/spree_cm_commissioner/branch.rb +12 -0
  63. data/app/models/spree_cm_commissioner/crew_invite_link.rb +4 -0
  64. data/app/models/spree_cm_commissioner/dynamic_field.rb +37 -3
  65. data/app/models/spree_cm_commissioner/dynamic_field_option.rb +7 -1
  66. data/app/models/spree_cm_commissioner/guest.rb +57 -19
  67. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +61 -3
  68. data/app/models/spree_cm_commissioner/invite.rb +4 -6
  69. data/app/models/spree_cm_commissioner/invite_team.rb +3 -1
  70. data/app/models/spree_cm_commissioner/line_item_decorator.rb +78 -46
  71. data/app/models/spree_cm_commissioner/line_item_seat.rb +10 -0
  72. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  73. data/app/models/spree_cm_commissioner/option_type_decorator.rb +11 -1
  74. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +8 -0
  75. data/app/models/spree_cm_commissioner/order_decorator.rb +1 -30
  76. data/app/models/spree_cm_commissioner/pin_code.rb +3 -2
  77. data/app/models/spree_cm_commissioner/pin_code_telegram.rb +28 -0
  78. data/app/models/spree_cm_commissioner/place.rb +3 -1
  79. data/app/models/spree_cm_commissioner/product_decorator.rb +26 -10
  80. data/app/models/spree_cm_commissioner/promotion_category_decorator.rb +11 -0
  81. data/app/models/spree_cm_commissioner/service_calendar.rb +2 -0
  82. data/app/models/spree_cm_commissioner/state_decorator.rb +1 -0
  83. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +25 -26
  84. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +1 -2
  85. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  86. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +0 -17
  87. data/app/models/spree_cm_commissioner/stop.rb +23 -0
  88. data/app/models/spree_cm_commissioner/taxon_decorator.rb +6 -2
  89. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +6 -0
  90. data/app/models/spree_cm_commissioner/telegram_chat.rb +6 -0
  91. data/app/models/spree_cm_commissioner/trip.rb +10 -12
  92. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  93. data/app/models/spree_cm_commissioner/trip_stop.rb +3 -2
  94. data/app/models/spree_cm_commissioner/user_identity_provider.rb +26 -4
  95. data/app/models/spree_cm_commissioner/user_taxon.rb +1 -0
  96. data/app/models/spree_cm_commissioner/variant_decorator.rb +47 -36
  97. data/app/models/spree_cm_commissioner/variant_options.rb +23 -0
  98. data/app/models/spree_cm_commissioner/vehicle.rb +14 -9
  99. data/app/models/spree_cm_commissioner/vehicle_seat.rb +11 -0
  100. data/app/models/spree_cm_commissioner/vehicle_type.rb +76 -0
  101. data/app/models/spree_cm_commissioner/vendor_decorator.rb +13 -7
  102. data/app/models/spree_cm_commissioner/vendor_place.rb +5 -6
  103. data/app/models/spree_cm_commissioner/vendor_stop.rb +2 -1
  104. data/app/overrides/spree/admin/taxons/_form/check_in_flows.html.erb.deface +18 -0
  105. data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +2 -2
  106. data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +45 -3
  107. data/app/queries/spree_cm_commissioner/trip_query.rb +26 -23
  108. data/app/queries/spree_cm_commissioner/trip_search_query.rb +76 -0
  109. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +45 -0
  110. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +55 -0
  111. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +0 -3
  112. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  113. data/app/serializers/spree/v2/organizer/invite_crews_serializer.rb +11 -0
  114. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +0 -2
  115. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +0 -1
  116. data/app/serializers/spree/v2/tenant/user_serializer.rb +1 -0
  117. data/app/serializers/spree_cm_commissioner/v2/operator/dashboard_crew_event_serializer.rb +4 -1
  118. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +1 -3
  119. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -3
  120. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +2 -1
  121. data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +23 -15
  122. data/app/services/spree_cm_commissioner/user_authenticator.rb +1 -1
  123. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +11 -0
  124. data/app/views/blazer/queries/_content.html.erb +8 -0
  125. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +2 -7
  126. data/app/views/spree/admin/stock_managements/index.html.erb +6 -55
  127. data/app/views/spree/admin/tenant_vendors/index.html.erb +9 -2
  128. data/app/views/spree/admin/tenants/_form.html.erb +118 -42
  129. data/app/views/spree/admin/tenants/edit.html.erb +2 -1
  130. data/app/views/spree/admin/tenants/index.html.erb +7 -1
  131. data/app/views/spree/admin/vendors/_form.html.erb +14 -0
  132. data/app/views/spree/order_mailer/confirm_email.html.erb +27 -16
  133. data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +5 -1
  134. data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +41 -4
  135. data/app/views/spree_cm_commissioner/order_mailer/tenant/_customer_info.html.erb +42 -0
  136. data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +25 -0
  137. data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +19 -0
  138. data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +33 -0
  139. data/config/initializers/spree_permitted_attributes.rb +2 -5
  140. data/config/locales/en.yml +10 -1
  141. data/config/routes.rb +6 -22
  142. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +1 -3
  143. data/db/migrate/20250616084219_add_description_to_cm_vendor_place.rb +5 -0
  144. data/db/migrate/20250630103536_create_cm_telegram_chats.rb +13 -0
  145. data/db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb +6 -0
  146. data/db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb +5 -0
  147. data/db/migrate/20250702091935_add_status_to_dynamic_field_option.rb +5 -0
  148. data/db/migrate/20250707032008_add_vendor_id_to_spree_category.rb +7 -0
  149. data/db/migrate/20250709073455_add_email_fields_to_spree_vendors.rb +6 -0
  150. data/db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb +11 -0
  151. data/db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb +11 -0
  152. data/db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb +7 -0
  153. data/db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb +19 -0
  154. data/db/migrate/20250715103333_remove_indexes_from_cm_user_identity_providers.rb +13 -0
  155. data/db/migrate/20250718071620_add_data_fill_stage_to_dynamic_fields.rb +5 -0
  156. data/docker-compose.yml +1 -1
  157. data/lib/cm_app_logger.rb +4 -11
  158. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +11 -14
  159. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_dashboard/spree_cm_commissioner → spree_cm_commissioner}/utilities.js +0 -4
  160. data/lib/spree_cm_commissioner/calendar_event.rb +1 -11
  161. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +12 -0
  162. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +8 -0
  163. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +8 -0
  164. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +0 -10
  165. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  166. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  167. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +7 -0
  168. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +30 -6
  169. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +36 -0
  170. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +34 -18
  171. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  172. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +14 -0
  173. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +8 -0
  174. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +3 -10
  175. data/lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb +1 -1
  176. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +19 -41
  177. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  178. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +8 -0
  179. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +96 -0
  180. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -1
  181. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +11 -0
  182. data/lib/spree_cm_commissioner/version.rb +1 -1
  183. data/lib/spree_cm_commissioner.rb +1 -35
  184. data/spree_cm_commissioner.gemspec +0 -7
  185. metadata +66 -135
  186. data/app/controllers/spree/admin/inventory_items_controller.rb +0 -83
  187. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +0 -42
  188. data/app/finders/spree_cm_commissioner/accommodations/find.rb +0 -37
  189. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +0 -32
  190. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +0 -40
  191. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +0 -25
  192. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +0 -44
  193. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +0 -13
  194. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +0 -15
  195. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +0 -75
  196. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +0 -32
  197. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +0 -7
  198. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +0 -7
  199. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +0 -11
  200. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +0 -11
  201. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +0 -9
  202. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +0 -44
  203. data/app/models/spree_cm_commissioner/block.rb +0 -23
  204. data/app/models/spree_cm_commissioner/inventory.rb +0 -11
  205. data/app/models/spree_cm_commissioner/inventory_item.rb +0 -69
  206. data/app/models/spree_cm_commissioner/price_decorator.rb +0 -9
  207. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +0 -41
  208. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +0 -126
  209. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +0 -36
  210. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +0 -25
  211. data/app/models/spree_cm_commissioner/reserved_block.rb +0 -30
  212. data/app/models/spree_cm_commissioner/seat_layout.rb +0 -20
  213. data/app/models/spree_cm_commissioner/seat_section.rb +0 -16
  214. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +0 -30
  215. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +0 -53
  216. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +0 -49
  217. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +0 -4
  218. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +0 -4
  219. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +0 -4
  220. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +0 -4
  221. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +0 -44
  222. data/app/models/spree_cm_commissioner/taxon_blazer_query.rb +0 -8
  223. data/app/models/spree_cm_commissioner/variant_block.rb +0 -9
  224. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +0 -19
  225. data/app/views/spree/admin/inventory_items/show.html.erb +0 -72
  226. data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -56
  227. data/config/initializers/paper_trail.rb +0 -1
  228. data/db/migrate/20250304293518_create_cm_inventory_items.rb +0 -21
  229. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +0 -5
  230. data/db/migrate/20250502025848_add_index_to_spree_products.rb +0 -5
  231. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +0 -5
  232. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +0 -5
  233. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +0 -7
  234. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +0 -5
  235. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +0 -5
  236. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +0 -9
  237. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +0 -5
  238. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +0 -9
  239. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +0 -5
  240. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +0 -5
  241. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +0 -5
  242. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +0 -6
  243. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +0 -17
  244. data/db/migrate/20250620090002_create_cm_seat_sections.rb +0 -18
  245. data/db/migrate/20250620090003_create_cm_blocks.rb +0 -18
  246. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +0 -29
  247. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +0 -24
  248. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +0 -13
  249. data/lib/spree_cm_commissioner/cached_inventory_item.rb +0 -23
  250. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +0 -9
  251. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +0 -9
  252. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +0 -27
  253. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +0 -8
  254. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +0 -8
  255. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +0 -6
  256. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +0 -7
  257. data/lib/tasks/create_default_non_permanent_inventory_items.rake +0 -16
  258. data/lib/tasks/ensure_correct_product_type.rake +0 -7
  259. data/lib/tasks/generate_inventory_items.rake +0 -7
@@ -0,0 +1,45 @@
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
@@ -0,0 +1,55 @@
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
@@ -3,9 +3,6 @@ module SpreeCmCommissioner
3
3
  params do
4
4
  required(:from_date).value(:date)
5
5
  required(:to_date).value(:date)
6
- required(:province_id).value(:integer)
7
- required(:adult).value(:integer)
8
- required(:children).value(:integer)
9
6
  end
10
7
 
11
8
  rule(:from_date, :to_date) do
@@ -11,7 +11,7 @@ module SpreeCmCommissioner
11
11
  end
12
12
 
13
13
  def error_message
14
- errors.map { |error| "#{error.path.join(', ')}: #{error.text}" }.to_sentence
14
+ errors.map(&:text).join(', ')
15
15
  end
16
16
 
17
17
  private
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Organizer
4
+ class InviteCrewsSerializer < BaseSerializer
5
+ attributes :token, :expires_at
6
+ belongs_to :taxon, serializer: Spree::V2::Organizer::TaxonSerializer
7
+ belongs_to :inviter, serializer: Spree::V2::Organizer::UserSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -9,12 +9,10 @@ module Spree
9
9
 
10
10
  attributes :total_inventory, :service_availabilities
11
11
 
12
- # Deprecated
13
12
  attribute :total_booking do |vendor|
14
13
  vendor.respond_to?(:total_booking) ? vendor.total_booking : 0
15
14
  end
16
15
 
17
- # Deprecated
18
16
  attribute :remaining do |vendor|
19
17
  vendor.respond_to?(:remaining) ? vendor.remaining : vendor.total_inventory
20
18
  end
@@ -4,7 +4,6 @@ module Spree
4
4
  module LineItemSerializerDecorator
5
5
  def self.prepended(base)
6
6
  base.attributes :from_date, :to_date, :need_confirmation, :product_type, :event_status, :amount, :display_amount,
7
- :checkin_date, :checkout_date,
8
7
  :number, :qr_data,
9
8
  :kyc, :kyc_fields, :remaining_total_guests, :number_of_guests,
10
9
  :completion_steps, :available_social_contact_platforms, :allow_anonymous_booking, :discontinue_on,
@@ -11,6 +11,7 @@ module Spree
11
11
  has_one :profile, serializer: Spree::V2::Tenant::AssetSerializer
12
12
  has_many :device_tokens, serializer: Spree::V2::Tenant::UserDeviceTokenSerializer
13
13
  has_many :spree_roles, serializer: Spree::V2::Tenant::RoleSerializer
14
+ has_many :user_identity_providers, serializer: Spree::V2::Tenant::UserIdentityProviderSerializer
14
15
 
15
16
  attribute :store_credits, &:total_available_store_credit
16
17
 
@@ -2,7 +2,10 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Operator
4
4
  class DashboardCrewEventSerializer < BaseSerializer
5
- attributes :id, :name, :permalink, :from_date, :to_date, :updated_at
5
+ attributes :id, :name, :permalink,
6
+ :from_date, :to_date,
7
+ :check_in_flows,
8
+ :updated_at
6
9
 
7
10
  has_many :children_classifications, serializer: :classification
8
11
  has_one :category_icon, serializer: SpreeCmCommissioner::V2::Storefront::AssetSerializer
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldOptionSerializer < BaseSerializer
5
- set_type :dynamic_field_option
6
-
7
- attributes :id, :value, :dynamic_field_id, :created_at, :updated_at
5
+ attributes :id, :value, :dynamic_field_id, :status, :created_at, :updated_at, :position
8
6
  end
9
7
  end
10
8
  end
@@ -2,9 +2,7 @@ module SpreeCmCommissioner
2
2
  module V2
3
3
  module Storefront
4
4
  class DynamicFieldSerializer < BaseSerializer
5
- set_type :dynamic_field
6
-
7
- attributes :id, :label, :data_type, :vendor_id, :created_at, :updated_at
5
+ attributes :id, :label, :data_type, :vendor_id, :multiple_select, :created_at, :updated_at, :position, :data_fill_stage
8
6
 
9
7
  has_many :dynamic_field_options, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
10
8
  end
@@ -4,9 +4,10 @@ module SpreeCmCommissioner
4
4
  class GuestDynamicFieldSerializer < BaseSerializer
5
5
  set_type :guest_dynamic_field
6
6
 
7
- attributes :id, :value, :guest_id, :dynamic_field_id, :created_at, :updated_at
7
+ attributes :id, :value, :guest_id, :dynamic_field_id, :dynamic_field_option_id, :created_at, :updated_at
8
8
 
9
9
  belongs_to :dynamic_field, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldSerializer
10
+ belongs_to :dynamic_field_option, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
10
11
  end
11
12
  end
12
13
  end
@@ -1,11 +1,12 @@
1
1
  module SpreeCmCommissioner
2
2
  module Organizer
3
3
  class ExportGuestCsvService
4
- attr_reader :event_id, :columns
4
+ attr_reader :event_id, :columns, :filters
5
5
 
6
- def initialize(event_id, columns)
6
+ def initialize(event_id, columns, filters = {})
7
7
  @event_id = event_id
8
8
  @columns = columns
9
+ @filters = filters
9
10
  end
10
11
 
11
12
  def call
@@ -18,7 +19,7 @@ module SpreeCmCommissioner
18
19
  private
19
20
 
20
21
  def headers
21
- columns.map(&:humanize).uniq
22
+ columns.map { |col| col.titleize(keep_id_suffix: true) }.uniq
22
23
  end
23
24
 
24
25
  def build_row(guest)
@@ -28,10 +29,8 @@ module SpreeCmCommissioner
28
29
  def fetch_value(guest, column)
29
30
  if guest_field?(column)
30
31
  fetch_guest_value(guest, column)
31
- elsif option_type_field?(column)
32
- fetch_option_value(guest, column)
33
32
  else
34
- ''
33
+ fetch_option_value(guest, column)
35
34
  end
36
35
  end
37
36
 
@@ -39,19 +38,21 @@ module SpreeCmCommissioner
39
38
  SpreeCmCommissioner::KycBitwise::ORDERED_BIT_FIELDS.include?(column.to_sym)
40
39
  end
41
40
 
42
- def option_type_field?(column)
43
- Spree::OptionType.exists?(name: column)
44
- end
45
-
46
41
  def fetch_guest_value(guest, column)
47
42
  column_mappings(guest)[column] || ''
48
43
  end
49
44
 
50
- def fetch_option_value(guest, option_type_name)
51
- return guest.formatted_bib_number if option_type_name == 'bib-prefix'
45
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
46
+ def fetch_option_value(guest, column_name)
47
+ return guest.formatted_bib_number if column_name == 'bib-prefix'
48
+ return guest.line_item&.number if column_name == 'item_id'
49
+ return guest.line_item&.order&.number if column_name == 'order_id'
50
+ return guest.created_at if column_name == 'created_at'
51
+ return guest.updated_at if column_name == 'updated_at'
52
52
 
53
- guest.line_item&.variant&.find_option_value_name_for(option_type_name: option_type_name)
53
+ guest.line_item&.variant&.find_option_value_name_for(option_type_name: column_name) || ''
54
54
  end
55
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
55
56
 
56
57
  def column_mappings(guest)
57
58
  {
@@ -77,12 +78,19 @@ module SpreeCmCommissioner
77
78
  end
78
79
 
79
80
  def guests_with_associations
80
- event.guests.includes(
81
+ scope = event.guests.includes(
81
82
  :occupation,
82
83
  :nationality,
83
84
  :id_card,
84
85
  line_item: { variant: { option_values: :option_type } }
85
- )
86
+ ).complete
87
+ scope = scope.where('cm_guests.created_at >= ?', formatted_date_time(filters[:from_date])) if filters[:from_date].present?
88
+ scope = scope.where('cm_guests.created_at <= ?', formatted_date_time(filters[:to_date])) if filters[:to_date].present?
89
+ scope
90
+ end
91
+
92
+ def formatted_date_time(date)
93
+ Time.zone.parse(date.to_s).strftime('%Y-%m-%d %H:%M:%S %z')
86
94
  end
87
95
 
88
96
  def event
@@ -32,7 +32,7 @@ module SpreeCmCommissioner
32
32
  options = { login: params[:username], password: params[:password], tenant_id: tenant_id }
33
33
  SpreeCmCommissioner::UserPasswordAuthenticator.call(options)
34
34
  when 'social_auth'
35
- options = { id_token: params[:id_token] }
35
+ options = { id_token: params[:id_token], tenant_id: tenant_id }
36
36
  SpreeCmCommissioner::UserIdTokenAuthenticator.call(options)
37
37
  when 'telegram_web_app_auth'
38
38
  options = { telegram_init_data: params[:telegram_init_data], telegram_bot_username: params[:tg_bot] }
@@ -0,0 +1,11 @@
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
@@ -47,6 +47,14 @@
47
47
  class: "btn btn-primary",
48
48
  style: "margin-left: 10px;" %>
49
49
  </div>
50
+ <% elsif !@error && @success && params[:trip_id].present? %>
51
+ <div>
52
+ <%= link_to 'Save Trip',
53
+ spree.admin_trip_blazer_queries_path(trip_id: params[:trip_id], blazer_query_id: @query.id),
54
+ method: :post,
55
+ class: "btn btn-primary",
56
+ style: "margin-left: 10px;" %>
57
+ </div>
50
58
  <% end %>
51
59
  </div>
52
60
 
@@ -17,11 +17,9 @@
17
17
  </td>
18
18
  <td class="text-center d-flex flex-column align-items-center justify-content-center">
19
19
  <div style="width: 90px;">
20
- <%= form_tag admin_product_stock_managements_path(product_id: params[:product_id], variant_id: variant.id, stock_location_id: stock_location.id), method: :post do %>
20
+ <%= form_tag admin_stock_items_path(variant_id: variant.id, stock_location_id: stock_location.id), method: :post do %>
21
21
  <div class="input-group input-group-sm">
22
22
  <%= number_field_tag 'stock_movement[quantity]', 0, class: 'form-control text-center p-0' %>
23
- <%= hidden_field_tag 'stock_movement[originator_id]', spree_current_user.id %>
24
- <%= hidden_field_tag 'stock_movement[originator_type]', spree_current_user.class.name %>
25
23
  <div class="input-group-append">
26
24
  <%= button_tag(class: 'btn btn-outline-success pl-2 pr-1') do %>
27
25
  <%= svg_icon(name: 'arrow-left-right.svg', classes: "icon", width: 14, height: 14) %>
@@ -34,10 +32,7 @@
34
32
  <td class="text-center">
35
33
  <% if item.persisted? && can?(:update, item) %>
36
34
  <%= form_tag admin_stock_item_path(item), method: :put, class: 'toggle_stock_item_backorderable' do %>
37
- <%= check_box_tag 'stock_item[backorderable]', true, item.backorderable?,
38
- class: 'stock_item_backorderable',
39
- id: "stock_item_backorderable_#{stock_location.id}",
40
- onclick: "if (!confirm('Are you sure to change backorderable status?')) { this.checked = !this.checked; }" %>
35
+ <%= check_box_tag 'stock_item[backorderable]', true, item.backorderable?, class: 'stock_item_backorderable', id: "stock_item_backorderable_#{stock_location.id}" %>
41
36
  <% end %>
42
37
  <% else %>
43
38
  <%= 'N/A' %>
@@ -19,73 +19,30 @@
19
19
  <% @variants.each do |variant| %>
20
20
  <tr id="<%= spree_dom_id variant %>" data-hook="admin_product_stock_management_index_rows">
21
21
  <td class="image text-center">
22
- <%= small_image(variant) %>
22
+ <%= small_image(variant) %>
23
+ <div class="mt-4">
24
+ Reserved Stock: <%= @reserved_stocks[variant.id] || 0 %></strong>
25
+ </div>
23
26
  </td>
24
27
  <td>
25
28
  <%= variant.sku_and_options_text %>
26
29
  <%= form_tag admin_product_variants_including_master_path(@product, variant, format: :js), method: :put, class: 'toggle_variant_track_inventory mt-2' do %>
27
30
  <div class="checkbox">
28
31
  <%= label_tag "track_inventory_#{ variant.id }", class: 'm-0' do %>
29
- <%= check_box_tag 'track_inventory', 1, variant.track_inventory?,
30
- class: 'track_inventory_checkbox',
31
- id: "track_inventory_#{ variant.id }",
32
- onclick: "if (!confirm('Are you sure to change track inventory status?')) { this.checked = !this.checked; }" %>
32
+ <%= check_box_tag 'track_inventory', 1, variant.track_inventory?, class: 'track_inventory_checkbox', id: "track_inventory_#{ variant.id }" %>
33
33
  <%= Spree.t(:track_inventory) %>
34
34
  <%= hidden_field_tag 'variant[track_inventory]', variant.track_inventory?, class: 'variant_track_inventory', id: "variant_track_inventory_#{variant.id}" %>
35
35
  <% end %>
36
36
  </div>
37
37
  <% end if can?(:update, @product) && can?(:update, variant) %>
38
-
39
- <% if defined?(@reserved_stocks) %>
40
- <div>
41
- <%= svg_icon name: "cart-check.svg", width: '14', height: '14' %>
42
- <%= label_tag "reserved_stock#{variant.id}", "Reserved Stock: #{@reserved_stocks[variant.id] || 0}", class: "m-0" %>
43
- <%= link_to_with_icon('capture.svg', "Create Inventory Item", admin_product_stock_management_variant_inventory_items(@product, variant.id),
44
- method: :post,
45
- remote: false,
46
- class: 'icon_link btn btn-sm btn-outline-primary ml-2',
47
- no_text: true
48
- ) unless @inventory_items[variant.id].present? %>
49
- </div>
50
- <% end %>
51
-
52
38
  <% if variant.permanent_stock? %>
53
39
  <div>
54
40
  <span type="button" data-toggle="popover" data-trigger="hover" data-placement="right" data-content="This product stock will renew every day">
55
41
  <%= svg_icon name: "info-circle-fill.svg", width: '14', height: '14' %>
56
42
  </span>
57
- <%= label_tag "permanent_stock_#{ variant.id }", Spree.t(:permanent_stock), class: "m-0" %>
43
+ <%= label_tag "permanent_stock_#{ variant.id }", Spree.t(:permanent_stock) %>
58
44
  </div>
59
45
  <% end %>
60
-
61
- <% if defined?(@inventory_items) %>
62
- <% @inventory_items[variant.id]&.each do |inventory_item| %>
63
- <div>
64
- <%= svg_icon name: "handbag.svg", width: '14', height: '14' %>
65
- <%= label_tag "max_capacity_#{ inventory_item.id }", "Max capacity: #{inventory_item.max_capacity}", class: "m-0" %>
66
- </div>
67
- <div>
68
- <%= svg_icon name: "approve.svg", width: '14', height: '14' %>
69
- <%= label_tag "quantity_available_#{ inventory_item.id }", "Quantity available: #{inventory_item.quantity_available}", class: "m-0" %>
70
-
71
- <% synced = inventory_item.quantity_available == @cached_inventory_items[inventory_item.id].quantity_available %>
72
- <span type="button" data-toggle="popover" data-trigger="hover" data-placement="right" data-content="<%= inventory_item_message(inventory_item, @cached_inventory_items[inventory_item.id]) %>">
73
- <% if synced %>
74
- <%= svg_icon name: "cloud-check.svg", width: '14', height: '14', classes: 'text-success' %>
75
- <% else %>
76
- <%= svg_icon name: "cloud-slash.svg", width: '14', height: '14', classes: 'text-danger' %>
77
- <% end %>
78
- </span>
79
-
80
- <%= link_to_with_icon('arrow-counterclockwise.svg', "Reset Inventory Item", reset_admin_product_variant_inventory_item_path(@product, inventory_item.variant_id, inventory_item.id),
81
- method: :patch,
82
- remote: false,
83
- class: 'icon_link btn btn-sm outline text-dark',
84
- data: { confirm: "Only reset if stock is incorrect. Are you sure?" }, no_text: true
85
- ) %>
86
- </div>
87
- <% end %>
88
- <% end %>
89
46
  </td>
90
47
 
91
48
  <td colspan="3" class="stock_location_info">
@@ -96,9 +53,3 @@
96
53
  </tbody>
97
54
  </table>
98
55
  </div>
99
-
100
- <%= turbo_frame_tag "calendar", src: calendar_admin_product_stock_managements_path(year: params[:year]) do %>
101
- <div class="spinner-border mt-2" role="status">
102
- <span class="sr-only">Loading...</span>
103
- </div>
104
- <% end if @product.permanent_stock? %>
@@ -1,6 +1,6 @@
1
1
  <% content_for :page_title do %>
2
2
  <%= page_header_back_button spree.admin_tenants_url %>
3
- <%= link_to @tenant.name, spree.admin_tenants_url %> / <%= Spree.t('vendors') %>
3
+ <%= link_to Spree.t('tenants'), spree.admin_tenants_url %> / <%= link_to @tenant.name, spree.admin_tenants_url%> / <%= Spree.t('vendors') %>
4
4
  <% end %>
5
5
 
6
6
  <% content_for :page_actions do %>
@@ -24,13 +24,20 @@
24
24
  <tbody>
25
25
  <% @vendors.each do |vendor| %>
26
26
  <tr id="<%= spree_dom_id vendor %>" data-hook="admin_vendors_index_rows">
27
- <td><%= vendor.name %></td>
27
+ <td>
28
+ <% if can?(:edit, vendor) %>
29
+ <%= link_to vendor.name, edit_admin_vendor_path(vendor.slug) %>
30
+ <% else %>
31
+ <td><%= vendor.name %></td>
32
+ <% end %>
33
+ </td>
28
34
  <td><%= vendor.slug %></td>
29
35
  <td><%= vendor.created_at %></td>
30
36
  <td><%= vendor.updated_at %></td>
31
37
  <td><%= vendor.tenant.name %></td>
32
38
  <td data-hook="admin_tenants_index_row_actions" class="actions">
33
39
  <span class="d-flex justify-content-end">
40
+ <%= link_to_edit vendor, url: edit_admin_vendor_path(vendor.slug), no_text: true if can?(:edit, vendor) %>
34
41
  <%= link_to_delete vendor, url: admin_tenant_vendor_path(@tenant, vendor.id), no_text: true if can?(:delete, vendor) %>
35
42
  </span>
36
43
  </td>