spree_cm_commissioner 1.11.0.pre.pre4 → 1.13.0

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 (175) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test_and_build_gem.yml +143 -12
  3. data/.gitignore +1 -2
  4. data/Gemfile.lock +1 -22
  5. data/Rakefile +4 -33
  6. data/app/controllers/spree/admin/cms_pages_controller_decorator.rb +32 -0
  7. data/app/controllers/spree/admin/product_places_controller.rb +2 -0
  8. data/app/controllers/spree/admin/stock_managements_controller.rb +1 -62
  9. data/app/controllers/spree/api/v2/organizer/invite_guests_controller.rb +70 -0
  10. data/app/controllers/spree/api/v2/storefront/accommodations_controller.rb +31 -14
  11. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
  12. data/app/controllers/spree/api/v2/storefront/waiting_room_sessions_controller.rb +1 -0
  13. data/app/controllers/spree/api/v2/tenant/account_checker_controller.rb +1 -1
  14. data/app/controllers/spree/api/v2/tenant/account_recovers_controller.rb +2 -2
  15. data/app/controllers/spree/api/v2/tenant/cms_pages_controller.rb +41 -0
  16. data/app/controllers/spree/api/v2/tenant/reset_passwords_controller.rb +1 -1
  17. data/app/controllers/spree/api/v2/tenant/waiting_room_sessions_controller.rb +30 -0
  18. data/app/controllers/spree_cm_commissioner/admin/variants_controller_decorator.rb +17 -0
  19. data/app/controllers/spree_cm_commissioner/api/v2/storefront/cms_pages_controller_decorator.rb +18 -0
  20. data/app/interactors/spree_cm_commissioner/account_recover.rb +2 -2
  21. data/app/interactors/spree_cm_commissioner/create_event.rb +7 -26
  22. data/app/interactors/spree_cm_commissioner/create_ticket.rb +95 -0
  23. data/app/interactors/spree_cm_commissioner/event_line_items_date_syncer.rb +19 -0
  24. data/app/interactors/spree_cm_commissioner/existing_account_checker.rb +1 -1
  25. data/app/interactors/spree_cm_commissioner/order_importer/multi_guest.rb +31 -0
  26. data/app/interactors/spree_cm_commissioner/organizers_transactional_email_notifier.rb +27 -0
  27. data/app/interactors/spree_cm_commissioner/pin_code_sender.rb +3 -3
  28. data/app/interactors/spree_cm_commissioner/product_event_id_to_children_syncer.rb +15 -0
  29. data/app/interactors/spree_cm_commissioner/sms.rb +14 -0
  30. data/app/interactors/spree_cm_commissioner/telegram_debug_pin_code_sender.rb +2 -1
  31. data/app/interactors/spree_cm_commissioner/transactional_email_sender.rb +50 -0
  32. data/app/interactors/spree_cm_commissioner/user_forgotten_password_updater.rb +2 -1
  33. data/app/interactors/spree_cm_commissioner/user_password_authenticator.rb +4 -2
  34. data/app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb +7 -14
  35. data/app/interactors/spree_cm_commissioner/waiting_room_session_firebase_logger.rb +30 -0
  36. data/app/jobs/spree_cm_commissioner/ensure_event_for_product_line_item_guests_job.rb +13 -0
  37. data/app/jobs/spree_cm_commissioner/event_line_items_date_syncer_job.rb +8 -0
  38. data/app/jobs/spree_cm_commissioner/product_event_id_to_children_syncer_job.rb +8 -0
  39. data/app/jobs/spree_cm_commissioner/telegram_debug_pin_code_sender_job.rb +3 -1
  40. data/app/jobs/spree_cm_commissioner/waiting_room_session_firebase_logger_job.rb +13 -0
  41. data/app/mailers/spree_cm_commissioner/event_transactional_mailer.rb +23 -0
  42. data/app/mailers/spree_cm_commissioner/pin_code_mailer.rb +1 -0
  43. data/app/models/concerns/spree_cm_commissioner/kyc_bitwise.rb +2 -0
  44. data/app/models/concerns/spree_cm_commissioner/line_item_durationable.rb +10 -6
  45. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +13 -26
  46. data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +4 -3
  47. data/app/models/concerns/spree_cm_commissioner/product_type.rb +0 -10
  48. data/app/models/concerns/spree_cm_commissioner/user_identity.rb +7 -4
  49. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +8 -10
  50. data/app/models/spree_cm_commissioner/cms_page_decorator.rb +9 -0
  51. data/app/models/spree_cm_commissioner/event_ticket_google_wallet.rb +2 -2
  52. data/app/models/spree_cm_commissioner/guest.rb +1 -1
  53. data/app/models/spree_cm_commissioner/invite_guest.rb +23 -0
  54. data/app/models/spree_cm_commissioner/line_item_decorator.rb +10 -16
  55. data/app/models/spree_cm_commissioner/option_type_decorator.rb +6 -0
  56. data/app/models/spree_cm_commissioner/order_decorator.rb +0 -15
  57. data/app/models/spree_cm_commissioner/place.rb +1 -1
  58. data/app/models/spree_cm_commissioner/product_decorator.rb +17 -14
  59. data/app/models/spree_cm_commissioner/product_place.rb +1 -0
  60. data/app/models/spree_cm_commissioner/role_decorator.rb +3 -0
  61. data/app/models/spree_cm_commissioner/stock/availability_checker.rb +25 -27
  62. data/app/models/spree_cm_commissioner/stock/availability_validator_decorator.rb +1 -2
  63. data/app/models/spree_cm_commissioner/stock/line_item_availability_checker.rb +3 -3
  64. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +0 -14
  65. data/app/models/spree_cm_commissioner/taxon_decorator.rb +26 -3
  66. data/app/models/spree_cm_commissioner/transactional_email.rb +6 -0
  67. data/app/models/spree_cm_commissioner/user_decorator.rb +6 -0
  68. data/app/models/spree_cm_commissioner/variant_decorator.rb +27 -34
  69. data/app/models/spree_cm_commissioner/vehicle.rb +0 -7
  70. data/app/models/spree_cm_commissioner/vendor_decorator.rb +9 -1
  71. data/app/overrides/spree/admin/cms_pages/_form/tenant_fields.html.erb.deface +9 -0
  72. data/app/overrides/spree/admin/cms_pages/index/cms_pages_tabs.html.erb.deface +21 -0
  73. data/app/overrides/spree/admin/taxons/_form/assets_form.html.erb.deface +2 -2
  74. data/app/overrides/spree/admin/taxons/_form/available_on.html.erb.deface +3 -1
  75. data/app/overrides/spree/admin/taxons/_form/background_color_and_foreground_color.html.erb.deface +3 -1
  76. data/app/overrides/spree/admin/taxons/_form/custom_redirect_url.html.erb.deface +3 -1
  77. data/app/overrides/spree/admin/taxons/_form/hide_video_banner.html.erb.deface +3 -1
  78. data/app/overrides/spree/admin/taxons/_form/purchasable_on_status.html.erb.deface +3 -1
  79. data/app/overrides/spree/admin/taxons/_form/show_badge_status.html.erb.deface +3 -1
  80. data/app/overrides/spree/admin/taxons/_form/to_date_form_date.html.erb.deface +3 -4
  81. data/app/overrides/spree/admin/users/_form/roles_fields.html.erb.deface +1 -1
  82. data/app/overrides/spree/admin/users/index/body.html.erb.deface +3 -0
  83. data/app/overrides/spree/admin/users/index/headers.html.erb.deface +3 -0
  84. data/app/overrides/spree/admin/variants/_form/kyc_field.html.erb.deface +40 -0
  85. data/app/overrides/spree/admin/variants/edit/variant_status.html.erb.deface +6 -3
  86. data/app/queries/spree_cm_commissioner/variant_availability/non_permanent_stock_query.rb +45 -0
  87. data/app/queries/spree_cm_commissioner/variant_availability/permanent_stock_query.rb +55 -0
  88. data/app/request_schemas/spree_cm_commissioner/accommodation_request_schema.rb +0 -3
  89. data/app/request_schemas/spree_cm_commissioner/application_request_schema.rb +1 -1
  90. data/app/serializers/spree/v2/organizer/invite_guest_serializer.rb +13 -0
  91. data/app/serializers/spree/v2/storefront/accommodation_serializer.rb +0 -2
  92. data/app/serializers/spree/v2/storefront/taxon_serializer_decorator.rb +2 -0
  93. data/app/serializers/spree/v2/tenant/waiting_room_session_serializer.rb +9 -0
  94. data/app/serializers/spree_cm_commissioner/v2/storefront/guest_serializer.rb +2 -1
  95. data/app/services/spree_cm_commissioner/user_authenticator.rb +3 -1
  96. data/app/services/spree_cm_commissioner/user_roles_assigner.rb +62 -0
  97. data/app/views/spree/admin/shared/_cms_pages_tabs.html.erb +20 -0
  98. data/app/views/spree/admin/shared/_taxon_tabs.html.erb +19 -19
  99. data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +1 -3
  100. data/app/views/spree/admin/stock_managements/index.html.erb +5 -40
  101. data/app/views/spree/shared/_base_mailer_header.html.erb +10 -2
  102. data/app/views/spree_cm_commissioner/event_transactional_mailer/_event_banner.html.erb +3 -0
  103. data/app/views/spree_cm_commissioner/event_transactional_mailer/_mailer_stylesheets.html.erb +317 -0
  104. data/app/views/spree_cm_commissioner/event_transactional_mailer/_note.html.erb +8 -0
  105. data/app/views/spree_cm_commissioner/event_transactional_mailer/_share_button.html.erb +3 -0
  106. data/app/views/spree_cm_commissioner/event_transactional_mailer/send_to_organizer.html.erb +59 -0
  107. data/app/views/spree_cm_commissioner/event_transactional_mailer/send_to_participant.html.erb +52 -0
  108. data/app/views/spree_cm_commissioner/layouts/event_transactional_mailer.html.erb +14 -0
  109. data/config/initializers/spree_permitted_attributes.rb +0 -5
  110. data/config/locales/en.yml +36 -0
  111. data/config/locales/km.yml +2 -0
  112. data/config/routes.rb +6 -11
  113. data/db/migrate/20250422014417_create_spree_cm_commissioner_invite_guest.rb +21 -0
  114. data/db/migrate/20250509033437_create_spree_cm_commissioner_transactional_emails.rb +12 -0
  115. data/db/migrate/20250509075429_add_max_order_quantity_to_spree_product.rb +5 -0
  116. data/db/migrate/20250512075319_add_tenant_id_to_spree_cms_pages.rb +6 -0
  117. data/db/migrate/20250520042602_add_event_to_spree_products.rb +7 -0
  118. data/db/migrate/20250520044533_add_event_to_spree_line_items.rb +7 -0
  119. data/db/migrate/20250521024345_add_tenant_id_to_cm_waiting_room_sessions.rb +6 -0
  120. data/db/migrate/20250521095539_add_kyc_to_spree_variants.rb +5 -0
  121. data/docker-compose.yml +1 -1
  122. data/lib/generators/spree_cm_commissioner/install/install_generator.rb +3 -11
  123. data/lib/generators/spree_cm_commissioner/install/templates/app/javascript/{spree_dashboard/spree_cm_commissioner → spree_cm_commissioner}/utilities.js +0 -4
  124. data/lib/spree_cm_commissioner/calendar_event.rb +1 -11
  125. data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
  126. data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
  127. data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +5 -18
  128. data/lib/spree_cm_commissioner/test_helper/factories/role.rb +7 -0
  129. data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
  130. data/lib/spree_cm_commissioner/test_helper/factories/taxon_home_banner_factory.rb +5 -0
  131. data/lib/spree_cm_commissioner/test_helper/factories/transactional_email_factory.rb +6 -0
  132. data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +6 -41
  133. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -1
  134. data/lib/spree_cm_commissioner/version.rb +1 -1
  135. data/lib/spree_cm_commissioner.rb +0 -34
  136. data/lib/tasks/ensure_event_for_product_line_item_guests.rake +7 -0
  137. data/lib/tasks/update_invalid_self_root_places.rake +9 -0
  138. data/lib/tasks/update_orphan_root_places.rake +1 -0
  139. data/spree_cm_commissioner.gemspec +0 -5
  140. metadata +54 -82
  141. data/app/controllers/spree/api/v2/storefront/accommodations/variants_controller.rb +0 -42
  142. data/app/finders/spree_cm_commissioner/accommodations/find.rb +0 -40
  143. data/app/finders/spree_cm_commissioner/accommodations/find_variant.rb +0 -35
  144. data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +0 -40
  145. data/app/interactors/spree_cm_commissioner/inventory_item_syncer.rb +0 -25
  146. data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +0 -13
  147. data/app/interactors/spree_cm_commissioner/stock/inventory_items_generator.rb +0 -15
  148. data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +0 -75
  149. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +0 -24
  150. data/app/interactors/spree_cm_commissioner/user_roles_assigner.rb +0 -22
  151. data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +0 -7
  152. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +0 -7
  153. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +0 -11
  154. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +0 -11
  155. data/app/jobs/spree_cm_commissioner/stock/permanent_inventory_items_generator_job.rb +0 -9
  156. data/app/models/spree_cm_commissioner/inventory.rb +0 -11
  157. data/app/models/spree_cm_commissioner/inventory_item.rb +0 -56
  158. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +0 -40
  159. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +0 -126
  160. data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +0 -36
  161. data/app/models/spree_cm_commissioner/redis_stock/variant_cached_inventory_items_builder.rb +0 -27
  162. data/app/models/spree_cm_commissioner/stock/order_availability_checker.rb +0 -44
  163. data/app/request_schemas/spree_cm_commissioner/variant_request_schema.rb +0 -19
  164. data/app/views/spree/admin/stock_managements/_events_popover.html.erb +0 -23
  165. data/app/views/spree/admin/stock_managements/calendar.html.erb +0 -35
  166. data/db/migrate/20250304293518_create_cm_inventory_items.rb +0 -21
  167. data/db/migrate/20250429094228_add_lock_version_to_cm_inventory_items.rb +0 -5
  168. data/db/migrate/20250502025848_add_index_to_spree_products.rb +0 -5
  169. data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +0 -5
  170. data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +0 -5
  171. data/lib/spree_cm_commissioner/cached_inventory_item.rb +0 -23
  172. data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +0 -9
  173. data/lib/tasks/create_default_non_permanent_inventory_items.rake +0 -16
  174. data/lib/tasks/ensure_correct_product_type.rake +0 -7
  175. data/lib/tasks/generate_inventory_items.rake +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f178313a2ff417bbefb328e143380ba8c9d26b8d49f7e8081cfc99dd2d6cbbf0
