spree_cm_commissioner 2.0.3 → 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 (263) 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 +28 -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/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 +42 -0
  14. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +28 -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/controllers/spree_cm_commissioner/admin/products_controller_decorator.rb +14 -0
  22. data/app/finders/spree_cm_commissioner/accommodations/find.rb +37 -0
  23. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +32 -0
  24. data/app/interactors/spree_cm_commissioner/billing_address_creator.rb +33 -0
  25. data/app/interactors/spree_cm_commissioner/create_vendor.rb +11 -1
  26. data/app/interactors/spree_cm_commissioner/customer_notification_sender.rb +7 -2
  27. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +40 -0
  28. data/app/interactors/spree_cm_commissioner/fetch_facebook_user_data.rb +45 -0
  29. data/app/interactors/spree_cm_commissioner/google_places_fetcher.rb +1 -0
  30. data/app/interactors/spree_cm_commissioner/intercity_taxi_order_creator.rb +106 -0
  31. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +25 -0
  32. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +44 -0
  33. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +13 -0
  34. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +15 -0
  35. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +75 -0
  36. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +32 -0
  37. data/app/interactors/spree_cm_commissioner/taxi_trip_creator.rb +66 -0
  38. data/app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb +136 -0
  39. data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +155 -0
  40. data/app/interactors/spree_cm_commissioner/user_fb_token_authenticator.rb +37 -0
  41. data/app/interactors/spree_cm_commissioner/user_fb_token_checker.rb +20 -0
  42. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +8 -8
  43. data/app/interactors/spree_cm_commissioner/user_registration_with_fb_token.rb +62 -0
  44. data/app/interactors/spree_cm_commissioner/variant_block_updater.rb +62 -0
  45. data/app/interactors/spree_cm_commissioner/vehicle_updater.rb +41 -0
  46. data/app/jobs/spree_cm_commissioner/application_job.rb +20 -0
  47. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +20 -0
  48. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +7 -0
  49. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +7 -0
  50. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +11 -0
  51. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +11 -0
  52. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +9 -0
  53. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +18 -15
  54. data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +29 -15
  55. data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +144 -0
  56. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -12
  57. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +44 -0
  58. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +39 -0
  59. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +1 -3
  60. data/app/models/concerns/spree_cm_commissioner/product_type.rb +10 -0
  61. data/app/models/concerns/spree_cm_commissioner/route_type.rb +1 -1
  62. data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +1 -1
  63. data/app/models/concerns/spree_cm_commissioner/user_identity.rb +12 -4
  64. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +1 -0
  65. data/app/models/concerns/spree_cm_commissioner/vehicle_type.rb +11 -0
  66. data/app/models/spree_cm_commissioner/address_decorator.rb +36 -2
  67. data/app/models/spree_cm_commissioner/block.rb +43 -0
  68. data/app/models/spree_cm_commissioner/customer_notification.rb +6 -1
  69. data/app/models/spree_cm_commissioner/dynamic_field.rb +2 -0
  70. data/app/models/spree_cm_commissioner/guest.rb +128 -40
  71. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +41 -27
  72. data/app/models/spree_cm_commissioner/inventory.rb +11 -0
  73. data/app/models/spree_cm_commissioner/inventory_item.rb +82 -0
  74. data/app/models/spree_cm_commissioner/line_item_decorator.rb +47 -78
  75. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  76. data/app/models/spree_cm_commissioner/option_type_decorator.rb +1 -11
  77. data/app/models/spree_cm_commissioner/order/address_book_decorator.rb +30 -12
  78. data/app/models/spree_cm_commissioner/order_decorator.rb +38 -1
  79. data/app/models/spree_cm_commissioner/place.rb +3 -4
  80. data/app/models/spree_cm_commissioner/price_decorator.rb +9 -0
  81. data/app/models/spree_cm_commissioner/product_decorator.rb +41 -9
  82. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +41 -0
  83. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +126 -0
  84. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +36 -0
  85. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +25 -0
  86. data/app/models/spree_cm_commissioner/reserved_block.rb +31 -0
  87. data/app/models/spree_cm_commissioner/saved_guest.rb +21 -0
  88. data/app/models/spree_cm_commissioner/seat_layout.rb +20 -0
  89. data/app/models/spree_cm_commissioner/seat_section.rb +16 -0
  90. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +30 -0
  91. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +53 -0
  92. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +49 -0
  93. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +4 -0
  94. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +4 -0
  95. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +4 -0
  96. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +4 -0
  97. data/app/models/spree_cm_commissioner/service_calendar.rb +0 -2
  98. data/app/models/spree_cm_commissioner/state_decorator.rb +0 -1
  99. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +26 -25
  100. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +2 -1
  101. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  102. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +44 -0
  103. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +17 -0
  104. data/app/models/spree_cm_commissioner/taxon_decorator.rb +7 -1
  105. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +0 -6
  106. data/app/models/spree_cm_commissioner/trip.rb +19 -10
  107. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  108. data/app/models/spree_cm_commissioner/trip_stop.rb +10 -21
  109. data/app/models/spree_cm_commissioner/user_decorator.rb +1 -1
  110. data/app/models/spree_cm_commissioner/variant_block.rb +17 -0
  111. data/app/models/spree_cm_commissioner/variant_decorator.rb +37 -47
  112. data/app/models/spree_cm_commissioner/variant_options.rb +4 -23
  113. data/app/models/spree_cm_commissioner/vehicle.rb +12 -15
  114. data/app/models/spree_cm_commissioner/vendor_decorator.rb +14 -14
  115. data/app/models/spree_cm_commissioner/vendor_place.rb +13 -3
  116. data/app/overrides/spree/admin/products/_form/industry_taxons.html.erb.deface +26 -0
  117. data/app/overrides/spree/admin/products/_form/taxons.html.erb.deface +26 -0
  118. data/app/overrides/spree/admin/shared/sub_menu/_configuration/locations_tab.html.erb.deface +5 -0
  119. data/app/queries/spree_cm_commissioner/trip_query.rb +110 -131
  120. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +3 -0
  121. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  122. data/app/request_schemas/spree_cm_commissioner/inventory_item_schema.rb +8 -0
  123. data/app/request_schemas/spree_cm_commissioner/trip_search_request_schema.rb +20 -0
  124. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +19 -0
  125. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +2 -0
  126. data/app/serializers/spree/v2/storefront/cart_serializer_decorator.rb +1 -0
  127. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +3 -1
  128. data/app/serializers/spree/v2/storefront/product_serializer_decorator.rb +2 -0
  129. data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +1 -0
  130. data/app/serializers/spree_cm_commissioner/v2/storefront/amenity_serializer.rb +15 -0
  131. data/app/serializers/spree_cm_commissioner/v2/storefront/block_serializer.rb +11 -0
  132. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +3 -1
  133. data/app/serializers/spree_cm_commissioner/v2/storefront/inventory_item_serializer.rb +42 -0
  134. data/app/serializers/spree_cm_commissioner/v2/storefront/reserved_block_serializer.rb +9 -0
  135. data/app/serializers/spree_cm_commissioner/v2/storefront/saved_guest_serializer.rb +21 -0
  136. data/app/serializers/spree_cm_commissioner/v2/storefront/seat_layout_serializer.rb +12 -0
  137. data/app/serializers/spree_cm_commissioner/v2/storefront/seat_section_serializer.rb +11 -0
  138. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_place_serializer.rb +10 -0
  139. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_query_result_serializer.rb +14 -0
  140. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +17 -0
  141. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb +20 -0
  142. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_stop_serializer.rb +11 -0
  143. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_variant_serializer.rb +12 -0
  144. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vehicle_serializer.rb +16 -0
  145. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_vendor_serializer.rb +16 -0
  146. data/app/serializers/spree_cm_commissioner/v2/storefront/variant_block_serializer.rb +9 -0
  147. data/app/services/spree_cm_commissioner/transit/legs_builder_service.rb +46 -0
  148. data/app/services/spree_cm_commissioner/user_authenticator.rb +10 -1
  149. data/app/views/shared/_map.html.erb +5 -4
  150. data/app/views/spree/admin/customer_notifications/_form.html.erb +3 -3
  151. data/app/views/spree/admin/inventory_items/show.html.erb +72 -0
  152. data/app/views/spree/admin/locations/_form.html.erb +133 -0
  153. data/app/views/spree/admin/locations/edit.html.erb +11 -0
  154. data/app/views/spree/admin/locations/index.html.erb +67 -0
  155. data/app/views/spree/admin/locations/new.html.erb +11 -0
  156. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +7 -2
  157. data/app/views/spree/admin/stock_managements/calendar.html.erb +56 -0
  158. data/app/views/spree/admin/stock_managements/index.html.erb +55 -6
  159. data/config/initializers/paper_trail.rb +1 -0
  160. data/config/initializers/spree_permitted_attributes.rb +24 -4
  161. data/config/locales/en.yml +2 -0
  162. data/config/routes.rb +33 -2
  163. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +3 -1
  164. data/db/migrate/20250122000000_move_route_type_from_vehicles_to_trips.rb +7 -0
  165. data/db/migrate/20250304293518_create_cm_inventory_items.rb +21 -0
  166. data/db/migrate/20250428092706_add_active_to_cm_customer_notifications.rb +7 -0
  167. data/db/migrate/20250428103550_remove_tenant_id_and_vendor_id_from_cm_customer_notifications.rb +9 -0
  168. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +5 -0
  169. data/db/migrate/20250502025848_add_index_to_spree_products.rb +5 -0
  170. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +5 -0
  171. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +5 -0
  172. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +7 -0
  173. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +5 -0
  174. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +5 -0
  175. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +9 -0
  176. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +5 -0
  177. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +9 -0
  178. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +5 -0
  179. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +5 -0
  180. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +5 -0
  181. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +6 -0
  182. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +17 -0
  183. data/db/migrate/20250620090002_create_cm_seat_sections.rb +18 -0
  184. data/db/migrate/20250620090003_create_cm_blocks.rb +18 -0
  185. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +29 -0
  186. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +24 -0
  187. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +13 -0
  188. data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +5 -0
  189. data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +5 -0
  190. data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +5 -0
  191. data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +5 -0
  192. data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +7 -0
  193. data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +11 -0
  194. data/db/migrate/20250721080738_add_vehicle_type_to_cm_vehicles.rb +7 -0
  195. data/db/migrate/20250725092713_add_block_type_to_cm_blocks.rb +5 -0
  196. data/db/migrate/20250731062816_add_departure_time_and_arrival_time_to_trip_stop.rb +6 -0
  197. data/db/migrate/20250807033035_create_spree_cm_commissioner_saved_guests.rb +23 -0
  198. data/db/migrate/20250807040000_generate_pickup_time_integer_option_values.rb +71 -0
  199. data/db/migrate/20250808054835_add_saved_guest_reference_to_cm_blocks.rb +5 -0
  200. data/db/migrate/20250812015522_remove_unique_indexes_from_cm_user_identity_providers.rb +8 -0
  201. data/db/migrate/20250812121745_add_data_fill_stage_phase_to_cm_guests.rb +5 -0
  202. data/db/migrate/20250814073854_add_call_to_action_to_spree_products.rb +5 -0
  203. data/docker-compose.yml +1 -1
  204. data/lib/cm_app_logger.rb +17 -1
  205. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +14 -11
  206. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_cm_commissioner → spree_dashboard/spree_cm_commissioner}/utilities.js +4 -0
  207. data/lib/spree_cm_commissioner/cached_inventory_item.rb +23 -0
  208. data/lib/spree_cm_commissioner/calendar_event.rb +11 -1
  209. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +16 -0
  210. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +10 -0
  211. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  212. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +20 -0
  213. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  214. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +6 -30
  215. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +0 -36
  216. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +18 -34
  217. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +27 -0
  218. data/lib/spree_cm_commissioner/test_helper/factories/saved_guest_factory.rb +8 -0
  219. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +11 -0
  220. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +16 -0
  221. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  222. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +6 -0
  223. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +11 -3
  224. data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +13 -0
  225. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +7 -0
  226. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +41 -19
  227. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  228. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +6 -1
  229. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +13 -1
  230. data/lib/spree_cm_commissioner/transit/leg.rb +37 -0
  231. data/lib/spree_cm_commissioner/transit/seat_selection.rb +27 -0
  232. data/lib/spree_cm_commissioner/trip_query_result.rb +50 -0
  233. data/lib/spree_cm_commissioner/trip_result.rb +19 -10
  234. data/lib/spree_cm_commissioner/version.rb +1 -1
  235. data/lib/spree_cm_commissioner.rb +37 -1
  236. data/lib/tasks/create_default_non_permanent_inventory_items.rake +16 -0
  237. data/lib/tasks/ensure_correct_product_type.rake +7 -0
  238. data/lib/tasks/generate_inventory_items.rake +7 -0
  239. data/spree_cm_commissioner.gemspec +7 -0
  240. metadata +203 -28
  241. data/app/controllers/concerns/spree_cm_commissioner/transit/taxon_bitwise.rb +0 -44
  242. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +0 -20
  243. data/app/models/spree_cm_commissioner/branch.rb +0 -12
  244. data/app/models/spree_cm_commissioner/line_item_seat.rb +0 -10
  245. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +0 -8
  246. data/app/models/spree_cm_commissioner/stop.rb +0 -23
  247. data/app/models/spree_cm_commissioner/vehicle_seat.rb +0 -11
  248. data/app/models/spree_cm_commissioner/vehicle_type.rb +0 -76
  249. data/app/models/spree_cm_commissioner/vendor_stop.rb +0 -10
  250. data/app/queries/spree_cm_commissioner/trip_search_query.rb +0 -76
  251. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +0 -45
  252. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +0 -55
  253. data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +0 -54
  254. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +0 -11
  255. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +0 -12
  256. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +0 -8
  257. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +0 -8
  258. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +0 -7
  259. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +0 -14
  260. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +0 -8
  261. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +0 -8
  262. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +0 -96
  263. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +0 -11
