diff --git a/InvenTree/InvenTree/api_version.py b/InvenTree/InvenTree/api_version.py
index 8c0cc057cc..e23914b191 100644
--- a/InvenTree/InvenTree/api_version.py
+++ b/InvenTree/InvenTree/api_version.py
@@ -2,11 +2,14 @@
# InvenTree API version
-INVENTREE_API_VERSION = 153
+INVENTREE_API_VERSION = 154
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
+v154 -> 2023-11-21 : https://github.com/inventree/InvenTree/pull/5944
+ - Adds "responsible" field to the ProjectCode table
+
v153 -> 2023-11-21 : https://github.com/inventree/InvenTree/pull/5956
- Adds override_min and override_max fields to part pricing API
diff --git a/InvenTree/common/migrations/0022_projectcode_responsible.py b/InvenTree/common/migrations/0022_projectcode_responsible.py
new file mode 100644
index 0000000000..a40a420f87
--- /dev/null
+++ b/InvenTree/common/migrations/0022_projectcode_responsible.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2.23 on 2023-11-20 08:04
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('users', '0010_alter_apitoken_key'),
+ ('common', '0021_auto_20230805_1748'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='projectcode',
+ name='responsible',
+ field=models.ForeignKey(blank=True, help_text='User or group responsible for this project', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='project_codes', to='users.owner', verbose_name='Responsible'),
+ ),
+ ]
diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
index e825d21ec9..918387a2d6 100644
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -51,6 +51,7 @@ import InvenTree.tasks
import InvenTree.validators
import order.validators
import report.helpers
+import users.models
from plugin import registry
logger = logging.getLogger('inventree')
@@ -126,6 +127,15 @@ class ProjectCode(InvenTree.models.MetadataMixin, models.Model):
help_text=_('Project description'),
)
+ responsible = models.ForeignKey(
+ users.models.Owner,
+ on_delete=models.SET_NULL,
+ blank=True, null=True,
+ verbose_name=_('Responsible'),
+ help_text=_('User or group responsible for this project'),
+ related_name='project_codes',
+ )
+
class SettingsKeyType(TypedDict, total=False):
"""Type definitions for a SettingsKeyType
diff --git a/InvenTree/common/serializers.py b/InvenTree/common/serializers.py
index c791f39f83..06a6d226e9 100644
--- a/InvenTree/common/serializers.py
+++ b/InvenTree/common/serializers.py
@@ -11,6 +11,7 @@ from InvenTree.helpers import get_objectreference
from InvenTree.helpers_model import construct_absolute_url
from InvenTree.serializers import (InvenTreeImageSerializerField,
InvenTreeModelSerializer)
+from users.serializers import OwnerSerializer
class SettingsValueField(serializers.Field):
@@ -281,9 +282,13 @@ class ProjectCodeSerializer(InvenTreeModelSerializer):
fields = [
'pk',
'code',
- 'description'
+ 'description',
+ 'responsible',
+ 'responsible_detail',
]
+ responsible_detail = OwnerSerializer(source='responsible', read_only=True)
+
class FlagSerializer(serializers.Serializer):
"""Serializer for feature flags."""
diff --git a/InvenTree/templates/InvenTree/settings/settings_staff_js.html b/InvenTree/templates/InvenTree/settings/settings_staff_js.html
index f5e89462c8..3ee6ab180d 100644
--- a/InvenTree/templates/InvenTree/settings/settings_staff_js.html
+++ b/InvenTree/templates/InvenTree/settings/settings_staff_js.html
@@ -145,6 +145,25 @@ onPanelLoad('project-codes', function() {
sortable: true,
title: '{% trans "Project Code" %}',
},
+ {
+ field: 'responsible',
+ title: '{% trans "Responsible" %}',
+ formatter: function(value, row) {
+ if (!row.responsible_detail) {
+ return '-';
+ }
+
+ var html = row.responsible_detail.name;
+
+ if (row.responsible_detail.label == '{% trans "group" %}') {
+ html += ``;
+ } else {
+ html += ``;
+ }
+
+ return html;
+ }
+ },
{
field: 'description',
sortable: false,
@@ -171,6 +190,7 @@ onPanelLoad('project-codes', function() {
fields: {
code: {},
description: {},
+ responsible: {},
},
refreshTable: '#project-code-table',
});
diff --git a/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx b/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx
index 52663727fa..6493c142e3 100644
--- a/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx
+++ b/src/frontend/src/components/tables/settings/ProjectCodeTable.tsx
@@ -14,7 +14,7 @@ import { apiUrl } from '../../../states/ApiState';
import { useUserState } from '../../../states/UserState';
import { AddItemButton } from '../../buttons/AddItemButton';
import { TableColumn } from '../Column';
-import { DescriptionColumn } from '../ColumnRenderers';
+import { DescriptionColumn, ResponsibleColumn } from '../ColumnRenderers';
import { InvenTreeTable } from '../InvenTreeTable';
import { RowAction, RowDeleteAction, RowEditAction } from '../RowActions';
@@ -33,7 +33,8 @@ export function ProjectCodeTable() {
sortable: true,
title: t`Project Code`
},
- DescriptionColumn()
+ DescriptionColumn(),
+ ResponsibleColumn()
];
}, []);
@@ -49,7 +50,8 @@ export function ProjectCodeTable() {
title: t`Edit project code`,
fields: {
code: {},
- description: {}
+ description: {},
+ responsible: {}
},
onFormSuccess: refreshTable,
successMessage: t`Project code updated`
@@ -82,7 +84,8 @@ export function ProjectCodeTable() {
title: t`Add project code`,
fields: {
code: {},
- description: {}
+ description: {},
+ responsible: {}
},
onFormSuccess: refreshTable,
successMessage: t`Added project code`