spree_cm_commissioner 2.0.0.pre.pre → 2.0.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 (267) 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/operator/pie_chart_events_controller.rb +46 -0
  26. data/app/controllers/spree/api/v2/organizer/invite_crews_controller.rb +33 -0
  27. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +1 -1
  28. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +31 -14
  29. data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +5 -1
  30. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +30 -4
  31. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  32. data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +2 -0
  33. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
  34. data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +11 -0
  35. data/app/controllers/spree_cm_commissioner/well_known_controller.rb +31 -17
  36. data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +24 -81
  37. data/app/finders/spree_cm_commissioner/line_items/find_by_variant_decorator.rb +20 -0
  38. data/app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb +27 -0
  39. data/app/interactors/spree_cm_commissioner/asset_links_fetcher.rb +27 -0
  40. data/app/interactors/spree_cm_commissioner/create_ticket.rb +6 -5
  41. data/app/interactors/spree_cm_commissioner/create_vendor.rb +44 -0
  42. data/app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb +48 -0
  43. data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +0 -1
  44. data/app/interactors/spree_cm_commissioner/sms.rb +1 -1
  45. data/app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb +144 -0
  46. data/app/interactors/spree_cm_commissioner/user_id_token_authenticator.rb +7 -3
  47. data/app/interactors/spree_cm_commissioner/user_id_token_checker.rb +11 -3
  48. data/app/interactors/spree_cm_commissioner/user_identity_checker.rb +12 -6
  49. data/app/interactors/spree_cm_commissioner/user_registration_with_id_token.rb +7 -1
  50. data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +5 -1
  51. data/app/jobs/spree_cm_commissioner/application_job.rb +0 -20
  52. data/app/jobs/spree_cm_commissioner/application_unique_job.rb +0 -20
  53. data/app/jobs/spree_cm_commissioner/sms_pin_code_job.rb +1 -1
  54. data/app/mailers/spree/order_mailer_decorator.rb +18 -3
  55. data/app/models/concerns/spree_cm_commissioner/event_check_in_flowable.rb +30 -0
  56. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +33 -9
  57. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +13 -1
  58. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -39
  59. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +3 -1
  60. data/app/models/concerns/spree_cm_commissioner/product_type.rb +0 -10
  61. data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +1 -1
  62. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +5 -0
  63. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +4 -2
  64. data/app/models/spree_cm_commissioner/blazer_queryable.rb +8 -0
  65. data/app/models/spree_cm_commissioner/branch.rb +12 -0
  66. data/app/models/spree_cm_commissioner/chart_type.rb +10 -0
  67. data/app/models/spree_cm_commissioner/crew_invite_link.rb +4 -0
  68. data/app/models/spree_cm_commissioner/dynamic_field.rb +37 -3
  69. data/app/models/spree_cm_commissioner/dynamic_field_option.rb +7 -1
  70. data/app/models/spree_cm_commissioner/guest.rb +57 -19
  71. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +61 -3
  72. data/app/models/spree_cm_commissioner/invite.rb +4 -6
  73. data/app/models/spree_cm_commissioner/invite_team.rb +3 -1
  74. data/app/models/spree_cm_commissioner/line_item_decorator.rb +78 -46
  75. data/app/models/spree_cm_commissioner/line_item_seat.rb +10 -0
  76. data/app/models/spree_cm_commissioner/notification_taxon.rb +1 -1
  77. data/app/models/spree_cm_commissioner/option_type_decorator.rb +11 -1
  78. data/app/models/spree_cm_commissioner/option_value_vehicle_type.rb +8 -0
  79. data/app/models/spree_cm_commissioner/order_decorator.rb +1 -30
  80. data/app/models/spree_cm_commissioner/pin_code.rb +3 -2
  81. data/app/models/spree_cm_commissioner/pin_code_telegram.rb +28 -0
  82. data/app/models/spree_cm_commissioner/place.rb +3 -1
  83. data/app/models/spree_cm_commissioner/product_decorator.rb +26 -10
  84. data/app/models/spree_cm_commissioner/promotion_category_decorator.rb +11 -0
  85. data/app/models/spree_cm_commissioner/service_calendar.rb +2 -0
  86. data/app/models/spree_cm_commissioner/state_decorator.rb +1 -0
  87. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +25 -26
  88. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +1 -2
  89. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  90. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +0 -17
  91. data/app/models/spree_cm_commissioner/stop.rb +23 -0
  92. data/app/models/spree_cm_commissioner/taxon_decorator.rb +6 -2
  93. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +6 -0
  94. data/app/models/spree_cm_commissioner/telegram_chat.rb +6 -0
  95. data/app/models/spree_cm_commissioner/trip.rb +10 -12
  96. data/app/models/spree_cm_commissioner/trip_connection.rb +5 -5
  97. data/app/models/spree_cm_commissioner/trip_stop.rb +3 -2
  98. data/app/models/spree_cm_commissioner/user_decorator.rb +6 -0
  99. data/app/models/spree_cm_commissioner/user_identity_provider.rb +26 -4
  100. data/app/models/spree_cm_commissioner/user_taxon.rb +1 -0
  101. data/app/models/spree_cm_commissioner/variant_decorator.rb +47 -36
  102. data/app/models/spree_cm_commissioner/variant_options.rb +23 -0
  103. data/app/models/spree_cm_commissioner/vehicle.rb +14 -9
  104. data/app/models/spree_cm_commissioner/vehicle_seat.rb +11 -0
  105. data/app/models/spree_cm_commissioner/vehicle_type.rb +76 -0
  106. data/app/models/spree_cm_commissioner/vendor_decorator.rb +13 -7
  107. data/app/models/spree_cm_commissioner/vendor_place.rb +5 -6
  108. data/app/models/spree_cm_commissioner/vendor_stop.rb +2 -1
  109. data/app/overrides/spree/admin/taxons/_form/check_in_flows.html.erb.deface +18 -0
  110. data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +2 -2
  111. data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +45 -3
  112. data/app/queries/spree_cm_commissioner/pie_chart_event_queries.rb +179 -0
  113. data/app/queries/spree_cm_commissioner/trip_query.rb +26 -23
  114. data/app/queries/spree_cm_commissioner/trip_search_query.rb +76 -0
  115. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +45 -0
  116. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +55 -0
  117. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +0 -3
  118. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  119. data/app/serializables/spree_cm_commissioner/pie_chart_event.rb +11 -0
  120. data/app/serializers/spree/v2/organizer/invite_crews_serializer.rb +11 -0
  121. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +0 -2
  122. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +0 -1
  123. data/app/serializers/spree/v2/tenant/user_serializer.rb +1 -0
  124. data/app/serializers/spree_cm_commissioner/v2/operator/chart_type_serializer.rb +10 -0
  125. data/app/serializers/spree_cm_commissioner/v2/operator/dashboard_crew_event_serializer.rb +4 -1
  126. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +1 -3
  127. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -3
  128. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +2 -1
  129. data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +23 -15
  130. data/app/services/spree_cm_commissioner/user_authenticator.rb +1 -1
  131. data/app/services/spree_cm_commissioner/vehicle_option_value_creator.rb +11 -0
  132. data/app/views/blazer/queries/_content.html.erb +8 -0
  133. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +2 -7
  134. data/app/views/spree/admin/stock_managements/index.html.erb +6 -55
  135. data/app/views/spree/admin/tenant_vendors/index.html.erb +9 -2
  136. data/app/views/spree/admin/tenants/_form.html.erb +118 -42
  137. data/app/views/spree/admin/tenants/edit.html.erb +2 -1
  138. data/app/views/spree/admin/tenants/index.html.erb +7 -1
  139. data/app/views/spree/admin/vendors/_form.html.erb +14 -0
  140. data/app/views/spree/order_mailer/confirm_email.html.erb +27 -16
  141. data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +5 -1
  142. data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +41 -4
  143. data/app/views/spree_cm_commissioner/order_mailer/tenant/_customer_info.html.erb +42 -0
  144. data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +25 -0
  145. data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +19 -0
  146. data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +33 -0
  147. data/config/initializers/spree_permitted_attributes.rb +2 -5
  148. data/config/locales/en.yml +10 -1
  149. data/config/routes.rb +7 -22
  150. data/db/migrate/20240202080634_update_counter_cache_of_vehicle_type.rb +1 -3
  151. data/db/migrate/20250616084219_add_description_to_cm_vendor_place.rb +5 -0
  152. data/db/migrate/20250630103536_create_cm_telegram_chats.rb +13 -0
  153. data/db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb +6 -0
  154. data/db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb +5 -0
  155. data/db/migrate/20250702091935_add_status_to_dynamic_field_option.rb +5 -0
  156. data/db/migrate/20250707032008_add_vendor_id_to_spree_category.rb +7 -0
  157. data/db/migrate/20250709073455_add_email_fields_to_spree_vendors.rb +6 -0
  158. data/db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb +11 -0
  159. data/db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb +11 -0
  160. data/db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb +7 -0
  161. data/db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb +19 -0
  162. data/db/migrate/20250715103333_remove_indexes_from_cm_user_identity_providers.rb +13 -0
  163. data/db/migrate/20250718071620_add_data_fill_stage_to_dynamic_fields.rb +5 -0
  164. data/docker-compose.yml +1 -1
  165. data/lib/cm_app_logger.rb +4 -11
  166. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +11 -14
  167. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_dashboard/spree_cm_commissioner → spree_cm_commissioner}/utilities.js +0 -4
  168. data/lib/spree_cm_commissioner/calendar_event.rb +1 -11
  169. data/lib/spree_cm_commissioner/test_helper/factories/branch_factory.rb +12 -0
  170. data/lib/spree_cm_commissioner/test_helper/factories/departure_time_option_type_factory.rb +8 -0
  171. data/lib/spree_cm_commissioner/test_helper/factories/duration_option_type_factory.rb +8 -0
  172. data/lib/spree_cm_commissioner/test_helper/factories/guest_factory.rb +0 -10
  173. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  174. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  175. data/lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb +7 -0
  176. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +30 -6
  177. data/lib/spree_cm_commissioner/test_helper/factories/order_factory.rb +36 -0
  178. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +34 -18
  179. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  180. data/lib/spree_cm_commissioner/test_helper/factories/stop_factory.rb +14 -0
  181. data/lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb +8 -0
  182. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +3 -10
  183. data/lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb +1 -1
  184. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +19 -41
  185. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
  186. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_option_type_factory.rb +8 -0
  187. data/lib/spree_cm_commissioner/test_helper/factories/vehicle_type_factory.rb +96 -0
  188. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -1
  189. data/lib/spree_cm_commissioner/trip_seat_layout_result.rb +11 -0
  190. data/lib/spree_cm_commissioner/version.rb +1 -1
  191. data/lib/spree_cm_commissioner.rb +1 -35
  192. data/spree_cm_commissioner.gemspec +0 -7
  193. metadata +70 -133
  194. data/app/controllers/spree/admin/inventory_items_controller.rb +0 -83
  195. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +0 -42
  196. data/app/finders/spree_cm_commissioner/accommodations/find.rb +0 -37
  197. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +0 -32
  198. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +0 -40
  199. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +0 -25
  200. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +0 -44
  201. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +0 -13
  202. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +0 -15
  203. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +0 -75
  204. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +0 -32
  205. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +0 -7
  206. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +0 -7
  207. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +0 -11
  208. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +0 -11
  209. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +0 -9
  210. data/app/models/concerns/spree_cm_commissioner/order_seatable.rb +0 -44
  211. data/app/models/spree_cm_commissioner/block.rb +0 -23
  212. data/app/models/spree_cm_commissioner/inventory.rb +0 -11
  213. data/app/models/spree_cm_commissioner/inventory_item.rb +0 -69
  214. data/app/models/spree_cm_commissioner/price_decorator.rb +0 -9
  215. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +0 -41
  216. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +0 -126
  217. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +0 -36
  218. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +0 -25
  219. data/app/models/spree_cm_commissioner/reserved_block.rb +0 -30
  220. data/app/models/spree_cm_commissioner/seat_layout.rb +0 -20
  221. data/app/models/spree_cm_commissioner/seat_section.rb +0 -16
  222. data/app/models/spree_cm_commissioner/seats/blocks_canceler.rb +0 -30
  223. data/app/models/spree_cm_commissioner/seats/blocks_holder.rb +0 -53
  224. data/app/models/spree_cm_commissioner/seats/blocks_reserver.rb +0 -49
  225. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_on_hold_by_other_guest.rb +0 -4
  226. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_other_guest.rb +0 -4
  227. data/app/models/spree_cm_commissioner/seats/errors/blocks_are_reserved_by_same_guest.rb +0 -4
  228. data/app/models/spree_cm_commissioner/seats/errors/unable_to_save_reserved_block_record.rb +0 -4
  229. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +0 -44
  230. data/app/models/spree_cm_commissioner/taxon_blazer_query.rb +0 -8
  231. data/app/models/spree_cm_commissioner/variant_block.rb +0 -9
  232. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +0 -19
  233. data/app/views/spree/admin/inventory_items/show.html.erb +0 -72
  234. data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -56
  235. data/config/initializers/paper_trail.rb +0 -1
  236. data/db/migrate/20250304293518_create_cm_inventory_items.rb +0 -21
  237. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +0 -5
  238. data/db/migrate/20250502025848_add_index_to_spree_products.rb +0 -5
  239. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +0 -5
  240. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +0 -5
  241. data/db/migrate/20250603035256_add_inventory_item_to_spree_prices.rb +0 -7
  242. data/db/migrate/20250619073724_drop_table_cm_line_item_seats.rb +0 -5
  243. data/db/migrate/20250619073812_drop_table_cm_vehicle_seats.rb +0 -5
  244. data/db/migrate/20250619073844_drop_table_cm_vehicle_types.rb +0 -9
  245. data/db/migrate/20250619073957_drop_table_cm_option_value_vehicle_types.rb +0 -5
  246. data/db/migrate/20250619082354_remove_unnecessary_fields_from_cm_places.rb +0 -9
  247. data/db/migrate/20250619082736_remove_route_type_from_spree_products.rb +0 -5
  248. data/db/migrate/20250619083055_remove_unnecessary_fields_from_spree_taxons.rb +0 -5
  249. data/db/migrate/20250620083055_remove_variant_id_from_cm_trips.rb +0 -5
  250. data/db/migrate/20250620090000_update_cm_trip_connections_to_use_cm_trips.rb +0 -6
  251. data/db/migrate/20250620090001_create_cm_seat_layouts.rb +0 -17
  252. data/db/migrate/20250620090002_create_cm_seat_sections.rb +0 -18
  253. data/db/migrate/20250620090003_create_cm_blocks.rb +0 -18
  254. data/db/migrate/20250624091005_create_cm_reserved_blocks.rb +0 -29
  255. data/db/migrate/20250626083642_create_cm_variant_blocks.rb +0 -24
  256. data/db/migrate/20250627023314_add_block_id_to_cm_guests.rb +0 -13
  257. data/lib/spree_cm_commissioner/cached_inventory_item.rb +0 -23
  258. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +0 -9
  259. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +0 -9
  260. data/lib/spree_cm_commissioner/test_helper/factories/reserved_block_factory.rb +0 -27
  261. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +0 -8
  262. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +0 -8
  263. data/lib/spree_cm_commissioner/test_helper/factories/trip_connection_factory.rb +0 -6
  264. data/lib/spree_cm_commissioner/test_helper/factories/variant_block_factory.rb +0 -7
  265. data/lib/tasks/create_default_non_permanent_inventory_items.rake +0 -16
  266. data/lib/tasks/ensure_correct_product_type.rake +0 -7
  267. data/lib/tasks/generate_inventory_items.rake +0 -7
