From 02449332d3861326eb554f8f1ae89e93e60bc2f4 Mon Sep 17 00:00:00 2001 From: David Cook Date: Tue, 7 Apr 2026 16:45:41 +1000 Subject: [PATCH] Prevent linked variants and inventory being enabled for a supplier --- app/models/enterprise_relationship.rb | 12 ++++++ config/locales/en.yml | 2 + spec/models/enterprise_relationship_spec.rb | 40 +++++++++++++++++++ .../admin/enterprise_relationships_spec.rb | 28 ++++++++++--- 4 files changed, 77 insertions(+), 5 deletions(-) diff --git a/app/models/enterprise_relationship.rb b/app/models/enterprise_relationship.rb index bdc318c08b..4f0900796f 100644 --- a/app/models/enterprise_relationship.rb +++ b/app/models/enterprise_relationship.rb @@ -9,6 +9,7 @@ class EnterpriseRelationship < ApplicationRecord scope: :parent_id, message: I18n.t('validation_msg_relationship_already_established') } + validate :validate_permissions_list before_destroy :revoke_all_child_variant_overrides before_destroy :destroy_related_exchanges @@ -71,6 +72,10 @@ class EnterpriseRelationship < ApplicationRecord relatives end + def permissions_list + permissions.map(&:name) + end + def permissions_list=(perms) if perms.nil? permissions.destroy_all @@ -86,6 +91,13 @@ class EnterpriseRelationship < ApplicationRecord private + def validate_permissions_list + if permissions_list.include?('create_variant_overrides') && + permissions_list.include?('create_linked_variants') + errors.add(:base, :inventory_vs_linked_variants) + end + end + def update_permissions_of_child_variant_overrides if has_permission?(:create_variant_overrides) allow_all_child_variant_overrides diff --git a/config/locales/en.yml b/config/locales/en.yml index 2b8134bc77..9fabe6abf1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -104,6 +104,8 @@ en: models: enterprise_fee: inherit_tax_requires_per_item_calculator: "Inheriting the tax category requires a per-item calculator." + enterprise_relationship: + inventory_vs_linked_variants: "Cannot grant both inventory and linked variants permissions." spree/image: attributes: attachment: diff --git a/spec/models/enterprise_relationship_spec.rb b/spec/models/enterprise_relationship_spec.rb index a5e08817f8..6e4ffd8a48 100644 --- a/spec/models/enterprise_relationship_spec.rb +++ b/spec/models/enterprise_relationship_spec.rb @@ -1,6 +1,46 @@ # frozen_string_literal: true RSpec.describe EnterpriseRelationship do + describe "validation" do + let(:parent) { create(:enterprise, name: 'Child') } + let(:child) { create(:enterprise, name: 'Parent') } + + describe "validate_permissions_list" do + it "invalid when both create_variant_overrides and create_linked_variants are selected" do + enterprise_relationship = build(:enterprise_relationship, parent:, child:, permissions_list: + [ + "create_linked_variants", + "create_variant_overrides" + ]) + + expect(enterprise_relationship).not_to be_valid + expect(enterprise_relationship.errors.full_messages).to eq [ + "Cannot grant both inventory and linked variants permissions." + ] + end + + it "valid when create_variant_overrides and another are selected" do + enterprise_relationship = build(:enterprise_relationship, parent:, child:, permissions_list: + [ + "one", + "create_variant_overrides" + ]) + + expect(enterprise_relationship).to be_valid + end + + it "valid when create_linked_variants and another are selected" do + enterprise_relationship = build(:enterprise_relationship, parent:, child:, permissions_list: + [ + "one", + "create_linked_variants" + ]) + + expect(enterprise_relationship).to be_valid + end + end + end + describe "scopes" do let(:e1) { create(:enterprise, name: 'A') } let(:e2) { create(:enterprise, name: 'B') } diff --git a/spec/system/admin/enterprise_relationships_spec.rb b/spec/system/admin/enterprise_relationships_spec.rb index aef6096605..768eee9334 100644 --- a/spec/system/admin/enterprise_relationships_spec.rb +++ b/spec/system/admin/enterprise_relationships_spec.rb @@ -44,9 +44,9 @@ create(:enterprise) check 'to add to order cycle' check 'to manage products' - uncheck 'to manage products' + check 'to manage products' check 'to edit profile' - check 'to add products to inventory' + uncheck 'to add products to inventory' check 'to create linked variants' select2_select 'Two', from: 'enterprise_relationship_child_id' click_button 'Create' @@ -57,12 +57,12 @@ create(:enterprise) expect_relationship_with_permissions e1, e2, ['to add to order cycle', 'to create linked variants [BETA]', - 'to add products to inventory', - 'to edit profile'] + 'to edit profile', + 'to manage products'] er = EnterpriseRelationship.where(parent_id: e1, child_id: e2).first expect(er).to be_present expect(er.permissions.map(&:name)).to match_array ['add_to_order_cycle', 'edit_profile', - 'create_variant_overrides', + 'manage_products', 'create_linked_variants'] end @@ -83,6 +83,24 @@ create(:enterprise) end.to change { EnterpriseRelationship.count }.by(0) end + it "attempting to create a relationship with conflicting permissions" do + e1 = create(:enterprise, name: 'One') + e2 = create(:enterprise, name: 'Two') + + expect do + # When I attempt to create a duplicate relationship + visit admin_enterprise_relationships_path + select2_select 'One', from: 'enterprise_relationship_parent_id' + select2_select 'Two', from: 'enterprise_relationship_child_id' + check "to add products to inventory" + check "to create linked variants" + click_button 'Create' + + # Then I should see an error message + expect(page).to have_content "Cannot grant both inventory and linked variants permissions." + end.to change { EnterpriseRelationship.count }.by(0) + end + it "deleting a relationship" do e1 = create(:enterprise, name: 'One') e2 = create(:enterprise, name: 'Two')