spree_cm_commissioner 2.5.0.pre.pre8 → 2.5.0.pre.pre10

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/.bundle/config +3 -2
  3. data/.github/workflows/test_and_build_gem.yml +123 -57
  4. data/.tool-versions +1 -1
  5. data/Gemfile.lock +1 -1
  6. data/Rakefile +55 -29
  7. data/app/controllers/spree/admin/base_controller_decorator.rb +3 -3
  8. data/app/controllers/spree/admin/base_import_orders_controller.rb +6 -1
  9. data/app/controllers/spree/admin/classifications_controller.rb +1 -1
  10. data/app/controllers/spree/admin/integration_mappings_controller.rb +21 -0
  11. data/app/controllers/spree/admin/integration_sessions_controller.rb +21 -0
  12. data/app/controllers/spree/admin/integrations_controller.rb +83 -0
  13. data/app/controllers/spree/admin/notification_sender_controller.rb +1 -1
  14. data/app/controllers/spree/api/v2/storefront/event_matches_controller.rb +15 -0
  15. data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +6 -6
  16. data/app/controllers/spree/api/v2/storefront/trips_controller.rb +11 -0
  17. data/app/errors/spree_cm_commissioner/integrations/external_client_error.rb +10 -0
  18. data/app/errors/spree_cm_commissioner/integrations/sync_error.rb +4 -0
  19. data/app/finders/spree_cm_commissioner/events/find_matches.rb +15 -0
  20. data/app/helpers/spree_cm_commissioner/external_integrations_helper.rb +58 -0
  21. data/app/interactors/spree_cm_commissioner/create_event.rb +1 -1
  22. data/app/interactors/spree_cm_commissioner/customer_notification_cron_executor.rb +1 -1
  23. data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +1 -1
  24. data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +3 -2
  25. data/app/jobs/spree_cm_commissioner/conversion_pre_calculator_job.rb +2 -2
  26. data/app/jobs/spree_cm_commissioner/customer_notification_sender_job.rb +3 -3
  27. data/app/jobs/spree_cm_commissioner/enqueue_cart/add_item_job.rb +7 -7
  28. data/app/jobs/spree_cm_commissioner/ensure_event_for_product_line_item_guests_job.rb +1 -1
  29. data/app/jobs/spree_cm_commissioner/event_line_items_date_syncer_job.rb +2 -2
  30. data/app/jobs/spree_cm_commissioner/export_csv_job.rb +2 -2
  31. data/app/jobs/spree_cm_commissioner/import_order_job.rb +5 -5
  32. data/app/jobs/spree_cm_commissioner/integrations/base_job.rb +39 -0
  33. data/app/jobs/spree_cm_commissioner/integrations/polling_job.rb +53 -0
  34. data/app/jobs/spree_cm_commissioner/integrations/polling_scheduler_job.rb +30 -0
  35. data/app/jobs/spree_cm_commissioner/invalidate_cache_request_job.rb +2 -2
  36. data/app/jobs/spree_cm_commissioner/inventory_item_syncer_job.rb +8 -2
  37. data/app/jobs/spree_cm_commissioner/option_type_variants_public_metadata_updater_job.rb +7 -3
  38. data/app/jobs/spree_cm_commissioner/option_value_variants_public_metadata_updater_job.rb +6 -2
  39. data/app/jobs/spree_cm_commissioner/order_complete_telegram_sender_job.rb +2 -2
  40. data/app/jobs/spree_cm_commissioner/product_event_id_to_children_syncer_job.rb +2 -2
  41. data/app/jobs/spree_cm_commissioner/reports_assigner_job.rb +2 -2
  42. data/app/jobs/spree_cm_commissioner/sms_pin_code_job.rb +1 -1
  43. data/app/jobs/spree_cm_commissioner/state_job.rb +2 -2
  44. data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +6 -3
  45. data/app/jobs/spree_cm_commissioner/stock/inventory_items_generator_job.rb +2 -2
  46. data/app/jobs/spree_cm_commissioner/telegram_alerts/integration_sync_failure_job.rb +17 -0
  47. data/app/jobs/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_job.rb +2 -2
  48. data/app/jobs/spree_cm_commissioner/transit/route_order_count_incrementer_job.rb +2 -2
  49. data/app/jobs/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_job.rb +2 -2
  50. data/app/jobs/spree_cm_commissioner/transit/route_trip_count_decrementer_job.rb +2 -2
  51. data/app/jobs/spree_cm_commissioner/transit/route_trip_count_incrementer_job.rb +2 -2
  52. data/app/jobs/spree_cm_commissioner/vendor_creation_telegram_alert_sender_job.rb +2 -2
  53. data/app/jobs/spree_cm_commissioner/vendor_job.rb +2 -2
  54. data/app/jobs/spree_cm_commissioner/waiting_room_session_firebase_logger_job.rb +1 -1
  55. data/app/models/concerns/spree_cm_commissioner/integrations/integration_mappable.rb +61 -0
  56. data/app/models/concerns/spree_cm_commissioner/line_item_integration.rb +36 -0
  57. data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +16 -4
  58. data/app/models/concerns/spree_cm_commissioner/option_value_attr_type.rb +1 -1
  59. data/app/models/concerns/spree_cm_commissioner/order_integration.rb +33 -0
  60. data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +4 -2
  61. data/app/models/concerns/spree_cm_commissioner/store_metadata.rb +14 -2
  62. data/app/models/concerns/spree_cm_commissioner/variant_options_concern.rb +1 -7
  63. data/app/models/spree_cm_commissioner/export.rb +1 -1
  64. data/app/models/spree_cm_commissioner/guest.rb +13 -0
  65. data/app/models/spree_cm_commissioner/integration.rb +29 -0
  66. data/app/models/spree_cm_commissioner/integration_mapping.rb +41 -0
  67. data/app/models/spree_cm_commissioner/integration_sync_session.rb +15 -0
  68. data/app/models/spree_cm_commissioner/integrations/stadium_x_v1.rb +37 -0
  69. data/app/models/spree_cm_commissioner/inventory_item.rb +5 -1
  70. data/app/models/spree_cm_commissioner/line_item_decorator.rb +13 -1
  71. data/app/models/spree_cm_commissioner/option_type_decorator.rb +8 -0
  72. data/app/models/spree_cm_commissioner/option_value_decorator.rb +34 -0
  73. data/app/models/spree_cm_commissioner/order_decorator.rb +1 -0
  74. data/app/models/spree_cm_commissioner/product_decorator.rb +4 -3
  75. data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +2 -2
  76. data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +6 -3
  77. data/app/models/spree_cm_commissioner/stock_item_decorator.rb +4 -4
  78. data/app/models/spree_cm_commissioner/taxon_decorator.rb +2 -1
  79. data/app/models/spree_cm_commissioner/taxonomy_decorator.rb +13 -1
  80. data/app/models/spree_cm_commissioner/variant_decorator.rb +7 -4
  81. data/app/models/spree_cm_commissioner/vendor_decorator.rb +6 -2
  82. data/app/overrides/spree/admin/shared/sub_menu/_integrations/external_integrations.html.erb.deface +6 -0
  83. data/app/presenters/spree/variants/{visable_options_presenter.rb → visible_options_presenter.rb} +2 -4
  84. data/app/serializers/spree_cm_commissioner/v2/storefront/trip_serializer.rb +1 -1
  85. data/app/services/spree_cm_commissioner/integrations/base/sync_manager.rb +69 -0
  86. data/app/services/spree_cm_commissioner/integrations/base/sync_result.rb +183 -0
  87. data/app/services/spree_cm_commissioner/integrations/polling.rb +70 -0
  88. data/app/services/spree_cm_commissioner/integrations/polling_scheduler.rb +79 -0
  89. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/external_client/client.rb +152 -0
  90. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/inventory/unstock_inventory.rb +83 -0
  91. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_matches.rb +113 -0
  92. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/polling/sync_zones.rb +215 -0
  93. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/base.rb +20 -0
  94. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/league.rb +19 -0
  95. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/match.rb +95 -0
  96. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/ticket.rb +81 -0
  97. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/ticket_image.rb +19 -0
  98. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/resources/zone.rb +90 -0
  99. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_manager.rb +35 -0
  100. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/full_sync_strategy.rb +38 -0
  101. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/incremental_sync_strategy.rb +44 -0
  102. data/app/services/spree_cm_commissioner/integrations/stadium_x_v1/sync_strategies/webhook_sync_strategy.rb +16 -0
  103. data/app/services/spree_cm_commissioner/telegram_alerts/integration_sync_failure.rb +49 -0
  104. data/app/views/spree/admin/integration_mappings/_integration_mappings.html.erb +107 -0
  105. data/app/views/spree/admin/integration_mappings/index.html.erb +33 -0
  106. data/app/views/spree/admin/integration_sessions/_integration_sync_sessions.html.erb +116 -0
  107. data/app/views/spree/admin/integration_sessions/index.html.erb +42 -0
  108. data/app/views/spree/admin/integrations/_form.html.erb +104 -0
  109. data/app/views/spree/admin/integrations/_stadium_x_v1_fields.html.erb +29 -0
  110. data/app/views/spree/admin/integrations/edit.html.erb +45 -0
  111. data/app/views/spree/admin/integrations/index.html.erb +75 -0
  112. data/app/views/spree/admin/integrations/new.html.erb +25 -0
  113. data/bin/run_spec_group +101 -0
  114. data/config/locales/en.yml +8 -0
  115. data/config/locales/km.yml +8 -0
  116. data/config/routes.rb +8 -0
  117. data/db/migrate/20251017094845_create_cm_integrations.rb +22 -0
  118. data/db/migrate/20251017101555_create_cm_integration_sync_sessions.rb +68 -0
  119. data/db/migrate/20251017101605_create_cm_integration_mappings.rb +52 -0
  120. data/lib/cm_app_logger.rb +36 -4
  121. data/lib/spree_cm_commissioner/test_helper/factories/integration_factory.rb +25 -0
  122. data/lib/spree_cm_commissioner/test_helper/factories/integration_mapping_factory.rb +14 -0
  123. data/lib/spree_cm_commissioner/test_helper/factories/integration_sync_session_factory.rb +7 -0
  124. data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -0
  125. data/lib/spree_cm_commissioner/test_helper/factories/vendor_place_factory.rb +3 -2
  126. data/lib/spree_cm_commissioner/version.rb +1 -1
  127. data/lib/spree_cm_commissioner.rb +8 -7
  128. metadata +58 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 538969bdcdc4e74a70c795d9355b5c49357852b362d0534d208098434dcc8558