@@ -1,26 +1,16 @@
1
- # 🎟️ --- [TICKET CLAIMED] ---
1
+ # 🎫 --- [NEW INVITATION CLAIMED] ---
2
2
  #
3
- # Order Number:
4
- # <code>R621016753</code>
5
- #
6
- # ✅ <b>Ticket Successfully Claimed!</b>
7
- #
8
- # [ x1 ]
9
- # <b>5km Running Ticket</b>
10
- # <i>👉 Distance: 5km, T-shirt: M</i>
11
- # <i>🗓️ Nov 15, 2023</i>
12
- # <i>🏪 Temple Run with Sai</i>
3
+ # <b>🙍 Claimed By</b>
4
+ # Name: Orng SreyMoch
5
+ # Tel: <code>+85570760548</code>
13
6
  #
14
- # [ x2 ]
15
7
  # <b>5km Running Ticket</b>
8
+ # Quantity: 1
16
9
  # <i>👉 Distance: 5km, T-shirt: S</i>
17
10
  # <i>🗓️ Nov 15, 2023 -> Nov 17, 2023</i>
18
- # <i>🏪 Temple Run with Sai</i>
19
11
  #
20
- # <b>🙍 Claimed By</b>
21
- # Name: Vaneath Awesome
22
- # Tel: <code>+85570760548</code>
23
- # Email: <code>admin_dev@cm.com</code>
12
+ # Order Number:
13
+ # <code>R621016753</code>
24
14
 
