spree_cm_commissioner 2.3.0.pre.pre18 → 2.3.0.pre.pre19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31d13343c99ba15786dc8ea2706e64fd79ada05ce505f06fea9dfdffd24f1313
4
- data.tar.gz: 2638b1befd6df8abbc2ed8bcabfd447bb15bb2006336e2ff894662c58c07e933
3
+ metadata.gz: ba19c5f6b8ae1e8a80fb0128bf1f58b1a653d6430aa11d46ae3722b13e2d17be
4
+ data.tar.gz: 7993749d255ca3800e9d200adc21820bad68ac350a60b88882a5bda4ee054701
5
5
  SHA512:
6
- metadata.gz: 487aa62c3894d83cd38036169a677ab79633f9792654e4d87e59c61fdbbe6a6bb60cd303f69727e093fc37fcf41c361ad43fbb2f60e79f84e5cd6e830aa05ed2
7
- data.tar.gz: 608a5d18e523889840e11a31f2686d357636de604fb360abb0c5074c1f3eda129c33012e779f5dc5ce025aed2842eb605cb051014217fccf4fa36361b8315fb5
6
+ metadata.gz: 83ffc09e4828acf4abb37b4d10e537f2302f967dca20fdf86a806f260fe733dbd9da4097a2f813650e29f2f1420350c538ec4aa8eedc7d9b7543a68e9c535d07
7
+ data.tar.gz: 40448782e45555c79e319cca373607a53ca34125ce1c5e13f45a74aa0014992a7294c768fdca9826287e645b2073a2f953eb2956ce983d1147d810f68a31c608
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (2.3.0.pre.pre18)
37
+ spree_cm_commissioner (2.3.0.pre.pre19)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -2,54 +2,26 @@ module SpreeCmCommissioner
2
2
  class UserRegistrationWithIdToken < BaseInteractor
3
3
  # :id_token
4
4
  def call
5
- firebase_context = validate_firebase_token!
6
- return if firebase_context.nil?
7
-
8
- ActiveRecord::Base.transaction do
9
- find_or_register_user!(firebase_context.provider[:name], firebase_context.provider[:email])
10
- link_user_account!(firebase_context.provider)
11
- end
12
- end
13
-
14
- private
15
-
16
- def validate_firebase_token!
17
5
  firebase_context = SpreeCmCommissioner::FirebaseIdTokenProvider.call(id_token: context.id_token)
18
- return firebase_context if firebase_context.success?
19
6
 
20
- context.fail!(message: firebase_context.message)
21
- nil
22
- end
23
-
24
- def find_or_register_user!(name, email)
25
- if email.present?
26
- register_user_with_email!(name, email)
27
- else
28
- register_user_without_email!(name)
29
- end
30
- end
31
-
32
- def register_user_with_email!(name, email)
33
- user = Spree.user_class.find_by(email: email, tenant_id: context.tenant_id)
34
- return context.user = ensure_user_confirmed!(user) if user.present?
35
-
36
- begin
37
- context.user = Spree.user_class.find_or_create_by!(email: email, tenant_id: context.tenant_id) do |u|
38
- assign_user_attributes(u, name)
7
+ if firebase_context.success?
8
+ ActiveRecord::Base.transaction do
9
+ register_user!(firebase_context.provider[:name], firebase_context.provider[:email])
10
+ link_user_account!(firebase_context.provider)
39
11
  end
40
- # Handle potential race condition: Another request might have created the user
41
- # between our find_by and find_or_create_by calls. If we get a RecordNotUnique,
42
- # it means the user was created by another process, so we find and return it.
43
- rescue ActiveRecord::RecordNotUnique
44
- user = Spree.user_class.find_by!(email: email, tenant_id: context.tenant_id)
45
- context.user = ensure_user_confirmed!(user)
12
+ else
13
+ context.fail!(message: firebase_context.message)
46
14
  end
47
15
  end
48
16
 
