spree_cm_commissioner 2.9.3.pre.pre1 → 2.9.5
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/concerns/spree_cm_commissioner/turnstile_protectable.rb +9 -7
- data/app/controllers/spree/api/chatrace/guests_controller.rb +1 -1
- data/app/controllers/spree/api/v2/operator/event_charts_controller.rb +1 -0
- data/app/controllers/spree/api/v2/operator/guest_json_gzips_controller.rb +14 -4
- 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/account_checker_controller.rb +4 -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/orders_controller.rb +1 -1
- data/app/controllers/spree/api/v2/tenant/account/saved_guests_controller.rb +70 -0
- data/app/controllers/spree/api/v2/tenant/guests_controller.rb +11 -21
- data/app/controllers/spree/api/v2/tenant/my_votes_controller.rb +51 -0
- data/app/controllers/spree/api/v2/tenant/order_histories_controller.rb +0 -1
- data/app/controllers/spree/api/v2/tenant/show_people_controller.rb +1 -4
- data/app/controllers/spree/api/v2/tenant/show_person_assignments_controller.rb +4 -1
- data/app/controllers/spree/api/v2/tenant/voting_contestants_controller.rb +6 -2
- data/app/controllers/spree_cm_commissioner/api/v2/storefront/checkout_controller_decorator.rb +3 -14
- data/app/interactors/spree_cm_commissioner/host_matcher.rb +6 -5
- data/app/interactors/spree_cm_commissioner/turnstile_token_validator.rb +43 -13
- 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_qr_codeable.rb +39 -0
- data/app/models/concerns/spree_cm_commissioner/order_scopes.rb +5 -0
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +13 -31
- data/app/models/spree_cm_commissioner/check_in_session.rb +36 -0
- 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/exports/operator_guest_json_gzip.rb +26 -1
- data/app/models/spree_cm_commissioner/guest.rb +5 -144
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +43 -71
- data/app/models/spree_cm_commissioner/maintenance_tasks/event.rb +9 -1
- data/app/models/spree_cm_commissioner/maintenance_tasks/guest_data_fill_stage.rb +21 -0
- data/app/models/spree_cm_commissioner/order_decorator.rb +22 -31
- 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/role_decorator.rb +41 -4
- data/app/models/spree_cm_commissioner/role_user_decorator.rb +11 -0
- data/app/models/spree_cm_commissioner/show_person.rb +5 -1
- data/app/models/spree_cm_commissioner/show_person_assignment.rb +1 -1
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +2 -0
- data/app/models/spree_cm_commissioner/tenant.rb +17 -6
- data/app/models/spree_cm_commissioner/user_decorator.rb +58 -1
- data/app/models/spree_cm_commissioner/voting_contestant.rb +2 -0
- data/app/queries/spree_cm_commissioner/event_chart_queries.rb +25 -9
- data/app/queries/spree_cm_commissioner/guest_searcher_query.rb +16 -3
- data/app/queries/spree_cm_commissioner/pie_chart_event_aggregator_queries.rb +3 -2
- data/app/queries/spree_cm_commissioner/user_votes_per_contestant_query.rb +48 -0
- 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/my_vote_serializer.rb +19 -0
- data/app/serializers/spree/v2/tenant/saved_guest_serializer.rb +23 -0
- data/app/serializers/spree/v2/tenant/show_serializer.rb +2 -1
- data/app/serializers/spree/v2/tenant/voting_contestant_serializer.rb +2 -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/check_ins/create_bulk.rb +10 -6
- 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/imports/contestants/create.rb +19 -1
- 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/operator_guest_json_gzips/create.rb +14 -7
- data/app/services/spree_cm_commissioner/order/guests/update.rb +5 -8
- data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +12 -11
- data/app/services/spree_cm_commissioner/show_contestants/normalize_video_highlights.rb +5 -1
- data/app/views/spree/admin/tenants/_form.html.erb +13 -1
- data/config/initializers/spree_permitted_attributes.rb +19 -0
- data/config/locales/en.yml +12 -12
- data/config/locales/km.yml +12 -4
- data/config/routes.rb +4 -1
- data/db/migrate/20260714002626_rename_data_fill_stage_phase_on_cm_guests.rb +5 -0
- data/db/migrate/20260720000001_add_check_in_fields_to_spree_roles.rb +11 -0
- data/db/migrate/20260723000000_add_payment_host_to_cm_tenants.rb +6 -0
- data/db/migrate/20260723000001_add_metadata_to_spree_roles.rb +11 -0
- data/db/migrate/20260728074153_add_role_to_cm_exports.rb +5 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vehicle_factory.rb +1 -1
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/tasks/recompute_guest_data_fill_stage.rake +19 -0
- metadata +26 -14
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8b5fced09e0795a88c5dfc1cd5ef84584dc557c0c8f0c26f0c1ed8f0c62f5b9a
|
|
4
|
+
data.tar.gz: 612e81f2f3b4f7e15e6481c9910523fabc9fed36c9b8b265c83bd9fa1834b826
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 460533fe4a445145c9edd9e4c0fa1c9fa4c4fc6153105f0dea7e9cf2e873e423e6f967ba734931b5206a9309706a40d92c0a0a13b93d3c59bc57d65fc8be023f
|
|
7
|
+
data.tar.gz: 5f11f494bc107000bd15cf51a6ba29f43c64436f8803257f793488fce84f8d4549c15057f2c5b169460cc601a9fd5cea86bf5ec044999467fe013f9a5c6e5778
|
data/Gemfile.lock
CHANGED
|
@@ -10,37 +10,30 @@ module SpreeCmCommissioner
|
|
|
10
10
|
raise NotImplementedError, "#{self.class} must implement #load_test_tenant"
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
# covering realistic load-test pool sizes.
|
|
15
|
-
EXPORT_SCAN_LIMIT = 2000
|
|
16
|
-
|
|
17
|
-
DEFAULT_EXPORT_PER_PAGE = 20
|
|
13
|
+
DEFAULT_EXPORT_PER_PAGE = 10
|
|
18
14
|
|
|
19
15
|
# Queried fresh from the DB every time, so it's always in sync with the current pool rather than
|
|
20
16
|
# a stashed file or session state.
|
|
21
17
|
#
|
|
22
|
-
# `load_test_account`
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
# correctly regardless of that storage quirk.
|
|
18
|
+
# Filters the `load_test_account` flag in SQL via the model's `load_test_accounts` scope (see
|
|
19
|
+
# UserDecorator), so only the tenant's load-test accounts are considered — never the whole users
|
|
20
|
+
# table. Unlike the old `order(:id).limit(2000).select(&:...)` approach, there's no scan cap:
|
|
21
|
+
# newly created accounts (highest ids, ordered first below) always show up even on tenants with
|
|
22
|
+
# far more than 2,000 users.
|
|
28
23
|
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
# instead of hand-rolled pagination just for this one page.
|
|
24
|
+
# Kaminari pages on the relation itself, so the DB only ever loads the current page's rows
|
|
25
|
+
# (`LIMIT`/`OFFSET`) — never the full pool into memory — via the same `page`/`per_page` params
|
|
26
|
+
# and `paginate` view helper every other index page in this app uses.
|
|
33
27
|
#
|
|
34
28
|
# Shared between LoadTestAccountManagement (lists/mutates the pool) and
|
|
35
29
|
# LoadTestLoginTokenGeneration (mints tokens for exactly the page shown), so both controllers
|
|
36
30
|
# resolve the same page the same way.
|
|
37
31
|
def export_accounts
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Kaminari.paginate_array(matches).page(params[:page]).per(params[:per_page] || DEFAULT_EXPORT_PER_PAGE)
|
|
32
|
+
Spree::User.where(tenant_id: load_test_tenant&.id)
|
|
33
|
+
.load_test_accounts
|
|
34
|
+
.order(id: :desc)
|
|
35
|
+
.page(params[:page])
|
|
36
|
+
.per(params[:per_page] || DEFAULT_EXPORT_PER_PAGE)
|
|
44
37
|
end
|
|
45
38
|
end
|
|
46
39
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
# Sets Current.load_test_bypass when the request carries the correct X-Request-Verify secret, so
|
|
3
|
+
# anti-abuse services (e.g. InventoryHolds::ValidateLimits) can skip their checks for trusted
|
|
4
|
+
# load tests. No-op unless LOAD_TEST_BYPASS_KEY is set. Include in any controller that can
|
|
5
|
+
# trigger such a check.
|
|
6
|
+
module LoadTestBypassable
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
before_action :set_load_test_bypass_current
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
# Always assigns the flag (false unless the request carries the correct
|
|
16
|
+
# secret), so its value never leaks from a previous request.
|
|
17
|
+
def set_load_test_bypass_current
|
|
18
|
+
SpreeCmCommissioner::Current.load_test_bypass = load_test_bypass_requested?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load_test_bypass_requested?
|
|
22
|
+
key = ENV.fetch('LOAD_TEST_BYPASS_KEY', nil)
|
|
23
|
+
return false if key.blank?
|
|
24
|
+
|
|
25
|
+
provided = request.headers.fetch('X-Request-Verify', nil).to_s
|
|
26
|
+
ActiveSupport::SecurityUtils.secure_compare(provided, key)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -27,13 +27,15 @@ module SpreeCmCommissioner
|
|
|
27
27
|
return unless result.failure?
|
|
28
28
|
|
|
29
29
|
render json: {
|
|
30
|
-
errors: [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
errors: [
|
|
31
|
+
{
|
|
32
|
+
status: '403',
|
|
33
|
+
error_code: 'human_verification_failed',
|
|
34
|
+
title: I18n.t('turnstile.verification_failed'),
|
|
35
|
+
detail: result.message,
|
|
36
|
+
turnstile_error_code: result.respond_to?(:error_code) ? result.error_code : nil
|
|
37
|
+
}
|
|
38
|
+
]
|
|
37
39
|
}, status: :forbidden
|
|
38
40
|
end
|
|
39
41
|
|
|
@@ -53,7 +53,7 @@ module Spree
|
|
|
53
53
|
preferences upload_later social_contact_platform user_id
|
|
54
54
|
bib_number bib_prefix bib_index public_metadata private_metadata
|
|
55
55
|
seat_number intel_phone_number block_id saved_guest_id
|
|
56
|
-
|
|
56
|
+
data_fill_stage
|
|
57
57
|
].freeze
|
|
58
58
|
|
|
59
59
|
def guest_base_columns
|
|
@@ -26,6 +26,8 @@ module Spree
|
|
|
26
26
|
|
|
27
27
|
result = SpreeCmCommissioner::OperatorGuestJsonGzips::Create.call(
|
|
28
28
|
exportable: exportable,
|
|
29
|
+
# Scope the offline file to the requesting operator's check-in role (nil = unrestricted).
|
|
30
|
+
role: spree_current_user.check_in_role_for(exportable),
|
|
29
31
|
force_create: false,
|
|
30
32
|
options: {
|
|
31
33
|
created_by_id: spree_current_user.id.to_s,
|
|
@@ -53,11 +55,19 @@ module Spree
|
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
# override
|
|
58
|
+
# Scope the list to the requesting operator's check-in group, the same way the create cache
|
|
59
|
+
# does — otherwise a restricted crew could list (and download via exported_file_url) other
|
|
60
|
+
# groups' files for the event.
|
|
56
61
|
def scope
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
exportable = Spree::Taxon.find(params[:taxon_id])
|
|
63
|
+
|
|
64
|
+
SpreeCmCommissioner::Exports::OperatorGuestJsonGzip
|
|
65
|
+
.where(
|
|
66
|
+
exportable_type: 'Spree::Taxon',
|
|
67
|
+
exportable_id: params[:taxon_id],
|
|
68
|
+
role_id: spree_current_user.check_in_role_for(exportable)&.id
|
|
69
|
+
)
|
|
70
|
+
.order(created_at: :desc)
|
|
61
71
|
end
|
|
62
72
|
|
|
63
73
|
# override
|
|
@@ -4,69 +4,40 @@ module Spree
|
|
|
4
4
|
module Storefront
|
|
5
5
|
module Account
|
|
6
6
|
class GuestDynamicFieldsController < ::Spree::Api::V2::ResourceController
|
|
7
|
+
ALLOWED_PHASES = %w[pre_registration post_registration].freeze
|
|
8
|
+
|
|
7
9
|
before_action :require_spree_current_user
|
|
8
10
|
before_action :load_guest
|
|
9
11
|
|
|
10
12
|
def update_dynamic_field
|
|
11
|
-
phase
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
process_dynamic_field(field)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
@guest.save_and_move_to_next_stage
|
|
13
|
+
return render_error_payload('Invalid phase') unless ALLOWED_PHASES.include?(params[:phase])
|
|
14
|
+
return render_error_payload('No dynamic fields provided') if dynamic_fields_params.blank?
|
|
15
|
+
|
|
16
|
+
result = SpreeCmCommissioner::Guests::Update.call(
|
|
17
|
+
guest: @guest,
|
|
18
|
+
guest_params: {
|
|
19
|
+
guest_dynamic_fields_attributes: dynamic_fields_params.map { |f| { dynamic_field_id: f[:id], value: f[:value] } }
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
if result.success?
|
|
24
|
+
render_serialized_payload { serialize_guest(result.value[:guest]) }
|
|
25
|
+
else
|
|
26
|
+
render_error_payload(result.error)
|
|
29
27
|
end
|
|
30
|
-
|
|
31
|
-
render_serialized_payload { serialize_guest(@guest) }
|
|
32
|
-
rescue ActiveRecord::RecordInvalid => e
|
|
33
|
-
render_error_payload(e.record.errors, 422)
|
|
34
|
-
rescue ActiveRecord::RecordNotFound => e
|
|
35
|
-
render_error_payload(e.message, 404)
|
|
36
28
|
end
|
|
37
29
|
|
|
38
30
|
private
|
|
39
31
|
|
|
40
32
|
def dynamic_fields_params
|
|
41
|
-
params
|
|
42
|
-
field.permit(:id, :value)
|
|
43
|
-
end
|
|
33
|
+
Array(params[:dynamic_fields]).map { |field| field.permit(:id, :value) }
|
|
44
34
|
end
|
|
45
35
|
|
|
46
36
|
def load_guest
|
|
47
37
|
@guest = SpreeCmCommissioner::Guest.find(params[:guest_id])
|
|
48
38
|
|
|
49
|
-
unless spree_current_user.guests.exists?(id: @guest.id) ||
|
|
50
|
-
|
|
51
|
-
render_error_payload('Unauthorized', 401)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def process_dynamic_field(field)
|
|
56
|
-
dynamic_field = SpreeCmCommissioner::DynamicField.find(field[:id])
|
|
57
|
-
guest_field = @guest.guest_dynamic_fields.build(dynamic_field_id: dynamic_field.id)
|
|
58
|
-
|
|
59
|
-
if dynamic_field.requires_dynamic_field_options?
|
|
60
|
-
option = dynamic_field.dynamic_field_options.find_by(value: field[:value])
|
|
61
|
-
raise ActiveRecord::RecordNotFound, "Invalid value for dynamic field #{dynamic_field.label}" unless option
|
|
62
|
-
|
|
63
|
-
guest_field.dynamic_field_option = option
|
|
64
|
-
guest_field.value = option.value
|
|
65
|
-
else
|
|
66
|
-
guest_field.value = field[:value]
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
guest_field.save!
|
|
39
|
+
raise CanCan::AccessDenied unless spree_current_user.guests.exists?(id: @guest.id) ||
|
|
40
|
+
@guest.line_item.order.user == spree_current_user
|
|
70
41
|
end
|
|
71
42
|
|
|
72
43
|
def serialize_guest(guest)
|
|
@@ -7,7 +7,7 @@ module Spree
|
|
|
7
7
|
before_action :require_spree_current_user
|
|
8
8
|
|
|
9
9
|
def update
|
|
10
|
-
|
|
10
|
+
spree_current_user.clear_has_incomplete_guest_info_cache
|
|
11
11
|
render_success
|
|
12
12
|
end
|
|
13
13
|
|
|
@@ -18,7 +18,7 @@ module Spree
|
|
|
18
18
|
{
|
|
19
19
|
success: true,
|
|
20
20
|
message: 'Guest information marked as complete',
|
|
21
|
-
has_incomplete_guest_info:
|
|
21
|
+
has_incomplete_guest_info: spree_current_user.has_incomplete_guest_info?
|
|
22
22
|
}
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -24,21 +24,11 @@ module Spree
|
|
|
24
24
|
private
|
|
25
25
|
|
|
26
26
|
def find_orders_with_incomplete_guest_info
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
order.line_items.any? do |line_item|
|
|
33
|
-
line_item.guests.any? do |guest|
|
|
34
|
-
guest.pre_registration_completed? &&
|
|
35
|
-
guest.post_registration_fields? &&
|
|
36
|
-
!guest.post_registration_completed?
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end.map(&:id)
|
|
40
|
-
|
|
41
|
-
spree_current_user.orders.where(id: incomplete_order_ids)
|
|
27
|
+
spree_current_user.orders
|
|
28
|
+
.complete
|
|
29
|
+
.joins(:guests)
|
|
30
|
+
.merge(SpreeCmCommissioner::Guest.post_registration)
|
|
31
|
+
.distinct
|
|
42
32
|
end
|
|
43
33
|
|
|
44
34
|
def collection_finder
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Storefront
|
|
5
|
+
module Account
|
|
6
|
+
class SavedGuestsController < ::Spree::Api::V2::ResourceController
|
|
7
|
+
before_action :require_spree_current_user
|
|
8
|
+
before_action :load_saved_guest, only: %i[show update destroy]
|
|
9
|
+
|
|
10
|
+
def collection
|
|
11
|
+
spree_current_user.saved_guests.order(created_at: :desc)
|
|
12
|
+
.page(params[:page])
|
|
13
|
+
.per(params[:per_page])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create
|
|
17
|
+
saved_guest = spree_current_user.saved_guests.new(saved_guest_params)
|
|
18
|
+
|
|
19
|
+
if saved_guest.save
|
|
20
|
+
render_serialized_payload(201) { serialize_resource(saved_guest) }
|
|
21
|
+
else
|
|
22
|
+
render_error_payload(saved_guest.errors.full_messages.to_sentence, 422)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def update
|
|
27
|
+
if @saved_guest.update(saved_guest_params)
|
|
28
|
+
render_serialized_payload { serialize_resource(@saved_guest) }
|
|
29
|
+
else
|
|
30
|
+
render_error_payload(@saved_guest.errors.full_messages.to_sentence, 422)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def destroy
|
|
35
|
+
@saved_guest.destroy
|
|
36
|
+
head :no_content
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def model_class
|
|
42
|
+
SpreeCmCommissioner::SavedGuest
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def collection_serializer
|
|
46
|
+
resource_serializer
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def resource_serializer
|
|
50
|
+
SpreeCmCommissioner::V2::Storefront::SavedGuestSerializer
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def load_saved_guest
|
|
54
|
+
@saved_guest = spree_current_user.saved_guests.find(params[:id])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def saved_guest_params
|
|
58
|
+
params.require(:saved_guest).permit(*::Spree::PermittedAttributes.saved_guest_attributes)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -3,6 +3,10 @@ module Spree
|
|
|
3
3
|
module V2
|
|
4
4
|
module Storefront
|
|
5
5
|
class AccountCheckerController < Spree::Api::V2::BaseController
|
|
6
|
+
include SpreeCmCommissioner::TurnstileProtectable
|
|
7
|
+
|
|
8
|
+
before_action :verify_turnstile!, only: :index
|
|
9
|
+
|
|
6
10
|
def index
|
|
7
11
|
checker = SpreeCmCommissioner::ExistingAccountChecker.call(filter_params.to_h)
|
|
8
12
|
|
|
@@ -3,6 +3,9 @@ module Spree
|
|
|
3
3
|
module V2
|
|
4
4
|
module Storefront
|
|
5
5
|
class DraftOrdersController < ::Spree::Api::V2::ResourceController
|
|
6
|
+
# Creating the order acquires the inventory hold, so honor the load-test bypass here too.
|
|
7
|
+
include SpreeCmCommissioner::LoadTestBypassable
|
|
8
|
+
|
|
6
9
|
# Creates a generic draft order from a locally-assembled cart in a single request.
|
|
7
10
|
# Endpoint: POST /api/v2/storefront/draft_orders
|
|
8
11
|
# Params:
|
|
@@ -31,26 +31,27 @@ module Spree
|
|
|
31
31
|
def create
|
|
32
32
|
spree_authorize! :update, spree_current_order, order_token
|
|
33
33
|
|
|
34
|
-
result = SpreeCmCommissioner::
|
|
34
|
+
result = SpreeCmCommissioner::Guests::Create.call(
|
|
35
35
|
line_item: parent,
|
|
36
|
-
|
|
36
|
+
guest_params: guest_params
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
if result.success?
|
|
40
|
-
render_serialized_payload(201) { serialize_resource(result.value) }
|
|
40
|
+
render_serialized_payload(201) { serialize_resource(result.value[:guest]) }
|
|
41
41
|
else
|
|
42
|
-
render_error_payload(result.value.errors, 422)
|
|
42
|
+
render_error_payload(result.error || result.value.errors, 422)
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def update
|
|
47
47
|
spree_authorize! :update, spree_current_order, order_token unless guest_for_update.pre_registration?
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
result = SpreeCmCommissioner::Guests::Update.call(guest: guest_for_update, guest_params: guest_params)
|
|
50
|
+
|
|
51
|
+
if result.success?
|
|
52
|
+
render_serialized_payload { serialize_resource(result.value[:guest]) }
|
|
53
|
+
else
|
|
54
|
+
render_error_payload(result.error || result.value&.errors, 422)
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
|
|
@@ -18,7 +18,6 @@ module Spree
|
|
|
18
18
|
order = Spree::Order.not_archived.find_by!(token: order_token)
|
|
19
19
|
|
|
20
20
|
spree_authorize! :update, order, order_token
|
|
21
|
-
raise CanCan::AccessDenied unless order.payment?
|
|
22
21
|
|
|
23
22
|
if order.mark_as_archive
|
|
24
23
|
render_serialized_payload { serialize_resource(order) }
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
module Account
|
|
6
|
+
class SavedGuestsController < BaseController
|
|
7
|
+
around_action :wrap_with_multitenant_without
|
|
8
|
+
before_action :require_spree_current_user
|
|
9
|
+
before_action :load_saved_guest, only: %i[show update destroy]
|
|
10
|
+
|
|
11
|
+
def collection
|
|
12
|
+
spree_current_user.saved_guests.order(created_at: :desc)
|
|
13
|
+
.page(params[:page])
|
|
14
|
+
.per(params[:per_page])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create
|
|
18
|
+
saved_guest = spree_current_user.saved_guests.new(saved_guest_params)
|
|
19
|
+
|
|
20
|
+
if saved_guest.save
|
|
21
|
+
render_serialized_payload(201) { serialize_resource(saved_guest) }
|
|
22
|
+
else
|
|
23
|
+
render_error_payload(saved_guest.errors.full_messages.to_sentence, 422)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def update
|
|
28
|
+
if @saved_guest.update(saved_guest_params)
|
|
29
|
+
render_serialized_payload { serialize_resource(@saved_guest) }
|
|
30
|
+
else
|
|
31
|
+
render_error_payload(@saved_guest.errors.full_messages.to_sentence, 422)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def destroy
|
|
36
|
+
@saved_guest.destroy
|
|
37
|
+
head :no_content
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def wrap_with_multitenant_without(&block)
|
|
43
|
+
MultiTenant.without(&block)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def model_class
|
|
47
|
+
SpreeCmCommissioner::SavedGuest
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def collection_serializer
|
|
51
|
+
resource_serializer
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def resource_serializer
|
|
55
|
+
Spree::V2::Tenant::SavedGuestSerializer
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def load_saved_guest
|
|
59
|
+
@saved_guest = spree_current_user.saved_guests.find(params[:id])
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def saved_guest_params
|
|
63
|
+
params.require(:saved_guest).permit(*::Spree::PermittedAttributes.saved_guest_attributes)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -30,28 +30,25 @@ module Spree
|
|
|
30
30
|
def create
|
|
31
31
|
spree_authorize! :update, spree_current_order, order_token
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
result = SpreeCmCommissioner::Guests::Create.call(line_item: parent, guest_params: guest_params)
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
if result.success?
|
|
36
|
+
render_serialized_payload(201) { serialize_resource(result.value[:guest]) }
|
|
37
|
+
else
|
|
38
|
+
render_error_payload(result.error || result.value&.errors, 422)
|
|
39
39
|
end
|
|
40
|
-
|
|
41
|
-
render_serialized_payload(201) { serialize_resource(resource) }
|
|
42
40
|
end
|
|
43
41
|
|
|
44
42
|
def update
|
|
45
43
|
spree_authorize! :update, spree_current_order, order_token
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
run_dynamic_fields(resource) if guest_params[:guest_dynamic_fields_attributes]
|
|
49
|
-
resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
|
|
50
|
-
resource.save!
|
|
51
|
-
resource.save_and_move_to_next_stage
|
|
52
|
-
end
|
|
45
|
+
result = SpreeCmCommissioner::Guests::Update.call(guest: resource, guest_params: guest_params)
|
|
53
46
|
|
|
54
|
-
|
|
47
|
+
if result.success?
|
|
48
|
+
render_serialized_payload { serialize_resource(result.value[:guest]) }
|
|
49
|
+
else
|
|
50
|
+
render_error_payload(result.error || result.value&.errors, 422)
|
|
51
|
+
end
|
|
55
52
|
end
|
|
56
53
|
|
|
57
54
|
private
|
|
@@ -99,13 +96,6 @@ module Spree
|
|
|
99
96
|
)
|
|
100
97
|
end
|
|
101
98
|
|
|
102
|
-
def run_dynamic_fields(resource)
|
|
103
|
-
SpreeCmCommissioner::GuestDynamicFieldsManager.call(
|
|
104
|
-
resource: resource,
|
|
105
|
-
dynamic_fields_attributes: guest_params[:guest_dynamic_fields_attributes]
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
99
|
def handle_record_invalid(exception)
|
|
110
100
|
render_error_payload(exception.record.errors, 422)
|
|
111
101
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
# Returns the session's contestants each annotated with the current
|
|
6
|
+
# user's own vote tally (my_vote_count).
|
|
7
|
+
#
|
|
8
|
+
# Kept separate from the public VotingContestantsController — that
|
|
9
|
+
# endpoint does not require an authenticated user and is cacheable,
|
|
10
|
+
# whereas this one is strictly per-user and must never be cached.
|
|
11
|
+
class MyVotesController < BaseController
|
|
12
|
+
before_action :require_spree_current_user
|
|
13
|
+
before_action :load_voting_session
|
|
14
|
+
|
|
15
|
+
def show
|
|
16
|
+
render_serialized_payload do
|
|
17
|
+
serialize_collection(collection)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def collection
|
|
24
|
+
@collection ||= SpreeCmCommissioner::UserVotesPerContestantQuery.new(
|
|
25
|
+
user: spree_current_user,
|
|
26
|
+
voting_session: @voting_session
|
|
27
|
+
).contestants
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def load_voting_session
|
|
31
|
+
@voting_session = current_vendor.voting_sessions.find(params[:voting_session_id])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Overrided: skip collection_options (pagination/links) — this is a
|
|
35
|
+
# bounded per-session collection, not a paginated one.
|
|
36
|
+
def serialize_collection(collection)
|
|
37
|
+
collection_serializer.new(collection).serializable_hash
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def collection_serializer
|
|
41
|
+
Spree::V2::Tenant::MyVoteSerializer
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def model_class
|
|
45
|
+
SpreeCmCommissioner::VotingContestant
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -21,7 +21,6 @@ module Spree
|
|
|
21
21
|
order = Spree::Order.not_archived.find_by!(token: order_token)
|
|
22
22
|
|
|
23
23
|
spree_authorize! :update, order, order_token
|
|
24
|
-
raise CanCan::AccessDenied unless order.payment?
|
|
25
24
|
|
|
26
25
|
if order.mark_as_archive
|
|
27
26
|
render_serialized_payload { serialize_resource(order) }
|