25
15
  module SpreeCmCommissioner
26
16
  class InviteGuestClaimedTelegramMessageFactory < TelegramMessageFactory
@@ -36,85 +26,38 @@ module SpreeCmCommissioner
36
26
  end
37
27
 
38
28
  def selected_line_items
39
- return order.line_items.for_vendor(vendor) if vendor.present?
40
-
41
- order.line_items
29
+ vendor.present? ? order.line_items.for_vendor(vendor) : order.line_items
42
30
  end
43
31
 
44
32
  # override
45
33
  def body
46
34
  text = []
47
- text << "Order Number:\n<code>#{order.number}</code>\n"
48
- text << "\n✅ <b>Ticket Successfully Claimed!</b>\n"
49
- text << selected_line_items.map { |item| line_item_content(item) }.compact.join("\n\n")
50
- text.compact.join("\n")
51
- end
52
35
 
53
- def line_item_content(line_item)
54
- text = []
36
+ text << bold('🙍 Claimed By')
37
+ text << "Name: #{guest.first_name} #{guest.last_name}"
38
+ text << "Tel: #{inline_code(guest.phone_number)}"
39
+ text << ''
40
+
41
+ # Each invitation_link leads to one order with one line_item, claimed by one guest so quantity is always 1.
42
+ selected_line_items.each do |item|
43
+ text << bold(item.product.name.to_s)
44
+ text << '🎟️ Quantity: 1'
45
+ text << italic("👉 #{item.options_text}") if item.options_text.present?
46
+ text << italic(pretty_date_for(item)) if item.date_present?
47
+ text << ''
48
+ end
55
49
 
