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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/concerns/spree_cm_commissioner/load_test_account_scope.rb +14 -21
- data/app/controllers/concerns/spree_cm_commissioner/load_test_bypassable.rb +29 -0
- data/app/controllers/spree/api/chatrace/guests_controller.rb +1 -1
- data/app/controllers/spree/api/v2/storefront/account/guest_dynamic_fields_controller.rb +19 -48
- data/app/controllers/spree/api/v2/storefront/account/mark_guest_info_complete_controller.rb +2 -2
- data/app/controllers/spree/api/v2/storefront/account/orders_controller_decorator.rb +5 -15
- data/app/controllers/spree/api/v2/storefront/account/saved_guests_controller.rb +65 -0
- data/app/controllers/spree/api/v2/storefront/draft_orders_controller.rb +3 -0
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +10 -9
- data/app/controllers/spree/api/v2/storefront/order_histories_controller.rb +0 -1
- data/app/controllers/spree/api/v2/tenant/account/saved_guests_controller.rb +70 -0
- data/app/controllers/spree/api/v2/tenant/episodes_controller.rb +3 -1
- data/app/controllers/spree/api/v2/tenant/guests_controller.rb +11 -21
- data/app/controllers/spree/api/v2/tenant/order_histories_controller.rb +0 -1
- data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +7 -1
- data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +3 -14
- data/app/jobs/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage_batch_job.rb +28 -0
- data/app/models/concerns/spree_cm_commissioner/guest_data_fill_stage_concern.rb +82 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +4 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +13 -31
- data/app/models/spree_cm_commissioner/current.rb +6 -3
- data/app/models/spree_cm_commissioner/dynamic_field.rb +12 -0
- data/app/models/spree_cm_commissioner/guest.rb +1 -144
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +43 -71
- data/app/models/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage.rb +21 -0
- data/app/models/spree_cm_commissioner/order_decorator.rb +26 -0
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -22
- data/app/models/spree_cm_commissioner/product_dynamic_field.rb +17 -0
- data/app/models/spree_cm_commissioner/request_guard.rb +19 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +26 -1
- data/app/models/spree_cm_commissioner/voting_contestant.rb +13 -2
- data/app/queries/spree_cm_commissioner/event_chart_queries.rb +2 -2
- data/app/queries/spree_cm_commissioner/pie_chart_event_aggregator_queries.rb +2 -2
- data/app/serializers/spree/v2/storefront/line_item_serializer_decorator.rb +2 -2
- data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +3 -1
- data/app/serializers/spree/v2/tenant/saved_guest_serializer.rb +23 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/cart_serializer_decorator.rb +1 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +3 -6
- data/app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_serializer.rb +2 -2
- data/app/services/spree_cm_commissioner/{cart/create_guest.rb → guests/create.rb} +12 -10
- data/app/services/spree_cm_commissioner/guests/refresh_data_fill_stage.rb +20 -0
- data/app/services/spree_cm_commissioner/guests/send_dynamic_field_notification.rb +15 -0
- data/app/services/spree_cm_commissioner/guests/update.rb +68 -0
- data/app/services/spree_cm_commissioner/inventory_holds/validate_limits.rb +8 -3
- data/app/services/spree_cm_commissioner/load_test/destroy_accounts.rb +7 -10
- data/app/services/spree_cm_commissioner/load_test/generate_booking_ticket_data.rb +83 -19
- data/app/services/spree_cm_commissioner/order/guests/update.rb +5 -8
- data/app/services/spree_cm_commissioner/voting_contestants/advancer.rb +10 -3
- data/app/services/spree_cm_commissioner/voting_contestants/assigner.rb +20 -2
- data/app/services/spree_cm_commissioner/voting_contestants/bulk_updater.rb +15 -9
- data/app/views/spree/admin/variants/fixture.html.erb +1 -1
- data/config/initializers/spree_permitted_attributes.rb +19 -0
- data/config/load_test_flows/tenant.yml +47 -0
- data/config/locales/en.yml +2 -5
- data/config/locales/km.yml +2 -0
- data/config/routes.rb +3 -1
- data/db/migrate/20260713022227_add_advanced_to_episode_id_to_cm_voting_contestants.rb +8 -0
- data/db/migrate/20260714002626_rename_data_fill_stage_phase_on_cm_guests.rb +5 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/tasks/recompute_guest_data_fill_stage.rake +19 -0
- metadata +17 -12
- data/app/controllers/spree/api/v2/storefront/saved_guests_controller.rb +0 -77
- data/app/interactors/spree_cm_commissioner/guest_dynamic_field_notification_sender.rb +0 -11
- data/app/interactors/spree_cm_commissioner/guest_dynamic_fields_manager.rb +0 -33
- data/app/serializers/spree/v2/storefront/order_serializer_decorator.rb +0 -63
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_minimal_serializer.rb +0 -30
- data/app/serializers/spree_cm_commissioner/v2/storefront/line_item_minimal_serializer.rb +0 -57
- data/app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_minimal_serializer.rb +0 -17
- data/app/services/spree_cm_commissioner/update_guest_service.rb +0 -129
- data/app/services/spree_cm_commissioner/users/incomplete_guest_checker_service.rb +0 -34
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module V2
|
|
3
|
-
module Storefront
|
|
4
|
-
class GuestMinimalSerializer < BaseSerializer
|
|
5
|
-
set_type :guest
|
|
6
|
-
|
|
7
|
-
attributes :first_name, :last_name, :dob, :gender, :kyc_fields, :other_occupation, :created_at, :updated_at,
|
|
8
|
-
:qr_data, :social_contact_platform, :social_contact, :available_social_contact_platforms,
|
|
9
|
-
:age, :emergency_contact, :other_organization, :expectation, :upload_later, :address, :formatted_bib_number, :phone_number,
|
|
10
|
-
:token, :country_code, :contact, :data_fill_stage_phase,
|
|
11
|
-
:saved_guest_id, :state
|
|
12
|
-
|
|
13
|
-
attribute :seat_number do |object|
|
|
14
|
-
object.seat_number || object.formatted_bib_number
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
attribute :allowed_checkout, &:allowed_checkout?
|
|
18
|
-
attribute :allowed_upload_later, &:allowed_upload_later?
|
|
19
|
-
attribute :require_kyc_field, &:require_kyc_field?
|
|
20
|
-
|
|
21
|
-
belongs_to :line_item, serializer: SpreeCmCommissioner::V2::Storefront::LineItemMinimalSerializer
|
|
22
|
-
|
|
23
|
-
has_many :check_ins, serializer: SpreeCmCommissioner::V2::Storefront::CheckInSerializer
|
|
24
|
-
has_many :ticket_transfers, serializer: SpreeCmCommissioner::V2::Storefront::TicketTransferMinimalSerializer
|
|
25
|
-
|
|
26
|
-
cache_options store: nil
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module V2
|
|
3
|
-
module Storefront
|
|
4
|
-
# Mirrors LineItemSerializer + its decorator attributes and relationships,
|
|
5
|
-
# but omits has_many :guests, :pending_guests, and :saved_guests to prevent
|
|
6
|
-
# a circular serialization cycle: LineItemSerializer embeds guests via
|
|
7
|
-
# GuestMinimalSerializer, which in turn embeds this LineItemMinimalSerializer.
|
|
8
|
-
class LineItemMinimalSerializer < BaseSerializer
|
|
9
|
-
set_type :line_item
|
|
10
|
-
|
|
11
|
-
attributes :name, :quantity, :price, :slug, :options_text, :currency,
|
|
12
|
-
:display_price, :total, :display_total, :adjustment_total,
|
|
13
|
-
:display_adjustment_total, :additional_tax_total,
|
|
14
|
-
:discounted_amount, :display_discounted_amount,
|
|
15
|
-
:display_additional_tax_total, :promo_total, :display_promo_total,
|
|
16
|
-
:included_tax_total, :display_included_tax_total,
|
|
17
|
-
:pre_tax_amount, :display_pre_tax_amount, :public_metadata,
|
|
18
|
-
:from_date, :to_date, :need_confirmation, :product_type, :event_status, :amount, :display_amount,
|
|
19
|
-
:checkin_date, :checkout_date,
|
|
20
|
-
:number, :qr_data,
|
|
21
|
-
:kyc, :kyc_fields, :remaining_total_guests, :number_of_guests,
|
|
22
|
-
:completion_steps, :available_social_contact_platforms, :allow_anonymous_booking, :discontinue_on,
|
|
23
|
-
:high_demand, :jwt_token,
|
|
24
|
-
:direction, :trip_id, :boarding_trip_stop_id, :drop_off_trip_stop_id
|
|
25
|
-
|
|
26
|
-
attribute :required_self_check_in_location, &:required_self_check_in_location?
|
|
27
|
-
attribute :allowed_self_check_in, &:allowed_self_check_in?
|
|
28
|
-
attribute :allowed_upload_later, &:allowed_upload_later?
|
|
29
|
-
attribute :delivery_required, &:delivery_required?
|
|
30
|
-
attribute :sufficient_stock, &:sufficient_stock?
|
|
31
|
-
|
|
32
|
-
attribute :pickup_map_place do |line_item|
|
|
33
|
-
line_item.pickup_map_place&.to_h
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
attribute :dropoff_map_place do |line_item|
|
|
37
|
-
line_item.dropoff_map_place&.to_h
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
attribute :distance do |line_item|
|
|
41
|
-
line_item.distance&.to_h
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
belongs_to :variant, serializer: Spree::V2::Storefront::VariantSerializer
|
|
45
|
-
has_many :digital_links, serializer: Spree::V2::Storefront::DigitalLinkSerializer
|
|
46
|
-
|
|
47
|
-
has_one :vendor, serializer: Spree::V2::Storefront::VendorSerializer
|
|
48
|
-
belongs_to :order, serializer: Spree::V2::Storefront::OrderSerializer
|
|
49
|
-
has_one :google_wallet, serializer: SpreeCmCommissioner::V2::Storefront::GoogleWalletSerializer
|
|
50
|
-
has_one :product, serializer: Spree::V2::Storefront::ProductSerializer
|
|
51
|
-
has_one :event, serializer: Spree::V2::Storefront::TaxonSerializer
|
|
52
|
-
|
|
53
|
-
cache_options store: nil
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
data/app/serializers/spree_cm_commissioner/v2/storefront/ticket_transfer_minimal_serializer.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module V2
|
|
3
|
-
module Storefront
|
|
4
|
-
class TicketTransferMinimalSerializer < BaseSerializer
|
|
5
|
-
set_type :ticket_transfer
|
|
6
|
-
|
|
7
|
-
attributes :number, :state, :price, :platform_fee, :seller_net, :total, :currency, :token,
|
|
8
|
-
:transfer_type, :settlement_status, :completed_at, :expires_at, :created_at, :updated_at
|
|
9
|
-
|
|
10
|
-
belongs_to :from_user, serializer: ::Spree::V2::Storefront::UserSerializer
|
|
11
|
-
belongs_to :to_user, serializer: ::Spree::V2::Storefront::UserSerializer
|
|
12
|
-
belongs_to :event, serializer: Spree::V2::Storefront::TaxonSerializer
|
|
13
|
-
belongs_to :product, serializer: Spree::V2::Storefront::ProductSerializer
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
# Updates guest records with dynamic fields.
|
|
3
|
-
# Handles create/update/delete of dynamic fields with automatic cleanup of removed fields.
|
|
4
|
-
class UpdateGuestService
|
|
5
|
-
attr_reader :guest, :guest_params
|
|
6
|
-
|
|
7
|
-
def initialize(guest, guest_params)
|
|
8
|
-
@guest = guest
|
|
9
|
-
@guest_params = guest_params
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# Updates guest within transaction: process dynamic fields → update attributes → move to next stage
|
|
13
|
-
def call
|
|
14
|
-
ActiveRecord::Base.transaction do
|
|
15
|
-
process_dynamic_fields(guest_params[:guest_dynamic_fields_attributes]) if guest_params[:guest_dynamic_fields_attributes]
|
|
16
|
-
|
|
17
|
-
guest.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
|
|
18
|
-
guest.save!
|
|
19
|
-
|
|
20
|
-
guest.save_and_move_to_next_stage
|
|
21
|
-
end
|
|
22
|
-
guest
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
# Processes dynamic fields: destroy marked fields, upsert valid ones, cleanup unlisted fields
|
|
28
|
-
def process_dynamic_fields(dynamic_fields_attributes)
|
|
29
|
-
sent_keys = []
|
|
30
|
-
|
|
31
|
-
dynamic_fields_attributes.each do |raw_attributes|
|
|
32
|
-
attributes = raw_attributes.to_h.symbolize_keys
|
|
33
|
-
should_destroy = ActiveModel::Type::Boolean.new.cast(attributes[:_destroy])
|
|
34
|
-
|
|
35
|
-
if should_destroy
|
|
36
|
-
destroy_guest_dynamic_field(attributes[:id])
|
|
37
|
-
elsif attributes[:id].blank? || guest.guest_dynamic_fields.exists?(attributes[:id])
|
|
38
|
-
field = upsert_guest_dynamic_field(attributes)
|
|
39
|
-
sent_keys << field_key(field)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Auto-cleanup: delete existing fields not in current submission
|
|
44
|
-
guest.guest_dynamic_fields.includes(:dynamic_field).find_each do |field|
|
|
45
|
-
field.destroy! unless sent_keys.include?(field_key(field))
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def field_key(field)
|
|
50
|
-
if field.dynamic_field.requires_dynamic_field_options?
|
|
51
|
-
[field.dynamic_field_id, field.dynamic_field_option_id]
|
|
52
|
-
else
|
|
53
|
-
[field.dynamic_field_id]
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Creates/updates field with validation: prevents dynamic_field_id changes, loads associations, sets options
|
|
58
|
-
def upsert_guest_dynamic_field(attributes)
|
|
59
|
-
field = find_or_initialize_guest_dynamic_field(attributes)
|
|
60
|
-
|
|
61
|
-
if attributes[:id].present? && attributes[:dynamic_field_id].present? && field.dynamic_field_id.to_i != attributes[:dynamic_field_id].to_i
|
|
62
|
-
field.errors.add(:base, "Cannot change dynamic_field_id for existing GuestDynamicField (ID: #{attributes[:id]})")
|
|
63
|
-
raise ActiveRecord::RecordInvalid, field
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
if attributes[:dynamic_field_id].present? && field.dynamic_field.blank?
|
|
67
|
-
field.dynamic_field = SpreeCmCommissioner::DynamicField.find_by(id: attributes[:dynamic_field_id])
|
|
68
|
-
unless field.dynamic_field
|
|
69
|
-
field.errors.add(:dynamic_field, 'not found')
|
|
70
|
-
raise ActiveRecord::RecordInvalid, field
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
field.assign_attributes(attributes.except(:id, :_destroy, :dynamic_field_option_id))
|
|
75
|
-
|
|
76
|
-
field.dynamic_field_option_id = attributes[:dynamic_field_option_id].to_i if attributes[:dynamic_field_option_id].present?
|
|
77
|
-
|
|
78
|
-
associate_dynamic_field_option(field) if field.dynamic_field&.requires_dynamic_field_options?
|
|
79
|
-
|
|
80
|
-
field.save!
|
|
81
|
-
field
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Finds and associates option by ID or value, sets field value if empty
|
|
85
|
-
def associate_dynamic_field_option(field)
|
|
86
|
-
return unless field.dynamic_field&.requires_dynamic_field_options?
|
|
87
|
-
|
|
88
|
-
option_id = field.dynamic_field_option_id.presence || field.value
|
|
89
|
-
|
|
90
|
-
option_lookup_id = option_id.to_s.match?(/\A\d+\z/) ? option_id.to_i : option_id
|
|
91
|
-
|
|
92
|
-
option = if option_lookup_id.is_a?(Integer)
|
|
93
|
-
field.dynamic_field.dynamic_field_options.find_by(id: option_lookup_id)
|
|
94
|
-
else
|
|
95
|
-
field.dynamic_field.dynamic_field_options.find_by(value: option_lookup_id)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
raise ActiveRecord::RecordNotFound, 'Option not found' unless option
|
|
99
|
-
|
|
100
|
-
field.dynamic_field_option = option
|
|
101
|
-
field.value = option.value if field.value.blank?
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def find_or_initialize_guest_dynamic_field(attributes)
|
|
105
|
-
if attributes[:id].present?
|
|
106
|
-
guest.guest_dynamic_fields.find(attributes[:id])
|
|
107
|
-
|
|
108
|
-
elsif attributes[:dynamic_field_option_id].present?
|
|
109
|
-
guest.guest_dynamic_fields.find_by(
|
|
110
|
-
dynamic_field_id: attributes[:dynamic_field_id],
|
|
111
|
-
dynamic_field_option_id: attributes[:dynamic_field_option_id]
|
|
112
|
-
) || guest.guest_dynamic_fields.build
|
|
113
|
-
|
|
114
|
-
else
|
|
115
|
-
guest.guest_dynamic_fields.find_by(
|
|
116
|
-
dynamic_field_id: attributes[:dynamic_field_id],
|
|
117
|
-
dynamic_field_option_id: nil
|
|
118
|
-
) || guest.guest_dynamic_fields.build
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def destroy_guest_dynamic_field(id)
|
|
123
|
-
return if id.blank?
|
|
124
|
-
|
|
125
|
-
field = guest.guest_dynamic_fields.find_by(id: id)
|
|
126
|
-
field&.destroy!
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module Users
|
|
3
|
-
class IncompleteGuestCheckerService
|
|
4
|
-
attr_reader :user
|
|
5
|
-
|
|
6
|
-
def initialize(user)
|
|
7
|
-
@user = user
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def call
|
|
11
|
-
return if user.blank? || incomplete_guest_info?
|
|
12
|
-
|
|
13
|
-
user.public_metadata['has_incomplete_guest_info'] = false
|
|
14
|
-
user.save!
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
def incomplete_guest_info?
|
|
20
|
-
guests =
|
|
21
|
-
SpreeCmCommissioner::Guest
|
|
22
|
-
.joins(line_item: :order)
|
|
23
|
-
.includes(:guest_dynamic_fields, line_item: { product: :dynamic_fields })
|
|
24
|
-
.where(spree_orders: { user_id: user.id, state: 'complete' })
|
|
25
|
-
|
|
26
|
-
guests.any? do |guest|
|
|
27
|
-
guest.pre_registration_completed? &&
|
|
28
|
-
guest.post_registration_fields? &&
|
|
29
|
-
!guest.post_registration_completed?
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|