diff --git a/api/lib/spree/api_configuration.rb b/api/lib/spree/api_configuration.rb
index 2dce13e62d8..9684e3ffd9e 100644
--- a/api/lib/spree/api_configuration.rb
+++ b/api/lib/spree/api_configuration.rb
@@ -127,7 +127,7 @@ def promotion_attributes=(value)
preference :store_attributes, :array, default: [
:id, :name, :url, :meta_description, :meta_keywords, :seo_title,
:mail_from_address, :default_currency, :code, :default, :available_locales,
- :bcc_email
+ :bcc_email, :reverse_charge_status
]
preference :store_credit_history_attributes, :array, default: [
diff --git a/api/spec/requests/spree/api/stores_spec.rb b/api/spec/requests/spree/api/stores_spec.rb
index 55b4f102416..ab9dec43ba1 100644
--- a/api/spec/requests/spree/api/stores_spec.rb
+++ b/api/spec/requests/spree/api/stores_spec.rb
@@ -32,6 +32,7 @@ module Spree::Api
"meta_description" => nil,
"meta_keywords" => nil,
"seo_title" => nil,
+ "reverse_charge_status" => 'disabled',
"mail_from_address" => "solidus@example.org",
"bcc_email" => nil,
"default_currency" => nil,
@@ -46,6 +47,7 @@ module Spree::Api
"meta_description" => nil,
"meta_keywords" => nil,
"seo_title" => nil,
+ "reverse_charge_status" => 'disabled',
"mail_from_address" => "solidus@example.org",
"bcc_email" => nil,
"default_currency" => nil,
@@ -65,6 +67,7 @@ module Spree::Api
"meta_description" => nil,
"meta_keywords" => nil,
"seo_title" => nil,
+ "reverse_charge_status" => 'disabled',
"mail_from_address" => "solidus@example.org",
"bcc_email" => nil,
"default_currency" => nil,
@@ -112,6 +115,36 @@ module Spree::Api
expect(response.status).to eq(204)
end
end
+
+ context "reverse_charge_status attribute" do
+ it "can create a new store with reverse_charge_status" do
+ store_hash = {
+ code: "spree123",
+ name: "Hack0rz",
+ url: "spree123.example.com",
+ mail_from_address: "me@example.com",
+ reverse_charge_status: "enabled"
+ }
+ post spree.api_stores_path, params: { store: store_hash }
+ expect(response.status).to eq(201)
+ expect(json_response["reverse_charge_status"]).to eq('enabled')
+ end
+
+ it "can update an existing store with reverse_charge_status" do
+ store_hash = {
+ url: "spree123.example.com",
+ mail_from_address: "me@example.com",
+ bcc_email: "bcc@example.net",
+ reverse_charge_status: "disabled"
+ }
+ put spree.api_store_path(store), params: { store: store_hash }
+ expect(response.status).to eq(200)
+ expect(store.reload.url).to eql "spree123.example.com"
+ expect(store.reload.mail_from_address).to eql "me@example.com"
+ expect(store.reload.bcc_email).to eql "bcc@example.net"
+ expect(store.reload.reverse_charge_status).to eql "disabled"
+ end
+ end
end
context "as an user" do
diff --git a/backend/app/views/spree/admin/stores/_form.html.erb b/backend/app/views/spree/admin/stores/_form.html.erb
index 59dc4a4e899..52cdaf346e8 100644
--- a/backend/app/views/spree/admin/stores/_form.html.erb
+++ b/backend/app/views/spree/admin/stores/_form.html.erb
@@ -30,6 +30,17 @@
<%= f.text_area :meta_description, class: 'fullwidth' %>
<%= f.error_message_on :meta_description %>
<% end %>
+
+ <% if Spree::Backend::Config.show_reverse_charge_fields %>
+ <%= f.field_container :reverse_charge_status do %>
+ <%= f.label :reverse_charge_status %>
+ <%= f.select :reverse_charge_status,
+ Spree::Store.reverse_charge_statuses.keys.map { |key| [I18n.t("spree.reverse_charge_statuses.#{key}"), key] },
+ { include_blank: false },
+ { class: 'custom-select fullwidth' } %>
+ <%= f.error_message_on :reverse_charge_status %>
+ <% end %>
+ <% end %>
<%= f.field_container :url do %>
diff --git a/backend/lib/spree/backend_configuration.rb b/backend/lib/spree/backend_configuration.rb
index 5d0c130e30e..5621fb4641a 100644
--- a/backend/lib/spree/backend_configuration.rb
+++ b/backend/lib/spree/backend_configuration.rb
@@ -19,6 +19,10 @@ class BackendConfiguration < Preferences::Configuration
solidus_admin: 'spree/backend/themes/solidus_admin'
}
+ # @!attribute [rw] show_reverse_charge_fields
+ # @return [Boolean] Request reverse charge fields. (default: +false+)
+ preference :show_reverse_charge_fields, :boolean, default: false
+
preference :search_fields, :hash, default: {
"spree/admin/orders" => [
{
diff --git a/core/app/models/spree/store.rb b/core/app/models/spree/store.rb
index 9350fb0a2b8..fd5aef8289c 100644
--- a/core/app/models/spree/store.rb
+++ b/core/app/models/spree/store.rb
@@ -27,6 +27,12 @@ class Store < Spree::Base
before_save :ensure_default_exists_and_is_unique
before_destroy :validate_not_default
+ enum :reverse_charge_status, {
+ disabled: 0,
+ enabled: 1,
+ not_validated: 2
+ }, prefix: true
+
def available_locales
locales = super()
if locales
diff --git a/core/config/locales/en.yml b/core/config/locales/en.yml
index e7e1d1910a5..1c155bd1bbc 100644
--- a/core/config/locales/en.yml
+++ b/core/config/locales/en.yml
@@ -2081,6 +2081,10 @@ en:
return_quantity: Return Quantity
return_reasons: Return Reasons
returned: Returned
+ reverse_charge_statuses:
+ disabled: Disabled
+ enabled: Enabled
+ not_validated: Not Validated
review: Review
risk: Risk
risk_analysis: Risk Analysis
diff --git a/core/db/migrate/20250214094207_add_reverse_charge_status_to_store.rb b/core/db/migrate/20250214094207_add_reverse_charge_status_to_store.rb
new file mode 100644
index 00000000000..78d2a7c2847
--- /dev/null
+++ b/core/db/migrate/20250214094207_add_reverse_charge_status_to_store.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class AddReverseChargeStatusToStore < ActiveRecord::Migration[7.2]
+ def change
+ add_column :spree_stores, :reverse_charge_status, :integer, default: 0, null: false,
+ comment: "Enum values: 0 = disabled, 1 = enabled, 2 = not_validated"
+ end
+end
diff --git a/core/lib/spree/permitted_attributes.rb b/core/lib/spree/permitted_attributes.rb
index a09a6eb53e6..6e15ff1b2a2 100644
--- a/core/lib/spree/permitted_attributes.rb
+++ b/core/lib/spree/permitted_attributes.rb
@@ -113,7 +113,7 @@ module PermittedAttributes
@@store_attributes = [:name, :url, :seo_title, :meta_keywords,
:meta_description, :default_currency,
:mail_from_address, :cart_tax_country_iso,
- :bcc_email]
+ :bcc_email, :reverse_charge_status]
@@taxonomy_attributes = [:name]
diff --git a/core/spec/models/spree/store_spec.rb b/core/spec/models/spree/store_spec.rb
index 8492d4da26b..9bf552581d6 100644
--- a/core/spec/models/spree/store_spec.rb
+++ b/core/spec/models/spree/store_spec.rb
@@ -106,4 +106,34 @@
end
end
end
+
+ describe 'enum reverse_charge_status' do
+ it 'defines the expected enum values' do
+ expect(Spree::Store.reverse_charge_statuses).to eq({
+ 'disabled' => 0,
+ 'enabled' => 1,
+ 'not_validated' => 2
+ })
+ end
+
+ it 'allows valid values' do
+ store = build(:store)
+ # Updates the reverse_charge_status to "not_validated"
+ expect(store).to be_valid
+ store.reverse_charge_status_not_validated!
+
+ # Updates the reverse_charge_status to "disabled"
+ expect(store).to be_valid
+ store.reverse_charge_status_disabled!
+ expect(store).to be_valid
+
+ # Updates the reverse_charge_status to "enabled"
+ store.reverse_charge_status_enabled!
+ expect(store).to be_valid
+ end
+
+ it 'raises an error for invalid values' do
+ expect { Spree::Store.new(reverse_charge_status: :invalid_status) }.to raise_error(ArgumentError)
+ end
+ end
end