spree_cm_commissioner 1.8.0.pre.deploy.pre.demo → 1.8.1

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test_and_build_gem.yml +16 -16
  3. data/Gemfile.lock +1 -1
  4. data/app/assets/images/mailer/bookme-plus_light.svg +1 -0
  5. data/app/controllers/spree/api/v2/organizer/invites_controller.rb +35 -0
  6. data/app/controllers/spree/api/v2/tenant/profile_images_controller.rb +52 -0
  7. data/app/controllers/spree/api/v2/tenant/s3_signed_urls_controller.rb +29 -0
  8. data/app/interactors/spree_cm_commissioner/crew_inviter.rb +63 -0
  9. data/app/interactors/spree_cm_commissioner/profile_image_destroyer.rb +16 -0
  10. data/app/mailers/spree_cm_commissioner/crew_invite_mailer.rb +13 -0
  11. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +6 -1
  12. data/app/models/spree_cm_commissioner/crew_invite.rb +7 -0
  13. data/app/models/spree_cm_commissioner/invite.rb +22 -0
  14. data/app/models/spree_cm_commissioner/invite_user_event.rb +5 -0
  15. data/app/models/spree_cm_commissioner/invite_user_taxon.rb +11 -0
  16. data/app/models/spree_cm_commissioner/line_item_decorator.rb +1 -1
  17. data/app/models/spree_cm_commissioner/order_decorator.rb +1 -1
  18. data/app/models/spree_cm_commissioner/place.rb +2 -0
  19. data/app/models/spree_cm_commissioner/product_decorator.rb +4 -0
  20. data/app/models/spree_cm_commissioner/taxon_decorator.rb +4 -0
  21. data/app/models/spree_cm_commissioner/user_decorator.rb +4 -0
  22. data/app/models/spree_cm_commissioner/variant_options.rb +23 -0
  23. data/app/overrides/spree/admin/taxons/edit/title.html.erb.deface +5 -3
  24. data/app/serializers/spree/v2/organizer/asset_serializer.rb +11 -0
  25. data/app/serializers/spree/v2/organizer/invite_serializer.rb +11 -0
  26. data/app/serializers/spree/v2/organizer/taxon_serializer.rb +10 -0
  27. data/app/serializers/spree/v2/organizer/user_serializer.rb +9 -0
  28. data/app/serializers/spree/v2/tenant/s3_signed_url_serializer.rb +9 -0
  29. data/app/serializers/spree/v2/tenant/user_profile_serializer.rb +8 -0
  30. data/app/views/spree/admin/classifications/index.html.erb +1 -1
  31. data/app/views/spree/admin/guest_card_classes/index.html.erb +1 -1
  32. data/app/views/spree/admin/taxon_vendors/index.html.erb +1 -1
  33. data/app/views/spree/admin/user_events/_users.html.erb +1 -1
  34. data/app/views/spree_cm_commissioner/crew_invite_mailer/_mailer_stylesheets.html.erb +82 -0
  35. data/app/views/spree_cm_commissioner/crew_invite_mailer/send_crew_invite_email.html.erb +33 -0
  36. data/app/views/spree_cm_commissioner/layouts/crew_invite_mailer.html.erb +15 -0
  37. data/config/locales/en.yml +8 -1
  38. data/config/locales/km.yml +8 -1
  39. data/config/routes.rb +3 -0
  40. data/db/migrate/20250304101907_create_spree_cm_commissioner_invite.rb +12 -0
  41. data/db/migrate/20250304101946_create_spree_cm_commissioner_invite_user_taxon.rb +11 -0
  42. data/db/migrate/20250307013422_add_parent_id_to_cm_place.rb +9 -0
  43. data/lib/spree_cm_commissioner/test_helper/factories/invite_factory.rb +7 -0
  44. data/lib/spree_cm_commissioner/test_helper/factories/invite_user_event_factory.rb +5 -0
  45. data/lib/spree_cm_commissioner/test_helper/factories/option_type_factory.rb +30 -0
  46. data/lib/spree_cm_commissioner/test_helper/factories/user_event_factory.rb +6 -0
  47. data/lib/spree_cm_commissioner/version.rb +1 -1
  48. metadata +30 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c35795a4846afff06697c40726a7cba898af9f4055b50b213d679a65731c087
4
- data.tar.gz: e3d6368170092b5cf1a572c20c0a5fe9cb062a40f92ca54065206d9b52b60d40
3
+ metadata.gz: '0788ffeb87d1c46c1f4744a776a0fb2cef13d206f43a36eaa9b80c3b0020678a'
4
+ data.tar.gz: f78da29a145dfb3d1f29eb3ec14b766edd4f45832a9ca61ba082e762f008490f
5
5
  SHA512:
6
- metadata.gz: 43a82e2d5a436a577a2f56308b48b69931924d90fc9503ca68965dff10edfcccc11e31afffda9cc3788c3b5a1992b158df486ecd4c00b71c4d88918946b7c157
7
- data.tar.gz: ccd67cabb34cf5ab3f07f9a9b056707065c02ef941e92a4a058ae63383f59c9729e897a84208a138190be469f74d5feebee9f65ce464dda6ef1c6af1c4a0b85b
6
+ metadata.gz: 46a102addf52edcaa69f92f88d4172782edee7f0eb174d7eb9f467a5301177dae472d01cd0492fdcc11f3170717f8e45eff3f4e5d113779dee4cfec31d496d0f
7
+ data.tar.gz: 0f2e3e69f2e93f6a9c04593f24bd8beeeb7609913549dce842263a17ec2653fcb1f236b5a0fe6400fb2b766e068139bf0b7ad2c6d33fd238912baee1c4860f3a
@@ -48,25 +48,25 @@ jobs:
48
48
  gem install bundler
49
49
  bundle install --jobs 4 --retry 3
50
50
 
51
- # - name: Quality
52
- # env:
53
- # DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
54
- # run: |
55
- # bundle exec rubocop
51
+ - name: Quality
52
+ env:
53
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
54
+ run: |
55
+ bundle exec rubocop
56
56
 
57
- # - name: Security
58
- # env:
59
- # DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
60
- # run: |
61
- # bundle exec brakeman
57
+ - name: Security
58
+ env:
59
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
60
+ run: |
61
+ bundle exec brakeman
62
62
 