@@ -4,10 +4,17 @@ module SpreeCmCommissioner
4
4
  belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
5
5
  belongs_to :dynamic_field_option, class_name: 'SpreeCmCommissioner::DynamicFieldOption', optional: true
6
6
 
7
- validates :value, presence: true
8
7
  validate :validate_value_format, if: -> { value.present? && dynamic_field.present? }
9
8
  validate :validate_option_reference, if: -> { dynamic_field_option.present? }
9
+ validate :validate_phase_sequence
10
10
  validate :check_required_fields_based_on_phase
11
+ validate :reject_empty_string_for_text_fields
12
+
13
+ after_commit :sync_guest_data_fill_stage_phase
14
+
15
+ scope :with_dynamic_field_and_options, lambda {
16
+ includes(:dynamic_field, :dynamic_field_option)
17
+ }
11
18
 
12
19
  private
13
20
 
@@ -15,6 +22,8 @@ module SpreeCmCommissioner
15
22
  return if dynamic_field.blank?
16
23
 
17
24
  case dynamic_field.data_type.to_s
25
+ when 'text', 'textarea'
26
+ errors.add(:value, "can't be blank") if value.is_a?(String) && value.strip == ''
18
27
  when 'number'
19
28
  errors.add(:value, 'must be a number') unless value.to_s.match?(/\A\d+\z/)