56
- text << bold(line_item.product.name.to_s)
57
- text << "Quantity: #{line_item.quantity}"
58
- text << italic("👉 #{line_item.options_text}") if line_item.options_text.present?
59
- text << italic(pretty_date_for(line_item)) if pretty_date_for(line_item).present?
60
- text << italic("🏪 #{line_item.vendor.name}") if line_item.vendor&.name.present? && vendor.blank?
50
+ text << bold('Order Number:')
51
+ text << inline_code(order.number)
61
52
 
62
53
  text.compact.join("\n")
63
54
  end
64
55
 
65
56
  def pretty_date_for(line_item)
66
- return nil unless line_item.date_present?
67
-
68
57
  from_date = pretty_date(line_item.from_date)
69
58
  to_date = pretty_date(line_item.to_date)
70
59
 
71
- if from_date == to_date
72
- "🗓️ #{from_date}"
73
- else
74
- "🗓️ #{from_date} -> #{to_date}"
75
- end
76
- end
77
-
78
- # override
79
- def footer
80
- text = []
81
-
82
- text << bold('🙍 Claimed By')
83
- text << "Name: #{guest.first_name} #{guest.last_name}" if guest.first_name.present? || guest.last_name.present?
84
- text << "Tel: #{inline_code(guest.intel_phone_number)}" if guest.intel_phone_number.present?
85
-
86
- if show_details_link && order.guests.any?
87
- text << ''
88
- text << 'View Tickets:'
89
- text += generate_guests_links(order.guests)
90
- end
91
-
92
- text.compact.join("\n")
93
- end
94
-
95
- # Result:
96
- # | No. A24 | No. A24 |
97
- # | No. A24 | No. A24 |
98
- # | No. A24 | No. A24 |
99
- # | No. A24 | No. A24 |
100
- # | No. A24 | No. A24 |
101
- # | No. A24 |
102
- def generate_guests_links(guests, guests_per_row = 2)
103
- rows = (guests.size.to_f / guests_per_row).ceil
104
- formatted_rows = []
105
-
106
- rows.times do |i|
107
- row_guests = guests.slice(i * guests_per_row, guests_per_row)
108
- formatted_row = row_guests.map do |guest|
109
- button_label = guest.seat_number.present? ? "No. #{guest.seat_number}" : "No. #{guest.formatted_bib_number || 'N/A'}"
110
- link = Rails.application.routes.url_helpers.guest_cards_url(guest.token)
111
- "| <a href='#{link}'>#{button_label}</a>"
112
- end.join(' ')
113
-
114
- formatted_rows << ("#{formatted_row} |")
115
- end
116
-
117
- formatted_rows
60
+ from_date == to_date ? "🗓️ #{from_date}" : "🗓️ #{from_date} -> #{to_date}"
118
61
  end
