mirror of
https://github.com/inventree/InvenTree.git
synced 2026-07-08 16:11:23 +00:00
Project code active (#12250)
* Add 'active' field to the ProjectCode model - Allows retiring of old project codes without deleting * Update UI table * Refactor ProjectCodeField * Add unit test * Bump API version and CHANGELOG
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 512
|
||||
INVENTREE_API_VERSION = 513
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v513 -> 2026-06-25 : https://github.com/inventree/InvenTree/pull/12250
|
||||
- Adds "active" field to the ProjectCode model and API endpoints
|
||||
|
||||
v512 -> 2026-06-20 : https://github.com/inventree/InvenTree/pull/12022
|
||||
- Adds optional "merge" field to each item in the Stock Transfer API endpoint
|
||||
- When merge is enabled, transferred stock is combined into compatible existing stock at the destination
|
||||
|
||||
@@ -115,7 +115,8 @@ class BarcodeScanResultAdmin(admin.ModelAdmin):
|
||||
class ProjectCodeAdmin(admin.ModelAdmin):
|
||||
"""Admin settings for ProjectCode."""
|
||||
|
||||
list_display = ('code', 'description')
|
||||
list_display = ('code', 'description', 'active')
|
||||
list_filter = ('active',)
|
||||
|
||||
search_fields = ('code', 'description')
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ class ProjectCodeList(DataExportViewMixin, ListCreateAPI):
|
||||
filter_backends = SEARCH_ORDER_FILTER
|
||||
|
||||
ordering_fields = ['code']
|
||||
|
||||
filterset_fields = ['active']
|
||||
search_fields = ['code', 'description']
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Generated by Django 5.2.15 on 2026-06-25 03:13
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("common", "0044_notificationmessage_charfield_pk"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="projectcode",
|
||||
name="active",
|
||||
field=models.BooleanField(
|
||||
default=True,
|
||||
help_text="Is this project code active?",
|
||||
verbose_name="Active",
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -181,6 +181,12 @@ class ProjectCode(InvenTree.models.InvenTreeMetadataModel):
|
||||
help_text=_('Project description'),
|
||||
)
|
||||
|
||||
active = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name=_('Active'),
|
||||
help_text=_('Is this project code active?'),
|
||||
)
|
||||
|
||||
responsible = models.ForeignKey(
|
||||
users.models.Owner,
|
||||
on_delete=models.SET_NULL,
|
||||
|
||||
@@ -417,7 +417,14 @@ class ProjectCodeSerializer(DataImportExportSerializerMixin, InvenTreeModelSeria
|
||||
"""Meta options for ProjectCodeSerializer."""
|
||||
|
||||
model = common_models.ProjectCode
|
||||
fields = ['pk', 'code', 'description', 'responsible', 'responsible_detail']
|
||||
fields = [
|
||||
'pk',
|
||||
'code',
|
||||
'description',
|
||||
'active',
|
||||
'responsible',
|
||||
'responsible_detail',
|
||||
]
|
||||
|
||||
responsible_detail = OwnerSerializer(
|
||||
source='responsible', read_only=True, allow_null=True
|
||||
|
||||
@@ -1752,6 +1752,22 @@ class ProjectCodesTest(InvenTreeAPITestCase):
|
||||
str(response.data['code']),
|
||||
)
|
||||
|
||||
def test_filter_active(self):
|
||||
"""Test that the 'active' field can be filtered via the API."""
|
||||
# Mark one code as inactive
|
||||
code = ProjectCode.objects.first()
|
||||
code.active = False
|
||||
code.save()
|
||||
|
||||
active_count = ProjectCode.objects.filter(active=True).count()
|
||||
inactive_count = ProjectCode.objects.filter(active=False).count()
|
||||
|
||||
response = self.get(self.url, data={'active': True}, expected_code=200)
|
||||
self.assertEqual(len(response.data), active_count)
|
||||
|
||||
response = self.get(self.url, data={'active': False}, expected_code=200)
|
||||
self.assertEqual(len(response.data), inactive_count)
|
||||
|
||||
def test_write_access(self):
|
||||
"""Test that non-staff users have read-only access."""
|
||||
# By default user has staff access, can create a new project code
|
||||
|
||||
Reference in New Issue
Block a user