20
29
  when 'boolean'
@@ -40,44 +49,49 @@ module SpreeCmCommissioner
40
49
  errors.add(:dynamic_field_option, 'must belong to the same dynamic field')
41
50
  end
42
51
 
43
- def before_checkin_phase?
44
- guest.present? && guest.line_item.present? && guest.check_in.nil?
45
- end
52
+ def validate_phase_sequence
53
+ return if dynamic_field.blank? || guest.blank?
46
54
 
47
- def after_purchase_phase?
48
- guest.present? && guest.line_item.present? && guest.line_item.completed? && guest.check_in.nil?
55
+ case dynamic_field.data_fill_stage.to_sym
56
+ when :post_registration
57
+ errors.add(:base, 'Must complete pre_registration fields first') unless guest.pre_registration_completed?
58
+ when :during_check_in
59
+ unless guest.post_registration_completed? || !guest.post_registration_fields?
60
+ errors.add(:base, 'Must complete post_registration fields first')
61
+ end
62
+ end
49
63
  end
50
64
 
51
- def during_checkin_phase?
52
- guest.present? && guest.check_in.present?
53
- end
65
+ def field_required_in_current_phase?
66
+ return false if dynamic_field.blank? || guest.blank?
54
67
 
55
- def pre_registration_required?
56
- dynamic_field.data_fill_stage.to_sym == :pre_registration &&
68
+ case dynamic_field.data_fill_stage.to_sym
69
+ when :pre_registration, :post_registration
57
70
  guest.line_item.order.completed? && guest.check_in.blank?