4
- data.tar.gz: 14329cc3a2c2e8b0ae754057f65c6175c16e6f3251b9d16cd589efe64460ebde
3
+ metadata.gz: b5cbbf00c2631fe710fb1ea7860ddb1f932dcbdd77f266104f9a51ceffbebc70
4
+ data.tar.gz: cd934346b3bc288b68ff82410a19ebf40809f88d66562539fd6d08770b69b1b3
5
5
  SHA512:
6
- metadata.gz: 8f989e81e1e4fc89004874ac6fe64535b450aeff5d709127e125339c0a71f5f4fd35eb344722354950fb72c28dbd751325b4b9c44ac3acb73c3ea6473626bdca
7
- data.tar.gz: 624b7a73bf7ac18e24a60de96e284a6c1f336d3efbc3d818cbcdb0bda0e1839a9107e9264af5924c934d0e383bac7093db07b88e3ab0543bf0e6512a1f46d3d0
6
+ metadata.gz: 6550f4205c95a6f33b6619f8d3184307c9a0a99801db530124f97f973da7978d40f089f6444e984ff0d1c725492eb734cf0df59b774ed23992a7a17fbf2bf2d9
7
+ data.tar.gz: 49ec91822b20df7d0b939dee101125f7d344fe96972f57c9b93aeccdf96a22fb0edc688cbc052e171d9452684daeee9b54e72934d6206beb29f7ec972ba285d7
data/.bundle/config CHANGED
@@ -1,3 +1,4 @@
1
1
  ---
