diff --git a/src/backend/InvenTree/InvenTree/api_version.py b/src/backend/InvenTree/InvenTree/api_version.py index 396614153a..10c2aa52c1 100644 --- a/src/backend/InvenTree/InvenTree/api_version.py +++ b/src/backend/InvenTree/InvenTree/api_version.py @@ -1,13 +1,17 @@ """InvenTree API version information.""" # InvenTree API version -INVENTREE_API_VERSION = 315 +INVENTREE_API_VERSION = 316 """Increment this API version number whenever there is a significant change to the API that any clients need to know about.""" INVENTREE_API_TEXT = """ +v316 - 2025-02-26 : https://github.com/inventree/InvenTree/pull/9185 + - Allow 'icon' field to be nullified in the PartCategory API + - Allow 'custom_icon' field to be nullified in the StockLocation API + v315 - 2025-02-22 : https://github.com/inventree/InvenTree/pull/9150 - Remove outdated 'url' field from some API endpoints diff --git a/src/backend/InvenTree/part/migrations/0133_alter_partcategory__icon.py b/src/backend/InvenTree/part/migrations/0133_alter_partcategory__icon.py new file mode 100644 index 0000000000..754d08cad6 --- /dev/null +++ b/src/backend/InvenTree/part/migrations/0133_alter_partcategory__icon.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.19 on 2025-02-25 22:14 + +import common.icons +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("part", "0132_partparametertemplate_selectionlist"), + ] + + operations = [ + migrations.AlterField( + model_name="partcategory", + name="_icon", + field=models.CharField( + blank=True, + db_column="icon", + help_text="Icon (optional)", + max_length=100, + null=True, + validators=[common.icons.validate_icon], + verbose_name="Icon", + ), + ), + ] diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index 81ba09adb8..ba686d53b2 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -128,6 +128,7 @@ class PartCategory(InvenTree.models.InvenTreeTree): _icon = models.CharField( blank=True, + null=True, max_length=100, verbose_name=_('Icon'), help_text=_('Icon (optional)'), diff --git a/src/backend/InvenTree/part/serializers.py b/src/backend/InvenTree/part/serializers.py index 636c587291..6850259bd4 100644 --- a/src/backend/InvenTree/part/serializers.py +++ b/src/backend/InvenTree/part/serializers.py @@ -136,7 +136,11 @@ class CategorySerializer( ) icon = serializers.CharField( - required=False, allow_blank=True, help_text=_('Icon (optional)'), max_length=100 + required=False, + allow_blank=True, + allow_null=True, + help_text=_('Icon (optional)'), + max_length=100, ) parent_default_location = serializers.IntegerField(read_only=True) diff --git a/src/backend/InvenTree/part/test_category.py b/src/backend/InvenTree/part/test_category.py index 5def83ee04..341a43ae4a 100644 --- a/src/backend/InvenTree/part/test_category.py +++ b/src/backend/InvenTree/part/test_category.py @@ -419,7 +419,7 @@ class CategoryTest(TestCase): """Test the category icon.""" # No default icon set cat = PartCategory.objects.create(name='Test Category') - self.assertEqual(cat.icon, '') + self.assertIn(cat.icon, ['', None]) # Set a default icon InvenTreeSetting.set_setting('PART_CATEGORY_DEFAULT_ICON', 'ti:package:outline') @@ -428,7 +428,7 @@ class CategoryTest(TestCase): # Set custom icon to default icon and assert that it does not get written to the database cat.icon = 'ti:package:outline' cat.save() - self.assertEqual(cat._icon, '') + self.assertIn(cat._icon, ['', None]) # Set a different custom icon and assert that it takes precedence cat.icon = 'ti:tag:outline' @@ -439,4 +439,4 @@ class CategoryTest(TestCase): # Test that the icon can be set to None again cat.icon = '' cat.save() - self.assertEqual(cat.icon, '') + self.assertIn(cat.icon, ['', None]) diff --git a/src/backend/InvenTree/stock/migrations/0114_alter_stocklocation_custom_icon.py b/src/backend/InvenTree/stock/migrations/0114_alter_stocklocation_custom_icon.py new file mode 100644 index 0000000000..1e21e79e8a --- /dev/null +++ b/src/backend/InvenTree/stock/migrations/0114_alter_stocklocation_custom_icon.py @@ -0,0 +1,27 @@ +# Generated by Django 4.2.19 on 2025-02-25 22:14 + +import common.icons +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("stock", "0113_stockitem_status_custom_key_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="stocklocation", + name="custom_icon", + field=models.CharField( + blank=True, + db_column="icon", + help_text="Icon (optional)", + max_length=100, + null=True, + validators=[common.icons.validate_icon], + verbose_name="Icon", + ), + ), + ] diff --git a/src/backend/InvenTree/stock/models.py b/src/backend/InvenTree/stock/models.py index ce8ed2025b..99ce63b7d7 100644 --- a/src/backend/InvenTree/stock/models.py +++ b/src/backend/InvenTree/stock/models.py @@ -171,6 +171,7 @@ class StockLocation( custom_icon = models.CharField( blank=True, + null=True, max_length=100, verbose_name=_('Icon'), help_text=_('Icon (optional)'),