49
- def register_user_without_email!(name)
50
- user = Spree.user_class.new(email: nil, tenant_id: context.tenant_id)
51
- assign_user_attributes(user, name)
52
-
17
+ def register_user!(name, email)
18
+ user = Spree.user_class.new(
19
+ password: SecureRandom.base64(16),
20
+ email: email,
21
+ tenant_id: context.tenant_id,
22
+ **name_attributes(name)
23
+ )
24
+ user.confirmed_at = Time.zone.now
53
25
  if user.save(validate: false)
54
26
  context.user = user
55
27
  else
@@ -57,32 +29,39 @@ module SpreeCmCommissioner
57
29
  end
58
30
  end
59
31
 
60
- def assign_user_attributes(user, name)
61
- user.password = SecureRandom.base64(16)
62
- user.confirmed_at = Time.zone.now
63
- user.assign_attributes(name_attributes(name))
64
- end
65
-
66
32
  def name_attributes(name)
67
33
  full_name = name&.strip
68
34
  return {} if full_name.blank?
69
35
 
70
- parts = full_name.split
71
- attributes = { first_name: parts[0] }
72
- attributes[:last_name] = parts[1..].join(' ') if parts.size > 1
36
+ split = full_name.split
37
+ first_name = split[0]
38
+ last_name = split[1..].join(' ')
39
+
40
+ attributes = {}
41
+ attributes[:first_name] = first_name if first_name.present?
42
+ attributes[:last_name] = last_name if last_name.present?
73
43
 
74
44
  attributes
75
45
  end
76
46
 
47
+ # provider object
48
+
49
+ # {
50
+ # identity_type: identity_type,
51
+ # sub: sub
52
+ # }
53
+
77
54
  def link_user_account!(provider)
78
55
  identity_type = SpreeCmCommissioner::UserIdentityProvider.identity_types[provider[:identity_type]]
79
- user_identity_provider = find_or_initialize_identity_provider(identity_type)
80
56
 
81
- user_identity_provider.assign_attributes(
82
- sub: provider[:sub],
83
- email: provider[:email],
84
- name: provider[:name]
85
- )
57
+ user_identity_provider = SpreeCmCommissioner::UserIdentityProvider.where(
58
+ user_id: context.user,
59
+ identity_type: identity_type
60
+ ).first_or_initialize
61
+
62
+ user_identity_provider.sub = provider[:sub]
63
+ user_identity_provider.email = provider[:email]
64
+ user_identity_provider.name = provider[:name]
86
65
 
87
66
  if user_identity_provider.save
88
67
  context.user_identity_provider = user_identity_provider
@@ -90,20 +69,5 @@ module SpreeCmCommissioner
90
69
  context.fail!(message: user_identity_provider.errors.full_messages)
91
70
  end
92
71
  end
93
-
94
- def find_or_initialize_identity_provider(identity_type)
95
- SpreeCmCommissioner::UserIdentityProvider.where(
96
- user_id: context.user,
97
- identity_type: identity_type
98
- ).first_or_initialize
99
- end
100
-
101
- # Ensure user is confirmed when linking with identity provider.
102
- # Users created via OAuth should be auto-confirmed since they've proven
103
- # their identity through the OAuth provider.
104
- def ensure_user_confirmed!(user)
105
- user.update(confirmed_at: Time.zone.now) if user.confirmed_at.nil?
106
- user
107
- end
108
72
  end
109
73
  end
@@ -0,0 +1,12 @@
1
+ module SpreeCmCommissioner
2
+ module Orders
3
+ class ArchiveInactiveOrdersJob < ApplicationJob
4
+ # Scheduled job that runs daily to archive incomplete orders inactive for 14+ days.
5
+ # Thin wrapper that calls ArchiveInactiveOrders service.
6
+ # ApplicationJob handles error logging via around_perform hook.
7
+ def perform
8
+ SpreeCmCommissioner::Orders::ArchiveInactiveOrders.new.call
9
+ end
10
+ end
11
+ end
12
+ end
@@ -88,6 +88,7 @@ module SpreeCmCommissioner
88
88
  def restart_checkout_flow
89
89
  ActiveRecord::Base.transaction do
90
90
  cancel_blocks! if should_manage_blocks?
