spree_cm_commissioner 2.0.0.pre.pre → 2.0.1.pre.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +3 -0
  3. data/Gemfile.lock +1 -1
  4. data/app/assets/images/cm-hangmeas-checkout_image.svg +63 -0
  5. data/app/assets/images/cm-hangmeas-failed.svg +56 -0
  6. data/app/assets/images/cm-hangmeas-loader.svg +50 -0
  7. data/app/assets/images/cm-hangmeas-success.svg +51 -0
  8. data/app/assets/javascripts/spree_cm_commissioner/backend.js +1 -0
  9. data/app/assets/javascripts/spree_cm_commissioner/tenant_payment_icon_fields.js +65 -0
  10. data/app/assets/stylesheets/spree_cm_commissioner/backend/commissioner_admin.css.scss +1 -0
  11. data/app/assets/stylesheets/spree_cm_commissioner/backend/tenant_payment_icon_fields.scss +60 -0
  12. data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +2 -1
  13. data/app/controllers/spree/admin/event_blazer_queries_controller.rb +11 -4
  14. data/app/controllers/spree/admin/tenants_controller.rb +8 -0
  15. data/app/controllers/spree/admin/trip_blazer_queries_controller.rb +35 -0
  16. data/app/controllers/spree/api/v2/organizer/invite_crews_controller.rb +33 -0
  17. data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +5 -1
  18. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +31 -5
  19. data/app/controllers/spree/api/v2/tenant/checkout_controller.rb +2 -0
  20. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +1 -1
  21. data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +11 -0
  22. data/app/controllers/spree_cm_commissioner/well_known_controller.rb +31 -17
  23. data/app/interactors/spree_cm_commissioner/apple_app_site_association_fetcher.rb +27 -0
  24. data/app/interactors/spree_cm_commissioner/asset_links_fetcher.rb +27 -0
  25. data/app/interactors/spree_cm_commissioner/crew_invite_link_handler.rb +48 -0
  26. data/app/interactors/spree_cm_commissioner/telegram_chats_auto_finder.rb +144 -0
  27. data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +5 -1
  28. data/app/models/concerns/spree_cm_commissioner/event_check_in_flowable.rb +30 -0
  29. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +2 -1
  30. data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +4 -0
  31. data/app/models/spree_cm_commissioner/blazer_queryable.rb +8 -0
  32. data/app/models/spree_cm_commissioner/crew_invite_link.rb +4 -0
  33. data/app/models/spree_cm_commissioner/dynamic_field.rb +17 -3
  34. data/app/models/spree_cm_commissioner/dynamic_field_option.rb +7 -1
  35. data/app/models/spree_cm_commissioner/guest.rb +1 -1
  36. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +21 -3
  37. data/app/models/spree_cm_commissioner/invite.rb +4 -6
  38. data/app/models/spree_cm_commissioner/invite_team.rb +3 -1
  39. data/app/models/spree_cm_commissioner/pin_code.rb +3 -2
  40. data/app/models/spree_cm_commissioner/pin_code_telegram.rb +28 -0
  41. data/app/models/spree_cm_commissioner/place.rb +0 -1
  42. data/app/models/spree_cm_commissioner/product_decorator.rb +0 -2
  43. data/app/models/spree_cm_commissioner/promotion_category_decorator.rb +11 -0
  44. data/app/models/spree_cm_commissioner/taxon_decorator.rb +5 -2
  45. data/app/models/spree_cm_commissioner/telegram_chat.rb +6 -0
  46. data/app/models/spree_cm_commissioner/trip.rb +9 -13
  47. data/app/models/spree_cm_commissioner/trip_stop.rb +5 -23
  48. data/app/models/spree_cm_commissioner/user_taxon.rb +1 -0
  49. data/app/models/spree_cm_commissioner/variant_decorator.rb +1 -0
  50. data/app/models/spree_cm_commissioner/vendor_decorator.rb +9 -9
  51. data/app/models/spree_cm_commissioner/vendor_place.rb +8 -3
  52. data/app/overrides/spree/admin/taxons/_form/check_in_flows.html.erb.deface +18 -0
  53. data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +2 -2
  54. data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +45 -3
  55. data/app/queries/spree_cm_commissioner/trip_query.rb +56 -27
  56. data/app/serializers/spree/v2/organizer/invite_crews_serializer.rb +11 -0
  57. data/app/serializers/spree_cm_commissioner/v2/operator/dashboard_crew_event_serializer.rb +4 -1
  58. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +1 -3
  59. data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -3
  60. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +2 -1
  61. data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +23 -15
  62. data/app/views/blazer/queries/_content.html.erb +8 -0
  63. data/app/views/spree/admin/tenants/_form.html.erb +109 -42
  64. data/config/initializers/spree_permitted_attributes.rb +2 -0
  65. data/config/locales/en.yml +5 -0
  66. data/config/routes.rb +4 -1
  67. data/db/migrate/20250616084219_add_description_to_cm_vendor_place.rb +5 -0
  68. data/db/migrate/20250630103536_create_cm_telegram_chats.rb +13 -0
  69. data/db/migrate/20250701093203_add_configurations_to_cm_dynamic_field.rb +6 -0
  70. data/db/migrate/20250702091305_add_dynamic_field_option_to_guest_dynamic_field.rb +5 -0
  71. data/db/migrate/20250702091935_add_status_to_dynamic_field_option.rb +5 -0
  72. data/db/migrate/20250707032008_add_vendor_id_to_spree_category.rb +7 -0
  73. data/db/migrate/20250711092937_add_position_to_cm_dynamic_fields.rb +11 -0
  74. data/db/migrate/20250711093045_add_position_to_cm_dynamic_field_options.rb +11 -0
  75. data/db/migrate/20250714121508_rename_cm_taxon_blazer_query_to_blazer_queryables.rb +7 -0
  76. data/db/migrate/20250714124323_make_cm_blazer_queryables_polymorphic.rb +19 -0
  77. data/db/migrate/20250716022821_add_location_reference_to_cm_vendor_places.rb +5 -0
  78. data/db/migrate/20250716031743_drop_table_cm_vendor_stops.rb +5 -0
  79. data/db/migrate/20250717023824_add_vendor_reference_to_cm_trips.rb +5 -0
  80. data/db/migrate/20250717041414_add_location_place_reference_to_cm_trip_stops.rb +5 -0
  81. data/db/migrate/20250717042539_rename_cm_trip_stops_stop_id_column_to_stop_place_id.rb +7 -0
  82. data/db/migrate/20250717042707_rename_cm_trips_origin_and_destination_to_origin_place_and_destination_place.rb +11 -0
  83. data/lib/spree_cm_commissioner/test_helper/factories/block_factory.rb +9 -3
  84. data/lib/spree_cm_commissioner/test_helper/factories/seat_layout_factory.rb +6 -3
  85. data/lib/spree_cm_commissioner/test_helper/factories/seat_section_factory.rb +11 -3
  86. data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +3 -2
  87. data/lib/spree_cm_commissioner/test_helper/factories/trip_stop_factory.rb +10 -0
  88. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +5 -0
  89. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +13 -1
  90. data/lib/spree_cm_commissioner/trip_query_result.rb +8 -0
  91. data/lib/spree_cm_commissioner/trip_result.rb +5 -3
  92. data/lib/spree_cm_commissioner/version.rb +1 -1
  93. metadata +39 -5
  94. data/app/models/spree_cm_commissioner/taxon_blazer_query.rb +0 -8
  95. data/app/models/spree_cm_commissioner/vendor_stop.rb +0 -9
  96. data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +0 -54
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c84700dfc0c91553426b4c3957ab2e2906f4327f9b968efe1d88ce590d69a63
4
- data.tar.gz: c98479e1dd2ff5f4def2b7799ff2ffc894812dd737e52a6e2488839318ca514b
3
+ metadata.gz: 8df566cd09596e4c650becdc82fc0811b70d88212de9360a167657dee601e86a
4
+ data.tar.gz: 4f1e946fba7f81c360e83ea7a711c8732bb85e7c9e9d3119fc7fd90149a71467
5
5
  SHA512:
6
- metadata.gz: ddc75d3e7e17ad18de9c620336c8233191f268bd2c18911455b6169f4a6a379b2d8d537e1a7cc6c2d8f280842772b787d19d3215263cf3a6856309f263712512
7
- data.tar.gz: 551e01c90befa48ad8fa44adc40e9be2af4bda32319f05e562d66d099a0d729477f9ade32aee9c9256728481756e35ccec863782d033962756daba9720e868e8
6
+ metadata.gz: f4b42ff8956579cd7b32be8d151089f0b9e5ba52df63de5064425d281952c39eef3162d790492d9c1b199f05dea62a22cd056165cd0081b1ca81893e883eb54b
7
+ data.tar.gz: eda744ec6cba88fbac6ad868bfcf1d4f1ddb7d66fce896e701808f68d51222c5988fe6987ccba58fa0d0ff723631dfb0b48cb0cad2e6751a8a7cab1ad340ed4b
data/.env.example CHANGED
@@ -24,3 +24,6 @@ WAITING_ROOM_DISABLED=no
24
24
  # Vattanac Bank
25
25
  VATTANAC_AES_SECRET_KEY= ""
26
26
  VATTANAC_PUBLIC_KEY=""
27
+
28
+ # Organizer URL
29
+ ORGANIZER_URL=http://127.0.0.1:4000/organizer
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (2.0.0.pre.pre)
37
+ spree_cm_commissioner (2.0.1.pre.pre)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -0,0 +1,63 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="payment_proccessing" data-name="payment proccessing" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 334 200">
3
+ <defs>
4
+ <clipPath id="clippath">
5
+ <path d="m332.72,16.62v166.75c0,8.27-6.28,15.08-14.33,15.92-.55.05-1.11.08-1.67.08H16c-.48,0-.96-.02-1.43-.06-8.17-.73-14.57-7.59-14.57-15.94V16.62C0,7.78,7.16.62,16,.62h300.72c8.84,0,16,7.16,16,16Z" style="fill: none;"/>
6
+ </clipPath>
7
+ </defs>
8
+ <g style="clip-path: url(#clippath);">
9
+ <path d="m332.72,16.62v166.75c0,8.27-6.28,15.08-14.33,15.92-.55.05-1.11.08-1.67.08H16c-.48,0-.96-.02-1.43-.06-8.17-.73-14.57-7.59-14.57-15.94V16.62C0,7.78,7.16.62,16,.62h300.72c8.84,0,16,7.16,16,16Z" style="fill: #130d07;"/>
10
+ <path d="m160.11,89.69c1.41-5.81-3.61-9.74-10.21-9.27-6.6.47-26.31,10.68-28.51,12.26-2.2,1.57-29.54,6.6-34.25,3.77-4.71-2.83-12.46-7.49-12.46-7.49,0,0-23.81-23.81-40.47,2.86-16.67,26.66-13.99,61.42-13.99,61.42l-24.1,29.05s-10.95,10,3.81,19.05,22.11,18.14,31.15,21.3c9.04,3.16,14.46-7,14.46-7.68,0-.68,19.43-30.27,19.43-30.27,10.27-.69,20.53-1.41,30.79-2.17,10.81-.8,24.65.44,31.99-9.08,3.2-4.15,1.59-8.37-.02-12.85.06.18,3.68-1,4-1.13,1.81-.72,3.12-1.91,3.94-3.7,1.55-3.36,2.03-8.12.07-11.41-2.91-4.88-3.85-5.31-3.85-5.31.93.42,4.7-2.76,5.32-3.27,2.69-2.21,4.81-5.03,5.27-8.57,1.31-10.16-10.01-17.26-18.56-19.27,5.59,1.31,10.8,2.15,16.21-.39,3.01-1.41,5.69-3.43,8.35-5.44,4.02-3.03,10.38-7.18,11.65-12.41" style="fill: #e89875;"/>
11
+ <path d="m138.73,45.68c-1.83-.91-5.84-1.99-7.86-2.27-3.17-.44-12.78-.68-12.78-.68l-1.24,3.76-31.45-1.3c-4.73-.2-8.98,2.88-10.27,7.44l-27.87,101.59c-1.74,6.14,2.5,12.35,8.85,12.97l49.44,1.78c4.98.49,9.59-2.69,10.89-7.53l27.25-101.35c.17-.64.26-1.28.31-1.92,0-.02.01-.05.02-.07,1.59-7.52-1.35-10.47-5.29-12.43Z" style="fill: #302b31;"/>
12
+ <path d="m51.51,163.26l49.44,1.78c4.98.49,9.59-2.69,10.89-7.53l27.25-101.35c1.7-6.33-2.91-12.61-9.46-12.88l-48.82-2.02c-4.73-.2-8.98,2.88-10.27,7.44l-27.87,101.59c-1.74,6.14,2.5,12.35,8.85,12.97Z" style="fill: #212028;"/>
13
+ <path d="m108.45,126.85c-1.64.07-3.43-.23-5.08-.3-4.13-.18-8.26-.36-12.39-.54l-22.43-.98-.81-.04c-2.87-.41-4.61-1.99-3.7-4.96l.84-3.54c.55-2.49,2.89-4.15,5.42-3.86,13.54.41,27.15.41,40.66,1.23,2,.12,4.17.45,4.34,2.96.15,2.13-1.09,4.94-1.91,6.87-1.02,2.41-2.87,3.07-4.95,3.16Z" style="fill: #f59b1d;"/>
14
+ <path d="m117.78,96.1l-48.7-1.94c-2.03-.08-3.25-1.77-2.74-3.76l8.36-32.34c.52-2,2.58-3.55,4.61-3.47l48.7,1.94c2.03.08,3.25,1.77,2.74,3.76l-8.36,32.34c-.52,2-2.58,3.55-4.61,3.47Z" style="fill: #fffaf8;"/>
15
+ <path d="m85.83,77.72l-8.87-.35c-.88-.04-1.41-.77-1.19-1.63l1.23-4.78c.22-.87,1.12-1.54,2-1.51l8.87.35c.88.04,1.41.77,1.19,1.63l-1.23,4.78c-.22.87-1.12,1.54-2,1.51Z" style="fill: #d6d6d6;"/>
16
+ <path d="m124.55,64.16l-9.8-.39c-.62-.02-1-.54-.84-1.15l.45-1.74c.16-.61.79-1.09,1.41-1.06l9.8.39c.62.02,1,.54.84,1.15l-.45,1.74c-.16.61-.79,1.09-1.41,1.06Z" style="fill: #d6d6d6;"/>
17
+ <path d="m84.05,81.98l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
18
+ <path d="m99.83,91.71l-27.44-1.09c-.25-.01-.41-.22-.34-.47l.42-1.62c.06-.25.32-.44.57-.43l27.44,1.09c.25.01.41.22.34.47l-.42,1.62c-.06.25-.32.44-.57.43Z" style="fill: #d6d6d6;"/>
19
+ <path d="m95.54,82.43l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
20
+ <path d="m107.03,82.89l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
21
+ <path d="m118.52,83.35l-8.95-.36c-.47-.02-.75-.41-.63-.87l.22-.86c.12-.46.59-.82,1.06-.8l8.95.36c.47.02.75.41.63.87l-.22.86c-.12.46-.59.82-1.06.8Z" style="fill: #d6d6d6;"/>
22
+ <path d="m111.65,93.7c-.49.15-.94.45-1.44.61-2.03.64-4.12-.62-4.15-2.53-.02-1.28.45-2.44,1.6-3.42.84-.72,1.78-1.08,2.78-1.14.88-.05,1.65.12,2.24.65.12.11.29.16.44.24-.17.19.02.23.08.32.37.57.57,1.21.45,1.96-.2,1.22-.73,2.32-1.89,3.17-.05.03-.08.09-.11.14Z" style="fill: #d6d6d6;"/>
23
+ <path d="m111.65,93.7s.07-.11.11-.14c1.16-.85,1.69-1.95,1.89-3.17.12-.75-.08-1.39-.45-1.96-.06-.09-.25-.14-.08-.32.59-.27,1.16-.59,1.79-.67,2.25-.26,3.6.86,3.66,2.68.06,1.96-1.32,3.73-3.42,4.37-1.29.39-2.36.14-3.23-.58-.09-.07-.18-.15-.26-.22Z" style="fill: #5e5e5e;"/>
24
+ <path d="m53.69,110.12s1.51-5.75,5.56,2.51c4.05,8.27,15.38,11.23,20.41,6.86s-.79-23.41-15.54-36.21c-14.75-12.8-30.48,5.41-37.12,19.9-6.65,14.49-6.78,50.07-6.78,50.07l48.9,21.12s8.3-15.25.02-34.98c-4.68-11.15-9.08-16.86-12.8-21.88-3.73-5.02-2.64-7.37-2.64-7.37Z" style="fill: #e89875;"/>
25
+ <g>
26
+ <rect x="222.73" y="98.72" width="8.27" height="27.35" style="fill: #fbc01a;"/>
27
+ <polygon points="231 100.13 222.73 100.13 221.53 95.4 232.39 95.4 231 100.13" style="fill: #fbc01a;"/>
28
+ <line x1="223.67" y1="100.13" x2="231" y2="100.13" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
29
+ <polygon points="222.73 126.08 231 126.08 232.2 130.8 221.33 130.8 222.73 126.08" style="fill: #fbc01a;"/>
30
+ <line x1="231" y1="126.08" x2="222.73" y2="126.08" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
31
+ </g>
32
+ <g>
33
+ <rect x="240.34" y="98.72" width="8.27" height="27.35" style="fill: #f4b200;"/>
34
+ <polygon points="248.61 100.13 240.34 100.13 239.15 95.4 250.01 95.4 248.61 100.13" style="fill: #f4b200;"/>
35
+ <polygon points="240.35 126.08 248.62 126.08 249.81 130.8 238.95 130.8 240.35 126.08" style="fill: #f4b200;"/>
36
+ </g>
37
+ <g>
38
+ <rect x="257.95" y="98.72" width="8.27" height="27.35" style="fill: #fbc01a;"/>
39
+ <polygon points="266.22 100.13 257.95 100.13 256.76 95.4 267.62 95.4 266.22 100.13" style="fill: #fbc01a;"/>
40
+ <line x1="258.9" y1="100.13" x2="266.22" y2="100.13" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
41
+ <polygon points="257.96 126.08 266.23 126.08 267.42 130.8 256.56 130.8 257.96 126.08" style="fill: #fbc01a;"/>
42
+ <line x1="266.22" y1="126.08" x2="257.96" y2="126.08" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
43
+ </g>
44
+ <g>
45
+ <rect x="275.56" y="98.72" width="8.27" height="27.35" style="fill: #fbc01a;"/>
46
+ <polygon points="283.84 100.13 275.56 100.13 274.37 95.4 285.23 95.4 283.84 100.13" style="fill: #fbc01a;"/>
47
+ <line x1="276.51" y1="100.13" x2="283.84" y2="100.13" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
48
+ <polygon points="275.57 126.08 283.84 126.08 285.04 130.8 274.17 130.8 275.57 126.08" style="fill: #fbc01a;"/>
49
+ <line x1="283.84" y1="126.08" x2="275.57" y2="126.08" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
50
+ </g>
51
+ <rect x="218.79" y="91.42" width="69.46" height="3.98" style="fill: #f9b500;"/>
52
+ <rect x="218.79" y="130.8" width="69.46" height="3.98" style="fill: #fbc01a;"/>
53
+ <rect x="209.25" y="134.79" width="88.53" height="4.09" style="fill: #f4b200;"/>
54
+ <path d="m216.67,88.29l34.23-15.08c2.1-.93,4.5-.93,6.6,0l34.23,15.08c1.62.71,1.11,3.13-.66,3.13h-73.75c-1.77,0-2.28-2.42-.66-3.13Z" style="fill: #fbc01a;"/>
55
+ <path d="m230.81,86.16l21.33-9.4c1.31-.58,2.8-.58,4.11,0l21.33,9.4c1.01.44.69,1.95-.41,1.95h-45.96c-1.1,0-1.42-1.51-.41-1.95Z" style="fill: #f4b200;"/>
56
+ <path d="m256.72,83.21c0-1.39-1.13-2.51-2.51-2.51s-2.51,1.13-2.51,2.51,1.13,2.51,2.51,2.51,2.51-1.13,2.51-2.51Z" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
57
+ <line x1="218.8" y1="131.54" x2="288.24" y2="131.54" style="fill: none; stroke: #f9b500; stroke-miterlimit: 10; stroke-width: .5px;"/>
58
+ <path d="m143.42,43.43l2.99-1.92c34.81-22.3,81.11-12.16,103.41,22.65h0" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 4px;"/>
59
+ <polyline points="242.93 64.16 250.34 64.16 250.34 56.12" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 3px;"/>
60
+ <path d="m253.66,141.68l-3.52,4.34c-28.53,29.92-75.91,31.04-105.83,2.5h0" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 4px;"/>
61
+ <polyline points="151 146.9 143.8 148.65 145.77 156.76" style="fill: none; stroke: #fff; stroke-miterlimit: 10; stroke-width: 3px;"/>
62
+ </g>
63
+ </svg>
@@ -0,0 +1,56 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ viewBox="0 0 52 52"
5
+ width="100"
6
+ height="100"
7
+ >
8
+ <style>
9
+ .svg-failed {
10
+ stroke: white;
11
+ stroke-width: 5;
12
+ stroke-miterlimit: 10;
13
+ stroke-linecap: round;
14
+ stroke-linejoin: round;
15
+ fill: none;
16
+ animation: svg-failed-scale 0.3s ease-in-out 0.9s both;
17
+ }
18
+
19
+ .svg-failed-circle {
20
+ stroke: none;
21
+ fill: #FF5A5F;
22
+ }
23
+
24
+ .svg-failed-x {
25
+ stroke-dasharray: 48;
26
+ stroke-dashoffset: 48;
27
+ animation: svg-failed-draw 0.5s ease forwards 0.6s;
28
+ }
29
+
30
+ @keyframes svg-failed-draw {
31
+ to {
32
+ stroke-dashoffset: 0;
33
+ }
34
+ }
35
+
36
+ @keyframes svg-failed-scale {
37
+ 0%, 100% {
38
+ transform: scale(1);
39
+ }
40
+ 50% {
41
+ transform: scale(1.1);
42
+ }
43
+ }
44
+ </style>
45
+
46
+ <circle class="svg-failed-circle" cx="26" cy="26" r="25" />
47
+ <!-- X mark: two lines crossing -->
48
+ <path
49
+ class="svg-failed svg-failed-x"
50
+ d="M16 16 L36 36"
51
+ />
52
+ <path
53
+ class="svg-failed svg-failed-x"
54
+ d="M36 16 L16 36"
55
+ />
56
+ </svg>
@@ -0,0 +1,50 @@
1
+ <svg class="pl" width="300" height="300" viewBox="0 0 300 300" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <style>
3
+ .pl__ring { animation: ringA 3s linear infinite; }
4
+ .pl__ring--a { stroke: #F79E1B; }
5
+ .pl__ring--b { animation-name: ringB; stroke: #F79E1B; }
6
+ .pl__ring--c { animation-name: ringC; stroke: #F79E1B; }
7
+ .pl__ring--d { animation-name: ringD; stroke: #F79E1B; }
8
+
9
+ @keyframes ringA {
10
+ from, 4% { stroke-dasharray: 0 660; stroke-width: 20; stroke-dashoffset: -330; }
11
+ 12% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -335; }
12
+ 32% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -595; }
13
+ 40%, 54% { stroke-dasharray: 0 660; stroke-width: 20; stroke-dashoffset: -660; }
14
+ 62% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -665; }
15
+ 82% { stroke-dasharray: 60 600; stroke-width: 30; stroke-dashoffset: -925; }
16
+ 90%, to { stroke-dasharray: 0 660; stroke-width: 20; stroke-dashoffset: -990; }
17
+ }
18
+ @keyframes ringB {
19
+ from, 12% { stroke-dasharray: 0 220; stroke-width: 20; stroke-dashoffset: -110; }
20
+ 20% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -115; }
21
+ 40% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -195; }
22
+ 48%, 62% { stroke-dasharray: 0 220; stroke-width: 20; stroke-dashoffset: -220; }
23
+ 70% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -225; }
24
+ 90% { stroke-dasharray: 20 200; stroke-width: 30; stroke-dashoffset: -305; }
25
+ 98%, to { stroke-dasharray: 0 220; stroke-width: 20; stroke-dashoffset: -330; }
26
+ }
27
+ @keyframes ringC {
28
+ from { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: 0; }
29
+ 8% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -5; }
30
+ 28% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -175; }
31
+ 36%, 58% { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -220; }
32
+ 66% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -225; }
33
+ 86% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -395; }
34
+ 94%, to { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -440; }
35
+ }
36
+ @keyframes ringD {
37
+ from, 8% { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: 0; }
38
+ 16% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -5; }
39
+ 36% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -175; }
40
+ 44%, 50% { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -220; }
41
+ 58% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -225; }
42
+ 78% { stroke-dasharray: 40 400; stroke-width: 30; stroke-dashoffset: -395; }
43
+ 86%, to { stroke-dasharray: 0 440; stroke-width: 20; stroke-dashoffset: -440; }
44
+ }
45
+ </style>
46
+ <circle class="pl__ring pl__ring--a" cx="150" cy="150" r="105" fill="none" stroke-width="20" stroke-dasharray="0 660" stroke-dashoffset="-330" stroke-linecap="round"/>
47
+ <circle class="pl__ring pl__ring--b" cx="150" cy="150" r="35" fill="none" stroke-width="20" stroke-dasharray="0 220" stroke-dashoffset="-110" stroke-linecap="round"/>
48
+ <circle class="pl__ring pl__ring--c" cx="115" cy="150" r="70" fill="none" stroke-width="20" stroke-dasharray="0 440" stroke-linecap="round"/>
49
+ <circle class="pl__ring pl__ring--d" cx="185" cy="150" r="70" fill="none" stroke-width="20" stroke-dasharray="0 440" stroke-linecap="round"/>
50
+ </svg>
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ viewBox="0 0 52 52"
5
+ width="100"
6
+ height="100"
7
+ >
8
+ <style>
9
+ .svg-checkmark {
10
+ stroke: white;
11
+ stroke-width: 5;
12
+ stroke-miterlimit: 10;
13
+ stroke-linecap: round;
14
+ stroke-linejoin: round;
15
+ fill: none;
16
+ animation: svg-success-scale 0.3s ease-in-out 0.9s both;
17
+ }
18
+
19
+ .svg-checkmark-circle {
20
+ stroke: none;
21
+ fill: #00D290;
22
+ }
23
+
24
+ .svg-checkmark-check {
25
+ stroke-dasharray: 48;
26
+ stroke-dashoffset: 48;
27
+ animation: svg-success-draw 0.5s ease forwards 0.6s;
28
+ }
29
+
30
+ @keyframes svg-success-draw {
31
+ to {
32
+ stroke-dashoffset: 0;
33
+ }
34
+ }
35
+
36
+ @keyframes svg-success-scale {
37
+ 0%, 100% {
38
+ transform: scale(1);
39
+ }
40
+ 50% {
41
+ transform: scale(1.1);
42
+ }
43
+ }
44
+ </style>
45
+
46
+ <circle class="svg-checkmark-circle" cx="26" cy="26" r="25" />
47
+ <path
48
+ class="svg-checkmark svg-checkmark-check"
49
+ d="M14.1 27.2l7.1 7.2 16.7-16.8"
50
+ />
51
+ </svg>
@@ -11,3 +11,4 @@
11
11
  //= require spree_cm_commissioner/selected_field_filter_origin_destination