119
62
  end
120
63
  end
@@ -0,0 +1,20 @@
1
+ module SpreeCmCommissioner
2
+ module LineItems
3
+ module FindByVariantDecorator
4
+ # ovveride
5
+ def execute(order:, variant:, options: {})
6
+ return super unless variant.product.product_type == 'transit'
7
+
8
+ order.line_items.detect do |line_item|
9
+ next if options[:date].present? && !(line_item.variant_id == variant.id && line_item.date == options[:date])
10
+
11
+ Spree::Dependencies.cart_compare_line_items_service.constantize.call(order: order, line_item: line_item, options: options).value
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ unless Spree::LineItems::FindByVariant.included_modules.include?(SpreeCmCommissioner::LineItems::FindByVariantDecorator)
19
+ Spree::LineItems::FindByVariant.prepend(SpreeCmCommissioner::LineItems::FindByVariantDecorator)
20
+ end
@@ -0,0 +1,27 @@
1
+ module SpreeCmCommissioner
2
+ class AppleAppSiteAssociationFetcher < BaseInteractor
3
+ delegate :store, :tenant, :refreshed, to: :context
4
+
5
+ def call
6
+ key = cache_key
7
+
8
+ CmAppLogger.log(label: 'LOOKING_UP_CACHE', data: { cache_key: key })
9
+
10
+ Rails.cache.delete(key) if refreshed
11
+
12
+ context.contents = Rails.cache.fetch(key) do
13
+ CmAppLogger.log(label: 'CACHE_MISS', data: { cache_key: key })
14
+ resource.preferred_apple_app_site_association
15
+ end
16
+ end
17
+
18
+ def cache_key
19
+ updated_at = tenant&.updated_at || store&.updated_at
20
+ "well_known:apple-app-site-association:#{resource.class.name}:#{resource.id}:#{updated_at}"
21
+ end
22
+
23
+ def resource
24
+ tenant || store
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ module SpreeCmCommissioner
2
+ class AssetLinksFetcher < BaseInteractor
3
+ delegate :store, :tenant, :refreshed, to: :context
4
+
5
+ def call
6
+ key = cache_key
7
+
8
+ CmAppLogger.log(label: 'LOOKING_UP_CACHE', data: { cache_key: key })
9
+
10
+ Rails.cache.delete(key) if refreshed
11
+
12
+ context.contents = Rails.cache.fetch(key) do
13
+ CmAppLogger.log(label: 'CACHE_MISS', data: { cache_key: key })
14
+ resource.preferred_assetlinks
15
+ end
16
+ end
17
+
18
+ def cache_key
19
+ updated_at = tenant&.updated_at || store&.updated_at
20
+ "well_known:assetlinks.json:#{resource.class.name}:#{resource.id}:#{updated_at}"
21
+ end
22
+
23
+ def resource
24
+ tenant || store
25
+ end
26
+ end
27
+ end
@@ -9,7 +9,8 @@ module SpreeCmCommissioner
9
9
  set_option_value
10
10
  create_variant
11
11
  create_stock_item
12
- upload_image
12
+ upload_image_to(@ticket.master)
13
+ upload_image_to(@variant)
13
14
  create_place
14
15
  end
15
16
  end
@@ -77,13 +78,13 @@ module SpreeCmCommissioner
77
78
  context.fail!(message: @stock_item.errors.full_messages.join(', '))
78
79
  end
79
80
 
80
- def upload_image
81
+ def upload_image_to(target)
81
82
  return if context.params[:ticket_image].blank?
82
83
 
83
- @image = @ticket.master.images.new(attachment: context.params[:ticket_image])
84
- return if @image.save
84
+ image = target.images.new(attachment: context.params[:ticket_image])
85
+ return if image.save
85
86
 
86
- context.fail!(message: @image.errors.full_messages.join(', '))
87
+ context.fail!(message: image.errors.full_messages.join(', '))
87
88
  end
88
89
 
89
90
  def create_place