2
- BUNDLE_RETRY: "3"
3
- BUNDLE_JOBS: "4"
2
+ BUNDLE_PATH: "/home/runner/work/commissioner/commissioner/vendor/bundle"
3
+ BUNDLE_DEPLOYMENT: "true"
4
+ BUNDLE_JOBS: "2"
@@ -5,12 +5,11 @@ on:
5
5
  pull_request:
6
6
  types:
7
7
  - opened
8
- - edited
9
8
  - synchronize
10
9
  - reopened
11
10
  branches:
12
11
  - develop
13
- - milestone-77-scalable-design
12
+ - "*-milestone" # matches any branch with suffix *-milestone, eg. external-integration-milestone
14
13
  push:
15
14
  tags:
16
15
  - "*"
@@ -20,7 +19,7 @@ jobs:
20
19
 
21
20
  steps:
22
21
  - name: Check PR title format
23
- if: github.event_name == 'pull_request'
22
+ if: github.event_name == 'pull_request' && !contains(github.head_ref, '-milestone')
24
23
  uses: actions/github-script@v7
25
24
  with:
26
25
  script: |
@@ -38,8 +37,7 @@ jobs:
38
37
  console.log("PR title format is correct.");
39
38
  }
40
39
  - name: Check commit messages format
41
- # skip validation if the PR is from the milestone-77-scalable-design branch for temporary
42
- if: github.event_name == 'pull_request' && github.head_ref != 'milestone-77-scalable-design'
40
+ if: github.event_name == 'pull_request' && !contains(github.head_ref, '-milestone')
43
41
  uses: actions/github-script@v7
