spree_cm_commissioner 2.9.2 → 2.9.4

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/app/controllers/concerns/spree_cm_commissioner/load_test_account_scope.rb +14 -21
  4. data/app/controllers/concerns/spree_cm_commissioner/load_test_bypassable.rb +29 -0
  5. data/app/controllers/spree/api/chatrace/guests_controller.rb +1 -1
  6. data/app/controllers/spree/api/v2/storefront/account/guest_dynamic_fields_controller.rb +19 -48
  7. data/app/controllers/spree/api/v2/storefront/account/mark_guest_info_complete_controller.rb +2 -2
  8. data/app/controllers/spree/api/v2/storefront/account/orders_controller_decorator.rb +5 -15
  9. data/app/controllers/spree/api/v2/storefront/account/saved_guests_controller.rb +65 -0
  10. data/app/controllers/spree/api/v2/storefront/draft_orders_controller.rb +3 -0
  11. data/app/controllers/spree/api/v2/storefront/guests_controller.rb +10 -9
  12. data/app/controllers/spree/api/v2/storefront/order_histories_controller.rb +0 -1
  13. data/app/controllers/spree/api/v2/tenant/account/saved_guests_controller.rb +70 -0
  14. data/app/controllers/spree/api/v2/tenant/episodes_controller.rb +3 -1
  15. data/app/controllers/spree/api/v2/tenant/guests_controller.rb +11 -21
  16. data/app/controllers/spree/api/v2/tenant/order_histories_controller.rb +0 -1
  17. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +7 -1
  18. data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +3 -14
  19. data/app/jobs/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage_batch_job.rb +28 -0
  20. data/app/models/concerns/spree_cm_commissioner/guest_data_fill_stage_concern.rb +82 -0
  21. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +4 -0
  22. data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +1 -1
  23. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +13 -31
  24. data/app/models/spree_cm_commissioner/current.rb +6 -3
  25. data/app/models/spree_cm_commissioner/dynamic_field.rb +12 -0
  26. data/app/models/spree_cm_commissioner/guest.rb +1 -144
  27. data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +43 -71
  28. data/app/models/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage.rb +21 -0
  29. data/app/models/spree_cm_commissioner/order_decorator.rb +26 -0
  30. data/app/models/spree_cm_commissioner/product_decorator.rb +0 -22
  31. data/app/models/spree_cm_commissioner/product_dynamic_field.rb +17 -0
  32. data/app/models/spree_cm_commissioner/request_guard.rb +19 -0
  33. data/app/models/spree_cm_commissioner/user_decorator.rb +26 -1
  34. data/app/models/spree_cm_commissioner/voting_contestant.rb +13 -2
  35. data/app/queries/spree_cm_commissioner/event_chart_queries.rb +2 -2
  36. data/app/queries/spree_cm_commissioner/pie_chart_event_aggregator_queries.rb +2 -2
  37. data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +2 -2
  38. data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +3 -1
  39. data/app/serializers/spree/v2/tenant/saved_guest_serializer.rb +23 -0
  40. data/app/serializers/spree_cm_commissioner/v2/storefront/cart_serializer_decorator.rb +1 -0
  41. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +3 -6
  42. data/app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_serializer.rb +2 -2
  43. data/app/services/spree_cm_commissioner/{cart/create_guest.rb → guests/create.rb} +12 -10
  44. data/app/services/spree_cm_commissioner/guests/refresh_data_fill_stage.rb +20 -0
  45. data/app/services/spree_cm_commissioner/guests/send_dynamic_field_notification.rb +15 -0
  46. data/app/services/spree_cm_commissioner/guests/update.rb +68 -0
  47. data/app/services/spree_cm_commissioner/inventory_holds/validate_limits.rb +8 -3
  48. data/app/services/spree_cm_commissioner/load_test/destroy_accounts.rb +7 -10
  49. data/app/services/spree_cm_commissioner/load_test/generate_booking_ticket_data.rb +83 -19
  50. data/app/services/spree_cm_commissioner/order/guests/update.rb +5 -8
  51. data/app/services/spree_cm_commissioner/voting_contestants/advancer.rb +10 -3
  52. data/app/services/spree_cm_commissioner/voting_contestants/assigner.rb +20 -2
  53. data/app/services/spree_cm_commissioner/voting_contestants/bulk_updater.rb +15 -9
  54. data/app/views/spree/admin/variants/fixture.html.erb +1 -1
  55. data/config/initializers/spree_permitted_attributes.rb +19 -0
  56. data/config/load_test_flows/tenant.yml +47 -0
  57. data/config/locales/en.yml +2 -5
  58. data/config/locales/km.yml +2 -0
  59. data/config/routes.rb +3 -1
  60. data/db/migrate/20260713022227_add_advanced_to_episode_id_to_cm_voting_contestants.rb +8 -0
  61. data/db/migrate/20260714002626_rename_data_fill_stage_phase_on_cm_guests.rb +5 -0
  62. data/lib/spree_cm_commissioner/version.rb +1 -1
  63. data/lib/tasks/recompute_guest_data_fill_stage.rake +19 -0
  64. metadata +17 -12
  65. data/app/controllers/spree/api/v2/storefront/saved_guests_controller.rb +0 -77
  66. data/app/interactors/spree_cm_commissioner/guest_dynamic_field_notification_sender.rb +0 -11
  67. data/app/interactors/spree_cm_commissioner/guest_dynamic_fields_manager.rb +0 -33
  68. data/app/serializers/spree/v2/storefront/order_serializer_decorator.rb +0 -63
  69. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_minimal_serializer.rb +0 -30
  70. data/app/serializers/spree_cm_commissioner/v2/storefront/line_item_minimal_serializer.rb +0 -57
  71. data/app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_minimal_serializer.rb +0 -17
  72. data/app/services/spree_cm_commissioner/update_guest_service.rb +0 -129
  73. data/app/services/spree_cm_commissioner/users/incomplete_guest_checker_service.rb +0 -34