12
12
  //= require spree_cm_commissioner/location_checkbox_manager
13
13
  //= require spree_cm_commissioner/trip_stop_selection
14
+ //= require spree_cm_commissioner/tenant_payment_icon_fields
@@ -0,0 +1,65 @@
1
+ document.addEventListener('DOMContentLoaded', function () {
2
+ // Initialize Select2 for all tenant-payment-icon-select elements
3
+ if (window.$ && $.fn.select2) {
4
+ $('.tenant-payment-icon-select').each(function () {
5
+ $(this).select2({
6
+ width: '100%'
7
+ });
8
+ });
9
+ }
10
+
11
+ // Handle icon selection change
12
+ document.querySelectorAll('.tenant-payment-icon-select').forEach(function (select) {
13
+ select.addEventListener('change', function (e) {
14
+ const field = e.target.name.match(/\[([^\]]*)\]$/)[1]; // Extract field name
15
+ const preview = document.getElementById(`icon-preview-${field}`);
16
+ const removeBtn = document.querySelector(`.remove-icon-btn[data-target="${field}"]`);
17
+ const iconPath = e.target.value;
18
+
19
+ if (!preview || !removeBtn) return;
20
+
21
+ if (!iconPath) {
22
+ preview.innerHTML = '<span class="no-icon-placeholder"></span>';
23
+ removeBtn.classList.add('hidden');
24
+ return;
25
+ }
26
+
27
+ // Fetch SVG for the selected icon
28
+ fetch(`/admin/vector_icons/svg?path=${encodeURIComponent(iconPath)}`)
29
+ .then((response) => {
30
+ if (!response.ok) throw new Error('Failed to fetch SVG');
31
+ return response.text();
32
+ })
33
+ .then((svg) => {
34
+ preview.innerHTML = svg;
35
+ removeBtn.classList.remove('hidden');
36
+ })
37
+ .catch((error) => {
38
+ console.error('Error fetching SVG:', error);
39
+ preview.innerHTML = '<span class="no-icon-placeholder">Error loading icon</span>';
40
+ });
41
+ });
42
+ });
43
+
44
+ document.addEventListener('click', function (e) {
45
+ if (!e.target.classList.contains('remove-icon-btn')) return;
46
+
47
+ const field = e.target.getAttribute('data-target');
48
+ const select = document.querySelector(`.tenant-payment-icon-select[name*="[${field}]"]`);
49
+ const preview = document.getElementById(`icon-preview-${field}`);
50
+ const removeBtn = e.target;
51
+
52
+ if (!select || !preview || !removeBtn) return;
53
+
54
+ // Clear the select input
55
+ select.value = '';
56
+
57
+ if (window.$ && $(select).hasClass('select2-hidden-accessible')) {
58
+ $(select).val('').trigger('change.select2');
59
+ } else {
60
+ select.dispatchEvent(new Event('change', { bubbles: true }));
61
+ }
62
+ preview.innerHTML = '<span class="no-icon-placeholder"></span>';
63
+ removeBtn.classList.add('hidden');
64
+ });
65
+ });
@@ -3,3 +3,4 @@
3
3
  @import "spree_cm_commissioner/backend/service_calendar";
