spree_cm_commissioner 2.8.6 → 2.8.7.pre.pre2
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/.env.example +8 -0
- data/.gitignore +6 -0
- data/Gemfile.lock +1 -1
- data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +2 -0
- data/app/controllers/spree/admin/homepage_section_controller.rb +4 -1
- data/app/controllers/spree/admin/import_new_orders_controller.rb +25 -0
- data/app/controllers/spree/admin/inventory_holds_controller.rb +20 -1
- data/app/controllers/spree/admin/taxons_controller_decorator.rb +19 -0
- data/app/controllers/spree/api/v2/storefront/account/orders_controller_decorator.rb +5 -0
- data/app/controllers/spree/api/v2/storefront/homepage_sections_controller.rb +1 -0
- data/app/controllers/spree/api/v2/storefront/order_histories_controller.rb +7 -2
- data/app/controllers/spree/api/v2/storefront/preview_products_controller.rb +48 -0
- data/app/controllers/spree/api/v2/storefront/preview_sections_controller.rb +27 -0
- data/app/controllers/spree/api/v2/storefront/preview_taxons_controller.rb +18 -0
- data/app/controllers/spree/api/v2/storefront/products_controller_decorator.rb +15 -0
- data/app/controllers/spree/api/v2/storefront/taxons_controller_decorator.rb +15 -0
- data/app/controllers/spree/api/v2/storefront/ticket_transfers_controller.rb +4 -3
- data/app/controllers/spree/api/v2/tenant/ad_campaigns_controller.rb +25 -0
- data/app/controllers/spree/api/v2/tenant/base_controller.rb +4 -0
- data/app/controllers/spree/api/v2/tenant/episodes_controller.rb +38 -0
- data/app/controllers/spree/api/v2/tenant/free_vote_claims_controller.rb +37 -0
- data/app/controllers/spree/api/v2/tenant/homepage_sections_controller.rb +1 -0
- data/app/controllers/spree/api/v2/tenant/order_histories_controller.rb +7 -2
- data/app/controllers/spree/api/v2/tenant/preview_products_controller.rb +47 -0
- data/app/controllers/spree/api/v2/tenant/preview_sections_controller.rb +26 -0
- data/app/controllers/spree/api/v2/tenant/preview_shows_controller.rb +19 -0
- data/app/controllers/spree/api/v2/tenant/preview_taxons_controller.rb +19 -0
- data/app/controllers/spree/api/v2/tenant/products_controller.rb +1 -1
- data/app/controllers/spree/api/v2/tenant/show_contestants_controller.rb +52 -0
- data/app/controllers/spree/api/v2/tenant/show_elimination_sessions_controller.rb +57 -0
- data/app/controllers/spree/api/v2/tenant/show_people_controller.rb +49 -0
- data/app/controllers/spree/api/v2/tenant/show_person_assignments_controller.rb +36 -0
- data/app/controllers/spree/api/v2/tenant/shows_controller.rb +36 -0
- data/app/controllers/spree/api/v2/tenant/taxons_controller.rb +1 -1
- data/app/controllers/spree/api/v2/tenant/votes_controller.rb +94 -0
- data/app/controllers/spree/api/v2/tenant/voting_contestants_controller.rb +43 -0
- data/app/controllers/spree/api/v2/tenant/voting_credit_transactions_controller.rb +41 -0
- data/app/controllers/spree/api/v2/tenant/voting_credits_controller.rb +31 -0
- data/app/controllers/spree_cm_commissioner/admin/products_controller_decorator.rb +19 -0
- data/app/finders/spree_cm_commissioner/events/find_matches.rb +1 -0
- data/app/finders/spree_cm_commissioner/orders/find.rb +33 -3
- data/app/finders/spree_cm_commissioner/orders/find_by_all_state.rb +11 -0
- data/app/helpers/spree_cm_commissioner/admin/homepage_segment_helper.rb +2 -0
- data/app/interactors/spree_cm_commissioner/waiting_guests_caller.rb +16 -4
- data/app/jobs/concerns/spree_cm_commissioner/idempotent_job.rb +12 -0
- data/app/jobs/spree_cm_commissioner/cancel_import_order_job.rb +11 -0
- data/app/jobs/spree_cm_commissioner/idempotency_keys/prune_job.rb +20 -0
- data/app/jobs/spree_cm_commissioner/inventory_items/bulk_adjust_quantities_job.rb +21 -3
- data/app/jobs/spree_cm_commissioner/inventory_items/bulk_adjust_quantities_on_hold_job.rb +34 -3
- data/app/jobs/spree_cm_commissioner/show_contestants/import_job.rb +9 -0
- data/app/jobs/spree_cm_commissioner/telegram_alerts/order_integrity_check_job.rb +17 -0
- data/app/jobs/spree_cm_commissioner/vote_fraud_event_job.rb +9 -0
- data/app/jobs/spree_cm_commissioner/voting_credit_allocation_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/voting_credit_de_allocation_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/waiting_guests_caller_job.rb +5 -0
- data/app/mailers/spree/order_mailer_decorator.rb +2 -0
- data/app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb +2 -1
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +2 -1
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +43 -1
- data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +2 -0
- data/app/models/concerns/spree_cm_commissioner/product_type.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/store_preference.rb +1 -0
- data/app/models/concerns/spree_cm_commissioner/taxon_kind.rb +3 -1
- data/app/models/concerns/spree_cm_commissioner/voting_session_live_stream_concern.rb +41 -0
- data/app/models/spree_cm_commissioner/idempotency_key.rb +21 -0
- data/app/models/spree_cm_commissioner/import.rb +4 -2
- data/app/models/spree_cm_commissioner/imported_order.rb +6 -0
- data/app/models/spree_cm_commissioner/imports/import_contestant.rb +7 -0
- data/app/models/spree_cm_commissioner/imports/import_order.rb +21 -0
- data/app/models/spree_cm_commissioner/maintenance_tasks/voting_session.rb +36 -0
- data/app/models/spree_cm_commissioner/order_decorator.rb +14 -0
- data/app/models/spree_cm_commissioner/payment_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/preview_role.rb +8 -0
- data/app/models/spree_cm_commissioner/product_decorator.rb +53 -0
- data/app/models/spree_cm_commissioner/role_decorator.rb +4 -1
- data/app/models/spree_cm_commissioner/role_user_decorator.rb +8 -0
- data/app/models/spree_cm_commissioner/show.rb +163 -0
- data/app/models/spree_cm_commissioner/show_contestant.rb +39 -0
- data/app/models/spree_cm_commissioner/show_contestant_image.rb +11 -0
- data/app/models/spree_cm_commissioner/show_contestant_video.rb +15 -0
- data/app/models/spree_cm_commissioner/show_episode.rb +108 -0
- data/app/models/spree_cm_commissioner/show_person.rb +15 -0
- data/app/models/spree_cm_commissioner/show_person_assignment.rb +21 -0
- data/app/models/spree_cm_commissioner/show_person_image.rb +11 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +23 -0
- data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +19 -1
- data/app/models/spree_cm_commissioner/tenant.rb +9 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +5 -0
- data/app/models/spree_cm_commissioner/variant_decorator.rb +4 -0
- data/app/models/spree_cm_commissioner/variant_options.rb +4 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +4 -0
- data/app/models/spree_cm_commissioner/vote.rb +16 -0
- data/app/models/spree_cm_commissioner/vote_fraud_event.rb +20 -0
- data/app/models/spree_cm_commissioner/voting_contestant.rb +100 -0
- data/app/models/spree_cm_commissioner/voting_credit.rb +72 -0
- data/app/models/spree_cm_commissioner/voting_credit_transaction.rb +55 -0
- data/app/models/spree_cm_commissioner/voting_session.rb +216 -0
- data/app/models/spree_cm_commissioner/voting_session_stat.rb +8 -0
- data/app/overrides/spree/admin/orders/_search/payment_number_search_field.html.erb.deface +8 -0
- data/app/overrides/spree/admin/products/_form/allow_gift_transfer.html.erb.deface +1 -1
- data/app/overrides/spree/admin/products/_form/allow_transfer.html.erb.deface +1 -1
- data/app/overrides/spree/admin/products/_form/enable_telegram_alert.html.erb.deface +14 -0
- data/app/overrides/spree/admin/products/_form/preview_checkbox.html.erb.deface +9 -0
- data/app/overrides/spree/admin/stores/_form/store_preferences.html.erb.deface +9 -0
- data/app/overrides/spree/admin/taxons/_form/preview_checkbox.html.erb.deface +7 -0
- data/app/serializers/spree/v2/storefront/homepage_section_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/product_serializer_decorator.rb +2 -1
- data/app/serializers/spree/v2/storefront/role_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +2 -1
- data/app/serializers/spree/v2/tenant/ad_campaign_serializer.rb +13 -0
- data/app/serializers/spree/v2/tenant/advertisement_serializer.rb +11 -0
- 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/serializers/spree/v2/tenant/show_contestant_serializer.rb +21 -0
- data/app/serializers/spree/v2/tenant/show_episode_serializer.rb +20 -0
- data/app/serializers/spree/v2/tenant/show_parent_serializer.rb +13 -0
- data/app/serializers/spree/v2/tenant/show_person_assignment_serializer.rb +16 -0
- data/app/serializers/spree/v2/tenant/show_person_serializer.rb +13 -0
- data/app/serializers/spree/v2/tenant/show_serializer.rb +23 -0
- data/app/serializers/spree/v2/tenant/video_serializer.rb +9 -0
- data/app/serializers/spree/v2/tenant/vote_package_serializer.rb +9 -0
- data/app/serializers/spree/v2/tenant/vote_serializer.rb +14 -0
- data/app/serializers/spree/v2/tenant/voting_contestant_serializer.rb +23 -0
- data/app/serializers/spree/v2/tenant/voting_credit_serializer.rb +10 -0
- data/app/serializers/spree/v2/tenant/voting_credit_transaction_serializer.rb +14 -0
- data/app/serializers/spree/v2/tenant/voting_session_serializer.rb +21 -0
- data/app/services/spree_cm_commissioner/api_caches/invalidate.rb +12 -0
- data/app/services/spree_cm_commissioner/cart/add_guest.rb +16 -2
- data/app/services/spree_cm_commissioner/fraud_check.rb +299 -0
- data/app/services/spree_cm_commissioner/imports/contestants/create.rb +153 -0
- data/app/services/spree_cm_commissioner/imports/orders/cancel.rb +63 -0
- data/app/services/spree_cm_commissioner/imports/orders/create.rb +1 -0
- data/app/services/spree_cm_commissioner/show_contestants/normalize_video_highlights.rb +57 -0
- data/app/services/spree_cm_commissioner/show_persons/contestant_assigner.rb +51 -0
- data/app/services/spree_cm_commissioner/telegram_alerts/checks/order_complete_payment_not_paid.rb +21 -0
- data/app/services/spree_cm_commissioner/telegram_alerts/checks/payment_paid_order_not_complete.rb +21 -0
- data/app/services/spree_cm_commissioner/telegram_alerts/order_integrity_alert.rb +112 -0
- data/app/services/spree_cm_commissioner/telegram_alerts/order_integrity_checks_runner.rb +32 -0
- data/app/services/spree_cm_commissioner/url_embed/youtube_embed.rb +44 -0
- data/app/services/spree_cm_commissioner/vote_counters/audit_counters.rb +43 -0
- data/app/services/spree_cm_commissioner/vote_counters/base.rb +31 -0
- data/app/services/spree_cm_commissioner/vote_counters/increment.rb +44 -0
- data/app/services/spree_cm_commissioner/vote_counters/per_contestant_counter.rb +68 -0
- data/app/services/spree_cm_commissioner/vote_counters/rebuild_from_db.rb +70 -0
- data/app/services/spree_cm_commissioner/vote_counters/snapshot_to_db.rb +113 -0
- data/app/services/spree_cm_commissioner/vote_credit_deductor.rb +68 -0
- data/app/services/spree_cm_commissioner/vote_package/create.rb +145 -0
- data/app/services/spree_cm_commissioner/vote_package/update.rb +91 -0
- data/app/services/spree_cm_commissioner/vote_processor.rb +144 -0
- data/app/services/spree_cm_commissioner/voting_contestants/advancer.rb +335 -0
- data/app/services/spree_cm_commissioner/voting_contestants/assigner.rb +40 -0
- data/app/services/spree_cm_commissioner/voting_contestants/bulk_updater.rb +106 -0
- data/app/services/spree_cm_commissioner/voting_credits/allocate.rb +77 -0
- data/app/services/spree_cm_commissioner/voting_credits/claim_free_votes.rb +119 -0
- data/app/services/spree_cm_commissioner/voting_credits/credit_calculator.rb +35 -0
- data/app/services/spree_cm_commissioner/voting_credits/de_allocate.rb +87 -0
- data/app/services/spree_cm_commissioner/voting_leaderboards/calculate_score.rb +67 -0
- data/app/services/spree_cm_commissioner/voting_leaderboards/combined_result.rb +190 -0
- data/app/services/spree_cm_commissioner/voting_sessions/finalize.rb +105 -0
- data/app/services/spree_cm_commissioner/waiting_room/stamp_queue_positions.rb +66 -24
- data/app/views/spree/admin/homepage_section/_form.html.erb +5 -0
- data/app/views/spree/admin/import_new_orders/_cancel_modal.html.erb +35 -0
- data/app/views/spree/admin/import_new_orders/index.html.erb +4 -0
- data/app/views/spree/admin/import_new_orders/show.html.erb +30 -0
- data/app/views/spree/admin/imports/index.html.erb +2 -0
- data/app/views/spree/admin/inventory_holds/index.html.erb +8 -3
- data/app/views/spree_cm_commissioner/order_mailer/purchased_items/_items.html.erb +12 -9
- data/config/initializers/spree_permitted_attributes.rb +12 -0
- data/config/locales/en.yml +54 -8
- data/config/locales/km.yml +38 -6
- data/config/routes.rb +29 -0
- data/db/migrate/20260309230148_create_cm_show_people.rb +14 -0
- data/db/migrate/20260309230149_create_cm_show_people_assignments.rb +16 -0
- data/db/migrate/20260310082711_create_cm_show_contestants.rb +28 -0
- data/db/migrate/20260310082720_create_cm_voting_sessions.rb +21 -0
- data/db/migrate/20260310082721_create_cm_voting_contestants.rb +23 -0
- data/db/migrate/20260310082734_add_voting_fields_to_spree_taxons.rb +9 -0
- data/db/migrate/20260310082735_add_type_to_spree_products.rb +6 -0
- data/db/migrate/20260310082749_create_cm_voting_credits.rb +27 -0
- data/db/migrate/20260326080200_create_cm_voting_credit_transactions.rb +27 -0
- data/db/migrate/20260330160000_create_cm_votes.rb +25 -0
- data/db/migrate/20260401072500_add_advanced_from_to_cm_voting_contestants.rb +7 -0
- data/db/migrate/20260402000001_add_voting_credit_scope_to_spree_taxons.rb +6 -0
- data/db/migrate/20260402000002_rename_scopeable_to_votable_in_cm_voting_credits.rb +12 -0
- data/db/migrate/20260403070000_add_name_to_cm_voting_sessions.rb +5 -0
- data/db/migrate/20260406000001_add_vendor_id_to_voting_tables.rb +6 -0
- data/db/migrate/20260406000001_rename_votes_remaining_to_amount_in_cm_voting_credits.rb +11 -0
- data/db/migrate/20260408085255_add_show_id_and_vendor_id_to_cm_voting_sessions.rb +9 -0
- data/db/migrate/20260420000001_rename_type_to_credit_type_in_cm_voting_credits.rb +25 -0
- data/db/migrate/20260422000001_create_cm_vote_fraud_events.rb +23 -0
- data/db/migrate/20260423000001_add_preview_to_taxons_products_and_sections.rb +11 -0
- data/db/migrate/20260423000002_create_preview_roles.rb +24 -0
- data/db/migrate/20260515120000_add_public_metadata_to_cm_voting_sessions.rb +5 -0
- data/db/migrate/20260518090920_add_unique_voter_count_to_voting_contestants.rb +5 -0
- data/db/migrate/20260518094322_create_cm_voting_session_stats.rb +17 -0
- data/db/migrate/20260520000001_add_scoring_model_to_cm_voting_sessions.rb +5 -0
- data/db/migrate/20260520000001_optimize_cm_votes_indexes.rb +22 -0
- data/db/migrate/20260525042257_add_vote_number_to_cm_voting_contestants.rb +18 -0
- data/db/migrate/20260527035430_add_confirmed_rank_to_cm_voting_contestants.rb +5 -0
- data/db/migrate/20260527062005_add_eliminated_at_to_cm_show_contestants.rb +5 -0
- data/db/migrate/20260603063652_add_parent_to_voting_sessions.rb +9 -0
- data/db/migrate/20260603090000_add_session_type_to_cm_voting_sessions.rb +6 -0
- data/db/migrate/20260608000000_add_display_to_cm_voting_sessions.rb +5 -0
- data/db/migrate/20260616000001_add_canceled_by_id_to_cm_imports.rb +5 -0
- data/db/migrate/20260617000002_create_cm_imported_orders.rb +12 -0
- data/db/migrate/20260619000001_create_cm_idempotency_keys.rb +11 -0
- data/docs/sql/jsonb_query_guide.md +57 -0
- data/lib/spree_cm_commissioner/test_helper/factories/show_episode_factory.rb +12 -0
- data/lib/spree_cm_commissioner/test_helper/factories/show_factory.rb +120 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vote_credit_factory.rb +37 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vote_factory.rb +28 -0
- data/lib/spree_cm_commissioner/test_helper/factories/voting_credit_transaction_factory.rb +11 -0
- data/lib/spree_cm_commissioner/test_helper/factories/voting_session_factory.rb +11 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +7 -1
- data/spree_cm_commissioner.gemspec +1 -1
- metadata +149 -4
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class ShowContestantsController < BaseController
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# override
|
|
9
|
+
def model_class
|
|
10
|
+
SpreeCmCommissioner::ShowContestant
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# override
|
|
14
|
+
def scope
|
|
15
|
+
return model_class.none unless current_show
|
|
16
|
+
|
|
17
|
+
model_class
|
|
18
|
+
.where(show_id: current_show.id)
|
|
19
|
+
.includes(
|
|
20
|
+
:show_contestant_images,
|
|
21
|
+
:show_contestant_videos,
|
|
22
|
+
:current_voting_session,
|
|
23
|
+
:voting_contestants,
|
|
24
|
+
assigned_show_person: :show_person_images,
|
|
25
|
+
show: [
|
|
26
|
+
:parent,
|
|
27
|
+
{ episodes: :voting_sessions },
|
|
28
|
+
{ seasons: { episodes: :voting_sessions } }
|
|
29
|
+
]
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def current_show
|
|
34
|
+
@current_show ||= show_scope.find_by!(slug: params[:show_id])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def show_scope
|
|
38
|
+
vendor_ids = @tenant.vendors.select(:id)
|
|
39
|
+
return SpreeCmCommissioner::Show.none if vendor_ids.blank?
|
|
40
|
+
|
|
41
|
+
SpreeCmCommissioner::Show.where(vendor_id: vendor_ids)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# override
|
|
45
|
+
def resource_serializer
|
|
46
|
+
Spree::V2::Tenant::ShowContestantSerializer
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class ShowEliminationSessionsController < BaseController
|
|
6
|
+
# override
|
|
7
|
+
def collection
|
|
8
|
+
@collection ||= scope
|
|
9
|
+
.includes(
|
|
10
|
+
:episode,
|
|
11
|
+
:show,
|
|
12
|
+
eliminated_voting_contestants: [
|
|
13
|
+
:show_contestant,
|
|
14
|
+
{ show_contestant: %i[show_contestant_images show_contestant_videos] }
|
|
15
|
+
]
|
|
16
|
+
)
|
|
17
|
+
.order('cm_voting_sessions.closes_at DESC')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# override
|
|
21
|
+
def collection_serializer
|
|
22
|
+
Spree::V2::Tenant::VotingSessionSerializer
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# override
|
|
28
|
+
def model_class
|
|
29
|
+
SpreeCmCommissioner::VotingSession
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# override
|
|
33
|
+
def scope
|
|
34
|
+
return model_class.none unless current_show
|
|
35
|
+
|
|
36
|
+
current_show.voting_sessions
|
|
37
|
+
.joins(:episode)
|
|
38
|
+
.joins(:voting_contestants)
|
|
39
|
+
.where(voting_contestants: { eliminated: true })
|
|
40
|
+
.distinct
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def current_show
|
|
44
|
+
@current_show ||= show_scope.find_by!(slug: params[:show_id])
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def show_scope
|
|
48
|
+
vendor_ids = @tenant.vendors.select(:id)
|
|
49
|
+
return SpreeCmCommissioner::Show.none if vendor_ids.blank?
|
|
50
|
+
|
|
51
|
+
SpreeCmCommissioner::Show.where(vendor_id: vendor_ids)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class ShowPeopleController < BaseController
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# override
|
|
9
|
+
def model_class
|
|
10
|
+
SpreeCmCommissioner::ShowPerson
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# override
|
|
14
|
+
def scope
|
|
15
|
+
scope = current_show.show_people
|
|
16
|
+
.joins(:assignments)
|
|
17
|
+
.distinct
|
|
18
|
+
.includes(
|
|
19
|
+
:assignments,
|
|
20
|
+
assigned_contestants: %i[show_contestant_images current_voting_session]
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
role = params[:role].presence
|
|
24
|
+
return scope if role.blank?
|
|
25
|
+
|
|
26
|
+
role_value = SpreeCmCommissioner::ShowPersonAssignment.roles[role.to_s]
|
|
27
|
+
return scope.none if role_value.nil?
|
|
28
|
+
|
|
29
|
+
scope.where(cm_show_people_assignments: { role: role_value })
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# override
|
|
33
|
+
def collection_serializer
|
|
34
|
+
Spree::V2::Tenant::ShowPersonSerializer
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def current_show
|
|
38
|
+
@current_show ||= show_scope.find_by!(slug: params[:show_id])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def show_scope
|
|
42
|
+
vendor_ids = @tenant.vendors.select(:id)
|
|
43
|
+
SpreeCmCommissioner::Show.where(vendor_id: vendor_ids)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class ShowPersonAssignmentsController < BaseController
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def model_class
|
|
9
|
+
SpreeCmCommissioner::ShowPersonAssignment
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def scope
|
|
13
|
+
vendor_ids = @tenant.vendors.select(:id)
|
|
14
|
+
show_ids = SpreeCmCommissioner::Show.where(vendor_id: vendor_ids).select(:id)
|
|
15
|
+
|
|
16
|
+
model_class.where(show_id: show_ids)
|
|
17
|
+
.where(show_person_id: params[:person_id], show_id: current_show.id)
|
|
18
|
+
.includes(:show_person, :show)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def current_show
|
|
22
|
+
@current_show ||= SpreeCmCommissioner::Show.find_by!(slug: params[:show_id])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resource_serializer
|
|
26
|
+
Spree::V2::Tenant::ShowPersonAssignmentSerializer
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def collection_serializer
|
|
30
|
+
Spree::V2::Tenant::ShowPersonAssignmentSerializer
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class ShowsController < BaseController
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
# override
|
|
9
|
+
def model_class
|
|
10
|
+
SpreeCmCommissioner::Show
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def resource
|
|
14
|
+
@resource ||= scope.find_by!(slug: params[:id])
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# override
|
|
18
|
+
def scope
|
|
19
|
+
vendor_ids = @tenant.vendors.select(:id)
|
|
20
|
+
return model_class.none if vendor_ids.blank?
|
|
21
|
+
|
|
22
|
+
model_class.where(vendor_id: vendor_ids, preview: false)
|
|
23
|
+
.includes(:parent, :app_banner, show_people: :show_person_images,
|
|
24
|
+
episodes: :voting_sessions, seasons: { episodes: :voting_sessions }
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# override
|
|
29
|
+
def resource_serializer
|
|
30
|
+
Spree::V2::Tenant::ShowSerializer
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class VotesController < BaseController
|
|
6
|
+
before_action :require_spree_current_user
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
render_serialized_payload do
|
|
10
|
+
serialize_collection(collection)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def create
|
|
15
|
+
voting_session = current_vendor.voting_sessions.find(params[:voting_session_id])
|
|
16
|
+
contestant = voting_session.voting_contestants.find(params[:contestant_id])
|
|
17
|
+
|
|
18
|
+
processor_params = vote_params.merge(
|
|
19
|
+
device_fingerprint: device_params[:fingerprint],
|
|
20
|
+
voter_identifier: device_params[:identifier],
|
|
21
|
+
public_metadata: params[:public_metadata] || {},
|
|
22
|
+
tenant_id: MultiTenant.current_tenant_id,
|
|
23
|
+
vendor_id: current_vendor.id
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
result = SpreeCmCommissioner::VoteProcessor.call(
|
|
27
|
+
voting_session: voting_session,
|
|
28
|
+
contestant: contestant,
|
|
29
|
+
user: spree_current_user,
|
|
30
|
+
params: processor_params,
|
|
31
|
+
request: request
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
if result.success?
|
|
35
|
+
render_serialized_payload(201) { serialize_resource(result.value) }
|
|
36
|
+
else
|
|
37
|
+
render_error_payload(result.error)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def collection
|
|
44
|
+
@collection ||= scope.page(params[:page])
|
|
45
|
+
.per(params[:per_page])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def scope
|
|
49
|
+
MultiTenant.with(@tenant) do
|
|
50
|
+
scope = spree_current_user.votes
|
|
51
|
+
.includes(:contestant, :voting_session, :vote_credit)
|
|
52
|
+
.order(created_at: :desc)
|
|
53
|
+
|
|
54
|
+
scope = scope.for_session(params[:voting_session_id]) if params[:voting_session_id]
|
|
55
|
+
scope
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def model_class
|
|
60
|
+
SpreeCmCommissioner::Vote
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def resource_serializer
|
|
64
|
+
Spree::V2::Tenant::VoteSerializer
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def collection_serializer
|
|
68
|
+
Spree::V2::Tenant::VoteSerializer
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# {
|
|
72
|
+
# "contestant_id": 1,
|
|
73
|
+
# "vote": {
|
|
74
|
+
# "quantity": 1,
|
|
75
|
+
# "channel": "mobile"
|
|
76
|
+
# },
|
|
77
|
+
# "device": {
|
|
78
|
+
# "fingerprint": "fp-xyz",
|
|
79
|
+
# "identifier": "device-abc",
|
|
80
|
+
# "platform": "android"
|
|
81
|
+
# }
|
|
82
|
+
# }
|
|
83
|
+
def vote_params
|
|
84
|
+
params.require(:vote).permit(:quantity, :channel)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def device_params
|
|
88
|
+
params.require(:device).permit(:fingerprint, :identifier, :platform)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class VotingContestantsController < BaseController
|
|
6
|
+
before_action :load_voting_session, only: %i[index]
|
|
7
|
+
|
|
8
|
+
# override
|
|
9
|
+
def collection
|
|
10
|
+
@collection ||= @voting_session
|
|
11
|
+
.voting_contestants
|
|
12
|
+
.includes(:voting_session, :show_contestant,
|
|
13
|
+
:show_contestant_images, :show_contestant_videos,
|
|
14
|
+
:advanced_to, :advanced_from
|
|
15
|
+
)
|
|
16
|
+
.order(:id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# override
|
|
20
|
+
def collection_serializer
|
|
21
|
+
Spree::V2::Tenant::VotingContestantSerializer
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
# override
|
|
27
|
+
def model_class
|
|
28
|
+
SpreeCmCommissioner::VotingSession
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# override
|
|
32
|
+
def scope
|
|
33
|
+
current_vendor.voting_sessions.includes(:episode)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def load_voting_session
|
|
37
|
+
@voting_session = scope.find(params[:voting_session_id])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class VotingCreditTransactionsController < BaseController
|
|
6
|
+
before_action :require_spree_current_user
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
render_serialized_payload do
|
|
10
|
+
serialize_collection(collection)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def collection
|
|
17
|
+
@collection ||= scope.page(params[:page])
|
|
18
|
+
.per(params[:per_page])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def scope
|
|
22
|
+
scope = spree_current_user.voting_credit_transactions
|
|
23
|
+
.includes(:vote_credit, :originator)
|
|
24
|
+
.order(created_at: :desc)
|
|
25
|
+
|
|
26
|
+
scope = scope.by_action(params[:actions].split(',')) if params[:actions].present?
|
|
27
|
+
scope
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def model_class
|
|
31
|
+
SpreeCmCommissioner::VotingCreditTransaction
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def collection_serializer
|
|
35
|
+
Spree::V2::Tenant::VotingCreditTransactionSerializer
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
class VotingCreditsController < BaseController
|
|
6
|
+
before_action :require_spree_current_user
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
render_serialized_payload do
|
|
10
|
+
serialize_resource(voting_credit)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def voting_credit
|
|
17
|
+
spree_current_user.voting_credits.active.eligible(load_voting_session).first
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def load_voting_session
|
|
21
|
+
@voting_session ||= SpreeCmCommissioner::VotingSession.find(params[:voting_session_id])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def resource_serializer
|
|
25
|
+
Spree::V2::Tenant::VotingCreditSerializer
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -6,6 +6,7 @@ module SpreeCmCommissioner
|
|
|
6
6
|
base.around_action :set_writing_role, only: %i[index]
|
|
7
7
|
base.after_action :set_tenant_after_update, only: %i[update]
|
|
8
8
|
base.before_action :merge_industry_taxons_into_taxons, only: [:update]
|
|
9
|
+
base.before_action :normalize_sti_product_params, only: %i[create update]
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
# Override
|
|
@@ -51,6 +52,24 @@ module SpreeCmCommissioner
|
|
|
51
52
|
|
|
52
53
|
protected
|
|
53
54
|
|
|
55
|
+
# Some admin forms submit STI records under their class key while
|
|
56
|
+
# Spree update reads :product. Merge both into :product so all edited
|
|
57
|
+
# fields are persisted for STI product subclasses.
|
|
58
|
+
def normalize_sti_product_params
|
|
59
|
+
return unless @product
|
|
60
|
+
|
|
61
|
+
sti_key = @product.class.model_name.param_key.to_sym
|
|
62
|
+
sti_params = params[sti_key]
|
|
63
|
+
return unless sti_params.is_a?(::ActionController::Parameters)
|
|
64
|
+
|
|
65
|
+
base_params = params[:product]
|
|
66
|
+
base_hash = base_params.is_a?(::ActionController::Parameters) ? base_params.to_unsafe_h : {}
|
|
67
|
+
sti_hash = sti_params.to_unsafe_h
|
|
68
|
+
merged_params = ::ActionController::Parameters.new(base_hash.merge(sti_hash))
|
|
69
|
+
|
|
70
|
+
params[:product] = merged_params
|
|
71
|
+
end
|
|
72
|
+
|
|
54
73
|
def merge_industry_taxons_into_taxons
|
|
55
74
|
return if params[:product].blank?
|
|
56
75
|
|
|
@@ -4,14 +4,30 @@
|
|
|
4
4
|
module SpreeCmCommissioner
|
|
5
5
|
module Orders
|
|
6
6
|
class Find
|
|
7
|
+
CURRENT_CART_STATES = %w[cart address].freeze
|
|
8
|
+
CART_MAX_AGE_IN_MINUTES = ENV.fetch('CART_MAX_AGE_IN_MINUTES', '720').to_i # Default: 12 hours
|
|
9
|
+
|
|
7
10
|
def execute(store:, user:, currency:, token: nil, state: nil)
|
|
11
|
+
state = Array(state).map(&:to_s)
|
|
12
|
+
|
|
8
13
|
params = { store_id: store.id, currency: currency }
|
|
9
14
|
params[:state] = state if state.present?
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
order = if token.present?
|
|
17
|
+
find_by_token(params, token)
|
|
18
|
+
elsif user.present?
|
|
19
|
+
find_by_user(params, user)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Only enforce hold and age expiration when fetching current cart states ('cart' or 'address').
|
|
23
|
+
# For other states (like 'payment,complete'), we want to return the order even if it's old or expired
|
|
24
|
+
# because some pages on client still need some specific state of order to display.
|
|
25
|
+
if state.intersect?(CURRENT_CART_STATES)
|
|
26
|
+
return nil if hold_expired?(order)
|
|
27
|
+
return nil if cart_too_old?(order)
|
|
28
|
+
end
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
order
|
|
15
31
|
end
|
|
16
32
|
|
|
17
33
|
def find_by_token(params, token)
|
|
@@ -24,6 +40,20 @@ module SpreeCmCommissioner
|
|
|
24
40
|
scope.order(created_at: :desc).find_by(params)
|
|
25
41
|
end
|
|
26
42
|
|
|
43
|
+
def hold_expired?(order)
|
|
44
|
+
return false if order.nil?
|
|
45
|
+
|
|
46
|
+
# Check if the order has a hold_expires_at column and if it has already passed
|
|
47
|
+
order.hold_expires_at.present? && order.hold_expires_at < Time.current
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def cart_too_old?(order)
|
|
51
|
+
return false if order.nil?
|
|
52
|
+
|
|
53
|
+
# Treat the cart as active based on its last update time, not its creation time.
|
|
54
|
+
order.updated_at < CART_MAX_AGE_IN_MINUTES.minutes.ago
|
|
55
|
+
end
|
|
56
|
+
|
|
27
57
|
private
|
|
28
58
|
|
|
29
59
|
def scope
|
|
@@ -3,8 +3,11 @@ require 'google/cloud/firestore'
|
|
|
3
3
|
# TODO: alert when available_slots is negative.
|
|
4
4
|
module SpreeCmCommissioner
|
|
5
5
|
class WaitingGuestsCaller < BaseInteractor
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
# 10 min floor — Waiting Room step (full journey, most uncertainty)
|
|
7
|
+
MIN_WAIT_TO_ENTER_SECONDS = (ENV['WAITING_ROOM_MIN_WAIT_TO_ENTER_SECONDS'] || 600).to_i
|
|
8
|
+
|
|
9
|
+
# 5 min floor — Queue step (position assigned, sub-segment of the journey)
|
|
10
|
+
MIN_QUEUE_TO_ENTER_SECONDS = (ENV['WAITING_ROOM_MIN_QUEUE_TO_ENTER_SECONDS'] || 300).to_i
|
|
8
11
|
|
|
9
12
|
# Firestore bounds a batch update by payload size (10 MiB); 500 ops/commit leaves us far under that.
|
|
10
13
|
FIRESTORE_BATCH_SIZE = (ENV['WAITING_ROOM_FIRESTORE_BATCH_SIZE'] || 500).to_i
|
|
@@ -20,7 +23,8 @@ module SpreeCmCommissioner
|
|
|
20
23
|
full: long_waiting_guests.size >= available_slots,
|
|
21
24
|
available_slots: available_slots - long_waiting_guests.size,
|
|
22
25
|
avg_wait_to_enter_seconds: compute_avg_wait_to_enter_seconds(long_waiting_guests),
|
|
23
|
-
avg_queue_to_enter_seconds: compute_avg_queue_to_enter_seconds(long_waiting_guests)
|
|
26
|
+
avg_queue_to_enter_seconds: compute_avg_queue_to_enter_seconds(long_waiting_guests),
|
|
27
|
+
slots_per_call: available_slots
|
|
24
28
|
)
|
|
25
29
|
end
|
|
26
30
|
|
|
@@ -96,10 +100,18 @@ module SpreeCmCommissioner
|
|
|
96
100
|
end
|
|
97
101
|
|
|
98
102
|
# merge: true so we preserve the published `waiting_guests_records_path` on the lobby doc.
|
|
99
|
-
def mark_as(
|
|
103
|
+
def mark_as(
|
|
104
|
+
full:,
|
|
105
|
+
available_slots:,
|
|
106
|
+
avg_wait_to_enter_seconds: nil,
|
|
107
|
+
avg_queue_to_enter_seconds: nil,
|
|
108
|
+
slots_per_call: nil
|
|
109
|
+
)
|
|
100
110
|
data = { full: full, available_slots: available_slots }
|
|
101
111
|
data[:avg_wait_to_enter_seconds] = avg_wait_to_enter_seconds if avg_wait_to_enter_seconds
|
|
102
112
|
data[:avg_queue_to_enter_seconds] = avg_queue_to_enter_seconds if avg_queue_to_enter_seconds
|
|
113
|
+
data[:slots_per_call] = slots_per_call if slots_per_call
|
|
114
|
+
|
|
103
115
|
lobby_document.set(data, merge: true)
|
|
104
116
|
end
|
|
105
117
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module IdempotentJob
|
|
3
|
+
def with_idempotency(key = nil, &block)
|
|
4
|
+
SpreeCmCommissioner::IdempotencyKey.run_once(key.presence || default_idempotency_key, &block)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# Namespaced so the key is self-describing in the DB (no `source` column needed).
|
|
8
|
+
def default_idempotency_key
|
|
9
|
+
"#{self.class.name}:#{job_id}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class CancelImportOrderJob < ApplicationUniqueJob
|
|
3
|
+
def perform(options = {})
|
|
4
|
+
SpreeCmCommissioner::Imports::Orders::Cancel.new(
|
|
5
|
+
import_order_id: options[:import_order_id],
|
|
6
|
+
canceled_by_user_id: options[:canceled_by_user_id],
|
|
7
|
+
cancellation_reason: options[:cancellation_reason]
|
|
8
|
+
).call
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Prunes old idempotency keys. Keys only matter within the retry window
|
|
2
|
+
# (minutes–hours), so anything older than the cutoff is safe to delete.
|
|
3
|
+
# The `created_at` index supports the delete.
|
|
4
|
+
module SpreeCmCommissioner
|
|
5
|
+
module IdempotencyKeys
|
|
6
|
+
class PruneJob < SpreeCmCommissioner::ApplicationJob
|
|
7
|
+
DEFAULT_CUTOFF_DAYS = 3
|
|
8
|
+
|
|
9
|
+
queue_as :default
|
|
10
|
+
|
|
11
|
+
def perform(cutoff_days = DEFAULT_CUTOFF_DAYS)
|
|
12
|
+
days = [cutoff_days.to_i, 1].max
|
|
13
|
+
|
|
14
|
+
SpreeCmCommissioner::IdempotencyKey
|
|
15
|
+
.where(created_at: ...days.days.ago)
|
|
16
|
+
.delete_all
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|