@@ -29,12 +29,30 @@ module SpreeCmCommissioner
29
29
  )
30
30
  end
31
31
 
32
- @voting_session.voting_contestants.find_or_create_by!(show_contestant: show_contestant) do |voting_contestant|
33
- voting_contestant.show_id = @voting_session.show_id
32
+ voting_contestant = @voting_session.voting_contestants.find_or_create_by!(show_contestant: show_contestant) do |vc|
33
+ vc.show_id = @voting_session.show_id
34
34
  end
35
+
36
+ link_pending_episode_advance!(show_contestant, voting_contestant)
35
37
  end
36
38
  end
37
39
  end
40
+
41
+ # A contestant advanced "By Episode" (BulkUpdater#advanced_to_attrs with a ShowEpisode
42
+ # target) only has advanced_to_episode_id set, no specific session yet. Once they're
43
+ # manually placed into a session of that episode here, resolve the pointer on both sides
44
+ # so Advancer's reversion/unwind logic (which walks advanced_to_type/id and matches via
45
+ # advanced_from) works the same as it would for a normal session-to-session mirror.
46
+ def link_pending_episode_advance!(show_contestant, voting_contestant)
47
+ source = SpreeCmCommissioner::VotingContestant
48
+ .where(show_contestant_id: show_contestant.id, advanced_to_episode_id: @episode.id, advanced_to_id: nil)
49
+ .order(id: :desc)
50
+ .first
51
+ return unless source
52
+
53
+ source.update!(advanced_to_type: 'SpreeCmCommissioner::VotingSession', advanced_to_id: @voting_session.id)
54
+ voting_contestant.update!(advanced_from: source.voting_session) if voting_contestant.advanced_from.blank?
55
+ end
38
56
  end
39
57
  end
40
58
  end
@@ -85,24 +85,30 @@ module SpreeCmCommissioner
85
85
  out
86
86
  end
87
87
 
88
- # Parses "ClassName:id" format into { advanced_to_type:, advanced_to_id: }.
89
- # Returns :invalid if the type is not in ALLOWED_ADVANCED_TO_TYPES.
90
- # Returns {} (no-op) when the value doesn't include a colon separator.
88
+ # Parses "ClassName:id:episode_id" into advanced_to_type/id/episode_id attrs.
89
+ # ShowEpisode targets only mark eligibility (advanced_to_episode_id) rather
90
+ # than a real session pointer, so type/id are left nil for those.
91
91
  def advanced_to_attrs(value)
92
- return { advanced_to_type: nil, advanced_to_id: nil } if value.blank?
92
+ return { advanced_to_type: nil, advanced_to_id: nil, advanced_to_episode_id: nil } if value.blank?
93
93
 
94
94
  parts = value.to_s.split(':')
95
- return {} if parts.size < 2
95
+ return {} if parts.size < 3
96
96
 
97
+ advanced_to_episode_id = parts.pop.to_i
97
98
  advanced_to_id = parts.pop.to_i
98
99
  advanced_to_type = parts.join(':')
99
100
 
100
101
  return :invalid unless ALLOWED_ADVANCED_TO_TYPES.include?(advanced_to_type)
101
102
 
102
- {
103
- advanced_to_id: advanced_to_id,
104
- advanced_to_type: advanced_to_type
105
- }
103
+ if advanced_to_type == 'SpreeCmCommissioner::ShowEpisode'
104
+ { advanced_to_type: nil, advanced_to_id: nil, advanced_to_episode_id: advanced_to_episode_id }
105
+ else
106
+ {
107
+ advanced_to_id: advanced_to_id,
108
+ advanced_to_type: advanced_to_type,
109
+ advanced_to_episode_id: advanced_to_episode_id
110
+ }
111
+ end
106
112
  end
107
113
  end
108
114
  end
@@ -27,7 +27,7 @@
27
27
 
28
28
  <p class="text-muted">
29
29
  Save this as <code><%= filename %></code> in
30
- <code>load_testing/config/fixture/platform/booking_ticket_flow/</code>
30
+ <code>load_testing/config/fixture/<%= @fixture_workflow %>/<%= @fixture_flow %>/</code>
31
31
  (git-ignored).