44
42
  with:
45
43
  script: |
@@ -71,7 +69,7 @@ jobs:
71
69
  console.log("All commit messages are correctly formatted.");
72
70
  }
73
71
  - name: Check for unresolved review threads
74
- if: github.event_name == 'pull_request'
72
+ if: github.event_name == 'pull_request' && !contains(github.head_ref, '-milestone')
75
73
  uses: actions/github-script@v7
76
74
  with:
77
75
  script: |
@@ -117,9 +115,8 @@ jobs:
117
115
  console.log("✅ All review threads are resolved.");
118
116
  }
119
117
 
120
- test_and_build_gem:
118
+ setup:
121
119
  needs: [validate-commits]
122
- # if: github.head_ref != '2572-enforce-pr-workflow' || github.base_ref != 'develop'
123
120
  runs-on: ubuntu-latest
124
121
 
125
122
  services:
@@ -152,22 +149,10 @@ jobs:
152
149
  steps:
153
150
  - uses: actions/checkout@v3
154
151
 
155
- # - uses: borales/actions-yarn@v2.0.0
156
- # with:
157
- # cmd: install
158
-
159
152
  - uses: ruby/setup-ruby@v1
160
153
  with:
161
154
  ruby-version: "3.2.0"
162
-
163
- # bundle-cache might cause problem when upgrading ruby. Disable it when upgrading to solve the problem.
164
- # bundler-cache: true
165
-
166
- - name: Install dependencies
167
- run: |
168
- sudo apt-get -yqq install libpq-dev
169
- gem install bundler
170
- bundle install --jobs 4 --retry 3
155
+ bundler-cache: true
171
156
 
172
157
  - name: Quality
173
158
  env:
@@ -181,56 +166,137 @@ jobs:
181
166
  run: |
182
167
  bundle exec brakeman
183
168
 