4
4
  @import "spree_cm_commissioner/backend/guest_qr_code";
5
5
  @import "spree_cm_commissioner/backend/vehicle_seat";
6
+ @import "spree_cm_commissioner/backend/tenant_payment_icon_fields";
@@ -0,0 +1,60 @@
1
+ .payment-icon-preview {
2
+ width: 80px;
3
+ height: 80px;
4
+ background: #f8f9fa;
5
+ border: 1px dashed #ccc;
6
+ display: inline-flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ cursor: pointer;
10
+ }
11
+
12
+ .payment-icon-preview svg {
13
+ width: 100%;
14
+ height: 100%;
15
+ object-fit: contain;
16
+ }
17
+
18
+
19
+ .no-icon-placeholder {
20
+ width: 40px;
21
+ height: 40px;
22
+ border: 1px dashed #ddd;
23
+ background: #f8f9fa;
24
+ display: inline-block;
25
+ }
26
+
27
+ .icon-preview-container {
28
+ position: relative;
29
+ display: inline-block;
30
+ }
31
+
32
+ .remove-icon-btn {
33
+ position: absolute;
34
+ top: -8px;
35
+ right: -8px;
36
+ width: 24px;
37
+ height: 24px;
38
+ border-radius: 50%;
39
+ background: #dc3545;
40
+ color: white;
41
+ border: 2px solid white;
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ cursor: pointer;
46
+ font-size: 12px;
47
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
48
+ transition: all 0.2s ease;
49
+ z-index: 10;
50
+ }
51
+
52
+ .remove-icon-btn:hover {
53
+ background: #c82333;
54
+ transform: scale(1.1);
55
+ box-shadow: 0 3px 6px rgba(0,0,0,0.3);
56
+ }
57
+
58
+ .remove-icon-btn.hidden {
59
+ display: none;
60
+ }
@@ -6,8 +6,9 @@ module SpreeCmCommissioner
6
6
  after_action :set_cache_control_for_cdn