63
- # - name: Run test
64
- # env:
65
- # DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
63
+ - name: Run test
64
+ env:
65
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
66
66
 
67
- # if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'develop'
68
- # run: |
69
- # bundle exec rake
67
+ if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'develop'
68
+ run: |
69
+ bundle exec rake
70
70
 
71
71
  # 2405-build-and-publish-gem
72
72
  # - name: Rename long migration files
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (1.8.0.pre.deploy.pre.demo)
37
+ spree_cm_commissioner (1.8.1)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="408" height="66" fill="none"><path fill="#010304" d="M63.27 27.02c1.4-1.91 2.3-3.95 2.69-6.05l.82-4.51c.87-4.8-.26-8.67-3.38-11.52C60.33 2.14 55.8.72 49.95.72H17.81l-4.76 26.14-2.16 11.82-3.18 17.43c-.5 2.73 0 4.98 1.45 6.69 1.46 1.7 3.6 2.56 6.38 2.56h25.69c6.22 0 11.53-1.53 15.78-4.55 4.31-3.06 6.96-7.21 7.9-12.36l.86-4.69c.54-2.99.09-5.72-1.34-8.14-1.22-2.04-2.96-3.62-5.21-4.7 1.58-1.08 2.94-2.39 4.05-3.91zM51.78 43.77l-.72 3.97c-.31 1.68-1.14 2.93-2.54 3.84-1.47.95-3.47 1.43-5.93 1.43H22.27l2.61-14.31h21.67c1.9 0 3.34.48 4.28 1.44.92.94 1.23 2.13.96 3.65zm.76-25.96-.56 3.06c-.34 1.85-1.11 3.28-2.38 4.37-1.26 1.09-2.71 1.62-4.43 1.62H27.02l2.51-13.77h17.7c1.92 0 3.37.44 4.33 1.32.92.84 1.24 1.96.98 3.4"/><path fill="#010304" d="M44.91 26.87v11.82H.74l2.18-11.82zM114.17 19.64c-2.73-1.55-6.09-2.34-9.98-2.34h-8.11c-3.89 0-7.53.79-10.83 2.34-3.32 1.56-6.12 3.8-8.33 6.65-2.21 2.84-3.66 6.15-4.33 9.81l-1.92 10.55c-.67 3.67-.43 6.96.72 9.77 1.15 2.82 3.13 5.03 5.88 6.56 2.73 1.52 6.09 2.29 9.98 2.29h8.11c3.95 0 7.62-.77 10.91-2.29 3.31-1.53 6.11-3.74 8.31-6.56 2.2-2.81 3.66-6.1 4.33-9.77l1.92-10.55c.67-3.67.42-6.97-.75-9.81-1.17-2.85-3.16-5.08-5.91-6.65M89.63 53.17c-1.89 0-3.25-.66-4.18-2.03-.95-1.4-1.21-3.19-.79-5.49l1.59-8.74c.41-2.26 1.35-4.11 2.8-5.49 1.42-1.37 3.06-2.03 5.01-2.03h7.75c1.94 0 3.34.66 4.27 2.03.94 1.38 1.21 3.23.79 5.49l-1.59 8.74c-.41 2.26-1.35 4.11-2.79 5.49-1.43 1.37-3.1 2.03-5.1 2.03h-7.76M167.9 19.64c-2.73-1.55-6.09-2.34-9.98-2.34h-8.11c-3.89 0-7.54.79-10.83 2.34-3.32 1.56-6.12 3.8-8.33 6.65-2.21 2.84-3.66 6.15-4.33 9.81l-1.92 10.55c-.67 3.67-.43 6.95.72 9.77s3.13 5.03 5.88 6.56c2.73 1.52 6.09 2.29 9.98 2.29h8.11c3.95 0 7.62-.77 10.91-2.29 3.31-1.53 6.11-3.74 8.31-6.56 2.2-2.81 3.66-6.1 4.33-9.77l1.92-10.55c.67-3.67.42-6.97-.75-9.81-1.17-2.85-3.16-5.08-5.91-6.65m-29.51 26.02 1.59-8.74c.41-2.26 1.35-4.11 2.8-5.49 1.43-1.37 3.06-2.03 5.01-2.03h7.75c1.95 0 3.34.66 4.27 2.03.94 1.38 1.21 3.23.79 5.49l-1.59 8.74c-.41 2.26-1.35 4.11-2.8 5.49-1.43 1.37-3.09 2.03-5.1 2.03h-7.75c-1.88 0-3.25-.66-4.18-2.03-.95-1.4-1.21-3.19-.79-5.49M230.08 18.75h-16.44l-19.73 16.82L200.28.63h-13.81l-11.78 64.64h13.81l2.5-13.7 4.64-3.93 10.54 17.63h15.84L206.31 38.7zM265.04 36.88 251.68.63h-12.31l-11.78 64.64h13.72l6.87-37.7 7.91 21.35c.34.92.73 1.73 1.17 2.39l.04.06c.34.52.7.95 1.08 1.28.92.78 2.08 1.18 3.45 1.18h.27c1.37 0 2.68-.4 3.88-1.18.52-.34 1.04-.77 1.52-1.25.68-.65 1.39-1.48 2.12-2.46l15.68-21.35-6.87 37.69h13.72L303.93.64h-12.32l-26.56 36.25zM347.2 22.38c-3-3.37-7.54-5.08-13.48-5.08h-7.21c-3.89 0-7.53.79-10.83 2.34-3.32 1.56-6.12 3.78-8.32 6.6-2.2 2.81-3.66 6.1-4.33 9.77l-2.12 11.63c-.63 3.44-.33 6.54.88 9.2 1.21 2.67 3.22 4.77 5.99 6.23 2.74 1.46 6.1 2.2 9.99 2.2h6.85c3.87 0 7.48-.66 10.71-1.95 3.28-1.32 6.03-3.23 8.17-5.68 1.86-2.12 3.14-4.53 3.83-7.18h-13.8c-.37.67-.94 1.24-1.71 1.74-1.3.83-2.94 1.25-4.87 1.25h-7.03c-1.98 0-3.39-.52-4.31-1.59-.92-1.06-1.21-2.44-.89-4.21l.25-1.39h33.35l1.88-10.33c1.02-5.61 0-10.16-3.01-13.55zm-10.61 13.49H316.7c.45-2.03 1.35-3.68 2.68-4.94 1.42-1.34 3.06-1.99 5.01-1.99h7.3c1.89 0 3.24.61 4.13 1.86.9 1.27 1.15 2.92.77 5.06z"/><path fill="#6444D8" d="m372.06 63.5 8.12-44.57h13.06l-8.12 44.57z"/><path fill="#6444D8" d="M405.25 47.52h-47l2.44-13.22h46.99z"/></svg>
@@ -0,0 +1,35 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Organizer
5
+ class InvitesController < ::Spree::Api::V2::Organizer::BaseController
6
+ def show
7
+ if invite&.url_valid?
8
+ render_serialized_payload { serialize_resource(invite) }
9
+ else
10
+ render_error_payload(I18n.t('invite.url_not_found'))
11
+ end
12
+ end
13
+
14
+ def update
15
+ context = invite.confirm(params[:user_id])
16
+
17
+ if context.success?
18
+ render_serialized_payload { serialize_resource(context.invite) }
19
+ else
20
+ render_error_payload(context.message || I18n.t('invite.accept_fail'))
21
+ end
22
+ end
23
+
24
+ def invite
25
+ @invite ||= SpreeCmCommissioner::Invite.find_by!(token: params[:id])
26
+ end
27
+
28
+ def resource_serializer
29
+ ::Spree::V2::Organizer::InviteSerializer
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,52 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class ProfileImagesController < BaseController
6
+ before_action :require_spree_current_user
7
+ before_action :required_schema_validation!, except: [:destroy]
8
+
9
+ def update
10
+ context = SpreeCmCommissioner::ProfileImageUpdater.call(
11
+ user: spree_current_user,
12
+ url: schema.output.fetch(:url)
13
+ )
14
+ if context.success?
15
+ render_serialized_payload { serialize_resource(context.result) }
16
+ else
17
+ render_error_payload(context.message)
18
+ end
19
+ end
20
+
21
+ def destroy
22
+ context = SpreeCmCommissioner::ProfileImageDestroyer.call(
23
+ user: spree_current_user
24
+ )
25
+ if context.success?
26
+ render_serialized_payload(204) { serialize_resource(context.result) }
27
+ else
28
+ render_error_payload(context.message)
29
+ end
30
+ end
31
+
32
+ def required_schema_validation!
33
+ return true if required_schema.nil?
34
+
35
+ @schema = required_schema.new(request: request, locale: locale, user: spree_current_user)
36
+ return true if schema.success?
37
+
38
+ raise SchemaValidationError, schema.error_message
39
+ end
40
+
41
+ def required_schema
42
+ SpreeCmCommissioner::ProfileImageRequestSchema
43
+ end
44
+
45
+ def resource_serializer
46
+ Spree::V2::Tenant::UserProfileSerializer
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,29 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class S3SignedUrlsController < BaseController
6
+ def show
7
+ if resource.error_message.blank?
8
+ render_serialized_payload { serialize_resource(resource) }
9
+ else
10
+ render_error_payload(resource.error_message)
11
+ end
12
+ end
13
+
14
+ def resource
15
+ SpreeCmCommissioner::S3PresignedUrlBuilder.call(
16
+ bucket_name: params[:bucket_name],
17
+ object_key: params[:object_key],
18
+ file_name: params[:file_name]
19
+ )
20
+ end
21
+
22
+ def resource_serializer
23
+ Spree::V2::Tenant::S3SignedUrlSerializer
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ module SpreeCmCommissioner
2
+ class CrewInviter < BaseInteractor
3
+ delegate :id, :invitee_id, to: :context
4
+
5
+ def call
6
+ validate_data
7
+ assign_role_to_user
8
+ create_user_event
9
+ update_invite_user_event
10
+ context.invite = crew_invite
11
+ end
12
+
13
+ private
14
+
15
+ def validate_data
16
+ if invite_user_event.nil?
17
+ context.fail!(message: I18n.t('invite.url_not_found'))
18
+ elsif !invite_user_event.invite.url_valid?
19
+ context.fail!(message: I18n.t('invite.url_expired'))
20
+ end
21
+ end
22
+
23
+ def assign_role_to_user
24
+ return if user.operator?
25
+
26
+ role = Spree::Role.find_by(name: 'operator')
27
+ role_user = Spree::RoleUser.new(user_id: user.id, role_id: role.id)
28
+ role_user.save
29
+ end
30
+
31
+ def create_user_event
32
+ @user_event = SpreeCmCommissioner::UserEvent.new(
33
+ taxon_id: crew_invite.taxon_id,
34
+ user_id: user.id
35
+ )
36
+
37
+ return if @user_event.save
38
+
39
+ context.fail!(message: I18n.t('invite.already_invited'))
40
+ end
41
+
42
+ def update_invite_user_event
43
+ invite_user_event.user_taxon_id = @user_event.id
44
+ invite_user_event.confirmed_at = Time.current
45
+
46
+ return if @invite_user_event.save
47
+
48
+ context.fail!(message: I18n.t('invite.update_fail'))
49
+ end
50
+
51
+ def crew_invite
52
+ @crew_invite ||= SpreeCmCommissioner::CrewInvite.find(id)
53
+ end
54
+
55
+ def invite_user_event
56
+ @invite_user_event ||= crew_invite.invite_user_events.find_by(email: user.email, confirmed_at: nil)
57
+ end
58
+
59
+ def user
60
+ @user ||= Spree::User.find(invitee_id)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,16 @@
1
+ module SpreeCmCommissioner
2
+ class ProfileImageDestroyer < BaseInteractor
3
+ delegate :user, to: :context
4
+
5
+ def call
6
+ profile_image = SpreeCmCommissioner::UserProfile.find_by(viewable: user)
7
+
8
+ if profile_image
9
+ profile_image.destroy
10
+ context.result = profile_image
11
+ else
12
+ context.fail!(message: 'No profile image to delete')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ module SpreeCmCommissioner
2
+ class CrewInviteMailer < Spree::BaseMailer
3
+ layout 'spree_cm_commissioner/layouts/crew_invite_mailer'
4
+
5
+ def send_crew_invite_email(invite_user_event_id)
6
+ @invite_user_event = SpreeCmCommissioner::InviteUserEvent.find(invite_user_event_id)
7
+
8
+ subject = Spree::Store.default.name.to_s
9
+
10
+ mail(from: from_address, to: @invite_user_event.email, subject: subject)
11
+ end
12
+ end
13
+ end
@@ -46,7 +46,12 @@ module SpreeCmCommissioner
46
46
  'bib-zerofill' => 'integer',
