spree_cm_commissioner 1.8.0.pre.beta1 → 1.8.0.pre.beta2

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +1 -0
  3. data/Gemfile.lock +12 -12
  4. data/README.md +19 -6
  5. data/app/assets/images/mailer/bookme-plus_light.svg +1 -0
  6. data/app/controllers/spree/admin/taxons_controller_decorator.rb +10 -0
  7. data/app/controllers/spree/api/v2/organizer/invites_controller.rb +35 -0
  8. data/app/controllers/spree/api/v2/tenant/pin_code_generators_controller.rb +1 -17
  9. data/app/controllers/spree/api/v2/tenant/profile_images_controller.rb +52 -0
  10. data/app/controllers/spree/api/v2/tenant/s3_signed_urls_controller.rb +29 -0
  11. data/app/controllers/spree/api/v2/tenant/taxons_controller.rb +56 -0
  12. data/app/interactors/spree_cm_commissioner/crew_inviter.rb +63 -0
  13. data/app/interactors/spree_cm_commissioner/profile_image_destroyer.rb +16 -0
  14. data/app/mailers/spree_cm_commissioner/crew_invite_mailer.rb +13 -0
  15. data/app/models/concerns/spree_cm_commissioner/{order_requestable.rb → order_state_machine.rb} +44 -14
  16. data/app/models/spree_cm_commissioner/crew_invite.rb +7 -0
  17. data/app/models/spree_cm_commissioner/invite.rb +22 -0
  18. data/app/models/spree_cm_commissioner/invite_user_event.rb +5 -0
  19. data/app/models/spree_cm_commissioner/invite_user_taxon.rb +11 -0
  20. data/app/models/spree_cm_commissioner/order_decorator.rb +8 -44
  21. data/app/models/spree_cm_commissioner/place.rb +2 -0
  22. data/app/models/spree_cm_commissioner/product_decorator.rb +4 -0
  23. data/app/models/spree_cm_commissioner/taxon_decorator.rb +3 -0
  24. data/app/models/spree_cm_commissioner/taxon_video_banner.rb +4 -0
  25. data/app/models/spree_cm_commissioner/user_decorator.rb +4 -0
  26. data/app/models/spree_cm_commissioner/video.rb +15 -0
  27. data/app/overrides/spree/admin/taxons/_form/assets_form.html.erb.deface +19 -0
  28. data/app/overrides/spree/admin/taxons/_form/available_on.html.erb.deface +18 -0
  29. data/app/overrides/spree/admin/taxons/edit/title.html.erb.deface +5 -3
  30. data/app/serializers/spree/v2/organizer/asset_serializer.rb +11 -0
  31. data/app/serializers/spree/v2/organizer/invite_serializer.rb +11 -0
  32. data/app/serializers/spree/v2/organizer/taxon_serializer.rb +10 -0
  33. data/app/serializers/spree/v2/organizer/user_serializer.rb +9 -0
  34. data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +2 -1
  35. data/app/serializers/spree/v2/storefront/vendor_serializer_decorator.rb +1 -1
  36. data/app/serializers/spree/v2/tenant/s3_signed_url_serializer.rb +9 -0
  37. data/app/serializers/spree/v2/tenant/user_profile_serializer.rb +8 -0
  38. data/app/serializers/spree_cm_commissioner/v2/storefront/video_serializer.rb +9 -0
  39. data/app/views/spree/admin/classifications/index.html.erb +1 -1
  40. data/app/views/spree/admin/guest_card_classes/index.html.erb +1 -1
  41. data/app/views/spree/admin/taxon_vendors/index.html.erb +1 -1
  42. data/app/views/spree/admin/user_events/_users.html.erb +1 -1
  43. data/app/views/spree/admin/vendors/_form.html.erb +8 -0
  44. data/app/views/spree_cm_commissioner/crew_invite_mailer/_mailer_stylesheets.html.erb +82 -0
  45. data/app/views/spree_cm_commissioner/crew_invite_mailer/send_crew_invite_email.html.erb +33 -0
  46. data/app/views/spree_cm_commissioner/layouts/crew_invite_mailer.html.erb +15 -0
  47. data/config/initializers/spree_permitted_attributes.rb +1 -0
  48. data/config/locales/en.yml +10 -1
  49. data/config/locales/km.yml +10 -1
  50. data/config/routes.rb +5 -0
  51. data/db/migrate/20250304101907_create_spree_cm_commissioner_invite.rb +12 -0
  52. data/db/migrate/20250304101946_create_spree_cm_commissioner_invite_user_taxon.rb +11 -0
  53. data/db/migrate/20250304155234_add_meta_data_to_spree_vendors.rb +6 -0
  54. data/db/migrate/20250307013422_add_parent_id_to_cm_place.rb +9 -0
  55. data/db/migrate/20250314013434_add_available_on_to_spree_taxons.rb +5 -0
  56. data/lib/spree_cm_commissioner/test_helper/factories/invite_factory.rb +7 -0
  57. data/lib/spree_cm_commissioner/test_helper/factories/invite_user_event_factory.rb +5 -0
  58. data/lib/spree_cm_commissioner/test_helper/factories/user_event_factory.rb +6 -0
  59. data/lib/spree_cm_commissioner/version.rb +1 -1
  60. metadata +37 -4
  61. data/app/models/concerns/spree_cm_commissioner/order_bib_number_concern.rb +0 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 791d6f17676f557d59de96c1515213fa2b348f4e1727837ea10c4c985f302f45