7
7
  end
8
8
 
9
+ # Override This Method based on your UseCase
9
10
  def max_age
10
- ENV.fetch('CONTENT_CACHE_MAX_AGE', '180')
11
+ ENV.fetch('CONTENT_CACHE_MAX_AGE', 1.day.to_i).to_i
11
12
  end
12
13
 
13
14
  def set_cache_control_for_cdn
@@ -2,21 +2,28 @@ module Spree
2
2
  module Admin
3
3
  class EventBlazerQueriesController < Spree::Admin::ResourceController
4
4
  def model_class
5
- SpreeCmCommissioner::TaxonBlazerQuery
5
+ SpreeCmCommissioner::BlazerQueryable
6
6
  end
7
7
 
8
8
  def object_name
9
- 'spree_cm_commissioner_taxon_blazer_query'
9
+ 'spree_cm_commissioner_blazer_queryable'
10
10
  end
11
11
 
12
12
  def create
13
- event_blazer = SpreeCmCommissioner::TaxonBlazerQuery.new(taxon_id: params[:event_id], blazer_query_id: params[:blazer_query_id])
13
+ queryable = Spree::Taxon.find(params[:event_id])
14
+
15
+ event_blazer = SpreeCmCommissioner::BlazerQueryable.new(
16
+ queryable: queryable,
17
+ blazer_query_id: params[:blazer_query_id]
18
+ )
19
+
14
20
  if event_blazer.save