32
32
  </p>
33
33
 
@@ -3,6 +3,9 @@ module Spree
3
3
  ATTRIBUTES << :route_attributes unless ATTRIBUTES.include?(:route_attributes)
4
4
  mattr_reader :route_attributes
5
5
 
6
+ ATTRIBUTES << :saved_guest_attributes unless ATTRIBUTES.include?(:saved_guest_attributes)
7
+ mattr_reader :saved_guest_attributes
8
+
6
9
  @@vendor_attributes << :logo
7
10
  @@vendor_attributes << :service_origin_id
8
11
  @@vendor_attributes << :term_of_use
@@ -144,6 +147,22 @@ module Spree
144
147
  terms_and_conditions
145
148
  ]
146
149
 
150
+ @@saved_guest_attributes = %i[
151
+ first_name
152
+ last_name
153
+ dob
154
+ age
155
+ gender
156
+ email
157
+ country_code
158
+ phone_number
159
+ intel_phone_number
160
+ nationality_id
161
+ occupation_id
162
+ nationality_group
163
+ age_group
164
+ ]
165
+
147
166
  @@product_attributes += %i[
148
167
  preview
149
168
  ]
@@ -17,6 +17,19 @@ voting_flow:
17
17
  note: Resolves show_slug and voting_session_id straight off the voting session you picked.
18
18
  doc: tests/tenant/voting_flow/doc.md
19
19
 
20
+ topup_vote_flow:
21
+ description: >-
22
+ Top-up Vote screen — the organizer picker's "Fixture" button for this generates both the
23
+ Cash On and ABA (PayWay v2) fixtures at once (see aba_topup_vote_flow / cash_on_topup_vote_flow
24
+ below for their individual destinations).
25
+ data_button:
26
+ label: Fixture
27
+ where: >-
28
+ Organizer → Shows → Season → Episode → Voting Sessions table → row "⋮" menu →
29
+ Fixture → pick "Topup vote flow"
30
+ note: One click generates both payment methods' JSON on the same page.
31
+ doc: tests/tenant/aba_topup_vote_flow/doc.md
32
+
20
33
  aba_topup_vote_flow:
21
34
  description: Top-up Vote screen paid via ABA (PayWay v2 sandbox).
22
35
  destination: config/fixture/tenant/aba_topup_vote_flow/<env>.json
@@ -44,3 +57,37 @@ cash_on_topup_vote_flow:
44
57
  Resolves show_slug, voting_session_id, and payment_method_id off the tenant's active
45
58
  Cash On payment method — flags an issue if none is configured yet.
46
59
  doc: tests/tenant/cash_on_topup_vote_flow/doc.md
60
+
61
+ cash_on_booking_ticket_flow:
62
+ description: >-
63
+ Homepage → browse tickets → cart → checkout → cash payment → ticket pass (QR). The
64
+ organizer's "Fixture" button on a ticket variant generates this flow's JSON alongside
65
+ aba_booking_ticket_flow's on the same page in one click (each has its own destination file).
66
+ destination: config/fixture/tenant/cash_on_booking_ticket_flow/<env>.json
67
+ example: config/fixture/tenant/cash_on_booking_ticket_flow/example.json
68
+ data_button:
69
+ label: Fixture
70
+ where: >-
71
+ Organizer → Events → pick the event → Tickets → pick the ticket → Variants → the variant's
72
+ row → "⋮" menu → Fixture
73
+ note: >-
74
+ Runs a purchasable readiness check and resolves event_permalink, product_slug, product_id,
75
+ variant_id, and payment_method_id off the tenant's active Cash On payment method — flags an
76
+ issue if none is configured yet. Same as the platform flow, tenant ticket products here are
77
+ organized under an event taxon, so event_permalink is required.
78
+ doc: tests/tenant/cash_on_booking_ticket_flow/doc.md
79
+
80
+ aba_booking_ticket_flow:
81
+ description: Same booking flow as cash_on_booking_ticket_flow, paid via ABA (PayWay v2 sandbox) instead of cash.
82
+ destination: config/fixture/tenant/aba_booking_ticket_flow/<env>.json
83
+ example: config/fixture/tenant/aba_booking_ticket_flow/example.json
84
+ data_button:
85
+ label: Fixture
86
+ where: >-
87
+ Organizer → Events → pick the event → Tickets → pick the ticket → Variants → the variant's
88
+ row → "⋮" menu → Fixture
89
+ note: >-
90
+ Runs a purchasable readiness check and resolves event_permalink, product_slug, product_id,
91
+ variant_id, payment_method_id, and the payway config off the tenant's active ABA/PayWay
92
+ payment method — flags an issue if none is configured yet.
93
+ doc: tests/tenant/aba_booking_ticket_flow/doc.md
@@ -99,11 +99,6 @@ en:
99
99
  guest_card_classes:
100
100
  empty_info: "No guest card classes information available."
101
101
  background_image: "Background Image"