4
- data.tar.gz: f6820d0e682b0f8de8e3778b28bcba689b47aa8b02cefaba15c4c2a1bc5b2549
3
+ metadata.gz: 3da0bd043e4ceca1f57afecc1bab6fbc58c960ba296f7fffa42b449a2475f8f8
4
+ data.tar.gz: 974c8e19e026fa90254594447a9735be039371ae6d0bc11a24c9cdf3b86dfd8c
5
5
  SHA512:
6
- metadata.gz: 41fe4581e7208130cde9df5116937357474159a9c51235e8497f15af6cb85659d1dd6261fb55dd86ae84fe0b5206db57467069cee22aa6aff0d9a520f90a9fd5
7
- data.tar.gz: 9a63df1c9ed0bc588439950e3de8d8093e141a5fee4e5090f9003a22ccce7e801770a95eff2415b1abbfa6d215d654d80fc3c3c7a1eb062aad050eb7795f50de
6
+ metadata.gz: 4b1d418758d9880e50dd1481b095f4cad76cc106ca0a950b694d2a87c053bf7f48655029c52939f33bf099db0a7d84048f0482d488a20ac720f1b6f8015a687e
7
+ data.tar.gz: 93b3ffb94424ba4a4ed46e5cde3303dc33c54a58417dd1a0750a5cb56d3638778d1fa5ceb75cf812617c33e12ae3c38c6402b7719ddfa53b2ce9567a8bb860e4
@@ -10,12 +10,113 @@ on:
10
10
  - reopened