15
21
  flash[:success] = I18n.t('event_blazer_queries.success')
16
22
  else
17
23
  flash[:alert] = event_blazer.errors.full_messages.join(', ')
18
24
  end
19
- redirect_to blazer.query_path(id: event_blazer.blazer_query_id, event_id: event_blazer.taxon_id)
25
+
26
+ redirect_to blazer.query_path(id: event_blazer.blazer_query_id, event_id: queryable.id)
20
27
  end
21
28
  end
22
29
  end
@@ -1,6 +1,8 @@
1
1
  module Spree
2
2
  module Admin
3
3
  class TenantsController < Spree::Admin::ResourceController
4
+ before_action :load_vector_icons, only: %i[new edit]
5
+
4
6
  # override
5
7
  def collection
6
8
  params[:q] = {} if params[:q].blank?
@@ -31,6 +33,12 @@ module Spree
31
33
  def collection_url(options = {})
32
34
  admin_tenants_url(options)
33
35
  end
36
+
37
+ private
38
+
39
+ def load_vector_icons
40
+ @vector_icons = SpreeCmCommissioner::VectorIcon.all
41
+ end
34
42
  end
35
43
  end
36
44
  end
@@ -0,0 +1,35 @@
1
+ module Spree
2
+ module Admin
3
+ class TripBlazerQueriesController < Spree::Admin::ResourceController
4
+ def model_class
5
+ SpreeCmCommissioner::BlazerQueryable
6
+ end
7
+
8
+ def object_name
9
+ 'spree_cm_commissioner_blazer_queryable'
10
+ end
11
+
12
+ def create
13
+ queryable = SpreeCmCommissioner::Trip.find_by(id: params[:trip_id])
14
+
15
+ if queryable.nil?
16
+ flash[:alert] = I18n.t('trip_blazer_queries.not_found')
17
+ redirect_to request.referer || spree.admin_trips_path and return
18
+ end
19
+
20
+ trip_blazer = SpreeCmCommissioner::BlazerQueryable.new(
21
+ queryable: queryable,
22
+ blazer_query_id: params[:blazer_query_id]
23
+ )
24
+
25
+ if trip_blazer.save
26
+ flash[:success] = I18n.t('trip_blazer_queries.success')
27
+ else
28
+ flash[:alert] = trip_blazer.errors.full_messages.join(', ')
29
+ end
30
+
31
+ redirect_to blazer.query_path(id: trip_blazer.blazer_query_id, trip_id: queryable.id)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Organizer
5
+ class InviteCrewsController < ::Spree::Api::V2::Organizer::BaseController
6
+ def show
7
+ render_serialized_payload { serialize_resource(invite) }
8
+ end
9
+
10
+ def update
11
+ context = SpreeCmCommissioner::CrewInviteLinkHandler.call(
12
+ params: params
13
+ )
14
+
15
+ if context.success?
16
+ render_serialized_payload { serialize_resource(context.invite) }
17
+ else
18
+ render_error_payload(context.message || I18n.t('invite.accept_fail'))
19
+ end
20
+ end
21
+
22
+ def invite
23
+ @invite ||= SpreeCmCommissioner::Invite.find_by!(token: params[:id])
24
+ end
25
+
26
+ def resource_serializer
27
+ ::Spree::V2::Organizer::InviteCrewsSerializer
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -8,7 +8,11 @@ module Spree
8
8
  return @collection if defined?(@collection)
