diff --git a/src/backend/InvenTree/common/setting/system.py b/src/backend/InvenTree/common/setting/system.py
index 7a1c7349f9..9616c2f359 100644
--- a/src/backend/InvenTree/common/setting/system.py
+++ b/src/backend/InvenTree/common/setting/system.py
@@ -1003,6 +1003,12 @@ SYSTEM_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
'validator': bool,
'after_save': reload_plugin_registry,
},
+ 'PROJECT_CODES_ENABLED': {
+ 'name': _('Enable project codes'),
+ 'description': _('Enable project codes for tracking projects'),
+ 'default': False,
+ 'validator': bool,
+ },
'STOCKTAKE_ENABLE': {
'name': _('Stocktake Functionality'),
'description': _(
diff --git a/src/frontend/src/forms/BuildForms.tsx b/src/frontend/src/forms/BuildForms.tsx
index 8beffe2547..1f3c64c847 100644
--- a/src/frontend/src/forms/BuildForms.tsx
+++ b/src/frontend/src/forms/BuildForms.tsx
@@ -132,6 +132,10 @@ export function useBuildOrderFields({
fields.create_child_builds = {};
}
+ if (!globalSettings.isSet('PROJECT_CODES_ENABLED', true)) {
+ delete fields.project_code;
+ }
+
return fields;
}, [create, destination, batchCode, globalSettings]);
}
diff --git a/src/frontend/src/forms/PurchaseOrderForms.tsx b/src/frontend/src/forms/PurchaseOrderForms.tsx
index 50e0b2c66e..9b8415a0d6 100644
--- a/src/frontend/src/forms/PurchaseOrderForms.tsx
+++ b/src/frontend/src/forms/PurchaseOrderForms.tsx
@@ -147,6 +147,8 @@ export function usePurchaseOrderFields({
supplierId?: number;
duplicateOrderId?: number;
}): ApiFormFieldSet {
+ const globalSettings = useGlobalSettingsState();
+
return useMemo(() => {
const fields: ApiFormFieldSet = {
reference: {
@@ -217,8 +219,12 @@ export function usePurchaseOrderFields({
};
}
+ if (!globalSettings.isSet('PROJECT_CODES_ENABLED', true)) {
+ delete fields.project_code;
+ }
+
return fields;
- }, [duplicateOrderId, supplierId]);
+ }, [duplicateOrderId, supplierId, globalSettings]);
}
/**
diff --git a/src/frontend/src/forms/ReturnOrderForms.tsx b/src/frontend/src/forms/ReturnOrderForms.tsx
index 80d0d1188c..91fe3acd6c 100644
--- a/src/frontend/src/forms/ReturnOrderForms.tsx
+++ b/src/frontend/src/forms/ReturnOrderForms.tsx
@@ -15,6 +15,7 @@ import { ApiEndpoints } from '../enums/ApiEndpoints';
import { ModelType } from '../enums/ModelType';
import { useCreateApiFormModal } from '../hooks/UseForm';
import { apiUrl } from '../states/ApiState';
+import { useGlobalSettingsState } from '../states/SettingsState';
import { StatusFilterOptions } from '../tables/Filter';
export function useReturnOrderFields({
@@ -22,6 +23,8 @@ export function useReturnOrderFields({
}: {
duplicateOrderId?: number;
}): ApiFormFieldSet {
+ const globalSettings = useGlobalSettingsState();
+
return useMemo(() => {
const fields: ApiFormFieldSet = {
reference: {},
@@ -82,8 +85,12 @@ export function useReturnOrderFields({
};
}
+ if (!globalSettings.isSet('PROJECT_CODES_ENABLED', true)) {
+ delete fields.project_code;
+ }
+
return fields;
- }, [duplicateOrderId]);
+ }, [duplicateOrderId, globalSettings]);
}
export function useReturnOrderLineItemFields({
diff --git a/src/frontend/src/forms/SalesOrderForms.tsx b/src/frontend/src/forms/SalesOrderForms.tsx
index 72d986a025..c191357dda 100644
--- a/src/frontend/src/forms/SalesOrderForms.tsx
+++ b/src/frontend/src/forms/SalesOrderForms.tsx
@@ -16,6 +16,7 @@ import { ApiEndpoints } from '../enums/ApiEndpoints';
import { ModelType } from '../enums/ModelType';
import { useCreateApiFormModal } from '../hooks/UseForm';
import { apiUrl } from '../states/ApiState';
+import { useGlobalSettingsState } from '../states/SettingsState';
import { PartColumn } from '../tables/ColumnRenderers';
export function useSalesOrderFields({
@@ -23,6 +24,8 @@ export function useSalesOrderFields({
}: {
duplicateOrderId?: number;
}): ApiFormFieldSet {
+ const globalSettings = useGlobalSettingsState();
+
return useMemo(() => {
const fields: ApiFormFieldSet = {
reference: {},
@@ -76,8 +79,12 @@ export function useSalesOrderFields({
};
}
+ if (!globalSettings.isSet('PROJECT_CODES_ENABLED', true)) {
+ delete fields.project_code;
+ }
+
return fields;
- }, [duplicateOrderId]);
+ }, [duplicateOrderId, globalSettings]);
}
export function useSalesOrderLineItemFields({
diff --git a/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx b/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx
index c8d81c1b06..639737c181 100644
--- a/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx
+++ b/src/frontend/src/pages/Index/Settings/AdminCenter/Index.tsx
@@ -26,6 +26,7 @@ import PageTitle from '../../../../components/nav/PageTitle';
import { SettingsHeader } from '../../../../components/nav/SettingsHeader';
import type { PanelType } from '../../../../components/panels/Panel';
import { PanelGroup } from '../../../../components/panels/PanelGroup';
+import { GlobalSettingList } from '../../../../components/settings/SettingList';
import { Loadable } from '../../../../functions/loading';
import { useUserState } from '../../../../states/UserState';
@@ -144,6 +145,7 @@ export default function AdminCenter() {
icon: ,
content: (
+
)
diff --git a/src/frontend/src/tables/ColumnRenderers.tsx b/src/frontend/src/tables/ColumnRenderers.tsx
index d01d62f8ef..393ba8df39 100644
--- a/src/frontend/src/tables/ColumnRenderers.tsx
+++ b/src/frontend/src/tables/ColumnRenderers.tsx
@@ -14,6 +14,7 @@ import { formatCurrency, formatDate } from '../defaults/formatters';
import type { ModelType } from '../enums/ModelType';
import { resolveItem } from '../functions/conversion';
import { cancelEvent } from '../functions/events';
+import { useGlobalSettingsState } from '../states/SettingsState';
import type { TableColumn, TableColumnProps } from './Column';
import { ProjectCodeHoverCard } from './TableHoverCard';
@@ -161,11 +162,15 @@ export function LineItemsProgressColumn(): TableColumn {
}
export function ProjectCodeColumn(props: TableColumnProps): TableColumn {
+ const globalSettings = useGlobalSettingsState.getState();
+ const enabled = globalSettings.isSet('PROJECT_CODES_ENABLED', true);
+
return {
accessor: 'project_code',
ordering: 'project_code',
sortable: true,
title: t`Project Code`,
+ hidden: !enabled,
render: (record: any) => {
const project_code = resolveItem(
record,
diff --git a/src/frontend/src/tables/Filter.tsx b/src/frontend/src/tables/Filter.tsx
index dbeca42138..fd8bce2856 100644
--- a/src/frontend/src/tables/Filter.tsx
+++ b/src/frontend/src/tables/Filter.tsx
@@ -5,6 +5,7 @@ import type {
StatusCodeListInterface
} from '../components/render/StatusRenderer';
import type { ModelType } from '../enums/ModelType';
+import { useGlobalSettingsState } from '../states/SettingsState';
import { type StatusLookup, useGlobalStatusState } from '../states/StatusState';
/**
@@ -28,9 +29,16 @@ export type TableFilterType = 'boolean' | 'choice' | 'date' | 'text';
/**
* Interface for the table filter type. Provides a number of options for selecting filter value:
*
+ * name: The name of the filter (used for query string)
+ * label: The label to display in the UI (human readable)
+ * description: A description of the filter (human readable)
+ * type: The type of filter (see TableFilterType)
* choices: A list of TableFilterChoice objects
* choiceFunction: A function which returns a list of TableFilterChoice objects
- * statusType: A ModelType which is used to generate a list of status codes
+ * defaultValue: The default value for the filter
+ * value: The current value of the filter
+ * displayValue: The current display value of the filter
+ * active: Whether the filter is active (false = hidden, not used)
*/
export type TableFilter = {
name: string;
@@ -198,11 +206,15 @@ export function CompletedAfterFilter(): TableFilter {
}
export function HasProjectCodeFilter(): TableFilter {
+ const globalSettings = useGlobalSettingsState.getState();
+ const enabled = globalSettings.isSet('PROJECT_CODES_ENABLED', true);
+
return {
name: 'has_project_code',
type: 'boolean',
label: t`Has Project Code`,
- description: t`Show orders with an assigned project code`
+ description: t`Show orders with an assigned project code`,
+ active: enabled
};
}
@@ -220,10 +232,14 @@ export function OrderStatusFilter({
export function ProjectCodeFilter({
choices
}: { choices: TableFilterChoice[] }): TableFilter {
+ const globalSettings = useGlobalSettingsState.getState();
+ const enabled = globalSettings.isSet('PROJECT_CODES_ENABLED', true);
+
return {
name: 'project_code',
label: t`Project Code`,
description: t`Filter by project code`,
+ active: enabled,
choices: choices
};
}