spree_cm_commissioner 2.1.5.pre.pre3 → 2.1.5.pre.pre4

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: 06e22965144e75388dd801148c7d38580aee08856973332edc2c40ad31f6772a
4
- data.tar.gz: 1b33b7d645b36c9ccf42444dfa09aa7826a43d9c8e2a3dd0aaaa6d1668f6643d
3
+ metadata.gz: d8486b28317774d671766e586870afa3396fc006efd21ea825bdc6769985e4be
4
+ data.tar.gz: 60df005650d9f053548a82bb7aa3818dd36e3b6aec8773a5fe05c3c5bf7d5d5a
5
5
  SHA512:
6
- metadata.gz: 781da351e0880acf7f46fbbc060844a31f26b322d781fc17ad1da51ac4a3e7d0a9c991d2fb4921ec1cc1e89a255c2abf9457c3bf7c163108838b199cb9865054
7
- data.tar.gz: 6322d9ef0cca35c6d225cb91917cb3e49a6a96221b60025103f09f607658eaf0c797d0d37f6ad44b3c183a5f7c8d6a64afd0326de016047cf005dfb8ae200b4b
6
+ metadata.gz: 16f526c38a5084769158d1a1cf643c77458f9a031adb21911f6b6699b2cd9421cb865d2de8d200bb7d4649aa30f79ef98273283aebf51a09ce25b45eeb1ae0c4
7
+ data.tar.gz: 894f3c5cb26b1506042a35a3fc36ac7d09b40828ee242715a47d83dc4141dcfb9ddcde3603e6a233b92df6aefab59ad0873778fa9f1ee286041ba262e6f95e9c
data/Gemfile.lock CHANGED
@@ -34,7 +34,7 @@ GIT
34
34
  PATH
35
35
  remote: .
36
36
  specs:
37
- spree_cm_commissioner (2.1.5.pre.pre3)
37
+ spree_cm_commissioner (2.1.5.pre.pre4)
38
38
  activerecord-multi-tenant
39
39
  activerecord_json_validator (~> 2.1, >= 2.1.3)
40
40
  aws-sdk-cloudfront
@@ -156,7 +156,7 @@ module Spree
156
156
  end
157
157
 
158
158
  def resource_serializer
159
- Spree::Api::Dependencies.storefront_cart_serializer.constantize
159
+ Spree::V2::Tenant::CartSerializer
160
160
  end
161
161
 
162
162
  def create_service
@@ -67,7 +67,7 @@ module Spree
67
67
  end
68
68
 
69
69
  def resource_serializer
70
- Spree::Api::Dependencies.storefront_cart_serializer.constantize
70
+ Spree::V2::Tenant::CartSerializer
71
71
  end
72
72
 
73
73
  def next_service
@@ -0,0 +1,32 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class DynamicFieldOptionsController < BaseController
6
+ # override
7
+ def collection
8
+ return @collection if defined?(@collection)
9
+ return SpreeCmCommissioner::DynamicFieldOption.none if params[:dynamic_field_id].blank?
10
+
11
+ @collection = SpreeCmCommissioner::DynamicFieldOption
12
+ .where(dynamic_field_id: params[:dynamic_field_id])
13
+ .active
14
+ .order(position: :asc)
15
+
16
+ @collection = @collection.where('value LIKE ?', "%#{params[:query]}%") if params[:query].present?
17
+ @collection
18
+ end
19
+
20
+ # override
21
+ def collection_serializer
22
+ Spree::V2::Tenant::DynamicFieldOptionSerializer
23
+ end
24
+
25
+ def model_class
26
+ SpreeCmCommissioner::DynamicFieldOption
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -9,6 +9,9 @@ module Spree
9
9
  # raise 404 when no order
10
10
  before_action :ensure_order
11
11
 
12
+ rescue_from ActiveRecord::RecordInvalid, with: :handle_record_invalid
13
+ rescue_from ActiveRecord::RecordNotFound, with: :handle_record_not_found
14
+
12
15
  # override
13
16
  def model_class
14
17
  SpreeCmCommissioner::Guest
@@ -27,23 +30,28 @@ module Spree
27
30
  def create
28
31
  spree_authorize! :update, spree_current_order, order_token
29
32
 
30
- resource = scope.new(guest_params)
33
+ resource = scope.new(guest_params.except(:guest_dynamic_fields_attributes))
31
34
 