11
11
  branches:
12
12
  - develop
13
- - milestone-77-scalable-design
14
13
  push:
15
14
  tags:
16
15
  - "*"
17
16
  jobs:
17
+ validate-commits:
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - name: Check PR title format
22
+ if: github.event_name == 'pull_request'
23
+ uses: actions/github-script@v7
24
+ with:
25
+ script: |
26
+ const title = context.payload.pull_request.title.trim();
27
+
28
+ console.log("PR title: ", title);
29
+
30
+ const pattern = /^Close\s+#\d+\s.+/;
31
+
32
+ if (!pattern.test(title)) {
33
+ core.setFailed(
34
+ `PR title must start with "Close #issue_number message". Example: Close #123 Add login form`
35
+ );
36
+ } else {
37
+ console.log("PR title format is correct.");
38
+ }
39
+ - name: Check commit messages format
40
+ if: github.event_name == 'pull_request'
41
+ uses: actions/github-script@v7
42
+ with:
43
+ script: |
44
+ const pr = context.payload.pull_request;
45
+ const commits_url = pr.commits_url;
46
+
47
+ const commits = await github.request(commits_url);
48
+ const pattern = /^Close\s+#\d+\s.+/;
49
+
50
+ let invalidCommits = [];
51
+
52
+ for (const commit of commits.data) {
53
+ const msg = commit.commit.message.trim();
54
+
55
+ console.log("commit message: ", msg);
56
+
57
+ if (!pattern.test(msg)) {
58
+ invalidCommits.push(`- ${msg}`);
59
+ }
60
+ }
61
+
62
+ if (invalidCommits.length > 0) {
63
+ core.setFailed(
64
+ `The following commit messages are not in the correct format:\n\n${invalidCommits.join(
65
+ '\n'
66
+ )}\n\nEach commit message must start with "Close #<issue_number> <message>"`
67
+ );
68
+ } else {
69
+ console.log("All commit messages are correctly formatted.");
70
+ }
71
+ - name: Check for unresolved review threads
72
+ if: github.event_name == 'pull_request'
73
+ uses: actions/github-script@v7
74
+ with:
75
+ script: |
76
+ const prNumber = context.payload.pull_request.number;
77
+ const { owner, repo } = context.repo;
78
+
79
+ const query = `
80
+ query($owner: String!, $repo: String!, $prNumber: Int!) {
81
+ repository(owner: $owner, name: $repo) {
82
+ pullRequest(number: $prNumber) {
83
+ reviewThreads(first: 100) {
84
+ nodes {
85
+ isResolved
86
+ comments(first: 1) {
87
+ nodes {
88
+ body
89
+ author {
90
+ login
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ `;
100
+ const variables = { owner, repo, prNumber };
101
+ const result = await github.graphql(query, variables);
102
+ const threads = result.repository.pullRequest.reviewThreads.nodes;
103
+
104
+ const unresolved = threads.filter(t => !t.isResolved);
105
+
106
+ if (unresolved.length > 0) {
107
+ unresolved.forEach(thread => {
108
+ const comments = thread.comments.nodes;
109
+ if (comments.length > 0) {
110
+ console.log(`💬 Comment by ${comments[0].author.login}: ${comments[0].body}`);
111
+ }
112
+ });
113
+ core.setFailed(`❌ There are ${unresolved.length} unresolved review thread(s). Please resolve them before merging.`);
114
+ } else {
115
+ console.log("✅ All review threads are resolved.");
116
+ }
117
+
18
118
  test_and_build_gem:
119
+ needs: [validate-commits]
19
120
  # if: github.head_ref != '2572-enforce-pr-workflow' || github.base_ref != 'develop'
20
121
  runs-on: ubuntu-latest
21
122
 
@@ -35,17 +136,6 @@ jobs:
35
136
  --health-timeout 5s
36
137
  --health-retries 5
37
138
 
38
- redis:
39
- image: redis
40
- # Set health checks to wait until redis has started
41
- options: >-
42
- --health-cmd "redis-cli ping"
43
- --health-interval 10s
44
- --health-timeout 5s
45
- --health-retries 5
46
- ports:
47
- - 6379:6379 # Maps port 6379 on service container to the host
48
-
49
139
  steps:
50
140
  - uses: actions/checkout@v3
51
141
 
@@ -66,6 +156,47 @@ jobs:
66
156
  gem install bundler
67
157
  bundle install --jobs 4 --retry 3
68
158
 
159
+ - name: Quality
160
+ env:
161
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
162
+ run: |
163
+ bundle exec rubocop
164
+
165
+ - name: Security
166
+ env:
167
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
168
+ run: |
169
+ bundle exec brakeman
170
+
171
+ - name: Run test
172
+ env:
173
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
174
+
175
+ if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'develop'
176
+ run: |
177
+ bundle exec rake
178
+
179
+ # 2405-build-and-publish-gem
180
+ # - name: Rename long migration files
181
+ # env:
182
+ # DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
183
+ # # if: startsWith(github.ref, 'refs/tags/') # Only on tag pushes
184
+ # if: github.ref == 'refs/heads/2405-build-and-publish-gem'
185
+
186
+ # run: |
187
+ # cd db/migrate
188
+ # for file in *.rb; do
189
+ # if [ ${#file} -gt 60 ]; then # Adjust threshold if needed
190
+ # # Extract timestamp (first 14 chars) and shorten the rest
191
+ # timestamp=${file:0:14}
192
+ # suffix=$(echo "$file" | sed 's/^[0-9]\{14\}_//' | sed 's/\.rb$//')
193
+ # short_suffix=$(echo "$suffix" | cut -c1-40) # Limit suffix to 40 chars
194
+ # new_name="${timestamp}_${short_suffix}.rb"
195
+ # mv "$file" "$new_name"
196
+ # echo "Renamed $file to $new_name"
197
+ # fi
198
+ # done
199
+
69
200
  # Build the gem