71
+ when :during_check_in
72
+ guest.check_in.present?
73
+ else
74
+ false
75
+ end
58
76
  end
59
77
 
60
- def post_registration_required?
61
- dynamic_field.data_fill_stage.to_sym == :post_registration &&
62
- guest.line_item.order.completed? && guest.check_in.blank?
78
+ def check_required_fields_based_on_phase
79
+ return if dynamic_field.blank? || value.present?
80
+ return unless field_required_in_current_phase?
81
+
82
+ errors.add(:value, I18n.t("guest_dynamic_field.errors.#{dynamic_field.data_fill_stage}_required"))
63
83
  end
64
84
 
65
- def during_check_in_required?
66
- dynamic_field.data_fill_stage.to_sym == :during_check_in &&
67
- guest.check_in.present?
85
+ def sync_guest_data_fill_stage_phase
86
+ guest&.save_and_move_to_next_stage
68
87
  end
69
88
 
70
- def check_required_fields_based_on_phase
71
- return if dynamic_field.blank? || value.present?
89
+ def reject_empty_string_for_text_fields
90
+ return if dynamic_field.blank?
91
+ return unless %w[text textarea].include?(dynamic_field.data_type.to_s)
92
+ return unless value.is_a?(String)
72
93
 
73
- case dynamic_field.data_fill_stage.to_sym
74
- when :pre_registration
75
- errors.add(:value, I18n.t('guest_dynamic_field.errors.pre_registration_required')) if pre_registration_required?
76
- when :post_registration
77
- errors.add(:value, I18n.t('guest_dynamic_field.errors.post_registration_required')) if post_registration_required?
78
- when :during_check_in
79
- errors.add(:value, I18n.t('guest_dynamic_field.errors.during_check_in_required')) if during_check_in_required?
80
- end
94
+ errors.add(:value, "can't be blank") if value.strip == ''
81
95
  end
82
96
  end
83
97
  end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ class Inventory