102
- guest_dynamic_field:
103
- errors:
104
- pre_registration_required: "is required before ticket issuance"
105
- post_registration_required: "must be completed after purchase"
106
- during_check_in_required: "is required during check-in"
107
102
  google_wallet:
108
103
  note: "Click <b>Create</b> or <b> Update</b> to connect to Google Wallet after filled all information "
109
104
  google_wallet_class_created: "Google Wallet class created successfully."
@@ -667,6 +662,8 @@ en:
667
662
  advanced_from_session: 'was advanced from a previous session and cannot be removed directly. Clear the advancement in the source session instead.'
668
663
  pre_vote_session: 'cannot be removed from a pre-vote session.'
669
664
  has_advanced_to_session: 'has been assigned to advance to another session. Clear the advancement first before removing this contestant.'
665
+ advanced_to_id:
666
+ same_as_advanced_from: 'cannot be the same as the contestant it was advanced from'
670
667
  spree_cm_commissioner/voting_credit:
671
668
  attributes:
672
669
  free_votes_amount:
@@ -432,6 +432,8 @@ km:
432
432
  advanced_from_session: 'ត្រូវបានដំឡើងពី session មុន ហើយមិនអាចដកចេញដោយផ្ទាល់បានទេ។ សូមលុបការដំឡើងនៅក្នុង session ប្រភពជំនួសវិញ។'
433
433
  pre_vote_session: 'មិនអាចដកចេញពី pre-vote session បានទេ។'
434
434
  has_advanced_to_session: 'ត្រូវបានកំណត់ឱ្យដំឡើងទៅ session មួយទៀត។ សូមលុបការដំឡើងជាមុនសិន មុននឹងដកអ្នកចូលប្រកួតនេះចេញ។'
435
+ advanced_to_id:
436
+ same_as_advanced_from: 'មិនអាចដូចនឹងអ្នកចូលប្រកួតដែលវាត្រូវបានដំឡើងចេញពីនោះទេ'
435
437
  spree_cm_commissioner/voting_credit:
436
438
  attributes:
437
439
  free_votes_amount:
data/config/routes.rb CHANGED
@@ -552,6 +552,7 @@ Spree::Core::Engine.add_routes do
552
552
  resource :account_recovers, only: [:update]
553
553
  namespace :account do
554
554
  resources :orders, controller: :orders, only: %i[index show]
555
+ resources :saved_guests
555
556
  end
556
557
 
557
558
  resource :cart, controller: :cart, only: %i[show create destroy] do
@@ -712,9 +713,10 @@ Spree::Core::Engine.add_routes do
712
713
  resources :guests, only: [] do
713
714
  patch 'dynamic_fields/:phase', to: 'guest_dynamic_fields#update_dynamic_field', as: :update_dynamic_fields
714
715
  end
716
+
717
+ resources :saved_guests
715
718
  end
716
719
 
717
- resources :saved_guests
718
720
  resource :s3_signed_urls
719
721
  resources :google_wallet_object_tokens
720
722
  resources :provinces, only: %i[index]
@@ -0,0 +1,8 @@
1
+ class AddAdvancedToEpisodeIdToCmVotingContestants < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_reference :cm_voting_contestants, :advanced_to_episode,
4
+ foreign_key: { to_table: :spree_products },
5
+ index: true,
6
+ if_not_exists: true
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ class RenameDataFillStagePhaseOnCmGuests < ActiveRecord::Migration[7.0]
2
+ def change
3
+ rename_column :cm_guests, :data_fill_stage_phase, :data_fill_stage
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '2.9.2'.freeze
2
+ VERSION = '2.9.4'.freeze
3
3
 
4
4
  module_function
5
5
 
@@ -0,0 +1,19 @@
1
+ # One-off remediation: fixes Guest#data_fill_stage staleness that accumulated before
2
+ # ProductDynamicField/DynamicField config changes had any recompute trigger. Not intended to run
3
+ # on a schedule. Enqueues small batches instead of looping over every guest inline, so this stays
4
+ # safe to run even on a small server or if the invoking process gets interrupted partway through —
5
+ # already-enqueued batches keep processing independently, and re-running is a harmless no-op for
6
+ # guests already corrected.
7
+ namespace :spree_cm_commissioner do
8
+ desc 'Recompute data_fill_stage for all guests (silent, no notifications).'
9
+ task recompute_guest_data_fill_stage: :environment do
10
+ batch_size = ENV.fetch('RECOMPUTE_GUEST_DATA_FILL_STAGE_BATCH_SIZE', '300').to_i
11
+
12
+ SpreeCmCommissioner::Guest.in_batches(of: batch_size) do |batch|
13
+ SpreeCmCommissioner::MaintenanceTasks::GuestDataFillStageBatchJob.perform_later(
14
+ guest_ids: batch.pluck(:id),
15
+ notify: false
16
+ )
17
+ end
18
+ end
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_cm_commissioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.2
4
+ version: 2.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-07-15 00:00:00.000000000 Z
11
+ date: 2026-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -828,6 +828,7 @@ files:
828
828
  - app/controllers/concerns/spree_cm_commissioner/exception_notificable.rb