70
201
  - name: Build gem
71
202
  env:
data/.gitignore CHANGED
@@ -28,5 +28,4 @@ node_modules
28
28
  # VScode
29
29
  .vscode
30
30
  !.vscode/.settings.json
31
- .env
32
- vendor/bundle/
31
+ .env
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (1.11.0.pre.pre4)
37
+ spree_cm_commissioner (1.13.0)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -42,7 +42,6 @@ PATH
42
42
  aws-sdk-s3
43
43
  blazer (~> 3.0.4)
44
44
  byebug
45
- connection_pool
46
45
  counter_culture (~> 3.2)
47
46
  dry-validation (~> 1.10)
48
47
  elasticsearch (~> 8.5)
@@ -58,8 +57,6 @@ PATH
58
57
  phonelib
59
58
  premailer-rails
60
59
  rails (~> 7.0.4)
61
- redis
62
- redis-rails
63
60
  rqrcode (~> 2.0)
64
61
  searchkick (~> 5.1)
65
62
  simple_calendar (~> 2.4)
@@ -620,8 +617,6 @@ GEM
620
617
  activesupport (>= 2.3.14)
621
618
  racc (1.7.1)
622
619
  rack (2.2.8)
623
- rack-session (1.0.2)
624
- rack (< 3)
625
620
  rack-test (2.1.0)
626
621
  rack (>= 1.3)
627
622
  rails (7.0.8)
@@ -665,24 +660,8 @@ GEM
665
660
  rbtree (0.4.6)
666
661
  redis (5.0.7)
667
662
  redis-client (>= 0.9.0)
668
- redis-actionpack (5.5.0)
669
- actionpack (>= 5)
670
- redis-rack (>= 2.1.0, < 4)
671
- redis-store (>= 1.1.0, < 2)
672
- redis-activesupport (5.3.0)
673
- activesupport (>= 3, < 8)
674
- redis-store (>= 1.3, < 2)
675
663
  redis-client (0.17.0)
676
664
  connection_pool
677
- redis-rack (3.0.0)
678
- rack-session (>= 0.2.0)
679
- redis-store (>= 1.2, < 2)
680
- redis-rails (5.0.2)
681
- redis-actionpack (>= 5.0, < 6)
682
- redis-activesupport (>= 5.0, < 6)
683
- redis-store (>= 1.2, < 2)
684
- redis-store (1.11.0)
685
- redis (>= 4, < 6)
686
665
  regexp_parser (2.8.2)
687
666
  representable (3.2.0)
688
667
  declarative (< 0.1.0)
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
3
 
4
4
  require 'rspec/core/rake_task'
5
- require 'spree/testing_support/common_rake'
5
+ require 'spree/testing_support/extension_rake'
6
6
 
7
7
  RSpec::Core::RakeTask.new
8
8
 