32
- if resource.save
33
- render_serialized_payload(201) { serialize_resource(resource) }
34
- else
35
- render_error_payload(resource.errors, 400)
35
+ ActiveRecord::Base.transaction do
36
+ resource.save!
37
+ run_dynamic_fields(resource)
38
+ resource.save_and_move_to_next_stage
36
39
  end
40
+
41
+ render_serialized_payload(201) { serialize_resource(resource) }
37
42
  end
38
43
 
39
44
  def update
40
45
  spree_authorize! :update, spree_current_order, order_token
41
46
 
42
- if resource.update(guest_params)
43
- render_serialized_payload { serialize_resource(resource) }
44
- else
45
- render_error_payload(resource, 400)
47
+ ActiveRecord::Base.transaction do
48
+ run_dynamic_fields(resource) if guest_params[:guest_dynamic_fields_attributes]
49
+ resource.assign_attributes(guest_params.except(:guest_dynamic_fields_attributes))
50
+ resource.save!
51
+ resource.save_and_move_to_next_stage
46
52
  end
53
+
54
+ render_serialized_payload { serialize_resource(resource) }
47
55
  end
48
56
 
49
57
  private
@@ -78,9 +86,31 @@ module Spree
78
86
  :address,
79
87
  :other_organization,
80
88
  :expectation,
81
- :upload_later
89
+ :upload_later,
90
+ guest_dynamic_fields_attributes: %i[
91
+ id
92
+ dynamic_field_id
93
+ dynamic_field_option_id
94
+ value
95
+ _destroy
96
+ ]
97
+ )
98
+ end
99
+
100
+ def run_dynamic_fields(resource)
101
+ SpreeCmCommissioner::GuestDynamicFieldsManager.call(
102
+ resource: resource,
103
+ dynamic_fields_attributes: guest_params[:guest_dynamic_fields_attributes]
82
104
  )
83
105
  end
106
+
107
+ def handle_record_invalid(exception)
108
+ render_error_payload(exception.record.errors, 422)
109
+ end
110
+
111
+ def handle_record_not_found(exception)
112
+ render_error_payload({ base: [exception.message] }, 404)
113
+ end
84
114
  end
85
115
  end
86
116
  end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ module Api
3
+ module V2
4
+ module Tenant
5
+ class ProductDynamicFieldsController < BaseController
6
+ before_action :load_product, only: :index
7
+
8
+ # override
9
+ def collection
10
+ return @collection if defined?(@collection)
11
+
12
+ product_dynamic_fields = @product.product_dynamic_fields.includes(dynamic_field: :dynamic_field_options)
13
+
14
+ if params[:phase].present?
15
+ requested_phase = params[:phase].to_s
16
+ if SpreeCmCommissioner::DynamicField.data_fill_stages.key?(requested_phase)
17
+ product_dynamic_fields = product_dynamic_fields.joins(:dynamic_field)
18
+ .where(dynamic_field: { data_fill_stage: requested_phase })
19
+ .order(:position)
20
+ end
21
+ end
22
+
23
+ @collection = product_dynamic_fields.order(:section)
24
+ end
25
+
26
+ private
27
+
28
+ def load_product
29
+ return render_error_payload({ error: 'product_id is required' }, 400) if params[:product_id].blank?
30
+
31
+ @product ||= Spree::Product.find(params[:product_id])
32
+ end
33
+
34
+ def collection_serializer
35
+ Spree::V2::Tenant::ProductDynamicFieldSerializer
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ module SpreeCmCommissioner
2
+ class GuestDynamicFieldsManager < BaseInteractor
3
+ delegate :resource, :dynamic_fields_attributes, to: :context
4
+
5
+ def call
6
+ return if dynamic_fields_attributes.blank?
7
+
8
+ dynamic_fields_attributes.each { |attr| upsert_or_destroy_field(attr) }
9
+ end
10
+
11
+ private
12
+
13
+ def upsert_or_destroy_field(attr)
14
+ if attr[:_destroy] == '1' && attr[:id].present?
15
+ resource.guest_dynamic_fields.find_by(id: attr[:id])&.destroy!
16
+ return
17
+ end
18
+
19
+ return if attr[:dynamic_field_id].blank?
20
+
21
+ field = attr[:id].present? ? resource.guest_dynamic_fields.find(attr[:id]) : resource.guest_dynamic_fields.build
22
+ field.assign_attributes(attr.except(:id, :_destroy))
23
+ associate_dynamic_field_option(field)
24
+ field.save!
25
+ end
26
+
27
+ def associate_dynamic_field_option(field)
28
+ return unless field.value.to_s.match?(/\A\d+\z/)
29
+
30
+ field.dynamic_field_option = field.dynamic_field.dynamic_field_options.find_by(id: field.value.to_i)
31
+ end
32
+ end
33
+ end
@@ -39,8 +39,7 @@ module SpreeCmCommissioner
39
39
  login = login.downcase