829
829
  - app/controllers/concerns/spree_cm_commissioner/load_test_account_management.rb
830
830
  - app/controllers/concerns/spree_cm_commissioner/load_test_account_scope.rb
831
+ - app/controllers/concerns/spree_cm_commissioner/load_test_bypassable.rb
831
832
  - app/controllers/concerns/spree_cm_commissioner/load_test_login_token_generation.rb
832
833
  - app/controllers/concerns/spree_cm_commissioner/order_concern.rb
833
834
  - app/controllers/concerns/spree_cm_commissioner/turnstile_protectable.rb
@@ -964,6 +965,7 @@ files:
964
965
  - app/controllers/spree/api/v2/storefront/account/preferred_payment_method_controller.rb
965
966
  - app/controllers/spree/api/v2/storefront/account/qr_data_controller.rb
966
967
  - app/controllers/spree/api/v2/storefront/account/recipients_controller.rb
968
+ - app/controllers/spree/api/v2/storefront/account/saved_guests_controller.rb
967
969
  - app/controllers/spree/api/v2/storefront/account_checker_controller.rb
968
970
  - app/controllers/spree/api/v2/storefront/account_deletions_controller.rb
969
971
  - app/controllers/spree/api/v2/storefront/account_recovers_controller.rb
@@ -1019,7 +1021,6 @@ files:
1019
1021
  - app/controllers/spree/api/v2/storefront/reset_passwords_controller.rb
1020
1022
  - app/controllers/spree/api/v2/storefront/route_places_controller.rb
1021
1023
  - app/controllers/spree/api/v2/storefront/s3_signed_urls_controller.rb
1022
- - app/controllers/spree/api/v2/storefront/saved_guests_controller.rb
1023
1024
  - app/controllers/spree/api/v2/storefront/seat_layouts_controller.rb
1024
1025
  - app/controllers/spree/api/v2/storefront/self_check_in_controller.rb
1025
1026
  - app/controllers/spree/api/v2/storefront/taxons_controller_decorator.rb
@@ -1047,6 +1048,7 @@ files:
1047
1048
  - app/controllers/spree/api/v2/storefront/wishlists_controller_decorator.rb
1048
1049
  - app/controllers/spree/api/v2/tenant/access_tokens_controller.rb
1049
1050
  - app/controllers/spree/api/v2/tenant/account/orders_controller.rb
1051
+ - app/controllers/spree/api/v2/tenant/account/saved_guests_controller.rb
1050
1052
  - app/controllers/spree/api/v2/tenant/account_checker_controller.rb
1051
1053
  - app/controllers/spree/api/v2/tenant/account_controller.rb
1052
1054
  - app/controllers/spree/api/v2/tenant/account_deletions_controller.rb
@@ -1258,8 +1260,6 @@ files:
1258
1260
  - app/interactors/spree_cm_commissioner/firebase_id_token_provider.rb
1259
1261
  - app/interactors/spree_cm_commissioner/google_places_fetcher.rb
1260
1262
  - app/interactors/spree_cm_commissioner/google_routes_distance_calculator.rb
1261
- - app/interactors/spree_cm_commissioner/guest_dynamic_field_notification_sender.rb
1262
- - app/interactors/spree_cm_commissioner/guest_dynamic_fields_manager.rb
1263
1263
  - app/interactors/spree_cm_commissioner/guest_id_card_manager.rb
1264
1264
  - app/interactors/spree_cm_commissioner/host_matcher.rb
1265
1265
  - app/interactors/spree_cm_commissioner/id_card_image_updater.rb
@@ -1397,6 +1397,7 @@ files:
1397
1397
  - app/jobs/spree_cm_commissioner/inventory_items/generate_inventory_items_job.rb
1398
1398
  - app/jobs/spree_cm_commissioner/invite_guests/bulk_create_job.rb
1399
1399
  - app/jobs/spree_cm_commissioner/line_items/sync_event_date_job.rb
1400
+ - app/jobs/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage_batch_job.rb
1400
1401
  - app/jobs/spree_cm_commissioner/maintenance_tasks/orchestrate_job.rb
1401
1402
  - app/jobs/spree_cm_commissioner/maintenance_tasks/process_job.rb
1402
1403
  - app/jobs/spree_cm_commissioner/maintenance_tasks/refinalize_guests_batch_job.rb
@@ -1453,6 +1454,7 @@ files:
1453
1454
  - app/mailers/spree_cm_commissioner/team_invite_mailer.rb
1454
1455
  - app/models/.gitkeep
1455
1456
  - app/models/concerns/spree_cm_commissioner/event_metadata.rb
1457
+ - app/models/concerns/spree_cm_commissioner/guest_data_fill_stage_concern.rb
1456
1458
  - app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb
1457
1459
  - app/models/concerns/spree_cm_commissioner/homepage_section_relatable_concern.rb
1458
1460
  - app/models/concerns/spree_cm_commissioner/integrations/integration_mappable.rb
