diff --git a/app/serializers/api/admin/enterprise_serializer.rb b/app/serializers/api/admin/enterprise_serializer.rb
index f189e57fd01..7c29b41e708 100644
--- a/app/serializers/api/admin/enterprise_serializer.rb
+++ b/app/serializers/api/admin/enterprise_serializer.rb
@@ -15,7 +15,7 @@ class EnterpriseSerializer < ActiveModel::Serializer
:terms_and_conditions_file_name, :terms_and_conditions_updated_at,
:preferred_invoice_order_by_supplier, :preferred_product_low_stock_display,
:visible, :hide_ofn_navigation, :white_label_logo,
- :white_label_logo_link
+ :white_label_logo_link, :external_billing_id
has_one :owner, serializer: Api::Admin::UserSerializer
has_many :users, serializer: Api::Admin::UserSerializer
diff --git a/app/services/permitted_attributes/enterprise.rb b/app/services/permitted_attributes/enterprise.rb
index 234fadac77a..1dd5b5a8385 100644
--- a/app/services/permitted_attributes/enterprise.rb
+++ b/app/services/permitted_attributes/enterprise.rb
@@ -37,7 +37,7 @@ def self.basic_permitted_attributes
:preferred_invoice_order_by_supplier,
:preferred_product_low_stock_display,
:hide_ofn_navigation, :white_label_logo, :white_label_logo_link,
- :hide_groups_tab
+ :hide_groups_tab, :external_billing_id,
]
end
end
diff --git a/app/views/admin/enterprises/form/_primary_details.html.haml b/app/views/admin/enterprises/form/_primary_details.html.haml
index 04609e9b586..e5bbf4eed06 100644
--- a/app/views/admin/enterprises/form/_primary_details.html.haml
+++ b/app/views/admin/enterprises/form/_primary_details.html.haml
@@ -16,24 +16,8 @@
%label= t('.primary_producer')
= render partial: 'admin/shared/whats_this_tooltip', locals: {tooltip_text: t('.primary_producer_tip')}
.five.columns.omega
- = f.check_box :is_primary_producer, data: { action: "change->primary-details#primaryProducerChanged" }
+ = f.check_box :is_primary_producer, data: { action: "change->primary-details#primaryProducerChanged" }
= f.label :is_primary_producer, t('.producer')
-- if spree_current_user.admin?
- .row
- .three.columns.alpha
- = f.label :sells, t('.sells')
- = render partial: 'admin/shared/whats_this_tooltip', locals: {tooltip_text: t('.sells_tip')}
- .two.columns
- = f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells', data: {action: "change->primary-details#enterpriseSellsChanged"}
- = f.label :sells, t('.none'), value: "none"
- .two.columns
- = f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells', data: {action: "change->primary-details#enterpriseSellsChanged"}
- = f.label :sells, t('.own'), value: "own"
- .four.columns.omega
- = f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells', data: {action: "change->primary-details#enterpriseSellsChanged"}
- = f.label :sells, t('.any'), value: "any"
- %span{ style: "width: 30px; height: 30px;", class: "hidden", data: { "primary-details-target": "spinner" } }
- = render partial: "components/admin_spinner"
.row
.three.columns.alpha
%label= t('.visible_in_search')
@@ -49,3 +33,29 @@
= f.label :visible, t('.hidden'), value: 'hidden'
= render partial: 'admin/enterprises/form/permalink'
+
+- if spree_current_user.admin?
+ .row
+ %fieldset.alpha.no-border-bottom
+ %legend= t('.admin_only_legend')
+ .row
+ .three.columns.alpha
+ = f.label :sells, t('.sells')
+ = render partial: 'admin/shared/whats_this_tooltip', locals: {tooltip_text: t('.sells_tip')}
+ .two.columns
+ = f.radio_button :sells, "none", 'ng-model' => 'Enterprise.sells', data: {action: "change->primary-details#enterpriseSellsChanged"}
+ = f.label :sells, t('.none'), value: "none"
+ .two.columns
+ = f.radio_button :sells, "own", 'ng-model' => 'Enterprise.sells', data: {action: "change->primary-details#enterpriseSellsChanged"}
+ = f.label :sells, t('.own'), value: "own"
+ .four.columns.omega
+ = f.radio_button :sells, "any", 'ng-model' => 'Enterprise.sells', data: {action: "change->primary-details#enterpriseSellsChanged"}
+ = f.label :sells, t('.any'), value: "any"
+ %span{ style: "width: 30px; height: 30px;", class: "hidden", data: { "primary-details-target": "spinner" } }
+ = render partial: "components/admin_spinner"
+ .row
+ .three.columns.alpha
+ = f.label :external_billing_id, t('.external_billing_id')
+ = render partial: 'admin/shared/whats_this_tooltip', locals: {tooltip_text: t('.external_billing_id_tip')}
+ .four.columns
+ = f.text_field :external_billing_id, { placeholder: t('.external_billing_id_placeholder') }
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 6c8fa2dbdcf..a1a5bb33c73 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1284,11 +1284,15 @@ en:
own: Own
sells: Sells
sells_tip: "None - enterprise does not sell to customers directly.
Own - Enterprise sells own products to customers.
Any - Enterprise can sell own or other enterprises products.
"
+ external_billing_id: External Billing ID
+ external_billing_id_placeholder: eg. INV-2024-123456
+ external_billing_id_tip: "This is the ID used by the external billing system to identify this enterprise."
visible_in_search: Visible in search?
visible_in_search_tip: "Shops can be
1. publicly visible, appearing on the OFN map and listings.
2. Hidden on maps and listings but referenced by other shops and linked in their profile.
3. Completely hidden."
visible: Public
not_visible: Hidden
hidden: Hide all references
+ admin_only_legend: Admin only
properties:
legend: "Properties"
permalink:
@@ -3193,6 +3197,7 @@ See the %{link} to find out more about %{sitename}'s features and to start using
report_header_hub_code: Hub Code
report_header_hub_id: Hub ID
report_header_hub_business_number: "Hub Business Number"
+ report_header_hub_external_billing_id: "Hub External Billing Id"
report_header_hub_legal_name: "Hub Legal Name"
report_header_hub_contact_name: "Hub Contact Name"
report_header_hub_email: "Hub Public Email"
diff --git a/db/migrate/20241113185651_add_external_billing_id_on_enterprises.rb b/db/migrate/20241113185651_add_external_billing_id_on_enterprises.rb
new file mode 100644
index 00000000000..bd0292bbe3d
--- /dev/null
+++ b/db/migrate/20241113185651_add_external_billing_id_on_enterprises.rb
@@ -0,0 +1,5 @@
+class AddExternalBillingIdOnEnterprises < ActiveRecord::Migration[7.0]
+ def change
+ add_column :enterprises, :external_billing_id, :string, limit: 128
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index be371a9499d..37bab4a1e64 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_11_12_230401) do
+ActiveRecord::Schema[7.0].define(version: 2024_11_13_185651) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "plpgsql"
@@ -229,6 +229,7 @@
t.boolean "hide_ofn_navigation", default: false, null: false
t.text "white_label_logo_link"
t.boolean "hide_groups_tab", default: false
+ t.string "external_billing_id", limit: 128
t.index ["address_id"], name: "index_enterprises_on_address_id"
t.index ["is_primary_producer", "sells"], name: "index_enterprises_on_is_primary_producer_and_sells"
t.index ["name"], name: "index_enterprises_on_name", unique: true
diff --git a/lib/reporting/reports/revenues_by_hub/base.rb b/lib/reporting/reports/revenues_by_hub/base.rb
index e539c77fed2..8b10386a6f2 100644
--- a/lib/reporting/reports/revenues_by_hub/base.rb
+++ b/lib/reporting/reports/revenues_by_hub/base.rb
@@ -24,6 +24,7 @@ def columns # rubocop:disable Metrics/AbcSize
hub: proc { |orders| distributor(orders).name },
hub_id: proc { |orders| distributor(orders).id },
hub_business_number: proc { |orders| distributor(orders).abn },
+ hub_external_billing_id: proc { |orders| distributor(orders).external_billing_id },
hub_legal_name: proc { |orders| distributor(orders).business_address&.company },
hub_contact_name: proc { |orders| distributor(orders).contact_name },
hub_email: proc { |orders| distributor(orders).email_address },
diff --git a/spec/controllers/admin/enterprises_controller_spec.rb b/spec/controllers/admin/enterprises_controller_spec.rb
index 4caf3e38d79..415f75cc2a5 100644
--- a/spec/controllers/admin/enterprises_controller_spec.rb
+++ b/spec/controllers/admin/enterprises_controller_spec.rb
@@ -409,6 +409,16 @@
distributor.reload
expect(distributor.users).to include user
end
+
+ it "allows 'external_billing_id' to be changed" do
+ allow(controller).to receive_messages spree_current_user: admin_user
+ enterprise_params =
+ { id: profile_enterprise, enterprise: { external_billing_id: 'INV123456' } }
+
+ spree_put :update, enterprise_params
+ profile_enterprise.reload
+ expect(profile_enterprise.external_billing_id).to eq 'INV123456'
+ end
end
context "geocoding" do
diff --git a/spec/controllers/api/v0/enterprises_controller_spec.rb b/spec/controllers/api/v0/enterprises_controller_spec.rb
index d0529f3eeba..55fd6a2a158 100644
--- a/spec/controllers/api/v0/enterprises_controller_spec.rb
+++ b/spec/controllers/api/v0/enterprises_controller_spec.rb
@@ -7,6 +7,30 @@
let(:enterprise) { create(:distributor_enterprise) }
+ context "as an admin user" do
+ let(:admin) { create(:admin_user) }
+ let!(:enterprise) { create(:distributor_enterprise) }
+
+ before do
+ allow(controller).to receive(:spree_current_user) { admin }
+ end
+
+ describe "updating an enterprise" do
+ let(:enterprise_params) do
+ {
+ external_billing_id: 'INV123456'
+ }
+ end
+
+ it "changes the external_billing_id field" do
+ api_put :update, id: enterprise.id, enterprise: enterprise_params
+ expect(response.status).to eq 200
+
+ expect(enterprise.reload.external_billing_id).to eq('INV123456')
+ end
+ end
+ end
+
context "as an enterprise owner" do
let(:enterprise_owner) { create(:user) }
let!(:enterprise) { create(:distributor_enterprise, owner: enterprise_owner) }
diff --git a/spec/serializers/api/admin/enterprise_serializer_spec.rb b/spec/serializers/api/admin/enterprise_serializer_spec.rb
index 3f20145771f..8483c2e27c9 100644
--- a/spec/serializers/api/admin/enterprise_serializer_spec.rb
+++ b/spec/serializers/api/admin/enterprise_serializer_spec.rb
@@ -5,10 +5,11 @@
RSpec.describe Api::Admin::EnterpriseSerializer do
include FileHelper
- let(:enterprise) { create(:distributor_enterprise) }
+ let(:enterprise) { create(:distributor_enterprise, external_billing_id: 'INV123456') }
it "serializes an enterprise" do
serializer = Api::Admin::EnterpriseSerializer.new enterprise
expect(serializer.to_json).to match enterprise.name
+ expect(serializer.as_json[:external_billing_id]).to eq('INV123456')
end
context "for logo" do
diff --git a/spec/system/admin/reports/revenues_by_hub_spec.rb b/spec/system/admin/reports/revenues_by_hub_spec.rb
index 079a94d2fa2..9834fc55ba0 100644
--- a/spec/system/admin/reports/revenues_by_hub_spec.rb
+++ b/spec/system/admin/reports/revenues_by_hub_spec.rb
@@ -37,9 +37,9 @@
tax_rate_name: "Tax 1"
)
end
- let(:distributor1) { create(:enterprise, name: "Hub 1", owner:) }
+ let(:distributor1) { create(:enterprise, name: "Hub 1", owner:, external_billing_id: 'INV1234') }
let(:distributor2) { create(:enterprise, name: "Hub 2", owner:) }
- let(:distributor3) { create(:enterprise, name: "Hub 3", owner:) }
+ let(:distributor3) { create(:enterprise, name: "Hub 3", owner:, external_billing_id: 'INV4321') }
let(:owner) { create(:user, email: 'email@email.com') }
let(:order_cycle) { create(:simple_order_cycle) }
let(:product) { create(:product) }
@@ -64,6 +64,7 @@
"Hub",
"Hub ID",
"Hub Business Number",
+ "Hub External Billing Id",
"Hub Legal Name",
"Hub Contact Name",
"Hub Public Email",
@@ -86,6 +87,7 @@
"Hub 1",
order.distributor.id,
"none",
+ "INV1234",
"none",
"none",
"none",
@@ -110,6 +112,7 @@
"none",
"none",
"none",
+ "none",
"email@email.com",
"none",
"10 Lovely Street",
@@ -128,6 +131,7 @@
"Hub 3",
order_with_voucher_tax_excluded.distributor.id,
"none",
+ "INV4321",
"none",
"none",
"none",