40
40
  parser = PhoneNumberParser.call(phone_number: login)
41
41
 
42
- scope = Spree.user_class.all
43
- scope = scope.where(tenant_id: tenant_id) if tenant_id.present?
42
+ scope = tenant_id.present? ? Spree.user_class.by_tenant(tenant_id) : Spree.user_class.by_non_tenant
44
43
 
45
44
  if parser.intel_phone_number.present?
46
45
  scope.find_by(intel_phone_number: parser.intel_phone_number)
@@ -40,7 +40,7 @@ module SpreeCmCommissioner
40
40
 
41
41
  has_many :state_changes, as: :stateful, class_name: 'Spree::StateChange'
42
42
  has_many :guest_dynamic_fields, dependent: :destroy, class_name: 'SpreeCmCommissioner::GuestDynamicField'
43
- accepts_nested_attributes_for :guest_dynamic_fields, allow_destroy: true
43
+ accepts_nested_attributes_for :guest_dynamic_fields, allow_destroy: true, reject_if: :reject_guest_dynamic_field?
44
44
 
45
45
  belongs_to :event, class_name: 'Spree::Taxon'
46
46
 
@@ -402,6 +402,11 @@ module SpreeCmCommissioner
402
402
 
403
403
  required_fields.reject { |field| filled_ids.include?(field.id) }
404
404
  end
405
+
406
+ def reject_guest_dynamic_field?(attributes)
407
+ # Reject if dynamic_field_id is blank or if _destroy is true
408
+ attributes[:dynamic_field_id].blank? || ActiveModel::Type::Boolean.new.cast(attributes[:_destroy])
409
+ end
405
410
  end
406
411
  end
407
412
  # rubocop:enable Metrics/ClassLength
@@ -46,6 +46,10 @@ module SpreeCmCommissioner
46
46
  return if dynamic_field.blank? || dynamic_field_option.blank?
47
47
  return if dynamic_field_option.dynamic_field_id == dynamic_field_id
48
48
 
49
+ # Only validate if both dynamic_field and dynamic_field_option are persisted
50
+ # This prevents validation errors during creation when associations might not be fully loaded
51
+ return if dynamic_field.new_record? || dynamic_field_option.new_record?
52
+
49
53
  errors.add(:dynamic_field_option, 'must belong to the same dynamic field')
50
54
  end
51
55
 
@@ -32,6 +32,7 @@ module SpreeCmCommissioner
32
32
  base.has_secure_password :confirm_pin_code, validations: false
33
33
 
34
34
  base.multi_tenant :tenant, class_name: 'SpreeCmCommissioner::Tenant'
35
+
35
36
  base.scope :by_tenant, -> (tenant_id) { where(tenant_id: tenant_id) }
36
37
  base.scope :by_non_tenant, -> { where(tenant_id: nil) }
37
38
  base.scope :vendor_users, -> (vendor_id) { joins(:role_users => :role).where(spree_roles: { vendor_id: vendor_id }).distinct }
@@ -1,7 +1,30 @@
1
1
  module Spree
2
2
  module V2
3
3
  module Tenant
4
- class CartSerializer < Spree::V2::Storefront::CartSerializer
4
+ class CartSerializer < BaseSerializer
5
+ attributes :number, :item_total, :total, :ship_total, :adjustment_total, :created_at,
6
+ :updated_at, :completed_at, :included_tax_total, :additional_tax_total, :display_additional_tax_total,
7
+ :display_included_tax_total, :tax_total, :currency, :state, :token, :email,
8
+ :display_item_total, :display_ship_total, :display_adjustment_total, :display_tax_total,
9
+ :promo_total, :display_promo_total, :item_count, :special_instructions, :display_total,
10
+ :pre_tax_item_amount, :display_pre_tax_item_amount, :pre_tax_total, :display_pre_tax_total,
11
+ :shipment_state, :payment_state, :public_metadata,
12
+ :phone_number, :intel_phone_number, :country_code, :request_state, :channel
13
+
14
+ belongs_to :user, serializer: Spree::V2::Tenant::UserSerializer
15
+ belongs_to :billing_address,
16
+ id_method_name: :bill_address_id,
17
+ serializer: :address,
18
+ record_type: :address
19
+
20
+ has_many :promotions, object_method_name: :valid_promotions, id_method_name: :valid_promotion_ids,
21
+ serializer: Spree::V2::Storefront::PromotionSerializer
22
+
23
+ has_many :variants, serializer: Spree::V2::Tenant::VariantSerializer
24
+ has_many :products, serializer: Spree::V2::Tenant::ProductSerializer
25
+ has_many :line_items, serializer: Spree::V2::Tenant::LineItemSerializer
26
+ has_many :payments, serializer: Spree::V2::Storefront::PaymentSerializer
27
+ has_many :guests, serializer: Spree::V2::Tenant::GuestSerializer
5
28
  end
