spree_cm_commissioner 2.8.3.pre.pre13 → 2.8.4.pre.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test_and_build_gem.yml +1 -2
- data/.gitignore +0 -6
- data/Gemfile.lock +1 -1
- data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +0 -2
- data/app/controllers/spree/admin/homepage_section_controller.rb +1 -4
- data/app/controllers/spree/admin/taxons_controller_decorator.rb +5 -19
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +7 -5
- 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/interactors/spree_cm_commissioner/waiting_guests_caller.rb +38 -4
- data/app/jobs/spree_cm_commissioner/waiting_room/stamp_queue_positions_job.rb +84 -0
- data/app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb +1 -2
- data/app/models/concerns/spree_cm_commissioner/line_item_guests_concern.rb +16 -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/concerns/spree_cm_commissioner/taxon_kind.rb +1 -3
- data/app/models/spree_cm_commissioner/import.rb +1 -1
- data/app/models/spree_cm_commissioner/product_decorator.rb +0 -52
- data/app/models/spree_cm_commissioner/role_decorator.rb +1 -4
- data/app/models/spree_cm_commissioner/taxon_ad_banner.rb +12 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +1 -23
- data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +1 -19
- 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_decorator.rb +0 -4
- data/app/models/spree_cm_commissioner/variant_options.rb +0 -4
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +0 -4
- data/app/overrides/spree/admin/taxons/_form/assets_form.html.erb.deface +10 -1
- data/app/serializers/spree/v2/storefront/homepage_section_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/product_serializer_decorator.rb +1 -2
- data/app/serializers/spree/v2/storefront/role_serializer.rb +1 -1
- data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +3 -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/services/spree_cm_commissioner/cart/add_guest.rb +6 -1
- data/app/services/spree_cm_commissioner/cart/create_guest.rb +61 -0
- data/app/services/spree_cm_commissioner/cart/remove_guest.rb +6 -1
- 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 +4 -45
- data/config/locales/km.yml +2 -32
- data/config/routes.rb +1 -28
- 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 -127
- 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/ad_campaigns_controller.rb +0 -25
- data/app/controllers/spree/api/v2/tenant/episodes_controller.rb +0 -38
- 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 -36
- data/app/controllers/spree/api/v2/tenant/votes_controller.rb +0 -94
- data/app/controllers/spree/api/v2/tenant/voting_contestants_controller.rb +0 -43
- 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/show_contestants/import_job.rb +0 -9
- 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/concerns/spree_cm_commissioner/voting_session_live_stream_concern.rb +0 -41
- data/app/models/spree_cm_commissioner/imports/import_contestant.rb +0 -7
- 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 -163
- 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 -108
- data/app/models/spree_cm_commissioner/show_person.rb +0 -15
- data/app/models/spree_cm_commissioner/show_person_assignment.rb +0 -21
- 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 -20
- data/app/models/spree_cm_commissioner/voting_contestant.rb +0 -100
- 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 -216
- 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/ad_campaign_serializer.rb +0 -13
- data/app/serializers/spree/v2/tenant/advertisement_serializer.rb +0 -11
- data/app/serializers/spree/v2/tenant/show_contestant_serializer.rb +0 -21
- data/app/serializers/spree/v2/tenant/show_episode_serializer.rb +0 -20
- 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 -21
- data/app/serializers/spree/v2/tenant/video_serializer.rb +0 -9
- data/app/serializers/spree/v2/tenant/vote_package_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 -23
- 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 -21
- data/app/services/spree_cm_commissioner/fraud_check.rb +0 -299
- data/app/services/spree_cm_commissioner/imports/contestants/create.rb +0 -153
- data/app/services/spree_cm_commissioner/show_contestants/normalize_video_highlights.rb +0 -57
- data/app/services/spree_cm_commissioner/show_persons/contestant_assigner.rb +0 -51
- 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 -335
- data/app/services/spree_cm_commissioner/voting_contestants/assigner.rb +0 -40
- 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 -67
- data/app/services/spree_cm_commissioner/voting_leaderboards/combined_result.rb +0 -190
- data/app/services/spree_cm_commissioner/voting_sessions/finalize.rb +0 -105
- 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/db/migrate/20260603063652_add_parent_to_voting_sessions.rb +0 -9
- data/db/migrate/20260603090000_add_session_type_to_cm_voting_sessions.rb +0 -6
- data/db/migrate/20260608000000_add_display_to_cm_voting_sessions.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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b4cb4f14de6554d09bdd97872267ca1f23e73d144401b49a8969203e601b910
|
|
4
|
+
data.tar.gz: 454758bb34c6df3a4f1e2272b65bb19f57e7d829c06c045d7f748a72a56cb42f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3dea963b405471ddcf3a1b7819bab6d7ffca7b76f0567b6a0092262b5b8d980db83fc052c4913f06ff42921727bc4168c2c044beeeb38ddc65ef242071918f34
|
|
7
|
+
data.tar.gz: f9a841e7c01222124a041e65adf42b7e6d57b53fdc8e731c08e595dbceb601fb45fbe7ef6850df709d454b75220c4e58da2af1f8c2d0bb37d58ab00bc4c2031c
|
|
@@ -164,8 +164,7 @@ jobs:
|
|
|
164
164
|
env:
|
|
165
165
|
DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
|
|
166
166
|
run: |
|
|
167
|
-
|
|
168
|
-
bundle exec brakeman --no-threads --no-exit-on-warn
|
|
167
|
+
bundle exec brakeman --no-exit-on-warn
|
|
169
168
|
|
|
170
169
|
test:
|
|
171
170
|
needs: [setup]
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -16,7 +16,6 @@ module SpreeCmCommissioner
|
|
|
16
16
|
GuestCardClassesController
|
|
17
17
|
SeatLayoutController
|
|
18
18
|
CmsPagesController
|
|
19
|
-
AdvertisementsController
|
|
20
19
|
].freeze
|
|
21
20
|
|
|
22
21
|
# Priority 2: Semi-Static (1 hour)
|
|
@@ -26,7 +25,6 @@ module SpreeCmCommissioner
|
|
|
26
25
|
HomepageDataController
|
|
27
26
|
PopularRoutesController
|
|
28
27
|
RoutePlacesController
|
|
29
|
-
ShowsController
|
|
30
28
|
].freeze
|
|
31
29
|
|
|
32
30
|
# Priority 3: Moderate Freshness (30 minutes)
|
|
@@ -51,10 +51,7 @@ module Spree
|
|
|
51
51
|
def permitted_resource_params
|
|
52
52
|
segment_value = helpers.calculate_segment_value(params[:spree_cm_commissioner_homepage_section])
|
|
53
53
|
|
|
54
|
-
params
|
|
55
|
-
.require(:spree_cm_commissioner_homepage_section)
|
|
56
|
-
.permit(:title, :description, :active, :tenant_id, :preview)
|
|
57
|
-
.merge(segment: segment_value)
|
|
54
|
+
params.require(:spree_cm_commissioner_homepage_section).permit(:title, :description, :active, :tenant_id).merge(segment: segment_value)
|
|
58
55
|
end
|
|
59
56
|
|
|
60
57
|
def load_tenants
|
|
@@ -3,7 +3,6 @@ module Spree
|
|
|
3
3
|
module TaxonsControllerDecorator
|
|
4
4
|
def self.prepended(base)
|
|
5
5
|
base.before_action :build_assets, only: %i[create update]
|
|
6
|
-
base.before_action :normalize_sti_taxon_params, only: %i[create update]
|
|
7
6
|
end
|
|
8
7
|
|
|
9
8
|
# override
|
|
@@ -28,6 +27,10 @@ module Spree
|
|
|
28
27
|
remove_asset(@taxon.home_banner)
|
|
29
28
|
end
|
|
30
29
|
|
|
30
|
+
def remove_ad_banner
|
|
31
|
+
remove_asset(@taxon.ad_banner)
|
|
32
|
+
end
|
|
33
|
+
|
|
31
34
|
def remove_video_banner
|
|
32
35
|
remove_asset(@taxon.video_banner)
|
|
33
36
|
end
|
|
@@ -49,26 +52,9 @@ module Spree
|
|
|
49
52
|
@taxon.build_app_banner(attachment: permitted_resource_params.delete(:app_banner)) if permitted_resource_params[:app_banner]
|
|
50
53
|
@taxon.build_web_banner(attachment: permitted_resource_params.delete(:web_banner)) if permitted_resource_params[:web_banner]
|
|
51
54
|
@taxon.build_home_banner(attachment: permitted_resource_params.delete(:home_banner)) if permitted_resource_params[:home_banner]
|
|
55
|
+
@taxon.build_ad_banner(attachment: permitted_resource_params.delete(:ad_banner)) if permitted_resource_params[:ad_banner]
|
|
52
56
|
@taxon.build_video_banner(attachment: permitted_resource_params.delete(:video_banner)) if permitted_resource_params[:video_banner]
|
|
53
57
|
end
|
|
54
|
-
|
|
55
|
-
# Some admin forms submit STI records under their class key
|
|
56
|
-
# (e.g. :spree_cm_commissioner_show) while Spree update reads :taxon.
|
|
57
|
-
# Merge both into :taxon so all edited fields are persisted.
|
|
58
|
-
def normalize_sti_taxon_params
|
|
59
|
-
return unless @taxon
|
|
60
|
-
|
|
61
|
-
sti_key = @taxon.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[:taxon]
|
|
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[:taxon] = merged_params
|
|
71
|
-
end
|
|
72
58
|
end
|
|
73
59
|
end
|
|
74
60
|
end
|
|
@@ -31,13 +31,15 @@ module Spree
|
|
|
31
31
|
def create
|
|
32
32
|
spree_authorize! :update, spree_current_order, order_token
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
result = SpreeCmCommissioner::Cart::CreateGuest.call(
|
|
35
|
+
line_item: parent,
|
|
36
|
+
options: guest_params
|
|
37
|
+
)
|
|
35
38
|
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
-
render_serialized_payload(201) { serialize_resource(resource) }
|
|
39
|
+
if result.success?
|
|
40
|
+
render_serialized_payload(201) { serialize_resource(result.value) }
|
|
39
41
|
else
|
|
40
|
-
render_error_payload(
|
|
42
|
+
render_error_payload(result.value.errors, 422)
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -6,7 +6,6 @@ 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]
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
# Override
|
|
@@ -52,24 +51,6 @@ module SpreeCmCommissioner
|
|
|
52
51
|
|
|
53
52
|
protected
|
|
54
53
|
|
|
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
|
-
|
|
73
54
|
def merge_industry_taxons_into_taxons
|
|
74
55
|
return if params[:product].blank?
|
|
75
56
|
|
|
@@ -3,6 +3,9 @@ require 'google/cloud/firestore'
|
|
|
3
3
|
# TODO: alert when available_slots is negative.
|
|
4
4
|
module SpreeCmCommissioner
|
|
5
5
|
class WaitingGuestsCaller < BaseInteractor
|
|
6
|
+
MIN_WAIT_TO_ENTER_SECONDS = 120 # 2 min floor — Waiting Room step (full journey, more uncertainty)
|
|
7
|
+
MIN_QUEUE_TO_ENTER_SECONDS = 60 # 1 min floor — Queue step (position assigned, one caller cycle minimum)
|
|
8
|
+
|
|
6
9
|
def call
|
|
7
10
|
available_slots = fetch_available_slots
|
|
8
11
|
return unless available_slots.positive?
|
|
@@ -10,7 +13,12 @@ module SpreeCmCommissioner
|
|
|
10
13
|
long_waiting_guests = fetch_long_waiting_guests(available_slots)
|
|
11
14
|
calling_all(long_waiting_guests)
|
|
12
15
|
|
|
13
|
-
mark_as(
|
|
16
|
+
mark_as(
|
|
17
|
+
full: long_waiting_guests.size >= available_slots,
|
|
18
|
+
available_slots: available_slots - long_waiting_guests.size,
|
|
19
|
+
avg_wait_to_enter_seconds: compute_avg_wait_to_enter_seconds(long_waiting_guests),
|
|
20
|
+
avg_queue_to_enter_seconds: compute_avg_queue_to_enter_seconds(long_waiting_guests)
|
|
21
|
+
)
|
|
14
22
|
end
|
|
15
23
|
|
|
16
24
|
def fetch_available_slots
|
|
@@ -78,10 +86,36 @@ module SpreeCmCommissioner
|
|
|
78
86
|
1.day.ago.strftime('%Y-%m-%d')
|
|
79
87
|
end
|
|
80
88
|
|
|
81
|
-
# When open app, app request to check whether room is full or not via Firebase instead of server to minimize server requests.
|
|
82
89
|
# merge: true so we preserve the published `waiting_guests_records_path` on the lobby doc.
|
|
83
|
-
def mark_as(full:, available_slots:)
|
|
84
|
-
|
|
90
|
+
def mark_as(full:, available_slots:, avg_wait_to_enter_seconds: nil, avg_queue_to_enter_seconds: nil)
|
|
91
|
+
data = { full: full, available_slots: available_slots }
|
|
92
|
+
data[:avg_wait_to_enter_seconds] = avg_wait_to_enter_seconds if avg_wait_to_enter_seconds
|
|
93
|
+
data[:avg_queue_to_enter_seconds] = avg_queue_to_enter_seconds if avg_queue_to_enter_seconds
|
|
94
|
+
lobby_document.set(data, merge: true)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Average total wait (queued_at → allow_to_enter_room_at) for just-called guests.
|
|
98
|
+
# Used for the Waiting Room step ETA: how long until I get in from when I joined.
|
|
99
|
+
def compute_avg_wait_to_enter_seconds(guests)
|
|
100
|
+
return nil if guests.empty?
|
|
101
|
+
|
|
102
|
+
now = Time.zone.now
|
|
103
|
+
total = guests.sum { |doc| (now - doc.data[:queued_at].to_time).to_f }
|
|
104
|
+
[(total / guests.size).round, MIN_WAIT_TO_ENTER_SECONDS].max
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Average queue wait (position_set_at → allow_to_enter_room_at) for just-called guests.
|
|
108
|
+
# Used for the Queue step ETA: how long after getting a position until I actually enter.
|
|
109
|
+
# Returns nil when none of the called guests had position_set_at (first run, or no prior stamp).
|
|
110
|
+
def compute_avg_queue_to_enter_seconds(guests)
|
|
111
|
+
return nil if guests.empty?
|
|
112
|
+
|
|
113
|
+
now = Time.zone.now
|
|
114
|
+
positioned = guests.select { |doc| doc.data[:position_set_at] }
|
|
115
|
+
return nil if positioned.empty?
|
|
116
|
+
|
|
117
|
+
total = positioned.sum { |doc| (now - doc.data[:position_set_at].to_time).to_f }
|
|
118
|
+
[(total / positioned.size).round, MIN_QUEUE_TO_ENTER_SECONDS].max
|
|
85
119
|
end
|
|
86
120
|
|
|
87
121
|
def lobby_data
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'google/cloud/firestore'
|
|
2
|
+
|
|
3
|
+
module SpreeCmCommissioner
|
|
4
|
+
module WaitingRoom
|
|
5
|
+
class StampQueuePositionsJob < ApplicationJob
|
|
6
|
+
queue_as :waiting_room
|
|
7
|
+
|
|
8
|
+
STAMP_LIMIT = (ENV['WAITING_ROOM_POSITION_STAMP_LIMIT'] || 1000).to_i
|
|
9
|
+
|
|
10
|
+
def perform
|
|
11
|
+
paths = stamp_paths
|
|
12
|
+
avg_queue_to_enter = lobby_data[:avg_queue_to_enter_seconds].to_i
|
|
13
|
+
total = paths.sum { |p| waiting_count(p) }
|
|
14
|
+
return if total.zero?
|
|
15
|
+
|
|
16
|
+
stamped_at = Time.zone.now
|
|
17
|
+
global = 0
|
|
18
|
+
|
|
19
|
+
paths.each do |path|
|
|
20
|
+
remaining = STAMP_LIMIT - global
|
|
21
|
+
break if remaining <= 0
|
|
22
|
+
|
|
23
|
+
docs = waiting_query(path).order('queued_at').limit(remaining).get.to_a
|
|
24
|
+
docs.each_slice(500) do |slice|
|
|
25
|
+
firestore.batch do |b|
|
|
26
|
+
slice.each do |doc|
|
|
27
|
+
global += 1
|
|
28
|
+
data = {
|
|
29
|
+
position: global,
|
|
30
|
+
queue_total: total,
|
|
31
|
+
estimated_wait_seconds: avg_queue_to_enter,
|
|
32
|
+
status_updated_at: stamped_at
|
|
33
|
+
}
|
|
34
|
+
data[:position_set_at] = stamped_at unless doc.data[:position_set_at]
|
|
35
|
+
b.update(doc.ref, data)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def stamp_paths
|
|
45
|
+
[previous_records_path, records_path]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def records_path
|
|
49
|
+
default_records_path(Time.zone.now.strftime('%Y-%m-%d'))
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def previous_records_path
|
|
53
|
+
default_records_path(1.day.ago.strftime('%Y-%m-%d'))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def default_records_path(date)
|
|
57
|
+
"waiting_guests/#{date}/records"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def waiting_count(path)
|
|
61
|
+
waiting_query(path).aggregate_query.add_count.get.first.get.to_i
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def waiting_query(path)
|
|
65
|
+
firestore.col(path).where('allow_to_enter_room_at', '==', nil)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def lobby_data
|
|
69
|
+
@lobby_data ||= firestore.col('waiting_rooms').doc('lobby').get.data || {}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def firestore
|
|
73
|
+
@firestore ||= Google::Cloud::Firestore.new(
|
|
74
|
+
project_id: service_account[:project_id],
|
|
75
|
+
credentials: service_account
|
|
76
|
+
)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def service_account
|
|
80
|
+
@service_account ||= Rails.application.credentials.cloud_firestore_service_account
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -14,8 +14,8 @@ module SpreeCmCommissioner
|
|
|
14
14
|
validate :validate_total_kids, if: -> { valid_integer_metadata?('number_of_kids') }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def number_of_adults =
|
|
18
|
-
def number_of_kids =
|
|
17
|
+
def number_of_adults = metadata_guest_count('number_of_adults') || (variant.number_of_adults * quantity)
|
|
18
|
+
def number_of_kids = metadata_guest_count('number_of_kids') || (variant.number_of_kids * quantity)
|
|
19
19
|
def number_of_guests = number_of_adults + number_of_kids
|
|
20
20
|
|
|
21
21
|
def allowed_extra_adults = variant.allowed_extra_adults * quantity
|
|
@@ -26,6 +26,10 @@ module SpreeCmCommissioner
|
|
|
26
26
|
|
|
27
27
|
def remaining_total_guests = [number_of_guests - guests.size, 0].max
|
|
28
28
|
|
|
29
|
+
# True when the guest count is set via the public_metadata override (accommodation/transit),
|
|
30
|
+
# i.e. decoupled from quantity rather than derived from variant.number_of_guests * quantity.
|
|
31
|
+
def custom_guest_count? = public_metadata['number_of_adults'].to_i.positive? || public_metadata['number_of_kids'].to_i.positive?
|
|
32
|
+
|
|
29
33
|
def generate_remaining_guests
|
|
30
34
|
return if remaining_total_guests.zero?
|
|
31
35
|
|
|
@@ -82,6 +86,16 @@ module SpreeCmCommissioner
|
|
|
82
86
|
value.present? && value.to_s.match?(/\A-?\d+\z/)
|
|
83
87
|
end
|
|
84
88
|
|
|
89
|
+
# public_metadata override for a guest count, only when it's a non-negative integer;
|
|
90
|
+
# nil otherwise so callers fall back to the variant default. Keeps number_of_guests >= 0
|
|
91
|
+
# (a negative would make custom_guest_count? false and spin the bump loop in Cart::CreateGuest).
|
|
92
|
+
def metadata_guest_count(key)
|
|
93
|
+
return nil unless valid_integer_metadata?(key)
|
|
94
|
+
|
|
95
|
+
value = public_metadata[key].to_i
|
|
96
|
+
value.negative? ? nil : value
|
|
97
|
+
end
|
|
98
|
+
|
|
85
99
|
def validate_total_adults
|
|
86
100
|
errors.add(:quantity, 'exceed_total_adults') if public_metadata['number_of_adults'].to_i > allowed_total_adults
|
|
87
101
|
end
|
|
@@ -26,10 +26,8 @@ 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
|
|
30
29
|
|
|
31
30
|
state_machine.after_transition to: :complete, do: :increment_route_fulfilled_order_count
|
|
32
|
-
state_machine.after_transition to: :complete, do: :allocate_resources
|
|
33
31
|
|
|
34
32
|
scope :accepted, -> { where(request_state: 'accepted') }
|
|
35
33
|
|
|
@@ -330,13 +328,5 @@ module SpreeCmCommissioner
|
|
|
330
328
|
factory = OrderTelegramMessageFactory.new(title: title, order: self)
|
|
331
329
|
TelegramNotificationSenderJob.perform_later(chat_id: chat_id, message: factory.message, parse_mode: factory.parse_mode)
|
|
332
330
|
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
|
|
341
331
|
end
|
|
342
332
|
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
|
|
8
|
+
PRODUCT_TYPES = %i[accommodation service ecommerce transit].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
|
|
|
@@ -3,9 +3,7 @@ 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
|
|
7
|
-
ads: 9
|
|
8
|
-
}
|
|
6
|
+
enum kind: { category: 0, cms: 1, event: 2, occupation: 3, nationality: 4, organization: 5, transit: 6, industry: 7, agency_category: 8 }
|
|
9
7
|
end
|
|
10
8
|
end
|
|
11
9
|
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 }
|
|
7
7
|
has_one_attached :imported_file
|
|
8
8
|
friendly_id :name, use: :slugged
|
|
9
9
|
|
|
@@ -12,10 +12,6 @@ module SpreeCmCommissioner
|
|
|
12
12
|
base.include SpreeCmCommissioner::StoreMetadata
|
|
13
13
|
base.include SpreeCmCommissioner::HomepageSectionRelatableConcern
|
|
14
14
|
|
|
15
|
-
base.delegate :is_open_dated, :is_open_dated?, to: :trip, allow_nil: true
|
|
16
|
-
|
|
17
|
-
base.has_many :voting_sessions, class_name: 'SpreeCmCommissioner::VotingSession', foreign_key: :episode_id, dependent: :destroy
|
|
18
|
-
|
|
19
15
|
base.has_many :variant_kind_option_types, -> { where(kind: :variant).order(:position) },
|
|
20
16
|
through: :product_option_types, source: :option_type
|
|
21
17
|
|
|
@@ -63,45 +59,8 @@ module SpreeCmCommissioner
|
|
|
63
59
|
|
|
64
60
|
base.belongs_to :event, class_name: 'Spree::Taxon', optional: true
|
|
65
61
|
|
|
66
|
-
base.has_many :preview_roles, class_name: 'SpreeCmCommissioner::PreviewRole', as: :previewable
|
|
67
62
|
base.has_many :industry_classifications, -> { joins(:taxon).where(spree_taxons: { kind: :industry }) }, class_name: 'Spree::Classification'
|
|
68
63
|
base.has_many :industry_taxons, through: :industry_classifications, source: :taxon
|
|
69
|
-
base.scope :visible_to, lambda { |user|
|
|
70
|
-
publicly_available = where(status: :active, preview: false)
|
|
71
|
-
|
|
72
|
-
if user
|
|
73
|
-
# Resolved through associations — avoids hardcoding class names.
|
|
74
|
-
taxon_type = reflect_on_association(:taxons).klass.polymorphic_name
|
|
75
|
-
|
|
76
|
-
# IDs of products that have been explicitly assigned their own PreviewRole.
|
|
77
|
-
products_with_own_roles = SpreeCmCommissioner::PreviewRole
|
|
78
|
-
.where(previewable_type: polymorphic_name)
|
|
79
|
-
.select(:previewable_id)
|
|
80
|
-
|
|
81
|
-
# Path A: product has its own PreviewRole → user must hold that role directly.
|
|
82
|
-
# Taxon membership is irrelevant for these products.
|
|
83
|
-
via_product_role = where(status: :active, preview: true)
|
|
84
|
-
.where(id: products_with_own_roles)
|
|
85
|
-
.where(id: user.preview_roles.where(previewable_type: polymorphic_name).select(:previewable_id))
|
|
86
|
-
|
|
87
|
-
# Path B: product has no own PreviewRole → inherit access from its event or taxons.
|
|
88
|
-
# Accessible if the user holds a preview role for the product's event_id or any
|
|
89
|
-
# taxon the product belongs to via the classifications join table.
|
|
90
|
-
allowed_taxon_ids = user.preview_roles.where(previewable_type: taxon_type).select(:previewable_id)
|
|
91
|
-
preview_no_own = where(status: :active, preview: true).where.not(id: products_with_own_roles)
|
|
92
|
-
|
|
93
|
-
via_event_id = preview_no_own.where(event_id: allowed_taxon_ids)
|
|
94
|
-
via_taxon_join = preview_no_own.joins(:taxons).where(spree_taxons: { id: allowed_taxon_ids })
|
|
95
|
-
|
|
96
|
-
publicly_available
|
|
97
|
-
.or(via_product_role)
|
|
98
|
-
.or(where(id: via_event_id.select(:id)))
|
|
99
|
-
.or(where(id: via_taxon_join.select(:id)))
|
|
100
|
-
else
|
|
101
|
-
publicly_available
|
|
102
|
-
end
|
|
103
|
-
}
|
|
104
|
-
|
|
105
64
|
base.scope :min_price, lambda { |vendor|
|
|
106
65
|
joins(:prices_including_master)
|
|
107
66
|
.where(vendor_id: vendor.id, product_type: vendor.primary_product_type)
|
|
@@ -114,12 +73,6 @@ module SpreeCmCommissioner
|
|
|
114
73
|
.maximum('spree_prices.price').to_f
|
|
115
74
|
}
|
|
116
75
|
base.scope :subscribable, -> { where(subscribable: 1) }
|
|
117
|
-
base.scope :advertisements, lambda {
|
|
118
|
-
advertisement
|
|
119
|
-
.available
|
|
120
|
-
.where('spree_products.available_on IS NULL OR spree_products.available_on <= CURRENT_TIMESTAMP')
|
|
121
|
-
.where('spree_products.discontinue_on IS NULL OR spree_products.discontinue_on > CURRENT_TIMESTAMP')
|
|
122
|
-
}
|
|
123
76
|
|
|
124
77
|
base.before_validation :set_event_id
|
|
125
78
|
|
|
@@ -133,11 +86,6 @@ module SpreeCmCommissioner
|
|
|
133
86
|
base.store_public_metadata :open_dated_validity_days, :integer, default: 90
|
|
134
87
|
base.store_public_metadata :enable_inventory_hold, :boolean, default: false
|
|
135
88
|
|
|
136
|
-
base.store_private_metadata :advertise_weight, :integer, default: 1
|
|
137
|
-
base.store_private_metadata :video_url, :string
|
|
138
|
-
base.store_private_metadata :skip_after_seconds, :integer, default: 5
|
|
139
|
-
base.store_private_metadata :duration_seconds, :integer, default: 30
|
|
140
|
-
|
|
141
89
|
base.after_update :update_variants_vendor_id, if: :saved_change_to_vendor_id?
|
|
142
90
|
base.after_update :sync_event_id_to_children, if: :saved_change_to_event_id?
|
|
143
91
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
module RoleDecorator
|
|
3
3
|
def self.prepended(base)
|
|
4
|
-
base.enum role_type: { internal: 0, external: 1
|
|
4
|
+
base.enum role_type: { internal: 0, external: 1 }
|
|
5
5
|
|
|
6
6
|
base.has_many :role_permissions, class_name: 'SpreeCmCommissioner::RolePermission'
|
|
7
7
|
base.has_many :permissions, through: :role_permissions, class_name: 'SpreeCmCommissioner::Permission'
|
|
8
|
-
base.has_many :preview_roles, class_name: 'SpreeCmCommissioner::PreviewRole'
|
|
9
8
|
|
|
10
9
|
base.belongs_to :vendor, optional: true
|
|
11
10
|
|
|
@@ -14,8 +13,6 @@ module SpreeCmCommissioner
|
|
|
14
13
|
where(vendor_id: vendor)
|
|
15
14
|
}
|
|
16
15
|
base.scope :filter_external, -> { where(role_type: :external) }
|
|
17
|
-
base.scope :filter_internal, -> { where(role_type: :internal) }
|
|
18
|
-
base.scope :filter_preview, -> { where(role_type: :preview) }
|
|
19
16
|
|
|
20
17
|
base.accepts_nested_attributes_for :role_permissions, allow_destroy: true
|
|
21
18
|
|