diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py index 3d2d143eea..d84136c2bf 100644 --- a/InvenTree/plugin/models.py +++ b/InvenTree/plugin/models.py @@ -16,6 +16,30 @@ import common.models from plugin import InvenTreePlugin, registry +class MetadataMixin(models.Model): + """ + Model mixin class which adds a JSON metadata field to a model, + for use by any (and all) plugins. + + The intent of this mixin is to provide a metadata field on a model instance, + for plugins to read / modify as required, to store any extra information. + + The assumptions for models implementing this mixin are: + + - The internal InvenTree business logic will make no use of this field + - Multiple plugins may read / write to this metadata field, and not assume they have sole rights + """ + + class Meta: + abstract = True + + metadata = models.JSONField( + blank=True, null=True, + verbose_name=_('Plugin Metadata'), + help_text=_('JSON metadata field, for use by external plugins'), + ) + + class PluginConfig(models.Model): """ A PluginConfig object holds settings for plugins. diff --git a/InvenTree/stock/migrations/0075_auto_20220515_1440.py b/InvenTree/stock/migrations/0075_auto_20220515_1440.py new file mode 100644 index 0000000000..814a97edb3 --- /dev/null +++ b/InvenTree/stock/migrations/0075_auto_20220515_1440.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.13 on 2022-05-15 14:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stock', '0074_alter_stockitem_batch'), + ] + + operations = [ + migrations.AddField( + model_name='stockitem', + name='metadata', + field=models.JSONField(blank=True, help_text='JSON metadata field, for use by external plugins', null=True, verbose_name='Plugin Metadata'), + ), + migrations.AddField( + model_name='stocklocation', + name='metadata', + field=models.JSONField(blank=True, help_text='JSON metadata field, for use by external plugins', null=True, verbose_name='Plugin Metadata'), + ), + migrations.AlterUniqueTogether( + name='stocklocation', + unique_together=set(), + ), + ] diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index a46d43b007..acd021caa6 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -38,6 +38,7 @@ import common.models import report.models import label.models +from plugin.models import MetadataMixin from plugin.events import trigger_event from InvenTree.status_codes import StockStatus, StockHistoryCode @@ -51,7 +52,7 @@ from company import models as CompanyModels from part import models as PartModels -class StockLocation(InvenTreeTree): +class StockLocation(MetadataMixin, InvenTreeTree): """ Organization tree for StockItem objects A "StockLocation" can be considered a warehouse, or storage location Stock locations can be heirarchical as required @@ -242,7 +243,7 @@ def generate_batch_code(): return Template(batch_template).render(context) -class StockItem(MPTTModel): +class StockItem(MetadataMixin, MPTTModel): """ A StockItem object represents a quantity of physical instances of a part.