@@ -0,0 +1,44 @@
1
+ module SpreeCmCommissioner
2
+ class CreateVendor
3
+ include Interactor
4
+
5
+ def call
6
+ validate_context!
7
+
8
+ ActiveRecord::Base.transaction do
9
+ create_vendor
10
+ assign_vendor_to_user
11
+ create_role
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def validate_context!
18
+ context.fail!(message: 'User is missing') unless context.user
19
+ context.fail!(message: 'Vendor parameters are missing') unless context.vendor_params
20
+ end
21
+
22
+ def create_vendor
23
+ @vendor = Spree::Vendor.new(context.vendor_params)
24
+ return if @vendor.save
25
+
26
+ context.fail!(message: @vendor.errors.full_messages.join(', '))
27
+ end
28
+
29
+ def assign_vendor_to_user
30
+ context.user.vendors << @vendor
31
+ end
32
+
33
+ def create_role
34
+ role = context.user.spree_roles.create(
35
+ name: "#{@vendor.name.downcase.parameterize(separator: '-')}-organizer",
36
+ vendor_id: @vendor.id,
37
+ presentation: 'Organizer'
38
+ )
39
+ return if role.persisted?
40
+
41
+ context.fail!(message: role.errors.full_messages.to_sentence)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ module SpreeCmCommissioner
2
+ class CrewInviteLinkHandler < BaseInteractor
3
+ delegate :params, to: :context
4
+
5
+ def call
6
+ validate_data
7
+ assign_role_to_user
8
+ create_user_event
9
+ end
10
+
11
+ private
12
+
13
+ def validate_data
14
+ if invite.nil?
15
+ context.fail!(message: I18n.t('invite.url_not_found'))
16
+ else
17
+ context.invite = invite
18
+ end
19
+ end
20
+
21
+ def assign_role_to_user
22
+ return if user.operator?
23
+
24
+ role = Spree::Role.find_by(name: 'operator')
25
+ role_user = Spree::RoleUser.new(user_id: user.id, role_id: role.id)
26
+ role_user.save
27
+ end
28
+
29
+ def create_user_event
30
+ @user_event = SpreeCmCommissioner::UserEvent.new(
31
+ taxon_id: invite.taxon_id,
32
+ user_id: user.id
33
+ )
34
+
35
+ return if @user_event.save
36
+
37
+ context.fail!(message: I18n.t('invite.already_invited'))
38
+ end
39
+
40
+ def invite
41
+ @invite ||= SpreeCmCommissioner::Invite.find_by(token: params[:id])
42
+ end
43
+
44
+ def user
45
+ @user ||= Spree::User.find(params[:user_id])
46
+ end
47
+ end
48
+ end
@@ -18,7 +18,6 @@ module SpreeCmCommissioner
18
18
 
19
19
  def send_sms
20
20
  options = {
21
- from: sender_name(context.tenant),
22
21
  to: context.pin_code.contact,
23
22
  body: I18n.t('pincode_sender.sms.body', code: context.pin_code.code, readable_type: context.pin_code.readable_type)
24
23
  }
@@ -42,7 +42,7 @@ module SpreeCmCommissioner
42
42
  end
43
43
 
44
44
  def sms_options
45
- opts = { from: context.from, to: context.to, body: context.body }
45
+ opts = { to: context.to, body: context.body }
46
46
  opts[:to] = sanitize(opts[:to]) if opts[:to].present?
47
47
  opts[:from] = from_number
48
48
  opts