@@ -1590,6 +1592,7 @@ files:
1590
1592
  - app/models/spree_cm_commissioner/maintenance_task.rb
1591
1593
  - app/models/spree_cm_commissioner/maintenance_tasks/cache_invalidation.rb
1592
1594
  - app/models/spree_cm_commissioner/maintenance_tasks/event.rb
1595
+ - app/models/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage.rb
1593
1596
  - app/models/spree_cm_commissioner/maintenance_tasks/voting_session.rb
1594
1597
  - app/models/spree_cm_commissioner/menu_decorator.rb
1595
1598
  - app/models/spree_cm_commissioner/menu_item_decorator.rb
@@ -1663,6 +1666,7 @@ files:
1663
1666
  - app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb
1664
1667
  - app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb
1665
1668
  - app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb
1669
+ - app/models/spree_cm_commissioner/request_guard.rb
1666
1670
  - app/models/spree_cm_commissioner/reserved_block.rb
1667
1671
  - app/models/spree_cm_commissioner/role_decorator.rb
1668
1672
  - app/models/spree_cm_commissioner/role_permission.rb
@@ -2000,7 +2004,6 @@ files:
2000
2004
  - app/serializers/spree/v2/storefront/notification_serializer.rb
2001
2005
  - app/serializers/spree/v2/storefront/option_type_serializer_decorator.rb
2002
2006
  - app/serializers/spree/v2/storefront/option_value_serializer_decorator.rb
2003
- - app/serializers/spree/v2/storefront/order_serializer_decorator.rb
2004
2007
  - app/serializers/spree/v2/storefront/place_serializer.rb
2005
2008
  - app/serializers/spree/v2/storefront/product_serializer_decorator.rb
2006
2009
  - app/serializers/spree/v2/storefront/role_serializer.rb
@@ -2050,6 +2053,7 @@ files:
2050
2053
  - app/serializers/spree/v2/tenant/reset_password_serializer.rb
2051
2054
  - app/serializers/spree/v2/tenant/role_serializer.rb
2052
2055
  - app/serializers/spree/v2/tenant/s3_signed_url_serializer.rb
2056
+ - app/serializers/spree/v2/tenant/saved_guest_serializer.rb
2053
2057
  - app/serializers/spree/v2/tenant/show_contestant_serializer.rb
2054
2058
  - app/serializers/spree/v2/tenant/show_episode_serializer.rb
2055
2059
  - app/serializers/spree/v2/tenant/show_parent_serializer.rb
@@ -2123,7 +2127,6 @@ files:
2123
2127
  - app/serializers/spree_cm_commissioner/v2/storefront/google_wallet_serializer.rb
2124
2128
  - app/serializers/spree_cm_commissioner/v2/storefront/guest_card_class_serializer.rb
2125
2129
  - app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb
2126
- - app/serializers/spree_cm_commissioner/v2/storefront/guest_minimal_serializer.rb
2127
2130
  - app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb
2128
2131
  - app/serializers/spree_cm_commissioner/v2/storefront/homepage_background_serializer.rb
2129
2132
  - app/serializers/spree_cm_commissioner/v2/storefront/homepage_banner_serializer.rb
@@ -2132,7 +2135,6 @@ files:
2132
2135
  - app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_cart_serializer.rb
2133
2136
  - app/serializers/spree_cm_commissioner/v2/storefront/intercity_taxi_line_item_serializer.rb
2134
2137
  - app/serializers/spree_cm_commissioner/v2/storefront/inventory_item_serializer.rb
2135
- - app/serializers/spree_cm_commissioner/v2/storefront/line_item_minimal_serializer.rb
2136
2138
  - app/serializers/spree_cm_commissioner/v2/storefront/menu_item_serializer_decorator.rb
2137
2139
  - app/serializers/spree_cm_commissioner/v2/storefront/menu_serializer_decorator.rb
2138
2140
  - app/serializers/spree_cm_commissioner/v2/storefront/payment_method_group_serializer.rb
@@ -2158,7 +2160,6 @@ files:
2158
2160
  - app/serializers/spree_cm_commissioner/v2/storefront/self_check_in_serializer.rb
2159
2161
  - app/serializers/spree_cm_commissioner/v2/storefront/stock_item_serializer.rb
2160
2162
  - app/serializers/spree_cm_commissioner/v2/storefront/taxon_include_product_serializer.rb
2161
- - app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_minimal_serializer.rb
2162
2163
  - app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_serializer.rb
2163
2164
  - app/serializers/spree_cm_commissioner/v2/storefront/transit_line_item_serializer.rb
2164
2165
  - app/serializers/spree_cm_commissioner/v2/storefront/trip_place_serializer.rb
@@ -2188,7 +2189,6 @@ files:
2188
2189
  - app/services/spree_cm_commissioner/calculate_distance.rb
2189
2190
  - app/services/spree_cm_commissioner/cart/add_guest.rb
2190
2191
  - app/services/spree_cm_commissioner/cart/add_item_decorator.rb