3
+ include ActiveModel::Model
4
+
5
+ attr_accessor :variant_id, :inventory_date, :quantity_available, :max_capacity, :product_type
6
+
7
+ validates :variant_id, presence: true
8
+ validates :quantity_available, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, allow_nil: true
9
+ validates :max_capacity, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, allow_nil: true
10
+ end
11
+ end
@@ -0,0 +1,82 @@
1
+ module SpreeCmCommissioner
2
+ class InventoryItem < Base
3
+ include SpreeCmCommissioner::ProductType
4
+
5
+ MAX_DISPLAY_STOCK = 20
6
+
7
+ # Association
8
+ belongs_to :variant, class_name: 'Spree::Variant', optional: false
9
+
10
+ has_many :prices, class_name: 'Spree::Price', inverse_of: :inventory_item, dependent: :destroy
11
+
12
+ has_many :reserved_blocks, -> { reserved_or_on_hold }, class_name: 'SpreeCmCommissioner::ReservedBlock', inverse_of: :inventory_item
13
+
14
+ # Validation
15
+ validates :quantity_available, numericality: { greater_than_or_equal_to: 0 }
16
+ validates :max_capacity, numericality: { greater_than_or_equal_to: 0 } # Originally inventory of each variant.
17
+ validates :inventory_date, presence: true, if: :permanent_stock?
18
+ validates :variant_id, uniqueness: { scope: :inventory_date, message: -> (object, _data) { "The variant is taken on #{object.inventory_date}" } }
19
+
20
+ # Scope
21
+ scope :active, -> { where(inventory_date: nil).or(where('inventory_date >= ?', Time.zone.today)) }
22
+
23
+ before_save -> { self.product_type = variant.product_type }, if: -> { product_type.nil? }
24
+
25
+ def public_quantity_available
26
+ [quantity_available, MAX_DISPLAY_STOCK].min
27
+ end
28
+
29
+ def price_in(currency)
30
+ prices.detect { |price| price.currency == currency } || prices.build(currency: currency)
31
+ end
32
+
33
+ # This method is only used when admin update stock
34
+ def adjust_quantity!(quantity)
35
+ with_lock do
36
+ self.max_capacity = [max_capacity + quantity, 0].max
37
+ self.quantity_available = [quantity_available + quantity, 0].max
38
+ save!
39
+
40
+ # When user has been searched or booked a product, it has cached the quantity in redis,
41
+ # So we need to update redis cache if inventory key has been created in redis
42
+ adjust_quantity_in_redis(quantity)
43
+ end
44
+ end
45
+
46
+ def redis_key
47
+ "inventory:#{id}"
48
+ end
49
+
50
+ def adjust_quantity_in_redis(quantity)
51
+ SpreeCmCommissioner.redis_pool.with do |redis|
52
+ cached_quantity_available = redis.get(redis_key)
53
+ # ignore if redis doesn't exist
54
+ return if cached_quantity_available.nil? # rubocop:disable Lint/NonLocalExitFromIterator
55
+
56
+ script = <<~LUA
57
+ local key = KEYS[1]
58
+ local increment = tonumber(ARGV[1])
59
+ local current = tonumber(redis.call('GET', key) or 0)
60
+ local new_value = current + increment
61
+ if new_value < 0 then
62
+ new_value = 0
63
+ end
64
+ redis.call('SET', key, new_value)
65
+ return new_value
66
+ LUA
67
+
68
+ redis.eval(script, keys: [redis_key], argv: [quantity])
69
+ end
70
+ end
71
+
72
+ def active?
73
+ inventory_date.nil? || inventory_date >= Time.zone.today
74
+ end
75
+
76
+ def redis_expired_in
77
+ expired_in = 31_536_000 # 1 year for normal stock
78
+ expired_in = Time.parse(inventory_date.to_s).end_of_day.to_i - Time.zone.now.to_i if inventory_date.present?
79
+ [expired_in, 0].max
80
+ end
81
+ end
82
+ end
@@ -1,6 +1,6 @@
1
1
  module SpreeCmCommissioner
2
2
  module LineItemDecorator
3
- def self.prepended(base) # rubocop:disable Metrics/MethodLength
3
+ def self.prepended(base) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
4
4
  include_modules(base)
5
5
 
6
6
  base.belongs_to :accepter, class_name: 'Spree::User', optional: true
@@ -10,31 +10,32 @@ module SpreeCmCommissioner
10
10
  base.has_one :google_wallet, class_name: 'SpreeCmCommissioner::GoogleWallet', through: :product
11
11
 
12
12
  base.has_many :option_types, through: :product
13
+
14
+ base.has_many :inventory_items, lambda { |line_item|
15
+ where(inventory_date: nil).or(where(inventory_date: line_item.date_range))
16
+ }, through: :variant
17
+
13
18
  base.has_many :taxons, class_name: 'Spree::Taxon', through: :product
14
19
  base.has_many :guests, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
20
+ base.has_many :guests_with_blocks, -> { where.not(block_id: nil) }, class_name: 'SpreeCmCommissioner::Guest'
21
+ base.has_many :reserved_blocks, through: :guests, class_name: 'SpreeCmCommissioner::ReservedBlock'
15
22
  base.has_many :pending_guests, pending_guests_query, class_name: 'SpreeCmCommissioner::Guest', dependent: :destroy
16
23
  base.has_many :product_completion_steps, class_name: 'SpreeCmCommissioner::ProductCompletionStep', through: :product
17
- base.has_many :line_item_seats, class_name: 'SpreeCmCommissioner::LineItemSeat', dependent: :destroy
18
24
 
19
25
  base.before_save :update_vendor_id
20
- base.before_save :update_quantity, if: :transit?
21
-
22
- base.validate :validate_seats_reservation, if: :transit?
23
26
 
24
27
  base.before_create :add_due_date, if: :subscription?
28
+ base.before_save -> { self.product_type = variant.product_type }, if: -> { product_type.nil? }
25
29
 
26
30
  base.validate :ensure_not_exceed_max_quantity_per_order, if: -> { variant&.max_quantity_per_order.present? }
27
31
 
28
32
  base.whitelisted_ransackable_associations |= %w[guests order]
29
33
  base.whitelisted_ransackable_attributes |= %w[number to_date from_date vendor_id]
30
34
 
31
- base.delegate :delivery_required?, :permanent_stock?, :high_demand, :transit?,
35
+ base.delegate :delivery_required?, :high_demand,
32
36
  to: :variant
33
- base.delegate :discontinue_on, :product_type, :accommodation?, :service?, :ecommerce?, :need_confirmation,
34
- to: :product
35
37
 
36
38
  base.accepts_nested_attributes_for :guests, allow_destroy: true
37
- base.accepts_nested_attributes_for :line_item_seats, allow_destroy: true
38
39
 
39
40
  def base.json_api_columns
40
41
  json_api_columns = column_names.reject { |c| c.match(/_id$|id|preferences|(.*)password|(.*)token|(.*)api_key/) }
@@ -42,6 +43,10 @@ module SpreeCmCommissioner
42
43
  json_api_columns << :vendor_id
