spree_cm_commissioner 2.0.3.pre.pre.pre7 → 2.1.0.pre.pre1

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 (253) 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 +39 -4
  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/locations_controller.rb +62 -0
  9. data/app/controllers/spree/admin/stock_managements_controller.rb +63 -1
  10. data/app/controllers/spree/api/v2/platform/places_controller.rb +4 -1
  11. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +42 -0
  12. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +14 -31
  13. data/app/controllers/spree/api/v2/storefront/dynamic_fields_controller.rb +1 -1
  14. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +26 -18
  15. data/app/controllers/spree/api/v2/storefront/inventory_items_controller.rb +57 -0
  16. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  17. data/app/controllers/spree/api/v2/storefront/transit/draft_orders_controller.rb +46 -0
  18. data/app/controllers/spree/api/v2/storefront/trip_places_controller.rb +29 -0
  19. data/app/controllers/spree/api/v2/storefront/trip_search_controller.rb +62 -0
  20. data/app/controllers/spree/api/v2/storefront/trips_controller.rb +24 -0
  21. data/app/finders/spree_cm_commissioner/accommodations/find.rb +37 -0
  22. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +32 -0
  23. data/app/interactors/spree_cm_commissioner/billing_address_creator.rb +33 -0
  24. data/app/interactors/spree_cm_commissioner/customer_notification_sender.rb +7 -2
  25. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +40 -0
  26. data/app/interactors/spree_cm_commissioner/fetch_facebook_user_data.rb +45 -0
  27. data/app/interactors/spree_cm_commissioner/google_places_fetcher.rb +1 -0
  28. data/app/interactors/spree_cm_commissioner/intercity_taxi_order_creator.rb +106 -0
  29. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +25 -0
  30. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +44 -0
  31. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +13 -0
  32. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +15 -0
  33. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +75 -0
  34. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +32 -0
  35. data/app/interactors/spree_cm_commissioner/taxi_trip_creator.rb +66 -0
  36. data/app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb +136 -0
  37. data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +155 -0
  38. data/app/interactors/spree_cm_commissioner/user_fb_token_authenticator.rb +37 -0
  39. data/app/interactors/spree_cm_commissioner/user_fb_token_checker.rb +20 -0
  40. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +8 -8
  41. data/app/interactors/spree_cm_commissioner/user_registration_with_fb_token.rb +62 -0
  42. data/app/interactors/spree_cm_commissioner/variant_block_updater.rb +62 -0
  43. data/app/interactors/spree_cm_commissioner/vehicle_updater.rb +41 -0
  44. data/app/jobs/spree_cm_commissioner/application_job.rb +20 -0
  45. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +20 -0
  46. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +7 -0
  47. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +7 -0
  48. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +11 -0
  49. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +11 -0
  50. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +9 -0
  51. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +18 -15
  52. data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +29 -15
  53. data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +144 -0
  54. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -12
  55. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +44 -0
  56. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +39 -0
  57. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +1 -3
  58. data/app/models/concerns/spree_cm_commissioner/product_type.rb +10 -0
  59. data/app/models/concerns/spree_cm_commissioner/route_type.rb +1 -1
  60. data/app/models/concerns/spree_cm_commissioner/user_identity.rb +12 -4
  61. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +1 -0
  62. data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +11 -0
  63. data/app/models/spree_cm_commissioner/address_decorator.rb +36 -2
  64. data/app/models/spree_cm_commissioner/block.rb +43 -0
  65. data/app/models/spree_cm_commissioner/customer_notification.rb +6 -1
  66. data/app/models/spree_cm_commissioner/dynamic_field.rb +2 -0
  67. data/app/models/spree_cm_commissioner/guest.rb +39 -0
  68. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +4 -0
  69. data/app/models/spree_cm_commissioner/inventory.rb +11 -0
  70. data/app/models/spree_cm_commissioner/inventory_item.rb +82 -0
  71. data/app/models/spree_cm_commissioner/line_item_decorator.rb +47 -78
  72. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  73. data/app/models/spree_cm_commissioner/option_type_decorator.rb +1 -11
  74. data/app/models/spree_cm_commissioner/order/address_book_decorator.rb +30 -12
  75. data/app/models/spree_cm_commissioner/order_decorator.rb +38 -1
  76. data/app/models/spree_cm_commissioner/place.rb +3 -4
  77. data/app/models/spree_cm_commissioner/price_decorator.rb +9 -0
  78. data/app/models/spree_cm_commissioner/product_decorator.rb +13 -10
  79. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +41 -0
  80. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +126 -0
  81. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +36 -0
  82. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +25 -0
  83. data/app/models/spree_cm_commissioner/reserved_block.rb +31 -0
  84. data/app/models/spree_cm_commissioner/saved_guest.rb +21 -0
  85. data/app/models/spree_cm_commissioner/seat_layout.rb +20 -0
  86. data/app/models/spree_cm_commissioner/seat_section.rb +16 -0
  87. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +30 -0
  88. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +53 -0
  89. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +49 -0
  90. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +4 -0
  91. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +4 -0
  92. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +4 -0
  93. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +4 -0
  94. data/app/models/spree_cm_commissioner/service_calendar.rb +0 -2
  95. data/app/models/spree_cm_commissioner/state_decorator.rb +0 -1
  96. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +26 -25
  97. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +2 -1
  98. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  99. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +44 -0
  100. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +17 -0
  101. data/app/models/spree_cm_commissioner/taxon_decorator.rb +7 -1
  102. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +0 -6
  103. data/app/models/spree_cm_commissioner/trip.rb +19 -10
  104. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  105. data/app/models/spree_cm_commissioner/trip_stop.rb +10 -21
  106. data/app/models/spree_cm_commissioner/variant_block.rb +17 -0
  107. data/app/models/spree_cm_commissioner/variant_decorator.rb +37 -47
  108. data/app/models/spree_cm_commissioner/variant_options.rb +4 -23
  109. data/app/models/spree_cm_commissioner/vehicle.rb +12 -15
  110. data/app/models/spree_cm_commissioner/vendor_decorator.rb +14 -14
  111. data/app/models/spree_cm_commissioner/vendor_place.rb +13 -3
  112. data/app/overrides/spree/admin/shared/sub_menu/_configuration/locations_tab.html.erb.deface +5 -0
  113. data/app/queries/spree_cm_commissioner/trip_query.rb +110 -131
  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/inventory_item_schema.rb +8 -0
  117. data/app/request_schemas/spree_cm_commissioner/trip_search_request_schema.rb +20 -0
  118. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +19 -0
  119. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +2 -0
  120. data/app/serializers/spree/v2/storefront/cart_serializer_decorator.rb +1 -0
  121. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +3 -1
  122. data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +1 -0
  123. data/app/serializers/spree_cm_commissioner/v2/storefront/amenity_serializer.rb +15 -0
  124. data/app/serializers/spree_cm_commissioner/v2/storefront/block_serializer.rb +11 -0
  125. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +5 -1
  126. data/app/serializers/spree_cm_commissioner/v2/storefront/inventory_item_serializer.rb +42 -0
  127. data/app/serializers/spree_cm_commissioner/v2/storefront/reserved_block_serializer.rb +9 -0
  128. data/app/serializers/spree_cm_commissioner/v2/storefront/saved_guest_serializer.rb +21 -0
  129. data/app/serializers/spree_cm_commissioner/v2/storefront/seat_layout_serializer.rb +12 -0
  130. data/app/serializers/spree_cm_commissioner/v2/storefront/seat_section_serializer.rb +11 -0
  131. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_place_serializer.rb +10 -0
  132. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_query_result_serializer.rb +14 -0
  133. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +17 -0
  134. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb +20 -0
  135. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +11 -0
  136. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_variant_serializer.rb +12 -0
  137. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_serializer.rb +16 -0
  138. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vendor_serializer.rb +16 -0
  139. data/app/serializers/spree_cm_commissioner/v2/storefront/variant_block_serializer.rb +9 -0
  140. data/app/services/spree_cm_commissioner/transit/legs_builder_service.rb +46 -0
  141. data/app/services/spree_cm_commissioner/user_authenticator.rb +10 -1
  142. data/app/views/shared/_map.html.erb +5 -4
  143. data/app/views/spree/admin/customer_notifications/_form.html.erb +3 -3
  144. data/app/views/spree/admin/inventory_items/show.html.erb +72 -0
  145. data/app/views/spree/admin/locations/_form.html.erb +133 -0
  146. data/app/views/spree/admin/locations/edit.html.erb +11 -0
  147. data/app/views/spree/admin/locations/index.html.erb +67 -0
  148. data/app/views/spree/admin/locations/new.html.erb +11 -0
  149. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +7 -2
  150. data/app/views/spree/admin/stock_managements/calendar.html.erb +56 -0
  151. data/app/views/spree/admin/stock_managements/index.html.erb +55 -6
  152. data/config/initializers/paper_trail.rb +1 -0
  153. data/config/initializers/spree_permitted_attributes.rb +24 -4
  154. data/config/locales/en.yml +2 -0
  155. data/config/routes.rb +32 -2
  156. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +3 -1
  157. data/db/migrate/20250122000000_move_route_type_from_vehicles_to_trips.rb +7 -0
  158. data/db/migrate/20250304293518_create_cm_inventory_items.rb +21 -0
  159. data/db/migrate/20250428092706_add_active_to_cm_customer_notifications.rb +7 -0
  160. data/db/migrate/20250428103550_remove_tenant_id_and_vendor_id_from_cm_customer_notifications.rb +9 -0
  161. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +5 -0
  162. data/db/migrate/20250502025848_add_index_to_spree_products.rb +5 -0
  163. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +5 -0
  164. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +5 -0
  165. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +7 -0
  166. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +5 -0
  167. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +5 -0
  168. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +9 -0
  169. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +5 -0
  170. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +9 -0
  171. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +5 -0
  172. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +5 -0
  173. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +5 -0
  174. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +6 -0
  175. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +17 -0
  176. data/db/migrate/20250620090002_create_cm_seat_sections.rb +18 -0
  177. data/db/migrate/20250620090003_create_cm_blocks.rb +18 -0
  178. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +29 -0
  179. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +24 -0
  180. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +13 -0
  181. data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +5 -0
  182. data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +5 -0
  183. data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +5 -0
  184. data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +5 -0
  185. data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +7 -0
  186. data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +11 -0
  187. data/db/migrate/20250721080738_add_vehicle_type_to_cm_vehicles.rb +7 -0
  188. data/db/migrate/20250725092713_add_block_type_to_cm_blocks.rb +5 -0
  189. data/db/migrate/20250731062816_add_departure_time_and_arrival_time_to_trip_stop.rb +6 -0
  190. data/db/migrate/20250807033035_create_spree_cm_commissioner_saved_guests.rb +23 -0
  191. data/db/migrate/20250807040000_generate_pickup_time_integer_option_values.rb +71 -0
  192. data/db/migrate/20250808054835_add_saved_guest_reference_to_cm_blocks.rb +5 -0
  193. data/docker-compose.yml +1 -1
  194. data/lib/cm_app_logger.rb +17 -1
  195. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +14 -11
  196. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_cm_commissioner → spree_dashboard/spree_cm_commissioner}/utilities.js +4 -0
  197. data/lib/spree_cm_commissioner/cached_inventory_item.rb +23 -0
  198. data/lib/spree_cm_commissioner/calendar_event.rb +11 -1
  199. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +16 -0
  200. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +10 -0
  201. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  202. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +20 -0
  203. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  204. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +6 -30
  205. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +0 -36
  206. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +18 -34
  207. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +27 -0
  208. data/lib/spree_cm_commissioner/test_helper/factories/saved_guest_factory.rb +8 -0
  209. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +11 -0
  210. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +16 -0
  211. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  212. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
  213. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +11 -3
  214. data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +13 -0
  215. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +7 -0
  216. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +41 -19
  217. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  218. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +6 -1
  219. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +13 -1
  220. data/lib/spree_cm_commissioner/transit/leg.rb +37 -0
  221. data/lib/spree_cm_commissioner/transit/seat_selection.rb +27 -0
  222. data/lib/spree_cm_commissioner/trip_query_result.rb +50 -0
  223. data/lib/spree_cm_commissioner/trip_result.rb +19 -10
  224. data/lib/spree_cm_commissioner/version.rb +1 -1
  225. data/lib/spree_cm_commissioner.rb +37 -1
  226. data/lib/tasks/create_default_non_permanent_inventory_items.rake +16 -0
  227. data/lib/tasks/ensure_correct_product_type.rake +7 -0
  228. data/lib/tasks/generate_inventory_items.rake +7 -0
  229. data/spree_cm_commissioner.gemspec +7 -0
  230. metadata +195 -26
  231. data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +0 -44
  232. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +0 -20
  233. data/app/models/spree_cm_commissioner/branch.rb +0 -12
  234. data/app/models/spree_cm_commissioner/line_item_seat.rb +0 -10
  235. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +0 -8
  236. data/app/models/spree_cm_commissioner/stop.rb +0 -23
  237. data/app/models/spree_cm_commissioner/vehicle_seat.rb +0 -11
  238. data/app/models/spree_cm_commissioner/vehicle_type.rb +0 -76
  239. data/app/models/spree_cm_commissioner/vendor_stop.rb +0 -10
  240. data/app/queries/spree_cm_commissioner/trip_search_query.rb +0 -76
  241. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +0 -45
  242. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +0 -55
  243. data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +0 -54
  244. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +0 -11
  245. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +0 -12
  246. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +0 -8
  247. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +0 -8
  248. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +0 -7
  249. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +0 -14
  250. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +0 -8
  251. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +0 -8
  252. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +0 -96
  253. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +0 -11
