spree_cm_commissioner 2.8.2 → 2.8.3.pre.pre4
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 +0 -1
- data/.gitignore +4 -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/taxons_controller_decorator.rb +19 -0
- data/app/controllers/spree/api/v2/storefront/homepage_sections_controller.rb +1 -0
- 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/trip_search_controller.rb +1 -0
- data/app/controllers/spree/api/v2/tenant/advertisements_controller.rb +24 -0
- data/app/controllers/spree/api/v2/tenant/base_controller.rb +4 -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/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 +34 -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 +40 -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/helpers/spree_cm_commissioner/admin/homepage_segment_helper.rb +2 -0
- data/app/jobs/spree_cm_commissioner/cleanup_expired_access_tokens_job.rb +9 -0
- data/app/jobs/spree_cm_commissioner/show_contestants/import_job.rb +9 -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/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb +2 -1
- data/app/models/concerns/spree_cm_commissioner/line_item_transitable.rb +0 -8
- 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 +10 -0
- data/app/models/concerns/spree_cm_commissioner/product_type.rb +1 -1
- data/app/models/concerns/spree_cm_commissioner/store_preference.rb +0 -1
- 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/import.rb +1 -1
- data/app/models/spree_cm_commissioner/imports/import_contestant.rb +7 -0
- data/app/models/spree_cm_commissioner/inventory_item.rb +2 -17
- data/app/models/spree_cm_commissioner/maintenance_tasks/cache_invalidation.rb +0 -2
- data/app/models/spree_cm_commissioner/maintenance_tasks/voting_session.rb +36 -0
- data/app/models/spree_cm_commissioner/preview_role.rb +8 -0
- data/app/models/spree_cm_commissioner/product_decorator.rb +50 -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/route.rb +1 -6
- 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 +110 -0
- data/app/models/spree_cm_commissioner/show_person.rb +15 -0
- data/app/models/spree_cm_commissioner/show_person_assignment.rb +20 -0
- data/app/models/spree_cm_commissioner/show_person_image.rb +11 -0
- data/app/models/spree_cm_commissioner/stock_item_decorator.rb +3 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +18 -7
- 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/trip.rb +0 -5
- data/app/models/spree_cm_commissioner/user_decorator.rb +5 -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 +61 -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 +215 -0
- data/app/models/spree_cm_commissioner/voting_session_stat.rb +8 -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 +0 -9
- data/app/overrides/spree/admin/taxons/_form/preview_checkbox.html.erb.deface +7 -0
- data/app/queries/spree_cm_commissioner/multi_leg_trips_query.rb +44 -26
- data/app/queries/spree_cm_commissioner/single_leg_trips_query.rb +31 -36
- data/app/queries/spree_cm_commissioner/trip_query.rb +4 -2
- 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 +2 -1
- data/app/serializers/spree/v2/tenant/advertisement_serializer.rb +11 -0
- data/app/serializers/spree/v2/tenant/campaign_serializer.rb +13 -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 +17 -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 +19 -0
- data/app/serializers/spree/v2/tenant/video_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 +22 -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 +19 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/trip_result_serializer.rb +2 -7
- data/app/services/spree_cm_commissioner/advertisements/weight_validator.rb +43 -0
- data/app/services/spree_cm_commissioner/api_caches/invalidate.rb +12 -0
- data/app/services/spree_cm_commissioner/cleanup_expired_access_tokens.rb +52 -0
- 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/pricing_models/preview.rb +6 -15
- data/app/services/spree_cm_commissioner/routes/create.rb +5 -0
- data/app/services/spree_cm_commissioner/show_contestants/normalize_video_highlights.rb +57 -0
- data/app/services/spree_cm_commissioner/trips/create_multi_leg.rb +16 -5
- data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +1 -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 +334 -0
- data/app/services/spree_cm_commissioner/voting_contestants/assigner.rb +32 -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 +183 -0
- data/app/services/spree_cm_commissioner/voting_sessions/finalize.rb +66 -0
- data/app/views/spree/admin/homepage_section/_form.html.erb +5 -0
- data/config/initializers/spree_permitted_attributes.rb +8 -1
- data/config/locales/en.yml +36 -0
- data/config/locales/km.yml +18 -0
- data/config/routes.rb +27 -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/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/trip_result.rb +21 -48
- 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 +129 -10
- data/app/factory/spree_cm_commissioner/event_telegram_message_factory.rb +0 -68
- data/app/jobs/spree_cm_commissioner/event_creation_telegram_alert_sender_job.rb +0 -10
- data/app/jobs/spree_cm_commissioner/oauth_access_tokens/cleanup_expired_job.rb +0 -11
- data/app/models/concerns/spree_cm_commissioner/service_origin.rb +0 -22
- data/app/services/spree_cm_commissioner/oauth_access_tokens/cleanup_expired.rb +0 -53
- data/app/services/spree_cm_commissioner/telegram_alerts/event_creation.rb +0 -35
|
@@ -0,0 +1,34 @@
|
|
|
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, episodes: :voting_sessions, seasons: { episodes: :voting_sessions })
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# override
|
|
27
|
+
def resource_serializer
|
|
28
|
+
Spree::V2::Tenant::ShowSerializer
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
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,40 @@
|
|
|
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(show_contestant: :show_contestant_images)
|
|
13
|
+
.order(:id)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# override
|
|
17
|
+
def collection_serializer
|
|
18
|
+
Spree::V2::Tenant::VotingContestantSerializer
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# override
|
|
24
|
+
def model_class
|
|
25
|
+
SpreeCmCommissioner::VotingSession
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# override
|
|
29
|
+
def scope
|
|
30
|
+
current_vendor.voting_sessions.includes(:episode)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def load_voting_session
|
|
34
|
+
@voting_session = scope.find(params[:voting_session_id])
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
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
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class VotingCreditAllocationJob < ApplicationUniqueJob
|
|
3
|
+
def perform(options = {})
|
|
4
|
+
order = Spree::Order.find_by(id: options[:order_id])
|
|
5
|
+
return if order.nil?
|
|
6
|
+
|
|
7
|
+
SpreeCmCommissioner::VotingCredits::Allocate.new(order).call
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class VotingCreditDeAllocationJob < ApplicationUniqueJob
|
|
3
|
+
def perform(options = {})
|
|
4
|
+
order = Spree::Order.find_by(id: options[:order_id])
|
|
5
|
+
return if order.nil?
|
|
6
|
+
|
|
7
|
+
SpreeCmCommissioner::VotingCredits::DeAllocate.new(order).call
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -23,8 +23,6 @@ module SpreeCmCommissioner
|
|
|
23
23
|
TripKey = Struct.new(:trip_id, :direction, :boarding_trip_stop_id, :drop_off_trip_stop_id)
|
|
24
24
|
|
|
25
25
|
included do
|
|
26
|
-
include SpreeCmCommissioner::ServiceOrigin
|
|
27
|
-
|
|
28
26
|
validates :direction, inclusion: { in: DIRECTION }, allow_nil: true
|
|
29
27
|
validates :trip_id, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
|
30
28
|
validates :service_origin_id, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
|
@@ -127,12 +125,6 @@ module SpreeCmCommissioner
|
|
|
127
125
|
|
|
128
126
|
private
|
|
129
127
|
|
|
130
|
-
def resolve_service_origin_id
|
|
131
|
-
return nil if trip_id.blank?
|
|
132
|
-
|
|
133
|
-
SpreeCmCommissioner::Trip.find_by(id: trip_id)&.service_origin_id
|
|
134
|
-
end
|
|
135
|
-
|
|
136
128
|
def validate_trip_stops_for_scheduled_trips
|
|
137
129
|
return if trip_id.blank? || trip_id.zero?
|
|
138
130
|
|
|
@@ -26,8 +26,10 @@ module SpreeCmCommissioner
|
|
|
26
26
|
|
|
27
27
|
state_machine.after_transition to: :canceled, do: :precalculate_conversion
|
|
28
28
|
state_machine.after_transition to: :canceled, do: :restock_inventory!
|
|
29
|
+
state_machine.after_transition to: :canceled, do: :de_allocate_resources
|
|
29
30
|
|
|
30
31
|
state_machine.after_transition to: :complete, do: :increment_route_fulfilled_order_count
|
|
32
|
+
state_machine.after_transition to: :complete, do: :allocate_resources
|
|
31
33
|
|
|
32
34
|
scope :accepted, -> { where(request_state: 'accepted') }
|
|
33
35
|
|
|
@@ -328,5 +330,13 @@ module SpreeCmCommissioner
|
|
|
328
330
|
factory = OrderTelegramMessageFactory.new(title: title, order: self)
|
|
329
331
|
TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
|
|
330
332
|
end
|
|
333
|
+
|
|
334
|
+
def allocate_resources
|
|
335
|
+
SpreeCmCommissioner::VotingCreditAllocationJob.perform_later(order_id: id)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def de_allocate_resources
|
|
339
|
+
SpreeCmCommissioner::VotingCreditDeAllocationJob.perform_later(order_id: id)
|
|
340
|
+
end
|
|
331
341
|
end
|
|
332
342
|
end
|
|
@@ -5,7 +5,7 @@ module SpreeCmCommissioner
|
|
|
5
5
|
module ProductType
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
7
|
|
|
8
|
-
PRODUCT_TYPES = %i[accommodation service ecommerce transit].freeze
|
|
8
|
+
PRODUCT_TYPES = %i[accommodation service ecommerce transit show_episode vote_package advertisement].freeze
|
|
9
9
|
PERMANENT_STOCK_PRODUCT_TYPES = %w[accommodation service transit].freeze
|
|
10
10
|
PRE_INVENTORY_DAYS = { 'transit' => 90, 'accommodation' => 365, 'service' => 30 }.freeze
|
|
11
11
|
|
|
@@ -7,7 +7,6 @@ module SpreeCmCommissioner
|
|
|
7
7
|
preference :telegram_order_alert_chat_id, :string
|
|
8
8
|
preference :telegram_order_request_alert_chat_id, :string
|
|
9
9
|
preference :telegram_new_vendor_alert_chat_id, :string
|
|
10
|
-
preference :telegram_new_event_alert_chat_id, :string
|
|
11
10
|
preference :assetlinks, :string, default: ''
|
|
12
11
|
preference :apple_app_site_association, :string, default: ''
|
|
13
12
|
end
|
|
@@ -3,7 +3,9 @@ module SpreeCmCommissioner
|
|
|
3
3
|
extend ActiveSupport::Concern
|
|
4
4
|
|
|
5
5
|
included do
|
|
6
|
-
enum kind: { category: 0, cms: 1, event: 2, occupation: 3, nationality: 4, organization: 5, transit: 6, industry: 7, agency_category: 8
|
|
6
|
+
enum kind: { category: 0, cms: 1, event: 2, occupation: 3, nationality: 4, organization: 5, transit: 6, industry: 7, agency_category: 8,
|
|
7
|
+
ads: 9
|
|
8
|
+
}
|
|
7
9
|
end
|
|
8
10
|
end
|
|
9
11
|
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module VotingSessionLiveStreamConcern
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
store_public_metadata :live_stream_url, :string
|
|
7
|
+
store_public_metadata :live_stream_enabled, :boolean
|
|
8
|
+
store_public_metadata :live_stream_thumbnail, :string
|
|
9
|
+
store_public_metadata :live_stream_title, :string
|
|
10
|
+
store_public_metadata :live_stream_description, :text
|
|
11
|
+
|
|
12
|
+
validate :validate_live_stream_url, if: :live_stream_url_changed?
|
|
13
|
+
before_save :update_live_stream_thumbnail
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def embedded_live_stream_url
|
|
17
|
+
return nil if live_stream_url.blank?
|
|
18
|
+
|
|
19
|
+
result = SpreeCmCommissioner::UrlEmbed::YoutubeEmbed.call(url: live_stream_url)
|
|
20
|
+
result.success? ? result.value : nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def validate_live_stream_url
|
|
26
|
+
return if live_stream_url.blank?
|
|
27
|
+
|
|
28
|
+
result = SpreeCmCommissioner::UrlEmbed::YoutubeEmbed.call(url: live_stream_url)
|
|
29
|
+
return if result.success?
|
|
30
|
+
|
|
31
|
+
errors.add(:live_stream_url, result.error)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def update_live_stream_thumbnail
|
|
35
|
+
return if live_stream_url.blank?
|
|
36
|
+
|
|
37
|
+
video_id = SpreeCmCommissioner::UrlEmbed::YoutubeEmbed.extract_video_id(live_stream_url)
|
|
38
|
+
self.live_stream_thumbnail = "https://img.youtube.com/vi/#{video_id}/hqdefault.jpg" if video_id
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -3,7 +3,7 @@ module SpreeCmCommissioner
|
|
|
3
3
|
extend FriendlyId
|
|
4
4
|
|
|
5
5
|
enum :status, { :queue => 0, :progress => 1, :done => 2, :failed => 3 }
|
|
6
|
-
enum :import_type, { :new_order => 0, :existing_order => 1, :aba_payment_reference => 2 }
|
|
6
|
+
enum :import_type, { :new_order => 0, :existing_order => 1, :aba_payment_reference => 2, :contestant_import => 3 }
|
|
7
7
|
has_one_attached :imported_file
|
|
8
8
|
friendly_id :name, use: :slugged
|
|
9
9
|
|
|
@@ -23,23 +23,8 @@ module SpreeCmCommissioner
|
|
|
23
23
|
|
|
24
24
|
before_save -> { self.product_type = variant.product_type }, if: -> { product_type.nil? }
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# Only for ecommerce: the app uses product.in_stock? (derived from quantity_available) for product cards.
|
|
29
|
-
# Other types (e.g. accommodation, bus) have many inventory items (including daily-generated ones),
|
|
30
|
-
# so invalidating per item would flood the task queue.
|
|
31
|
-
#
|
|
32
|
-
# This is temporary until we have a more robust cache invalidation strategy in place.
|
|
33
|
-
def schedule_product_cache_invalidation
|
|
34
|
-
return unless ecommerce?
|
|
35
|
-
return unless saved_change_to_quantity_available?
|
|
36
|
-
|
|
37
|
-
# Only fires on in_stock status transition (0 ↔ N); non-zero to non-zero changes are skipped.
|
|
38
|
-
old_val, new_val = saved_change_to_quantity_available
|
|
39
|
-
return if old_val.to_i.positive? && new_val.to_i.positive?
|
|
40
|
-
|
|
41
|
-
SpreeCmCommissioner::MaintenanceTasks::CacheInvalidation.pending.create_or_find_by(maintainable: variant.product)
|
|
42
|
-
end
|
|
26
|
+
# Create maintaining task to purge product related caches
|
|
27
|
+
after_commit { SpreeCmCommissioner::MaintenanceTasks::CacheInvalidation.pending.create_or_find_by(maintainable: variant.product) }
|
|
43
28
|
|
|
44
29
|
def public_quantity_available
|
|
45
30
|
[quantity_available, MAX_DISPLAY_STOCK].min
|
|
@@ -3,8 +3,6 @@ module SpreeCmCommissioner
|
|
|
3
3
|
module MaintenanceTasks
|
|
4
4
|
class CacheInvalidation < MaintenanceTask
|
|
5
5
|
def maintain
|
|
6
|
-
return if ENV['CACHE_AUTO_INVALIDATION_DISABLED'] == 'yes'
|
|
7
|
-
|
|
8
6
|
if maintainable.is_a?(SpreeCmCommissioner::HomepageBackground) || maintainable.is_a?(Spree::Menu)
|
|
9
7
|
SpreeCmCommissioner::HomepageDataLoader.clear_cache
|
|
10
8
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Reconciles Redis vote counters against cm_votes for a specific voting session.
|
|
2
|
+
#
|
|
3
|
+
# Created automatically by VoteProcessor when Redis is unavailable during a vote —
|
|
4
|
+
# VoteProcessor skips async_execute (Sidekiq also needs Redis) and just creates
|
|
5
|
+
# the DB row so OrchestrateJob's cron can pick it up once Redis recovers.
|
|
6
|
+
#
|
|
7
|
+
# `maintain` runs three steps in order:
|
|
8
|
+
# 1. RebuildFromDb — overwrites Redis counters with DB totals (source of truth)
|
|
9
|
+
# 2. AuditCounters — logs any remaining mismatches between Redis and DB
|
|
10
|
+
# 3. SnapshotToDb — writes final aggregates to cm_voting_contestants and cm_voting_session_stats
|
|
11
|
+
#
|
|
12
|
+
# maintainable: SpreeCmCommissioner::VotingSession
|
|
13
|
+
#
|
|
14
|
+
# Trigger on-demand:
|
|
15
|
+
# MaintenanceTasks::VotingSession.create!(maintainable: session).async_execute
|
|
16
|
+
module SpreeCmCommissioner
|
|
17
|
+
module MaintenanceTasks
|
|
18
|
+
class VotingSession < MaintenanceTask
|
|
19
|
+
def maintain
|
|
20
|
+
ttl = rebuild_ttl
|
|
21
|
+
SpreeCmCommissioner::VoteCounters::RebuildFromDb.call(voting_session_id: maintainable.id, ttl: ttl)
|
|
22
|
+
SpreeCmCommissioner::VoteCounters::AuditCounters.call(voting_session_id: maintainable.id)
|
|
23
|
+
SpreeCmCommissioner::VoteCounters::SnapshotToDb.call(voting_session_id: maintainable.id)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# For closed sessions use the fixed 24h constant — closes_at is in the past
|
|
27
|
+
# so the dynamic formula would produce a TTL shorter than intended.
|
|
28
|
+
# For active sessions use closes_at + 24h buffer (same formula as Increment).
|
|
29
|
+
def rebuild_ttl
|
|
30
|
+
return SpreeCmCommissioner::VoteCounters::Base::REDIS_KEY_TTL if maintainable.closed?
|
|
31
|
+
|
|
32
|
+
[(maintainable.closes_at - Time.current).to_i + 1.day.to_i, 1].max
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class PreviewRole < Base
|
|
3
|
+
belongs_to :previewable, polymorphic: true, optional: false
|
|
4
|
+
belongs_to :role, class_name: 'Spree::Role', optional: false
|
|
5
|
+
|
|
6
|
+
validates :role_id, uniqueness: { scope: %i[previewable_type previewable_id] }
|
|
7
|
+
end
|
|
8
|
+
end
|