184
- - name: Run test
169
+ test:
170
+ needs: [setup]
171
+ runs-on: ubuntu-latest
172
+ if: github.event_name == 'pull_request'
173
+
174
+ strategy:
175
+ fail-fast: false
176
+ matrix:
177
+ spec_group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
178
+
179
+ services:
180
+ db:
181
+ image: postgres:12
182
+ env:
183
+ POSTGRES_HOST_AUTH_METHOD: trust
184
+ POSTGRES_USER: myuser
185
+ POSTGRES_PASSWORD: mypassword
186
+ POSTGRES_DB: test_db
187
+ ports: ["5432:5432"]
188
+ options: >-
189
+ --health-cmd pg_isready
190
+ --health-interval 10s
191
+ --health-timeout 5s
192
+ --health-retries 5
193
+
194
+ redis:
195
+ image: redis
196
+ options: >-
197
+ --health-cmd "redis-cli ping"
198
+ --health-interval 10s
199
+ --health-timeout 5s
200
+ --health-retries 5
201
+ ports:
202
+ - 6379:6379
203
+
204
+ steps:
205
+ - uses: actions/checkout@v3
206
+
207
+ - name: Install system dependencies
208
+ run: |
209
+ sudo apt-get update -qq
210
+ sudo apt-get install -yqq libpq-dev
211
+
212
+ - uses: ruby/setup-ruby@v1
213
+ with:
214
+ ruby-version: "3.2.0"
215
+ bundler-cache: true
216
+
217
+ # Cache Strategy: Speed up test runs by ~40 seconds
218
+ # ================================================
219
+ # We split test app setup into 2 parts:
220
+ # 1. Generate files (slow ~40s, cacheable) - rake test_app:generate
221
+ # 2. Setup database (fast ~20s, always run) - rake test_app:db
222
+ #
223
+ # Cache Key: test-app-{OS}-{hash of Gemfile.lock + db/migrate files}
224
+ # - If Gemfile.lock or migrations change → new cache key → regenerate files
225
+ # - If unchanged → restore cached spec/dummy → skip generation
226
+ #
227
+ # Example:
228
+ # First run: Generate files (40s) + Setup DB (20s) = 60s total
229
+ # Cache hit: Restore cache (5s) + Setup DB (20s) = 25s total
230
+ # Savings: ~35-40 seconds per test job (10 parallel jobs = 350-400s saved!)
231
+ #
232
+ # What's cached: spec/dummy directory containing:
233
+ # - Generated Rails app files
234
+ # - Spree installation files
235
+ # - Extension installation files
236
+ # - Config files (database.yml, routes.rb, etc.)
237
+ #
238
+ # What's NOT cached (always regenerated):
239
+ # - Database itself (PostgreSQL data)
240
+ # - Test results
241
+ # - Coverage reports
242
+ - name: Cache test app files
243
+ uses: actions/cache@v3
244
+ with:
245
+ path: spec/dummy
246
+ key: test-app-${{ runner.os }}-${{ hashFiles('Gemfile.lock', 'db/migrate/*.rb') }}
247
+ restore-keys: |
248
+ test-app-${{ runner.os }}-
249
+
250
+ # Generate dummy Rails app for testing (cacheable part)
251
+ # This step checks if spec/dummy exists and skips generation if found
252
+ # Defined in: gems/spree_cm_commissioner/Rakefile (test_app:generate task)
253
+ - name: Generate test app files
185
254
  env:
186
255
  DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
187
256
  REDIS_URL: redis://localhost:6379/0
257
+ run: |
258
+ bundle exec rake test_app:generate
188
259
 
189
- if: github.event_name == 'pull_request'
260
+ # Setup database (always runs, fast ~20s)
261
+ # Drops/creates database and runs migrations
262
+ # Defined in: gems/spree_cm_commissioner/Rakefile (test_app:db task)
263
+ - name: Setup database
264
+ env:
265
+ DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
266
+ REDIS_URL: redis://localhost:6379/0
190
267
  run: |
191
- bundle exec rake
192
-
193
- # 2405-build-and-publish-gem
194
- # - name: Rename long migration files
195
- # env:
196
- # DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
197
- # # if: startsWith(github.ref, 'refs/tags/') # Only on tag pushes
198
- # if: github.ref == 'refs/heads/2405-build-and-publish-gem'
199
-
200
- # run: |
201
- # cd db/migrate
202
- # for file in *.rb; do
203
- # if [ ${#file} -gt 60 ]; then # Adjust threshold if needed
204
- # # Extract timestamp (first 14 chars) and shorten the rest
205
- # timestamp=${file:0:14}
206
- # suffix=$(echo "$file" | sed 's/^[0-9]\{14\}_//' | sed 's/\.rb$//')
207
- # short_suffix=$(echo "$suffix" | cut -c1-40) # Limit suffix to 40 chars
208
- # new_name="${timestamp}_${short_suffix}.rb"
209
- # mv "$file" "$new_name"
210
- # echo "Renamed $file to $new_name"
211
- # fi
212
- # done
268
+ bundle exec rake test_app:db
213
269
 
214
- # Build the gem
215
- - name: Build gem
270
+ # Run specs in parallel groups (1-12)
271
+ # Each group runs ~1/12th of total spec files
272
+ # Script: bin/run_spec_group shows which files are in each group
273
+ - name: Run test (Group ${{ matrix.spec_group }}/12)
216
274
  env:
217
275
  DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
276
+ REDIS_URL: redis://localhost:6379/0
277
+ run: |
278
+ bin/run_spec_group ${{ matrix.spec_group }} 12
279
+
280
+ build_and_publish:
281
+ needs: [setup]
282
+ runs-on: ubuntu-latest
283
+ if: startsWith(github.ref, 'refs/tags/')
284
+
285
+ steps:
286
+ - uses: actions/checkout@v3
218
287
 