@@ -0,0 +1,144 @@
1
+ module SpreeCmCommissioner
2
+ class TelegramChatsAutoFinder < BaseInteractor
3
+ delegate :contact, :pin_code, to: :context
4
+
5
+ def call
6
+ context.chats = []
7
+ context.verified_chat_ids = []
8
+
9
+ updates = fetch_updates
10
+
11
+ if updates['result'].any?
12
+ updates['result'].sort_by { |u| u['update_id'] }.reverse.each do |update|
13
+ handle_message_update(update) if update['message']
14
+ handle_channel_post_update(update) if update['channel_post']
15
+ handle_chat_member_update(update) if update['my_chat_member']
16
+ end
17
+ end
18
+ context.fail!(message: 'No pin codes verified') if context.verified_chat_ids.empty?
19
+ end
20
+
21
+ private
22
+
23
+ def handle_chat_member_update(update)
24
+ chat = update.dig('my_chat_member', 'chat')
25
+ return unless chat
26
+
27
+ chat_data = {
28
+ id: chat['id'],
29
+ title: chat['title'] || 'Unnamed Chat',
30
+ type: chat['type']
31
+ }
32
+
33
+ return if context.chats.any? { |c| c[:id] == chat_data[:id] }
34
+
35
+ db_chat = SpreeCmCommissioner::TelegramChat.find_or_initialize_by(chat_id: chat_data[:id])
36
+ is_new_chat = db_chat.new_record?
37
+ db_chat.update(chat_title: chat_data[:title], chat_type: chat_data[:type])
38
+ context.chats << chat_data
39
+ message = "👋Hello! This is Bookme+ bot.\n\nPlease enter the 6-digit PIN code displayed in your portal."
40
+ send_message(chat_data[:id], message) if is_new_chat
41
+ end
42
+
43
+ def handle_channel_post_update(update)
44
+ message = update['channel_post']
45
+ process_pin_code_message(message)
46
+ end
47
+
48
+ def handle_message_update(update)
49
+ message = update['message']
50
+ process_pin_code_message(message)
51
+ end
52
+
53
+ def process_pin_code_message(message)
54
+ chat_id = message.dig('chat', 'id')
55
+ text = message['text']&.strip
56
+
57
+ return unless valid_pin_code?(text, chat_id)
58
+
59
+ pin_code_record = find_pin_code_record
60
+ return unless pin_code_record
61
+
62
+ vendor = find_vendor
63
+ return unless vendor
64
+
65
+ chat = update_telegram_chat(message, chat_id)
66
+ return unless chat
67
+
68
+ handle_successful_verification(chat, vendor, pin_code_record)
69
+ end
70
+
71
+ def valid_pin_code?(text, chat_id)
72
+ text && chat_id && text == pin_code
73
+ end
74
+
75
+ def find_pin_code_record
76
+ pin_code_record = SpreeCmCommissioner::PinCodeTelegram.find_by(code: pin_code, contact: contact)
77
+ unless pin_code_record
78
+ context.fail!(message: "Pin code #{pin_code} not found for contact #{contact}")
79
+ return nil
80
+ end
81
+ pin_code_record
82
+ end
83
+
84
+ def find_vendor
85
+ vendor = Spree::Vendor.find_by(id: contact)
86
+ unless vendor
87
+ context.fail!(message: "Vendor not found for contact #{contact}")
88
+ return nil
89
+ end
90
+ vendor
91
+ end
92
+
93
+ def update_telegram_chat(message, chat_id)
94
+ chat = SpreeCmCommissioner::TelegramChat.find_or_initialize_by(chat_id: chat_id)
95
+ unless chat.update(
96
+ chat_title: message.dig('chat', 'title') || 'Unnamed Chat',
97
+ chat_type: message.dig('chat', 'type')
98
+ )
99
+ context.fail!(message: "Failed to update chat: #{chat.errors.full_messages.join(', ')}")
100
+ return nil
101
+ end
102
+
103
+ context.chats << { id: chat.chat_id, title: chat.chat_title, type: chat.chat_type }
104
+ chat
105
+ end
106
+
107
+ def handle_successful_verification(chat, vendor, pin_code_record)
108
+ return if chat.vendor && chat.vendor != vendor
109
+
110
+ update_vendor_preferences(vendor, chat)
111
+ chat.update(active: true, vendor: vendor)
112
+ expire_pin_code(pin_code_record)
113
+ send_success_message(chat.chat_id, vendor.name)
114
+ context.verified_chat_ids << chat.chat_id
115
+ end
116
+
117
+ def update_vendor_preferences(vendor, chat)
118
+ vendor.update(
119
+ preferred_telegram_chat_id: chat.chat_id,
120
+ preferred_telegram_chat_name: chat.chat_title,
121
+ preferred_telegram_chat_type: chat.chat_type
122
+ )
123
+ end
124
+
125
+ def expire_pin_code(pin_code_record)
126
+ pin_code_record.expire
127
+ pin_code_record.save
128
+ end
129
+
130
+ def send_success_message(chat_id, vendor_name)
131
+ message = "✅ PIN code verified successfully! This chat is now connected to <b>#{vendor_name}</b>.\n\n" \
132
+ 'All completed orders will be sent to this chat.'
133
+ send_message(chat_id, message)
134
+ end
135
+
136
+ def fetch_updates
137
+ ::Telegram.bot.get_updates
138
+ end
139
+
140
+ def send_message(chat_id, text)
141
+ ::Telegram.bot.send_message(chat_id: chat_id, text: text, parse_mode: 'HTML')
142
+ end
143
+ end
144
+ end
@@ -1,6 +1,6 @@
1
1
  module SpreeCmCommissioner
2
2
  class UserIdTokenAuthenticator < BaseInteractor
3
- # :id_token
3
+ # :id_token, :tenant_id (optional)
4
4
  def call
5
5
  context.user = if checker.user.nil?
6
6
  register_user
@@ -14,7 +14,11 @@ module SpreeCmCommissioner
14
14
  end
15
15
 
16
16
  def register_user
17
- register_context = SpreeCmCommissioner::UserRegistrationWithIdToken.call(id_token: context.id_token)
17
+ register_context = SpreeCmCommissioner::UserRegistrationWithIdToken.call(
18
+ id_token: context.id_token,
19
+ tenant_id: context.tenant_id
20
+ )
21
+
18
22
  register_context.user
19
23
  end
20
24
 
@@ -27,7 +31,7 @@ module SpreeCmCommissioner
27
31
  end
28
32
 
29
33
  def checker
30
- @checker ||= SpreeCmCommissioner::UserIdTokenChecker.call(id_token: context.id_token)
34
+ @checker ||= SpreeCmCommissioner::UserIdTokenChecker.call(id_token: context.id_token, tenant_id: context.tenant_id)
31
35
  @checker
32
36
  end
33
37
  end
@@ -1,6 +1,9 @@
1
1
  module SpreeCmCommissioner
2
2
  class UserIdTokenChecker < BaseInteractor