47
47
  'bib-display-prefix' => 'boolean',
48
48
  'bib-pre-generation-on-create' => 'boolean',
49
- 'seat-number-positions' => 'array'
49
+ 'seat-number-positions' => 'array',
50
+ 'origin' => 'origin',
51
+ 'destination' => 'destination',
52
+ 'departure-time' => 'time',
53
+ 'vehicle' => 'vehicle_id',
54
+ 'allow-seat-selection' => 'boolean'
50
55
  }.freeze
51
56
 
52
57
  included do
@@ -0,0 +1,7 @@
1
+ module SpreeCmCommissioner
2
+ class CrewInvite < Invite
3
+ def confirm(invitee_id)
4
+ SpreeCmCommissioner::CrewInviter.call(id: id, invitee_id: invitee_id)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ module SpreeCmCommissioner
2
+ class Invite < SpreeCmCommissioner::Base
3
+ belongs_to :taxon, class_name: 'Spree::Taxon'
4
+ belongs_to :inviter, class_name: 'Spree::User'
5
+ has_many :invite_user_events, class_name: 'SpreeCmCommissioner::InviteUserEvent', dependent: :destroy
6
+ scope :active, -> { where('expires_at > ?', Time.current) }
7
+
8
+ after_create :set_expiration
9
+
10
+ def set_expiration
11
+ update(expires_at: 3.days.from_now)
12
+ end
13
+
14
+ def invite_url
15
+ "#{Spree::Store.default.formatted_url}/invite/#{token}?utm_source=email"
16
+ end
17
+
18
+ def url_valid?
19
+ expires_at.present? && expires_at > Time.current
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module SpreeCmCommissioner
2
+ class InviteUserEvent < InviteUserTaxon
3
+ alias_attribute :user_event, :user_taxon
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeCmCommissioner
2
+ class InviteUserTaxon < SpreeCmCommissioner::Base
3
+ belongs_to :user_taxon, class_name: 'SpreeCmCommissioner::UserTaxon'
4
+ belongs_to :invite, class_name: 'SpreeCmCommissioner::Invite'
5
+ after_create :send_crew_invite_email
6
+
7
+ def send_crew_invite_email
8
+ SpreeCmCommissioner::CrewInviteMailer.send_crew_invite_email(id).deliver_later
9
+ end
10
+ end
11
+ end
@@ -24,7 +24,7 @@ module SpreeCmCommissioner
24
24
 
