spree_cm_commissioner 2.5.2.pre.pre2 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test_and_build_gem.yml +1 -1
- data/Gemfile.lock +1 -1
- data/app/controllers/spree/api/v2/storefront/homepage_data_controller.rb +35 -4
- data/app/controllers/spree_cm_commissioner/application_controller_decorator.rb +0 -2
- data/app/interactors/spree_cm_commissioner/conversion_pre_calculator.rb +12 -3
- data/app/interactors/spree_cm_commissioner/notification_reader.rb +3 -1
- data/app/jobs/spree_cm_commissioner/line_items/sync_event_date_job.rb +10 -0
- data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +30 -23
- 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 +28 -4
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +47 -7
- data/app/models/spree_cm_commissioner/export.rb +1 -3
- data/app/models/spree_cm_commissioner/guest.rb +0 -21
- data/app/models/spree_cm_commissioner/notification.rb +28 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +1 -1
- data/app/models/spree_cm_commissioner/variant_options.rb +0 -5
- data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +2 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/homepage_data_serializer.rb +3 -9
- data/app/services/spree_cm_commissioner/guests/finalize.rb +76 -0
- data/app/services/spree_cm_commissioner/homepage_data.rb +23 -0
- data/app/services/spree_cm_commissioner/line_items/sync_event_date.rb +22 -0
- data/app/services/spree_cm_commissioner/trips/create_single_leg.rb +14 -19
- data/app/services/spree_cm_commissioner/trips/update_single_leg.rb +2 -4
- data/app/services/spree_cm_commissioner/trips/variants/create.rb +6 -6
- data/app/services/spree_cm_commissioner/user_counters_service.rb +55 -0
- data/app/views/spree/admin/classifications/edit.html.erb +1 -1
- data/config/routes.rb +0 -27
- data/db/migrate/20260128043540_add_counter_cache_to_spree_users.rb +6 -0
- data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +0 -6
- data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +0 -13
- data/lib/spree_cm_commissioner/transit/route_stop_collection.rb +0 -28
- data/lib/spree_cm_commissioner/transit/trip_form.rb +0 -24
- data/lib/spree_cm_commissioner/transit/trip_stop_form.rb +1 -5
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +0 -1
- metadata +10 -35
- data/app/controllers/concerns/spree_cm_commissioner/events/role_authorization.rb +0 -36
- data/app/controllers/spree/events/base_controller.rb +0 -35
- data/app/controllers/spree/events/check_ins_controller.rb +0 -23
- data/app/controllers/spree/events/data_exports_controller.rb +0 -41
- data/app/controllers/spree/events/errors_controller.rb +0 -19
- data/app/controllers/spree/events/guests_controller.rb +0 -139
- data/app/controllers/spree/events/state_changes_controller.rb +0 -11
- data/app/errors/spree_cm_commissioner/unauthorized_event_error.rb +0 -4
- data/app/interactors/spree_cm_commissioner/event_line_items_date_syncer.rb +0 -19
- data/app/jobs/spree_cm_commissioner/event_line_items_date_syncer_job.rb +0 -8
- data/app/jobs/spree_cm_commissioner/export_csv_job.rb +0 -7
- data/app/models/spree_cm_commissioner/exports/export_guest_csv.rb +0 -33
- data/app/services/spree_cm_commissioner/exports/export_guest_csv_service.rb +0 -48
- data/app/views/spree/events/check_ins/index.html.erb +0 -59
- data/app/views/spree/events/data_exports/index.html.erb +0 -54
- data/app/views/spree/events/errors/_error.html.erb +0 -7
- data/app/views/spree/events/errors/forbidden.html.erb +0 -1
- data/app/views/spree/events/errors/resource_not_found.html.erb +0 -1
- data/app/views/spree/events/guests/_check_in_status.html.erb +0 -44
- data/app/views/spree/events/guests/_form.html.erb +0 -37
- data/app/views/spree/events/guests/_swap_guest_bib_number.html.erb +0 -18
- data/app/views/spree/events/guests/edit.html.erb +0 -86
- data/app/views/spree/events/guests/index.html.erb +0 -102
- data/app/views/spree/events/shared/_event_switcher.html.erb +0 -39
- data/app/views/spree/events/shared/_filters.html.erb +0 -50
- data/app/views/spree/events/shared/_guest_tabs.html.erb +0 -19
- data/app/views/spree/events/shared/_header.html.erb +0 -10
- data/app/views/spree/events/shared/_main_menu.html.erb +0 -22
- data/app/views/spree/events/state_changes/index.html.erb +0 -48
- data/lib/spree_cm_commissioner/test_helper/factories/export_guest_csv_factory.rb +0 -9
- data/lib/spree_cm_commissioner/transit/service_calendar_form.rb +0 -51
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 847e4b0b554ef076b2daeafe2d90509a434254ef6bb7bc19d34905d9a72f5a42
|
|
4
|
+
data.tar.gz: ce1c22521e38c5d012d2cb3fbe1ac041958a6054808c9b1786f4446a3046483d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1bfbb01640f43c2b9540063a8c5e368b44b4009ecd27653f739c030c65ceffcdc48d1141d466f90e2870d3c088f933260366f9db3f3bfb4b1c68dba402f5522e
|
|
7
|
+
data.tar.gz: 7f128de24e2ad50a06c9a148dc37c2ccc4e8396077a32c2456a89a35b45236562073a185f67e8e50dca5b1a59efd9b6dbcfeef2018aa63becc88b334fa070609
|
data/Gemfile.lock
CHANGED
|
@@ -3,12 +3,43 @@ module Spree
|
|
|
3
3
|
module V2
|
|
4
4
|
module Storefront
|
|
5
5
|
class HomepageDataController < ::Spree::Api::V2::ResourceController
|
|
6
|
+
before_action :load_homepage_background, only: [:show]
|
|
7
|
+
before_action :load_menu, only: [:show]
|
|
8
|
+
|
|
6
9
|
def show
|
|
7
|
-
|
|
10
|
+
resource = SpreeCmCommissioner::HomepageData.new(
|
|
11
|
+
menu: @menu,
|
|
12
|
+
homepage_background: @homepage_background
|
|
13
|
+
)
|
|
14
|
+
render_serialized_payload { serialize_resource(resource) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def serialize_resource(resource)
|
|
20
|
+
resource_serializer.new(
|
|
21
|
+
resource,
|
|
22
|
+
params: serializer_params,
|
|
23
|
+
include: resource_includes
|
|
24
|
+
).serializable_hash
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load_homepage_background
|
|
28
|
+
@homepage_background ||= SpreeCmCommissioner::HomepageBackground
|
|
29
|
+
.active
|
|
30
|
+
.includes(:app_image, :web_image)
|
|
31
|
+
.where(segment: params[:segment] || :general)
|
|
32
|
+
.order(priority: :asc)
|
|
33
|
+
.first
|
|
34
|
+
end
|
|
8
35
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
36
|
+
def load_menu
|
|
37
|
+
# Spree::Menu::MENU_LOCATIONS = ['Header', 'Footer']
|
|
38
|
+
# Current our homepage use only location: header
|
|
39
|
+
@menu ||= Spree::Menu.by_locale(I18n.locale)
|
|
40
|
+
.includes({ menu_items: %i[children parent icon] })
|
|
41
|
+
.where(location: 'header')
|
|
42
|
+
.first
|
|
12
43
|
end
|
|
13
44
|
|
|
14
45
|
def resource_serializer
|
|
@@ -13,8 +13,6 @@ module SpreeCmCommissioner
|
|
|
13
13
|
def after_sign_in_path_for(_)
|
|
14
14
|
if spree_current_user.admin?
|
|
15
15
|
admin_path
|
|
16
|
-
elsif spree_current_user.organizer? && spree_current_user.events.present?
|
|
17
|
-
event_guests_path(spree_current_user.events.first.slug)
|
|
18
16
|
else
|
|
19
17
|
'/'
|
|
20
18
|
end
|
|
@@ -5,7 +5,7 @@ module SpreeCmCommissioner
|
|
|
5
5
|
def call
|
|
6
6
|
update_conversion
|
|
7
7
|
reassign_guests_event_id
|
|
8
|
-
|
|
8
|
+
refinalize_guests
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def update_conversion
|
|
@@ -28,14 +28,23 @@ module SpreeCmCommissioner
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
def
|
|
31
|
+
def refinalize_guests
|
|
32
32
|
return if event_id.blank?
|
|
33
33
|
|
|
34
34
|
SpreeCmCommissioner::Guest
|
|
35
35
|
.complete
|
|
36
36
|
.where(event_id: event_id)
|
|
37
37
|
.none_bib
|
|
38
|
-
.find_each
|
|
38
|
+
.find_each do |guest|
|
|
39
|
+
result = SpreeCmCommissioner::Guests::Finalize.call(
|
|
40
|
+
guest: guest,
|
|
41
|
+
user: guest.line_item.order.user,
|
|
42
|
+
event: guest.event,
|
|
43
|
+
variant: guest.variant
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
result.success? || raise(ActiveRecord::RecordInvalid, guest)
|
|
47
|
+
end
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
def event_id
|
|
@@ -15,9 +15,11 @@ module SpreeCmCommissioner
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def read_all_user_unread_notifications
|
|
18
|
-
# mark all unread notifications
|
|
18
|
+
# mark all unread notifications except type 'guest_dynamic_field_notification'
|
|
19
19
|
# due to it requires user to fill info before mark as read
|
|
20
20
|
user.notifications.markable_notifications.mark_as_read!
|
|
21
|
+
|
|
22
|
+
SpreeCmCommissioner::UserCountersService.reset_unread_notifications_count(user)
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
25
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module LineItems
|
|
3
|
+
class SyncEventDateJob < ApplicationJob
|
|
4
|
+
def perform(options = {})
|
|
5
|
+
event = Spree::Taxon.event.find(options[:event_id])
|
|
6
|
+
SpreeCmCommissioner::LineItems::SyncEventDate.call(event: event)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -52,30 +52,37 @@ module SpreeCmCommissioner
|
|
|
52
52
|
self.event_id ||= product.event_id
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
55
|
+
# Calculates line item duration with priority:
|
|
56
|
+
# - Date: variant date > event date > user input (from_date/to_date)
|
|
57
|
+
# - Time: always uses variant time configuration
|
|
58
|
+
#
|
|
59
|
+
# The variant date takes highest priority. If variant has no date configured,
|
|
60
|
+
# falls back to event date, then to user-provided date.
|
|
61
|
+
#
|
|
62
|
+
# Examples:
|
|
63
|
+
# 1. Variant has full date/time config:
|
|
64
|
+
# Variant: 2024-01-15 14:00 to 2024-01-16 18:00
|
|
65
|
+
# Event: 2024-07-20, User: 2024-06-15
|
|
66
|
+
# → Result: 2024-01-15 14:00 to 2024-01-16 18:00 (variant wins)
|
|
67
|
+
#
|
|
68
|
+
# 2. Variant has only time, event provides date:
|
|
69
|
+
# Variant: 14:00 (3 hours duration)
|
|
70
|
+
# Event: 2024-07-20, User: 2024-06-15
|
|
71
|
+
# → Result: 2024-07-20 14:00 to 2024-07-20 17:00 (event date + variant time)
|
|
72
|
+
#
|
|
73
|
+
# 3. Variant has only time, no event, user provides date:
|
|
74
|
+
# Variant: 14:00 (3 hours duration)
|
|
75
|
+
# No event, User: 2024-06-15
|
|
76
|
+
# → Result: 2024-06-15 14:00 to 2024-06-15 17:00 (user date + variant time)
|
|
58
77
|
def set_duration
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def apply_variant_time(field, variant_time)
|
|
69
|
-
field_value = send(field)
|
|
70
|
-
|
|
71
|
-
return unless field_value.present? && field_value.hour.zero? && variant_time.present?
|
|
72
|
-
|
|
73
|
-
send("#{field}=", field_value.change(
|
|
74
|
-
hour: variant_time.hour,
|
|
75
|
-
min: variant_time.min,
|
|
76
|
-
sec: variant_time.sec
|
|
77
|
-
)
|
|
78
|
-
)
|
|
78
|
+
# Prepare fallback dates: event date > user input
|
|
79
|
+
base_start_date = event&.from_date || from_date
|
|
80
|
+
base_end_date = event&.to_date || to_date
|
|
81
|
+
|
|
82
|
+
# Variant will use its own date if configured, otherwise uses base_*_date
|
|
83
|
+
# Variant time is always applied to the final date
|
|
84
|
+
self.from_date = variant.start_date_time(start_date: base_start_date)
|
|
85
|
+
self.to_date = variant.end_date_time(start_date: base_start_date, end_date: base_end_date)
|
|
79
86
|
end
|
|
80
87
|
end
|
|
81
88
|
end
|
|
@@ -4,7 +4,7 @@ module SpreeCmCommissioner
|
|
|
4
4
|
module OrderStateMachine
|
|
5
5
|
extend ActiveSupport::Concern
|
|
6
6
|
|
|
7
|
-
included do
|
|
7
|
+
included do # rubocop:disable Metrics/BlockLength
|
|
8
8
|
state_machine.before_transition to: :address, do: :hold_blocks
|
|
9
9
|
state_machine.before_transition to: :payment, do: :ensure_blocks_held
|
|
10
10
|
|
|
@@ -43,12 +43,14 @@ module SpreeCmCommissioner
|
|
|
43
43
|
event :request do
|
|
44
44
|
transition from: nil, to: :requested
|
|
45
45
|
end
|
|
46
|
+
after_transition to: :requested, do: :increment_user_request_orders_count
|
|
46
47
|
after_transition to: :requested, do: :send_order_requested_app_notification_to_user
|
|
47
48
|
after_transition to: :requested, do: :send_order_requested_telegram_alert_to_store
|
|
48
49
|
|
|
49
50
|
event :accept do
|
|
50
51
|
transition from: :requested, to: :accepted
|
|
51
52
|
end
|
|
53
|
+
after_transition from: :requested, to: :accepted, do: :decrement_user_request_orders_count
|
|
52
54
|
after_transition to: :accepted, do: :send_order_accepted_app_notification_to_user
|
|
53
55
|
after_transition to: :accepted, do: :send_order_accepted_telegram_alert_to_store
|
|
54
56
|
|
|
@@ -59,6 +61,8 @@ module SpreeCmCommissioner
|
|
|
59
61
|
transition from: :requested, to: :rejected
|
|
60
62
|
end
|
|
61
63
|
|
|
64
|
+
after_transition from: :requested, to: :rejected, do: :decrement_user_request_orders_count
|
|
65
|
+
|
|
62
66
|
after_transition to: :rejected, do: :send_order_rejected_app_notification_to_user
|
|
63
67
|
after_transition to: :rejected, do: :send_order_rejected_telegram_alert_to_store
|
|
64
68
|
|
|
@@ -72,6 +76,18 @@ module SpreeCmCommissioner
|
|
|
72
76
|
end
|
|
73
77
|
end
|
|
74
78
|
|
|
79
|
+
def increment_user_request_orders_count
|
|
80
|
+
return if user.nil?
|
|
81
|
+
|
|
82
|
+
SpreeCmCommissioner::UserCountersService.increment_request_orders_count(user)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def decrement_user_request_orders_count
|
|
86
|
+
return if user.nil?
|
|
87
|
+
|
|
88
|
+
SpreeCmCommissioner::UserCountersService.decrement_request_orders_count(user)
|
|
89
|
+
end
|
|
90
|
+
|
|
75
91
|
def product_completion_steps_exist?
|
|
76
92
|
product_completion_steps.any?
|
|
77
93
|
end
|
|
@@ -174,9 +190,17 @@ module SpreeCmCommissioner
|
|
|
174
190
|
line_item.generate_remaining_guests
|
|
175
191
|
|
|
176
192
|
line_item.guests.each do |guest|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
193
|
+
result = SpreeCmCommissioner::Guests::Finalize.call(
|
|
194
|
+
guest: guest,
|
|
195
|
+
user: user,
|
|
196
|
+
event: line_item.event,
|
|
197
|
+
variant: line_item.variant
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
unless result.success?
|
|
201
|
+
guest.errors.add(:base, result.error.value || result.error.to_s)
|
|
202
|
+
raise(ActiveRecord::RecordInvalid, guest)
|
|
203
|
+
end
|
|
180
204
|
end
|
|
181
205
|
end
|
|
182
206
|
end
|
|
@@ -26,7 +26,6 @@ module SpreeCmCommissioner
|
|
|
26
26
|
:bib_prefix,
|
|
27
27
|
:bib_zerofill,
|
|
28
28
|
:bib_display_prefix?,
|
|
29
|
-
:bib_pre_generation_on_create?,
|
|
30
29
|
:seat_number_positions,
|
|
31
30
|
:seat_number_layouts,
|
|
32
31
|
:color,
|
|
@@ -53,9 +52,28 @@ module SpreeCmCommissioner
|
|
|
53
52
|
option_values.detect { |o| o.option_type.name.downcase.strip == option_type_name.downcase.strip }.try(:name)
|
|
54
53
|
end
|
|
55
54
|
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
|
|
55
|
+
# Determines the start date/time with priority:
|
|
56
|
+
# - Date priority: variant date > event date > user input date
|
|
57
|
+
# - Time: always uses variant time (if configured)
|
|
58
|
+
#
|
|
59
|
+
# Examples:
|
|
60
|
+
# 1. Variant date takes priority:
|
|
61
|
+
# Variant: 2024-01-15, Event: 2024-02-20, User: 2024-03-10, Variant time: 14:00
|
|
62
|
+
# → Returns "2024-01-15 14:00:00" (variant date + variant time)
|
|
63
|
+
#
|
|
64
|
+
# 2. Event date used when variant has no date:
|
|
65
|
+
# Variant: only time (14:00), Event: 2024-02-20, User: 2024-03-10
|
|
66
|
+
# → Returns "2024-02-20 14:00:00" (event date + variant time)
|
|
67
|
+
#
|
|
68
|
+
# 3. User date used when no variant/event date:
|
|
69
|
+
# Variant: only time (14:00), No event, User: 2024-03-10
|
|
70
|
+
# → Returns "2024-03-10 14:00:00" (user date + variant time)
|
|
71
|
+
#
|
|
72
|
+
# Note: No need to fallback to event start date to avoid n+1.
|
|
73
|
+
# To get start_time duration of event, include event when needed instead.
|
|
74
|
+
def start_date_time(start_date: nil)
|
|
75
|
+
start_date = self.start_date if self.start_date.present?
|
|
76
|
+
|
|
59
77
|
return nil if start_date.blank? && start_time.blank?
|
|
60
78
|
return start_date if start_time.blank?
|
|
61
79
|
return start_time if start_date.blank?
|
|
@@ -63,9 +81,29 @@ module SpreeCmCommissioner
|
|
|
63
81
|
start_date.change(hour: start_time.hour, min: start_time.min, sec: start_time.sec)
|
|
64
82
|
end
|
|
65
83
|
|
|
66
|
-
#
|
|
84
|
+
# Determines the end date/time with priority:
|
|
85
|
+
# - Date priority: variant date > event date > user input date
|
|
86
|
+
# - Time: always uses variant time (if configured) or calculated from duration
|
|
87
|
+
#
|
|
88
|
+
# Examples:
|
|
89
|
+
# 1. Explicit variant end_date:
|
|
90
|
+
# Variant: end_date = 2024-01-20, end_time = 18:00, Event: 2024-02-25
|
|
91
|
+
# → Returns "2024-01-20 18:00:00" (variant date + variant time)
|
|
92
|
+
#
|
|
93
|
+
# 2. Duration-based calculation (no explicit end_date):
|
|
94
|
+
# Variant: start_date = 2024-01-15, start_time = 14:00, duration = 3 hours
|
|
95
|
+
# → Returns "2024-01-15 17:00:00" (start + duration)
|
|
96
|
+
#
|
|
97
|
+
# 3. Event date when variant has no date but has time:
|
|
98
|
+
# Variant: only end_time (18:00), Event: 2024-02-20
|
|
99
|
+
# → Returns "2024-02-20 18:00:00" (event date + variant time)
|
|
100
|
+
#
|
|
101
|
+
# Note: No need to fallback to event end date to avoid n+1.
|
|
67
102
|
# To get end_time duration of event, include event when needed instead.
|
|
68
|
-
def end_date_time
|
|
103
|
+
def end_date_time(start_date: nil, end_date: nil)
|
|
104
|
+
start_date = self.start_date if self.start_date.present?
|
|
105
|
+
end_date = self.end_date(start_date: start_date) if self.end_date(start_date: start_date).present?
|
|
106
|
+
|
|
69
107
|
return nil if end_date.blank? && end_time.blank?
|
|
70
108
|
return end_date if end_time.blank?
|
|
71
109
|
return end_time if end_date.blank?
|
|
@@ -73,7 +111,9 @@ module SpreeCmCommissioner
|
|
|
73
111
|
end_date.change(hour: end_time.hour, min: end_time.min, sec: end_time.sec)
|
|
74
112
|
end
|
|
75
113
|
|
|
76
|
-
def end_date
|
|
114
|
+
def end_date(start_date: nil)
|
|
115
|
+
start_date = self.start_date if self.start_date.present?
|
|
116
|
+
|
|
77
117
|
return start_date + options.total_duration_in_seconds.seconds if start_date.present? && options.total_duration_in_seconds.positive?
|
|
78
118
|
|
|
79
119
|
options.end_date
|
|
@@ -62,7 +62,6 @@ module SpreeCmCommissioner
|
|
|
62
62
|
before_validation :assign_seat_number_with_block, if: -> { will_save_change_to_block_id? }
|
|
63
63
|
|
|
64
64
|
before_save :preload_eligible_check_in_session_ids, if: -> { new_record? }
|
|
65
|
-
before_create :generate_bib_if_needed, if: -> { line_item.reload && variant.bib_pre_generation_on_create? }
|
|
66
65
|
after_create :preload_order_block_ids, if: -> { block_id.present? }
|
|
67
66
|
after_update :preload_order_block_ids, if: :saved_change_to_block_id?
|
|
68
67
|
before_destroy :cancel_reserved_block!, if: -> { reserved_block.present? }
|
|
@@ -248,26 +247,6 @@ module SpreeCmCommissioner
|
|
|
248
247
|
line_item.variant.bib_display_prefix?
|
|
249
248
|
end
|
|
250
249
|
|
|
251
|
-
def generate_bib_if_needed
|
|
252
|
-
return if bib_prefix.present?
|
|
253
|
-
return unless bib_required?
|
|
254
|
-
return if event_id.blank?
|
|
255
|
-
|
|
256
|
-
self.bib_prefix = line_item.variant.bib_prefix
|
|
257
|
-
|
|
258
|
-
last_bib_number = event.guests
|
|
259
|
-
.where(bib_prefix: bib_prefix)
|
|
260
|
-
.maximum(:bib_number) || 0
|
|
261
|
-
|
|
262
|
-
self.bib_number = last_bib_number + 1
|
|
263
|
-
self.bib_index = "#{event_id}-#{bib_prefix}-#{bib_number}"
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
def generate_bib!
|
|
267
|
-
generate_bib_if_needed
|
|
268
|
-
save!
|
|
269
|
-
end
|
|
270
|
-
|
|
271
250
|
# bib_number: 345, bib_prefix: 5KM, bib_zerofill: 5 => return 5KM00345
|
|
272
251
|
# bib_number: 345, bib_prefix: 5KM, bib_zerofill: 2 => return 5KM345
|
|
273
252
|
def formatted_bib_number
|
|
@@ -26,5 +26,33 @@ module SpreeCmCommissioner
|
|
|
26
26
|
|
|
27
27
|
belongs_to :recipient, polymorphic: true
|
|
28
28
|
belongs_to :notificable, polymorphic: true
|
|
29
|
+
|
|
30
|
+
after_create :increment_user_counters
|
|
31
|
+
after_update :decrement_user_counters, if: :saved_change_to_read_at?
|
|
32
|
+
after_destroy :decrement_user_counters
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def increment_user_counters
|
|
37
|
+
return unless recipient.is_a?(Spree::User)
|
|
38
|
+
|
|
39
|
+
return unless unread?
|
|
40
|
+
|
|
41
|
+
SpreeCmCommissioner::UserCountersService.increment_unread_notifications_count(recipient)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def decrement_user_counters
|
|
45
|
+
return unless recipient.is_a?(Spree::User)
|
|
46
|
+
|
|
47
|
+
# On update: decrement only if transitioning from unread (nil) to read (present)
|
|
48
|
+
if saved_change_to_read_at
|
|
49
|
+
return unless saved_change_to_read_at[0].nil? && saved_change_to_read_at[1].present?
|
|
50
|
+
# On destroy: decrement only if currently unread
|
|
51
|
+
else
|
|
52
|
+
return unless read_at.nil?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
SpreeCmCommissioner::UserCountersService.decrement_unread_notifications_count(recipient)
|
|
56
|
+
end
|
|
29
57
|
end
|
|
30
58
|
end
|
|
@@ -136,7 +136,7 @@ module SpreeCmCommissioner
|
|
|
136
136
|
def sync_event_dates_to_line_items
|
|
137
137
|
return unless event? && depth == 1
|
|
138
138
|
|
|
139
|
-
::SpreeCmCommissioner::
|
|
139
|
+
::SpreeCmCommissioner::LineItems::SyncEventDateJob.perform_later(event_id: id)
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
private
|
|
@@ -126,11 +126,6 @@ module SpreeCmCommissioner
|
|
|
126
126
|
@bib_display_prefix == 1
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
-
def bib_pre_generation_on_create?
|
|
130
|
-
@bib_pre_generation_on_create ||= option_value_name_for(option_type_name: 'bib-pre-generation-on-create')&.to_i || 0
|
|
131
|
-
@bib_pre_generation_on_create == 1
|
|
132
|
-
end
|
|
133
|
-
|
|
134
129
|
def seat_number_positions
|
|
135
130
|
@seat_number_positions ||= option_value_name_for(option_type_name: 'seat-number-positions')&.split(',')
|
|
136
131
|
end
|
|
@@ -6,7 +6,8 @@ module Spree
|
|
|
6
6
|
base.attributes :first_name, :last_name, :gender, :phone_number, :intel_phone_number,
|
|
7
7
|
:country_code, :otp_enabled, :otp_email, :otp_phone_number,
|
|
8
8
|
:confirm_pin_code_enabled, :tenant_id, :has_incomplete_guest_info,
|
|
9
|
-
:login, :qr_data, :qr_data_version, :qr_data_invalidated_at
|
|
9
|
+
:login, :qr_data, :qr_data_version, :qr_data_invalidated_at,
|
|
10
|
+
:unread_notifications_count, :request_orders_count
|
|
10
11
|
|
|
11
12
|
base.has_one :profile, serializer: ::Spree::V2::Storefront::UserProfileSerializer
|
|
12
13
|
base.has_many :device_tokens, serializer: Spree::V2::Storefront::UserDeviceTokenSerializer
|
|
@@ -2,16 +2,10 @@ module SpreeCmCommissioner
|
|
|
2
2
|
module V2
|
|
3
3
|
module Storefront
|
|
4
4
|
class HomepageDataSerializer < BaseSerializer
|
|
5
|
-
|
|
5
|
+
attributes :menu_id, :homepage_background_id
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
has_many :featured_vendors, serializer: ::Spree::V2::Storefront::AccommodationSerializer
|
|
10
|
-
|
|
11
|
-
# has_many :trending_categories, serializer: :category_taxon
|
|
12
|
-
# has_many :top_categories, serializer: :category_taxon
|
|
13
|
-
# has_many :display_products, serializer: :taxon_include_product
|
|
14
|
-
# has_many :featured_brands, serializer: :brand_taxon
|
|
7
|
+
has_one :menu, serializer: Spree::Api::Dependencies.storefront_menu_serializer.constantize
|
|
8
|
+
has_one :homepage_background, serializer: SpreeCmCommissioner::V2::Storefront::HomepageBackgroundSerializer
|
|
15
9
|
end
|
|
16
10
|
end
|
|
17
11
|
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Guests
|
|
3
|
+
class Finalize
|
|
4
|
+
prepend ::Spree::ServiceModule::Base
|
|
5
|
+
|
|
6
|
+
MAX_RETRY_ATTEMPTS = 5
|
|
7
|
+
|
|
8
|
+
def call(guest:, variant:, event: nil, user: nil) # rubocop:disable Metrics/MethodLength,Metrics/PerceivedComplexity
|
|
9
|
+
attempts = 0
|
|
10
|
+
|
|
11
|
+
begin
|
|
12
|
+
attempts += 1
|
|
13
|
+
|
|
14
|
+
guest.user = user if user.present?
|
|
15
|
+
assign_bib(guest: guest, event: event, variant: variant)
|
|
16
|
+
guest.save!
|
|
17
|
+
|
|
18
|
+
success(guest)
|
|
19
|
+
rescue ActiveRecord::RecordInvalid => e
|
|
20
|
+
# Handle Rails-level validation error
|
|
21
|
+
if e.record.errors[:bib_index].any? && attempts < MAX_RETRY_ATTEMPTS
|
|
22
|
+
# Reload guest to get fresh data and retry
|
|
23
|
+
if guest.persisted?
|
|
24
|
+
guest.reload
|
|
25
|
+
else
|
|
26
|
+
# Clear bib values for new records so they get recalculated on retry
|
|
27
|
+
guest.bib_prefix = nil
|
|
28
|
+
guest.bib_number = nil
|
|
29
|
+
guest.bib_index = nil
|
|
30
|
+
end
|
|
31
|
+
retry
|
|
32
|
+
else
|
|
33
|
+
# Return failure if not a bib_index error or exceeded max attempts
|
|
34
|
+
failure(nil, e.message)
|
|
35
|
+
end
|
|
36
|
+
rescue ActiveRecord::RecordNotUnique => e
|
|
37
|
+
# Handle database-level uniqueness constraint violation
|
|
38
|
+
# Return failure if not a bib_index error or exceeded max attempts
|
|
39
|
+
return failure(nil, e.message) unless e.message.include?('bib_index') && attempts < MAX_RETRY_ATTEMPTS
|
|
40
|
+
|
|
41
|
+
# Reload guest to get fresh data and retry
|
|
42
|
+
if guest.persisted?
|
|
43
|
+
guest.reload
|
|
44
|
+
else
|
|
45
|
+
# Clear bib values for new records so they get recalculated on retry
|
|
46
|
+
guest.bib_prefix = nil
|
|
47
|
+
guest.bib_number = nil
|
|
48
|
+
guest.bib_index = nil
|
|
49
|
+
end
|
|
50
|
+
retry
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def assign_bib(guest:, event:, variant:)
|
|
55
|
+
bib_prefix = variant.bib_prefix
|
|
56
|
+
|
|
57
|
+
return false unless variant.bib_required?
|
|
58
|
+
|
|
59
|
+
return false if guest.bib_prefix.present?
|
|
60
|
+
return false if guest.event_id.blank?
|
|
61
|
+
return false if event.nil? || guest.event_id != event.id
|
|
62
|
+
|
|
63
|
+
guest.bib_prefix = bib_prefix
|
|
64
|
+
|
|
65
|
+
last_bib_number = event.guests
|
|
66
|
+
.where(bib_prefix: bib_prefix)
|
|
67
|
+
.maximum(:bib_number) || 0
|
|
68
|
+
|
|
69
|
+
guest.bib_number = last_bib_number + 1
|
|
70
|
+
guest.bib_index = "#{event.id}-#{bib_prefix}-#{guest.bib_number}"
|
|
71
|
+
|
|
72
|
+
true
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class HomepageData
|
|
3
|
+
attr_reader :menu, :homepage_background
|
|
4
|
+
|
|
5
|
+
# Plain Old Ruby Object (PORO) for homepage data
|
|
6
|
+
def initialize(menu:, homepage_background:)
|
|
7
|
+
@menu = menu
|
|
8
|
+
@homepage_background = homepage_background
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def id
|
|
12
|
+
@id ||= SecureRandom.uuid
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def menu_id
|
|
16
|
+
menu&.id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def homepage_background_id
|
|
20
|
+
homepage_background&.id
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module LineItems
|
|
3
|
+
class SyncEventDate
|
|
4
|
+
prepend ::Spree::ServiceModule::Base
|
|
5
|
+
|
|
6
|
+
def call(event:)
|
|
7
|
+
return failure(:invalid_event_kind) unless event.event?
|
|
8
|
+
return failure(:invalid_event_depth) unless event.depth == 1
|
|
9
|
+
|
|
10
|
+
event.event_line_items.includes(:variant).find_each do |line_item|
|
|
11
|
+
line_item.send(:set_duration)
|
|
12
|
+
|
|
13
|
+
# Update could be failed here if case line item does not allowed to change or no longer available.
|
|
14
|
+
# We can ignore this line item in this case.
|
|
15
|
+
line_item.save if line_item.from_date_changed? || line_item.to_date_changed?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
success(nil)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|