43
44
  end
44
45
 
46
+ def discontinue_on
47
+ variant.discontinue_on || product.discontinue_on
48
+ end
49
+
45
50
  def base.search_by_qr_data!(data)
46
51
  matches = data.match(/(R\d+)-([A-Za-z0-9_\-]+)-(L\d+)/)&.captures
47
52
 
@@ -60,6 +65,8 @@ module SpreeCmCommissioner
60
65
  base.include SpreeCmCommissioner::LineItemDurationable
61
66
  base.include SpreeCmCommissioner::LineItemsFilterScope
62
67
  base.include SpreeCmCommissioner::LineItemGuestsConcern
68
+ base.include SpreeCmCommissioner::LineItemTransitable
69
+ base.include SpreeCmCommissioner::ProductType
63
70
  base.include SpreeCmCommissioner::ProductDelegation
64
71
  base.include SpreeCmCommissioner::KycBitwise
65
72
  end
@@ -75,24 +82,39 @@ module SpreeCmCommissioner
75
82
  }
76
83
  end
77
84
 
78
- def reservation?
79
- date_present? && !subscription?
80
- end
85
+ # override to calculate price per date for permanent stock
86
+ def update_price_from_modifier(currency, opts)
87
+ self.currency = currency
81
88
 
82
- # date_unit could be number of nights, or days or hours depending on usecases
83
- # For example:
84
- # - accomodation uses number of nights.
85
- # - appointment uses number of hours, etc.
86
- #
87
- # override
88
- def amount
89
- base_price = price * quantity
89
+ # these fields can be null during this process below.
90
+ # it is needed for permanent_stock?, date_range to work.
91
+ self.product_type = variant.product_type
92
+ self.from_date = opts.delete(:from_date)&.to_datetime
93
+ self.to_date = opts.delete(:to_date)&.to_datetime
90
94
 
91
- if permanent_stock? && date_unit.present?
92
- base_price * date_unit
93
- else
94
- base_price
95
- end
95
+ base_price = variant.price_in(currency)
96
+
97
+ self.price = if permanent_stock?
98
+ date_range.map do |date|
99
+ selected_price = variant.price_for_date(date: date, currency: currency) || base_price
100
+ (selected_price.amount || 0) + variant.price_modifier_amount_in(currency, opts.merge(date: date))
101
+ end.sum
102
+ else
103
+ (base_price.amount || 0) + variant.price_modifier_amount_in(currency, opts)
104
+ end
105
+ end
106
+
107
+ # override to calculate price per date for permanent stock
108
+ def update_price
109
+ base_price = variant.price_in(order.currency)
110
+ self.price = if permanent_stock?
111
+ date_range.map do |date|
112
+ selected_price = variant.price_for_date(date: date, currency: order.currency) || base_price
113
+ selected_price.amount || 0
114
+ end.sum
115
+ else
116
+ base_price.amount || 0
117
+ end
96
118
  end
97
119
 
98
120
  def allowed_self_check_in?
@@ -179,8 +201,6 @@ module SpreeCmCommissioner
179
201
 
180
202
  # override
181
203
  def sufficient_stock?
182
- return transit_sufficient_stock? if variant.product.product_type == 'transit'
183
-
184
204
  SpreeCmCommissioner::Stock::LineItemAvailabilityChecker.new(self).can_supply?(quantity)
185
205
  end
186
206
 
@@ -199,18 +219,6 @@ module SpreeCmCommissioner
199
219
  errors.add(:quantity, 'exceeded_max_quantity_per_order') if quantity > variant.max_quantity_per_order
200
220
  end
201
221
 
202
- def transit_sufficient_stock?
203
- return selected_seats_available? if reservation_trip.allow_seat_selection
204
-
205
- seat_quantity_available?(reservation_trip)
206
- end
207
-
208
- def update_quantity
209
- return if line_item_seats.blank?
210
-
211
- self.quantity = line_item_seats.size
212
- end
213
-
214
222
  def update_vendor_id
215
223
  self.vendor_id = variant.vendor_id
216
224
  end
@@ -233,45 +241,6 @@ module SpreeCmCommissioner
233
241
 
234
242
  from_date + variant.month.month + day.days
235
243
  end
236
-
237
- def validate_seats_reservation
238
- if reservation_trip.allow_seat_selection && !selected_seats_available?
239
- errors.add(:base, :some_seats_are_booked, message: 'Some seats are already booked')
240
- elsif !reservation_trip.allow_seat_selection && !seat_quantity_available?(reservation_trip)
241
- errors.add(:quantity, :exceeded_available_quantity, message: 'exceeded available quantity')
242
- end
243
- end
244
-
245
- def selected_seats_available?
246
- selected_seat_ids = line_item_seats.map(&:seat_id)
247
- !selected_seat_ids_occupied?(selected_seat_ids)
248
- end
249
-
250
- def seat_quantity_available?(trip)
251
- booked_quantity = Spree::LineItem.joins(:order)
252
- .where(variant_id: variant_id, date: date, spree_orders: { state: 'complete' })
253
- .where.not(spree_line_items: { id: id })
254
- .sum(:quantity)
255
- remaining_quantity = trip.vehicle.number_of_seats - booked_quantity
256
- remaining_quantity >= quantity
257
- end
258
-
259
- def reservation_trip
260
- return @trip if defined? @trip
261
-
262
- route = Spree::Variant.find_by(id: variant_id).product
263
- @trip = route.trip
264
- end
265
-
266
- def selected_seat_ids_occupied?(selected_seat_ids)
267
- # check to see if there are any selected_ids exist in the line_item_seats and belongs to completed order
268
- SpreeCmCommissioner::LineItemSeat.joins(line_item: :order)
269
- .where(seat_id: selected_seat_ids, date: date, variant_id: variant_id, spree_orders: { state: 'complete',
270
- canceled_at: nil
271
- }
272
- )
273
- .present?
274
- end
275
244
  end