91
+ log_state_changes(state_name: 'cart', old_state: state, new_state: 'cart')
91
92
  update_columns( # rubocop:disable Rails/SkipsModelValidations
92
93
  state: 'cart',
93
94
  updated_at: Time.current
@@ -0,0 +1,55 @@
1
+ module SpreeCmCommissioner
2
+ module Orders
3
+ class ArchiveInactiveOrders
4
+ prepend ::Spree::ServiceModule::Base
5
+
6
+ # Archives incomplete orders that haven't been updated for 14 days.
7
+ # Archived orders are hidden from users (Orders::Find filters them out).
8
+ # Users will see an empty cart and can start a new one.
9
+ #
10
+ # Criteria for archiving:
11
+ # - archived_at IS NULL (not already archived)
12
+ # - completed_at IS NULL (incomplete/unfinished orders)
13
+ # - updated_at < 14 days ago (inactive for 2+ weeks)
14
+ #
15
+ # Why 14 days?
16
+ # - Gives users time to notice discontinued products and clean up their cart
17
+ # - If product is discontinued during these 14 days, users can manually clear
18
+ # their cart when they see the "unavailable" status in the UI
19
+ # - Gives the team time to investigate payment errors or stuck orders
20
+ #
21
+ # Why archive all payment states?
22
+ # - Data is preserved (archived_at is just a flag, not deletion)
23
+ # - Team can still review archived orders in the database if needed
24
+ # - Keeps user-facing order history clean (hidden from Orders::Find queries)
25
+ # - Reduces clutter in active carts/orders
26
+ def call
27
+ inactive_orders = Spree::Order
28
+ .where(archived_at: nil)
29
+ .where(completed_at: nil)
30
+ .where('updated_at < ?', 14.days.ago)
31
+
32
+ count = inactive_orders.count
33
+
34
+ # Archive all inactive orders with reason in internal_note
35
+ inactive_orders.update_all( # rubocop:disable Rails/SkipsModelValidations
36
+ archived_at: Time.current,
37
+ internal_note: 'Auto-archived: inactive for 14 days',
38
+ updated_at: Time.current
39
+ )
40
+
41
+ CmAppLogger.log(
42
+ label: 'SpreeCmCommissioner::Orders::ArchiveInactiveOrders#call completed',
43
+ data: {
44
+ archived_count: count,
45
+ threshold_days: 14
46
+ }
47
+ )
48
+
49
+ success(archived_count: count)
50
+ rescue StandardError => e
51
+ failure(nil, e.message)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '2.3.0-pre18'.freeze
2
+ VERSION = '2.3.0-pre19'.freeze
3
3
 
4
4
  module_function
5
5
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_cm_commissioner
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0.pre.pre18
4
+ version: 2.3.0.pre.pre19
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
@@ -1310,6 +1310,7 @@ files:
1310
1310
  - app/jobs/spree_cm_commissioner/option_type_variants_public_metadata_updater_job.rb
1311
1311
  - app/jobs/spree_cm_commissioner/option_value_variants_public_metadata_updater_job.rb
1312
1312
  - app/jobs/spree_cm_commissioner/order_complete_telegram_sender_job.rb
1313
+ - app/jobs/spree_cm_commissioner/orders/archive_inactive_orders_job.rb
1313
1314
  - app/jobs/spree_cm_commissioner/product_event_id_to_children_syncer_job.rb
1314
1315
  - app/jobs/spree_cm_commissioner/queue_order_webhooks_requests_job.rb
1315
1316
  - app/jobs/spree_cm_commissioner/reports_assigner_job.rb
@@ -1952,6 +1953,7 @@ files:
1952
1953
  - app/services/spree_cm_commissioner/intercity_taxi_order/update.rb
1953
1954
  - app/services/spree_cm_commissioner/metafields/product_metadata_service.rb
1954
1955
  - app/services/spree_cm_commissioner/order_params_checker.rb
1956
+ - app/services/spree_cm_commissioner/orders/archive_inactive_orders.rb
1955
1957
  - app/services/spree_cm_commissioner/orders/generate_commissions_decorator.rb
1956
1958
  - app/services/spree_cm_commissioner/organizer/export_guest_csv_service.rb
1957
1959
  - app/services/spree_cm_commissioner/organizer/export_invite_guest_csv_service.rb