spree_cm_commissioner 2.1.9.pre.pre2 → 2.2.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.tool-versions +1 -1
- data/Gemfile.lock +2 -1
- data/app/controllers/spree/admin/users_controller_decorator.rb +2 -0
- data/app/controllers/spree/api/v2/storefront/account/guest_dynamic_fields_controller.rb +3 -5
- data/app/controllers/spree/api/v2/storefront/account/mark_guest_info_complete_controller.rb +3 -8
- data/app/controllers/spree/api/v2/storefront/guests_controller.rb +37 -18
- data/app/interactors/spree_cm_commissioner/account_recover.rb +2 -2
- data/app/interactors/spree_cm_commissioner/guest_dynamic_field_notification_sender.rb +11 -0
- data/app/interactors/spree_cm_commissioner/notification_reader.rb +3 -1
- data/app/interactors/spree_cm_commissioner/stock/inventory_item_resetter.rb +1 -1
- data/app/interactors/spree_cm_commissioner/team_member_adder.rb +37 -0
- data/app/interactors/spree_cm_commissioner/team_member_creator.rb +58 -0
- data/app/interactors/spree_cm_commissioner/transit/draft_order_creator.rb +4 -0
- data/app/interactors/spree_cm_commissioner/trip_clone_creator.rb +2 -21
- data/app/interactors/spree_cm_commissioner/user_password_authenticator.rb +2 -2
- data/app/interactors/spree_cm_commissioner/user_registration_with_fb_token.rb +1 -1
- data/app/interactors/spree_cm_commissioner/user_registration_with_id_token.rb +1 -1
- data/app/interactors/spree_cm_commissioner/user_telegram_web_app_authenticator.rb +2 -0
- data/app/interactors/spree_cm_commissioner/user_vendor_assigner.rb +39 -0
- data/app/interactors/spree_cm_commissioner/vattanac_bank_initiator.rb +2 -0
- data/app/jobs/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_order_count_incrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_job.rb +13 -0
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_decrementer_job.rb +10 -0
- data/app/jobs/spree_cm_commissioner/transit/route_trip_count_incrementer_job.rb +10 -0
- data/app/models/concerns/spree_cm_commissioner/order_state_machine.rb +12 -0
- data/app/models/concerns/spree_cm_commissioner/route_order_countable.rb +30 -0
- data/app/models/concerns/spree_cm_commissioner/route_trip_count_callbacks.rb +48 -0
- data/app/models/concerns/spree_cm_commissioner/service_type.rb +35 -0
- data/app/models/concerns/spree_cm_commissioner/store_metadata.rb +14 -3
- data/app/models/spree_cm_commissioner/guest.rb +3 -0
- data/app/models/spree_cm_commissioner/inventory_item.rb +1 -1
- data/app/models/spree_cm_commissioner/notification.rb +5 -1
- data/app/models/spree_cm_commissioner/order_decorator.rb +5 -0
- data/app/models/spree_cm_commissioner/redis_stock/cached_inventory_items_builder.rb +2 -2
- data/app/models/spree_cm_commissioner/redis_stock/inventory_updater.rb +2 -2
- data/app/models/spree_cm_commissioner/route.rb +12 -0
- data/app/models/spree_cm_commissioner/trip.rb +40 -0
- data/app/models/spree_cm_commissioner/user_decorator.rb +11 -0
- data/app/models/spree_cm_commissioner/vendor_decorator.rb +1 -0
- data/app/models/spree_cm_commissioner/vendor_route.rb +9 -0
- data/app/notifications/spree_cm_commissioner/guest_dynamic_field_notification.rb +24 -0
- data/app/overrides/spree/admin/users/_form/user_add_on.html.erb.deface +27 -0
- data/app/services/spree_cm_commissioner/transit/base_route_order_metrics_updater.rb +62 -0
- data/app/services/spree_cm_commissioner/transit/route_fulfilled_order_count_incrementer_service.rb +18 -0
- data/app/services/spree_cm_commissioner/transit/route_order_count_incrementer_service.rb +19 -0
- data/app/services/spree_cm_commissioner/transit/route_previous_trip_count_decrementer_service.rb +30 -0
- data/app/services/spree_cm_commissioner/transit/route_trip_count_decrementer_service.rb +33 -0
- data/app/services/spree_cm_commissioner/transit/route_trip_count_incrementer_service.rb +33 -0
- data/app/services/spree_cm_commissioner/users/incomplete_guest_checker_service.rb +34 -0
- data/app/views/blazer/queries/embed/_content.html.erb +4 -2
- data/config/initializers/spree_permitted_attributes.rb +1 -0
- data/config/locales/en.yml +20 -0
- data/config/locales/km.yml +20 -0
- data/db/migrate/20250911042815_create_cm_routes.rb +16 -0
- data/db/migrate/20250911045649_create_cm_vendor_routes.rb +12 -0
- data/db/migrate/20251008064344_add_route_id_to_cm_trips.rb +7 -0
- data/db/migrate/20251009033331_add_registered_by_to_spree_users.rb +6 -0
- data/db/migrate/20251009073040_add_lock_version_to_cm_routes.rb +5 -0
- data/db/migrate/20251009073929_add_lock_version_to_cm_vendor_routes.rb +5 -0
- data/lib/spree_cm_commissioner/engine.rb +4 -0
- data/lib/spree_cm_commissioner/test_helper/factories/route_factory.rb +10 -0
- data/lib/spree_cm_commissioner/test_helper/factories/trip_factory.rb +1 -0
- data/lib/spree_cm_commissioner/test_helper/factories/vendor_route_factory.rb +7 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- data/lib/spree_cm_commissioner.rb +8 -14
- data/lib/tasks/backfill_confirmed_at.rake +21 -0
- data/spree_cm_commissioner.gemspec +1 -0
- metadata +50 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 03b6ceb6f610d931285c1edb4bf699bb82098cb042c7a675a7cf4ca97d20c2d1
|
|
4
|
+
data.tar.gz: 7e4a0b523320e28f397556545a5c912a3efc9418c993a3dcc06c403a6d1b64b0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a01870d81ac4d66b2c931b49552891ca2167257d0ae83956b7748af60d6c17b17bacd6d444a32b87b12d1db722451e3fc3c374eb108f45dc454ab3648f57b7a
|
|
7
|
+
data.tar.gz: 11efa1fc32c865d667bd37e2753b79d6971b923c4fc0ffa9e463c7b17a0e3ccf5cfb211b84aa97fe4d8554ff4542ec1cc36483c45ca578ef57e5ba7e863c73a8
|
data/.gitignore
CHANGED
data/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby 3.
|
|
1
|
+
ruby 3.3.5
|
data/Gemfile.lock
CHANGED
|
@@ -34,7 +34,7 @@ GIT
|
|
|
34
34
|
PATH
|
|
35
35
|
remote: .
|
|
36
36
|
specs:
|
|
37
|
-
spree_cm_commissioner (2.
|
|
37
|
+
spree_cm_commissioner (2.2.0)
|
|
38
38
|
activerecord-multi-tenant
|
|
39
39
|
activerecord_json_validator (~> 2.1, >= 2.1.3)
|
|
40
40
|
aws-sdk-cloudfront
|
|
@@ -69,6 +69,7 @@ PATH
|
|
|
69
69
|
spree_api_v1 (>= 4.5.0)
|
|
70
70
|
spree_auth_devise (>= 4.5.0)
|
|
71
71
|
spree_backend (>= 4.5.0)
|
|
72
|
+
spree_emails (>= 4.5.0)
|
|
72
73
|
spree_extension
|
|
73
74
|
spree_multi_vendor (>= 2.4.1)
|
|
74
75
|
spree_vpago
|
|
@@ -9,6 +9,8 @@ module Spree
|
|
|
9
9
|
def create
|
|
10
10
|
@user = Spree.user_class.new(user_params)
|
|
11
11
|
@user.assigned_roles = Spree::Role.where(id: params.dig(:user, :spree_role_ids)).pluck(:name) if params.dig(:user, :spree_role_ids)
|
|
12
|
+
@user.confirmed_at = Time.zone.now
|
|
13
|
+
@user.registered_by = :system_registered
|
|
12
14
|
|
|
13
15
|
if @user.save
|
|
14
16
|
flash[:success] = flash_message_for(@user, :successfully_created)
|
|
@@ -22,7 +22,7 @@ module Spree
|
|
|
22
22
|
|
|
23
23
|
ActiveRecord::Base.transaction do
|
|
24
24
|
fields.each do |field|
|
|
25
|
-
process_dynamic_field(field
|
|
25
|
+
process_dynamic_field(field)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
@guest.save_and_move_to_next_stage
|
|
@@ -52,11 +52,9 @@ module Spree
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
-
def process_dynamic_field(field
|
|
55
|
+
def process_dynamic_field(field)
|
|
56
56
|
dynamic_field = SpreeCmCommissioner::DynamicField.find(field[:id])
|
|
57
|
-
guest_field = @guest.guest_dynamic_fields.
|
|
58
|
-
|
|
59
|
-
return if guest_field.new_record? && dynamic_field.data_fill_stage != phase
|
|
57
|
+
guest_field = @guest.guest_dynamic_fields.build(dynamic_field_id: dynamic_field.id)
|
|
60
58
|
|
|
61
59
|
if dynamic_field.requires_dynamic_field_options?
|
|
62
60
|
option = dynamic_field.dynamic_field_options.find_by(value: field[:value])
|
|
@@ -7,18 +7,13 @@ module Spree
|
|
|
7
7
|
before_action :require_spree_current_user
|
|
8
8
|
|
|
9
9
|
def update
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
SpreeCmCommissioner::Users::IncompleteGuestCheckerService.new(spree_current_user).call
|
|
11
|
+
render_success
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
private
|
|
15
15
|
|
|
16
|
-
def
|
|
17
|
-
spree_current_user.public_metadata['has_incomplete_guest_info'] = false
|
|
18
|
-
spree_current_user.save!
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def render_success_response
|
|
16
|
+
def render_success
|
|
22
17
|
render_serialized_payload(200) do
|
|
23
18
|
{
|
|
24
19
|
success: true,
|
|
@@ -5,8 +5,8 @@ module Spree
|
|
|
5
5
|
class GuestsController < ::Spree::Api::V2::ResourceController
|
|
6
6
|
include OrderConcern
|
|
7
7
|
|
|
8
|
-
# raise 404 when no order
|
|
9
|
-
before_action :ensure_order
|
|
8
|
+
# raise 404 when no order, except for show
|
|
9
|
+
before_action :ensure_order, except: [:show]
|
|
10
10
|
|
|
11
11
|
# override
|
|
12
12
|
def model_class
|
|
@@ -23,6 +23,11 @@ module Spree
|
|
|
23
23
|
SpreeCmCommissioner::V2::Storefront::GuestSerializer
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
+
def show
|
|
27
|
+
@guest = SpreeCmCommissioner::Guest.find(params[:id])
|
|
28
|
+
render_serialized_payload { serialize_resource(@guest) }
|
|
29
|
+
end
|
|
30
|
+
|
|
26
31
|
def create
|
|
27
32
|
spree_authorize! :update, spree_current_order, order_token
|
|
28
33
|
|
|
@@ -90,22 +95,15 @@ module Spree
|
|
|
90
95
|
end
|
|
91
96
|
|
|
92
97
|
def process_dynamic_fields(dynamic_fields_attributes)
|
|
93
|
-
dynamic_fields_attributes.each do |
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if field
|
|
100
|
-
field.assign_attributes(attr.except(:id, :_destroy))
|
|
101
|
-
associate_dynamic_field_option(field) if field.dynamic_field.present?
|
|
102
|
-
field.save!
|
|
103
|
-
end
|
|
104
|
-
else
|
|
105
|
-
field = resource.guest_dynamic_fields.build(attr.except(:id, :_destroy))
|
|
106
|
-
associate_dynamic_field_option(field) if field.dynamic_field.present?
|
|
107
|
-
field.save!
|
|
98
|
+
dynamic_fields_attributes.each do |raw_attributes|
|
|
99
|
+
attributes = raw_attributes.to_h.symbolize_keys
|
|
100
|
+
|
|
101
|
+
if ActiveModel::Type::Boolean.new.cast(attributes[:_destroy])
|
|
102
|
+
destroy_guest_dynamic_field(attributes[:id])
|
|
103
|
+
next
|
|
108
104
|
end
|
|
105
|
+
|
|
106
|
+
upsert_guest_dynamic_field(attributes)
|
|
109
107
|
end
|
|
110
108
|
end
|
|
111
109
|
|
|
@@ -113,7 +111,28 @@ module Spree
|
|
|
113
111
|
return unless field.dynamic_field&.requires_dynamic_field_options?
|
|
114
112
|
|
|
115
113
|
option = field.dynamic_field.dynamic_field_options.find_by(id: field.value)
|
|
116
|
-
field.dynamic_field_option = option
|
|
114
|
+
field.dynamic_field_option = option
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def destroy_guest_dynamic_field(id)
|
|
118
|
+
return if id.blank?
|
|
119
|
+
|
|
120
|
+
resource.guest_dynamic_fields.find(id).destroy!
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def upsert_guest_dynamic_field(attributes)
|
|
124
|
+
field = find_or_initialize_guest_dynamic_field(attributes)
|
|
125
|
+
field.assign_attributes(attributes.except(:id, :_destroy))
|
|
126
|
+
associate_dynamic_field_option(field) if field.dynamic_field.present?
|
|
127
|
+
field.save!
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def find_or_initialize_guest_dynamic_field(attributes)
|
|
131
|
+
if attributes[:id].present?
|
|
132
|
+
resource.guest_dynamic_fields.find(attributes[:id])
|
|
133
|
+
else
|
|
134
|
+
resource.guest_dynamic_fields.find_or_initialize_by(dynamic_field_id: attributes[:dynamic_field_id])
|
|
135
|
+
end
|
|
117
136
|
end
|
|
118
137
|
end
|
|
119
138
|
end
|
|
@@ -8,8 +8,8 @@ module SpreeCmCommissioner
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def recover_user
|
|
11
|
-
updated = context.user.update(account_deletion_at: nil, account_restored_at: Time.current)
|
|
12
|
-
context.fail!(message: user.errors.full_messages.to_sentence) unless updated
|
|
11
|
+
updated = context.user.update(account_deletion_at: nil, account_restored_at: Time.current, confirmed_at: Time.current)
|
|
12
|
+
context.fail!(message: context.user.errors.full_messages.to_sentence) unless updated
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def validate_user
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class GuestDynamicFieldNotificationSender < BaseInteractor
|
|
3
|
+
def call
|
|
4
|
+
notification = SpreeCmCommissioner::GuestDynamicFieldNotification.with(
|
|
5
|
+
guest: context.guest
|
|
6
|
+
).deliver_later(context.guest.user)
|
|
7
|
+
|
|
8
|
+
context.notification = notification
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -15,7 +15,9 @@ module SpreeCmCommissioner
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def read_all_user_unread_notifications
|
|
18
|
-
|
|
18
|
+
# mark all unread notifications accept type 'guest_dynamic_field_notification'
|
|
19
|
+
# due to it requires user to fill info before mark as read
|
|
20
|
+
user.notifications.markable_notifications.mark_as_read!
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class TeamMemberAdder < BaseInteractor
|
|
3
|
+
delegate :user_id, :role_ids, :branch_ids, :vendor, :inviter, :service_type, to: :context
|
|
4
|
+
|
|
5
|
+
def call
|
|
6
|
+
find_user
|
|
7
|
+
assign_user_to_vendor
|
|
8
|
+
set_success_message
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def find_user
|
|
14
|
+
context.user = Spree::User.find_by(id: user_id)
|
|
15
|
+
|
|
16
|
+
return if context.user
|
|
17
|
+
|
|
18
|
+
context.fail!(
|
|
19
|
+
message: I18n.t('views.manage_team.add.user_not_found')
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def assign_user_to_vendor
|
|
24
|
+
SpreeCmCommissioner::UserVendorAssigner.call(
|
|
25
|
+
user: context.user,
|
|
26
|
+
role_ids: role_ids,
|
|
27
|
+
branch_ids: branch_ids,
|
|
28
|
+
vendor: vendor,
|
|
29
|
+
service_type: service_type
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def set_success_message
|
|
34
|
+
context.success_message = I18n.t('views.manage_team.add.user_assigned_successfully')
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class TeamMemberCreator < BaseInteractor
|
|
3
|
+
delegate :email, :first_name, :last_name, :password, :role_ids, :branch_ids, :vendor, :inviter, :service_type, to: :context
|
|
4
|
+
|
|
5
|
+
def call
|
|
6
|
+
create_user
|
|
7
|
+
assign_user_to_vendor
|
|
8
|
+
set_success_message
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def create_user
|
|
14
|
+
existing_user = Spree::User.find_by(email: normalized_email)
|
|
15
|
+
if existing_user.present?
|
|
16
|
+
context.fail!(
|
|
17
|
+
message: I18n.t('views.manage_team.create.user_already_exists'),
|
|
18
|
+
user: existing_user
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context.user = Spree::User.new(
|
|
23
|
+
email: normalized_email,
|
|
24
|
+
first_name: first_name,
|
|
25
|
+
last_name: last_name,
|
|
26
|
+
password: password,
|
|
27
|
+
password_confirmation: password,
|
|
28
|
+
registered_by: :system_registered,
|
|
29
|
+
primary_service_type: service_type
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return if context.user.save
|
|
33
|
+
|
|
34
|
+
context.fail!(
|
|
35
|
+
message: context.user.errors.full_messages.to_sentence,
|
|
36
|
+
user: context.user
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def assign_user_to_vendor
|
|
41
|
+
SpreeCmCommissioner::UserVendorAssigner.call(
|
|
42
|
+
user: context.user,
|
|
43
|
+
role_ids: role_ids,
|
|
44
|
+
branch_ids: branch_ids,
|
|
45
|
+
vendor: vendor,
|
|
46
|
+
service_type: service_type
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def set_success_message
|
|
51
|
+
context.success_message = I18n.t('views.manage_team.create.success')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def normalized_email
|
|
55
|
+
@normalized_email ||= email&.strip&.downcase
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -40,6 +40,10 @@ module SpreeCmCommissioner
|
|
|
40
40
|
inbound_qty = inbound_line_items.sum(&:quantity)
|
|
41
41
|
|
|
42
42
|
raise StandardError, 'Outbound & inbound line item quantities do not match' if inbound_line_items.any? && outbound_qty != inbound_qty
|
|
43
|
+
|
|
44
|
+
trip_ids = (outbound_legs.map(&:trip_id) + inbound_legs.map(&:trip_id)).uniq
|
|
45
|
+
order.preload_trip_ids = trip_ids
|
|
46
|
+
|
|
43
47
|
raise StandardError, order.errors.full_messages.to_sentence unless order.save
|
|
44
48
|
|
|
45
49
|
order.update_with_updater!
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# TODO: fix this to remove variant block related code as we already drop the table.
|
|
2
1
|
module SpreeCmCommissioner
|
|
3
2
|
class TripCloneCreator < BaseInteractor
|
|
4
3
|
delegate :vendor, :params, :original_trip, :places, :current_store, :current_vendor, to: :context
|
|
@@ -26,6 +25,7 @@ module SpreeCmCommissioner
|
|
|
26
25
|
return nil unless original_product
|
|
27
26
|
|
|
28
27
|
cloned_product = duplicate_product(original_product)
|
|
28
|
+
cloned_product.short_name = "Copy of #{original_product.short_name}"
|
|
29
29
|
assign_vendor_attributes(cloned_product)
|
|
30
30
|
|
|
31
31
|
cloned_product.save!
|
|
@@ -110,35 +110,16 @@ module SpreeCmCommissioner
|
|
|
110
110
|
# Clone Variants
|
|
111
111
|
def clone_variants(original_trip, cloned_trip)
|
|
112
112
|
original_trip.product.variants.each do |variant|
|
|
113
|
-
|
|
113
|
+
cloned_trip.product.variants.create!(
|
|
114
114
|
price: variant.price,
|
|
115
115
|
option_value_ids: variant.option_value_ids,
|
|
116
116
|
sku: ''
|
|
117
117
|
)
|
|
118
|
-
clone_variant_blocks(variant, new_variant)
|
|
119
118
|
end
|
|
120
119
|
rescue StandardError => e
|
|
121
120
|
raise StandardError, "Failed to clone variants: #{e.message}"
|
|
122
121
|
end
|
|
123
122
|
|
|
124
|
-
# clone variant_block (seat)
|
|
125
|
-
def clone_variant_blocks(origin_variant, new_variant)
|
|
126
|
-
block_data = {
|
|
127
|
-
block_ids: origin_variant.block_ids || []
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
context = SpreeCmCommissioner::VariantBlockUpdater.call(
|
|
131
|
-
variant: new_variant,
|
|
132
|
-
current_store: current_store,
|
|
133
|
-
data: block_data,
|
|
134
|
-
stock_location: current_vendor.stock_locations.first
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
raise StandardError, "Failed to update variant blocks: #{context.message}" unless context.success?
|
|
138
|
-
rescue StandardError => e
|
|
139
|
-
raise StandardError, "Failed to clone variant blocks: #{e.message}"
|
|
140
|
-
end
|
|
141
|
-
|
|
142
123
|
# Helpers
|
|
143
124
|
def departure_time_from_stops(trip)
|
|
144
125
|
first_departure = trip.trip_stops.first&.departure_time
|
|
@@ -6,7 +6,7 @@ module SpreeCmCommissioner
|
|
|
6
6
|
context.user = Spree.user_class.find_user_by_login(login, tenant_id)
|
|
7
7
|
context.fail!(message: I18n.t('authenticator.incorrect_login')) if context.user.nil?
|
|
8
8
|
|
|
9
|
-
if spree_confirmable? && active_for_authentication? && !validate_password(user)
|
|
9
|
+
if spree_confirmable? && active_for_authentication? && !validate_password(context.user)
|
|
10
10
|
context.fail!(message: I18n.t('authenticator.incorrect_password'))
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -25,7 +25,7 @@ module SpreeCmCommissioner
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def active_for_authentication?
|
|
28
|
-
user.active_for_authentication?
|
|
28
|
+
context.user.active_for_authentication?
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
end
|
|
@@ -24,7 +24,7 @@ module SpreeCmCommissioner
|
|
|
24
24
|
# Flag as social network registration to skip presence validation for email, login, phone_number, and user_identity_providers
|
|
25
25
|
# Other validations (uniqueness, format) still run if present
|
|
26
26
|
user.registering_via_social_network = true
|
|
27
|
-
|
|
27
|
+
user.confirmed_at = Time.zone.now
|
|
28
28
|
if user.save
|
|
29
29
|
context.user = user
|
|
30
30
|
else
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
class UserVendorAssigner < BaseInteractor
|
|
3
|
+
delegate :user, :role_ids, :branch_ids, :vendor, :service_type, to: :context
|
|
4
|
+
|
|
5
|
+
def call
|
|
6
|
+
assign_roles_to_user
|
|
7
|
+
assign_branches_to_user if should_assign_branches?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def assign_roles_to_user
|
|
13
|
+
SpreeCmCommissioner::UserRolesAssigner.create(
|
|
14
|
+
user_id: user.id,
|
|
15
|
+
role_ids: role_ids,
|
|
16
|
+
vendor_id: vendor.id
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def should_assign_branches?
|
|
21
|
+
(service_type == 'transit' || service_type == 'intercity_taxi') && branch_ids.present?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def assign_branches_to_user
|
|
25
|
+
cleaned_ids = Array(branch_ids).compact_blank.map(&:to_i)
|
|
26
|
+
|
|
27
|
+
return unless cleaned_ids.any?
|
|
28
|
+
|
|
29
|
+
valid_branch_ids = SpreeCmCommissioner::VendorPlace
|
|
30
|
+
.where(id: cleaned_ids, vendor_id: vendor.id, place_type: :branch)
|
|
31
|
+
.pluck(:id)
|
|
32
|
+
|
|
33
|
+
return unless valid_branch_ids.any?
|
|
34
|
+
|
|
35
|
+
user.branch_ids = valid_branch_ids
|
|
36
|
+
user.save
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteFulfilledOrderCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(order_id:)
|
|
5
|
+
order = Spree::Order.find(order_id)
|
|
6
|
+
SpreeCmCommissioner::Transit::RouteFulfilledOrderCountIncrementerService.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteOrderCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(order_id:)
|
|
5
|
+
order = Spree::Order.find(order_id)
|
|
6
|
+
SpreeCmCommissioner::Transit::RouteOrderCountIncrementerService.call(order: order)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Perform the previous-route decrement outside the Trip transaction.
|
|
2
|
+
|
|
3
|
+
module SpreeCmCommissioner
|
|
4
|
+
module Transit
|
|
5
|
+
class RoutePreviousTripCountDecrementerJob < ApplicationUniqueJob
|
|
6
|
+
queue_as :default
|
|
7
|
+
|
|
8
|
+
def perform(previous_route_id:)
|
|
9
|
+
SpreeCmCommissioner::Transit::RoutePreviousTripCountDecrementerService.call(previous_route_id: previous_route_id)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteTripCountDecrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(trip_id:)
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(trip_id)
|
|
6
|
+
SpreeCmCommissioner::Transit::RouteTripCountDecrementerService.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module Transit
|
|
3
|
+
class RouteTripCountIncrementerJob < ApplicationUniqueJob
|
|
4
|
+
def perform(trip_id:)
|
|
5
|
+
trip = SpreeCmCommissioner::Trip.find(trip_id)
|
|
6
|
+
SpreeCmCommissioner::Transit::RouteTripCountIncrementerService.call(trip: trip)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -26,6 +26,8 @@ module SpreeCmCommissioner
|
|
|
26
26
|
state_machine.after_transition to: :canceled, do: :precalculate_conversion
|
|
27
27
|
state_machine.after_transition to: :canceled, do: :restock_inventory!
|
|
28
28
|
|
|
29
|
+
state_machine.after_transition to: :complete, do: :increment_route_fulfilled_order_count
|
|
30
|
+
|
|
29
31
|
scope :accepted, -> { where(request_state: 'accepted') }
|
|
30
32
|
|
|
31
33
|
scope :filter_by_request_state, lambda {
|
|
@@ -77,6 +79,16 @@ module SpreeCmCommissioner
|
|
|
77
79
|
def mark_user_as_has_incomplete_guest_info
|
|
78
80
|
user&.public_metadata&.[]=('has_incomplete_guest_info', true)
|
|
79
81
|
user&.save!
|
|
82
|
+
|
|
83
|
+
line_items.each do |line_item|
|
|
84
|
+
line_item.guests.each do |guest|
|
|
85
|
+
guest.user ||= user
|
|
86
|
+
guest.save!(validate: false) if guest.changed?
|
|
87
|
+
guest.save_and_move_to_next_stage
|
|
88
|
+
# send notification only for guests that still have incomplete dynamic fields
|
|
89
|
+
SpreeCmCommissioner::GuestDynamicFieldNotificationSender.call(guest: guest) if guest_incomplete?(guest)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
80
92
|
end
|
|
81
93
|
|
|
82
94
|
def has_incomplete_guest_info? # rubocop:disable Naming/PredicateName
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module RouteOrderCountable
|
|
3
|
+
def should_update_count?
|
|
4
|
+
preload_trip_ids.any?
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def increment_route_fulfilled_order_count
|
|
8
|
+
return unless should_update_count?
|
|
9
|
+
|
|
10
|
+
SpreeCmCommissioner::Transit::RouteFulfilledOrderCountIncrementerJob.perform_later(order_id: id)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def increment_route_order_count
|
|
14
|
+
return unless should_update_count?
|
|
15
|
+
|
|
16
|
+
SpreeCmCommissioner::Transit::RouteOrderCountIncrementerJob.perform_later(order_id: id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Calling `.trip_ids` directly can cause many slow database queries (N+1 problem)
|
|
20
|
+
# every time `.should_update_trip_ids?` or `.preload_trip_ids` runs.
|
|
21
|
+
# To avoid this, we store a precomputed list of trip IDs in `private_metadata`.
|
|
22
|
+
def preload_trip_ids=(preload_trip_ids = [])
|
|
23
|
+
self.private_metadata = (private_metadata || {}).merge('preload_trip_ids' => preload_trip_ids)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def preload_trip_ids
|
|
27
|
+
private_metadata&.fetch('preload_trip_ids', []) || []
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module RouteTripCountCallbacks
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
after_create :increase_trip_count
|
|
7
|
+
before_destroy :decrease_trip_count
|
|
8
|
+
|
|
9
|
+
# When route context may change, enqueue an async job after commit that
|
|
10
|
+
# reads the previous values from `previous_changes` to decrement counts
|
|
11
|
+
# on the old route/vendor. This avoids keeping in-memory state and keeps
|
|
12
|
+
# the Trip update fast.
|
|
13
|
+
after_commit :enqueue_decrement_previous_route_trip_counts, on: :update
|
|
14
|
+
|
|
15
|
+
after_commit :increment_new_route_trip_counts, on: :update, if: :changed_route_context?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def decrease_trip_count
|
|
21
|
+
SpreeCmCommissioner::Transit::RouteTripCountDecrementerJob.perform_now(trip_id: id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def increase_trip_count
|
|
25
|
+
SpreeCmCommissioner::Transit::RouteTripCountIncrementerJob.perform_later(trip_id: id)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Read previous_changes to find prior route context and enqueue the job.
|
|
29
|
+
def enqueue_decrement_previous_route_trip_counts
|
|
30
|
+
prev_route_id = previous_changes['route_id']&.first
|
|
31
|
+
prev_origin_id = previous_changes['origin_place_id']&.first
|
|
32
|
+
prev_destination_id = previous_changes['destination_place_id']&.first
|
|
33
|
+
|
|
34
|
+
return unless prev_route_id.present? && prev_origin_id.present? && prev_destination_id.present?
|
|
35
|
+
|
|
36
|
+
SpreeCmCommissioner::Transit::RoutePreviousTripCountDecrementerJob.perform_later(
|
|
37
|
+
previous_route_id: prev_route_id
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Safely increment the trip_count for the trip's (new) route after update.
|
|
42
|
+
def increment_new_route_trip_counts
|
|
43
|
+
return if origin_place_id.blank? || destination_place_id.blank? || route_id.blank?
|
|
44
|
+
|
|
45
|
+
SpreeCmCommissioner::Transit::RouteTripCountIncrementerJob.perform_later(trip_id: id)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|