276
245
  end
277
246
 
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- class NotificationTaxon < SpreeCmCommissioner::Base
2
+ class NotificationTaxon < Base
3
3
  belongs_to :customer_notification, class_name: 'SpreeCmCommissioner::CustomerNotification'
4
4
  belongs_to :taxon, class_name: 'Spree::Taxon'
5
5
  end
@@ -6,7 +6,7 @@ module SpreeCmCommissioner
6
6
  base.include SpreeCmCommissioner::ParameterizeName
7
7
  base.include SpreeCmCommissioner::OptionTypeAttrType
8
8
 
9
- base.enum kind: %i[variant product vendor vehicle_type transit]
9
+ base.enum kind: %i[variant product vendor vehicle]
10
10
 
11
11
  base.validates :name, presence: true
12
12
 
@@ -19,16 +19,6 @@ module SpreeCmCommissioner
19
19
  base.scope :promoted, -> { where(promoted: true) }
20
20
  base.whitelisted_ransackable_attributes = %w[kind]
21
21
 
22
- def base.amenities
23
- Spree::OptionType.where(kind: 'vehicle_type', name: 'amenities', presentation: 'Amenities', attr_type: 'amenity').first_or_create
24
- end
25
-
26
- def base.vehicle
27
- Spree::OptionType.where(presentation: 'vehicle', attr_type: 'vehicle_id', kind: 'variant',
28
- name: 'vehicle'
29
- ).first_or_create
30
- end
31
-
32
22
  def base.rules_option_type
33
23
  Spree::OptionType.find_by(name: RULES_OPTION_TYPE_NAME)
34
24
  end
@@ -5,30 +5,48 @@
5
5
  module SpreeCmCommissioner
6
6
  module Order
7
7
  module AddressBookDecorator
8
- def guest_order? = user.blank?
9
-
10
8
  # override
11
9
  def bill_address_attributes=(attributes)
12
- attributes[:id] = bill_address&.id if attributes[:id].blank?
13
- return if guest_order? && !basic_info_included?(attributes)
10
+ attributes[:id] = bill_address_id if attributes[:id].blank?
11
+ attributes[:phone] = intel_phone_number if intel_phone_number.present?
14
12
 
15
- super
13
+ self.bill_address = assign_address_attributes(attributes)
14
+ user.bill_address = bill_address if user && user.bill_address.nil?
16
15
  end
17
16
 
18
17
  # override
19
18
  def ship_address_attributes=(attributes)
20
- attributes[:id] = bill_address&.id if attributes[:id].blank?
21
- return if guest_order? && !basic_info_included?(attributes)
19
+ attributes[:id] = ship_address_id if attributes[:id].blank?
20
+ attributes[:phone] = intel_phone_number if intel_phone_number.present?
22
21
 
23
- super
22
+ self.ship_address = assign_address_attributes(attributes)
23
+ user.ship_address = ship_address if user && user.ship_address.nil?
24
24
  end
25
25
 
26
- private
26
+ def assign_address_attributes(attributes = {})
27
+ return if attributes.blank?
28
+
29
+ attributes.transform_values! { |v| v == '' ? nil : v }
30
+ attributes = attributes.to_h.symbolize_keys
27
31
 
28
- def basic_info_included?(attributes)
29
- return true if attributes[:id].present?
32
+ existing_address = attributes[:id].present? ? find_existing_address(attributes[:id]) : nil
33
+
34
+ if existing_address&.editable?
35
+ existing_address.assign_attributes(attributes)
36
+ existing_address
37
+ else
38
+ ::Spree::Address.new(attributes.except(:id, :updated_at, :created_at))
39
+ end
40
+ end
30
41
 
31
- %i[firstname lastname phone].all? { |key| attributes[key].present? }
42
+ def find_existing_address(id)
43
+ if user.present?
44
+ ::Spree::Address.where('(user_id = ? OR user_id IS NULL) AND deleted_at IS NULL', user.id)
45
+ .find_by(id: id)
46
+ else
47
+ ::Spree::Address.where(user_id: nil, deleted_at: nil)
48
+ .find_by(id: id)
49
+ end
32
50
  end
33
51
  end
34
52
  end
@@ -2,6 +2,7 @@ module SpreeCmCommissioner
2
2
  module OrderDecorator
3
3
  def self.prepended(base) # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
4
4
  base.include SpreeCmCommissioner::PhoneNumberSanitizer
5
+ base.include SpreeCmCommissioner::OrderSeatable
5
6
  base.include SpreeCmCommissioner::OrderStateMachine