4
- data.tar.gz: c0c3ec726af5f626e385ea768ae13e463f6bd0f4d2d4cff54da8a450c3e1c414
3
+ metadata.gz: ea8803e08aefa14cf5aab9234abfb9619a75f220a60a40e4ccf81c64039906b5
4
+ data.tar.gz: 37474847fdd50ded47ced904e3c133781f132cbd94bd60d265d72332d25a7962
5
5
  SHA512:
6
- metadata.gz: a0e80224bd19c608dfe569e8fd7f92a78a2a0dba85a3a20f835f9af22f896762c4d657ce300bb0349e07d40c2d68a97690bcb4d913b865381e97fa423564b71b
7
- data.tar.gz: aa3bf4f391db785b76a6565542efc3d7c08e96621d89f0cfd986ab0ccc280374c308f8858cb630d82d25d3ab619cc8fcc538589c48953d9b780216949e55833d
6
+ metadata.gz: 8adc0d6d15702bfd001e29cbbe51337ba00f723acc5fa5ad31f865a1300626bf891cf6ccda2aac2d080be2fe885ce308cd98098e1c7e6b3f45fd0fbb0463930a
7
+ data.tar.gz: ecdc09159880d9144f6507f1e9e068ceb2d1a884ed07a72e32764ba96c88bd8b6c06b9c142a00b3dd72e39e41e1b791d572c4d3772ff315d98aed1930fa970c8
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.3.5
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.beta1)
37
+ spree_cm_commissioner (1.8.0.pre.beta2)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -418,29 +418,29 @@ GEM
418
418
  google-cloud-recaptcha_enterprise-v1beta1 (0.10.0)
419
419
  gapic-common (>= 0.20.0, < 2.a)
420
420
  google-cloud-errors (~> 1.0)
421
- google-protobuf (3.24.4)
422
- google-protobuf (3.24.4-x86_64-darwin)
423
- google-protobuf (3.24.4-x86_64-linux)
421
+ google-protobuf (3.25.6)
422
+ google-protobuf (3.25.6-x86_64-darwin)
423
+ google-protobuf (3.25.6-x86_64-linux)
424
424
  googleapis-common-protos (1.4.0)
425
425
  google-protobuf (~> 3.14)
426
426
  googleapis-common-protos-types (~> 1.2)
