spree_cm_commissioner 1.21.0 → 2.0.0.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/Gemfile.lock +1 -5
- data/app/assets/images/mailer/mail.png +0 -0
- data/app/assets/images/mailer/tenant_phone.png +0 -0
- data/app/assets/images/mailer/tenant_user.png +0 -0
- data/app/controllers/spree/api/v2/operator/pie_chart_events_controller.rb +46 -0
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +13 -13
- data/app/factory/spree_cm_commissioner/invite_guest_claimed_telegram_message_factory.rb +28 -38
- data/app/interactors/spree_cm_commissioner/create_ticket.rb +6 -5
- data/app/interactors/spree_cm_commissioner/create_vendor.rb +44 -0
- data/app/mailers/spree/order_mailer_decorator.rb +18 -3
- data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +18 -0
- data/app/models/concerns/spree_cm_commissioner/tenant_preference.rb +1 -0
- data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +4 -2
- data/app/models/spree_cm_commissioner/chart_type.rb +10 -0
- data/app/models/spree_cm_commissioner/dynamic_field.rb +20 -0
- data/app/models/spree_cm_commissioner/guest.rb +56 -0
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +41 -1
- data/app/models/spree_cm_commissioner/product_decorator.rb +22 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +6 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +3 -0
- data/app/queries/spree_cm_commissioner/pie_chart_event_queries.rb +179 -0
- data/app/serializables/spree_cm_commissioner/pie_chart_event.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/operator/chart_type_serializer.rb +10 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +1 -1
- data/app/views/spree/admin/tenant_vendors/index.html.erb +9 -2
- data/app/views/spree/admin/tenants/_form.html.erb +9 -0
- data/app/views/spree/admin/tenants/edit.html.erb +2 -1
- data/app/views/spree/admin/tenants/index.html.erb +7 -1
- data/app/views/spree/admin/vendors/_form.html.erb +14 -0
- data/app/views/spree/order_mailer/confirm_email.html.erb +27 -16
- data/app/views/spree_cm_commissioner/layouts/order_mailer.html.erb +5 -1
- data/app/views/spree_cm_commissioner/order_mailer/_mailer_stylesheets.html.erb +41 -4
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_customer_info.html.erb +42 -0
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_footer.html.erb +25 -0
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_greeting.html.erb +19 -0
- data/app/views/spree_cm_commissioner/order_mailer/tenant/_support_contact.html.erb +33 -0
- data/config/locales/en.yml +5 -1
- data/config/routes.rb +1 -0
- data/db/migrate/20250709073455_add_email_fields_to_spree_vendors.rb +6 -0
- data/db/migrate/20250718071620_add_data_fill_stage_to_dynamic_fields.rb +5 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +19 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b85b4b7a446688bc4aed2974e7150a9155a2d919b998188fc7e575ccea0d2714
|
4
|
+
data.tar.gz: 134a3e165301c382a7e48016e768755420d32003a31cf3b3dac79f33b7a0d5a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd91cb46cb05faec83d0978df8312e272265ad03d1d14c1319ea0303081521dac9468a4e9e6fd4e72698e61c175fcddfc3bed53527e7f0ebe1a23f81062bf9c3
|
7
|
+
data.tar.gz: 1d04b75c972c6cff71fa6e95ca3882411a8a54b6b0b226183369a97b1360fa00c2c334e728203f647405313da8deec7298e4662dedfb068cc51540e4caf548d7
|
data/Gemfile.lock
CHANGED
@@ -34,7 +34,7 @@ GIT
|
|
34
34
|
PATH
|
35
35
|
remote: .
|
36
36
|
specs:
|
37
|
-
spree_cm_commissioner (
|
37
|
+
spree_cm_commissioner (2.0.0.pre.pre1)
|
38
38
|
activerecord-multi-tenant
|
39
39
|
activerecord_json_validator (~> 2.1, >= 2.1.3)
|
40
40
|
aws-sdk-cloudfront
|
@@ -572,10 +572,6 @@ GEM
|
|
572
572
|
nokogiri (1.15.4)
|
573
573
|
mini_portile2 (~> 2.8.2)
|
574
574
|
racc (~> 1.4)
|
575
|
-
nokogiri (1.15.4-x86_64-darwin)
|
576
|
-
racc (~> 1.4)
|
577
|
-
nokogiri (1.15.4-x86_64-linux)
|
578
|
-
racc (~> 1.4)
|
579
575
|
noticed (1.6.3)
|
580
576
|
http (>= 4.0.0)
|
581
577
|
rails (>= 5.2.0)
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Operator
|
5
|
+
class PieChartEventsController < ::Spree::Api::V2::ResourceController
|
6
|
+
ACCEPTED_KYC_FIELDS = %i[guest_gender guest_occupation guest_nationality].freeze
|
7
|
+
ADDITIONAL_FIELDS = %i[participation entry_type].freeze
|
8
|
+
|
9
|
+
def index
|
10
|
+
kyc_fields = fetch_filtered_kyc_fields
|
11
|
+
types = ADDITIONAL_FIELDS + kyc_fields
|
12
|
+
|
13
|
+
resources = types.map { |type| SpreeCmCommissioner::ChartType.new(type) }
|
14
|
+
|
15
|
+
render json: SpreeCmCommissioner::V2::Operator::ChartTypeSerializer.new(resources).serializable_hash
|
16
|
+
end
|
17
|
+
|
18
|
+
def resource
|
19
|
+
@resource = pie_chart_event_aggregator_queries.call
|
20
|
+
end
|
21
|
+
|
22
|
+
def resource_serializer
|
23
|
+
SpreeCmCommissioner::V2::Operator::PieChartEventAggregatorSerializer
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def pie_chart_event_aggregator_queries
|
29
|
+
SpreeCmCommissioner::PieChartEventQueries.new(
|
30
|
+
taxon_id: params[:taxon_id],
|
31
|
+
chart_type: params[:id] || 'participation',
|
32
|
+
refreshed: params[:refreshed] || false
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def fetch_filtered_kyc_fields
|
37
|
+
Spree::Product
|
38
|
+
.where(event_id: params[:taxon_id])
|
39
|
+
.flat_map(&:kyc_fields)
|
40
|
+
.uniq & ACCEPTED_KYC_FIELDS
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -39,22 +39,22 @@ module Spree
|
|
39
39
|
spree_authorize! :update, spree_current_order, order_token
|
40
40
|
|
41
41
|
begin
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
ActiveRecord::Base.transaction do
|
43
|
+
if guest_params[:guest_dynamic_fields_attributes]
|
44
|
+
dynamic_field_ids = guest_params[:guest_dynamic_fields_attributes].pluck(:dynamic_field_id)
|
45
|
+
resource.guest_dynamic_fields.where(dynamic_field_id: dynamic_field_ids).destroy_all
|
46
|
+
|
47
|
+
guest_params[:guest_dynamic_fields_attributes].each do |attr|
|
48
|
+
field = build_dynamic_field(attr)
|
49
|
+
field.save!
|
50
|
+
end
|
48
51
|
end
|
49
|
-
end
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
if resource.save
|
54
|
-
render_serialized_payload { serialize_resource(resource) }
|
55
|
-
else
|
56
|
-
render_error_payload(resource.errors, 400)
|
53
|
+
resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
|
54
|
+
resource.save!
|
57
55
|
end
|
56
|
+
|
57
|
+
render_serialized_payload { serialize_resource(resource) }
|
58
58
|
rescue ActiveRecord::RecordInvalid => e
|
59
59
|
render_error_payload(e.record.errors, 400)
|
60
60
|
end
|
@@ -1,17 +1,16 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
# <
|
4
|
-
|
5
|
-
# <
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
9
|
-
# <
|
10
|
-
# <i
|
11
|
-
#
|
12
|
-
|
13
|
-
# <
|
14
|
-
# <code>R172627517</code></p>
|
1
|
+
# 🎫 --- [NEW INVITATION CLAIMED] ---
|
2
|
+
#
|
3
|
+
# <b>🙍 Claimed By</b>
|
4
|
+
# Name: Orng SreyMoch
|
5
|
+
# Tel: <code>+85570760548</code>
|
6
|
+
#
|
7
|
+
# <b>5km Running Ticket</b>
|
8
|
+
# Quantity: 1
|
9
|
+
# <i>👉 Distance: 5km, T-shirt: S</i>
|
10
|
+
# <i>🗓️ Nov 15, 2023 -> Nov 17, 2023</i>
|
11
|
+
#
|
12
|
+
# Order Number:
|
13
|
+
# <code>R621016753</code>
|
15
14
|
|
16
15
|
module SpreeCmCommissioner
|
17
16
|
class InviteGuestClaimedTelegramMessageFactory < TelegramMessageFactory
|
@@ -27,40 +26,31 @@ module SpreeCmCommissioner
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def selected_line_items
|
30
|
-
|
31
|
-
|
32
|
-
order.line_items
|
29
|
+
vendor.present? ? order.line_items.for_vendor(vendor) : order.line_items
|
33
30
|
end
|
34
31
|
|
35
32
|
# override
|
36
33
|
def body
|
37
34
|
text = []
|
38
|
-
text << '<p>📣 --- <b>[NEW GUEST CLAIMED INVITATION]</b> ---</p>'
|
39
|
-
text << '<p>✨ <b>Ticket Successfully Claimed!</b> ✨</p>'
|
40
|
-
text << '<p><b>🙍 Claimed By</b><br>'
|
41
|
-
text << "Name: #{guest.first_name} #{guest.last_name}<br>"
|
42
|
-
text << "Tel: <code>#{guest.phone_number}</code></p>"
|
43
35
|
|
36
|
+
text << bold('🙍 Claimed By')
|
37
|
+
text << "Name: #{guest.first_name} #{guest.last_name}"
|
38
|
+
text << "Tel: #{inline_code(guest.phone_number)}"
|
39
|
+
text << ''
|
40
|
+
|
41
|
+
# Each invitation_link leads to one order with one line_item, claimed by one guest so quantity is always 1.
|
44
42
|
selected_line_items.each do |item|
|
45
|
-
text <<
|
43
|
+
text << bold(item.product.name.to_s)
|
44
|
+
text << '🎟️ Quantity: 1'
|
45
|
+
text << italic("👉 #{item.options_text}") if item.options_text.present?
|
46
|
+
text << italic(pretty_date_for(item)) if item.date_present?
|
47
|
+
text << ''
|
46
48
|
end
|
47
49
|
|
48
|
-
text <<
|
49
|
-
|
50
|
-
text.join("\n")
|
51
|
-
end
|
52
|
-
|
53
|
-
def line_item_block(item)
|
54
|
-
parts = []
|
55
|
-
parts << "<p><b>#{item.product.name}</b><br>"
|
56
|
-
|
57
|
-
details = []
|
58
|
-
details << "👉 #{item.options_text}" if item.options_text.present?
|
59
|
-
details << pretty_date_for(item) if item.date_present?
|
50
|
+
text << bold('Order Number:')
|
51
|
+
text << inline_code(order.number)
|
60
52
|
|
61
|
-
|
62
|
-
parts << '</p>'
|
63
|
-
parts.join("\n")
|
53
|
+
text.compact.join("\n")
|
64
54
|
end
|
65
55
|
|
66
56
|
def pretty_date_for(line_item)
|
@@ -9,7 +9,8 @@ module SpreeCmCommissioner
|
|
9
9
|
set_option_value
|
10
10
|
create_variant
|
11
11
|
create_stock_item
|
12
|
-
|
12
|
+
upload_image_to(@ticket.master)
|
13
|
+
upload_image_to(@variant)
|
13
14
|
create_place
|
14
15
|
end
|
15
16
|
end
|
@@ -77,13 +78,13 @@ module SpreeCmCommissioner
|
|
77
78
|
context.fail!(message: @stock_item.errors.full_messages.join(', '))
|
78
79
|
end
|
79
80
|
|
80
|
-
def
|
81
|
+
def upload_image_to(target)
|
81
82
|
return if context.params[:ticket_image].blank?
|
82
83
|
|
83
|
-
|
84
|
-
return if
|
84
|
+
image = target.images.new(attachment: context.params[:ticket_image])
|
85
|
+
return if image.save
|
85
86
|
|
86
|
-
context.fail!(message:
|
87
|
+
context.fail!(message: image.errors.full_messages.join(', '))
|
87
88
|
end
|
88
89
|
|
89
90
|
def create_place
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class CreateVendor
|
3
|
+
include Interactor
|
4
|
+
|
5
|
+
def call
|
6
|
+
validate_context!
|
7
|
+
|
8
|
+
ActiveRecord::Base.transaction do
|
9
|
+
create_vendor
|
10
|
+
assign_vendor_to_user
|
11
|
+
create_role
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def validate_context!
|
18
|
+
context.fail!(message: 'User is missing') unless context.user
|
19
|
+
context.fail!(message: 'Vendor parameters are missing') unless context.vendor_params
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_vendor
|
23
|
+
@vendor = Spree::Vendor.new(context.vendor_params)
|
24
|
+
return if @vendor.save
|
25
|
+
|
26
|
+
context.fail!(message: @vendor.errors.full_messages.join(', '))
|
27
|
+
end
|
28
|
+
|
29
|
+
def assign_vendor_to_user
|
30
|
+
context.user.vendors << @vendor
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_role
|
34
|
+
role = context.user.spree_roles.create(
|
35
|
+
name: "#{@vendor.name.downcase.parameterize(separator: '-')}-organizer",
|
36
|
+
vendor_id: @vendor.id,
|
37
|
+
presentation: 'Organizer'
|
38
|
+
)
|
39
|
+
return if role.persisted?
|
40
|
+
|
41
|
+
context.fail!(message: role.errors.full_messages.to_sentence)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Spree
|
2
2
|
module OrderMailerDecorator
|
3
|
-
# overrided
|
4
3
|
def cancel_email(order, resend: false)
|
5
4
|
@order = order.respond_to?(:id) ? order : Spree::Order.find(order)
|
6
5
|
return false if @order.email.blank?
|
@@ -12,18 +11,34 @@ module Spree
|
|
12
11
|
@order = order.respond_to?(:id) ? order : Spree::Order.find(order)
|
13
12
|
return false if @order.email.blank?
|
14
13
|
|
14
|
+
@tenant = @order.tenant
|
15
|
+
if @tenant.present?
|
16
|
+
@brand_color = @tenant.preferences[:brand_primary_color]
|
17
|
+
@vendor_logo_url = @tenant.active_vendor&.logo&.original_url
|
18
|
+
end
|
19
|
+
|
15
20
|
@current_store = @order.store
|
16
21
|
@product_type = @order.products.first&.product_type || 'accommodation'
|
17
22
|
|
18
|
-
subject =
|
23
|
+
subject = resend ? "[#{Spree.t(:resend).upcase}] " : ''
|
19
24
|
subject += "#{@current_store&.name} Booking Confirmation ##{@order.number}"
|
20
25
|
|
21
|
-
mail(to: @order.email, from:
|
26
|
+
mail(to: @order.email, from: from_email_address, subject: subject, store_url: @current_store.url) do |format|
|
22
27
|
format.html { render layout: 'spree_cm_commissioner/layouts/order_mailer' }
|
23
28
|
format.text
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
32
|
+
private
|
33
|
+
|
34
|
+
def from_email_address
|
35
|
+
if @order.tenant.nil?
|
36
|
+
from_address
|
37
|
+
else
|
38
|
+
@order.tenant.active_vendor&.from_email
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
27
42
|
def ticket_email(guest, email)
|
28
43
|
@guest = guest
|
29
44
|
@event = @guest.event
|
@@ -55,6 +55,24 @@ module SpreeCmCommissioner
|
|
55
55
|
def set_duration
|
56
56
|
self.from_date ||= variant.start_date_time || event&.from_date
|
57
57
|
self.to_date ||= variant.end_date_time || event&.to_date
|
58
|
+
|
59
|
+
return if persisted?
|
60
|
+
|
61
|
+
apply_variant_time(:from_date, variant.start_date_time)
|
62
|
+
apply_variant_time(:to_date, variant.end_date_time)
|
63
|
+
end
|
64
|
+
|
65
|
+
def apply_variant_time(field, variant_time)
|
66
|
+
field_value = send(field)
|
67
|
+
|
68
|
+
return unless field_value.present? && field_value.hour.zero? && variant_time.present?
|
69
|
+
|
70
|
+
send("#{field}=", field_value.change(
|
71
|
+
hour: variant_time.hour,
|
72
|
+
min: variant_time.min,
|
73
|
+
sec: variant_time.sec
|
74
|
+
)
|
75
|
+
)
|
58
76
|
end
|
59
77
|
end
|
60
78
|
end
|
@@ -9,6 +9,7 @@ module SpreeCmCommissioner
|
|
9
9
|
preference :payment_failed_image, :string, default: ''
|
10
10
|
preference :payment_success_image, :string, default: ''
|
11
11
|
preference :payment_loader, :string, default: ''
|
12
|
+
preference :brand_primary_color, :string, default: ''
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -53,8 +53,9 @@ module SpreeCmCommissioner
|
|
53
53
|
# No need to fallback to event start date to avoid n+1.
|
54
54
|
# To get end_time duration of event, include event when needed instead.
|
55
55
|
def start_date_time
|
56
|
-
return nil if start_date.blank?
|
56
|
+
return nil if start_date.blank? && start_time.blank?
|
57
57
|
return start_date if start_time.blank?
|
58
|
+
return start_time if start_date.blank?
|
58
59
|
|
59
60
|
start_date.change(hour: start_time.hour, min: start_time.min, sec: start_time.sec)
|
60
61
|
end
|
@@ -62,8 +63,9 @@ module SpreeCmCommissioner
|
|
62
63
|
# No need to fallback to event end date to avoid n+1.
|
63
64
|
# To get end_time duration of event, include event when needed instead.
|
64
65
|
def end_date_time
|
65
|
-
return nil if end_date.blank?
|
66
|
+
return nil if end_date.blank? && end_time.blank?
|
66
67
|
return end_date if end_time.blank?
|
68
|
+
return end_time if end_date.blank?
|
67
69
|
|
68
70
|
end_date.change(hour: end_time.hour, min: end_time.min, sec: end_time.sec)
|
69
71
|
end
|
@@ -9,12 +9,14 @@ module SpreeCmCommissioner
|
|
9
9
|
has_many :product_dynamic_fields, class_name: 'SpreeCmCommissioner::ProductDynamicField', dependent: :destroy
|
10
10
|
|
11
11
|
enum data_type: { text: 0, number: 1, boolean: 2, checkbox: 3, radio: 4, selection: 5, textarea: 6 }
|
12
|
+
enum data_fill_stage: { pre_registration: 0, post_registration: 1, during_check_in: 2 }
|
12
13
|
|
13
14
|
accepts_nested_attributes_for :dynamic_field_options, allow_destroy: true, reject_if: :all_blank
|
14
15
|
|
15
16
|
validates :label, presence: true
|
16
17
|
validates :data_type, presence: true
|
17
18
|
validates :configurations, presence: true, allow_blank: false
|
19
|
+
validate :validate_data_fill_stage_phase
|
18
20
|
|
19
21
|
def requires_dynamic_field_options?
|
20
22
|
checkbox? || radio? || selection?
|
@@ -30,5 +32,23 @@ module SpreeCmCommissioner
|
|
30
32
|
self.configurations ||= {}
|
31
33
|
self.configurations['multiple_select'] = ActiveModel::Type::Boolean.new.cast(value)
|
32
34
|
end
|
35
|
+
|
36
|
+
def required_at_stage?(stage)
|
37
|
+
data_fill_stage == stage.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def display_label
|
41
|
+
label + " (#{data_fill_stage.humanize})"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def validate_data_fill_stage_phase
|
47
|
+
return if data_fill_stage.blank?
|
48
|
+
|
49
|
+
return if data_fill_stage.in?(self.class.data_fill_stages.keys)
|
50
|
+
|
51
|
+
errors.add(:data_fill_stage, "must be one of: #{self.class.data_fill_stages.keys.join(', ')}")
|
52
|
+
end
|
33
53
|
end
|
34
54
|
end
|
@@ -213,6 +213,62 @@ module SpreeCmCommissioner
|
|
213
213
|
save!
|
214
214
|
end
|
215
215
|
|
216
|
+
def missing_dynamic_fields_for_stage(stage)
|
217
|
+
required_fields = line_item.product.dynamic_fields.where(data_fill_stage: stage)
|
218
|
+
filled_ids = guest_dynamic_fields.map(&:dynamic_field_id)
|
219
|
+
|
220
|
+
required_fields.reject { |field| filled_ids.include?(field.id) }
|
221
|
+
end
|
222
|
+
|
223
|
+
def all_required_dynamic_fields_completed?(stage)
|
224
|
+
missing_dynamic_fields_for_stage(stage).blank?
|
225
|
+
end
|
226
|
+
|
227
|
+
def validate_dynamic_fields_for_phase(phase)
|
228
|
+
required_fields = line_item.product.dynamic_fields.where(data_fill_stage: phase)
|
229
|
+
filled_ids = guest_dynamic_fields.map(&:dynamic_field_id)
|
230
|
+
|
231
|
+
required_fields.each do |field|
|
232
|
+
errors.add(:base, "#{field.label} is required for #{phase} phase") unless filled_ids.include?(field.id)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def pre_registration_completed?
|
237
|
+
return true unless line_item.product.dynamic_fields.pre_registration.any?
|
238
|
+
|
239
|
+
pre_registration_fields_completed?
|
240
|
+
end
|
241
|
+
|
242
|
+
def post_registration_completed?
|
243
|
+
return true unless line_item.product.dynamic_fields.post_registration.any?
|
244
|
+
|
245
|
+
post_registration_fields_completed?
|
246
|
+
end
|
247
|
+
|
248
|
+
def check_in_completed?
|
249
|
+
return true unless line_item.product.dynamic_fields.during_check_in.any?
|
250
|
+
|
251
|
+
check_in_fields_completed?
|
252
|
+
end
|
253
|
+
|
254
|
+
def current_collection_phase
|
255
|
+
if check_in.present?
|
256
|
+
:during_check_in
|
257
|
+
elsif line_item.order.completed?
|
258
|
+
:post_registration
|
259
|
+
else
|
260
|
+
:pre_registration
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def phase_completion_status
|
265
|
+
{
|
266
|
+
pre_registration: pre_registration_completed?,
|
267
|
+
post_registration: post_registration_completed?,
|
268
|
+
during_check_in: check_in_completed?
|
269
|
+
}
|
270
|
+
end
|
271
|
+
|
216
272
|
# bib_number: 345, bib_prefix: 5KM, bib_zerofill: 5 => return 5KM00345
|
217
273
|
# bib_number: 345, bib_prefix: 5KM, bib_zerofill: 2 => return 5KM345
|
218
274
|
def formatted_bib_number
|
@@ -7,6 +7,7 @@ module SpreeCmCommissioner
|
|
7
7
|
validates :value, presence: true
|
8
8
|
validate :validate_value_format, if: -> { value.present? && dynamic_field.present? }
|
9
9
|
validate :validate_option_reference, if: -> { dynamic_field_option.present? }
|
10
|
+
validate :check_required_fields_based_on_phase
|
10
11
|
|
11
12
|
private
|
12
13
|
|
@@ -34,10 +35,49 @@ module SpreeCmCommissioner
|
|
34
35
|
|
35
36
|
def validate_option_reference
|
36
37
|
return if dynamic_field.blank? || dynamic_field_option.blank?
|
37
|
-
|
38
38
|
return if dynamic_field_option.dynamic_field_id == dynamic_field_id
|
39
39
|
|
40
40
|
errors.add(:dynamic_field_option, 'must belong to the same dynamic field')
|
41
41
|
end
|
42
|
+
|
43
|
+
def before_checkin_phase?
|
44
|
+
guest.present? && guest.line_item.present? && guest.check_in.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def after_purchase_phase?
|
48
|
+
guest.present? && guest.line_item.present? && guest.line_item.completed? && guest.check_in.nil?
|
49
|
+
end
|
50
|
+
|
51
|
+
def during_checkin_phase?
|
52
|
+
guest.present? && guest.check_in.present?
|
53
|
+
end
|
54
|
+
|
55
|
+
def pre_registration_required?
|
56
|
+
dynamic_field.data_fill_stage.to_sym == :pre_registration &&
|
57
|
+
guest.line_item.order.completed? && guest.check_in.blank?
|
58
|
+
end
|
59
|
+
|
60
|
+
def post_registration_required?
|
61
|
+
dynamic_field.data_fill_stage.to_sym == :post_registration &&
|
62
|
+
guest.line_item.order.completed? && guest.check_in.blank?
|
63
|
+
end
|
64
|
+
|
65
|
+
def during_check_in_required?
|
66
|
+
dynamic_field.data_fill_stage.to_sym == :during_check_in &&
|
67
|
+
guest.check_in.present?
|
68
|
+
end
|
69
|
+
|
70
|
+
def check_required_fields_based_on_phase
|
71
|
+
return if dynamic_field.blank? || value.present?
|
72
|
+
|
73
|
+
case dynamic_field.data_fill_stage.to_sym
|
74
|
+
when :pre_registration
|
75
|
+
errors.add(:value, I18n.t('guest_dynamic_field.errors.pre_registration_required')) if pre_registration_required?
|
76
|
+
when :post_registration
|
77
|
+
errors.add(:value, I18n.t('guest_dynamic_field.errors.post_registration_required')) if post_registration_required?
|
78
|
+
when :during_check_in
|
79
|
+
errors.add(:value, I18n.t('guest_dynamic_field.errors.during_check_in_required')) if during_check_in_required?
|
80
|
+
end
|
81
|
+
end
|
42
82
|
end
|
43
83
|
end
|
@@ -86,6 +86,28 @@ module SpreeCmCommissioner
|
|
86
86
|
"#{Spree::Store.default.formatted_url}/tickets/#{slug}"
|
87
87
|
end
|
88
88
|
|
89
|
+
def dynamic_fields_by_collection_phase
|
90
|
+
{
|
91
|
+
pre_registration: dynamic_fields.pre_registration.order(:position),
|
92
|
+
post_registration: dynamic_fields.post_registration.order(:position),
|
93
|
+
during_check_in: dynamic_fields.during_check_in.order(:position)
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def required_dynamic_fields_completed?(guest, phase)
|
98
|
+
required_fields = dynamic_fields.where(data_fill_stage: phase)
|
99
|
+
return true if required_fields.empty?
|
100
|
+
|
101
|
+
filled_ids = guest.guest_dynamic_fields.where(dynamic_field_id: required_fields.select(:id)).pluck(:dynamic_field_id)
|
102
|
+
(required_fields.pluck(:id) - filled_ids).empty?
|
103
|
+
end
|
104
|
+
|
105
|
+
def required_fields_for_guest(guest)
|
106
|
+
dynamic_fields_by_collection_phase.transform_values do |fields|
|
107
|
+
fields.select { |field| guest.guest_dynamic_fields.where(dynamic_field: field).empty? }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
89
111
|
private
|
90
112
|
|
91
113
|
def set_tenant
|
@@ -88,6 +88,12 @@ module SpreeCmCommissioner
|
|
88
88
|
has_spree_role?('operator')
|
89
89
|
end
|
90
90
|
|
91
|
+
def vendor_organizer?(vendor)
|
92
|
+
spree_roles.any? do |role|
|
93
|
+
role.name == "#{vendor.name.downcase.parameterize(separator: '-')}-organizer"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
91
97
|
def full_name
|
92
98
|
[first_name, last_name].compact_blank.join(' ')
|
93
99
|
end
|
@@ -93,6 +93,7 @@ module SpreeCmCommissioner
|
|
93
93
|
}
|
94
94
|
|
95
95
|
base.validates :commission_rate, presence: true, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
|
96
|
+
base.validates :from_email, presence: true, if: :tenant_present?
|
96
97
|
|
97
98
|
def base.by_vendor_id!(vendor_id)
|
98
99
|
if vendor_id.to_s =~ /^\d+$/
|
@@ -195,6 +196,8 @@ module SpreeCmCommissioner
|
|
195
196
|
|
196
197
|
vendor_kind_option_values.where(option_type_id: rules_option_type.id)
|
197
198
|
end
|
199
|
+
|
200
|
+
delegate :present?, to: :tenant, prefix: true
|
198
201
|
end
|
199
202
|
end
|
200
203
|
|