@@ -14,37 +14,8 @@ task :default do
14
14
  Rake::Task[:spec].invoke
15
15
  end
16
16
 
17
- # Copied from:
18
- # spree_core:lib/spree/testing_support/common_rake.rb
19
- # But refactored to skip frontend & backend setup.
20
17
  desc 'Generates a dummy app for testing'
21
- task :test_app do |_t, args|
22
- require 'spree_cm_commissioner'
23
- require "generators/spree_cm_commissioner/install/install_generator"
24
-
25
- Rails.env = ENV['RAILS_ENV'] = 'test'
26
-
27
- Spree::DummyGeneratorHelper.inject_extension_requirements = true
28
- Spree::DummyGenerator.start ["--lib_name=spree_cm_commissioner", '--quiet']
29
- Spree::InstallGenerator.start [
30
- "--lib_name=spree_cm_commissioner",
31
- '--auto-accept',
32
- '--migrate=false',
33
- '--seed=false',
34
- '--sample=false',
35
- '--quiet',
36
- '--copy_storefront=false',
37
- "--install_storefront=false",
38
- "--install_admin=false",
39
- "--user_class=Spree::User"
40
- ]
41
-
42
- puts 'Setting up dummy database...'
43
- system('bin/rails db:environment:set RAILS_ENV=test')
44
- system('bundle exec rake db:drop db:create')
45
- Spree::DummyModelGenerator.start
46
- system('bundle exec rake db:migrate')
47
-
48
- puts 'Running extension installation generator...'
49
- SpreeCmCommissioner::Generators::InstallGenerator.start(['--auto-run-migrations'])
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'spree_cm_commissioner'
20
+ Rake::Task['extension:test_app'].invoke
50
21
  end
@@ -0,0 +1,32 @@
1
+ module Spree
2
+ module Admin
3
+ module CmsPagesControllerDecorator
4
+ def scope
5
+ return Spree::CmsPage.none unless current_store&.cms_pages
6
+
7
+ scope = current_store.cms_pages
8
+
9
+ case params[:tab]
10
+ when 'default'
11
+ scope = scope.where(tenant_id: nil)
12
+ when 'tenants'
13
+ scope = if params[:tenant_id].present?
14
+ scope.where(tenant_id: params[:tenant_id])
15
+ else
16
+ scope.where.not(tenant_id: nil)
17
+ end
18
+ end
19
+
20
+ scope
21
+ end
22
+
23
+ def permitted_resource_params
24
+ super.merge(tenant_id: params[:cms_page][:tenant_id])
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ unless Spree::Admin::CmsPagesController.included_modules.include?(Spree::Admin::CmsPagesControllerDecorator)
31
+ Spree::Admin::CmsPagesController.prepend(Spree::Admin::CmsPagesControllerDecorator)
32
+ end
@@ -49,6 +49,8 @@ module Spree
49
49
  place_json = Base64.strict_decode64(place_base_64_content)
50
50
  place_hash = JSON.parse(place_json)
51
51
 
52
+ place_hash = place_hash.except('lft', 'rgt', 'parent_id', 'depth')
53
+
52
54
  @place = SpreeCmCommissioner::Place.where(reference: place_hash['reference']).first_or_initialize do |place|
53
55
  place.assign_attributes(place_hash)
54
56
  end
@@ -5,8 +5,6 @@ module Spree
5
5
 
6
6
  before_action :load_parent
7
7
 
8
- helper_method :inventory_item_message
9
-
10
8
  def load_parent
11
9
  @product = Spree::Product.find_by(slug: params[:product_id])
12
10
  end
@@ -14,58 +12,9 @@ module Spree
14
12
  def index
15
13
  @variants = @product.variants.includes(:images, stock_items: :stock_location, option_values: :option_type)
16
14
  @variants = [@product.master] if @variants.empty?
17
- @stock_locations = (@variants.flat_map(&:stock_locations) + @product.vendor.stock_locations).uniq
18
-
19
- load_inventories unless @product.permanent_stock?
20
- end
21
-
22
- def create
23
- result = SpreeCmCommissioner::Stock::StockMovementCreator.call(
24
- variant_id: params[:variant_id],
25
- stock_location_id: params[:stock_location_id],
26
- current_store: current_store,
27
- stock_movement_params: stock_movement_params
28
- )
29
-
30
- if result.success?
31
- flash[:success] = flash_message_for(result.stock_movement, :successfully_created)
32
- else
33
- flash[:error] = result.message
34
- end
35
-
36
- redirect_back fallback_location: admin_product_stock_managements_path(@product)
37
- end
38
-
39
- def calendar
40
- @year = params[:year].present? ? params[:year].to_i : Time.zone.today.year
41
15
 