219
- # if: startsWith(github.ref, 'refs/tags/') # Only on tag pushes
220
- if: |
221
- startsWith(github.ref, 'refs/tags/')
288
+ - uses: ruby/setup-ruby@v1
289
+ with:
290
+ ruby-version: "3.2.0"
291
+ bundler-cache: true
292
+
293
+ # Build the gem
294
+ - name: Build gem
222
295
  run: |
223
296
  gem build *.gemspec
224
297
 
225
298
  # Publish the gem
226
299
  - name: Publish gem
227
- env:
228
- DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
229
-
230
- # if: startsWith(github.ref, 'refs/tags/') # Only on tag pushes
231
- # (github.event_name == 'push' && github.ref == 'refs/heads/2405-build-and-publish-gem')
232
- if: |
233
- startsWith(github.ref, 'refs/tags/')
234
300
  run: |
235
301
  mkdir -p ~/.gem
236
302
  echo ":rubygems_api_key: ${{ secrets.RUBYGEMS_API_KEY }}" > ~/.gem/credentials
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.3.5
1
+ ruby 3.2.0
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (2.5.0.pre.pre8)
37
+ spree_cm_commissioner (2.5.0.pre.pre10)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
data/Rakefile CHANGED
@@ -17,34 +17,60 @@ end
17
17
  # Copied from:
18
18
  # spree_core:lib/spree/testing_support/common_rake.rb
19
19
  # But refactored to skip frontend & backend setup.
20
+
21
+ namespace :test_app do
22
+ desc 'Generate dummy app files (cacheable)'
23
+ task :generate do
24
+ require 'spree_cm_commissioner'
25
+ require "generators/spree_cm_commissioner/install/install_generator"
26
+
27
+ Rails.env = ENV['RAILS_ENV'] = 'test'
28
+
29
+ # Skip if already generated
30
+ if Dir.exist?('spec/dummy') && File.exist?('spec/dummy/config/database.yml')
31
+ puts '✓ Test app files already exist, skipping generation...'
32
+ else
33
+ puts 'Generating test app files...'
34
+ Spree::DummyGeneratorHelper.inject_extension_requirements = true
35
+ Spree::DummyGenerator.start ["--lib_name=spree_cm_commissioner", '--quiet']
36
+ Spree::InstallGenerator.start [
37
+ "--lib_name=spree_cm_commissioner",
38
+ '--auto-accept',
39
+ '--migrate=false',
40
+ '--seed=false',
41
+ '--sample=false',
42
+ '--quiet',
43
+ '--copy_storefront=false',
44
+ "--install_storefront=false",
45
+ "--install_admin=false",
46
+ "--user_class=Spree::User"
47
+ ]
48
+
49
+ puts 'Generating dummy model...'
50
+ Spree::DummyModelGenerator.start
51
+
52
+ puts 'Running extension installation generator...'
53
+ SpreeCmCommissioner::Generators::InstallGenerator.start(['--auto-run-migrations'])
54
+
55
+ puts '✓ Test app files generated'
56
+ end
57
+ end
58
+
59
+ desc 'Setup database'
60
+ task :db do
61
+ Rails.env = ENV['RAILS_ENV'] = 'test'
62
+
63
+ puts 'Setting up dummy database...'
64
+ Dir.chdir('spec/dummy') do
65
+ system('RAILS_ENV=test bundle exec rake db:drop db:create')
66
+ system('RAILS_ENV=test bundle exec rake db:migrate')
67
+ puts '✓ Database setup complete'
68
+ end
69
+ end
70
+ end
71
+
20
72
  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'])
73
+ task :test_app do
74
+ Rake::Task['test_app:generate'].invoke
75
+ Rake::Task['test_app:db'].invoke
50
76
  end
@@ -61,11 +61,11 @@ module Spree
61
61
  api_patterns = api_patterns_map[model]
62
62
 
63
63
  if api_patterns.is_a?(Array)
64
- api_patterns.each { |pattern| SpreeCmCommissioner::InvalidateCacheRequestJob.perform_later(pattern) }
64
+ api_patterns.each { |pattern| SpreeCmCommissioner::InvalidateCacheRequestJob.perform_later(pattern: pattern) }
65
65
  elsif api_patterns.is_a?(String)
66
- SpreeCmCommissioner::InvalidateCacheRequestJob.perform_later(api_patterns)
66
+ SpreeCmCommissioner::InvalidateCacheRequestJob.perform_later(pattern: api_patterns)
67
67
  elsif params[:api_pattern].present?