9
9
  return SpreeCmCommissioner::DynamicFieldOption.none if params[:dynamic_field_id].blank?
10
10
 
11
- @collection = SpreeCmCommissioner::DynamicFieldOption.where(dynamic_field_id: params[:dynamic_field_id])
11
+ @collection = SpreeCmCommissioner::DynamicFieldOption
12
+ .where(dynamic_field_id: params[:dynamic_field_id])
13
+ .active
14
+ .order(position: :asc)
15
+
12
16
  @collection = @collection.where('value LIKE ?', "%#{params[:query]}%") if params[:query].present?
13
17
  @collection
14
18
  end
@@ -38,10 +38,25 @@ module Spree
38
38
  def update
39
39
  spree_authorize! :update, spree_current_order, order_token
40
40
 
41
- if resource.update(guest_params)
42
- render_serialized_payload { serialize_resource(resource) }
43
- else
44
- render_error_payload(resource, 400)
41
+ begin
42
+ if guest_params[:guest_dynamic_fields_attributes]
43
+ resource.guest_dynamic_fields.destroy_all
44
+
45
+ guest_params[:guest_dynamic_fields_attributes].each do |attr|
46
+ field = build_dynamic_field(attr)
47
+ field.save!
48
+ end
49
+ end
50
+
51
+ resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
52
+
53
+ if resource.save
54
+ render_serialized_payload { serialize_resource(resource) }
55
+ else
56
+ render_error_payload(resource.errors, 400)
57
+ end
58
+ rescue ActiveRecord::RecordInvalid => e
59
+ render_error_payload(e.record.errors, 400)
45
60
  end