@@ -0,0 +1,12 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class SeatLayoutSerializer < BaseSerializer
5
+ attributes :name, :status, :width, :height
6
+
7
+ has_many :seat_sections, serializer: SpreeCmCommissioner::V2::Storefront::SeatSectionSerializer
8
+ has_many :top_level_blocks, serializer: SpreeCmCommissioner::V2::Storefront::BlockSerializer
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class SeatSectionSerializer < BaseSerializer
5
+ attributes :name, :width, :height, :x, :y, :rotation, :shape_path
6
+
7
+ has_many :blocks, serializer: SpreeCmCommissioner::V2::Storefront::BlockSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripPlaceSerializer < BaseSerializer
5
+ attributes :reference, :name, :vicinity, :lat, :lon, :icon, :url, :rating,
6
+ :formatted_phone_number, :formatted_address, :address_components, :types
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripQueryResultSerializer < BaseSerializer
5
+ set_type :trip_query_result
6
+
7
+ attributes :quantity_available, :max_capacity
8
+
9
+ attribute :direct, &:direct?
10
+ has_many :trips, serializer: ::SpreeCmCommissioner::V2::Storefront::TripResultSerializer
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripResultSerializer < BaseSerializer
5
+ set_type :trip_result
6
+
7
+ attributes :origin_place, :destination_place, :boarding, :drop_off, :price, :compare_at_amount, :currency, :quantity_available, :max_capacity,
8
+ :allow_seat_selection, :departure_time, :route_type
9
+ attribute :duration_in_hms, &:duration_in_hms
10
+ attribute :arrival_time, &:arrival_time
11
+ belongs_to :vendor, serializer: ::SpreeCmCommissioner::V2::Storefront::TripVendorSerializer
12
+ belongs_to :vehicle, serializer: ::SpreeCmCommissioner::V2::Storefront::TripVehicleSerializer
13
+ has_many :amenities, serializer: ::SpreeCmCommissioner::V2::Storefront::AmenitySerializer
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripSerializer < BaseSerializer
5
+ attributes :departure_time, :arrival_time, :duration_in_hms, :route_type
6
+
7
+ has_one :vehicle, serializer: ::SpreeCmCommissioner::V2::Storefront::TripVehicleSerializer
8
+
9
+ has_one :origin_place, serializer: ::SpreeCmCommissioner::V2::Storefront::TripPlaceSerializer
10
+ has_one :destination_place, serializer: ::SpreeCmCommissioner::V2::Storefront::TripPlaceSerializer
11
+
12
+ has_many :boarding_trip_stops, serializer: ::SpreeCmCommissioner::V2::Storefront::TripStopSerializer
13
+ has_many :drop_off_trip_stops, serializer: ::SpreeCmCommissioner::V2::Storefront::TripStopSerializer
14
+ has_many :variants, serializer: ::SpreeCmCommissioner::V2::Storefront::TripVariantSerializer
15
+
16
+ belongs_to :vendor, serializer: ::SpreeCmCommissioner::V2::Storefront::TripVendorSerializer
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripStopSerializer < BaseSerializer
5
+ attributes :id, :stop_type, :stop_name, :arrival_time, :departure_time
6
+
7
+ has_one :stop_place, serializer: ::SpreeCmCommissioner::V2::Storefront::TripPlaceSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripVariantSerializer < BaseSerializer
5
+ attributes :price, :display_price, :compare_at_price, :display_compare_at_price, :currency,
6
+ :number_of_guests, :seat_type
7
+
8
+ has_many :variant_blocks, serializer: ::SpreeCmCommissioner::V2::Storefront::VariantBlockSerializer
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripVehicleSerializer < BaseSerializer
5
+ set_type :vehicle
6
+
7
+ attributes :id, :code, :vehicle_type
8
+
9
+ has_many :vehicle_photos, serializer: ::SpreeCmCommissioner::V2::Storefront::AssetSerializer
10
+ has_many :amenities, serializer: ::SpreeCmCommissioner::V2::Storefront::AmenitySerializer
11
+
12
+ has_one :seat_layout, serializer: SpreeCmCommissioner::V2::Storefront::SeatLayoutSerializer
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class TripVendorSerializer < BaseSerializer
5
+ set_type :vendor
6
+
7
+ attributes :name, :star_rating
8
+
9
+ has_one :logo, serializer: ::SpreeCmCommissioner::V2::Storefront::AssetSerializer
10
+
11
+ has_many :vendor_kind_option_types, serializer: ::Spree::V2::Storefront::OptionTypeSerializer
12
+ has_many :vendor_kind_option_values, serializer: ::Spree::V2::Storefront::OptionValueSerializer
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ module SpreeCmCommissioner
2
+ module V2
3
+ module Storefront
4
+ class VariantBlockSerializer < BaseSerializer
5
+ attributes :variant_id, :block_id
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ module SpreeCmCommissioner
2
+ module Transit
3
+ class LegsBuilderService
4
+ attr_reader :direction, :legs
5
+
6
+ def initialize(direction:, legs_params:)
7
+ @direction = direction
8
+ @legs = extract_legs_from_params(legs_params)
9
+ end
10
+
11
+ def call
12
+ legs.map do |leg|
13
+ SpreeCmCommissioner::Transit::Leg.new(
14
+ direction: direction,
15
+ trip_id: leg['trip_id'].to_i,
16
+ boarding_trip_stop_id: leg['boarding_trip_stop_id'].to_i,
17
+ drop_off_trip_stop_id: leg['drop_off_trip_stop_id'].to_i,
18
+ seat_selections: Array(leg['seat_selections']).map do |seat|
19
+ next if seat['quantity'].blank? && seat['block_ids'].blank?
20
+
21
+ SpreeCmCommissioner::Transit::SeatSelection.new(
22
+ variant_id: seat['variant_id'].to_i,
23
+ quantity: seat['quantity'].to_i.zero? ? seat['block_ids']&.size.to_i : seat['quantity'].to_i,
24
+ block_ids: seat['block_ids']&.map(&:to_i)
25
+ )
26
+ end.compact
27
+ )
28
+ end
29
+ end
30
+
31
+ def extract_legs_from_params(legs_params)
32
+ if legs_params.is_a?(String)
33
+ contents = Base64.urlsafe_decode64(legs_params)
34
+ JSON.parse(contents)
35
+ else
36
+ legs_params.map do |leg|
37
+ leg.permit(
38
+ :trip_id, :boarding_trip_stop_id, :drop_off_trip_stop_id,
39
+ seat_selections: [:variant_id, :quantity, { block_ids: [] }]
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -3,6 +3,10 @@ module SpreeCmCommissioner
3
3
  class UserAuthenticator
4
4
  # :username, :password
5
5
  # :id_token
6
+ # :fb_access_token
7
+ # :telegram_init_data, :tg_bot
8
+ # :session_id
9
+
6
10
  def self.call!(params)
7
11
  context = auth_context(params)
8
12
  raise exception(context.message) unless context.success?
@@ -25,7 +29,8 @@ module SpreeCmCommissioner
25
29
  end
26
30
 
27
31
  def self.auth_context(params)
28
- tenant_id = find_oauth_application(params)&.tenant_id
32
+ oauth_application = find_oauth_application(params)
33
+ tenant_id = oauth_application&.tenant_id
29
34
 
30
35
  case flow_type(params)
31
36
  when 'login_auth'
@@ -34,6 +39,9 @@ module SpreeCmCommissioner
34
39
  when 'social_auth'
35
40
  options = { id_token: params[:id_token], tenant_id: tenant_id }
36
41
  SpreeCmCommissioner::UserIdTokenAuthenticator.call(options)
42
+ when 'facebook_auth'
43
+ options = { fb_access_token: params[:fb_access_token], tenant_id: tenant_id }
44
+ SpreeCmCommissioner::UserFbTokenAuthenticator.call(options)
37
45
  when 'telegram_web_app_auth'
38
46
  options = { telegram_init_data: params[:telegram_init_data], telegram_bot_username: params[:tg_bot] }
39
47
  SpreeCmCommissioner::UserTelegramWebAppAuthenticator.call(options)
@@ -46,6 +54,7 @@ module SpreeCmCommissioner
46
54
  def self.flow_type(params)
47
55
  return 'login_auth' if params.key?(:username) && params.key?(:password)
48
56
  return 'social_auth' if params.key?(:id_token)
57
+ return 'facebook_auth' if params.key?(:fb_access_token)
49
58
  return 'telegram_web_app_auth' if params.key?(:telegram_init_data) && params.key?(:tg_bot)
50
59
  return 'vattanac_bank_web_app_auth' if params.key?(:session_id)
51
60
 
@@ -1,14 +1,15 @@
1
- <div class="border rounded mb-4"><div id="map" class="rounded" style="height: 200px;"></div></div>
1
+ <% map_height ||= 200 %>
2
2
 
3
+ <div class="border rounded mb-4">
4
+ <div id="map" class="rounded" style="height: <%= map_height %>px;"></div>
5
+ </div>
3
6
  <% @default_latlon = ENV.fetch("DEFAULT_LATLON") %>
4
7
  <% @default_lat = @default_latlon.split(",")[0] %>
5
8
  <% @default_lon = @default_latlon.split(",")[1] %>
6
-
7
9
  <%= content_tag :div, class: 'map-selector', data: {
8
- lat: lat || @default_lat,
10
+ lat: lat || @default_lat,
9
11
  lon: lon || @default_lon
10
12
  } do %><% end %>
11
-
12
13
  <%# MAP scripts %>
13
14
  <% @map_key = ENV.fetch("GOOGLE_MAP_KEY") %>
14
15
  <% @map_src = "https://maps.googleapis.com/maps/api/js?key=#{@map_key}&callback=initMap&v=weekly" %>
@@ -77,9 +77,9 @@
77
77
 
78
78
  <div class="col-lg-12 col-sm-12">
79
79
  <div class="form-group">
80
- <%= f.label :tenant_id, raw(Spree.t(:tenant) + ' (optional)') %>
81
- <%= f.collection_select :tenant_id, SpreeCmCommissioner::Tenant.all, :id, :name, { prompt: Spree.t(:select_tenant) }, { class: 'form-control select2' } %>
82
- <%= f.error_message_on :tenant_id %>
80
+ <%= f.label :vendor_id, raw(Spree.t(:vendor) + ' (optional)') %>
81
+ <%= f.collection_select :vendor_id, Spree::Vendor.all, :id, :name, { prompt: Spree.t(:select_vendor) }, { class: 'form-control select2' } %>
82
+ <%= f.error_message_on :vendor_id %>
83
83
  </div>
84
84
  </div>
85
85
  </div>
@@ -0,0 +1,72 @@
1
+ <%= turbo_frame_tag "inventory_item" do %>
2
+ <div>
3
+ <h5 class="modal-title">Inventory</h5>
4
+ <p>
5
+ <% if @inventory_item.inventory_date.present? %>
6
+ <span><%= @inventory_item.inventory_date %></span><br>
7
+ <% end %>
8
+ <%= @inventory_item.variant.options_text %>
9
+ </p>
10
+
11
+ <ul class="list-group mb-1">
12
+ <li class="list-group-item d-flex justify-content-between align-items-center">
13
+ Max capacity
14
+ <span class="badge badge-primary badge-pill"><%= @inventory_item.max_capacity %></span>
15
+ </li>
16
+ <li class="list-group-item d-flex justify-content-between align-items-center">
17
+ Quantity available
18
+ <span class="badge badge-primary badge-pill"><%= @inventory_item.quantity_available %></span>
19
+ </li>
20
+ </ul>
21
+
22
+ <small class="text-muted">
23
+ <%= inventory_item_message(@inventory_item, @cached_inventory_item) %>
24
+ </small>
25
+
26
+ <%= 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),
27
+ method: :patch,
28
+ remote: false,
29
+ class: 'icon_link btn btn-sm outline text-dark',
30
+ data: { confirm: "Only reset if stock is incorrect. Are you sure?" }, no_text: true
31
+ ) %>
32
+ </div>
33
+
34
+ <hr />
35
+
36
+ <div class="mt-2">
37
+ <h6 class="modal-title mb-1 d-flex flex-row justify-content-between">
38
+ Custom Prices
39
+ <%= link_to_with_icon('delete.svg', Spree.t(:remove),
40
+ delete_prices_admin_product_variant_inventory_item_path(@product, @inventory_item.variant_id, @inventory_item.id),
41
+ method: :delete, remote: false, class: 'icon_link btn btn-sm text-danger', data: { action: :remove, confirm: "Are you sure to remove these prices & use base price?" }, no_text: true
42
+ ) if @prices.any?(&:persisted?) %>
43
+ </h6>
44
+
45
+ <%= form_with url: update_prices_admin_product_variant_inventory_item_path(@product, @inventory_item.variant_id, @inventory_item.id), method: :patch, local: true, html: { class: 'inventory-item-prices-form' } do |form| %>
46
+ <table class="table">
47
+ <tbody>
48
+ <% @prices.each do |price| %>
49
+ <% currency = price.currency %>
50
+ <% default_price = @default_prices[currency] || Spree::Price.new %>
51
+ <tr id="inventory-item_prices_row_<%= currency %>" data-hook="inventory-item_prices_row">
52
+ <td><%= form.label "price_#{currency}", currency, class: 'form-label' %></td>
53
+ <td>
54
+ <%= form.hidden_field "prices[#{currency}][currency]", value: currency %>
55
+ <%= form.text_field "prices[#{currency}][price]", value: price.amount, placeholder: "Default: #{default_price.amount || 'N/A'}", class: 'form-control' %>
56
+ </td>
57
+ <td>
58
+ <%= form.text_field "prices[#{currency}][compare_at_price]", value: price.compare_at_price, placeholder: "Default: #{default_price.compare_at_price || 'N/A'}", class: 'form-control' %>
59
+ </td>
60
+ </tr>
61
+ <% end %>
62
+ </tbody>
63
+ </table>
64
+
65
+ <div class="d-flex flex-row justify-content-end mt-2">
66
+ <div class="form-actions" data-hook="buttons">
67
+ <%= button Spree.t('actions.save'), 'save.svg', 'submit', { class: 'btn-outline-success', data: { disable_with: "#{ Spree.t(:saving) }...", turbo_frame: "_top" } } %>
68
+ </div>
69
+ </div>
70
+ <% end %>
71
+ </div>
72
+ <% end %>
@@ -0,0 +1,133 @@
1
+ <div class="row g-4" data-controller="place">
2
+ <div class="col-md-6">
3
+ <div class="form-group">
4
+ <%= f.field_container :base_64_content do %>
5
+ <%= f.label :base_64_content, Spree.t(:place) %>
6
+ <% if can? :modify, SpreeCmCommissioner::Place %>
7
+ <% selected_name = f.object.name.presence || f.object.formatted_address || "Search Place" %>
8
+ <%= f.select :base_64_content, [], { include_hidden: true },
9
+ class: 'select2autocomplete',
10
+ data: {
11
+ autocomplete_url_value: 'places_api_v2',
12
+ autocomplete_return_attr_value: :name,
13
+ autocomplete_custom_return_id_value: :base_64_content
14
+ } do %>
15
+ <option selected><%= selected_name %></option>
16
+ <% end %>
17
+ <% end %>
18
+ <% end %>
19
+ </div>
20
+
21
+ <%= render 'shared/map', lat: f.object.lat, lon: f.object.lon, map_height: 270 %>
22
+ </div>
23
+
24
+ <div class="col-md-6">
25
+ <div class="card shadow-sm border-0">
26
+ <div class="card-header bg-light fw-semibold">
27
+ <i class="bi bi-geo-alt-fill me-2"></i><%= Spree.t(:location_details) %>
28
+ </div>
29
+
30
+ <div class="card-body">
31
+ <div class="mb-3">
32
+ <%= f.label :name, raw(Spree.t(:name) + required_span_tag) %>
33
+ <%= f.text_field :name,
34
+ class: "form-control",
35
+ placeholder: "Enter your name",
36
+ required: :required,
37
+ data: { target: "place.name" } %>
38
+ <%= error_message_on(f.object, :name) %>
39
+ </div>
40
+
41
+ <div class="row">
42
+ <div class="col-md-6 mb-3">
43
+ <%= f.label :lat, Spree.t(:lat), class: "form-label" %>
44
+ <%= f.text_field :lat,
45
+ class: "form-control",
46
+ placeholder: "e.g., 11.5621",
47
+ data: { target: "place.lat" } %>
48
+ <%= error_message_on(f.object, :lat) %>
49
+ </div>
50
+
51
+ <div class="col-md-6 mb-3">
52
+ <%= f.label :lon, Spree.t(:lon), class: "form-label" %>
53
+ <%= f.text_field :lon,
54
+ class: "form-control",
55
+ placeholder: "e.g., 104.9143",
56
+ data: { target: "place.lon" } %>
57
+ <%= error_message_on(f.object, :lon) %>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="mb-3">
62
+ <%= f.label :formatted_address, Spree.t(:address), class: "form-label" %>
63
+ <%= f.text_field :formatted_address,
64
+ class: "form-control",
65
+ placeholder: "Enter your address",
66
+ data: { target: "place.address" } %>
67
+ <%= error_message_on(f.object, :formatted_address) %>
68
+ </div>
69
+
70
+ <%= f.hidden_field :reference, value: f.object.reference, data: { target: "place.reference" } %>
71
+ <%= f.hidden_field :types, value: f.object.types, data: { target: "place.types" } %>
72
+ <%= f.hidden_field :vicinity, value: f.object.vicinity, data: { target: "place.vicinity" } %>
73
+ <%= f.hidden_field :icon, value: f.object.icon, data: { target: "place.icon" } %>
74
+ <%= f.hidden_field :rating, value: f.object.rating, data: { target: "place.rating" } %>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+
80
+ <script>
81
+ let map, marker;
82
+
83
+ function initMap() {
84
+ const mapElement = document.getElementById("map");
85
+ if (!mapElement) return;
86
+
87
+ const container = document.querySelector(".map-selector");
88
+ const defaultLat = parseFloat(container?.dataset.lat) || 11.5621;
89
+ const defaultLon = parseFloat(container?.dataset.lon) || 104.8885;
90
+
91
+ const center = { lat: defaultLat, lng: defaultLon };
92
+
93
+ map = new google.maps.Map(mapElement, { center, zoom: 18 });
94
+ marker = new google.maps.Marker({ position: center, map });
95
+ }
96
+
97
+ document.addEventListener("spree:load", () => {
98
+ const select = document.querySelector(".select2autocomplete");
99
+ if (!select) return;
100
+
101
+ $(select).on("select2:select", (e) => {
102
+ const base64Content = e.params.data.id;
103
+ if (!base64Content) return;
104
+
105
+ try {
106
+ const placeData = JSON.parse(atob(base64Content));
107
+
108
+ const setValue = (selector, value) => {
109
+ const el = document.querySelector(selector);
110
+ if (el) el.value = value ?? "";
111
+ };
112
+
113
+ setValue('[data-target="place.name"]', placeData.name);
114
+ setValue('[data-target="place.lat"]', placeData.lat);
115
+ setValue('[data-target="place.lon"]', placeData.lon);
116
+ setValue('[data-target="place.address"]', placeData.formatted_address);
117
+ setValue('[data-target="place.reference"]', placeData.reference);
118
+ setValue('[data-target="place.types"]', placeData.types?.[0] || "");
119
+ setValue('[data-target="place.vicinity"]', placeData.vicinity);
120
+ setValue('[data-target="place.icon"]', placeData.icon);
121
+ setValue('[data-target="place.rating"]', placeData.rating);
122
+
123
+ if (placeData.lat && placeData.lon && map && marker) {
124
+ const newLatLng = new google.maps.LatLng(+placeData.lat, +placeData.lon);
125
+ map.setCenter(newLatLng);
126
+ marker.setPosition(newLatLng);
127
+ }
128
+ } catch (err) {
129
+ console.error("Error decoding or parsing place data:", err);
130
+ }
131
+ });
132
+ });
133
+ </script>
@@ -0,0 +1,11 @@
1
+ <% content_for :page_title do %>
2
+ <%= page_header_back_button spree.admin_locations_path %>
3
+ <%= @object.name %>
4
+ <% end %>
5
+
6
+ <%= form_with model: @object, url: { action: 'update' }, html: { multipart: true } do |f| %>
7
+ <fieldset>
8
+ <%= render partial: 'form', locals: { f: f } %>
9
+ <%= render partial: 'spree/admin/shared/edit_resource_links' %>
10
+ </fieldset>
11
+ <% end %>
@@ -0,0 +1,67 @@
1
+ <% content_for :page_title do %>
2
+ <%= Spree.t(:locations) %>
3
+ <% end %>
4
+
5
+ <% content_for :page_actions do %>
6
+ <% if can?(:create, SpreeCmCommissioner::Place) %>
7
+ <%= button_link_to Spree.t(:new_location),
8
+ new_object_url,
9
+ class: "btn-success",
10
+ icon: "add.svg",
11
+ id: "admin_new_location" %>
12
+ <% end %>
13
+ <% end %>
14
+
15
+ <% content_for :table_filter do %>
16
+ <div data-hook="admin_locations_index_search">
17
+ <%= search_form_for [:admin, @search], url: spree.admin_locations_path do |f| %>
18
+ <div class="row">
19
+ <div class="col-md-6">
20
+ <div class="form-group">
21
+ <%= label_tag :q_name_cont, Spree.t(:name) %>
22
+ <%= f.text_field :name_cont, tabindex: 1, class: "form-control js-quick-search-target" %>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <div data-hook="admin_locations_index_search_buttons" class="form-actions">
27
+ <%= button Spree.t(:filter_results), 'search' %>
28
+ </div>
29
+ <% end %>
30
+ </div>
31
+ <% end %>
32
+
33
+ <div class="table-responsive border rounded bg-white mb-3" >
34
+ <table class="table" id="listing_locations" data-hook>
35
+ <thead class="text-muted">
36
+ <tr data-hook="location_header">
37
+ <th><%= sort_link @search, :name, Spree.t(:name), {}, { title: 'name' } %></th>
38
+ <th><%= Spree.t(:address) %></th>
39
+ <th><%= Spree.t(:latitude) %></th>
40
+ <th><%= Spree.t(:longitude) %></th>
41
+ <th><%= sort_link @search, :created_at, Spree.t(:created_at), {}, { title: 'created_at' } %></th>
42
+ <th><%= sort_link @search, :updated_at, Spree.t(:updated_at), {}, { title: 'updated_at' } %></th>
43
+ <th scope="col" data-hook="admin_locations_actions" class="actions"></th>
44
+ </tr>
45
+ </thead>
46
+ <tbody>
47
+ <% @locations.each do |location| %>
48
+ <tr id="<%= spree_dom_id(location) %>" data-hook="location_row">
49
+ <td><%= link_to location.name, spree.edit_admin_location_path(location) %></td>
50
+ <td><%= location.formatted_address.presence || location.vicinity %></td>
51
+ <td><%= location.lat %></td>
52
+ <td><%= location.lon %></td>
53
+ <td><%= location.created_at %></td>
54
+ <td><%= location.updated_at %></td>
55
+ <td data-hook="admin_locations_index_row_actions">
56
+ <span class="d-flex justify-content-end ">
57
+ <%= link_to_edit(location, url: edit_admin_location_url(location), no_text: true, class: 'edit') if can?(:edit, location) %>
58
+ <%= link_to_delete(location, url: admin_location_url(location), no_text: true) if can?(:delete, location) %>
59
+ </span>
60
+ </td>
61
+ </tr>
62
+ <% end %>
63
+ </tbody>
64
+ </table>
65
+ </div>
66
+
67
+ <%= paginate @locations, theme: 'admin-twitter-bootstrap-4' %>
@@ -0,0 +1,11 @@
1
+ <% content_for :page_title do %>
2
+ <%= page_header_back_button spree.admin_locations_path %>
3
+ <%= Spree.t(:new_location) %>
4
+ <% end %>
5
+
6
+ <%= form_with model: @object, url: { action: 'create' }, html: { multipart: true } do |f| %>
7
+ <fieldset>
8
+ <%= render partial: 'form', locals: { f: f } %>
9
+ <%= render partial: 'spree/admin/shared/new_resource_links' %>
10
+ </fieldset>
11
+ <% end %>
@@ -17,9 +17,11 @@
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_stock_items_path(variant_id: variant.id, stock_location_id: stock_location.id), method: :post do %>
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 %>
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 %>
23
25
  <div class="input-group-append">
24
26
  <%= button_tag(class: 'btn btn-outline-success pl-2 pr-1') do %>
25
27
  <%= svg_icon(name: 'arrow-left-right.svg', classes: "icon", width: 14, height: 14) %>
@@ -32,7 +34,10 @@
32
34
  <td class="text-center">
33
35
  <% if item.persisted? && can?(:update, item) %>
34
36
  <%= form_tag admin_stock_item_path(item), method: :put, class: 'toggle_stock_item_backorderable' do %>
35
- <%= check_box_tag 'stock_item[backorderable]', true, item.backorderable?, class: 'stock_item_backorderable', id: "stock_item_backorderable_#{stock_location.id}" %>
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; }" %>
36
41
  <% end %>
37
42
  <% else %>
38
43
  <%= 'N/A' %>