25
25
  base.validate :ensure_not_exceed_max_quantity_per_order, if: -> { variant&.max_quantity_per_order.present? }
26
26
 
27
- base.whitelisted_ransackable_associations |= %w[guests]
27
+ base.whitelisted_ransackable_associations |= %w[guests order]
28
28
  base.whitelisted_ransackable_attributes |= %w[number to_date from_date vendor_id]
29
29
 
30
30
  base.delegate :delivery_required?, :permanent_stock?, :high_demand, :transit?,
@@ -42,7 +42,7 @@ module SpreeCmCommissioner
42
42
  base.delegate :customer, to: :user, allow_nil: true
43
43
 
44
44
  base.whitelisted_ransackable_associations |= %w[customer taxon payments invoice]
45
- base.whitelisted_ransackable_attributes |= %w[intel_phone_number phone_number email number]
45
+ base.whitelisted_ransackable_attributes |= %w[intel_phone_number phone_number email number state]
46
46
 
47
47
  def base.search_by_qr_data!(data)
48
48
  token = data.match(/^R\d{9,}-([A-Za-z0-9_\-]+)$/)&.captures
@@ -13,6 +13,8 @@ module SpreeCmCommissioner
13
13
 
14
14
  has_many :product_places, class_name: 'SpreeCmCommissioner::ProductPlace', dependent: :destroy
15
15
  has_many :products, through: :product_places
16
+ has_many :children, class_name: 'SpreeCmCommissioner::Place', foreign_key: :parent_id, dependent: :destroy
17
+ belongs_to :parent, class_name: 'SpreeCmCommissioner::Place', optional: true
16
18
 
17
19
  def self.ransackable_attributes(auth_object = nil)
18
20
  super & %w[name code]
@@ -75,6 +75,10 @@ module SpreeCmCommissioner
75
75
  taxons.event.first&.parent
76
76
  end
77
77
 
78
+ def ticket_url
79
+ "#{Spree::Store.default.formatted_url}/tickets/#{slug}"
80
+ end
81
+
78
82
  private
79
83
 
80
84
  def set_tenant
@@ -48,6 +48,10 @@ module SpreeCmCommissioner
48
48
  base.whitelisted_ransackable_attributes |= %w[kind]
49
49
 
50
50
  base.enum purchasable_on: { both: 0, web: 1, app: 2 }
51
+ base.has_many :crew_invites, class_name: 'SpreeCmCommissioner::CrewInvite', dependent: :destroy
52
+ base.has_many :invite_user_events, through: :user_events, class_name: 'SpreeCmCommissioner::InviteUserEvent'
53
+
54
+ base.has_many :line_items, through: :products
51
55
  end
52
56
  # rubocop:enable Metrics/MethodLength
53
57
 
@@ -67,6 +67,10 @@ module SpreeCmCommissioner
67
67
  has_spree_role?('organizer')
68
68
  end
69
69
 
70
+ def operator?
71
+ has_spree_role?('operator')
72
+ end
73
+
70
74
  def full_name
71
75
  [first_name, last_name].compact_blank.join(' ')
72
76
  end
@@ -143,5 +143,28 @@ module SpreeCmCommissioner
143
143
  def number_of_guests
144
144
  number_of_adults + number_of_kids
145
145
  end