6
7
 
7
8
  base.scope :subscription, -> { where.not(subscription_id: nil) }
@@ -42,6 +43,14 @@ module SpreeCmCommissioner
42
43
  base.has_many :vendors, through: :products, class_name: 'Spree::Vendor'
43
44
  base.has_many :taxons, through: :products, class_name: 'Spree::Taxon'
44
45
  base.has_many :guests, through: :line_items, class_name: 'SpreeCmCommissioner::Guest'
46
+
47
+ base.has_many :saved_guests,
48
+ through: :guests,
49
+ source: :saved_guest,
50
+ class_name: 'SpreeCmCommissioner::SavedGuest'
51
+
52
+ base.has_many :blocks, through: :guests, class_name: 'SpreeCmCommissioner::Block', source: :block
53
+ base.has_many :reserved_blocks, through: :guests, class_name: 'SpreeCmCommissioner::ReservedBlock'
45
54
  base.has_many :guest_card_classes, class_name: 'SpreeCmCommissioner::GuestCardClass', through: :variants
46
55
 
47
56
  base.delegate :customer, to: :user, allow_nil: true
@@ -49,6 +58,8 @@ module SpreeCmCommissioner
49
58
  base.whitelisted_ransackable_associations |= %w[customer taxon payments guests invoice]
50
59
  base.whitelisted_ransackable_attributes |= %w[intel_phone_number phone_number email number state]
51
60
 
61
+ base.accepts_nested_attributes_for :saved_guests, allow_destroy: true
62
+
52
63
  def base.search_by_qr_data!(data)
53
64
  token = data.match(/^R\d{9,}-([A-Za-z0-9_\-]+)$/)&.captures
54
65
 
@@ -58,6 +69,13 @@ module SpreeCmCommissioner
58
69
  end
59
70
  end
60
71
 
72
+ # override
73
+ # spree use this method to check stock availability & consider whether :order can continue to next state.
74
+ def insufficient_stock_lines
75
+ checker = SpreeCmCommissioner::Stock::OrderAvailabilityChecker.new(self)
76
+ checker.insufficient_stock_lines
77
+ end
78
+
61
79
  def ticket_seller_user?
62
80
  return false if user.nil?
63
81
 
@@ -106,7 +124,14 @@ module SpreeCmCommissioner
106
124
  end
107
125
 
108
126
  def mark_as_archive
109
- update(archived_at: Time.current)
127
+ blocks_canceled = begin
128
+ cancel_blocks!
129
+ true
130
+ rescue StandardError
131
+ false
132
+ end
133
+
134
+ update(archived_at: Time.current) if blocks_canceled
110
135
  end
111
136
 
112
137
  # overrided
@@ -199,6 +224,18 @@ module SpreeCmCommissioner
199
224
 
200
225
  private
201
226
 
227
+ def unstock_inventory_in_redis!
228
+ CmAppLogger.log(label: "#{self.class.name}#unstock_inventory_in_redis!", data: { order_id: id }) do
229
+ SpreeCmCommissioner::RedisStock::InventoryUpdater.new(line_item_ids).unstock!
230
+ end
231
+ end
232
+
233
+ def restock_inventory_in_redis!
234
+ CmAppLogger.log(label: "#{self.class.name}#restock_inventory_in_redis!", data: { order_id: id }) do
235
+ SpreeCmCommissioner::RedisStock::InventoryUpdater.new(line_item_ids).restock!
236
+ end
237
+ end
238
+
202
239
  # override :spree_api
203
240
  def webhook_payload_body
204
241
  resource_serializer.new(
@@ -1,7 +1,5 @@
1
- require_dependency 'spree_cm_commissioner'
2
-
3
1
  module SpreeCmCommissioner
4
- class Place < ApplicationRecord
2
+ class Place < Base
5
3
  acts_as_nested_set
6
4
 
7
5
  validates :reference, presence: true, if: :validate_reference?
@@ -16,8 +14,9 @@ module SpreeCmCommissioner
16
14
  has_many :product_places, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
17
15
  has_many :products, through: :product_places
18
16
 
17
+ has_many :location_vendor_places, -> { where(place_type: :location) }, class_name: 'SpreeCmCommissioner::VendorPlace'
18
+
19
19
  has_many :children, -> { order(:lft) }, class_name: 'SpreeCmCommissioner::Place', foreign_key: :parent_id, dependent: :destroy
20
- has_many :vendor_stops, class_name: 'SpreeCmCommissioner::VendorStop', dependent: :destroy, foreign_key: :stop_id
21
20
 
22
21
  has_many :taxon_places, class_name: 'SpreeCmCommissioner::TaxonPlace', dependent: :destroy
23
22
  has_many :taxons, through: :taxon_places
@@ -0,0 +1,9 @@
1
+ module SpreeCmCommissioner
2
+ module PriceDecorator
3
+ def self.prepended(base)
4
+ base.belongs_to :inventory_item, class_name: 'SpreeCmCommissioner::InventoryItem', inverse_of: :prices, optional: true
5
+ end
6
+ end
7
+ end
8
+
9
+ Spree::Price.prepend(SpreeCmCommissioner::PriceDecorator) unless Spree::Price.included_modules.include?(SpreeCmCommissioner::PriceDecorator)