68
- SpreeCmCommissioner::InvalidateCacheRequestJob.perform_later(params[:api_pattern])
68
+ SpreeCmCommissioner::InvalidateCacheRequestJob.perform_later(pattern: params[:api_pattern])
69
69
  end
70
70
  end
71
71
  redirect_back fallback_location: admin_root_path
@@ -17,7 +17,12 @@ module Spree
17
17
  import_order = build_import_order(name, imported_file)
18
18
 
19
19
  if import_order.save
20
- SpreeCmCommissioner::ImportOrderJob.perform_later(import_order.id, spree_current_user.id, import_order.import_type)
20
+ SpreeCmCommissioner::ImportOrderJob.perform_later(
21
+ import_order_id: import_order.id,
22
+ import_by_user_id: spree_current_user.id,
23
+
24
+ import_type: import_order.import_type
25
+ )
21
26
  flash[:success] = I18n.t('import_orders.success_message')
22
27
  else
23
28
  flash[:error] = I18n.t('import_orders.error_message')
@@ -5,7 +5,7 @@ module Spree
5
5
 
6
6
  def recalculate_conversions
7
7
  @taxon.products.each do |product|
8
- SpreeCmCommissioner::ConversionPreCalculatorJob.perform_later(product.id)
8
+ SpreeCmCommissioner::ConversionPreCalculatorJob.perform_later(product_id: product.id)
9
9
  end
10
10
 
11
11
  flash[:success] = flash_message_for(@taxon, :successfully_updated)
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module Admin
3
+ class IntegrationMappingsController < Spree::Admin::BaseController
4
+ helper SpreeCmCommissioner::ExternalIntegrationsHelper
5
+ before_action :load_integration
6
+
7
+ def index
8
+ @mappings = @integration.integration_mappings
9
+ .order(updated_at: :desc)
10
+ .page(params[:page])
11
+ .per(params[:per_page] || 25)
12
+ end
13
+
14
+ private
15
+
16
+ def load_integration
17
+ @integration ||= SpreeCmCommissioner::Integration.find(params[:integration_id])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module Admin
3
+ class IntegrationSessionsController < Spree::Admin::BaseController
4
+ helper SpreeCmCommissioner::ExternalIntegrationsHelper
5
+ before_action :load_integration
6
+
7
+ def index
8
+ @sync_sessions = @integration.integration_sync_sessions
9
+ .order(created_at: :desc)
10
+ .page(params[:page])
11
+ .per(params[:per_page] || 25)
12
+ end
13
+
14
+ private
15
+
16
+ def load_integration
17
+ @integration ||= SpreeCmCommissioner::Integration.find(params[:integration_id])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,83 @@
1
+ module Spree
2
+ module Admin
3
+ class IntegrationsController < Spree::Admin::ResourceController
4
+ helper SpreeCmCommissioner::ExternalIntegrationsHelper
5
+ before_action :load_form_collections, only: %i[new create edit update]
6
+ before_action :load_integration, only: %i[enqueue_polling]
7
+
8
+ def index
9
+ @integrations = model_class.all
10
+ end
11
+
12
+ def enqueue_polling
13
+ sync_type = params[:sync_type].presence || :full
14
+
15
+ if @integration.active?
16
+ SpreeCmCommissioner::Integrations::PollingJob.perform_later(
17
+ integration_id: @integration.id,
18
+ sync_type: sync_type
19
+ )
20
+ flash[:success] = Spree.t('admin.integration_sync_enqueued')
21
+ else
22
+ flash[:error] = Spree.t('admin.integration_inactive')
23
+ end
24
+
25
+ redirect_to admin_integration_sessions_path(@integration)
26
+ end
27
+
28
+ # override
29
+ def model_class
30
+ SpreeCmCommissioner::Integration
31
+ end
32
+
33
+ # override
34
+ def collection_url(options = {})
35
+ admin_integrations_url(options)
36
+ end
37
+
38
+ private
39
+
40
+ def permitted_resource_params
41
+ params.require(:spree_cm_commissioner_integration).permit(
42
+ :name,
43
+ :type,
44
+ :status,
45
+ :conflict_strategy,
46
+ :incremental_sync_interval_seconds,
47
+ :full_sync_interval_hours,
48
+ :tenant_id,
49
+ :vendor_id,
50
+ public_metadata: {},
51
+ private_metadata: {}
52
+ )
53
+ end
54
+
55
+ def load_integration
56
+ @integration ||= SpreeCmCommissioner::Integration.find(params[:id])
57
+ end
58
+
59
+ def load_form_collections
60
+ @integration_type_options ||= integration_type_options
61
+ @status_options ||= enum_to_options(SpreeCmCommissioner::Integration.statuses)
62
+ @conflict_strategy_options ||= enum_to_options(SpreeCmCommissioner::Integration.conflict_strategies)
63
+ @tenants ||= SpreeCmCommissioner::Tenant.select(:id, :name).order(:name)
64
+ @vendors ||= Spree::Vendor.select(:id, :name).order(:name)
65
+ end
66
+
67
+ def enum_to_options(enum_hash)
68
+ enum_hash.keys.map { |key| [key.humanize, key] }
69
+ end
70
+
71
+ def integration_type_options
72
+ files = Dir[SpreeCmCommissioner::Engine.root.join('app/models/spree_cm_commissioner/integrations/*.rb')]
73
+
74
+ return [[Spree.t(:type), 'SpreeCmCommissioner::Integration']] if files.blank?
75
+
76
+ files.map do |path|
77
+ class_name = "SpreeCmCommissioner::Integrations::#{File.basename(path, '.rb').camelize}"
78
+ [class_name, class_name]
79
+ end.sort_by(&:first)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -5,7 +5,7 @@ module Spree
5
5
  customer_notification_id = params[:notification_id]