146
+
147
+ def origin
148
+ @origin ||= option_value_name_for(option_type_name: 'origin')&.to_i
149
+ end
150
+
151
+ def destination
152
+ @destination ||= option_value_name_for(option_type_name: 'destination')&.to_i
153
+ end
154
+
155
+ def vehicle
156
+ @vehicle ||= option_value_name_for(option_type_name: 'vehicle')&.to_i
157
+ end
158
+
159
+ def allow_seat_selection
160
+ @allow_seat_selection ||= option_value_name_for(option_type_name: 'allow-seat-selection')&.to_i
161
+ end
162
+
163
+ def departure_time
164
+ @departure_time ||= begin
165
+ time = option_value_name_for(option_type_name: 'departure-time')
166
+ Time.zone.parse(time) if time.present?
167
+ end
168
+ end
146
169
  end
147
170
  end
@@ -1,6 +1,8 @@
1
1
  <!-- replace "erb[silent]:contains('unless @taxon.root?')" closing_selector "erb[silent]:contains('end')" -->
2
2
 
3
- <%if @taxon.depth !=1 %>
4
- / <%= link_to @taxon.parent.name, spree.edit_admin_taxonomy_taxon_url(@taxonomy,@taxon.parent.id) %>
3
+ <%if @taxon.depth !=1 && @taxon.parent.present? %>
4
+ / <%= link_to @taxon.parent.name, spree.edit_admin_taxonomy_taxon_url(@taxonomy,@taxon.parent.id) %>
5
5
  <%end%>
6
- / <%= @taxon.name %>
6
+ <% unless @taxon.root? %>
7
+ / <%= @taxon.name %>
8
+ <% end %>
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Organizer
4
+ class AssetSerializer < BaseSerializer
5
+ include ::Spree::Api::V2::ImageTransformationConcern
6
+
7
+ attributes :alt, :original_url, :position, :styles
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Organizer
4
+ class InviteSerializer < BaseSerializer
5
+ attributes :token, :expires_at
6
+ belongs_to :taxon, serializer: Spree::V2::Organizer::TaxonSerializer
7
+ belongs_to :inviter, serializer: Spree::V2::Organizer::UserSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module Spree
2
+ module V2
3
+ module Organizer
4
+ class TaxonSerializer < BaseSerializer
5
+ attributes :name
6
+ has_one :app_banner, serializer: Spree::V2::Organizer::AssetSerializer
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Spree
2
+ module V2
3
+ module Organizer
4
+ class UserSerializer < BaseSerializer
5
+ attributes :first_name, :last_name, :email
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class S3SignedUrlSerializer < BaseSerializer
5
+ attribute :host, :fields, :url
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class UserProfileSerializer < Spree::V2::Tenant::AssetSerializer
5
+ end
6
+ end
7
+ end
8
+ end
@@ -2,7 +2,7 @@
2
2
  <%= link_to Spree.t(:taxonomies), spree.admin_taxonomies_url %> /
3
3
 
4
4
  <%= link_to @taxonomy.root.name, spree.edit_admin_taxonomy_url(@taxonomy) %>
5
- <%if @taxon.depth !=1 %>
5
+ <%if @taxon.depth !=1 && @taxon.parent.present? %>
6
6
  / <%= link_to @taxon.parent.name, spree.edit_admin_taxonomy_taxon_url(@taxonomy,@taxon.parent.id) %>
7
7
  <%end%>
8
8
  <% unless @taxon.root? %>
@@ -2,7 +2,7 @@
2
2
  <%= link_to Spree.t(:taxonomies), spree.admin_taxonomies_url %> /
3
3
 
4
4
  <%= link_to @taxonomy.root.name, spree.edit_admin_taxonomy_url(@taxonomy) %>
5
- <%if @taxon.depth !=1 %>
5
+ <%if @taxon.depth !=1 && @taxon.parent.present? %>
6
6
  / <%= link_to @taxon.parent.name, spree.edit_admin_taxonomy_taxon_url(@taxonomy,@taxon.parent.id) %>
7
7
  <%end%>
8
8
  <% unless @taxon.root? %>
@@ -2,7 +2,7 @@
2
2
  <%= link_to Spree.t(:taxonomies), spree.admin_taxonomies_url %> /
3
3
 
4
4
  <%= link_to @taxonomy.root.name, spree.edit_admin_taxonomy_url(@taxonomy) %>
5
- <%if @taxon.depth !=1 %>
5
+ <%if @taxon.depth !=1 && @taxon.parent.present? %>
6
6
  / <%= link_to @taxon.parent.name, spree.edit_admin_taxonomy_taxon_url(@taxonomy,@taxon.parent.id) %>
7
7
  <%end%>
8
8
  <% unless @taxon.root? %>
@@ -2,7 +2,7 @@
2
2
  <%= link_to Spree.t(:taxonomies), spree.admin_taxonomies_url %> /
3
3
 
4
4
  <%= link_to @taxonomy.root.name, spree.edit_admin_taxonomy_url(@taxonomy) %>
5
- <%if @taxon.depth !=1 %>
5
+ <%if @taxon.depth !=1 && @taxon.parent.present? %>
6
6
  / <%= link_to @taxon.parent.name, spree.edit_admin_taxonomy_taxon_url(@taxonomy,@taxon.parent.id) %>
7
7
  <%end%>
8
8
  <% unless @taxon.root? %>
