diff --git a/app/serializers/api/admin/enterprise_serializer.rb b/app/serializers/api/admin/enterprise_serializer.rb
index f189e57fd0..7c29b41e70 100644
--- a/app/serializers/api/admin/enterprise_serializer.rb
+++ b/app/serializers/api/admin/enterprise_serializer.rb
@@ -15,7 +15,7 @@ module Api
: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 234fadac77..1dd5b5a838 100644
--- a/app/services/permitted_attributes/enterprise.rb
+++ b/app/services/permitted_attributes/enterprise.rb
@@ -37,7 +37,7 @@ module PermittedAttributes
: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 04609e9b58..e5bbf4eed0 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 6c8fa2dbdc..a1a5bb33c7 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 0000000000..bd0292bbe3
--- /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 be371a9499..37bab4a1e6 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 @@ ActiveRecord::Schema[7.0].define(version: 2024_11_12_230401) do
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 e539c77fed..8b10386a6f 100644
--- a/lib/reporting/reports/revenues_by_hub/base.rb
+++ b/lib/reporting/reports/revenues_by_hub/base.rb
@@ -24,6 +24,7 @@ module Reporting
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 4caf3e38d7..415f75cc2a 100644
--- a/spec/controllers/admin/enterprises_controller_spec.rb
+++ b/spec/controllers/admin/enterprises_controller_spec.rb
@@ -409,6 +409,16 @@ RSpec.describe Admin::EnterprisesController, type: :controller do
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 d0529f3eeb..55fd6a2a15 100644
--- a/spec/controllers/api/v0/enterprises_controller_spec.rb
+++ b/spec/controllers/api/v0/enterprises_controller_spec.rb
@@ -7,6 +7,30 @@ RSpec.describe Api::V0::EnterprisesController, type: :controller do
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 3f20145771..8483c2e27c 100644
--- a/spec/serializers/api/admin/enterprise_serializer_spec.rb
+++ b/spec/serializers/api/admin/enterprise_serializer_spec.rb
@@ -5,10 +5,11 @@ require "spec_helper"
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 079a94d2fa..9834fc55ba 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 @@ RSpec.describe "Revenues By Hub Reports" do
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 @@ RSpec.describe "Revenues By Hub Reports" do
"Hub",
"Hub ID",
"Hub Business Number",
+ "Hub External Billing Id",
"Hub Legal Name",
"Hub Contact Name",
"Hub Public Email",
@@ -86,6 +87,7 @@ RSpec.describe "Revenues By Hub Reports" do
"Hub 1",
order.distributor.id,
"none",
+ "INV1234",
"none",
"none",
"none",
@@ -110,6 +112,7 @@ RSpec.describe "Revenues By Hub Reports" do
"none",
"none",
"none",
+ "none",
"email@email.com",
"none",
"10 Lovely Street",
@@ -128,6 +131,7 @@ RSpec.describe "Revenues By Hub Reports" do
"Hub 3",
order_with_voucher_tax_excluded.distributor.id,
"none",
+ "INV4321",
"none",
"none",
"none",