spree_cm_commissioner 1.16.0 → 1.17.0.pre.pre
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 +8 -12
- data/app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb +28 -0
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +2 -1
- data/app/interactors/spree_cm_commissioner/create_event.rb +2 -1
- data/app/mailers/spree_cm_commissioner/team_invite_mailer.rb +13 -0
- data/app/models/concerns/spree_cm_commissioner/participation_type_bitwise.rb +47 -0
- data/app/models/spree_cm_commissioner/dynamic_field.rb +20 -0
- data/app/models/spree_cm_commissioner/dynamic_field_option.rb +18 -0
- data/app/models/spree_cm_commissioner/guest.rb +4 -2
- data/app/models/spree_cm_commissioner/guest_dynamic_field.rb +25 -0
- data/app/models/spree_cm_commissioner/invite_team.rb +44 -0
- data/app/models/spree_cm_commissioner/product_decorator.rb +2 -0
- data/app/models/spree_cm_commissioner/product_dynamic_field.rb +8 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
- data/app/serializers/spree/v2/storefront/product_serializer_decorator.rb +1 -0
- data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +2 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb +11 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb +13 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb +13 -0
- data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +3 -2
- data/app/serializers/spree_cm_commissioner/v2/storefront/product_dynamic_field_serializer.rb +13 -0
- data/app/services/spree_cm_commissioner/user_roles_assigner.rb +0 -6
- data/app/views/spree_cm_commissioner/layouts/team_invite_mailer.html.erb +15 -0
- data/app/views/spree_cm_commissioner/team_invite_mailer/_mailer_stylesheets.html.erb +79 -0
- data/app/views/spree_cm_commissioner/team_invite_mailer/send_team_invite_email.html.erb +42 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20250512072817_create_spree_cm_commissioner_invite_team.rb +15 -0
- data/db/migrate/20250605024523_add_participation_type_to_spree_taxon.rb +5 -0
- data/db/migrate/20250606020914_create_cm_dynamic_fields.rb +11 -0
- data/db/migrate/20250606020958_create_cm_guest_dynamic_fields.rb +11 -0
- data/db/migrate/20250606021044_create_cm_dynamic_field_options.rb +10 -0
- data/db/migrate/20250606021045_create_cm_product_dynamic_fields.rb +10 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +25 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cc0c166a073d01107caea18b4b7f2381d12b9372ac67aa80b570687aaf59702
|
4
|
+
data.tar.gz: 0d736865e66226bed4f07171d02879c6d009d760595d88f6f63605e57bc228a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e55841d41f47a5aedd68cb9c81309f356f1731d24c1771d8955f6d20d0cb8050f5aefe867bbe3d1501b4fb421aca87daea26a9314281efda5d2b89792f332c63
|
7
|
+
data.tar.gz: 2f6b56fb52a8cf35206c8b24c99d0b991fbed3343c8ca56377f53febc7080c25af53ff1d839ae63c6bfa6ca6a148ffcb427c88fce10e58f60892d536106a14bb
|
data/Gemfile.lock
CHANGED
@@ -34,7 +34,7 @@ GIT
|
|
34
34
|
PATH
|
35
35
|
remote: .
|
36
36
|
specs:
|
37
|
-
spree_cm_commissioner (1.
|
37
|
+
spree_cm_commissioner (1.17.0.pre.pre)
|
38
38
|
activerecord-multi-tenant
|
39
39
|
activerecord_json_validator (~> 2.1, >= 2.1.3)
|
40
40
|
aws-sdk-cloudfront
|
@@ -446,14 +446,14 @@ GEM
|
|
446
446
|
google-cloud-recaptcha_enterprise-v1beta1 (0.10.0)
|
447
447
|
gapic-common (>= 0.20.0, < 2.a)
|
448
448
|
google-cloud-errors (~> 1.0)
|
449
|
-
google-protobuf (3.25.
|
450
|
-
google-protobuf (3.25.
|
451
|
-
google-protobuf (3.25.
|
449
|
+
google-protobuf (3.25.8)
|
450
|
+
google-protobuf (3.25.8-x86_64-darwin)
|
451
|
+
google-protobuf (3.25.8-x86_64-linux)
|
452
452
|
googleapis-common-protos (1.4.0)
|
453
453
|
google-protobuf (~> 3.14)
|
454
454
|
googleapis-common-protos-types (~> 1.2)
|
455
455
|
grpc (~> 1.27)
|
456
|
-
googleapis-common-protos-types (1.
|
456
|
+
googleapis-common-protos-types (1.20.0)
|
457
457
|
google-protobuf (>= 3.18, < 5.a)
|
458
458
|
googleauth (1.8.1)
|
459
459
|
faraday (>= 0.17.3, < 3.a)
|
@@ -461,13 +461,13 @@ GEM
|
|
461
461
|
multi_json (~> 1.11)
|
462
462
|
os (>= 0.9, < 2.0)
|
463
463
|
signet (>= 0.16, < 2.a)
|
464
|
-
grpc (1.
|
464
|
+
grpc (1.72.0)
|
465
465
|
google-protobuf (>= 3.25, < 5.0)
|
466
466
|
googleapis-common-protos-types (~> 1.0)
|
467
|
-
grpc (1.
|
467
|
+
grpc (1.72.0-x86_64-darwin)
|
468
468
|
google-protobuf (>= 3.25, < 5.0)
|
469
469
|
googleapis-common-protos-types (~> 1.0)
|
470
|
-
grpc (1.
|
470
|
+
grpc (1.72.0-x86_64-linux)
|
471
471
|
google-protobuf (>= 3.25, < 5.0)
|
472
472
|
googleapis-common-protos-types (~> 1.0)
|
473
473
|
hana (1.3.7)
|
@@ -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)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Spree
|
2
|
+
module Api
|
3
|
+
module V2
|
4
|
+
module Storefront
|
5
|
+
class DynamicFieldOptionsController < ::Spree::Api::V2::ResourceController
|
6
|
+
# override
|
7
|
+
def collection
|
8
|
+
return @collection if defined?(@collection)
|
9
|
+
return SpreeCmCommissioner::DynamicFieldOption.none if params[:dynamic_field_id].blank?
|
10
|
+
|
11
|
+
@collection = SpreeCmCommissioner::DynamicFieldOption.where(dynamic_field_id: params[:dynamic_field_id])
|
12
|
+
@collection = @collection.where('value LIKE ?', "%#{params[:query]}%") if params[:query].present?
|
13
|
+
@collection
|
14
|
+
end
|
15
|
+
|
16
|
+
# override
|
17
|
+
def collection_serializer
|
18
|
+
SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
|
19
|
+
end
|
20
|
+
|
21
|
+
def model_class
|
22
|
+
SpreeCmCommissioner::DynamicFieldOption
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -23,7 +23,8 @@ module SpreeCmCommissioner
|
|
23
23
|
from_date: context.params[:from_date],
|
24
24
|
to_date: context.params[:to_date],
|
25
25
|
parent_id: context.params[:parent_id],
|
26
|
-
taxonomy_id: context.params[:taxonomy_id]
|
26
|
+
taxonomy_id: context.params[:taxonomy_id],
|
27
|
+
vendor_id: context.current_vendor.id
|
27
28
|
)
|
28
29
|
|
29
30
|
if @parent_taxon.save
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class TeamInviteMailer < Spree::BaseMailer
|
3
|
+
layout 'spree_cm_commissioner/layouts/team_invite_mailer'
|
4
|
+
|
5
|
+
def send_team_invite_email(invite_team_id)
|
6
|
+
@invite_team = SpreeCmCommissioner::InviteTeam.find(invite_team_id)
|
7
|
+
|
8
|
+
subject = Spree::Store.default.name.to_s
|
9
|
+
|
10
|
+
mail(from: from_address, to: @invite_team.email, subject: subject)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module ParticipationTypeBitwise
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
BIT_FIELDS = {
|
6
|
+
invitation_only: 0b1,
|
7
|
+
public: 0b10,
|
8
|
+
private: 0b100,
|
9
|
+
virtual: 0b1000,
|
10
|
+
free: 0b10000,
|
11
|
+
internal: 0b100000
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
ORDERED_BIT_FIELDS = %i[
|
15
|
+
invitation_only
|
16
|
+
public
|
17
|
+
private
|
18
|
+
virtual
|
19
|
+
free
|
20
|
+
internal
|
21
|
+
].freeze
|
22
|
+
|
23
|
+
def participation_type? = participation_type != 0
|
24
|
+
|
25
|
+
BIT_FIELDS.each do |field, bit_value|
|
26
|
+
define_method "#{field}?" do
|
27
|
+
participation_type_enabled?(bit_value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def unordered_participation_type_fields
|
32
|
+
BIT_FIELDS.filter_map do |field, bit_value|
|
33
|
+
field if participation_type & bit_value != 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def participation_type_fields
|
38
|
+
unordered_participation_type_fields.sort_by { |item| ORDERED_BIT_FIELDS.index(item) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def participation_type_enabled?(bit_value)
|
42
|
+
return false if participation_type.nil?
|
43
|
+
|
44
|
+
participation_type & bit_value != 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class DynamicField < SpreeCmCommissioner::Base
|
3
|
+
belongs_to :vendor, class_name: 'Spree::Vendor', optional: false
|
4
|
+
|
5
|
+
has_many :dynamic_field_options, class_name: 'SpreeCmCommissioner::DynamicFieldOption', dependent: :destroy
|
6
|
+
has_many :guest_dynamic_fields, class_name: 'SpreeCmCommissioner::GuestDynamicField', dependent: :destroy
|
7
|
+
has_many :product_dynamic_fields, class_name: 'SpreeCmCommissioner::ProductDynamicField', dependent: :destroy
|
8
|
+
|
9
|
+
enum data_type: { string: 0, integer: 1, boolean: 2, checkbox: 3, radio: 4 }
|
10
|
+
|
11
|
+
accepts_nested_attributes_for :dynamic_field_options, allow_destroy: true, reject_if: :all_blank
|
12
|
+
|
13
|
+
validates :label, presence: true
|
14
|
+
validates :data_type, presence: true
|
15
|
+
|
16
|
+
def selection?
|
17
|
+
checkbox? || radio?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class DynamicFieldOption < SpreeCmCommissioner::Base
|
3
|
+
belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
|
4
|
+
|
5
|
+
validates :value, presence: true, uniqueness: { scope: :dynamic_field_id }
|
6
|
+
validate :parent_field_must_be_selection_type
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def parent_field_must_be_selection_type
|
11
|
+
return unless dynamic_field
|
12
|
+
|
13
|
+
return if dynamic_field.selection?
|
14
|
+
|
15
|
+
errors.add(:dynamic_field, 'must be a selection type field')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# rubocop:disable Metrics/ClassLength
|
2
2
|
module SpreeCmCommissioner
|
3
|
-
class Guest < SpreeCmCommissioner::Base
|
3
|
+
class Guest < SpreeCmCommissioner::Base # rubocop:disable Metrics/ClassLength
|
4
4
|
include SpreeCmCommissioner::KycBitwise
|
5
5
|
include SpreeCmCommissioner::PhoneNumberSanitizer
|
6
6
|
|
@@ -32,6 +32,8 @@ module SpreeCmCommissioner
|
|
32
32
|
scope :no_show, -> { left_outer_joins(:check_in).where(cm_check_ins: { id: nil }) }
|
33
33
|
|
34
34
|
has_many :state_changes, as: :stateful, class_name: 'Spree::StateChange'
|
35
|
+
has_many :guest_dynamic_fields, dependent: :destroy, class_name: 'SpreeCmCommissioner::GuestDynamicField'
|
36
|
+
accepts_nested_attributes_for :guest_dynamic_fields, allow_destroy: true
|
35
37
|
|
36
38
|
belongs_to :event, class_name: 'Spree::Taxon'
|
37
39
|
|
@@ -44,7 +46,7 @@ module SpreeCmCommissioner
|
|
44
46
|
before_validation :set_event_id
|
45
47
|
before_validation :assign_seat_number, if: -> { bib_number.present? }
|
46
48
|
|
47
|
-
before_create :generate_bib, if: -> { variant.bib_pre_generation_on_create? }
|
49
|
+
before_create :generate_bib, if: -> { line_item.reload && variant.bib_pre_generation_on_create? }
|
48
50
|
|
49
51
|
validates :seat_number, uniqueness: { scope: :event_id }, allow_nil: true, if: -> { event_id.present? }
|
50
52
|
validates :bib_index, uniqueness: true, allow_nil: true
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class GuestDynamicField < SpreeCmCommissioner::Base
|
3
|
+
belongs_to :guest, class_name: 'SpreeCmCommissioner::Guest', optional: false
|
4
|
+
belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
|
5
|
+
|
6
|
+
validates :value, presence: true
|
7
|
+
validate :validate_value_format, if: -> { value.present? && dynamic_field.present? }
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def validate_value_format
|
12
|
+
return if dynamic_field.blank?
|
13
|
+
|
14
|
+
case dynamic_field.data_type.to_s
|
15
|
+
when 'integer'
|
16
|
+
errors.add(:value, 'must be a number') unless value.to_s.match?(/\A\d+\z/)
|
17
|
+
when 'boolean'
|
18
|
+
errors.add(:value, 'must be true or false') unless %w[true false 1 0].include?(value.to_s.downcase)
|
19
|
+
when 'checkbox', 'radio'
|
20
|
+
valid_options = dynamic_field.dynamic_field_options.pluck(:id).map(&:to_s)
|
21
|
+
errors.add(:value, 'is not a valid option') unless valid_options.include?(value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class InviteTeam < SpreeCmCommissioner::Base
|
3
|
+
belongs_to :user, class_name: 'Spree::User', optional: true
|
4
|
+
belongs_to :inviter, class_name: 'Spree::User'
|
5
|
+
belongs_to :vendor, class_name: 'Spree::Vendor'
|
6
|
+
|
7
|
+
attr_reader :user_id, :vendor_id
|
8
|
+
|
9
|
+
enum status: { pending: 0, accepted: 1 }, _default: 0
|
10
|
+
|
11
|
+
preference :role_ids, :array, default: []
|
12
|
+
|
13
|
+
validate :validate_roles
|
14
|
+
|
15
|
+
after_create :set_expiration
|
16
|
+
after_create :send_team_invite_email
|
17
|
+
|
18
|
+
def roles
|
19
|
+
Spree::Role.where(id: preferred_role_ids)
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate_roles
|
23
|
+
return if preferred_role_ids.present?
|
24
|
+
|
25
|
+
errors.add(:base, I18n.t('user_roles_assigner.roles_required'))
|
26
|
+
end
|
27
|
+
|
28
|
+
def send_team_invite_email
|
29
|
+
SpreeCmCommissioner::TeamInviteMailer.send_team_invite_email(id).deliver_now
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_expiration
|
33
|
+
update(expires_at: 3.days.from_now)
|
34
|
+
end
|
35
|
+
|
36
|
+
def invitation_link
|
37
|
+
"http://#{ENV.fetch('APP_HOST')}/organizer/invite_teams/#{token}?utm_source=email"
|
38
|
+
end
|
39
|
+
|
40
|
+
def url_valid?
|
41
|
+
expires_at.present? && expires_at > Time.current
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -37,6 +37,8 @@ module SpreeCmCommissioner
|
|
37
37
|
|
38
38
|
base.has_many :product_places, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
|
39
39
|
base.has_many :places, through: :product_places
|
40
|
+
base.has_many :product_dynamic_fields, class_name: 'SpreeCmCommissioner::ProductDynamicField', dependent: :destroy
|
41
|
+
base.has_many :dynamic_fields, through: :product_dynamic_fields, class_name: 'SpreeCmCommissioner::DynamicField'
|
40
42
|
|
41
43
|
base.has_one :venue, -> { where(type: :venue) }, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
|
42
44
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class ProductDynamicField < SpreeCmCommissioner::Base
|
3
|
+
belongs_to :product, class_name: 'Spree::Product', optional: false
|
4
|
+
belongs_to :dynamic_field, class_name: 'SpreeCmCommissioner::DynamicField', optional: false
|
5
|
+
|
6
|
+
validates :dynamic_field_id, uniqueness: { scope: :product_id }
|
7
|
+
end
|
8
|
+
end
|
@@ -3,6 +3,7 @@ module SpreeCmCommissioner
|
|
3
3
|
def self.prepended(base) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
4
4
|
base.include SpreeCmCommissioner::TaxonKind
|
5
5
|
base.include SpreeCmCommissioner::Transit::TaxonBitwise
|
6
|
+
base.include SpreeCmCommissioner::ParticipationTypeBitwise
|
6
7
|
|
7
8
|
base.preference :background_color, :string
|
8
9
|
base.preference :foreground_color, :string
|
@@ -33,6 +33,7 @@ module SpreeCmCommissioner
|
|
33
33
|
|
34
34
|
base.multi_tenant :tenant, class_name: 'SpreeCmCommissioner::Tenant'
|
35
35
|
base.scope :by_tenant, -> (tenant_id) { where(tenant_id: tenant_id) }
|
36
|
+
base.scope :vendor_users, -> (vendor_id) { joins(:role_users => :role).where(spree_roles: { vendor_id: vendor_id }).distinct }
|
36
37
|
|
37
38
|
base.whitelisted_ransackable_attributes = %w[email first_name last_name gender phone_number]
|
38
39
|
|
@@ -51,6 +51,7 @@ module SpreeCmCommissioner
|
|
51
51
|
through: :vendor_stops, source: :stop, class_name: 'SpreeCmCommissioner::Place'
|
52
52
|
base.has_many :drop_off_points, -> { where(cm_vendor_stops: { stop_type: 1 }) },
|
53
53
|
through: :vendor_stops, source: :stop, class_name: 'SpreeCmCommissioner::Place'
|
54
|
+
base.has_many :dynamic_fields, class_name: 'SpreeCmCommissioner::DynamicField', foreign_key: :vendor_id, dependent: :destroy
|
54
55
|
|
55
56
|
base.has_one :logo, as: :viewable, dependent: :destroy, class_name: 'SpreeCmCommissioner::VendorLogo'
|
56
57
|
base.has_one :payment_qrcode, as: :viewable, dependent: :destroy, class_name: 'SpreeCmCommissioner::VendorPaymentQrcode'
|
@@ -7,6 +7,7 @@ module Spree
|
|
7
7
|
base.has_many :product_kind_option_types, serializer: :option_type
|
8
8
|
base.has_many :promoted_option_types, serializer: :option_type
|
9
9
|
base.has_many :possible_promotions, serializer: ::SpreeCmCommissioner::V2::Storefront::PromotionSerializer
|
10
|
+
base.has_many :dynamic_fields, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldSerializer
|
10
11
|
|
11
12
|
base.has_one :default_state, serializer: :state
|
12
13
|
base.has_one :venue, serializer: ::SpreeCmCommissioner::V2::Storefront::ProductPlaceSerializer
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module V2
|
3
|
+
module Storefront
|
4
|
+
class DynamicFieldSerializer < BaseSerializer
|
5
|
+
set_type :dynamic_field
|
6
|
+
|
7
|
+
attributes :id, :label, :data_type, :vendor_id, :created_at, :updated_at
|
8
|
+
|
9
|
+
has_many :dynamic_field_options, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldOptionSerializer
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module V2
|
3
|
+
module Storefront
|
4
|
+
class GuestDynamicFieldSerializer < BaseSerializer
|
5
|
+
set_type :guest_dynamic_field
|
6
|
+
|
7
|
+
attributes :id, :value, :guest_id, :dynamic_field_id, :created_at, :updated_at
|
8
|
+
|
9
|
+
belongs_to :dynamic_field, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldSerializer
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -20,12 +20,13 @@ module SpreeCmCommissioner
|
|
20
20
|
|
21
21
|
belongs_to :occupation, serializer: Spree::V2::Storefront::TaxonSerializer
|
22
22
|
belongs_to :nationality, serializer: Spree::V2::Storefront::TaxonSerializer
|
23
|
+
belongs_to :line_item, serializer: Spree::V2::Storefront::LineItemSerializer
|
24
|
+
|
25
|
+
has_many :guest_dynamic_fields, serializer: SpreeCmCommissioner::V2::Storefront::GuestDynamicFieldSerializer
|
23
26
|
|
24
27
|
has_one :id_card, serializer: Spree::V2::Storefront::IdCardSerializer
|
25
28
|
has_one :check_in
|
26
29
|
|
27
|
-
belongs_to :line_item, serializer: Spree::V2::Storefront::LineItemSerializer
|
28
|
-
|
29
30
|
# allowed_checkout updates frequently
|
30
31
|
cache_options store: nil
|
31
32
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module V2
|
3
|
+
module Storefront
|
4
|
+
class ProductDynamicFieldSerializer < BaseSerializer
|
5
|
+
set_type :product_dynamic_field
|
6
|
+
|
7
|
+
attributes :id, :product_id, :dynamic_field_id, :created_at, :updated_at
|
8
|
+
|
9
|
+
belongs_to :dynamic_field, serializer: SpreeCmCommissioner::V2::Storefront::DynamicFieldSerializer
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -19,17 +19,11 @@ module SpreeCmCommissioner
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def create
|
22
|
-
return { success: false, message: I18n.t('user_roles_assigner.user_not_found') } unless user
|
23
|
-
return { success: false, message: I18n.t('user_roles_assigner.user_already_assigned') } if user.vendors.exists?(id: vendor_id)
|
24
|
-
return { success: false, message: I18n.t('user_roles_assigner.roles_required') } if role_ids.blank?
|
25
|
-
|
26
22
|
create_roles
|
27
23
|
{ success: true }
|
28
24
|
end
|
29
25
|
|
30
26
|
def update
|
31
|
-
return { success: false, message: I18n.t('user_roles_assigner.roles_required') } if role_ids.blank?
|
32
|
-
|
33
27
|
update_roles
|
34
28
|
{ success: true }
|
35
29
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
6
|
+
<meta name="x-apple-disable-message-reformatting"/>
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
8
|
+
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
|
9
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
10
|
+
<%= render partial: 'spree_cm_commissioner/team_invite_mailer/mailer_stylesheets' %>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<%= yield %>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -0,0 +1,79 @@
|
|
1
|
+
<style>
|
2
|
+
body, table, td {
|
3
|
+
font-family: 'Poppins', Arial, sans-serif;
|
4
|
+
margin: 0;
|
5
|
+
padding: 0;
|
6
|
+
}
|
7
|
+
|
8
|
+
.content-wrapper {
|
9
|
+
max-width: 500px;
|
10
|
+
margin: 0 auto;
|
11
|
+
border: 1px solid grey;
|
12
|
+
border-top: none;
|
13
|
+
}
|
14
|
+
|
15
|
+
.main-content{
|
16
|
+
padding-top: 10px;
|
17
|
+
padding-bottom: 25px;
|
18
|
+
}
|
19
|
+
|
20
|
+
.heading-1 {
|
21
|
+
font-size: 24px;
|
22
|
+
text-align: center;
|
23
|
+
line-height: 1.4;
|
24
|
+
margin-top: 10px;
|
25
|
+
margin-bottom: 15px;
|
26
|
+
padding-left: 5px;
|
27
|
+
padding-right: 5px;
|
28
|
+
|
29
|
+
}
|
30
|
+
|
31
|
+
.bar-large {
|
32
|
+
height: 10px;
|
33
|
+
background-color: #5D54D9;
|
34
|
+
margin-bottom: 20px;
|
35
|
+
|
36
|
+
}
|
37
|
+
|
38
|
+
.bar-thin {
|
39
|
+
height: 1px;
|
40
|
+
background-color: grey;
|
41
|
+
width: 100%;
|
42
|
+
margin: 20px auto;
|
43
|
+
}
|
44
|
+
|
45
|
+
.heading-2 {
|
46
|
+
font-size: 16px;
|
47
|
+
text-align: center;
|
48
|
+
line-height: 1.5;
|
49
|
+
}
|
50
|
+
|
51
|
+
.title-bold {
|
52
|
+
font-weight: bold;
|
53
|
+
color: #000;
|
54
|
+
}
|
55
|
+
|
56
|
+
.action-button {
|
57
|
+
display: inline-block;
|
58
|
+
background-color: #5D54D9;
|
59
|
+
border-radius: 24px;
|
60
|
+
font-size: 14px;
|
61
|
+
width: 222px;
|
62
|
+
height: 50px;
|
63
|
+
text-align: center;
|
64
|
+
line-height: 50px;
|
65
|
+
text-decoration: none;
|
66
|
+
cursor: pointer;
|
67
|
+
margin: 15px 0;
|
68
|
+
color: white !important;
|
69
|
+
text-decoration: none;
|
70
|
+
}
|
71
|
+
|
72
|
+
.heading-3 {
|
73
|
+
font-size: 12px;
|
74
|
+
text-align: center;
|
75
|
+
margin-bottom: 15px;
|
76
|
+
color: #888;
|
77
|
+
}
|
78
|
+
</style>
|
79
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<table role="presentation" cellspacing="0" cellpadding="0" border="0" align="center" width="100%">
|
2
|
+
<tr>
|
3
|
+
<td align="center">
|
4
|
+
<div class="content-wrapper">
|
5
|
+
<div class="bar-large"></div>
|
6
|
+
<div class="main-content">
|
7
|
+
<div class="content">
|
8
|
+
<div>
|
9
|
+
<%= image_tag(main_app.rails_blob_url(Spree::StoreLogo.first.attachment), style: "width: 120px; height: 120px;") %>
|
10
|
+
</div>
|
11
|
+
<div class="heading-1">
|
12
|
+
You're invited to join
|
13
|
+
<span class="title-bold">
|
14
|
+
BookMe+
|
15
|
+
</span>
|
16
|
+
Business.
|
17
|
+
</div>
|
18
|
+
<div class="bar-thin"></div>
|
19
|
+
<div class="heading-2">
|
20
|
+
<span class="title-bold"><%= @invite_team.inviter.full_name.presence || @invite_team.inviter.email %></span> has invited you to manage bookings and grow together on the platform. <br>
|
21
|
+
</div>
|
22
|
+
<div style="text-align: center;">
|
23
|
+
<a href="<%= @invite_team.invitation_link %>" class="action-button">
|
24
|
+
Accept Invitation
|
25
|
+
</a>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="heading-3">
|
29
|
+
Use this email <span class="title-bold"><%= @invite_team.email %></span> to log in or <br>create an account on BookMe+ Platform
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<div class="heading-3">
|
33
|
+
This invitation will expire<br>
|
34
|
+
in <%= ((@invite_team.expires_at - Time.current) / 1.hour).round %> hours.
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</td>
|
40
|
+
</tr>
|
41
|
+
</table>
|
42
|
+
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateSpreeCmCommissionerInviteTeam < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :cm_invite_teams, if_not_exists: true do |t|
|
4
|
+
t.string :email, null: false
|
5
|
+
t.string :token, null: false, unique: true, index: true
|
6
|
+
t.references :inviter, null: false, foreign_key: { to_table: :spree_users }, index: true
|
7
|
+
t.references :vendor, null:false, foreign_key: { to_table: :spree_vendors }, index: true
|
8
|
+
t.integer :status, default: 0, null: false
|
9
|
+
t.text :preferences
|
10
|
+
t.datetime :expires_at
|
11
|
+
t.datetime :confirmed_at
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateCmDynamicFields < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :cm_dynamic_fields, if_not_exists: true do |t|
|
4
|
+
t.string :label, null: false
|
5
|
+
t.integer :data_type, null: false
|
6
|
+
t.references :vendor, null: false, foreign_key: { to_table: :spree_vendors }
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateCmGuestDynamicFields < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :cm_guest_dynamic_fields, if_not_exists: true do |t|
|
4
|
+
t.references :guest, null: false, foreign_key: { to_table: :cm_guests }
|
5
|
+
t.references :dynamic_field, null: false, foreign_key: { to_table: :cm_dynamic_fields }
|
6
|
+
t.jsonb :value, default: [], null: false
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateCmDynamicFieldOptions < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :cm_dynamic_field_options, if_not_exists: true do |t|
|
4
|
+
t.references :dynamic_field, null: false, foreign_key: { to_table: :cm_dynamic_fields }
|
5
|
+
t.string :value, null: false
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateCmProductDynamicFields < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
create_table :cm_product_dynamic_fields, if_not_exists: true do |t|
|
4
|
+
t.references :product, null: false, foreign_key: { to_table: :spree_products }
|
5
|
+
t.references :dynamic_field, null: false, foreign_key: { to_table: :cm_dynamic_fields }
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_cm_commissioner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.17.0.pre.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- You
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: spree
|
@@ -839,6 +839,7 @@ files:
|
|
839
839
|
- app/controllers/spree/api/v2/storefront/check_ins_controller.rb
|
840
840
|
- app/controllers/spree/api/v2/storefront/confirm_pin_code_checkers_controller.rb
|
841
841
|
- app/controllers/spree/api/v2/storefront/customer_notifications_controller.rb
|
842
|
+
- app/controllers/spree/api/v2/storefront/dynamic_field_options_controller.rb
|
842
843
|
- app/controllers/spree/api/v2/storefront/events_controller.rb
|
843
844
|
- app/controllers/spree/api/v2/storefront/google_wallet_object_tokens_controller.rb
|
844
845
|
- app/controllers/spree/api/v2/storefront/guest_card_classes_controller.rb
|
@@ -1176,6 +1177,7 @@ files:
|
|
1176
1177
|
- app/mailers/spree_cm_commissioner/crew_invite_mailer.rb
|
1177
1178
|
- app/mailers/spree_cm_commissioner/event_transactional_mailer.rb
|
1178
1179
|
- app/mailers/spree_cm_commissioner/pin_code_mailer.rb
|
1180
|
+
- app/mailers/spree_cm_commissioner/team_invite_mailer.rb
|
1179
1181
|
- app/models/.gitkeep
|
1180
1182
|
- app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb
|
1181
1183
|
- app/models/concerns/spree_cm_commissioner/json_preference_validator.rb
|
@@ -1188,6 +1190,7 @@ files:
|
|
1188
1190
|
- app/models/concerns/spree_cm_commissioner/option_value_attr_type.rb
|
1189
1191
|
- app/models/concerns/spree_cm_commissioner/order_state_machine.rb
|
1190
1192
|
- app/models/concerns/spree_cm_commissioner/parameterize_name.rb
|
1193
|
+
- app/models/concerns/spree_cm_commissioner/participation_type_bitwise.rb
|
1191
1194
|
- app/models/concerns/spree_cm_commissioner/phone_number_sanitizer.rb
|
1192
1195
|
- app/models/concerns/spree_cm_commissioner/product_delegation.rb
|
1193
1196
|
- app/models/concerns/spree_cm_commissioner/product_type.rb
|
@@ -1226,6 +1229,8 @@ files:
|
|
1226
1229
|
- app/models/spree_cm_commissioner/customer_taxon.rb
|
1227
1230
|
- app/models/spree_cm_commissioner/device_token.rb
|
1228
1231
|
- app/models/spree_cm_commissioner/digital_decorator.rb
|
1232
|
+
- app/models/spree_cm_commissioner/dynamic_field.rb
|
1233
|
+
- app/models/spree_cm_commissioner/dynamic_field_option.rb
|
1229
1234
|
- app/models/spree_cm_commissioner/event_ticket_google_wallet.rb
|
1230
1235
|
- app/models/spree_cm_commissioner/export.rb
|
1231
1236
|
- app/models/spree_cm_commissioner/exports/export_guest_csv.rb
|
@@ -1240,6 +1245,7 @@ files:
|
|
1240
1245
|
- app/models/spree_cm_commissioner/guest_card_classes/bib_card_class.rb
|
1241
1246
|
- app/models/spree_cm_commissioner/guest_card_classes/booking_card_background_image.rb
|
1242
1247
|
- app/models/spree_cm_commissioner/guest_card_classes/booking_card_class.rb
|
1248
|
+
- app/models/spree_cm_commissioner/guest_dynamic_field.rb
|
1243
1249
|
- app/models/spree_cm_commissioner/guest_occupation_promotion_rule.rb
|
1244
1250
|
- app/models/spree_cm_commissioner/homepage_background.rb
|
1245
1251
|
- app/models/spree_cm_commissioner/homepage_background_app_image.rb
|
@@ -1259,6 +1265,7 @@ files:
|
|
1259
1265
|
- app/models/spree_cm_commissioner/imports/import_order.rb
|
1260
1266
|
- app/models/spree_cm_commissioner/invite.rb
|
1261
1267
|
- app/models/spree_cm_commissioner/invite_guest.rb
|
1268
|
+
- app/models/spree_cm_commissioner/invite_team.rb
|
1262
1269
|
- app/models/spree_cm_commissioner/invite_user_event.rb
|
1263
1270
|
- app/models/spree_cm_commissioner/invite_user_taxon.rb
|
1264
1271
|
- app/models/spree_cm_commissioner/invoice.rb
|
@@ -1292,6 +1299,7 @@ files:
|
|
1292
1299
|
- app/models/spree_cm_commissioner/product_completion_step.rb
|
1293
1300
|
- app/models/spree_cm_commissioner/product_completion_steps/chatrace_telegram.rb
|
1294
1301
|
- app/models/spree_cm_commissioner/product_decorator.rb
|
1302
|
+
- app/models/spree_cm_commissioner/product_dynamic_field.rb
|
1295
1303
|
- app/models/spree_cm_commissioner/product_google_wallet.rb
|
1296
1304
|
- app/models/spree_cm_commissioner/product_place.rb
|
1297
1305
|
- app/models/spree_cm_commissioner/promotion/actions/create_date_specific_item_adjustments.rb
|
@@ -1649,10 +1657,13 @@ files:
|
|
1649
1657
|
- app/serializers/spree_cm_commissioner/v2/storefront/calculator_serializer.rb
|
1650
1658
|
- app/serializers/spree_cm_commissioner/v2/storefront/category_taxon_serializer.rb
|
1651
1659
|
- app/serializers/spree_cm_commissioner/v2/storefront/check_in_serializer.rb
|
1660
|
+
- app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_option_serializer.rb
|
1661
|
+
- app/serializers/spree_cm_commissioner/v2/storefront/dynamic_field_serializer.rb
|
1652
1662
|
- app/serializers/spree_cm_commissioner/v2/storefront/event_option_value_serializer.rb
|
1653
1663
|
- app/serializers/spree_cm_commissioner/v2/storefront/event_variant_serializer.rb
|
1654
1664
|
- app/serializers/spree_cm_commissioner/v2/storefront/google_wallet_serializer.rb
|
1655
1665
|
- app/serializers/spree_cm_commissioner/v2/storefront/guest_card_class_serializer.rb
|
1666
|
+
- app/serializers/spree_cm_commissioner/v2/storefront/guest_dynamic_field_serializer.rb
|
1656
1667
|
- app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb
|
1657
1668
|
- app/serializers/spree_cm_commissioner/v2/storefront/homepage_background_serializer.rb
|
1658
1669
|
- app/serializers/spree_cm_commissioner/v2/storefront/homepage_banner_serializer.rb
|
@@ -1661,6 +1672,7 @@ files:
|
|
1661
1672
|
- app/serializers/spree_cm_commissioner/v2/storefront/menu_item_serializer_decorator.rb
|
1662
1673
|
- app/serializers/spree_cm_commissioner/v2/storefront/payment_method_group_serializer.rb
|
1663
1674
|
- app/serializers/spree_cm_commissioner/v2/storefront/pin_code_serializer.rb
|
1675
|
+
- app/serializers/spree_cm_commissioner/v2/storefront/product_dynamic_field_serializer.rb
|
1664
1676
|
- app/serializers/spree_cm_commissioner/v2/storefront/product_place_serializer.rb
|
1665
1677
|
- app/serializers/spree_cm_commissioner/v2/storefront/promotion_action_serializer.rb
|
1666
1678
|
- app/serializers/spree_cm_commissioner/v2/storefront/promotion_rule_serializer.rb
|
@@ -2140,6 +2152,7 @@ files:
|
|
2140
2152
|
- app/views/spree_cm_commissioner/layouts/event_transactional_mailer.html.erb
|
2141
2153
|
- app/views/spree_cm_commissioner/layouts/line_item_mailer.html.erb
|
2142
2154
|
- app/views/spree_cm_commissioner/layouts/order_mailer.html.erb
|
2155
|
+
- app/views/spree_cm_commissioner/layouts/team_invite_mailer.html.erb
|
2143
2156
|
- app/views/spree_cm_commissioner/layouts/telegram.html.erb
|
2144
2157
|
- app/views/spree_cm_commissioner/line_item_mailer/_greeting.html.erb
|
2145
2158
|
- app/views/spree_cm_commissioner/line_item_mailer/_mailer_stylesheets.html.erb
|
@@ -2156,6 +2169,8 @@ files:
|
|
2156
2169
|
- app/views/spree_cm_commissioner/order_mailer/purchased_items/_items.html.erb
|
2157
2170
|
- app/views/spree_cm_commissioner/order_mailer/purchased_items/_summary.html.erb
|
2158
2171
|
- app/views/spree_cm_commissioner/pin_code_mailer/send_pin_code.html.erb
|
2172
|
+
- app/views/spree_cm_commissioner/team_invite_mailer/_mailer_stylesheets.html.erb
|
2173
|
+
- app/views/spree_cm_commissioner/team_invite_mailer/send_team_invite_email.html.erb
|
2159
2174
|
- bin/rails
|
2160
2175
|
- config/brakeman.yml
|
2161
2176
|
- config/initializers/assets.rb
|
@@ -2471,6 +2486,7 @@ files:
|
|
2471
2486
|
- db/migrate/20250506092929_add_trip_count_to_cm_vendor_stops.rb
|
2472
2487
|
- db/migrate/20250509033437_create_spree_cm_commissioner_transactional_emails.rb
|
2473
2488
|
- db/migrate/20250509075429_add_max_order_quantity_to_spree_product.rb
|
2489
|
+
- db/migrate/20250512072817_create_spree_cm_commissioner_invite_team.rb
|
2474
2490
|
- db/migrate/20250512075319_add_tenant_id_to_spree_cms_pages.rb
|
2475
2491
|
- db/migrate/20250520042602_add_event_to_spree_products.rb
|
2476
2492
|
- db/migrate/20250520044533_add_event_to_spree_line_items.rb
|
@@ -2483,6 +2499,11 @@ files:
|
|
2483
2499
|
- db/migrate/20250531074036_create_spree_cm_commissioner_option_value_vehicle.rb
|
2484
2500
|
- db/migrate/20250531074258_create_spree_cm_commissioner_vehicle_option_types.rb
|
2485
2501
|
- db/migrate/20250602094751_add_host_to_cm_tenants.rb
|
2502
|
+
- db/migrate/20250605024523_add_participation_type_to_spree_taxon.rb
|
2503
|
+
- db/migrate/20250606020914_create_cm_dynamic_fields.rb
|
2504
|
+
- db/migrate/20250606020958_create_cm_guest_dynamic_fields.rb
|
2505
|
+
- db/migrate/20250606021044_create_cm_dynamic_field_options.rb
|
2506
|
+
- db/migrate/20250606021045_create_cm_product_dynamic_fields.rb
|
2486
2507
|
- db/migrate/20250609015216_remove_claimed_at_and_expires_at_from_cm_invite_guest.rb
|
2487
2508
|
- db/migrate/20250610080108_add_contact_to_cm_guests.rb
|
2488
2509
|
- db/migrate/20250611023548_add_country_code_to_guests.rb
|
@@ -2639,9 +2660,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
2639
2660
|
version: '2.7'
|
2640
2661
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
2641
2662
|
requirements:
|
2642
|
-
- - "
|
2663
|
+
- - ">"
|
2643
2664
|
- !ruby/object:Gem::Version
|
2644
|
-
version:
|
2665
|
+
version: 1.3.1
|
2645
2666
|
requirements:
|
2646
2667
|
- none
|
2647
2668
|
rubygems_version: 3.4.1
|