@@ -0,0 +1,82 @@
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
+ .logo {
21
+ display: block;
22
+ width: 150px;
23
+ margin-top: 10px;
24
+ margin-bottom: 20px;
25
+ }
26
+
27
+ .heading-1 {
28
+ font-size: 24px;
29
+ text-align: center;
30
+ line-height: 1.4;
31
+ margin-bottom: 15px;
32
+ }
33
+
34
+ .bar-large {
35
+ height: 10px;
36
+ background-color: #5D54D9;
37
+ margin-bottom: 20px;
38
+
39
+ }
40
+
41
+ .bar-thin {
42
+ height: 3px;
43
+ height: 1px;
44
+ background-color: grey;
45
+ width: 100%;
46
+ margin: 20px auto;
47
+ }
48
+
49
+ .heading-2 {
50
+ font-size: 16px;
51
+ text-align: center;
52
+ line-height: 1.5;
53
+ }
54
+
55
+ .title-bold {
56
+ font-weight: bold;
57
+ color: #000;
58
+ }
59
+
60
+ .action-button {
61
+ display: inline-block;
62
+ background-color: #5D54D9;
63
+ border-radius: 24px;
64
+ font-size: 14px;
65
+ width: 222px;
66
+ height: 50px;
67
+ text-align: center;
68
+ line-height: 50px;
69
+ text-decoration: none;
70
+ cursor: pointer;
71
+ margin: 15px 0;
72
+ color: white !important;
73
+ text-decoration: none;
74
+ }
75
+
76
+ .heading-3 {
77
+ font-size: 12px;
78
+ text-align: center;
79
+ color: #888;
80
+ }
81
+ </style>
82
+
@@ -0,0 +1,33 @@
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><%= image_tag "mailer/bookme-plus_light.svg", class: "logo" %></div>
9
+ <div class="heading-1">
10
+ Become a part of the <br> event <strong> <%= @invite_user_event.invite.taxon.name %> </strong>
11
+ </div>
12
+ <div class="bar-thin"></div>
13
+ <div class="heading-2">
14
+ <%= @invite_user_event.invite.inviter.full_name.presence || @invite_user_event.inviter.email %> invites you to join the <br>
15
+ <span class="title-bold">Check-in Crew</span> for the event <br>
16
+ <%= @invite_user_event.invite.taxon.name %>
17
+ </div>
18
+ <div style="text-align: center;">
19
+ <a href="<%= @invite_user_event.invite.invite_url %>" class="action-button">
20
+ Get Started
21
+ </a>
22
+ </div>
23
+ <div class="heading-3">
24
+ Please note that this invitation will expire<br>
25
+ in <%= ((@invite_user_event.invite.expires_at - Time.current) / 1.hour).round %> hours.
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </td>
31
+ </tr>
32
+ </table>
33
+
@@ -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/crew_invite_mailer/mailer_stylesheets' %>
11
+ </head>
12
+ <body>
13
+ <%= yield %>
14
+ </body>
15
+ </html>
@@ -564,4 +564,11 @@ en:
564
564
  update_success: Option Type updated successfully.
565
565
  user_roles_assigner:
566
566
  user_not_found: 'User not found'
567
- roles_empty: 'Roles are empty'
567
+ roles_empty: 'Roles are empty'
568
+ invite:
569
+ url_not_found: 'Invite link not found or have been expired'
570
+ accept_fail: 'Failed to accept invite'
571
+ url_expired: 'Invitation link is expired'
572
+ already_invited: 'Failed: User already invited to event'
573
+ update_fail: 'Failed: to Update invite user'
574
+
@@ -408,4 +408,11 @@ km:
408
408
  not_found: 'រកមិនឃើញរូបភាព'
409
409
  user_roles_assigner:
410
410
  user_not_found: 'រកមិនឃើញអ្នកប្រើប្រាស់'
411
- roles_empty: 'តួនាទីគឺទទេ'
411
+ roles_empty: 'តួនាទីគឺទទេ'
412
+
413
+ invite:
414
+ url_not_found: 'រកមិនឃើញតំណអញ្ជើញ ឬផុតកំណត់ហើយ'
415
+ accept_fail: 'បរាជ័យក្នុងការទទួលយកការអញ្ជើញ'
416
+ url_expired: 'តំណ​អញ្ជើញ​បាន​ផុត​កំណត់'
417
+ already_invited: 'បរាជ័យ៖ អ្នកប្រើប្រាស់បានអញ្ជើញចូលរួមព្រឹត្តិការណ៍រួចហើយ'
418
+ update_fail: 'បរាជ័យ៖ ធ្វើបច្ចុប្បន្នភាពអ្នកប្រើប្រាស់អញ្ជើញ'
data/config/routes.rb CHANGED
@@ -441,6 +441,7 @@ Spree::Core::Engine.add_routes do
441
441
  end
442
442
  resources :images
443
443
  resource :s3_signed_urls
444
+ resources :invites
444
445
  end
445
446
 
446
447
  namespace :tenant do
@@ -480,6 +481,8 @@ Spree::Core::Engine.add_routes do
480
481
  end
481
482
 
482
483
  resources :user_account_linkages, only: %i[index create destroy]
484
+ resource :s3_signed_urls
485
+ resource :profile_images, only: %i[update destroy]
483
486
  end
484
487
 
485
488
  namespace :storefront do
@@ -0,0 +1,12 @@
1
+ class CreateSpreeCmCommissionerInvite < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cm_invites, if_not_exists: true do |t|
4
+ t.string :token, null: false, unique: true
5
+ t.datetime :expires_at
6
+ t.string :type
7
+ t.references :inviter, null: false, foreign_key: { to_table: :spree_users }, index: true
8
+ t.references :taxon, null: false, foreign_key: { to_table: :spree_taxons }, index: true
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSpreeCmCommissionerInviteUserTaxon < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :cm_invite_user_taxons, if_not_exists: true do |t|
4
+ t.references :invite, foreign_key: { to_table: :cm_invites }, null: true, index: true
5
+ t.references :user_taxon, foreign_key: { to_table: :cm_user_taxons }, null: true, index: true
6
+ t.string :email, index: true
7
+ t.datetime :confirmed_at
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class AddParentIdToCmPlace < ActiveRecord::Migration[7.0]
2
+ def change
3
+ unless column_exists?(:cm_places, :parent_id)
4
+ add_column :cm_places, :parent_id, :integer, null: true
5
+ add_foreign_key :cm_places, :cm_places, column: :parent_id
6
+ add_index :cm_places, :parent_id
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :invite, class: SpreeCmCommissioner::Invite do
3
+ token { SecureRandom.hex(16) }
4
+ taxon { create(:taxon) }
5
+ inviter { create(:user) }
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :invite_user_event, class: SpreeCmCommissioner::InviteUserEvent do
3
+ invite { create(:invite) }
4
+ end
5
+ end
@@ -147,6 +147,36 @@ FactoryBot.define do
147
147
  presentation { 'seat-number-positions' }
148
148
  end
149
149
 