6
29
  end
7
30
  end
@@ -0,0 +1,9 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class DynamicFieldOptionSerializer < BaseSerializer
5
+ attributes :id, :value, :dynamic_field_id, :status, :position
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class DynamicFieldSerializer < BaseSerializer
5
+ attributes :id, :label, :data_type, :vendor_id, :multiple_select, :position, :data_fill_stage
6
+
7
+ has_many :dynamic_field_options, serializer: Spree::V2::Tenant::DynamicFieldOptionSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class GuestDynamicFieldSerializer < BaseSerializer
5
+ attributes :id, :value, :guest_id, :dynamic_field_id, :dynamic_field_option_id, :created_at, :updated_at
6
+
7
+ belongs_to :dynamic_field, serializer: Spree::V2::Tenant::DynamicFieldSerializer
8
+ belongs_to :dynamic_field_option, serializer: Spree::V2::Tenant::DynamicFieldOptionSerializer
9
+ end
10
+ end
11
+ end
12
+ end
@@ -14,6 +14,7 @@ module Spree
14
14
  belongs_to :occupation, serializer: Spree::V2::Tenant::TaxonSerializer
15
15
  belongs_to :nationality, serializer: Spree::V2::Tenant::TaxonSerializer
16
16
  has_one :id_card, serializer: Spree::V2::Tenant::IdCardSerializer
17
+ has_many :guest_dynamic_fields, serializer: Spree::V2::Tenant::GuestDynamicFieldSerializer
17
18
 
18
19
  # allowed_checkout updates frequently
19
20
  cache_options store: nil
@@ -0,0 +1,11 @@
1
+ module Spree
2
+ module V2
3
+ module Tenant
4
+ class ProductDynamicFieldSerializer < BaseSerializer
5
+ attributes :id, :product_id, :dynamic_field_id, :section
6
+
7
+ belongs_to :dynamic_field, serializer: Spree::V2::Tenant::DynamicFieldSerializer
8
+ end
9
+ end
10
+ end
11
+ end
@@ -5,6 +5,9 @@ module Spree
5
5
  # This serializer extends the Storefront ProductSerializer
6
6
  # to include any additional attributes or relationships needed
7
7
  # for the Tenant context.
8
+
9
+ # Overrided dynamic fields relationship of the parent serializer(Storefront).
10
+ has_many :dynamic_fields, serializer: Spree::V2::Tenant::DynamicFieldSerializer
8
11
  end
9
12
  end
10
13
  end
data/config/routes.rb CHANGED
@@ -507,6 +507,9 @@ Spree::Core::Engine.add_routes do
507
507
  resources :id_cards, only: %i[create update destroy]
508
508
  end
509
509
 
510
+ resources :product_dynamic_fields, only: :index
511
+ resources :dynamic_field_options, only: :index
512
+
510
513
  resource :checkout, controller: :checkout, only: %i[update] do
511
514
  patch :next
512
515
  patch :advance
@@ -0,0 +1,5 @@
1
+ class AddSectionToCmProductDynamicFields < ActiveRecord::Migration[7.0]
2
+ def change
3
+ add_column :cm_product_dynamic_fields, :section, :integer, if_not_exists: true
4
+ end
5
+ end
@@ -1,5 +1,5 @@
1
1
  module SpreeCmCommissioner
2
- VERSION = '2.1.5-pre3'.freeze
2
+ VERSION = '2.1.5-pre4'.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.1.5.pre.pre3
4
+ version: 2.1.5.pre.pre4
5
5
  platform: ruby
6
6
  authors:
7
7
  - You
@@ -976,6 +976,7 @@ files:
976
976
  - app/controllers/spree/api/v2/tenant/checkout_controller.rb
