spree_cm_commissioner 2.9.2 → 2.9.3.pre.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/api/v2/tenant/episodes_controller.rb +3 -1
- data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +7 -1
- data/app/models/spree_cm_commissioner/voting_contestant.rb +13 -2
- data/app/services/spree_cm_commissioner/load_test/generate_booking_ticket_data.rb +83 -19
- 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/load_test_flows/tenant.yml +47 -0
- data/config/locales/en.yml +2 -0
- data/config/locales/km.yml +2 -0
- data/db/migrate/20260713022227_add_advanced_to_episode_id_to_cm_voting_contestants.rb +8 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0cde283f01b472fecef2447fa4f2ecfbd2e89126a5c0100f6eb0da02d8470a81
|
|
4
|
+
data.tar.gz: 115e564d261168faef7c209fc743b7f57ef2914afbfaac75de7668d1d1579865
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61475e20da1c597866e2a2bf80d05ec60cbb5b26082c8103f002abde91d129738eb7d483c0955d66c0b1045d689ac4f68430888905ef638ddea162cf48d847b8
|
|
7
|
+
data.tar.gz: 659074571ef7ae8f01b2fe5737a4f569edb7986bd7d33bbb6e99342956bc211c6d0c85894feb5e4511557b22670711874d8316bcdc5f9deac5ffc63d446bc1c6
|
data/Gemfile.lock
CHANGED
|
@@ -14,7 +14,9 @@ module Spree
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def scope
|
|
17
|
-
current_season.episodes
|
|
17
|
+
current_season.episodes
|
|
18
|
+
.where(product_type: :show_episode, status: :active)
|
|
19
|
+
.includes(:voting_sessions, :vote_packages)
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def current_season
|
|
@@ -58,8 +58,14 @@ module SpreeCmCommissioner
|
|
|
58
58
|
|
|
59
59
|
# Builds the load-test fixture for this variant so it can be used by the k6 booking flow.
|
|
60
60
|
# Shown on a page (with a check for whether the variant can be booked) for the tester to
|
|
61
|
-
# copy into the load_testing config.
|
|
61
|
+
# copy into the load_testing config. A product with a tenant_id belongs to a tenant
|
|
62
|
+
# (SaaS-hosted) store rather than the platform — the two k6 workflows keep separate fixture
|
|
63
|
+
# folders (load_testing/config/fixture/platform/booking_ticket_flow/ vs
|
|
64
|
+
# load_testing/config/fixture/tenant/cash_on_booking_ticket_flow/ — the tenant flow is named
|
|
65
|
+
# cash_on_* since it has an ABA sibling; the platform flow doesn't).
|
|
62
66
|
def fixture
|
|
67
|
+
@fixture_workflow = @variant.product.tenant_id.present? ? 'tenant' : 'platform'
|
|
68
|
+
@fixture_flow = @fixture_workflow == 'tenant' ? 'cash_on_booking_ticket_flow' : 'booking_ticket_flow'
|
|
63
69
|
result = SpreeCmCommissioner::LoadTest::GenerateBookingTicketData.call(variant: @variant)
|
|
64
70
|
@fixture = result.value[:data]
|
|
65
71
|
@fixture_issues = result.value[:issues]
|
|
@@ -5,6 +5,7 @@ module SpreeCmCommissioner
|
|
|
5
5
|
belongs_to :show, class_name: 'Spree::Taxon', optional: false
|
|
6
6
|
belongs_to :voting_session, class_name: 'SpreeCmCommissioner::VotingSession', optional: false
|
|
7
7
|
belongs_to :show_contestant, class_name: 'SpreeCmCommissioner::ShowContestant', optional: false
|
|
8
|
+
belongs_to :advanced_to_episode, class_name: 'SpreeCmCommissioner::ShowEpisode', optional: true
|
|
8
9
|
belongs_to :advanced_to, polymorphic: true, optional: true
|
|
9
10
|
belongs_to :advanced_from, polymorphic: true, optional: true
|
|
10
11
|
has_many :votes, class_name: 'SpreeCmCommissioner::Vote', foreign_key: :contestant_id, dependent: :restrict_with_error
|
|
@@ -37,6 +38,7 @@ module SpreeCmCommissioner
|
|
|
37
38
|
# | 1 | 1 | 2 | ✓ OK | Can update/change number |
|
|
38
39
|
# | 1 | 2 | 1 | ✓ OK | Different session |
|
|
39
40
|
validates :vote_number, uniqueness: { scope: :voting_session_id, allow_nil: true }
|
|
41
|
+
validate :advanced_to_and_advanced_from_must_differ
|
|
40
42
|
|
|
41
43
|
delegate :name, :contestant_number, :category, :gender, :eliminated_at, to: :show_contestant, allow_nil: true
|
|
42
44
|
delegate :can_vote?, to: :voting_session, allow_nil: true
|
|
@@ -50,11 +52,11 @@ module SpreeCmCommissioner
|
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
def advanced_from_name
|
|
53
|
-
advanced_from&.name
|
|
55
|
+
[advanced_from&.episode&.name, advanced_from&.name].compact.join(' - ')
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def advanced_to_name
|
|
57
|
-
advanced_to&.name
|
|
59
|
+
[advanced_to&.episode&.name || advanced_to_episode&.name, advanced_to&.name].compact.join(' - ')
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
private
|
|
@@ -97,5 +99,14 @@ module SpreeCmCommissioner
|
|
|
97
99
|
errors.add(:base, :has_advanced_to_session)
|
|
98
100
|
throw :abort
|
|
99
101
|
end
|
|
102
|
+
|
|
103
|
+
# Prevent a contestant from being advanced to the same record it was advanced from,
|
|
104
|
+
# which would create a self-referencing loop between sessions.
|
|
105
|
+
def advanced_to_and_advanced_from_must_differ
|
|
106
|
+
return if advanced_to_id.blank? || advanced_from_id.blank?
|
|
107
|
+
return unless advanced_to_type == advanced_from_type && advanced_to_id == advanced_from_id
|
|
108
|
+
|
|
109
|
+
errors.add(:advanced_to_id, :same_as_advanced_from)
|
|
110
|
+
end
|
|
100
111
|
end
|
|
101
112
|
end
|
|
@@ -1,22 +1,43 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
module LoadTest
|
|
3
|
-
# Generates the
|
|
4
|
-
# k6 booking flow. An admin picks a ticket variant in the
|
|
5
|
-
# product / variant / event straight off the models and returns the
|
|
6
|
-
# plus a "can this actually be booked?" check so the tester knows it
|
|
3
|
+
# Generates the cash_on_booking_ticket_flow / aba_booking_ticket_flow load-test data for one variant
|
|
4
|
+
# so it can be used by the k6 booking flow. An admin/organizer picks a ticket variant in the
|
|
5
|
+
# dashboard; this reads its product / variant / event straight off the models and returns the
|
|
6
|
+
# payload the flow needs, plus a "can this actually be booked?" check so the tester knows it
|
|
7
|
+
# will drive the flow. Mirrors GenerateVotingFixtureData's cash-on/ABA payment resolution
|
|
8
|
+
# (gems/spree_cm_commissioner/app/services/spree_cm_commissioner/load_test/
|
|
9
|
+
# generate_voting_fixture_data.rb) for the same two payment methods, applied to a variant
|
|
10
|
+
# instead of a voting session.
|
|
7
11
|
#
|
|
8
|
-
# Flow: pick a ticket variant in admin -> copy this payload into
|
|
9
|
-
# load_testing/config/fixture
|
|
10
|
-
# that file when running k6
|
|
12
|
+
# Flow: pick a ticket variant in admin/organizer -> copy this payload into
|
|
13
|
+
# load_testing/config/fixture/<platform|tenant>/<flow>/<env>.json -> Env.fixture()/
|
|
14
|
+
# Env.optionalFixture() reads that file when running k6. Note: the k6 flows themselves still
|
|
15
|
+
# read the actual payment_method_id/payway config from env vars (TENANT_PAYMENT_METHOD_ID,
|
|
16
|
+
# TENANT_PAYWAY_*), not from this JSON — payment_method_id/payway are included here purely so
|
|
17
|
+
# whoever generates the fixture can see (and copy) what's actually configured, same as
|
|
18
|
+
# GenerateVotingFixtureData's topup flows.
|
|
11
19
|
#
|
|
12
|
-
# Returns success({ data: {...}, issues: [...] }). `issues` is empty when the variant
|
|
13
|
-
#
|
|
14
|
-
# `issues` (plus a `ready` flag) are
|
|
15
|
-
# the copied JSON — the k6 flow ignores
|
|
20
|
+
# Returns success({ data: {...}, issues: [...] }). `issues` is empty when the variant is ready
|
|
21
|
+
# to load-test; otherwise it lists why the booking flow would fail — including "no payment
|
|
22
|
+
# method configured" for whichever flow you asked for. `issues` (plus a `ready` flag) are
|
|
23
|
+
# duplicated into `data[:metadata]` so they travel with the copied JSON — the k6 flow ignores
|
|
24
|
+
# that key, it's there for a human to read later.
|
|
16
25
|
class GenerateBookingTicketData
|
|
17
26
|
prepend ::Spree::ServiceModule::Base
|
|
18
27
|
|
|
19
|
-
|
|
28
|
+
FLOWS = %w[cash_on_booking_ticket_flow aba_booking_ticket_flow].freeze
|
|
29
|
+
|
|
30
|
+
# ABA's checkout endpoint is fixed regardless of tenant/environment — only `host` (sandbox
|
|
31
|
+
# vs production) differs, and that comes off the payment method. See
|
|
32
|
+
# Vpago::PaywayV2::Checkout#checkout_url in gems/spree_vpago. Mirrors
|
|
33
|
+
# GenerateVotingFixtureData::PAYWAY_CHECKOUT_PATH.
|
|
34
|
+
PAYWAY_CHECKOUT_PATH = '/api/payment-gateway/v1/payments/purchase'.freeze
|
|
35
|
+
|
|
36
|
+
# flow: which payment method to resolve — 'cash_on_booking_ticket_flow' (the default) or
|
|
37
|
+
# 'aba_booking_ticket_flow' (ABA/PayWay v2, adds a `payway` block).
|
|
38
|
+
def call(variant:, flow: 'cash_on_booking_ticket_flow')
|
|
39
|
+
raise ArgumentError, "Unknown flow: #{flow.inspect} (expected one of: #{FLOWS.join(', ')})" unless FLOWS.include?(flow)
|
|
40
|
+
|
|
20
41
|
product = variant.product
|
|
21
42
|
event = product.event
|
|
22
43
|
issues = issues_for(variant, event)
|
|
@@ -25,15 +46,15 @@ module SpreeCmCommissioner
|
|
|
25
46
|
event_permalink: event&.permalink,
|
|
26
47
|
product_slug: product.slug,
|
|
27
48
|
product_id: product.id,
|
|
28
|
-
variant_id: variant.id
|
|
29
|
-
# Informational only — the k6 flow never reads this. Carries the readiness check into
|
|
30
|
-
# the copied JSON itself, so it's visible later without regenerating from admin.
|
|
31
|
-
metadata: {
|
|
32
|
-
ready: issues.empty?,
|
|
33
|
-
issues: issues
|
|
34
|
-
}
|
|
49
|
+
variant_id: variant.id
|
|
35
50
|
}
|
|
36
51
|
|
|
52
|
+
issues.concat(payment_method_issues(variant, flow, data))
|
|
53
|
+
|
|
54
|
+
# Informational only — the k6 flow never reads this. Carries the readiness check into
|
|
55
|
+
# the copied JSON itself, so it's visible later without regenerating from admin/organizer.
|
|
56
|
+
data[:metadata] = { ready: issues.empty?, issues: issues }
|
|
57
|
+
|
|
37
58
|
success(data: data, issues: issues)
|
|
38
59
|
rescue StandardError => e
|
|
39
60
|
failure(nil, e.message)
|
|
@@ -41,6 +62,49 @@ module SpreeCmCommissioner
|
|
|
41
62
|
|
|
42
63
|
private
|
|
43
64
|
|
|
65
|
+
# Resolves the payment method for `flow` into `data`, and (for ABA) its payway payload.
|
|
66
|
+
# Returns the readiness issues — "no payment method configured" is blocking, same as
|
|
67
|
+
# GenerateVotingFixtureData's topup_flow_issues.
|
|
68
|
+
def payment_method_issues(variant, flow, data)
|
|
69
|
+
payment_method = resolve_payment_method(variant.vendor, flow)
|
|
70
|
+
|
|
71
|
+
return ["No #{payment_method_label(flow)} payment method configured for this tenant."] if payment_method.nil?
|
|
72
|
+
|
|
73
|
+
data[:payment_method_id] = payment_method.id
|
|
74
|
+
return [] unless flow == 'aba_booking_ticket_flow'
|
|
75
|
+
|
|
76
|
+
data[:payway] = payway_payload(payment_method)
|
|
77
|
+
return [] if payment_method.preferred_host.to_s.match?(/sandbox/i)
|
|
78
|
+
|
|
79
|
+
[
|
|
80
|
+
"ABA payment method's host (#{payment_method.preferred_host.inspect}) doesn't look like a sandbox URL — " \
|
|
81
|
+
'load tests should run against ABA\'s sandbox, not production.'
|
|
82
|
+
]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def resolve_payment_method(vendor, flow)
|
|
86
|
+
type = flow == 'aba_booking_ticket_flow' ? Vpago::PaymentMethodDecorator::TYPE_PAYWAY_V2 : Vpago::PaymentMethodDecorator::TYPE_CASH_ON
|
|
87
|
+
|
|
88
|
+
Spree::PaymentMethod.active.where(vendor_id: vendor&.id, type: type).first
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def payment_method_label(flow)
|
|
92
|
+
flow == 'aba_booking_ticket_flow' ? 'ABA' : 'cash-on'
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def payway_payload(payment_method)
|
|
96
|
+
{
|
|
97
|
+
host: payment_method.preferred_host,
|
|
98
|
+
checkout_path: PAYWAY_CHECKOUT_PATH,
|
|
99
|
+
merchant_id: payment_method.preferred_merchant_id,
|
|
100
|
+
api_key: payment_method.preferred_api_key,
|
|
101
|
+
payment_option: payment_method.preferred_payment_option,
|
|
102
|
+
transaction_fee_fix: payment_method.preferred_transaction_fee_fix.to_f,
|
|
103
|
+
transaction_fee_percentage: payment_method.preferred_transaction_fee_percentage.to_f,
|
|
104
|
+
enable_pre_auth: payment_method.enable_pre_auth?
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
44
108
|
# Each check returns an explanatory string when it would break the booking flow, or nil when the
|
|
45
109
|
# variant is fine on that axis. Order mirrors the flow: availability first, then checkout shape.
|
|
46
110
|
def issues_for(variant, event)
|
|
@@ -63,9 +63,15 @@ module SpreeCmCommissioner
|
|
|
63
63
|
# --- Elimination ---------------------------------------------------------
|
|
64
64
|
|
|
65
65
|
def sync_elimination_status
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
|
|
66
|
+
# Episode-only advancement (no session mirror was ever created) — just
|
|
67
|
+
# drop the marker when eliminated; nothing to unwind.
|
|
68
|
+
# e.g. vc_a { advanced_to_id: nil, advanced_to_episode_id: 5, eliminated: true } → clear it
|
|
69
|
+
if @voting_contestant.advanced_to_id.blank?
|
|
70
|
+
if @voting_contestant.eliminated? && @voting_contestant.advanced_to_episode_id.present?
|
|
71
|
+
@voting_contestant.update!(advanced_to_episode_id: nil)
|
|
72
|
+
end
|
|
73
|
+
return
|
|
74
|
+
end
|
|
69
75
|
|
|
70
76
|
# Incomplete polymorphic ref — can't resolve a session without both parts.
|
|
71
77
|
# e.g. vc_a { advanced_to_type: nil } → return
|
|
@@ -203,6 +209,7 @@ module SpreeCmCommissioner
|
|
|
203
209
|
@voting_contestant.update!(
|
|
204
210
|
advanced_to_type: nil,
|
|
205
211
|
advanced_to_id: nil,
|
|
212
|
+
advanced_to_episode_id: nil,
|
|
206
213
|
updated_at: Time.current
|
|
207
214
|
)
|
|
208
215
|
end
|
|
@@ -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 |
|
|
33
|
-
|
|
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"
|
|
89
|
-
#
|
|
90
|
-
#
|
|
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 <
|
|
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:
|
|
104
|
-
|
|
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
|
|
30
|
+
<code>load_testing/config/fixture/<%= @fixture_workflow %>/<%= @fixture_flow %>/</code>
|
|
31
31
|
(git-ignored).
|
|
32
32
|
</p>
|
|
33
33
|
|
|
@@ -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
|
data/config/locales/en.yml
CHANGED
|
@@ -667,6 +667,8 @@ en:
|
|
|
667
667
|
advanced_from_session: 'was advanced from a previous session and cannot be removed directly. Clear the advancement in the source session instead.'
|
|
668
668
|
pre_vote_session: 'cannot be removed from a pre-vote session.'
|
|
669
669
|
has_advanced_to_session: 'has been assigned to advance to another session. Clear the advancement first before removing this contestant.'
|
|
670
|
+
advanced_to_id:
|
|
671
|
+
same_as_advanced_from: 'cannot be the same as the contestant it was advanced from'
|
|
670
672
|
spree_cm_commissioner/voting_credit:
|
|
671
673
|
attributes:
|
|
672
674
|
free_votes_amount:
|
data/config/locales/km.yml
CHANGED
|
@@ -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:
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_cm_commissioner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.9.
|
|
4
|
+
version: 2.9.3.pre.pre1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- You
|
|
@@ -3446,6 +3446,7 @@ files:
|
|
|
3446
3446
|
- db/migrate/20260701000001_add_device_info_to_cm_waiting_room_sessions.rb
|
|
3447
3447
|
- db/migrate/20260703065239_add_position_to_cm_voting_contestants.rb
|
|
3448
3448
|
- db/migrate/20260708150000_add_name_and_short_name_to_cm_trips.rb
|
|
3449
|
+
- db/migrate/20260713022227_add_advanced_to_episode_id_to_cm_voting_contestants.rb
|
|
3449
3450
|
- docker-compose.yml
|
|
3450
3451
|
- docs/api/scoped-access-token-endpoints.md
|
|
3451
3452
|
- docs/option_types/attr_types.md
|
|
@@ -3659,9 +3660,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
3659
3660
|
version: '2.7'
|
|
3660
3661
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
3661
3662
|
requirements:
|
|
3662
|
-
- - "
|
|
3663
|
+
- - ">"
|
|
3663
3664
|
- !ruby/object:Gem::Version
|
|
3664
|
-
version:
|
|
3665
|
+
version: 1.3.1
|
|
3665
3666
|
requirements:
|
|
3666
3667
|
- none
|
|
3667
3668
|
rubygems_version: 3.4.1
|