46
61
  end
47
62
 
@@ -76,9 +91,20 @@ module Spree
76
91
  :upload_later,
77
92
  :country_code,
78
93
  :contact,
79
- guest_dynamic_fields_attributes: %i[id dynamic_field_id value _destroy]
94
+ guest_dynamic_fields_attributes: %i[id dynamic_field_id dynamic_field_option_id value _destroy]
80
95
  )
81
96
  end
97
+
98
+ def build_dynamic_field(attr)
99
+ field = resource.guest_dynamic_fields.build(attr.except(:id))
100
+
101
+ if field.dynamic_field.requires_dynamic_field_options?
102
+ option = field.dynamic_field.dynamic_field_options.find_by(id: field.value)
103
+ field.dynamic_field_option = option if option
104
+ end
105
+
106
+ field
107
+ end
82
108
  end
83
109
  end
84
110
  end
@@ -27,6 +27,8 @@ module Spree
27
27
  end
28
28
 
29
29
  def complete
30
+ return render_serialized_payload { serialized_current_order } if spree_current_order.confirm? || spree_current_order.complete?
31
+
30
32
  spree_authorize! :update, spree_current_order, order_token
31
33
 
32
34
  result = complete_service.call(order: spree_current_order)
@@ -37,7 +37,7 @@ module SpreeCmCommissioner
37
37
  bit_fields = SpreeCmCommissioner::KycBitwise::BIT_FIELDS.keys
38
38
 
39
39
  if permitted_resource_params[:use_product_kyc] == '1'
40
- permitted_resource_params[:kyc] = @product.kyc
40
+ permitted_resource_params[:kyc] = nil
41
41
  else
42
42
  @kyc_result = calculate_kyc_value(params[:variant])
43
43
  permitted_resource_params[:kyc] = @kyc_result
@@ -6,6 +6,17 @@ module SpreeCmCommissioner
6
6
  def self.prepended(base)
7
7
  base.include SpreeCmCommissioner::OrderConcern
8
8
  end
9
+
10
+ # Override Spree's default behavior:
11
+ # By default, Spree raises an error if `complete` is called on a completed or confirmed order.
12
+ # We want to allow this call to succeed, so the API can be used both to:
13
+ # - complete the order (if it's not yet complete), or
14
+ # - return the latest state of a confirmed or completed order without raising a forbidden error.
15
+ def complete
16
+ return render_serialized_payload { serialized_current_order } if spree_current_order.confirm? || spree_current_order.complete?
17
+
18
+ super
19
+ end
9
20
  end
10
21
  end
11
22
  end