150
+ trait :origin do
151
+ attr_type { :origin }
152
+ name { 'origin' }
153
+ presentation { 'origin' }
154
+ end
155
+
156
+ trait :destination do
157
+ attr_type { :destination }
158
+ name { 'destination' }
159
+ presentation { 'destination' }
160
+ end
161
+
162
+ trait :departure_time do
163
+ attr_type { :time }
164
+ name { 'departure-time' }
165
+ presentation { 'departure-time' }
166
+ end
167
+
168
+ trait :vehicle do
169
+ attr_type { :vehicle_id }
170
+ name { 'vehicle' }
171
+ presentation { 'vehicle' }
172
+ end
173
+
174
+ trait :allow_seat_selection do
175
+ attr_type { :boolean }
176
+ name { 'allow-seat-selection' }
177
+ presentation { 'allow-seat-selection' }
178
+ end
179
+
150
180
  initialize_with { Spree::OptionType.where(name: name).first_or_initialize }
151
181
  end
152
182
  end
@@ -0,0 +1,6 @@
1
+ FactoryBot.define do
2
+ factory :user_event, class: SpreeCmCommissioner::UserEvent do
3
+ taxon { create(:taxon) }
4
+ user { create(:user) }
5
+ end
6
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '1.8.0-deploy-demo'.freeze
2
+ VERSION = '1.8.1'.freeze
3
3
 
4
4
  module_function
5
5
 
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.8.0.pre.deploy.pre.demo
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-06 00:00:00.000000000 Z
11
+ date: 2025-03-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: spree
@@ -578,6 +578,7 @@ files:
578
578
  - app/assets/images/cm-wifi-icon.svg
579
579
  - app/assets/images/mailer/bed.png
580
580
  - app/assets/images/mailer/bookme-plus.png
581
+ - app/assets/images/mailer/bookme-plus_light.svg
581
582
  - app/assets/images/mailer/calendar.png
582
583
  - app/assets/images/mailer/envelope.png
583
584
  - app/assets/images/mailer/event-mailer-bg.png
@@ -743,6 +744,7 @@ files:
743
744
  - app/controllers/spree/api/v2/operator/taxons_controller.rb
744
745
  - app/controllers/spree/api/v2/organizer/base_controller.rb
745
746
  - app/controllers/spree/api/v2/organizer/images_controller.rb
747
+ - app/controllers/spree/api/v2/organizer/invites_controller.rb
746
748
  - app/controllers/spree/api/v2/organizer/s3_signed_urls_controller.rb
747
749
  - app/controllers/spree/api/v2/organizer/ticket_images_controller.rb
748
750
  - app/controllers/spree/api/v2/organizer/tickets_controller.rb
@@ -822,6 +824,8 @@ files:
822
824
  - app/controllers/spree/api/v2/tenant/pin_code_checkers_controller.rb
823
825
  - app/controllers/spree/api/v2/tenant/pin_code_generators_controller.rb
824
826
  - app/controllers/spree/api/v2/tenant/products_controller.rb
827
+ - app/controllers/spree/api/v2/tenant/profile_images_controller.rb
828
+ - app/controllers/spree/api/v2/tenant/s3_signed_urls_controller.rb
825
829
  - app/controllers/spree/api/v2/tenant/taxons_controller.rb
826
830
  - app/controllers/spree/api/v2/tenant/user_account_linkages_controller.rb
827
831
  - app/controllers/spree/api/v2/tenant/user_device_tokens_controller.rb
@@ -940,6 +944,7 @@ files:
940
944
  - app/interactors/spree_cm_commissioner/check_in_destroyer.rb
941
945
  - app/interactors/spree_cm_commissioner/confirm_pin_code_checker.rb
942
946
  - app/interactors/spree_cm_commissioner/conversion_pre_calculator.rb
947
+ - app/interactors/spree_cm_commissioner/crew_inviter.rb
943
948
  - app/interactors/spree_cm_commissioner/customer_content_notification_creator.rb
944
949
  - app/interactors/spree_cm_commissioner/customer_notification_cron_executor.rb
945
950
  - app/interactors/spree_cm_commissioner/customer_notification_sender.rb
@@ -980,6 +985,7 @@ files:
980
985
  - app/interactors/spree_cm_commissioner/pin_code_creator.rb
981
986
  - app/interactors/spree_cm_commissioner/pin_code_generator.rb
982
987
  - app/interactors/spree_cm_commissioner/pin_code_sender.rb
988
+ - app/interactors/spree_cm_commissioner/profile_image_destroyer.rb
983
989
  - app/interactors/spree_cm_commissioner/profile_image_updater.rb
984
990
  - app/interactors/spree_cm_commissioner/recaptcha_token_validator.rb
985
991
  - app/interactors/spree_cm_commissioner/sms.rb
@@ -1053,6 +1059,7 @@ files:
1053
1059
  - app/jobs/spree_cm_commissioner/webhook_subscriber_orders_sender_job.rb
1054
1060
  - app/mailers/spree/order_mailer_decorator.rb
1055
1061
  - app/mailers/spree_cm_commissioner/application_mailer.rb
1062
+ - app/mailers/spree_cm_commissioner/crew_invite_mailer.rb
1056
1063
  - app/mailers/spree_cm_commissioner/pin_code_mailer.rb
1057
1064
  - app/models/.gitkeep
1058
1065
  - app/models/concerns/spree_cm_commissioner/homepage_section_bitwise.rb
@@ -1094,6 +1101,7 @@ files:
1094
1101
  - app/models/spree_cm_commissioner/check_in_record.rb
1095
1102
  - app/models/spree_cm_commissioner/classification_decorator.rb
1096
1103
  - app/models/spree_cm_commissioner/configuration.rb
1104
+ - app/models/spree_cm_commissioner/crew_invite.rb
1097
1105
  - app/models/spree_cm_commissioner/customer.rb
1098
1106
  - app/models/spree_cm_commissioner/customer_notification.rb
1099
1107
  - app/models/spree_cm_commissioner/customer_promotion_rule.rb
@@ -1131,6 +1139,9 @@ files:
1131
1139
  - app/models/spree_cm_commissioner/image_methods_decorator.rb
1132
1140
  - app/models/spree_cm_commissioner/import.rb
1133
1141
  - app/models/spree_cm_commissioner/imports/import_order.rb
1142
+ - app/models/spree_cm_commissioner/invite.rb
1143
+ - app/models/spree_cm_commissioner/invite_user_event.rb
1144
+ - app/models/spree_cm_commissioner/invite_user_taxon.rb
1134
1145
  - app/models/spree_cm_commissioner/invoice.rb
1135
1146
  - app/models/spree_cm_commissioner/line_item_decorator.rb