3
- # :id_token
3
+ # expects:
4
+ # context.id_token
5
+ # context.tenant_id (optional)
6
+
4
7
  def call
5
8
  firebase_id_token_context = SpreeCmCommissioner::FirebaseIdTokenProvider.call(id_token: context.id_token)
6
9
 
@@ -11,9 +14,14 @@ module SpreeCmCommissioner
11
14
  end
12
15
  end
13
16
 
14
- # :identity_type, :sub
17
+ # :identity_type, :sub, :tenant_id
15
18
  def validate_user_by_provider(provider)
16
- identity_checker = SpreeCmCommissioner::UserIdentityChecker.call(provider)
19
+ identity_checker = SpreeCmCommissioner::UserIdentityChecker.call(
20
+ identity_type: provider[:identity_type],
21
+ sub: provider[:sub],
22
+ tenant_id: context.tenant_id
23
+ )
24
+
17
25
  if identity_checker.success?
18
26
  context.user = identity_checker.user
19
27
  else
@@ -1,6 +1,10 @@
1
1
  module SpreeCmCommissioner
2
2
  class UserIdentityChecker < BaseInteractor
3
- # :identity_type, :sub
3
+ # expects:
4
+ # context.identity_type
5
+ # context.sub
6
+ # context.tenant_id (optional)
7
+
4
8
  def call
5
9
  load_user
6
10
 
@@ -11,12 +15,14 @@ module SpreeCmCommissioner
11
15
  end
12
16
 
13
17
  def load_user
14
- user_identity_provider = UserIdentityProvider.where(
15
- identity_type: context.identity_type,
16
- sub: context.sub
17
- ).first
18
+ return if context.sub.blank? || context.identity_type.blank?
19
+
20
+ user_identity_provider = UserIdentityProvider.joins(:user)
21
+ .where(identity_type: context.identity_type, sub: context.sub)
22
+ .where(spree_users: { tenant_id: context.tenant_id })
23
+ .first
18
24
 
19
- context.user = (user_identity_provider.user if user_identity_provider.present?)
25
+ context.user = user_identity_provider&.user
20
26
  end
21
27
  end
22
28
  end
@@ -15,7 +15,13 @@ module SpreeCmCommissioner
15
15
  end
16
16
 
17
17
  def register_user!(name, email)
18
- user = Spree.user_class.new(password: SecureRandom.base64(16), email: email, **name_attributes(name))
18
+ user = Spree.user_class.new(
19
+ password: SecureRandom.base64(16),
20
+ email: email,
21
+ tenant_id: context.tenant_id,
22
+ **name_attributes(name)
23
+ )
24
+
19
25
  if user.save(validate: false)
20
26
  context.user = user
21
27
  else
@@ -93,6 +93,10 @@ module SpreeCmCommissioner
93
93
  context.fail!(message: "User creation failed: #{context.user.errors.full_messages.join(', ')}")
94
94
  end
95
95
 
96
+ def disable_services
97
+ 'bus,ferry'
98
+ end
99
+
96
100
  def construct_data
97
101
  user = context.user
98
102
 
@@ -101,7 +105,7 @@ module SpreeCmCommissioner
101
105
  name: user.full_name,
102
106
  phone: user.phone_number,
103
107
  email: user.email,
104
- webUrl: "#{Spree::Store.default.formatted_url}/vattanac_bank_web_app?session_id=#{session_id}"
108
+ webUrl: "#{Spree::Store.default.formatted_url}/vattanac_bank_web_app?session_id=#{session_id}&ds=#{CGI.escape(disable_services)}"
105
109
  }
106
110
 
107
111
  json_data = raw_data.to_json
@@ -1,25 +1,5 @@
1
1
  module SpreeCmCommissioner
2
2
  class ApplicationJob < ::ApplicationJob
3
3
  queue_as :default
4
-
5
- around_perform :log_exceptions
6
-
7
- private
8
-
9
- def log_exceptions
10
- yield
11
- rescue StandardError => e
12
- CmAppLogger.log(
13
- label: "#{self.class.name} failed",
14
- data: {
15
- error_class: e.class.name,
16
- error_message: e.message,
17
- arguments: arguments.inspect,
18
- backtrace: e.backtrace&.first(5)&.join("\n")
19
- }
20
- )
21
-
22
- raise # Re-raise the exception to let Sidekiq handle retries or failure
23
- end
24
4
  end
25
5
  end
@@ -2,25 +2,5 @@
2
2
  module SpreeCmCommissioner
3
3
  class ApplicationUniqueJob < ::ApplicationUniqueJob
4
4
  queue_as :default
5
-
6
- around_perform :log_exceptions
7
-
8
- private
9
-
10
- def log_exceptions
11
- yield
12
- rescue StandardError => e
13
- CmAppLogger.log(
14
- label: "#{self.class.name} failed",
15
- data: {
16
- error_class: e.class.name,
17
- error_message: e.message,
18
- arguments: arguments.inspect,
19
- backtrace: e.backtrace&.first(5)&.join("\n")
20
- }
21
- )
22
-
23
- raise # Re-raise the exception to let Sidekiq handle retries or failure
24
- end
25
5
  end
26
6
  end