6
6
  user_ids = params[:send_all] == 'true' ? nil : params[:user_ids]
7
7
 
8
- SpreeCmCommissioner::CustomerNotificationSenderJob.perform_later(customer_notification_id, user_ids)
8
+ SpreeCmCommissioner::CustomerNotificationSenderJob.perform_later(customer_notification_id: customer_notification_id, user_ids: user_ids)
9
9
 
10
10
  redirect_to admin_customer_notifications_path
11
11
  end
@@ -0,0 +1,15 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Storefront
5
+ class EventMatchesController < TaxonsController
6
+ private
7
+
8
+ def collection_finder
9
+ SpreeCmCommissioner::Events::FindMatches
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -19,12 +19,12 @@ module Spree
19
19
  end
20
20
 
21
21
  job = SpreeCmCommissioner::EnqueueCart::AddItemJob.perform_later(
22
- spree_current_order.id,
23
- @variant.id,
24
- add_item_params[:quantity],
25
- add_item_params[:public_metadata],
26
- add_item_params[:private_metadata],
27
- add_item_params[:options]
22
+ order_id: spree_current_order.id,
23
+ variant_id: @variant.id,
24
+ quantity: add_item_params[:quantity],
25
+ public_metadata: add_item_params[:public_metadata],
26
+ private_metadata: add_item_params[:private_metadata],
27
+ options: add_item_params[:options]
28
28
  )
29
29
 
30
30
  return render_error_payload('Failed to enqueue the job') unless job
@@ -17,6 +17,17 @@ module Spree
17
17
  def resource_serializer
18
18
  SpreeCmCommissioner::V2::Storefront::TripSerializer
19
19
  end
20
+
21
+ # override
22
+ def serializer_params
23
+ super.merge(
24
+ include_details: include_details?
25
+ )
26
+ end
27
+
28
+ def include_details?
29
+ params.fetch(:include_details, 'true') == 'true'
30
+ end
20
31
  end
21
32
  end
22
33
  end
@@ -0,0 +1,10 @@
1
+ module SpreeCmCommissioner::Integrations
2
+ class ExternalClientError < StandardError
3
+ attr_reader :status_code
4
+
5
+ def initialize(message, status_code = nil)
6
+ super(message)
7
+ @status_code = status_code
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,4 @@
1
+ module SpreeCmCommissioner::Integrations
2
+ class SyncError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module SpreeCmCommissioner
2
+ module Events
3
+ class FindMatches < ::Spree::BaseFinder
4
+ # currently, there is no way to determine if an event is a match yet.
5
+ # this finder returns all events that have active integration mappings (synced from external systems like StadiumX)
6
+ # as a temporary workaround to filter out non-match events.
7
+ def execute
8
+ scope.joins(:integration_mappings).where(
9
+ kind: :event,
10
+ integration_mappings: { status: :active }
11
+ ).distinct
12
+ end
13
+ end
14
+ end
15
+ end