spree_cm_commissioner 2.5.0.pre.pre6 → 2.5.0.pre.pre8
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 -1
- data/.tool-versions +1 -1
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/api/v2/storefront/popular_route_places_controller.rb +7 -1
- data/app/controllers/spree/api/v2/storefront/route_places_controller.rb +9 -9
- data/app/finders/spree_cm_commissioner/places/find_with_route.rb +10 -10
- data/app/finders/spree_cm_commissioner/routes/find_popular.rb +10 -14
- data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +1 -1
- data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +4 -4
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -15
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +0 -2
- data/app/models/concerns/spree_cm_commissioner/store_metadata.rb +2 -14
- data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +3 -0
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +7 -1
- data/app/models/spree_cm_commissioner/guest.rb +0 -13
- data/app/models/spree_cm_commissioner/inventory_item.rb +1 -5
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +1 -13
- data/app/models/spree_cm_commissioner/option_type_decorator.rb +0 -8
- data/app/models/spree_cm_commissioner/option_value_decorator.rb +0 -34
- data/app/models/spree_cm_commissioner/order_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/product_decorator.rb +2 -3
- data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +2 -2
- data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +2 -2
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +0 -1
- data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +1 -13
- data/app/models/spree_cm_commissioner/variant_decorator.rb +4 -7
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +0 -4
- data/app/presenters/spree/variants/{visible_options_presenter.rb → visable_options_presenter.rb} +4 -2
- data/app/request_schemas/spree_cm_commissioner/popular_route_places_request_schema.rb +12 -0
- data/app/request_schemas/spree_cm_commissioner/route_places_request_schema.rb +5 -0
- data/app/views/spree/admin/tenants/_form.html.erb +18 -0
- data/app/views/spree/admin/tenants/form/_footer.html.erb +31 -0
- data/app/views/spree/admin/tenants/form/_social.html.erb +31 -0
- data/app/views/spree/order_mailer/confirm_email.html.erb +1 -1
- data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +1 -1
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +13 -6
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +23 -24
- data/config/locales/en.yml +0 -8
- data/config/locales/km.yml +0 -8
- data/config/routes.rb +0 -8
- data/db/migrate/20251209022924_add_contact_fields_to_cm_tenants.rb +9 -0
- data/lib/cm_app_logger.rb +0 -1
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +7 -8
- metadata +7 -57
- data/app/controllers/spree/admin/integration_mappings_controller.rb +0 -21
- data/app/controllers/spree/admin/integration_sessions_controller.rb +0 -21
- data/app/controllers/spree/admin/integrations_controller.rb +0 -83
- data/app/controllers/spree/api/v2/storefront/event_matches_controller.rb +0 -15
- data/app/errors/spree_cm_commissioner/integrations/external_client_error.rb +0 -10
- data/app/errors/spree_cm_commissioner/integrations/sync_error.rb +0 -4
- data/app/finders/spree_cm_commissioner/events/find_matches.rb +0 -15
- data/app/helpers/spree_cm_commissioner/external_integrations_helper.rb +0 -58
- data/app/jobs/spree_cm_commissioner/integrations/base_job.rb +0 -39
- data/app/jobs/spree_cm_commissioner/integrations/polling_job.rb +0 -53
- data/app/jobs/spree_cm_commissioner/integrations/polling_scheduler_job.rb +0 -30
- data/app/jobs/spree_cm_commissioner/telegram_alerts/integration_sync_failure_job.rb +0 -17
- data/app/models/concerns/spree_cm_commissioner/integrations/integration_mappable.rb +0 -61
- data/app/models/concerns/spree_cm_commissioner/line_item_integration.rb +0 -36
- data/app/models/concerns/spree_cm_commissioner/order_integration.rb +0 -33
- data/app/models/spree_cm_commissioner/integration.rb +0 -29
- data/app/models/spree_cm_commissioner/integration_mapping.rb +0 -41
- data/app/models/spree_cm_commissioner/integration_sync_session.rb +0 -15
- data/app/models/spree_cm_commissioner/integrations/stadium_x_v1.rb +0 -37
- data/app/overrides/spree/admin/shared/sub_menu/_integrations/external_integrations.html.erb.deface +0 -6
- data/app/services/spree_cm_commissioner/integrations/base/sync_manager.rb +0 -69
- data/app/services/spree_cm_commissioner/integrations/base/sync_result.rb +0 -183
- data/app/services/spree_cm_commissioner/integrations/polling.rb +0 -70
- data/app/services/spree_cm_commissioner/integrations/polling_scheduler.rb +0 -79
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/external_client/client.rb +0 -152
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb +0 -83
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb +0 -113
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_zones.rb +0 -215
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/base.rb +0 -20
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/league.rb +0 -19
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/match.rb +0 -95
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/ticket.rb +0 -81
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/ticket_image.rb +0 -19
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/zone.rb +0 -90
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_manager.rb +0 -35
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/full_sync_strategy.rb +0 -38
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/incremental_sync_strategy.rb +0 -44
- data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/webhook_sync_strategy.rb +0 -16
- data/app/services/spree_cm_commissioner/telegram_alerts/integration_sync_failure.rb +0 -49
- data/app/views/spree/admin/integration_mappings/_integration_mappings.html.erb +0 -107
- data/app/views/spree/admin/integration_mappings/index.html.erb +0 -33
- data/app/views/spree/admin/integration_sessions/_integration_sync_sessions.html.erb +0 -116
- data/app/views/spree/admin/integration_sessions/index.html.erb +0 -42
- data/app/views/spree/admin/integrations/_form.html.erb +0 -104
- data/app/views/spree/admin/integrations/_stadium_x_v1_fields.html.erb +0 -29
- data/app/views/spree/admin/integrations/edit.html.erb +0 -45
- data/app/views/spree/admin/integrations/index.html.erb +0 -75
- data/app/views/spree/admin/integrations/new.html.erb +0 -25
- data/db/migrate/20251017094845_create_cm_integrations.rb +0 -22
- data/db/migrate/20251017101555_create_cm_integration_sync_sessions.rb +0 -68
- data/db/migrate/20251017101605_create_cm_integration_mappings.rb +0 -52
- data/lib/spree_cm_commissioner/test_helper/factories/integration_factory.rb +0 -25
- data/lib/spree_cm_commissioner/test_helper/factories/integration_mapping_factory.rb +0 -14
- data/lib/spree_cm_commissioner/test_helper/factories/integration_sync_session_factory.rb +0 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 538969bdcdc4e74a70c795d9355b5c49357852b362d0534d208098434dcc8558
|
|
4
|
+
data.tar.gz: 14329cc3a2c2e8b0ae754057f65c6175c16e6f3251b9d16cd589efe64460ebde
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f989e81e1e4fc89004874ac6fe64535b450aeff5d709127e125339c0a71f5f4fd35eb344722354950fb72c28dbd751325b4b9c44ac3acb73c3ea6473626bdca
|
|
7
|
+
data.tar.gz: 624b7a73bf7ac18e24a60de96e284a6c1f336d3efbc3d818cbcdb0bda0e1839a9107e9264af5924c934d0e383bac7093db07b88e3ab0543bf0e6512a1f46d3d0
|
data/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby 3.
|
|
1
|
+
ruby 3.3.5
|
data/Gemfile.lock
CHANGED
|
@@ -19,7 +19,8 @@ module Spree
|
|
|
19
19
|
# override
|
|
20
20
|
def collection
|
|
21
21
|
@collection ||= collection_finder.new.execute(
|
|
22
|
-
route_type: params[:route_type]
|
|
22
|
+
route_type: params[:route_type],
|
|
23
|
+
query: params[:query]
|
|
23
24
|
)
|
|
24
25
|
end
|
|
25
26
|
|
|
@@ -51,6 +52,11 @@ module Spree
|
|
|
51
52
|
)
|
|
52
53
|
end
|
|
53
54
|
|
|
55
|
+
# override
|
|
56
|
+
def required_schema
|
|
57
|
+
SpreeCmCommissioner::PopularRoutePlacesRequestSchema
|
|
58
|
+
end
|
|
59
|
+
|
|
54
60
|
def include_vendors?
|
|
55
61
|
resource_includes.include?(:vendors) || false
|
|
56
62
|
end
|
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
# GET /api/v2/storefront/route_places
|
|
4
4
|
#
|
|
5
5
|
# Finds places (origins or destinations) that are connected to a given place through existing routes.
|
|
6
|
-
# Optionally filters results by
|
|
6
|
+
# Optionally filters results by query or route_type. Supports two modes:
|
|
7
7
|
#
|
|
8
8
|
# Usage 1: Connected places (requires place_id)
|
|
9
9
|
# - Finds places connected to a specific place via routes
|
|
10
10
|
# - Returns origins/destinations that have routes with the specified place
|
|
11
11
|
#
|
|
12
|
-
# Usage 2:
|
|
13
|
-
# - Searches all route places by
|
|
14
|
-
# - Returns all origins/destinations matching the
|
|
12
|
+
# Usage 2: query search (requires query, place_id optional)
|
|
13
|
+
# - Searches all route places by query
|
|
14
|
+
# - Returns all origins/destinations matching the query
|
|
15
15
|
#
|
|
16
16
|
# Query Parameters:
|
|
17
17
|
# - place_type: [String] Required. Type of route place: 'origin' or 'destination'
|
|
18
18
|
# * 'origin': returns origins that have routes TO the specified place (if place_id provided)
|
|
19
19
|
# * 'destination': returns destinations that have routes FROM the specified place (if place_id provided)
|
|
20
20
|
# - place_id: [Integer] Optional. The place ID to find connected places for
|
|
21
|
-
# - query: [String] Optional.
|
|
21
|
+
# - query: [String] Optional. query to filter place names (case-insensitive)
|
|
22
22
|
# - include: Optional comma-separated list (e.g., 'vendors,nearby_places')
|
|
23
23
|
#
|
|
24
24
|
# Response: Collection of places serialized with PlaceSerializer
|
|
@@ -27,15 +27,15 @@
|
|
|
27
27
|
# - Returns empty collection if place_type is invalid
|
|
28
28
|
# - If place_id provided: returns places connected to that place
|
|
29
29
|
# - If place_id blank: returns all origins/destinations
|
|
30
|
-
# - Filters results by
|
|
30
|
+
# - Filters results by query or route_type if provided
|
|
31
31
|
#
|
|
32
32
|
# @example Mode 1: Find destinations connected to origin place ID 123
|
|
33
33
|
# GET /api/v2/storefront/route_places?place_id=123&place_type=destination
|
|
34
34
|
#
|
|
35
|
-
# @example Mode 2: Search all destination places by
|
|
35
|
+
# @example Mode 2: Search all destination places by query
|
|
36
36
|
# GET /api/v2/storefront/route_places?place_type=destination&query=Phnom
|
|
37
37
|
#
|
|
38
|
-
# @example Combined: Find origins connected to place 456, filtered by
|
|
38
|
+
# @example Combined: Find origins connected to place 456, filtered by query
|
|
39
39
|
# GET /api/v2/storefront/route_places?place_id=456&place_type=origin&query=Siem
|
|
40
40
|
module Spree
|
|
41
41
|
module Api
|
|
@@ -49,7 +49,7 @@ module Spree
|
|
|
49
49
|
@collection ||= collection_finder.new(
|
|
50
50
|
place_type: params[:place_type],
|
|
51
51
|
place_id: params[:place_id],
|
|
52
|
-
|
|
52
|
+
query: params[:query],
|
|
53
53
|
route_type: params[:route_type]
|
|
54
54
|
).execute
|
|
55
55
|
end
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
#
|
|
3
3
|
# @param place_type [String] Required. 'origin' or 'destination'
|
|
4
4
|
# @param place_id [Integer] Optional. Filter by connected place ID
|
|
5
|
-
# @param
|
|
5
|
+
# @param query [String] Optional. Filter by place name (case-insensitive)
|
|
6
6
|
# @param route_type [Symbol, String] Optional. Filter by route type from associated trips (e.g., :ferry, :bus)
|
|
7
7
|
#
|
|
8
8
|
# @return [ActiveRecord::Relation<SpreeCmCommissioner::Place>]
|
|
9
9
|
#
|
|
10
10
|
# Modes:
|
|
11
11
|
# - place_id only: returns connected places (origins TO or destinations FROM given place)
|
|
12
|
-
# -
|
|
12
|
+
# - query only: filters by name
|
|
13
13
|
# - route_type only: filters by trip route types on those routes
|
|
14
14
|
# - combinations: connected places filtered by name and/or route type
|
|
15
15
|
# - neither: all origins/destinations in routes
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
# @example Origins with ferry trips to place 123
|
|
18
18
|
# FindWithRoute.new(place_type: 'origin', place_id: 123, route_type: :ferry).execute
|
|
19
19
|
#
|
|
20
|
-
# @example Destinations filtered by
|
|
21
|
-
# FindWithRoute.new(place_type: 'destination',
|
|
20
|
+
# @example Destinations filtered by query and route type
|
|
21
|
+
# FindWithRoute.new(place_type: 'destination', query: 'Phnom', route_type: :bus).execute
|
|
22
22
|
module SpreeCmCommissioner
|
|
23
23
|
module Places
|
|
24
24
|
class FindWithRoute
|
|
25
|
-
attr_reader :place_type, :place_id, :
|
|
25
|
+
attr_reader :place_type, :place_id, :query, :route_type
|
|
26
26
|
|
|
27
|
-
def initialize(place_type:, place_id: nil,
|
|
27
|
+
def initialize(place_type:, place_id: nil, query: nil, route_type: nil)
|
|
28
28
|
@place_type = place_type
|
|
29
29
|
@place_id = place_id
|
|
30
|
-
@
|
|
30
|
+
@query = query
|
|
31
31
|
@route_type = route_type
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -36,7 +36,7 @@ module SpreeCmCommissioner
|
|
|
36
36
|
return SpreeCmCommissioner::Place.none if place_id.present? && !SpreeCmCommissioner::Place.exists?(place_id)
|
|
37
37
|
|
|
38
38
|
result = scope
|
|
39
|
-
result =
|
|
39
|
+
result = apply_query_filter(result) if query.present?
|
|
40
40
|
result = apply_route_type_filter(result) if route_type.present?
|
|
41
41
|
result
|
|
42
42
|
end
|
|
@@ -57,8 +57,8 @@ module SpreeCmCommissioner
|
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def
|
|
61
|
-
result.where('cm_places.name ILIKE ?', "%#{
|
|
60
|
+
def apply_query_filter(result)
|
|
61
|
+
result.where('cm_places.name ILIKE ?', "%#{query}%")
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def apply_route_type_filter(result)
|
|
@@ -24,26 +24,22 @@
|
|
|
24
24
|
module SpreeCmCommissioner
|
|
25
25
|
module Routes
|
|
26
26
|
class FindPopular
|
|
27
|
-
def execute(route_type: nil)
|
|
28
|
-
scope(route_type: route_type)
|
|
27
|
+
def execute(route_type: nil, query: nil)
|
|
28
|
+
scope(route_type: route_type, query: query)
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
private
|
|
32
32
|
|
|
33
|
-
def scope(route_type:
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
def scope(route_type:, query:)
|
|
34
|
+
includes_associations = %i[origin_place destination_place]
|
|
35
|
+
includes_associations << :trips if route_type.present?
|
|
36
|
+
result = SpreeCmCommissioner::Route.includes(*includes_associations)
|
|
36
37
|
|
|
37
|
-
if route_type.present?
|
|
38
|
-
# Filter routes that have trips with the specified route_type
|
|
39
|
-
route_scope = SpreeCmCommissioner::Route
|
|
40
|
-
.joins(:trips)
|
|
41
|
-
.where(cm_trips: { route_type: route_type.to_sym })
|
|
42
|
-
result = result.where(id: route_scope.select(:id))
|
|
43
|
-
end
|
|
38
|
+
result = result.joins(:trips).where(cm_trips: { route_type: route_type.to_sym }) if route_type.present?
|
|
44
39
|
|
|
45
|
-
result.
|
|
46
|
-
|
|
40
|
+
result = result.where('cm_routes.route_name ILIKE ?', "%#{query}%") if query.present?
|
|
41
|
+
|
|
42
|
+
result.distinct.order(fulfilled_order_count: :desc, order_count: :desc)
|
|
47
43
|
end
|
|
48
44
|
end
|
|
49
45
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
module Stock
|
|
3
|
-
class InventoryItemsAdjusterJob <
|
|
4
|
-
def perform(
|
|
5
|
-
variant = Spree::Variant.find(
|
|
3
|
+
class InventoryItemsAdjusterJob < ApplicationUniqueJob
|
|
4
|
+
def perform(variant_id:, quantity:)
|
|
5
|
+
variant = Spree::Variant.find(variant_id)
|
|
6
6
|
|
|
7
|
-
SpreeCmCommissioner::Stock::InventoryItemsAdjuster.call(variant: variant, quantity:
|
|
7
|
+
SpreeCmCommissioner::Stock::InventoryItemsAdjuster.call(variant: variant, quantity: quantity)
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
10
|
end
|
|
@@ -45,8 +45,7 @@ module SpreeCmCommissioner
|
|
|
45
45
|
'color' => 'color',
|
|
46
46
|
'ticket-type' => 'string',
|
|
47
47
|
'seat-type' => 'string',
|
|
48
|
-
'intercity-taxi' => 'string'
|
|
49
|
-
'rules' => 'string'
|
|
48
|
+
'intercity-taxi' => 'string'
|
|
50
49
|
}.freeze
|
|
51
50
|
|
|
52
51
|
included do
|
|
@@ -57,7 +56,7 @@ module SpreeCmCommissioner
|
|
|
57
56
|
|
|
58
57
|
validate :ensure_name_is_not_changed, on: :update
|
|
59
58
|
|
|
60
|
-
before_validation :
|
|
59
|
+
before_validation :set_reverved_options_attributes, if: :reserved_option?
|
|
61
60
|
|
|
62
61
|
after_save :sort_date_time_option_values, if: -> { attr_type == 'date' || attr_type == 'time' }
|
|
63
62
|
after_save :update_variants_metadata, if: :saved_change_to_name?
|
|
@@ -69,17 +68,6 @@ module SpreeCmCommissioner
|
|
|
69
68
|
end
|
|
70
69
|
end
|
|
71
70
|
|
|
72
|
-
class_methods do
|
|
73
|
-
def rules_option_type = find_by(name: 'rules')
|
|
74
|
-
|
|
75
|
-
def ticket_type
|
|
76
|
-
Spree::OptionType.find_or_create_by!(name: 'ticket-type') do |ot|
|
|
77
|
-
ot.presentation = 'Ticket Type'
|
|
78
|
-
ot.kind = :variant
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
71
|
def reserved_option?
|
|
84
72
|
return name_was.in?(RESERVED_OPTIONS.keys) if name_changed?
|
|
85
73
|
|
|
@@ -90,7 +78,7 @@ module SpreeCmCommissioner
|
|
|
90
78
|
name == 'ticket-type'
|
|
91
79
|
end
|
|
92
80
|
|
|
93
|
-
def
|
|
81
|
+
def set_reverved_options_attributes
|
|
94
82
|
self.attr_type = RESERVED_OPTIONS[name]
|
|
95
83
|
self.kind = :variant
|
|
96
84
|
end
|
|
@@ -143,7 +143,6 @@ module SpreeCmCommissioner
|
|
|
143
143
|
# The payment will be reversed in vPago gem, and `Spree::Checkout::Complete` will be called, which checks `order.reload.complete?`.
|
|
144
144
|
# This is critical because if the order state is complete, the payment will be marked as paid.
|
|
145
145
|
|
|
146
|
-
unstock_inventory_from_external_system!
|
|
147
146
|
reserve_blocks!
|
|
148
147
|
unstock_inventory_in_redis!
|
|
149
148
|
|
|
@@ -162,7 +161,6 @@ module SpreeCmCommissioner
|
|
|
162
161
|
|
|
163
162
|
def restock_inventory!
|
|
164
163
|
ActiveRecord::Base.transaction do
|
|
165
|
-
restock_inventory_from_external_system!
|
|
166
164
|
cancel_blocks!
|
|
167
165
|
restock_inventory_in_redis!
|
|
168
166
|
end
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
# - integer
|
|
14
14
|
# - array
|
|
15
15
|
# - datetime
|
|
16
|
-
# - hash
|
|
17
16
|
#
|
|
18
17
|
# Example usage:
|
|
19
18
|
# ```
|
|
@@ -23,7 +22,6 @@
|
|
|
23
22
|
# store_public_metadata :completed, :boolean, default: true
|
|
24
23
|
# store_public_metadata :count, :integer, default: 5
|
|
25
24
|
# store_public_metadata :tags, :array, default: []
|
|
26
|
-
# store_public_metadata :tags, :hash
|
|
27
25
|
# store_private_metadata :app_token, :string, default: "XYZ"
|
|
28
26
|
# store_public_metadata :scheduled_at, :datetime, default: Time.now
|
|
29
27
|
# end
|
|
@@ -94,7 +92,7 @@ module SpreeCmCommissioner
|
|
|
94
92
|
# - Return default if nil
|
|
95
93
|
# - Cast to correct type
|
|
96
94
|
# - Add `?` predicate for booleans
|
|
97
|
-
def define_metadata_reader(column_name, key, type, default)
|
|
95
|
+
def define_metadata_reader(column_name, key, type, default)
|
|
98
96
|
define_method(key) do
|
|
99
97
|
metadata = send(column_name) || {}
|
|
100
98
|
raw_value = metadata[key.to_s]
|
|
@@ -111,8 +109,6 @@ module SpreeCmCommissioner
|
|
|
111
109
|
Array(raw_value)
|
|
112
110
|
when :datetime
|
|
113
111
|
Time.zone.parse(raw_value.to_s)
|
|
114
|
-
when :hash
|
|
115
|
-
raw_value.is_a?(Hash) ? raw_value : {}
|
|
116
112
|
else
|
|
117
113
|
raw_value
|
|
118
114
|
end
|
|
@@ -122,7 +118,7 @@ module SpreeCmCommissioner
|
|
|
122
118
|
end
|
|
123
119
|
|
|
124
120
|
# Validates only new assignments (raw JSON values) for type safety
|
|
125
|
-
def define_metadata_validation(column_name, key, type) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
121
|
+
def define_metadata_validation(column_name, key, type) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
126
122
|
case type
|
|
127
123
|
when :boolean
|
|
128
124
|
validates key, inclusion: { in: [true, false] }, allow_nil: true
|
|
@@ -164,14 +160,6 @@ module SpreeCmCommissioner
|
|
|
164
160
|
errors.add(key, 'is not a valid datetime')
|
|
165
161
|
end
|
|
166
162
|
end
|
|
167
|
-
when :hash
|
|
168
|
-
validate do
|
|
169
|
-
metadata = send(column_name) || {}
|
|
170
|
-
raw_value = metadata[key.to_s]
|
|
171
|
-
next if raw_value.nil?
|
|
172
|
-
|
|
173
|
-
errors.add(key, 'must be a hash') unless raw_value.is_a?(Hash)
|
|
174
|
-
end
|
|
175
163
|
end
|
|
176
164
|
end
|
|
177
165
|
end
|
|
@@ -12,6 +12,9 @@ module SpreeCmCommissioner
|
|
|
12
12
|
preference :brand_primary_color, :string, default: ''
|
|
13
13
|
preference :redirect_target_host, :string, default: ''
|
|
14
14
|
preference :redirect_excluded_paths, :string, default: ''
|
|
15
|
+
preference :facebook, :string, default: ''
|
|
16
|
+
preference :twitter, :string, default: ''
|
|
17
|
+
preference :instagram, :string, default: ''
|
|
15
18
|
end
|
|
16
19
|
end
|
|
17
20
|
end
|
|
@@ -35,6 +35,12 @@ module SpreeCmCommissioner
|
|
|
35
35
|
to: :options
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
+
# Override variant.rb to return cached formatted options text, avoiding repeated database queries.
|
|
39
|
+
# Falls back to database queries & computing the format if preload data is unavailable.
|
|
40
|
+
def options_text
|
|
41
|
+
@options_text ||= public_metadata[:preload_options_text].presence || Spree::Variants::VisableOptionsPresenter.new(self).to_sentence
|
|
42
|
+
end
|
|
43
|
+
|
|
38
44
|
def options
|
|
39
45
|
@options ||= VariantOptions.new(self)
|
|
40
46
|
end
|
|
@@ -105,7 +111,7 @@ module SpreeCmCommissioner
|
|
|
105
111
|
# Precomputes the human-readable format (e.g., "Red, 256GB") to avoid
|
|
106
112
|
# repeated formatting and association queries.
|
|
107
113
|
# Example: {"color" => "red", "storage" => "256GB"} - option_type_name => option_value_name pairs
|
|
108
|
-
self.public_metadata[:preload_options_text] = Spree::Variants::
|
|
114
|
+
self.public_metadata[:preload_options_text] = Spree::Variants::VisableOptionsPresenter.new(self).to_sentence
|
|
109
115
|
end
|
|
110
116
|
|
|
111
117
|
def set_options_to_public_metadata!
|
|
@@ -3,8 +3,6 @@ module SpreeCmCommissioner
|
|
|
3
3
|
class Guest < SpreeCmCommissioner::Base # rubocop:disable Metrics/ClassLength
|
|
4
4
|
include SpreeCmCommissioner::KycBitwise
|
|
5
5
|
include SpreeCmCommissioner::PhoneNumberSanitizer
|
|
6
|
-
include SpreeCmCommissioner::StoreMetadata
|
|
7
|
-
include SpreeCmCommissioner::Integrations::IntegrationMappable
|
|
8
6
|
|
|
9
7
|
delegate :kyc, to: :line_item, allow_nil: true
|
|
10
8
|
delegate :allowed_upload_later?, to: :line_item, allow_nil: true
|
|
@@ -214,20 +212,9 @@ module SpreeCmCommissioner
|
|
|
214
212
|
end
|
|
215
213
|
|
|
216
214
|
def qr_data
|
|
217
|
-
return external_qr_data if external_qr_data.present?
|
|
218
|
-
|
|
219
215
|
token
|
|
220
216
|
end
|
|
221
217
|
|
|
222
|
-
# QR data for check-in. If external_wins? is true, use their QR data (they have their own check-in system).
|
|
223
|
-
# Otherwise, use our system's QR data. Only applicable to models with QR support (e.g., line_item, guest).
|
|
224
|
-
def external_qr_data
|
|
225
|
-
return nil if line_item.nil? || !line_item.integration?
|
|
226
|
-
|
|
227
|
-
mapping = external_wins_integration_mappings.first
|
|
228
|
-
mapping.external_qr_data if mapping.present?
|
|
229
|
-
end
|
|
230
|
-
|
|
231
218
|
def current_age
|
|
232
219
|
return nil if dob.nil?
|
|
233
220
|
|
|
@@ -56,12 +56,8 @@ module SpreeCmCommissioner
|
|
|
56
56
|
"inventory:#{id}"
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
def quantity_in_redis
|
|
60
|
-
SpreeCmCommissioner.inventory_redis_pool.with { |redis| redis.get(redis_key).to_i }
|
|
61
|
-
end
|
|
62
|
-
|
|
63
59
|
def adjust_quantity_in_redis(quantity)
|
|
64
|
-
SpreeCmCommissioner.
|
|
60
|
+
SpreeCmCommissioner.redis_pool.with do |redis|
|
|
65
61
|
# Always update Redis cache, even if it doesn't exist yet.
|
|
66
62
|
# This prevents admin adjustments from being lost when cache is later initialized.
|
|
67
63
|
script = <<~LUA
|
|
@@ -72,12 +72,10 @@ module SpreeCmCommissioner
|
|
|
72
72
|
def self.include_modules(base)
|
|
73
73
|
base.include Spree::Core::NumberGenerator.new(prefix: 'L')
|
|
74
74
|
base.include SpreeCmCommissioner::StoreMetadata
|
|
75
|
-
base.include SpreeCmCommissioner::LineItemIntegration
|
|
76
75
|
base.include SpreeCmCommissioner::LineItemDurationable
|
|
77
76
|
base.include SpreeCmCommissioner::LineItemsFilterScope
|
|
78
77
|
base.include SpreeCmCommissioner::LineItemGuestsConcern
|
|
79
78
|
base.include SpreeCmCommissioner::LineItemTransitable
|
|
80
|
-
base.include SpreeCmCommissioner::Integrations::IntegrationMappable
|
|
81
79
|
base.include SpreeCmCommissioner::ProductType
|
|
82
80
|
base.include SpreeCmCommissioner::ProductDelegation
|
|
83
81
|
base.include SpreeCmCommissioner::KycBitwise
|
|
@@ -200,21 +198,11 @@ module SpreeCmCommissioner
|
|
|
200
198
|
end
|
|
201
199
|
|
|
202
200
|
def qr_data
|
|
203
|
-
return external_qr_data if external_qr_data.present?
|
|
204
201
|
return nil if order.nil?
|
|
205
202
|
|
|
206
203
|
"#{order.number}-#{order.token}-L#{id}"
|
|
207
204
|
end
|
|
208
205
|
|
|
209
|
-
# QR data for check-in. If external_wins? is true, use their QR data (they have their own check-in system).
|
|
210
|
-
# Otherwise, use our system's QR data. Only applicable to models with QR support (e.g., line_item, guest).
|
|
211
|
-
def external_qr_data
|
|
212
|
-
return nil unless integration?
|
|
213
|
-
|
|
214
|
-
mapping = external_wins_integration_mappings.first
|
|
215
|
-
mapping.external_qr_data if mapping.present?
|
|
216
|
-
end
|
|
217
|
-
|
|
218
206
|
def generate_completion_steps
|
|
219
207
|
generate_completion_steps!
|
|
220
208
|
true
|
|
@@ -267,7 +255,7 @@ module SpreeCmCommissioner
|
|
|
267
255
|
end
|
|
268
256
|
|
|
269
257
|
def update_vendor_id
|
|
270
|
-
self.vendor_id = variant
|
|
258
|
+
self.vendor_id = variant.vendor_id
|
|
271
259
|
end
|
|
272
260
|
|
|
273
261
|
def subscription?
|
|
@@ -22,14 +22,6 @@ module SpreeCmCommissioner
|
|
|
22
22
|
def base.rules_option_type
|
|
23
23
|
Spree::OptionType.find_by(name: RULES_OPTION_TYPE_NAME)
|
|
24
24
|
end
|
|
25
|
-
|
|
26
|
-
# override
|
|
27
|
-
def base.color
|
|
28
|
-
Spree::OptionType.find_or_create_by!(name: 'color') do |ot|
|
|
29
|
-
ot.presentation = 'Color'
|
|
30
|
-
ot.kind = :variant
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
25
|
end
|
|
34
26
|
|
|
35
27
|
private
|
|
@@ -3,36 +3,6 @@ module SpreeCmCommissioner
|
|
|
3
3
|
def self.prepended(base)
|
|
4
4
|
base.include SpreeCmCommissioner::OptionValueAttrType
|
|
5
5
|
base.has_many :option_value_vehicles, class_name: 'SpreeCmCommissioner::OptionValueVehicle', foreign_key: :option_value_id, dependent: :destroy
|
|
6
|
-
|
|
7
|
-
base.validates :name, presence: true, uniqueness: { scope: :option_type_id, case_sensitive: -> { name_case_sensitive? } }
|
|
8
|
-
|
|
9
|
-
# Ticket types: case-SENSITIVE matching (preserve external API casing)
|
|
10
|
-
# Other types: case-INSENSITIVE storage (prevent duplicates from varying API casing; presentation keeps original)
|
|
11
|
-
def base.find_or_create_by_name!(option_type, name)
|
|
12
|
-
name = name.strip
|
|
13
|
-
if option_type.ticket_type?
|
|
14
|
-
where(option_type_id: option_type.id, name: name).first_or_create! do |ov|
|
|
15
|
-
ov.option_type = option_type
|
|
16
|
-
ov.name = name
|
|
17
|
-
ov.presentation = name
|
|
18
|
-
end
|
|
19
|
-
else
|
|
20
|
-
where(option_type_id: option_type.id).where('LOWER(name) = ?', name.downcase).first_or_create! do |ov|
|
|
21
|
-
ov.option_type = option_type
|
|
22
|
-
ov.name = name.downcase
|
|
23
|
-
ov.presentation = name
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# Override Spree's name validation to make it case-sensitive only for ticket-type option values.
|
|
30
|
-
# Spree's default is case-insensitive (false), but we enforce case-sensitivity (true) for ticket-types.
|
|
31
|
-
# Which means ticket type "STANDARD" and "Standard" are different option values.
|
|
32
|
-
def name_case_sensitive?
|
|
33
|
-
return true if ticket_type?
|
|
34
|
-
|
|
35
|
-
false
|
|
36
6
|
end
|
|
37
7
|
|
|
38
8
|
def display_icon
|
|
@@ -44,9 +14,5 @@ module SpreeCmCommissioner
|
|
|
44
14
|
end
|
|
45
15
|
|
|
46
16
|
unless Spree::OptionValue.included_modules.include?(SpreeCmCommissioner::OptionValueDecorator)
|
|
47
|
-
# remove all name validations so we can override them in the decorator.
|
|
48
|
-
Spree::OptionValue._validators.reject! { |key, _| key == :name }
|
|
49
|
-
Spree::OptionValue._validate_callbacks.each { |c| c.filter.attributes.delete(:name) if c.filter.respond_to?(:attributes) }
|
|
50
|
-
|
|
51
17
|
Spree::OptionValue.prepend SpreeCmCommissioner::OptionValueDecorator
|
|
52
18
|
end
|
|
@@ -3,7 +3,6 @@ module SpreeCmCommissioner
|
|
|
3
3
|
def self.prepended(base) # rubocop:disable Metrics/MethodLength
|
|
4
4
|
base.include SpreeCmCommissioner::StoreMetadata
|
|
5
5
|
base.include SpreeCmCommissioner::PhoneNumberSanitizer
|
|
6
|
-
base.include SpreeCmCommissioner::OrderIntegration
|
|
7
6
|
base.include SpreeCmCommissioner::OrderSeatable
|
|
8
7
|
base.include SpreeCmCommissioner::OrderStateMachine
|
|
9
8
|
base.include SpreeCmCommissioner::RouteOrderCountable
|
|
@@ -8,7 +8,6 @@ module SpreeCmCommissioner
|
|
|
8
8
|
base.include SpreeCmCommissioner::TenantUpdatable
|
|
9
9
|
base.include SpreeCmCommissioner::ServiceType
|
|
10
10
|
base.include SpreeCmCommissioner::ServiceRecommendations
|
|
11
|
-
base.include SpreeCmCommissioner::Integrations::IntegrationMappable
|
|
12
11
|
|
|
13
12
|
base.has_many :variant_kind_option_types, -> { where(kind: :variant).order(:position) },
|
|
14
13
|
through: :product_option_types, source: :option_type
|
|
@@ -90,7 +89,7 @@ module SpreeCmCommissioner
|
|
|
90
89
|
request_to_book: 8
|
|
91
90
|
}
|
|
92
91
|
|
|
93
|
-
base.
|
|
92
|
+
base.multi_tenant :tenant, class_name: 'SpreeCmCommissioner::Tenant'
|
|
94
93
|
base.before_save :set_tenant
|
|
95
94
|
end
|
|
96
95
|
|
|
@@ -143,7 +142,7 @@ module SpreeCmCommissioner
|
|
|
143
142
|
end
|
|
144
143
|
|
|
145
144
|
def set_event_id
|
|
146
|
-
self.event_id
|
|
145
|
+
self.event_id = taxons.select(&:event?).first&.parent_id
|
|
147
146
|
end
|
|
148
147
|
|
|
149
148
|
def update_variants_vendor_id
|
|
@@ -12,7 +12,7 @@ module SpreeCmCommissioner
|
|
|
12
12
|
keys = inventory_items.map { |item| "inventory:#{item.id}" }
|
|
13
13
|
return [] unless keys.any?
|
|
14
14
|
|
|
15
|
-
counts = SpreeCmCommissioner.
|
|
15
|
+
counts = SpreeCmCommissioner.redis_pool.with { |redis| redis.mget(*keys) }
|
|
16
16
|
inventory_items.map.with_index do |inventory_item, i|
|
|
17
17
|
::SpreeCmCommissioner::CachedInventoryItem.new(
|
|
18
18
|
inventory_key: keys[i],
|
|
@@ -32,7 +32,7 @@ module SpreeCmCommissioner
|
|
|
32
32
|
|
|
33
33
|
# Use atomic SET NX to prevent race condition where multiple concurrent reads
|
|
34
34
|
# initialize cache with stale values. Only the first thread wins.
|
|
35
|
-
SpreeCmCommissioner.
|
|
35
|
+
SpreeCmCommissioner.redis_pool.with do |redis|
|
|
36
36
|
redis.eval(set_nx_with_expiry_script, keys: [key], argv: [inventory_item.quantity_available, inventory_item.redis_expired_in])
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -51,13 +51,13 @@ module SpreeCmCommissioner
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def unstock(keys, quantities)
|
|
54
|
-
SpreeCmCommissioner.
|
|
54
|
+
SpreeCmCommissioner.redis_pool.with do |redis|
|
|
55
55
|
redis.eval(unstock_redis_script, keys: keys, argv: quantities)
|
|
56
56
|
end.positive?
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def restock(keys, quantities)
|
|
60
|
-
SpreeCmCommissioner.
|
|
60
|
+
SpreeCmCommissioner.redis_pool.with do |redis|
|
|
61
61
|
redis.eval(restock_redis_script, keys: keys, argv: quantities)
|
|
62
62
|
end.positive?
|
|
63
63
|
end
|
|
@@ -5,7 +5,6 @@ module SpreeCmCommissioner
|
|
|
5
5
|
base.include SpreeCmCommissioner::TaxonKind
|
|
6
6
|
base.include SpreeCmCommissioner::ParticipationTypeBitwise
|
|
7
7
|
base.include SpreeCmCommissioner::EventMetadata
|
|
8
|
-
base.include SpreeCmCommissioner::Integrations::IntegrationMappable
|
|
9
8
|
|
|
10
9
|
base.has_many :taxon_vendors, class_name: 'SpreeCmCommissioner::TaxonVendor'
|
|
11
10
|
base.has_many :vendors, through: :taxon_vendors
|
|
@@ -3,21 +3,9 @@ module SpreeCmCommissioner
|
|
|
3
3
|
def self.prepended(base)
|
|
4
4
|
base.include SpreeCmCommissioner::TaxonKind
|
|
5
5
|
|
|
6
|
-
def base.events
|
|
7
|
-
ActiveRecord::Base.connected_to(role: :writing) do
|
|
8
|
-
events = Spree::Taxonomy.find_or_create_by(name: 'Events', store: Spree::Store.default)
|
|
9
|
-
events.kind = :event
|
|
10
|
-
events.save if events.changed?
|
|
11
|
-
events
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
6
|
def base.businesses
|
|
16
7
|
ActiveRecord::Base.connected_to(role: :writing) do
|
|
17
|
-
|
|
18
|
-
businesses.kind = :category
|
|
19
|
-
businesses.save if businesses.changed?
|
|
20
|
-
businesses
|
|
8
|
+
Spree::Taxonomy.find_or_create_by(name: 'Businesses', kind: 'category', store: Spree::Store.default)
|
|
21
9
|
end
|
|
22
10
|
end
|
|
23
11
|
end
|