42
- from_date = Date.new(@year, 1, 1).beginning_of_year
43
- to_date = Date.new(@year, 1, 1).end_of_year
44
-
45
- @inventory_items = @product.inventory_items.includes(:variant).where(inventory_date: from_date..to_date).to_a
46
- @cached_inventory_items = ::SpreeCmCommissioner::RedisStock::CachedInventoryItemsBuilder.new(@inventory_items)
47
- .call
48
- .index_by(&:inventory_item_id)
49
- @events = SpreeCmCommissioner::CalendarEvent.from_inventory_items(@inventory_items)
50
- end
51
-
52
- def inventory_item_message(inventory_item, cached_inventory_item)
53
- synced = inventory_item.quantity_available == cached_inventory_item.quantity_available
54
-
55
- if synced
56
- "Synced: Quantity available matches in both DB and Redis (#{cached_inventory_item.quantity_available})."
57
- else
58
- "Out of sync: Redis shows #{cached_inventory_item.quantity_available} available, which doesn't match the database."
59
- end
60
- end
61
-
62
- private
16
+ @stock_locations = (@variants.flat_map(&:stock_locations) + @product.vendor.stock_locations).uniq
63
17
 
64
- def load_inventories
65
- @inventory_items = @product.inventory_items.group_by { |item| item.variant.id }
66
- @cached_inventory_items = ::SpreeCmCommissioner::RedisStock::CachedInventoryItemsBuilder.new(@product.inventory_items)
67
- .call
68
- .index_by(&:inventory_item_id)
69
18
  @reserved_stocks = Spree::LineItem
70
19
  .complete
71
20
  .where(variant_id: @variants.pluck(:id))
@@ -76,16 +25,6 @@ module Spree
76
25
  def model_class
77
26
  Spree::StockItem
78
27
  end
79
-
80
- # This method processes the parameters for stock movement creation.
81
- # Expected attributes for `stock_movement` include:
82
- # - :quantity (Integer): The quantity of stock to move.
83
- # - :action (String): The type of stock movement (e.g., "add" or "remove").
84
- # - :originator_id, :originator_ty (String, optional): The ID and type of the entity creating the stock movement.
85
- # Ensure that `permitted_stock_movement_attributes` is updated to reflect any changes.
86
- def stock_movement_params
87
- params.require(:stock_movement).permit(permitted_stock_movement_attributes)
88
- end
89
28
  end
90
29
  end
91
30
  end
@@ -0,0 +1,70 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Organizer
5
+ class InviteGuestsController < ::Spree::Api::V2::Organizer::BaseController
6
+ before_action :load_invite_guest_by_token, only: :show
7
+ before_action :load_invite_guest, :assign_line_item_data, only: :update
8
+
9
+ def show
10
+ render_serialized_payload { serialize_resource(@invite_guest) }
11
+ end
12
+
13
+ def update
14
+ return render_error(:revoked) if @invite_guest.revoked?
15
+ return render_error(:closed) if @invite_guest.expired?
16
+ return render_error(:fully_claimed) if @invite_guest.fully_claimed?
17
+
18
+ guest = @line_item.guests.new(guest_params)
19
+
20
+ if guest.save
21
+ @invite_guest.update(claimed_status: :claimed) if @line_item.guests.count == @invite_guest.quantity
22
+ render json: SpreeCmCommissioner::V2::Storefront::GuestSerializer.new(guest.reload).serializable_hash
23
+ else
24
+ render_error_payload(guest.errors.full_messages.to_sentence)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def load_invite_guest_by_token
31
+ @invite_guest = SpreeCmCommissioner::InviteGuest.find_by(token: params[:id])
32
+ rescue ActiveRecord::RecordNotFound
33
+ render_error_payload(I18n.t('invite.url_not_found'))
34
+ end
35
+
36
+ def load_invite_guest
37
+ @invite_guest = SpreeCmCommissioner::InviteGuest.find(params[:id])
38
+ end
39
+
40
+ def assign_line_item_data
41
+ @line_item = @invite_guest.order.line_items.first
42
+ @guests = @line_item.guests
43
+ end
44
+
45
+ def render_error(message)
46
+ render json: { errors: message }
47
+ end
48
+
49
+ def guest_params
50
+ params.require(:invite_guest).permit(
51
+ :first_name,
52
+ :last_name,
53
+ :dob,
54
+ :gender,
55
+ :age,
56
+ :emergency_contact,
57
+ :phone_number,
58
+ :address,
59
+ :other_organization
60
+ )
61
+ end
62
+
63
+ def resource_serializer
64
+ ::Spree::V2::Organizer::InviteGuestSerializer
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -5,38 +5,55 @@ module Spree
5
5
  class AccommodationsController < ::Spree::Api::V2::ResourceController
6
6
  private
7
7
 
8
- # override
9
8
  def collection
10
- @collection ||= SpreeCmCommissioner::Accommodations::Find.new(
11
- from_date: params[:from_date]&.to_date,
12
- to_date: params[:to_date]&.to_date,
13
- state_id: params[:province_id],
14
- number_of_adults: params[:adult].to_i,
15
- number_of_kids: params[:children].to_i
16
- ).execute
9
+ @collection ||= collection_finder.call(params: params).value
10
+ end
11
+
12
+ def paginated_collection
13
+ return @paginated_collection if defined?(@paginated_collection)
14
+
15
+ @paginated_collection = super
16
+ @paginated_collection = apply_service_availability(@paginated_collection)
17
17
  end