427
427
  grpc (~> 1.27)
428
- googleapis-common-protos-types (1.9.0)
429
- google-protobuf (~> 3.18)
428
+ googleapis-common-protos-types (1.18.0)
429
+ google-protobuf (>= 3.18, < 5.a)
430
430
  googleauth (1.8.1)
431
431
  faraday (>= 0.17.3, < 3.a)
432
432
  jwt (>= 1.4, < 3.0)
433
433
  multi_json (~> 1.11)
434
434
  os (>= 0.9, < 2.0)
435
435
  signet (>= 0.16, < 2.a)
436
- grpc (1.58.0)
437
- google-protobuf (~> 3.23)
436
+ grpc (1.70.1)
437
+ google-protobuf (>= 3.25, < 5.0)
438
438
  googleapis-common-protos-types (~> 1.0)
439
- grpc (1.58.0-x86_64-darwin)
440
- google-protobuf (~> 3.23)
439
+ grpc (1.70.1-x86_64-darwin)
440
+ google-protobuf (>= 3.25, < 5.0)
441
441
  googleapis-common-protos-types (~> 1.0)
442
- grpc (1.58.0-x86_64-linux)
443
- google-protobuf (~> 3.23)
442
+ grpc (1.70.1-x86_64-linux)
443
+ google-protobuf (>= 3.25, < 5.0)
444
444
  googleapis-common-protos-types (~> 1.0)
445
445
  hana (1.3.7)
446
446
  hashdiff (1.0.1)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SpreeCmCommissioner
2
2
 