1136
1147
  - app/models/spree_cm_commissioner/line_item_seat.rb
@@ -1392,10 +1403,14 @@ files:
1392
1403
  - app/serializers/.gitkeep
1393
1404
  - app/serializers/concerns/spree_cm_commissioner/api/v2/resource_serializer_concern_decorator.rb
1394
1405
  - app/serializers/spree/api/v2/platform/create_date_specific_item_adjustment_serializer.rb
1406
+ - app/serializers/spree/v2/organizer/asset_serializer.rb
1395
1407
  - app/serializers/spree/v2/organizer/base_serializer.rb
1396
1408
  - app/serializers/spree/v2/organizer/image_serializer.rb
1409
+ - app/serializers/spree/v2/organizer/invite_serializer.rb
1397
1410
  - app/serializers/spree/v2/organizer/s3_signed_url_serializer.rb
1411
+ - app/serializers/spree/v2/organizer/taxon_serializer.rb
1398
1412
  - app/serializers/spree/v2/organizer/ticket_serializer.rb
1413
+ - app/serializers/spree/v2/organizer/user_serializer.rb
1399
1414
  - app/serializers/spree/v2/storefront/accommodation_serializer.rb
1400
1415
  - app/serializers/spree/v2/storefront/address_serializer_decorator.rb
1401
1416
  - app/serializers/spree/v2/storefront/cart_serializer_decorator.rb
@@ -1431,10 +1446,12 @@ files:
1431
1446
  - app/serializers/spree/v2/tenant/homepage_section_relatable_serializer.rb
1432
1447
  - app/serializers/spree/v2/tenant/homepage_section_serializer.rb
1433
1448
  - app/serializers/spree/v2/tenant/role_serializer.rb
1449
+ - app/serializers/spree/v2/tenant/s3_signed_url_serializer.rb
1434
1450
  - app/serializers/spree/v2/tenant/taxon_serializer.rb
1435
1451
  - app/serializers/spree/v2/tenant/taxonomy_serializer.rb
1436
1452
  - app/serializers/spree/v2/tenant/user_device_token_serializer.rb
1437
1453
  - app/serializers/spree/v2/tenant/user_identity_provider_serializer.rb
1454
+ - app/serializers/spree/v2/tenant/user_profile_serializer.rb
1438
1455
  - app/serializers/spree/v2/tenant/user_serializer.rb
1439
1456
  - app/serializers/spree/v2/tenant/vendor_image_serializer.rb
1440
1457
  - app/serializers/spree/v2/tenant/vendor_serializer.rb
@@ -1924,7 +1941,10 @@ files:
1924
1941
  - app/views/spree/transit/vendors/_form.html.erb
1925
1942
  - app/views/spree/transit/vendors/_tabs.html.erb
1926
1943
  - app/views/spree/transit/vendors/edit.html.erb
1944
+ - app/views/spree_cm_commissioner/crew_invite_mailer/_mailer_stylesheets.html.erb
1945
+ - app/views/spree_cm_commissioner/crew_invite_mailer/send_crew_invite_email.html.erb
1927
1946
  - app/views/spree_cm_commissioner/guest_cards/show.html.erb
1947
+ - app/views/spree_cm_commissioner/layouts/crew_invite_mailer.html.erb
1928
1948
  - app/views/spree_cm_commissioner/layouts/line_item_mailer.html.erb
1929
1949
  - app/views/spree_cm_commissioner/layouts/order_mailer.html.erb
1930
1950
  - app/views/spree_cm_commissioner/layouts/telegram.html.erb
@@ -2228,7 +2248,10 @@ files:
2228
2248
  - db/migrate/20250217075228_add_indexes_to_cm_guests.rb
2229
2249
  - db/migrate/20250220021751_remove_unique_constraint_from_email_in_spree_users.rb
2230
2250
  - db/migrate/20250226092650_add_index_to_email_in_spree_users.rb
2251
+ - db/migrate/20250304101907_create_spree_cm_commissioner_invite.rb
2252
+ - db/migrate/20250304101946_create_spree_cm_commissioner_invite_user_taxon.rb
2231
2253
  - db/migrate/20250304155234_add_meta_data_to_spree_vendors.rb
2254
+ - db/migrate/20250307013422_add_parent_id_to_cm_place.rb
2232
2255
  - docker-compose.yml
2233
2256
  - docs/option_types/attr_types.md
2234
2257
  - docs/private_key.pem
@@ -2281,6 +2304,8 @@ files:
2281
2304
  - lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb
2282
2305
  - lib/spree_cm_commissioner/test_helper/factories/id_card_factory.rb
2283
2306
  - lib/spree_cm_commissioner/test_helper/factories/image_factory.rb
2307
+ - lib/spree_cm_commissioner/test_helper/factories/invite_factory.rb
2308
+ - lib/spree_cm_commissioner/test_helper/factories/invite_user_event_factory.rb
2284
2309
  - lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb
2285
2310
  - lib/spree_cm_commissioner/test_helper/factories/line_item_seat_factory.rb
2286
2311
  - lib/spree_cm_commissioner/test_helper/factories/notification_factory.rb
@@ -2312,6 +2337,7 @@ files:
2312
2337
  - lib/spree_cm_commissioner/test_helper/factories/tenant_factory.rb
2313
2338
  - lib/spree_cm_commissioner/test_helper/factories/transit_place_factory.rb
2314
2339
  - lib/spree_cm_commissioner/test_helper/factories/user_deletion_reasons_factory.rb
2340
+ - lib/spree_cm_commissioner/test_helper/factories/user_event_factory.rb
2315
2341
  - lib/spree_cm_commissioner/test_helper/factories/user_factory.rb
2316
2342
  - lib/spree_cm_commissioner/test_helper/factories/user_identity_provider_factory.rb
2317
2343
  - lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb
@@ -2363,9 +2389,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
2363
2389
  version: '2.7'
2364
2390
  required_rubygems_version: !ruby/object:Gem::Requirement
2365
2391
  requirements:
2366
- - - ">"
2392
+ - - ">="
2367
2393
  - !ruby/object:Gem::Version
2368
- version: 1.3.1
2394
+ version: '0'
2369
2395
  requirements:
2370
2396
  - none
2371
2397
  rubygems_version: 3.4.1