2191
- - app/services/spree_cm_commissioner/cart/create_guest.rb
2192
2192
  - app/services/spree_cm_commissioner/cart/destroy_decorator.rb
2193
2193
  - app/services/spree_cm_commissioner/cart/empty_decorator.rb
2194
2194
  - app/services/spree_cm_commissioner/cart/recalculate_decorator.rb
@@ -2225,8 +2225,12 @@ files:
2225
2225
  - app/services/spree_cm_commissioner/google_wallets/hotel_class_updater.rb
2226
2226
  - app/services/spree_cm_commissioner/google_wallets/hotel_object_builder.rb
2227
2227
  - app/services/spree_cm_commissioner/guests/claim_invite_guest_service.rb
2228
+ - app/services/spree_cm_commissioner/guests/create.rb
2228
2229
  - app/services/spree_cm_commissioner/guests/finalize.rb
2229
2230
  - app/services/spree_cm_commissioner/guests/preload_check_in_session_ids.rb
2231
+ - app/services/spree_cm_commissioner/guests/refresh_data_fill_stage.rb
2232
+ - app/services/spree_cm_commissioner/guests/send_dynamic_field_notification.rb
2233
+ - app/services/spree_cm_commissioner/guests/update.rb
2230
2234
  - app/services/spree_cm_commissioner/guests/update_seat.rb
2231
2235
  - app/services/spree_cm_commissioner/homepage_data.rb
2232
2236
  - app/services/spree_cm_commissioner/homepage_data_loader.rb
@@ -2365,12 +2369,10 @@ files:
2365
2369
  - app/services/spree_cm_commissioner/trips/service_calendars/create_or_update.rb
2366
2370
  - app/services/spree_cm_commissioner/trips/update_single_leg.rb
2367
2371
  - app/services/spree_cm_commissioner/trips/variants/create.rb
2368
- - app/services/spree_cm_commissioner/update_guest_service.rb
2369
2372
  - app/services/spree_cm_commissioner/url_embed/youtube_embed.rb
2370
2373
  - app/services/spree_cm_commissioner/user_authenticator.rb
2371
2374
  - app/services/spree_cm_commissioner/user_counters_service.rb
2372
2375
  - app/services/spree_cm_commissioner/user_roles_assigner.rb
2373
- - app/services/spree_cm_commissioner/users/incomplete_guest_checker_service.rb
2374
2376
  - app/services/spree_cm_commissioner/users/qr_data/extract_login.rb
2375
2377
  - app/services/spree_cm_commissioner/users/qr_data/generate.rb
2376
2378
  - app/services/spree_cm_commissioner/users/qr_data/invalidate.rb
@@ -3446,6 +3448,8 @@ files:
3446
3448
  - db/migrate/20260701000001_add_device_info_to_cm_waiting_room_sessions.rb
3447
3449
  - db/migrate/20260703065239_add_position_to_cm_voting_contestants.rb
3448
3450
  - db/migrate/20260708150000_add_name_and_short_name_to_cm_trips.rb
3451
+ - db/migrate/20260713022227_add_advanced_to_episode_id_to_cm_voting_contestants.rb
3452
+ - db/migrate/20260714002626_rename_data_fill_stage_phase_on_cm_guests.rb
3449
3453
  - docker-compose.yml
3450
3454
  - docs/api/scoped-access-token-endpoints.md
3451
3455
  - docs/option_types/attr_types.md
@@ -3626,6 +3630,7 @@ files:
3626
3630
  - lib/tasks/kh_location_option_values.rake
3627
3631
  - lib/tasks/kh_provinces.rake
3628
3632
  - lib/tasks/migrate_and_rebuild_place_hierarchy.rake
3633
+ - lib/tasks/recompute_guest_data_fill_stage.rake
3629
3634
  - lib/tasks/remove_duplicate_device_tokens.rake
3630
3635
  - lib/tasks/subscriptions_order_creator.rake
3631
3636
  - lib/tasks/update_gateway_status.rake
