spree_cm_commissioner 1.10.0.pre.pre1 → 1.11.0.pre.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test_and_build_gem.yml +131 -100
- data/.vscode/settings.json +1 -1
- data/Gemfile.lock +1 -1
- data/Rakefile +33 -4
- data/app/controllers/spree/admin/stock_managements_controller.rb +39 -0
- data/app/controllers/spree/api/v2/storefront/queue_cart/line_items_controller.rb +2 -2
- data/app/interactors/spree_cm_commissioner/create_event.rb +23 -0
- data/app/interactors/spree_cm_commissioner/ensure_correct_product_type.rb +40 -0
- data/app/interactors/spree_cm_commissioner/stock/inventory_items_adjuster.rb +13 -0
- data/app/interactors/spree_cm_commissioner/stock/permanent_inventory_items_generator.rb +6 -2
- data/app/interactors/spree_cm_commissioner/stock/stock_movement_creator.rb +24 -0
- data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +2 -2
- data/app/jobs/spree_cm_commissioner/ensure_correct_product_type_job.rb +7 -0
- data/app/jobs/spree_cm_commissioner/stock/inventory_items_adjuster_job.rb +11 -0
- data/app/models/concerns/spree_cm_commissioner/option_type_attr_type.rb +3 -2
- data/app/models/concerns/spree_cm_commissioner/product_delegation.rb +1 -3
- data/app/models/spree_cm_commissioner/inventory_item.rb +21 -3
- data/app/models/spree_cm_commissioner/line_item_decorator.rb +16 -6
- data/app/models/spree_cm_commissioner/place.rb +11 -2
- data/app/models/spree_cm_commissioner/product_decorator.rb +8 -2
- data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +14 -2
- data/app/models/spree_cm_commissioner/redis_stock/line_items_cached_inventory_items_builder.rb +2 -8
- data/app/models/spree_cm_commissioner/stock_item_decorator.rb +18 -0
- data/app/models/spree_cm_commissioner/taxon_decorator.rb +11 -0
- data/app/models/spree_cm_commissioner/taxon_option_type.rb +8 -0
- data/app/models/spree_cm_commissioner/taxon_option_value.rb +8 -0
- data/app/models/spree_cm_commissioner/trip.rb +0 -11
- data/app/models/spree_cm_commissioner/trip_connection.rb +1 -0
- data/app/models/spree_cm_commissioner/trip_stop.rb +12 -5
- data/app/models/spree_cm_commissioner/variant_decorator.rb +19 -11
- data/app/models/spree_cm_commissioner/variant_options.rb +0 -14
- data/app/models/spree_cm_commissioner/vendor_stop.rb +2 -1
- data/app/queries/spree_cm_commissioner/trip_query.rb +11 -11
- data/app/queries/spree_cm_commissioner/vendor_stop_place_query.rb +54 -0
- data/app/serializers/spree/v2/tenant/guest_serializer.rb +1 -0
- data/app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb +2 -0
- data/app/views/spree/admin/stock_managements/_events_popover.html.erb +12 -6
- data/app/views/spree/admin/stock_managements/_variant_stock_items.html.erb +3 -1
- data/app/views/spree/admin/stock_managements/calendar.html.erb +6 -3
- data/app/views/spree/admin/stock_managements/index.html.erb +9 -0
- data/config/initializers/spree_permitted_attributes.rb +5 -0
- data/db/migrate/20250418072528_add_nested_set_columns_to_places.rb +10 -0
- data/db/migrate/20250430091742_create_cm_taxon_option_types.rb +9 -0
- data/db/migrate/20250430092928_create_cm_taxon_option_values.rb +9 -0
- data/db/migrate/20250502025848_add_index_to_spree_products.rb +5 -0
- data/db/migrate/20250502030001_add_product_type_to_spree_variants.rb +5 -0
- data/db/migrate/20250502030002_add_product_type_to_spree_line_items.rb +5 -0
- data/db/migrate/20250506092929_add_trip_count_to_cm_vendor_stops.rb +5 -0
- data/lib/generators/spree_cm_commissioner/install/install_generator.rb +11 -3
- data/lib/spree_cm_commissioner/test_helper/factories/homepage_section_relatable_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/inventory_item_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/line_item_factory.rb +1 -1
- data/lib/spree_cm_commissioner/test_helper/factories/place_factory.rb +11 -1
- data/lib/spree_cm_commissioner/test_helper/factories/product_factory.rb +18 -5
- data/lib/spree_cm_commissioner/test_helper/factories/stock_location_factory.rb +2 -2
- data/lib/spree_cm_commissioner/test_helper/factories/variant_factory.rb +12 -1
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_factory.rb +1 -1
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/tasks/ensure_correct_product_type.rake +7 -0
- data/lib/tasks/migrate_and_rebuild_place_hierarchy.rake +9 -0
- data/lib/tasks/update_orphan_root_places.rake +7 -0
- metadata +20 -3
- data/app/models/spree_cm_commissioner/stock_movement_decorator.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c727894cc45a2d005e5c0254542ce6b8bfc054a30fe9d7b9fa6c7dfea61cfc4
|
4
|
+
data.tar.gz: 9d99d30cfc27e987bffda2e0462e91a8cbe4d9a88c44c18dc67df02e947f3278
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51065e106d1939327817aa8c54154d1711faee026b771010c9f104083da88aad01aa2f3ced6383c8f3c952e8c8cfba8035324271ee92548dc2e22449da601bf1
|
7
|
+
data.tar.gz: dbc3410043aea748600477cfdd6724d1916155df35e28b62495a53950475f122eac3bf8b80de97282c82214e60ee880e807629246467ca8872753c519eb4afad
|
@@ -3,96 +3,117 @@ name: Commissioner Gem
|
|
3
3
|
|
4
4
|
on:
|
5
5
|
pull_request:
|
6
|
+
types:
|
7
|
+
- opened
|
8
|
+
- edited
|
9
|
+
- synchronize
|
10
|
+
- reopened
|
6
11
|
branches:
|
7
12
|
- develop
|
13
|
+
- milestone-77-scalable-design
|
8
14
|
push:
|
9
15
|
tags:
|
10
16
|
- "*"
|
11
17
|
jobs:
|
12
|
-
validate-commits:
|
13
|
-
|
18
|
+
# validate-commits:
|
19
|
+
# runs-on: ubuntu-latest
|
20
|
+
|
21
|
+
# steps:
|
22
|
+
# - name: Check PR title format
|
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
|
+
# uses: actions/github-script@v7
|
41
|
+
# with:
|
42
|
+
# script: |
|
43
|
+
# const pr = context.payload.pull_request;
|
44
|
+
# const commits_url = pr.commits_url;
|
45
|
+
|
46
|
+
# const commits = await github.request(commits_url);
|
47
|
+
# const pattern = /^Close\s+#\d+\s.+/;
|
48
|
+
|
49
|
+
# let invalidCommits = [];
|
50
|
+
|
51
|
+
# for (const commit of commits.data) {
|
52
|
+
# const msg = commit.commit.message.trim();
|
53
|
+
|
54
|
+
# console.log("commit message: ", msg);
|
55
|
+
|
56
|
+
# if (!pattern.test(msg)) {
|
57
|
+
# invalidCommits.push(`- ${msg}`);
|
58
|
+
# }
|
59
|
+
# }
|
60
|
+
|
61
|
+
# if (invalidCommits.length > 0) {
|
62
|
+
# core.setFailed(
|
63
|
+
# `The following commit messages are not in the correct format:\n\n${invalidCommits.join(
|
64
|
+
# '\n'
|
65
|
+
# )}\n\nEach commit message must start with "Close #<issue_number> <message>"`
|
66
|
+
# );
|
67
|
+
# } else {
|
68
|
+
# console.log("All commit messages are correctly formatted.");
|
69
|
+
# }
|
70
|
+
# - name: Check for unresolved review threads
|
71
|
+
# uses: actions/github-script@v7
|
72
|
+
# with:
|
73
|
+
# script: |
|
74
|
+
# const prNumber = context.payload.pull_request.number;
|
75
|
+
# const { owner, repo } = context.repo;
|
76
|
+
|
77
|
+
# const query = `
|
78
|
+
# query($owner: String!, $repo: String!, $prNumber: Int!) {
|
79
|
+
# repository(owner: $owner, name: $repo) {
|
80
|
+
# pullRequest(number: $prNumber) {
|
81
|
+
# reviewThreads(first: 100) {
|
82
|
+
# nodes {
|
83
|
+
# isResolved
|
84
|
+
# comments(first: 1) {
|
85
|
+
# nodes {
|
86
|
+
# body
|
87
|
+
# author {
|
88
|
+
# login
|
89
|
+
# }
|
90
|
+
# }
|
91
|
+
# }
|
92
|
+
# }
|
93
|
+
# }
|
94
|
+
# }
|
95
|
+
# }
|
96
|
+
# }
|
97
|
+
# `;
|
98
|
+
# const variables = { owner, repo, prNumber };
|
99
|
+
# const result = await github.graphql(query, variables);
|
100
|
+
# const threads = result.repository.pullRequest.reviewThreads.nodes;
|
101
|
+
|
102
|
+
# const unresolved = threads.filter(t => !t.isResolved);
|
103
|
+
|
104
|
+
# if (unresolved.length > 0) {
|
105
|
+
# unresolved.forEach(thread => {
|
106
|
+
# const comments = thread.comments.nodes;
|
107
|
+
# if (comments.length > 0) {
|
108
|
+
# console.log(`💬 Comment by ${comments[0].author.login}: ${comments[0].body}`);
|
109
|
+
# }
|
110
|
+
# });
|
111
|
+
# core.setFailed(`❌ There are ${unresolved.length} unresolved review thread(s). Please resolve them before merging.`);
|
112
|
+
# } else {
|
113
|
+
# console.log("✅ All review threads are resolved.");
|
114
|
+
# }
|
14
115
|
|
15
|
-
steps:
|
16
|
-
- name: Check PR title format
|
17
|
-
uses: actions/github-script@v7
|
18
|
-
if: github.event_name == 'pull_request'
|
19
|
-
with:
|
20
|
-
script: |
|
21
|
-
const title = context.payload.pull_request.title.trim();
|
22
|
-
|
23
|
-
console.log("PR title: ", title);
|
24
|
-
|
25
|
-
const pattern = /^Close\s+#\d+\s.+/;
|
26
|
-
|
27
|
-
if (!pattern.test(title)) {
|
28
|
-
core.setFailed(
|
29
|
-
`PR title must start with "Close #issue_number message". Example: Close #123 Add login form`
|
30
|
-
);
|
31
|
-
} else {
|
32
|
-
console.log("PR title format is correct.");
|
33
|
-
}
|
34
|
-
- name: Check commit messages format
|
35
|
-
uses: actions/github-script@v7
|
36
|
-
if: github.event_name == 'pull_request'
|
37
|
-
with:
|
38
|
-
script: |
|
39
|
-
const pr = context.payload.pull_request;
|
40
|
-
const commits_url = pr.commits_url;
|
41
|
-
|
42
|
-
const commits = await github.request(commits_url);
|
43
|
-
const pattern = /^Close\s+#\d+\s.+/;
|
44
|
-
|
45
|
-
let invalidCommits = [];
|
46
|
-
|
47
|
-
for (const commit of commits.data) {
|
48
|
-
const msg = commit.commit.message.trim();
|
49
|
-
|
50
|
-
console.log("commit message: ", msg);
|
51
|
-
|
52
|
-
if (!pattern.test(msg)) {
|
53
|
-
invalidCommits.push(`- ${msg}`);
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
if (invalidCommits.length > 0) {
|
58
|
-
core.setFailed(
|
59
|
-
`The following commit messages are not in the correct format:\n\n${invalidCommits.join(
|
60
|
-
'\n'
|
61
|
-
)}\n\nEach commit message must start with "Close #<issue_number> <message>"`
|
62
|
-
);
|
63
|
-
} else {
|
64
|
-
console.log("All commit messages are correctly formatted.");
|
65
|
-
}
|
66
|
-
- name: Check for unresolved review threads
|
67
|
-
uses: actions/github-script@v7
|
68
|
-
if: github.event_name == 'pull_request'
|
69
|
-
with:
|
70
|
-
script: |
|
71
|
-
const pr = context.payload.pull_request;
|
72
|
-
const owner = context.repo.owner;
|
73
|
-
const repo = context.repo.repo;
|
74
|
-
|
75
|
-
try {
|
76
|
-
const response = await github.rest.pulls.listReviewComments({
|
77
|
-
owner,
|
78
|
-
repo,
|
79
|
-
pull_number: pr.number,
|
80
|
-
per_page: 100
|
81
|
-
});
|
82
|
-
|
83
|
-
const unresolved = response.data.filter(comment => comment.in_reply_to_id && !comment.resolved);
|
84
|
-
|
85
|
-
if (unresolved.length > 0) {
|
86
|
-
core.setFailed(`There are ${unresolved.length} unresolved review comment(s). Please resolve all threads before merging.`);
|
87
|
-
} else {
|
88
|
-
console.log("All review comments are resolved.");
|
89
|
-
}
|
90
|
-
} catch (error) {
|
91
|
-
console.error("Error fetching review comments:", error.message);
|
92
|
-
core.setFailed("Failed to check for unresolved review threads.");
|
93
|
-
}
|
94
116
|
test_and_build_gem:
|
95
|
-
needs: [validate-commits]
|
96
117
|
# if: github.head_ref != '2572-enforce-pr-workflow' || github.base_ref != 'develop'
|
97
118
|
runs-on: ubuntu-latest
|
98
119
|
|
@@ -112,6 +133,17 @@ jobs:
|
|
112
133
|
--health-timeout 5s
|
113
134
|
--health-retries 5
|
114
135
|
|
136
|
+
redis:
|
137
|
+
image: redis
|
138
|
+
# Set health checks to wait until redis has started
|
139
|
+
options: >-
|
140
|
+
--health-cmd "redis-cli ping"
|
141
|
+
--health-interval 10s
|
142
|
+
--health-timeout 5s
|
143
|
+
--health-retries 5
|
144
|
+
ports:
|
145
|
+
- 6379:6379 # Maps port 6379 on service container to the host
|
146
|
+
|
115
147
|
steps:
|
116
148
|
- uses: actions/checkout@v3
|
117
149
|
|
@@ -132,27 +164,26 @@ jobs:
|
|
132
164
|
gem install bundler
|
133
165
|
bundle install --jobs 4 --retry 3
|
134
166
|
|
135
|
-
- name: Quality
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
bundle exec rubocop
|
167
|
+
# - name: Quality
|
168
|
+
# env:
|
169
|
+
# DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
|
170
|
+
# run: |
|
171
|
+
# bundle exec rubocop
|
141
172
|
|
142
|
-
- name: Security
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
bundle exec brakeman
|
173
|
+
# - name: Security
|
174
|
+
# env:
|
175
|
+
# DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
|
176
|
+
# run: |
|
177
|
+
# bundle exec brakeman
|
148
178
|
|
149
|
-
- name: Run test
|
150
|
-
|
151
|
-
|
179
|
+
# - name: Run test
|
180
|
+
# env:
|
181
|
+
# DATABASE_URL: postgres://myuser:mypassword@localhost:5432/test_db
|
182
|
+
# REDIS_URL: redis://localhost:6379/0
|
152
183
|
|
153
|
-
|
154
|
-
|
155
|
-
|
184
|
+
# if: github.event_name == 'pull_request'
|
185
|
+
# run: |
|
186
|
+
# bundle exec rake
|
156
187
|
|
157
188
|
# 2405-build-and-publish-gem
|
158
189
|
# - name: Rename long migration files
|
data/.vscode/settings.json
CHANGED
data/Gemfile.lock
CHANGED
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/
|
5
|
+
require 'spree/testing_support/common_rake'
|
6
6
|
|
7
7
|
RSpec::Core::RakeTask.new
|
8
8
|
|
@@ -14,8 +14,37 @@ 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.
|
17
20
|
desc 'Generates a dummy app for testing'
|
18
|
-
task :test_app do
|
19
|
-
|
20
|
-
|
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'])
|
21
50
|
end
|
@@ -5,6 +5,8 @@ module Spree
|
|
5
5
|
|
6
6
|
before_action :load_parent
|
7
7
|
|
8
|
+
helper_method :inventory_item_message
|
9
|
+
|
8
10
|
def load_parent
|
9
11
|
@product = Spree::Product.find_by(slug: params[:product_id])
|
10
12
|
end
|
@@ -17,6 +19,23 @@ module Spree
|
|
17
19
|
load_inventories unless @product.permanent_stock?
|
18
20
|
end
|
19
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
|
+
|
20
39
|
def calendar
|
21
40
|
@year = params[:year].present? ? params[:year].to_i : Time.zone.today.year
|
22
41
|
|
@@ -24,13 +43,29 @@ module Spree
|
|
24
43
|
to_date = Date.new(@year, 1, 1).end_of_year
|
25
44
|
|
26
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)
|
27
49
|
@events = SpreeCmCommissioner::CalendarEvent.from_inventory_items(@inventory_items)
|
28
50
|
end
|
29
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
|
+
|
30
62
|
private
|
31
63
|
|
32
64
|
def load_inventories
|
33
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)
|
34
69
|
@reserved_stocks = Spree::LineItem
|
35
70
|
.complete
|
36
71
|
.where(variant_id: @variants.pluck(:id))
|
@@ -41,6 +76,10 @@ module Spree
|
|
41
76
|
def model_class
|
42
77
|
Spree::StockItem
|
43
78
|
end
|
79
|
+
|
80
|
+
def stock_movement_params
|
81
|
+
params.require(:stock_movement).permit(permitted_stock_movement_attributes)
|
82
|
+
end
|
44
83
|
end
|
45
84
|
end
|
46
85
|
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)
|
15
|
+
availability_checker = SpreeCmCommissioner::Stock::AvailabilityChecker.new(@variant, add_item_params[:options])
|
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)
|
18
18
|
return render_error_payload(availability_checker.error_message || I18n.t('variant_availability.items_out_of_stock'))
|
19
19
|
end
|
20
20
|
|
@@ -10,6 +10,8 @@ module SpreeCmCommissioner
|
|
10
10
|
assign_prototype
|
11
11
|
create_child_taxon
|
12
12
|
build_home_banner
|
13
|
+
assign_option_types
|
14
|
+
assign_option_values
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
@@ -61,5 +63,26 @@ module SpreeCmCommissioner
|
|
61
63
|
|
62
64
|
context.fail!(message: 'Home banner upload failed') unless banner.persisted?
|
63
65
|
end
|
66
|
+
|
67
|
+
def assign_options(model_class, param_key, foreign_key)
|
68
|
+
return unless params[param_key]
|
69
|
+
|
70
|
+
params[param_key].each do |id|
|
71
|
+
record = model_class.new(
|
72
|
+
taxon_id: @parent_taxon.id,
|
73
|
+
foreign_key => id
|
74
|
+
)
|
75
|
+
|
76
|
+
context.fail!(message: record.errors.full_messages.join(', ')) unless record.save
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def assign_option_types
|
81
|
+
assign_options(SpreeCmCommissioner::TaxonOptionType, :option_type_id, :option_type_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
def assign_option_values
|
85
|
+
assign_options(SpreeCmCommissioner::TaxonOptionValue, :option_value_id, :option_value_id)
|
86
|
+
end
|
64
87
|
end
|
65
88
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
class EnsureCorrectProductType < BaseInteractor
|
3
|
+
def call
|
4
|
+
Spree::Product
|
5
|
+
.left_joins(variants_including_master: %i[inventory_items line_items])
|
6
|
+
.where(
|
7
|
+
'spree_variants.product_type IS NULL OR
|
8
|
+
spree_variants.product_type != spree_products.product_type OR
|
9
|
+
|
10
|
+
cm_inventory_items.product_type IS NULL OR
|
11
|
+
cm_inventory_items.product_type != spree_products.product_type OR
|
12
|
+
|
13
|
+
spree_line_items.product_type IS NULL OR
|
14
|
+
spree_line_items.product_type != spree_products.product_type OR
|
15
|
+
|
16
|
+
spree_products.product_type IS NOT NULL
|
17
|
+
'
|
18
|
+
)
|
19
|
+
.distinct.find_each do |product|
|
20
|
+
sync_product_type_for(product)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def sync_product_type_for(product)
|
25
|
+
product_type = Spree::Variant.product_types[product.product_type]
|
26
|
+
|
27
|
+
product.variants_including_master
|
28
|
+
.where('spree_variants.product_type IS NULL OR spree_variants.product_type != ?', product_type)
|
29
|
+
.update_all(product_type: product_type) # rubocop:disable Rails/SkipsModelValidations
|
30
|
+
|
31
|
+
product.line_items
|
32
|
+
.where('spree_line_items.product_type IS NULL OR spree_line_items.product_type != ?', product_type)
|
33
|
+
.update_all(product_type: product_type) # rubocop:disable Rails/SkipsModelValidations
|
34
|
+
|
35
|
+
product.inventory_items
|
36
|
+
.where('cm_inventory_items.product_type IS NULL OR cm_inventory_items.product_type != ?', product_type)
|
37
|
+
.update_all(product_type: product_type) # rubocop:disable Rails/SkipsModelValidations
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class InventoryItemsAdjuster < BaseInteractor
|
4
|
+
delegate :variant, :quantity, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
variant.inventory_items.active.find_each do |inventory_item|
|
8
|
+
inventory_item.adjust_quantity!(quantity)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -5,6 +5,10 @@ module SpreeCmCommissioner
|
|
5
5
|
|
6
6
|
def variants_per_batch = 1000
|
7
7
|
|
8
|
+
def pre_inventory_days_for(variant)
|
9
|
+
context.pre_inventory_days || variant.pre_inventory_days
|
10
|
+
end
|
11
|
+
|
8
12
|
def call
|
9
13
|
variants.in_batches(of: variants_per_batch) do |batch|
|
10
14
|
generate_inventory_items_for_batch(batch)
|
@@ -31,7 +35,7 @@ module SpreeCmCommissioner
|
|
31
35
|
|
32
36
|
def inventory_dates_for(variant)
|
33
37
|
start_date = Time.zone.tomorrow
|
34
|
-
end_date = Time.zone.today + variant
|
38
|
+
end_date = Time.zone.today + pre_inventory_days_for(variant)
|
35
39
|
|
36
40
|
(start_date..end_date)
|
37
41
|
end
|
@@ -62,7 +66,7 @@ module SpreeCmCommissioner
|
|
62
66
|
end
|
63
67
|
|
64
68
|
def variants
|
65
|
-
scope = Spree::Variant.active.with_permanent_stock.where(is_master: false)
|
69
|
+
scope = Spree::Variant.active.with_permanent_stock.where(is_master: false)
|
66
70
|
scope = scope.where(id: variant_ids) if variant_ids.present?
|
67
71
|
scope
|
68
72
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class StockMovementCreator < BaseInteractor
|
4
|
+
delegate :variant_id, :stock_location_id, :current_store, :stock_movement_params, to: :context
|
5
|
+
|
6
|
+
def call
|
7
|
+
variant = current_store.variants.find(variant_id)
|
8
|
+
|
9
|
+
return context.fail!(message: Spree.t(:doesnt_track_inventory)) unless variant.track_inventory?
|
10
|
+
|
11
|
+
stock_location = Spree::StockLocation.find(stock_location_id)
|
12
|
+
stock_movement = stock_location.stock_movements.build(stock_movement_params)
|
13
|
+
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
|
14
|
+
|
15
|
+
if stock_movement.save
|
16
|
+
SpreeCmCommissioner::Stock::InventoryItemsAdjusterJob.perform_later(variant_id: variant.id, quantity: stock_movement.quantity)
|
17
|
+
context.stock_movement = stock_movement
|
18
|
+
else
|
19
|
+
context.fail!(message: stock_movement.errors.full_messages.join(', '))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -53,7 +53,7 @@ module SpreeCmCommissioner
|
|
53
53
|
user_data = context.user_data
|
54
54
|
|
55
55
|
identity = SpreeCmCommissioner::UserIdentityProvider.vattanac_bank
|
56
|
-
.find_or_initialize_by(sub: user_data['
|
56
|
+
.find_or_initialize_by(sub: user_data['phoneNum'])
|
57
57
|
|
58
58
|
if identity.persisted?
|
59
59
|
context.user = identity.user
|
@@ -78,7 +78,7 @@ module SpreeCmCommissioner
|
|
78
78
|
identity = context.identity
|
79
79
|
|
80
80
|
identity.name = full_name
|
81
|
-
|
81
|
+
identity.email = user_data['email']
|
82
82
|
context.user = Spree::User.new(
|
83
83
|
first_name: user_data['firstName'],
|
84
84
|
last_name: user_data['lastName'],
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module SpreeCmCommissioner
|
2
|
+
module Stock
|
3
|
+
class InventoryItemsAdjusterJob < ApplicationUniqueJob
|
4
|
+
def perform(variant_id:, quantity:)
|
5
|
+
variant = Spree::Variant.find(variant_id)
|
6
|
+
|
7
|
+
SpreeCmCommissioner::Stock::InventoryItemsAdjuster.call(variant: variant, quantity: quantity)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -20,6 +20,7 @@ module SpreeCmCommissioner
|
|
20
20
|
vehicle_id
|
21
21
|
origin
|
22
22
|
destination
|
23
|
+
place_id
|
23
24
|
].freeze
|
24
25
|
|
25
26
|
RESERVED_OPTIONS = {
|
@@ -47,8 +48,8 @@ module SpreeCmCommissioner
|
|
47
48
|
'bib-display-prefix' => 'boolean',
|
48
49
|
'bib-pre-generation-on-create' => 'boolean',
|
49
50
|
'seat-number-positions' => 'array',
|
50
|
-
'origin' => '
|
51
|
-
'destination' => '
|
51
|
+
'origin' => 'place_id',
|
52
|
+
'destination' => 'place_id',
|
52
53
|
'departure-time' => 'time',
|
53
54
|
'vehicle' => 'vehicle_id',
|
54
55
|
'allow-seat-selection' => 'boolean'
|
@@ -3,12 +3,10 @@ module SpreeCmCommissioner
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
delegate :
|
7
|
-
:subscribable?,
|
6
|
+
delegate :subscribable?,
|
8
7
|
:allowed_upload_later?,
|
9
8
|
:need_confirmation?, :need_confirmation, :kyc,
|
10
9
|
:allow_anonymous_booking,
|
11
|
-
:accommodation?, :service?, :ecommerce?,
|
12
10
|
:associated_event,
|
13
11
|
:allow_self_check_in,
|
14
12
|
:allow_self_check_in?,
|