3
- ![Commission gem build status](https://github.com/channainfo/commissioner/actions/workflows/publish.yml/badge.svg?branch= "Build status")
3
+ ![Commission gem build status](https://github.com/channainfo/commissioner/actions/workflows/test_and_build_gem.yml/badge.svg?branch= "Build status")
4
4
 
5
5
  An application platform built on top of Spree commerce for modeling any bussiness applications.
6
6
 
@@ -196,12 +196,25 @@ This setup allows you to configure the environment and database services in a si
196
196
 
197
197
  ## Releasing
198
198
 
199
- ```sh
200
- bundle exec gem bump -p -t
201
- bundle exec gem release
202
- ```
199
+ To release the gem:
200
+
201
+ 1; Bump new version in the file: lib/spree_cm_commissioner/version.rb, for example
202
+
203
+ ```ruby
204
+ VERSION = '1.8.0-beta1'.freeze
205
+ ```
206
+
207
+ to release `1.8.0-beta1`
208
+
209
+ 2; Tag a repo with the same version, for example
210
+
211
+ ```sh
212
+ git tag 1.8.0-beta1
213
+ ```
214
+
215
+ 3; Push the tag to the repo and github action will build and push the gem to rubygem.org.
203
216
 
204
- For more options please see [gem-release REAMDE](https://github.com/svenfuchs/gem-release)
217
+ 4; Get the gem version to the project in cm-market-server.
205
218
 
206
219
  ## Troubleshooting Database Lock on Taxonomy Creation Errors
207
220
 
@@ -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>
@@ -5,6 +5,11 @@ module Spree
5
5
  base.before_action :build_assets, only: %i[create update]
6
6
  end
7
7
 
8
+ def update
9
+ @taxon.update(available_on: permitted_resource_params[:available_on]) if permitted_resource_params[:available_on].present?
10
+ super
11
+ end
12
+
8
13
  def remove_category_icon
9
14
  remove_asset(@taxon.category_icon)
10
15
  end
@@ -21,6 +26,10 @@ module Spree
21
26
  remove_asset(@taxon.home_banner)
22
27
  end
23
28
 
29
+ def remove_video_banner
30
+ remove_asset(@taxon.video_banner)
31
+ end
32
+
24
33
  private
25
34
 
26
35
  def remove_asset(asset)
@@ -38,6 +47,7 @@ module Spree
38
47
  @taxon.build_app_banner(attachment: permitted_resource_params.delete(:app_banner)) if permitted_resource_params[:app_banner]
39
48
  @taxon.build_web_banner(attachment: permitted_resource_params.delete(:web_banner)) if permitted_resource_params[:web_banner]
40
49
  @taxon.build_home_banner(attachment: permitted_resource_params.delete(:home_banner)) if permitted_resource_params[:home_banner]
50
+ @taxon.build_video_banner(attachment: permitted_resource_params.delete(:video_banner)) if permitted_resource_params[:video_banner]
41
51
  end
42
52
  end
43
53
  end
@@ -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({ message: 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
@@ -3,23 +3,7 @@ module Spree
3
3
  module V2
4
4
  module Tenant
5
5
  class PinCodeGeneratorsController < BaseController
6
- before_action :validate_recaptcha, only: [:create]
7
-
8
- def validate_recaptcha
9
- return unless ENV['RECAPTCHA_TOKEN_VALIDATOR_ENABLE'] == 'yes'
10
-
11
- context = SpreeCmCommissioner::RecaptchaTokenValidator.call(
12
- token: params[:recaptcha_token],
13
- action: params[:recaptcha_action],
14
- site_key: params[:recaptcah_site_key]
15
- )
16
-
17
- return if context.success?
18
-
19
- render_error_payload(context.message, 400)
20
- end
21
-
22
- # :phone_number, :email, :type, :recaptcha_token, :recaptcha_action, :recaptcah_site_key
6
+ # :phone_number, :email, :type
23
7
  def create
24
8
  context = SpreeCmCommissioner::PinCodeGenerator.call(pin_code_attrs)
25
9
 
@@ -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,56 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class TaxonsController < BaseController
6
+ private
7
+
8
+ def collection_serializer
9
+ Spree::Api::Dependencies.storefront_taxon_serializer.constantize
10
+ end
11
+
12
+ def resource_serializer
13
+ Spree::Api::Dependencies.storefront_taxon_serializer.constantize
14
+ end
15
+
16
+ def collection_finder
17
+ Spree::Api::Dependencies.storefront_taxon_finder.constantize
18
+ end
19
+
20
+ def paginated_collection
21
+ @paginated_collection ||= collection_paginator.new(collection, params).call
22
+ end
23
+
24
+ def resource
25
+ @resource ||= scope.find_by(permalink: params[:id]) || scope.find(params[:id])
26
+ end
27
+
28
+ def model_class
29
+ Spree::Taxon
30
+ end
31
+
32
+ def scope
33
+ MultiTenant.with(@tenant) do
34
+ model_class
35
+ end
36
+ end
37
+
38
+ def scope_includes
39
+ node_includes = %i[icon parent taxonomy]
40
+
41
+ {
42
+ parent: node_includes,
43
+ children: node_includes,
44
+ taxonomy: [root: node_includes],
45
+ icon: [attachment_attachment: :blob]
46
+ }
47
+ end
48
+
49
+ def serializer_params
50
+ super.merge(include_products: action_name == 'show')
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ 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
@@ -1,10 +1,23 @@
1
1
  # Make sure to put this concern below other concern or methods that generating additional order info like guests, seat number, etc.
2
2
  # This will ensure that when each notification is sent with neccessary data.
3
3
  module SpreeCmCommissioner
4
- module OrderRequestable
4
+ module OrderStateMachine
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
+ state_machine.before_transition to: :complete, do: :request, if: :need_confirmation?
9
+ state_machine.before_transition to: :complete, do: :generate_bib_number
10
+
11
+ state_machine.after_transition to: :complete, do: :precalculate_conversion
12
+ state_machine.after_transition to: :complete, do: :notify_order_complete_app_notification_to_user, unless: :subscription?
13
+ state_machine.after_transition to: :complete, do: :notify_order_complete_telegram_notification_to_user, unless: :subscription?
14
+ state_machine.after_transition to: :complete, do: :send_order_complete_telegram_alert_to_vendors, unless: :need_confirmation?
15
+ state_machine.after_transition to: :complete, do: :send_order_complete_telegram_alert_to_store, unless: :need_confirmation?
16
+
17
+ state_machine.after_transition to: :resumed, do: :precalculate_conversion
18
+
19
+ state_machine.after_transition to: :canceled, do: :precalculate_conversion
20
+
8
21
  scope :accepted, -> { where(request_state: 'accepted') }
9
22
 
10
23
  scope :filter_by_request_state, lambda {
@@ -14,15 +27,6 @@ module SpreeCmCommissioner
14
27
  .order(created_at: :desc)
15
28
  }
16
29
 
17
- # use after_update instead of after_transition
18
- # since it has usecase that order state is forced to update which not fire after_transition
19
-
20
- after_update :notify_order_complete_app_notification_to_user, if: -> { payment_state_changed_to_paid? && !subscription? }
21
- after_update :notify_order_complete_telegram_notification_to_user, if: -> { state_changed_to_complete? && !subscription? }
22
- after_update :request, if: -> { state_changed_to_complete? && need_confirmation? }
23
- after_update :send_order_complete_telegram_alert_to_vendors, if: -> { state_changed_to_complete? && !need_confirmation? }
24
- after_update :send_order_complete_telegram_alert_to_store, if: -> { state_changed_to_complete? && !need_confirmation? }
25
-
26
30
  state_machine :request_state, initial: nil, use_transactions: false do
27
31
  event :request do
28
32
  transition from: nil, to: :requested
@@ -42,6 +46,7 @@ module SpreeCmCommissioner
42
46
  event :reject do
43
47
  transition from: :requested, to: :rejected
44
48
  end
49
+
45
50
  after_transition to: :rejected, do: :send_order_rejected_app_notification_to_user
46
51
  after_transition to: :rejected, do: :send_order_rejected_telegram_alert_to_store
47
52
 
@@ -55,6 +60,29 @@ module SpreeCmCommissioner
55
60
  end
56
61
  end
57
62
 
63
+ def precalculate_conversion
64
+ line_items.each do |item|
65
+ SpreeCmCommissioner::ConversionPreCalculatorJob.perform_later(item.product_id)
66
+ end
67
+ end
68
+
69
+ def generate_bib_number
70
+ line_items.find_each(&:generate_remaining_guests)
71
+
72
+ line_items.with_bib_prefix.each do |line_item|
73
+ line_item.guests.none_bib.each do |guest|
74
+ guest.generate_bib
75
+ next if guest.save
76
+
77
+ guest.errors.each do |msg|
78
+ errors.add(:guests, msg)
79
+ end
80
+ end
81
+ end
82
+
83
+ errors.empty?
84
+ end
85
+
58
86
  def rejected_by(user)
59
87
  transaction do
60
88
  reject!
@@ -76,6 +104,12 @@ module SpreeCmCommissioner
76
104
  end
77
105
  end
78
106
 
107
+ # overrided not to send email yet to user if order needs confirmation
108
+ # it will send after vendors accepted.
109
+ def confirmation_delivered?
110
+ confirmation_delivered || need_confirmation?
111
+ end
112
+
79
113
  # can_accepted? already use by ransack/visitor.rb
80
114
  def can_accept_all?
81
115
  approved? && requested?
@@ -97,10 +131,6 @@ module SpreeCmCommissioner
97
131
  line_items.any?(&:need_confirmation)
98
132
  end
99
133
 
100
- def payment_state_changed_to_paid?
101
- saved_change_to_payment_state? && payment_state == 'paid'
102
- end
103
-
104
134
  def send_order_request_telegram_confirmation_alert_to_vendor; end
105
135
 
106
136
  def send_order_complete_telegram_alert_to_vendors
@@ -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