18
18
 
19
- # override
20
19
  def resource
21
- @resource ||= collection.find(params[:id])
20
+ resource = resource_finder.call(params: params).value
21
+ raise ActiveRecord::RecordNotFound if resource.nil?
22
+
23
+ apply_service_availability(resource)
24
+ end
25
+
26
+ def apply_service_availability(resource)
27
+ SpreeCmCommissioner::ApplyServiceAvailability.call(calendarable: resource,
28
+ from_date: params[:from_date].to_date,
29
+ to_date: params[:to_date].to_date
30
+ ).value
22
31
  end
23
32
 
24
- # override
25
33
  def allowed_sort_attributes
26
34
  super << :min_price << :max_price
27
35
  end
28
36
 
29
- # override
37
+ def model_class
38
+ Spree::Vendor
39
+ end
40
+
30
41
  def resource_serializer
31
42
  Spree::V2::Storefront::AccommodationSerializer
32
43
  end
33
44
 
34
- # override
35
45
  def collection_serializer
36
46
  Spree::V2::Storefront::AccommodationSerializer
37
47
  end
38
48
 
39
- # override
49
+ def collection_finder
50
+ SpreeCmCommissioner::AccommodationSearchDetail
51
+ end
52
+
53
+ def resource_finder
54
+ SpreeCmCommissioner::AccommodationSearchDetail
55
+ end
56
+
40
57
  def required_schema
41
58
  SpreeCmCommissioner::AccommodationRequestSchema
42
59
  end
@@ -12,9 +12,9 @@ module Spree
12
12
  spree_authorize! :update, spree_current_order, order_token
13
13
  spree_authorize! :show, @variant
14
14
 
15
- availability_checker = SpreeCmCommissioner::Stock::AvailabilityChecker.new(@variant, add_item_params[:options])
15
+ availability_checker = SpreeCmCommissioner::Stock::AvailabilityChecker.new(@variant)
16
16
 
17
- unless availability_checker.can_supply?(add_item_params[:quantity].to_i)
17
+ unless availability_checker.can_supply?(add_item_params[:quantity].to_i, add_item_params[:options])
18
18
  return render_error_payload(availability_checker.error_message || I18n.t('variant_availability.items_out_of_stock'))
19
19
  end
20
20
 
@@ -11,6 +11,7 @@ module Spree
11
11
 
12
12
  def create
13
13
  context = SpreeCmCommissioner::WaitingRoomSessionCreator.call(
14
+ tenant_id: nil,
14
15
  remote_ip: request.remote_ip,
15
16
  waiting_guest_firebase_doc_id: params[:waiting_guest_firebase_doc_id],
16
17
  page_path: params[:page_path]
@@ -14,7 +14,7 @@ module Spree
14
14
  end
15
15
 
16
16
  def filter_params
17
- params.permit(:login, :locale, :format)
17
+ params.permit(:login, :locale, :format).merge(tenant_id: MultiTenant.current_tenant_id)
18
18
  end
19
19
  end
20
20
  end
@@ -4,7 +4,7 @@ module Spree
4
4
  module Tenant
5
5
  class AccountRecoversController < BaseController
6
6
  def update
7
- context = SpreeCmCommissioner::AccountRecover.call(**filter_params.slice(:id_token, :login, :password))
7
+ context = SpreeCmCommissioner::AccountRecover.call(**filter_params.slice(:id_token, :login, :password, :tenant_id))
8
8
  if context.success?
9
9
  render json: { message: 'Account Recovered successfully' }, status: :ok
10
10
  else
@@ -15,7 +15,7 @@ module Spree
15
15
  private
16
16
 
17
17
  def filter_params
18
- params.permit(:id_token, :login, :password)
18
+ params.permit(:id_token, :login, :password).merge(tenant_id: MultiTenant.current_tenant_id)
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class CmsPagesController < BaseController
6
+ private
7
+
8
+ def model_class
9
+ Spree::CmsPage
10
+ end
11
+
12
+ def resource
13
+ @resource ||= scope.find_by(slug: params[:id]) || scope.find(params[:id])
14
+ end
15
+
16
+ def resource_serializer
17
+ Spree::Api::Dependencies.storefront_cms_page_serializer.constantize
18
+ end
19
+
20
+ def collection_serializer
21
+ Spree::Api::Dependencies.storefront_cms_page_serializer.constantize
22
+ end
23
+
24
+ def collection_finder
25
+ Spree::Api::Dependencies.storefront_cms_page_finder.constantize
26
+ end
27
+
28
+ def scope
29
+ model_class.by_locale(I18n.locale).where(tenant_id: MultiTenant.current_tenant_id)
30
+ end
31
+
32
+ def scope_includes
33
+ {
34
+ cms_sections: :linked_resource
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -26,7 +26,7 @@ module Spree
26
26
  :pin_code_token,
27
27
  :password,
28
28
  :password_confirmation
29
- )
29
+ ).merge(tenant_id: MultiTenant.current_tenant_id)
30
30
  end
31
31
  end
32
32
  end