@@ -1,77 +0,0 @@
1
- module Spree
2
- module Api
3
- module V2
4
- module Storefront
5
- class SavedGuestsController < ::Spree::Api::V2::ResourceController
6
- before_action :require_spree_current_user
7
- before_action :load_saved_guest, only: %i[show update destroy]
8
-
9
- def collection
10
- spree_current_user.saved_guests.order(created_at: :desc)
11
- .page(params[:page])
12
- .per(params[:per_page])
13
- end
14
-
15
- def create
16
- saved_guest = spree_current_user.saved_guests.new(saved_guest_params)
17
-
18
- if saved_guest.save
19
- render_serialized_payload(201) { serialize_resource(saved_guest) }
20
- else
21
- render_error_payload(saved_guest.errors.full_messages.to_sentence, 422)
22
- end
23
- end
24
-
25
- def update
26
- if @saved_guest.update(saved_guest_params)
27
- render_serialized_payload { serialize_resource(@saved_guest) }
28
- else
29
- render_error_payload(@saved_guest.errors.full_messages.to_sentence, 400)
30
- end
31
- end
32
-
33
- def destroy
34
- @saved_guest.destroy
35
- head :no_content
36
- end
37
-
38
- private
39
-
40
- def model_class
41
- SpreeCmCommissioner::SavedGuest
42
- end
43
-
44
- def collection_serializer
45
- resource_serializer
46
- end
47
-
48
- def resource_serializer
49
- SpreeCmCommissioner::V2::Storefront::SavedGuestSerializer
50
- end
51
-
52
- def load_saved_guest
53
- @saved_guest = spree_current_user.saved_guests.find(params[:id])
54
- end
55
-
56
- def saved_guest_params
57
- params.require(:saved_guest).permit(
58
- :first_name,
59
- :last_name,
60
- :dob,
61
- :age,
62
- :gender,
63
- :email,
64
- :country_code,
65
- :phone_number,
66
- :intel_phone_number,
67
- :nationality_id,
68
- :occupation_id,
69
- :nationality_group,
70
- :age_group
71
- )
72
- end
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,11 +0,0 @@
1
- module SpreeCmCommissioner
2
- class GuestDynamicFieldNotificationSender < BaseInteractor
3
- def call
4
- notification = SpreeCmCommissioner::GuestDynamicFieldNotification.with(
5
- guest: context.guest
6
- ).deliver_later(context.guest.user)
7
-
8
- context.notification = notification
9
- end
10
- end
11
- end
@@ -1,33 +0,0 @@
1
- module SpreeCmCommissioner
2
- class GuestDynamicFieldsManager < BaseInteractor
3
- delegate :resource, :dynamic_fields_attributes, to: :context
4
-
5
- def call
6
- return if dynamic_fields_attributes.blank?
7
-
8
- dynamic_fields_attributes.each { |attr| upsert_or_destroy_field(attr) }
9
- end
10
-
11
- private
12
-
13
- def upsert_or_destroy_field(attr)
14
- if attr[:_destroy] == '1' && attr[:id].present?
15
- resource.guest_dynamic_fields.find_by(id: attr[:id])&.destroy!
16
- return
17
- end
18
-
19
- return if attr[:dynamic_field_id].blank?
20
-
21
- field = attr[:id].present? ? resource.guest_dynamic_fields.find(attr[:id]) : resource.guest_dynamic_fields.build
22
- field.assign_attributes(attr.except(:id, :_destroy))
23
- associate_dynamic_field_option(field)
24
- field.save!
25
- end
26
-
27
- def associate_dynamic_field_option(field)
28
- return unless field.value.to_s.match?(/\A\d+\z/)
29
-
30
- field.dynamic_field_option = field.dynamic_field.dynamic_field_options.find_by(id: field.value.to_i)
31
- end
32
- end
33
- end
@@ -1,63 +0,0 @@
1
- module Spree
2
- module V2
3
- module Storefront
4
- module OrderSerializerDecorator
5
- def self.prepended(base)
6
- base.attribute :has_incomplete_guest_info do |order|
7
- order.user&.public_metadata&.[]('has_incomplete_guest_info') || false
8
- end
9
-
10
- base.attribute :guest_info_status do |order|
11
- {
12
- incomplete: order_has_incomplete_guests?(order),
13
- can_mark_complete: can_mark_complete?(order)
14
- }
15
- end
16
- end
17
-
18
- def self.order_has_incomplete_guests?(order)
19
- order.line_items.any? do |line_item|
20
- line_item.guests.any? do |guest|
21
- guest_incomplete?(guest)
22
- end
23
- end
24
- end
25
-
26
- def self.guest_incomplete?(guest)
27
- (guest.pre_registration_fields? && !guest.pre_registration_completed?) ||
28
- (guest.post_registration_fields? && !guest.post_registration_completed?) ||
29
- (guest.during_check_in_fields? && !guest.check_in_completed?)
30
- end
31
-
32
- def self.can_mark_complete?(order)
33
- event_ended?(order) || all_guest_info_complete?(order)
34
- end
35
-
36
- def self.event_ended?(order)
37
- order.line_items.any? { |line_item| event_ended_for_line_item?(line_item) }
38
- end
39
-
40
- def self.event_ended_for_line_item?(line_item)
41
- event = line_item.event
42
- event&.to_date.present? && event.to_date < Time.zone.today
43
- end
44
-
45
- def self.all_guest_info_complete?(order)
46
- order.line_items.all? { |line_item| line_item_guests_complete?(line_item) }
47
- end
48
-
49
- def self.line_item_guests_complete?(line_item)
50
- line_item.guests.all? { |guest| guest_complete?(guest) }
51
- end
52
-
53
- def self.guest_complete?(guest)
54
- guest.pre_registration_completed? &&
55
- (!guest.post_registration_fields? || guest.post_registration_completed?) &&
56
- (!guest.during_check_in_fields? || guest.check_in_completed?)
57
- end
58
- end
59
- end
60
- end
61
- end
62
-
63
- Spree::V2::Storefront::OrderSerializer.prepend(Spree::V2::Storefront::OrderSerializerDecorator)