977
977
  - app/controllers/spree/api/v2/tenant/cms_pages_controller.rb
978
978
  - app/controllers/spree/api/v2/tenant/customer_notifications_controller.rb
979
+ - app/controllers/spree/api/v2/tenant/dynamic_field_options_controller.rb
979
980
  - app/controllers/spree/api/v2/tenant/guests_controller.rb
980
981
  - app/controllers/spree/api/v2/tenant/homepage_sections_controller.rb
981
982
  - app/controllers/spree/api/v2/tenant/id_cards_controller.rb
@@ -984,6 +985,7 @@ files:
984
985
  - app/controllers/spree/api/v2/tenant/order_histories_controller.rb
985
986
  - app/controllers/spree/api/v2/tenant/pin_code_checkers_controller.rb
986
987
  - app/controllers/spree/api/v2/tenant/pin_code_generators_controller.rb
988
+ - app/controllers/spree/api/v2/tenant/product_dynamic_fields_controller.rb
987
989
  - app/controllers/spree/api/v2/tenant/products_controller.rb
988
990
  - app/controllers/spree/api/v2/tenant/profile_images_controller.rb
989
991
  - app/controllers/spree/api/v2/tenant/reset_passwords_controller.rb
@@ -1142,6 +1144,7 @@ files:
1142
1144
  - app/interactors/spree_cm_commissioner/firebase_email_fetcher_cron_executor.rb
1143
1145
  - app/interactors/spree_cm_commissioner/firebase_id_token_provider.rb
1144
1146
  - app/interactors/spree_cm_commissioner/google_places_fetcher.rb
1147
+ - app/interactors/spree_cm_commissioner/guest_dynamic_fields_manager.rb
1145
1148
  - app/interactors/spree_cm_commissioner/guest_id_card_manager.rb
1146
1149
  - app/interactors/spree_cm_commissioner/guest_seat_updater.rb
1147
1150
  - app/interactors/spree_cm_commissioner/host_matcher.rb
@@ -1741,7 +1744,10 @@ files:
1741
1744
  - app/serializers/spree/v2/tenant/cart_serializer.rb
1742
1745
  - app/serializers/spree/v2/tenant/customer_notification_serializer.rb
1743
1746
  - app/serializers/spree/v2/tenant/digital_link_serializer.rb
1747
+ - app/serializers/spree/v2/tenant/dynamic_field_option_serializer.rb
1748
+ - app/serializers/spree/v2/tenant/dynamic_field_serializer.rb
1744
1749
  - app/serializers/spree/v2/tenant/guest_card_class_serializer.rb
1750
+ - app/serializers/spree/v2/tenant/guest_dynamic_field_serializer.rb
1745
1751
  - app/serializers/spree/v2/tenant/guest_serializer.rb
1746
1752
  - app/serializers/spree/v2/tenant/homepage_section_relatable_serializer.rb
1747
1753
  - app/serializers/spree/v2/tenant/homepage_section_serializer.rb
@@ -1754,6 +1760,7 @@ files:
1754
1760
  - app/serializers/spree/v2/tenant/order_serializer.rb
1755
1761
  - app/serializers/spree/v2/tenant/payment_method_group_serializer.rb
1756
1762
  - app/serializers/spree/v2/tenant/payment_method_serializer.rb
1763
+ - app/serializers/spree/v2/tenant/product_dynamic_field_serializer.rb
1757
1764
  - app/serializers/spree/v2/tenant/product_serializer.rb
1758
1765
  - app/serializers/spree/v2/tenant/reset_password_serializer.rb
1759
1766
  - app/serializers/spree/v2/tenant/role_serializer.rb
@@ -2738,6 +2745,7 @@ files:
2738
2745
  - db/migrate/20250827022757_create_spree_cm_commissioner_check_in_rules.rb
2739
2746
  - db/migrate/20250827032901_add_check_in_session_to_check_ins.rb
2740
2747
  - db/migrate/20250827083828_add_unique_index_on_guest_id_check_in_session_id_to_cm_check_ins.rb
2748
+ - db/migrate/20250902092904_add_section_to_cm_product_dynamic_fields.rb
2741
2749
  - db/migrate/20250903085931_add_importable_to_cm_imports.rb
2742
2750
  - db/migrate/20250911100738_drop_cm_variant_blocks.rb
2743
2751
  - db/migrate/20250911100835_add_variant_id_to_cm_blocks.rb