spree_cm_commissioner 2.8.2.pre.pre.2 → 2.8.2
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/.gitignore +0 -4
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/admin/homepage_section_controller.rb +1 -4
- data/app/controllers/spree/admin/taxons_controller_decorator.rb +0 -19
- data/app/controllers/spree/api/v2/storefront/homepage_sections_controller.rb +0 -1
- data/app/controllers/spree/api/v2/tenant/base_controller.rb +0 -4
- data/app/controllers/spree/api/v2/tenant/homepage_sections_controller.rb +0 -1
- data/app/controllers/spree/api/v2/tenant/products_controller.rb +1 -1
- data/app/controllers/spree/api/v2/tenant/taxons_controller.rb +1 -1
- data/app/controllers/spree_cm_commissioner/admin/products_controller_decorator.rb +0 -19
- data/app/finders/spree_cm_commissioner/events/find_matches.rb +0 -1
- data/app/helpers/spree_cm_commissioner/admin/homepage_segment_helper.rb +0 -2
- data/app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb +1 -2
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +1 -2
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -10
- data/app/models/concerns/spree_cm_commissioner/product_type.rb +1 -1
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -39
- data/app/models/spree_cm_commissioner/role_decorator.rb +1 -4
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +0 -15
- data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +1 -10
- data/app/models/spree_cm_commissioner/tenant.rb +0 -9
- data/app/models/spree_cm_commissioner/user_decorator.rb +0 -5
- data/app/models/spree_cm_commissioner/variant_options.rb +0 -4
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +0 -4
- data/app/serializers/spree/v2/storefront/homepage_section_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/product_serializer_decorator.rb +1 -1
- data/app/serializers/spree/v2/storefront/role_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +1 -2
- data/app/serializers/spree/v2/tenant/homepage_section_serializer.rb +1 -1
- data/app/serializers/spree/v2/tenant/role_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/api_caches/invalidate.rb +0 -12
- data/app/views/spree/admin/homepage_section/_form.html.erb +0 -5
- data/config/initializers/spree_permitted_attributes.rb +0 -8
- data/config/locales/en.yml +0 -14
- data/config/locales/km.yml +0 -10
- data/config/routes.rb +0 -26
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +1 -7
- data/spree_cm_commissioner.gemspec +1 -1
- metadata +4 -116
- data/app/controllers/spree/api/v2/storefront/preview_products_controller.rb +0 -48
- data/app/controllers/spree/api/v2/storefront/preview_sections_controller.rb +0 -27
- data/app/controllers/spree/api/v2/storefront/preview_taxons_controller.rb +0 -18
- data/app/controllers/spree/api/v2/storefront/products_controller_decorator.rb +0 -15
- data/app/controllers/spree/api/v2/storefront/taxons_controller_decorator.rb +0 -15
- data/app/controllers/spree/api/v2/tenant/free_vote_claims_controller.rb +0 -37
- data/app/controllers/spree/api/v2/tenant/preview_products_controller.rb +0 -47
- data/app/controllers/spree/api/v2/tenant/preview_sections_controller.rb +0 -26
- data/app/controllers/spree/api/v2/tenant/preview_shows_controller.rb +0 -19
- data/app/controllers/spree/api/v2/tenant/preview_taxons_controller.rb +0 -19
- data/app/controllers/spree/api/v2/tenant/show_contestants_controller.rb +0 -52
- data/app/controllers/spree/api/v2/tenant/show_elimination_sessions_controller.rb +0 -57
- data/app/controllers/spree/api/v2/tenant/show_people_controller.rb +0 -49
- data/app/controllers/spree/api/v2/tenant/show_person_assignments_controller.rb +0 -36
- data/app/controllers/spree/api/v2/tenant/shows_controller.rb +0 -34
- data/app/controllers/spree/api/v2/tenant/votes_controller.rb +0 -94
- data/app/controllers/spree/api/v2/tenant/voting_contestants_controller.rb +0 -40
- data/app/controllers/spree/api/v2/tenant/voting_credit_transactions_controller.rb +0 -41
- data/app/controllers/spree/api/v2/tenant/voting_credits_controller.rb +0 -31
- data/app/jobs/spree_cm_commissioner/vote_fraud_event_job.rb +0 -9
- data/app/jobs/spree_cm_commissioner/voting_credit_allocation_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/voting_credit_de_allocation_job.rb +0 -10
- data/app/models/spree_cm_commissioner/maintenance_tasks/voting_session.rb +0 -36
- data/app/models/spree_cm_commissioner/preview_role.rb +0 -8
- data/app/models/spree_cm_commissioner/role_user_decorator.rb +0 -8
- data/app/models/spree_cm_commissioner/show.rb +0 -159
- data/app/models/spree_cm_commissioner/show_contestant.rb +0 -39
- data/app/models/spree_cm_commissioner/show_contestant_image.rb +0 -11
- data/app/models/spree_cm_commissioner/show_contestant_video.rb +0 -15
- data/app/models/spree_cm_commissioner/show_episode.rb +0 -135
- data/app/models/spree_cm_commissioner/show_person.rb +0 -15
- data/app/models/spree_cm_commissioner/show_person_assignment.rb +0 -20
- data/app/models/spree_cm_commissioner/show_person_image.rb +0 -11
- data/app/models/spree_cm_commissioner/vote.rb +0 -16
- data/app/models/spree_cm_commissioner/vote_fraud_event.rb +0 -19
- data/app/models/spree_cm_commissioner/voting_contestant.rb +0 -46
- data/app/models/spree_cm_commissioner/voting_credit.rb +0 -72
- data/app/models/spree_cm_commissioner/voting_credit_transaction.rb +0 -55
- data/app/models/spree_cm_commissioner/voting_session.rb +0 -223
- data/app/models/spree_cm_commissioner/voting_session_stat.rb +0 -8
- data/app/overrides/spree/admin/products/_form/preview_checkbox.html.erb.deface +0 -9
- data/app/overrides/spree/admin/taxons/_form/preview_checkbox.html.erb.deface +0 -7
- data/app/serializers/spree/v2/tenant/show_contestant_serializer.rb +0 -21
- data/app/serializers/spree/v2/tenant/show_episode_serializer.rb +0 -17
- data/app/serializers/spree/v2/tenant/show_person_assignment_serializer.rb +0 -16
- data/app/serializers/spree/v2/tenant/show_person_serializer.rb +0 -13
- data/app/serializers/spree/v2/tenant/show_serializer.rb +0 -26
- data/app/serializers/spree/v2/tenant/video_serializer.rb +0 -9
- data/app/serializers/spree/v2/tenant/vote_serializer.rb +0 -14
- data/app/serializers/spree/v2/tenant/voting_contestant_serializer.rb +0 -22
- data/app/serializers/spree/v2/tenant/voting_credit_serializer.rb +0 -10
- data/app/serializers/spree/v2/tenant/voting_credit_transaction_serializer.rb +0 -14
- data/app/serializers/spree/v2/tenant/voting_session_serializer.rb +0 -18
- data/app/services/spree_cm_commissioner/fraud_check.rb +0 -279
- data/app/services/spree_cm_commissioner/show_contestants/normalize_video_highlights.rb +0 -57
- data/app/services/spree_cm_commissioner/url_embed/youtube_embed.rb +0 -44
- data/app/services/spree_cm_commissioner/vote_counters/audit_counters.rb +0 -43
- data/app/services/spree_cm_commissioner/vote_counters/base.rb +0 -31
- data/app/services/spree_cm_commissioner/vote_counters/increment.rb +0 -44
- data/app/services/spree_cm_commissioner/vote_counters/per_contestant_counter.rb +0 -68
- data/app/services/spree_cm_commissioner/vote_counters/rebuild_from_db.rb +0 -70
- data/app/services/spree_cm_commissioner/vote_counters/snapshot_to_db.rb +0 -113
- data/app/services/spree_cm_commissioner/vote_credit_deductor.rb +0 -68
- data/app/services/spree_cm_commissioner/vote_package/create.rb +0 -145
- data/app/services/spree_cm_commissioner/vote_package/update.rb +0 -91
- data/app/services/spree_cm_commissioner/vote_processor.rb +0 -144
- data/app/services/spree_cm_commissioner/voting_contestants/advancer.rb +0 -334
- data/app/services/spree_cm_commissioner/voting_contestants/assigner.rb +0 -32
- data/app/services/spree_cm_commissioner/voting_contestants/bulk_updater.rb +0 -106
- data/app/services/spree_cm_commissioner/voting_credits/allocate.rb +0 -77
- data/app/services/spree_cm_commissioner/voting_credits/claim_free_votes.rb +0 -119
- data/app/services/spree_cm_commissioner/voting_credits/credit_calculator.rb +0 -35
- data/app/services/spree_cm_commissioner/voting_credits/de_allocate.rb +0 -87
- data/app/services/spree_cm_commissioner/voting_leaderboards/calculate_score.rb +0 -74
- data/app/services/spree_cm_commissioner/voting_sessions/finalize.rb +0 -66
- data/db/migrate/20260309230148_create_cm_show_people.rb +0 -14
- data/db/migrate/20260309230149_create_cm_show_people_assignments.rb +0 -16
- data/db/migrate/20260310082711_create_cm_show_contestants.rb +0 -28
- data/db/migrate/20260310082720_create_cm_voting_sessions.rb +0 -21
- data/db/migrate/20260310082721_create_cm_voting_contestants.rb +0 -23
- data/db/migrate/20260310082734_add_voting_fields_to_spree_taxons.rb +0 -9
- data/db/migrate/20260310082735_add_type_to_spree_products.rb +0 -6
- data/db/migrate/20260310082749_create_cm_voting_credits.rb +0 -27
- data/db/migrate/20260326080200_create_cm_voting_credit_transactions.rb +0 -27
- data/db/migrate/20260330160000_create_cm_votes.rb +0 -25
- data/db/migrate/20260401072500_add_advanced_from_to_cm_voting_contestants.rb +0 -7
- data/db/migrate/20260402000001_add_voting_credit_scope_to_spree_taxons.rb +0 -6
- data/db/migrate/20260402000002_rename_scopeable_to_votable_in_cm_voting_credits.rb +0 -12
- data/db/migrate/20260403070000_add_name_to_cm_voting_sessions.rb +0 -5
- data/db/migrate/20260406000001_add_vendor_id_to_voting_tables.rb +0 -6
- data/db/migrate/20260406000001_rename_votes_remaining_to_amount_in_cm_voting_credits.rb +0 -11
- data/db/migrate/20260408085255_add_show_id_and_vendor_id_to_cm_voting_sessions.rb +0 -9
- data/db/migrate/20260420000001_rename_type_to_credit_type_in_cm_voting_credits.rb +0 -25
- data/db/migrate/20260422000001_create_cm_vote_fraud_events.rb +0 -23
- data/db/migrate/20260423000001_add_preview_to_taxons_products_and_sections.rb +0 -11
- data/db/migrate/20260423000002_create_preview_roles.rb +0 -24
- data/db/migrate/20260515120000_add_public_metadata_to_cm_voting_sessions.rb +0 -5
- data/db/migrate/20260518090920_add_unique_voter_count_to_voting_contestants.rb +0 -5
- data/db/migrate/20260518094322_create_cm_voting_session_stats.rb +0 -17
- data/db/migrate/20260520000001_add_scoring_model_to_cm_voting_sessions.rb +0 -5
- data/db/migrate/20260520000001_optimize_cm_votes_indexes.rb +0 -22
- data/db/migrate/20260525042257_add_vote_number_to_cm_voting_contestants.rb +0 -18
- data/db/migrate/20260527035430_add_confirmed_rank_to_cm_voting_contestants.rb +0 -5
- data/db/migrate/20260527062005_add_eliminated_at_to_cm_show_contestants.rb +0 -5
- data/docs/sql/jsonb_query_guide.md +0 -57
- data/lib/spree_cm_commissioner/test_helper/factories/show_episode_factory.rb +0 -12
- data/lib/spree_cm_commissioner/test_helper/factories/show_factory.rb +0 -120
- data/lib/spree_cm_commissioner/test_helper/factories/vote_credit_factory.rb +0 -37
- data/lib/spree_cm_commissioner/test_helper/factories/vote_factory.rb +0 -28
- data/lib/spree_cm_commissioner/test_helper/factories/voting_credit_transaction_factory.rb +0 -11
- data/lib/spree_cm_commissioner/test_helper/factories/voting_session_factory.rb +0 -11
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module VotingCredits
|
|
3
|
-
class CreditCalculator
|
|
4
|
-
def initialize(line_item)
|
|
5
|
-
@line_item = line_item
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def call
|
|
9
|
-
amount = credits_per_ticket * @line_item.quantity
|
|
10
|
-
|
|
11
|
-
if amount <= 0
|
|
12
|
-
CmAppLogger.log(
|
|
13
|
-
label: 'VotingCredits::CreditCalculator skipped line item — vote_package_amount is 0 or missing',
|
|
14
|
-
data: {
|
|
15
|
-
order_id: @line_item.order_id,
|
|
16
|
-
line_item_id: @line_item.id,
|
|
17
|
-
variant_id: @line_item.variant_id
|
|
18
|
-
}
|
|
19
|
-
)
|
|
20
|
-
return 0
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
amount
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def credits_per_ticket
|
|
29
|
-
options = SpreeCmCommissioner::VariantOptions.new(@line_item.variant)
|
|
30
|
-
credits = options.vote_package_amount.to_i
|
|
31
|
-
credits.positive? ? credits : 0
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module VotingCredits
|
|
3
|
-
class DeAllocate
|
|
4
|
-
attr_reader :order
|
|
5
|
-
|
|
6
|
-
def initialize(order)
|
|
7
|
-
@order = order
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def call
|
|
11
|
-
return true if already_canceled?
|
|
12
|
-
|
|
13
|
-
# DeAllocate#call
|
|
14
|
-
# → purchase_transaction_exists? → false
|
|
15
|
-
# → raise RuntimeError
|
|
16
|
-
# → bubbles up to VotingCreditDeAllocationJob
|
|
17
|
-
# → Sidekiq retries
|
|
18
|
-
raise "Vote credits not yet allocated for order #{order.number}" unless purchase_transaction_exists?
|
|
19
|
-
|
|
20
|
-
process_refunds
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def process_refunds
|
|
26
|
-
purchase_events = SpreeCmCommissioner::VotingCreditTransaction
|
|
27
|
-
.where(originator: order, action: :purchase)
|
|
28
|
-
.includes(:vote_credit, :episode)
|
|
29
|
-
|
|
30
|
-
purchase_events.each { |event| refund_credit(event) }
|
|
31
|
-
true
|
|
32
|
-
rescue StandardError => e
|
|
33
|
-
CmAppLogger.error(
|
|
34
|
-
label: 'VotingCredits::DeAllocate failed',
|
|
35
|
-
data: {
|
|
36
|
-
order_id: order.try(:id),
|
|
37
|
-
error_class: e.class.name,
|
|
38
|
-
error_message: e.message
|
|
39
|
-
}
|
|
40
|
-
)
|
|
41
|
-
false
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def purchase_transaction_exists?
|
|
45
|
-
SpreeCmCommissioner::VotingCreditTransaction.exists?(
|
|
46
|
-
idempotency_key: "#{order.number}::purchase"
|
|
47
|
-
)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def already_canceled?
|
|
51
|
-
SpreeCmCommissioner::VotingCreditTransaction.exists?(
|
|
52
|
-
idempotency_key: cancel_idempotency_key
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def refund_credit(purchase_event)
|
|
57
|
-
credit = purchase_event.vote_credit
|
|
58
|
-
|
|
59
|
-
credit.with_lock do
|
|
60
|
-
raise StandardError, 'Cannot refund credit that is used' if credit.paid_votes_used.to_i.positive?
|
|
61
|
-
|
|
62
|
-
SpreeCmCommissioner::VotingCreditTransaction.create!(
|
|
63
|
-
tenant_id: credit.tenant_id,
|
|
64
|
-
episode_id: purchase_event.episode_id,
|
|
65
|
-
vote_credit: credit,
|
|
66
|
-
action: :canceled,
|
|
67
|
-
amount: purchase_event.amount,
|
|
68
|
-
memo: "Refund for order ##{order.number}",
|
|
69
|
-
originator: order,
|
|
70
|
-
user_total_amount: calculate_user_total_after_refund(credit.user, credit.votable, purchase_event.amount)
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
credit.update!(paid_votes_amount: credit.paid_votes_amount - purchase_event.amount)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def cancel_idempotency_key
|
|
78
|
-
"#{order.number}::canceled"
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def calculate_user_total_after_refund(user, votable, refund_amount)
|
|
82
|
-
current_total = votable.voting_credits.where(user: user).active.sum('paid_votes_amount - paid_votes_used')
|
|
83
|
-
current_total - refund_amount
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Computes balanced scores for all four scoring models for a voting contestant.
|
|
2
|
-
#
|
|
3
|
-
# Models:
|
|
4
|
-
# - geometric √(votes × voters) — balanced; penalises vote farming
|
|
5
|
-
# - harmonic 2·v·u / (v+u) — strictest anti-stuffing
|
|
6
|
-
# - weighted_sum w_v·votes_norm + w_u·voters_norm — rewards broad support; session-relative
|
|
7
|
-
# - arithmetic (votes + voters) / 2 — plain average; no balance enforcement
|
|
8
|
-
#
|
|
9
|
-
# Usage:
|
|
10
|
-
# result = SpreeCmCommissioner::VotingLeaderboards::CalculateScore.call(
|
|
11
|
-
# votes: row[:vote_count],
|
|
12
|
-
# unique_voters: row[:unique_voters],
|
|
13
|
-
# max_votes: session_max_votes,
|
|
14
|
-
# max_unique_voters: session_max_unique_voters,
|
|
15
|
-
# votes_weight: 0.4,
|
|
16
|
-
# voters_weight: 0.6
|
|
17
|
-
# )
|
|
18
|
-
# result.value # => { geometric: 4.0, harmonic: 3.2, weighted_sum: 0.7, arithmetic: 3.5 }
|
|
19
|
-
module SpreeCmCommissioner
|
|
20
|
-
module VotingLeaderboards
|
|
21
|
-
class CalculateScore
|
|
22
|
-
prepend ::Spree::ServiceModule::Base
|
|
23
|
-
|
|
24
|
-
def call(votes:, unique_voters:, max_votes: nil, max_unique_voters: nil, votes_weight: nil, voters_weight: nil) # rubocop:disable Metrics/ParameterLists
|
|
25
|
-
scores = compute_all(votes, unique_voters,
|
|
26
|
-
max_votes: max_votes, max_unique_voters: max_unique_voters,
|
|
27
|
-
votes_weight: votes_weight, voters_weight: voters_weight
|
|
28
|
-
)
|
|
29
|
-
success(scores)
|
|
30
|
-
rescue StandardError => e
|
|
31
|
-
failure(nil, e.message)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private
|
|
35
|
-
|
|
36
|
-
def compute_all(votes, unique_voters, max_votes:, max_unique_voters:, votes_weight:, voters_weight:) # rubocop:disable Metrics/ParameterLists
|
|
37
|
-
return { geometric: 0.0, harmonic: 0.0, weighted_sum: 0.0, arithmetic: 0.0 } if votes.zero? && unique_voters.zero?
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
geometric: geometric_score(votes, unique_voters),
|
|
41
|
-
harmonic: harmonic_score(votes, unique_voters),
|
|
42
|
-
weighted_sum: weighted_sum_score(votes, unique_voters, max_votes, max_unique_voters, votes_weight, voters_weight),
|
|
43
|
-
arithmetic: arithmetic_score(votes, unique_voters)
|
|
44
|
-
}
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# √(votes × voters) — default. Balances raw vote count and voter breadth.
|
|
48
|
-
def geometric_score(votes, unique_voters)
|
|
49
|
-
Math.sqrt(votes.to_f * unique_voters.to_f)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# 2·v·u / (v+u) — dominated by the weaker metric; strictest anti-stuffing.
|
|
53
|
-
def harmonic_score(votes, unique_voters)
|
|
54
|
-
denom = votes + unique_voters
|
|
55
|
-
return 0.0 if denom.zero?
|
|
56
|
-
|
|
57
|
-
(2.0 * votes * unique_voters) / denom
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# 0.4·votes_norm + 0.6·voters_norm — session-relative; rewards broad support.
|
|
61
|
-
# max_votes / max_unique_voters must be the session maximums for normalisation.
|
|
62
|
-
def weighted_sum_score(votes, unique_voters, max_votes, max_unique_voters, votes_weight, voters_weight) # rubocop:disable Metrics/ParameterLists
|
|
63
|
-
v_norm = max_votes&.positive? ? votes.to_f / max_votes : 0.0
|
|
64
|
-
u_norm = max_unique_voters&.positive? ? unique_voters.to_f / max_unique_voters : 0.0
|
|
65
|
-
(votes_weight.to_f * v_norm) + (voters_weight.to_f * u_norm)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# (votes + voters) / 2 — plain average; no balance enforcement.
|
|
69
|
-
def arithmetic_score(votes, unique_voters)
|
|
70
|
-
(votes + unique_voters) / 2.0
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
module SpreeCmCommissioner
|
|
2
|
-
module VotingSessions
|
|
3
|
-
class Finalize
|
|
4
|
-
prepend ::Spree::ServiceModule::Base
|
|
5
|
-
|
|
6
|
-
def call(voting_session:)
|
|
7
|
-
ApplicationRecord.transaction do
|
|
8
|
-
validate_confirmed_ranks!(voting_session)
|
|
9
|
-
advance_confirmed_winners(voting_session) if next_session?(voting_session)
|
|
10
|
-
voting_session.update!(status: :finalized)
|
|
11
|
-
success(voting_session: voting_session)
|
|
12
|
-
end
|
|
13
|
-
rescue StandardError => e
|
|
14
|
-
failure(nil, e.message)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
def validate_confirmed_ranks!(voting_session)
|
|
20
|
-
if next_session?(voting_session)
|
|
21
|
-
raise I18n.t('voting.errors.no_winners_confirmed') if voting_session.voting_contestants.where.not(confirmed_rank: nil).none?
|
|
22
|
-
else
|
|
23
|
-
unranked = voting_session.voting_contestants.where(eliminated: false, confirmed_rank: nil)
|
|
24
|
-
raise I18n.t('voting.errors.all_contestants_must_be_ranked') if unranked.any?
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Re-syncs advancement on every call — handles first finalize and re-finalize.
|
|
29
|
-
# Contestants without a confirmed_rank get their advanced_to cleared.
|
|
30
|
-
def advance_confirmed_winners(voting_session)
|
|
31
|
-
next_session = resolve_next_session(voting_session)
|
|
32
|
-
|
|
33
|
-
# Reset soft eliminations from previous finalize so re-finalize can re-evaluate them.
|
|
34
|
-
# rubocop:disable Rails/SkipsModelValidations
|
|
35
|
-
voting_session.voting_contestants
|
|
36
|
-
.where(eliminated: true, eliminated_via: :public_vote)
|
|
37
|
-
.update_all(eliminated: false, eliminated_via: nil)
|
|
38
|
-
# rubocop:enable Rails/SkipsModelValidations
|
|
39
|
-
|
|
40
|
-
voting_session.voting_contestants.reload.each do |voting_contestant|
|
|
41
|
-
if voting_contestant.confirmed_rank.present?
|
|
42
|
-
SpreeCmCommissioner::VotingContestants::Advancer.call(
|
|
43
|
-
voting_contestant: voting_contestant,
|
|
44
|
-
attributes: { advanced_to: next_session }
|
|
45
|
-
)
|
|
46
|
-
else
|
|
47
|
-
SpreeCmCommissioner::VotingContestants::Advancer.call(
|
|
48
|
-
voting_contestant: voting_contestant,
|
|
49
|
-
attributes: { eliminated: true, eliminated_via: :public_vote, advanced_to_type: nil, advanced_to_id: nil }
|
|
50
|
-
)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def next_session?(voting_session)
|
|
56
|
-
resolve_next_session(voting_session).present?
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def resolve_next_session(voting_session)
|
|
60
|
-
return @resolved_next_session if defined?(@resolved_next_session)
|
|
61
|
-
|
|
62
|
-
@resolved_next_session = voting_session.next_in_episode || voting_session.episode.next_episode_first_session
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
class CreateCmShowPeople < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_show_people, if_not_exists: true do |t|
|
|
4
|
-
t.string :name, null: false
|
|
5
|
-
t.text :bio
|
|
6
|
-
t.jsonb :social_links, default: {}
|
|
7
|
-
t.references :user, foreign_key: { to_table: :spree_users }
|
|
8
|
-
|
|
9
|
-
t.timestamps
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
add_index :cm_show_people, :name, if_not_exists: true
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
class CreateCmShowPeopleAssignments < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_show_people_assignments, if_not_exists: true do |t|
|
|
4
|
-
t.references :show_person, null: false, foreign_key: { to_table: :cm_show_people }
|
|
5
|
-
t.references :show, null: false, foreign_key: { to_table: :spree_taxons }
|
|
6
|
-
t.integer :role, null: false, default: 0
|
|
7
|
-
t.integer :position
|
|
8
|
-
|
|
9
|
-
t.timestamps
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
add_index :cm_show_people_assignments, [:show_person_id, :show_id, :role],
|
|
13
|
-
unique: true, name: 'idx_show_people_assignments_unique', if_not_exists: true
|
|
14
|
-
add_index :cm_show_people_assignments, [:show_id, :role], if_not_exists: true
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
class CreateCmShowContestants < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_show_contestants, if_not_exists: true do |t|
|
|
4
|
-
t.references :show, null: false, foreign_key: { to_table: :spree_taxons }
|
|
5
|
-
t.string :name, null: false
|
|
6
|
-
t.text :bio
|
|
7
|
-
t.integer :age
|
|
8
|
-
t.string :origin
|
|
9
|
-
t.integer :gender
|
|
10
|
-
t.string :contestant_number
|
|
11
|
-
t.jsonb :social_links, default: {}
|
|
12
|
-
t.jsonb :video_highlights, default: {}
|
|
13
|
-
t.integer :category
|
|
14
|
-
t.references :assigned_show_person, foreign_key: { to_table: :cm_show_people }
|
|
15
|
-
t.references :user, foreign_key: { to_table: :spree_users }
|
|
16
|
-
t.integer :status, null: false, default: 0
|
|
17
|
-
t.integer :position
|
|
18
|
-
t.jsonb :public_metadata, default: {}
|
|
19
|
-
|
|
20
|
-
t.timestamps
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
add_index :cm_show_contestants, [:show_id, :status], if_not_exists: true
|
|
24
|
-
add_index :cm_show_contestants, [:show_id, :position], if_not_exists: true
|
|
25
|
-
add_index :cm_show_contestants, [:show_id, :contestant_number], unique: true, if_not_exists: true
|
|
26
|
-
add_index :cm_show_contestants, :name, if_not_exists: true
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
class CreateCmVotingSessions < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_voting_sessions, if_not_exists: true do |t|
|
|
4
|
-
t.references :episode, null: false, foreign_key: { to_table: :spree_products }
|
|
5
|
-
t.string :session_key, null: false
|
|
6
|
-
t.datetime :opens_at, null: false
|
|
7
|
-
t.datetime :closes_at, null: false
|
|
8
|
-
t.integer :status, default: 0, null: false
|
|
9
|
-
t.integer :position
|
|
10
|
-
t.jsonb :voting_config, default: {}
|
|
11
|
-
t.jsonb :fraud_config, default: {}
|
|
12
|
-
|
|
13
|
-
t.timestamps
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
add_index :cm_voting_sessions, :session_key, unique: true, if_not_exists: true
|
|
17
|
-
add_index :cm_voting_sessions, :status, if_not_exists: true
|
|
18
|
-
add_index :cm_voting_sessions, :position, if_not_exists: true
|
|
19
|
-
add_index :cm_voting_sessions, [:episode_id, :status], if_not_exists: true
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
class CreateCmVotingContestants < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_voting_contestants, if_not_exists: true do |t|
|
|
4
|
-
t.references :show, null: false, foreign_key: { to_table: :spree_taxons }
|
|
5
|
-
t.references :voting_session, null: false, foreign_key: { to_table: :cm_voting_sessions }
|
|
6
|
-
t.references :show_contestant, null: false, foreign_key: { to_table: :cm_show_contestants }
|
|
7
|
-
t.integer :vote_count, null: false, default: 0
|
|
8
|
-
t.boolean :eliminated, default: false
|
|
9
|
-
t.integer :eliminated_via
|
|
10
|
-
t.references :advanced_to, polymorphic: true
|
|
11
|
-
t.jsonb :special_rules, default: {}
|
|
12
|
-
|
|
13
|
-
t.timestamps
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
add_index :cm_voting_contestants, [:voting_session_id, :show_contestant_id],
|
|
17
|
-
unique: true, name: 'idx_voting_contestants_session_contestant', if_not_exists: true
|
|
18
|
-
add_index :cm_voting_contestants, [:show_id, :voting_session_id], if_not_exists: true
|
|
19
|
-
add_index :cm_voting_contestants, :show_contestant_id, if_not_exists: true
|
|
20
|
-
add_index :cm_voting_contestants, [:advanced_to_type, :advanced_to_id],
|
|
21
|
-
name: 'idx_voting_contestants_advanced_to', if_not_exists: true
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
class AddVotingFieldsToSpreeTaxons < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
add_column :spree_taxons, :type, :string, if_not_exists: true
|
|
4
|
-
add_column :spree_taxons, :voting_config, :jsonb, default: {}, if_not_exists: true
|
|
5
|
-
add_column :spree_taxons, :fraud_config, :jsonb, default: {}, if_not_exists: true
|
|
6
|
-
|
|
7
|
-
add_index :spree_taxons, :type, if_not_exists: true
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
class CreateCmVotingCredits < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_voting_credits, if_not_exists: true do |t|
|
|
4
|
-
t.integer :tenant_id, null: false
|
|
5
|
-
t.references :user, null: false, foreign_key: { to_table: :spree_users }, index: true
|
|
6
|
-
t.integer :category, null: false, default: 0
|
|
7
|
-
t.integer :type, null: false, default: 0
|
|
8
|
-
t.references :created_by, foreign_key: { to_table: :spree_users }
|
|
9
|
-
t.string :scopeable_type
|
|
10
|
-
t.bigint :scopeable_id
|
|
11
|
-
|
|
12
|
-
t.integer :free_votes_remaining, null: false, default: 0
|
|
13
|
-
t.integer :free_votes_used, null: false, default: 0
|
|
14
|
-
t.integer :paid_votes_remaining, null: false, default: 0
|
|
15
|
-
t.integer :paid_votes_used, null: false, default: 0
|
|
16
|
-
t.datetime :last_free_reset_at
|
|
17
|
-
|
|
18
|
-
t.datetime :deleted_at
|
|
19
|
-
t.timestamps
|
|
20
|
-
|
|
21
|
-
t.index :tenant_id
|
|
22
|
-
t.index %i[user_id category type], name: 'index_cm_voting_credits_on_user_category_type'
|
|
23
|
-
t.index %i[scopeable_type scopeable_id]
|
|
24
|
-
t.index :deleted_at
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
class CreateCmVotingCreditTransactions < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_voting_credit_transactions, if_not_exists: true do |t|
|
|
4
|
-
t.integer :tenant_id, null: false
|
|
5
|
-
t.integer :episode_id, null: true
|
|
6
|
-
t.references :vote_credit, null: false, foreign_key: { to_table: :cm_voting_credits }, index: true
|
|
7
|
-
t.integer :action, null: false
|
|
8
|
-
|
|
9
|
-
t.integer :amount, null: false
|
|
10
|
-
t.integer :user_total_amount, null: false
|
|
11
|
-
|
|
12
|
-
t.references :originator, polymorphic: true
|
|
13
|
-
t.string :idempotency_key
|
|
14
|
-
t.text :memo
|
|
15
|
-
|
|
16
|
-
t.datetime :deleted_at
|
|
17
|
-
t.timestamps
|
|
18
|
-
|
|
19
|
-
t.index :tenant_id
|
|
20
|
-
t.index :episode_id
|
|
21
|
-
t.index :idempotency_key, unique: true
|
|
22
|
-
t.index %i[originator_type originator_id], name: 'idx_cm_vote_credit_txns_on_originator'
|
|
23
|
-
t.index %i[vote_credit_id created_at], name: 'idx_cm_vote_credit_txns_credit_time'
|
|
24
|
-
t.index :deleted_at
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
class CreateCmVotes < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_votes, if_not_exists: true do |t|
|
|
4
|
-
t.integer :tenant_id, null: false
|
|
5
|
-
t.references :voting_session, null: false, foreign_key: { to_table: :cm_voting_sessions }
|
|
6
|
-
t.references :contestant, null: false, foreign_key: { to_table: :cm_voting_contestants }
|
|
7
|
-
t.references :user, foreign_key: { to_table: :spree_users }
|
|
8
|
-
t.references :vote_credit, foreign_key: { to_table: :cm_voting_credits }
|
|
9
|
-
t.string :voter_identifier
|
|
10
|
-
t.integer :channel, null: false, default: 0
|
|
11
|
-
t.integer :quantity, null: false, default: 1
|
|
12
|
-
t.string :device_fingerprint
|
|
13
|
-
t.string :ip_address
|
|
14
|
-
t.jsonb :public_metadata, default: {}
|
|
15
|
-
|
|
16
|
-
t.timestamps
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
add_index :cm_votes, [:voting_session_id, :contestant_id], if_not_exists: true
|
|
20
|
-
add_index :cm_votes, [:user_id, :voting_session_id], if_not_exists: true
|
|
21
|
-
add_index :cm_votes, :voter_identifier, if_not_exists: true
|
|
22
|
-
add_index :cm_votes, :created_at, if_not_exists: true
|
|
23
|
-
add_index :cm_votes, :tenant_id, if_not_exists: true
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
class AddAdvancedFromToCmVotingContestants < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
add_column :cm_voting_contestants, :advanced_from_type, :string
|
|
4
|
-
add_column :cm_voting_contestants, :advanced_from_id, :integer
|
|
5
|
-
add_index :cm_voting_contestants, [:advanced_from_type, :advanced_from_id], name: 'idx_voting_contestants_advanced_from'
|
|
6
|
-
end
|
|
7
|
-
end
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
class RenameScopeableToVotableInCmVotingCredits < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
rename_column :cm_voting_credits, :scopeable_type, :votable_type
|
|
4
|
-
rename_column :cm_voting_credits, :scopeable_id, :votable_id
|
|
5
|
-
|
|
6
|
-
remove_index :cm_voting_credits, %i[votable_type votable_id], if_exists: true
|
|
7
|
-
remove_index :cm_voting_credits, name: 'index_cm_voting_credits_on_scopeable_type_and_scopeable_id', if_exists: true
|
|
8
|
-
add_index :cm_voting_credits, %i[votable_type votable_id],
|
|
9
|
-
name: 'index_cm_voting_credits_on_votable_type_and_votable_id',
|
|
10
|
-
if_not_exists: true
|
|
11
|
-
end
|
|
12
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
class RenameVotesRemainingToAmountInCmVotingCredits < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
if column_exists?(:cm_voting_credits, :free_votes_remaining)
|
|
4
|
-
rename_column :cm_voting_credits, :free_votes_remaining, :free_votes_amount
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
if column_exists?(:cm_voting_credits, :paid_votes_remaining)
|
|
8
|
-
rename_column :cm_voting_credits, :paid_votes_remaining, :paid_votes_amount
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
class AddShowIdAndVendorIdToCmVotingSessions < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
add_column :cm_voting_sessions, :show_id, :integer, if_not_exists: true
|
|
4
|
-
add_column :cm_voting_sessions, :vendor_id, :integer, if_not_exists: true
|
|
5
|
-
|
|
6
|
-
add_index :cm_voting_sessions, :show_id, if_not_exists: true
|
|
7
|
-
add_index :cm_voting_sessions, :vendor_id, if_not_exists: true
|
|
8
|
-
end
|
|
9
|
-
end
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
class RenameTypeToCreditTypeInCmVotingCredits < ActiveRecord::Migration[7.0]
|
|
2
|
-
def up
|
|
3
|
-
rename_column :cm_voting_credits, :type, :credit_type
|
|
4
|
-
change_column_null :cm_voting_credits, :credit_type, true
|
|
5
|
-
change_column_default :cm_voting_credits, :credit_type, nil
|
|
6
|
-
|
|
7
|
-
if index_exists?(:cm_voting_credits, nil, name: 'index_cm_voting_credits_on_user_category_type')
|
|
8
|
-
rename_index :cm_voting_credits,
|
|
9
|
-
'index_cm_voting_credits_on_user_category_type',
|
|
10
|
-
'index_cm_voting_credits_on_user_category_credit_type'
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def down
|
|
15
|
-
change_column_default :cm_voting_credits, :credit_type, 0
|
|
16
|
-
change_column_null :cm_voting_credits, :credit_type, false
|
|
17
|
-
rename_column :cm_voting_credits, :credit_type, :type
|
|
18
|
-
|
|
19
|
-
if index_exists?(:cm_voting_credits, nil, name: 'index_cm_voting_credits_on_user_category_credit_type')
|
|
20
|
-
rename_index :cm_voting_credits,
|
|
21
|
-
'index_cm_voting_credits_on_user_category_credit_type',
|
|
22
|
-
'index_cm_voting_credits_on_user_category_type'
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
class CreateCmVoteFraudEvents < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
create_table :cm_vote_fraud_events, if_not_exists: true do |t|
|
|
4
|
-
t.integer :tenant_id, null: false
|
|
5
|
-
t.references :voting_session, null: false, foreign_key: { to_table: :cm_voting_sessions }
|
|
6
|
-
t.references :user, foreign_key: { to_table: :spree_users }
|
|
7
|
-
t.references :vote, foreign_key: { to_table: :cm_votes }
|
|
8
|
-
t.integer :fraud_type, null: false, default: 0
|
|
9
|
-
t.integer :severity, null: false, default: 0
|
|
10
|
-
t.integer :action_taken, null: false, default: 0
|
|
11
|
-
t.jsonb :details, null: false, default: {}
|
|
12
|
-
t.datetime :resolved_at
|
|
13
|
-
t.references :resolved_by, foreign_key: { to_table: :spree_users }
|
|
14
|
-
t.text :resolution_notes
|
|
15
|
-
|
|
16
|
-
t.timestamps
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
add_index :cm_vote_fraud_events, :tenant_id, name: 'index_cm_vote_fraud_events_on_tenant_id', if_not_exists: true
|
|
20
|
-
add_index :cm_vote_fraud_events, :fraud_type, name: 'index_cm_vote_fraud_events_on_fraud_type', if_not_exists: true
|
|
21
|
-
add_index :cm_vote_fraud_events, :created_at, name: 'index_cm_vote_fraud_events_on_created_at', if_not_exists: true
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
class AddPreviewToTaxonsProductsAndSections < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
add_column :spree_taxons, :preview, :boolean, default: false, null: false unless column_exists?(:spree_taxons, :preview)
|
|
4
|
-
add_column :spree_products, :preview, :boolean, default: false, null: false unless column_exists?(:spree_products, :preview)
|
|
5
|
-
add_column :cm_homepage_sections, :preview, :boolean, default: false, null: false unless column_exists?(:cm_homepage_sections, :preview)
|
|
6
|
-
|
|
7
|
-
add_index :spree_taxons, :preview unless index_exists?(:spree_taxons, :preview)
|
|
8
|
-
add_index :spree_products, :preview unless index_exists?(:spree_products, :preview)
|
|
9
|
-
add_index :cm_homepage_sections, :preview unless index_exists?(:cm_homepage_sections, :preview)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
class CreatePreviewRoles < ActiveRecord::Migration[7.0]
|
|
2
|
-
def change
|
|
3
|
-
unless table_exists?(:cm_preview_roles)
|
|
4
|
-
create_table :cm_preview_roles do |t|
|
|
5
|
-
t.string :previewable_type, null: false, default: 'Spree::Taxon'
|
|
6
|
-
t.bigint :previewable_id, null: false
|
|
7
|
-
t.bigint :role_id, null: false
|
|
8
|
-
t.timestamps
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
unless index_exists?(:cm_preview_roles, [:previewable_type, :previewable_id, :role_id])
|
|
13
|
-
add_index :cm_preview_roles, [:previewable_type, :previewable_id, :role_id], unique: true, name: 'index_cm_preview_roles_on_previewable_and_role'
|
|
14
|
-
end
|
|
15
|
-
unless index_exists?(:cm_preview_roles, [:previewable_type, :previewable_id])
|
|
16
|
-
add_index :cm_preview_roles, [:previewable_type, :previewable_id], name: 'index_cm_preview_roles_on_previewable'
|
|
17
|
-
end
|
|
18
|
-
add_index :cm_preview_roles, :role_id unless index_exists?(:cm_preview_roles, :role_id)
|
|
19
|
-
|
|
20
|
-
unless foreign_key_exists?(:cm_preview_roles, :spree_roles, column: :role_id)
|
|
21
|
-
add_foreign_key :cm_preview_roles, :spree_roles, column: :role_id
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|