mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-17 04:25:42 +00:00
Add Metadata to further models (#4410)
* Add metadata for ManufacturerPart * Add Metadata for SupplierPart * Add metadata to label models * Add metadata to order line items * Add metadata to shipment * Add metadata to Build and BuildItem * Add metadata to BomItem * Add metadata to PartParameterTemplate * Syntax, lint * Fix isort style * Lint * Correction of model name * Metadata for Reports * Fix silly error * Fix silly error * Correct model name * Correct model name * Correction * Correct company urls * Apply generic model to Report metadat * Rename/remove redundant import * Remove shadowing of report in loop variable * Update import ordering * More corrections * better docstrings * Correct names for API endpoints * Default to PO, required for api-doc to work * Changes by @matmair * Suppress metadata from Bom export * Add migration files * Increment API version * Add tests for all Metadata models, even previously existing ones * Update tests * Fix * Delay tests * Fix imports * Fix tests * API Version number * Remove unused import * isort * Revent unintended change of cache
This commit is contained in:
@ -14,7 +14,9 @@ from InvenTree.api import AttachmentMixin, APIDownloadMixin, ListCreateDestroyAP
|
||||
from InvenTree.helpers import str2bool, isNull, DownloadFile
|
||||
from InvenTree.filters import InvenTreeOrderingFilter
|
||||
from InvenTree.status_codes import BuildStatus
|
||||
from InvenTree.mixins import CreateAPI, RetrieveUpdateDestroyAPI, ListCreateAPI
|
||||
from InvenTree.mixins import CreateAPI, RetrieveUpdateAPI, RetrieveUpdateDestroyAPI, ListCreateAPI
|
||||
|
||||
from plugin.serializers import MetadataSerializer
|
||||
|
||||
import build.admin
|
||||
import build.serializers
|
||||
@ -290,6 +292,16 @@ class BuildOrderContextMixin:
|
||||
return ctx
|
||||
|
||||
|
||||
class BuildOrderMetadata(RetrieveUpdateAPI):
|
||||
"""API endpoint for viewing / updating BuildOrder metadata."""
|
||||
|
||||
def get_serializer(self, *args, **kwargs):
|
||||
"""Return MetadataSerializer instance"""
|
||||
return MetadataSerializer(Build, *args, **kwargs)
|
||||
|
||||
queryset = Build.objects.all()
|
||||
|
||||
|
||||
class BuildOutputCreate(BuildOrderContextMixin, CreateAPI):
|
||||
"""API endpoint for creating new build output(s)."""
|
||||
|
||||
@ -461,6 +473,16 @@ class BuildItemList(ListCreateAPI):
|
||||
]
|
||||
|
||||
|
||||
class BuildItemMetadata(RetrieveUpdateAPI):
|
||||
"""API endpoint for viewing / updating BuildItem metadata."""
|
||||
|
||||
def get_serializer(self, *args, **kwargs):
|
||||
"""Return MetadataSerializer instance"""
|
||||
return MetadataSerializer(BuildItem, *args, **kwargs)
|
||||
|
||||
queryset = BuildItem.objects.all()
|
||||
|
||||
|
||||
class BuildAttachmentList(AttachmentMixin, ListCreateDestroyAPIView):
|
||||
"""API endpoint for listing (and creating) BuildOrderAttachment objects."""
|
||||
|
||||
@ -493,7 +515,10 @@ build_api_urls = [
|
||||
|
||||
# Build Items
|
||||
re_path(r'^item/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', BuildItemDetail.as_view(), name='api-build-item-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^metadata/', BuildItemMetadata.as_view(), name='api-build-item-metadata'),
|
||||
re_path(r'^.*$', BuildItemDetail.as_view(), name='api-build-item-detail'),
|
||||
])),
|
||||
re_path(r'^.*$', BuildItemList.as_view(), name='api-build-item-list'),
|
||||
])),
|
||||
|
||||
@ -507,6 +532,7 @@ build_api_urls = [
|
||||
re_path(r'^finish/', BuildFinish.as_view(), name='api-build-finish'),
|
||||
re_path(r'^cancel/', BuildCancel.as_view(), name='api-build-cancel'),
|
||||
re_path(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
|
||||
re_path(r'^metadata/', BuildOrderMetadata.as_view(), name='api-build-metadata'),
|
||||
re_path(r'^.*$', BuildDetail.as_view(), name='api-build-detail'),
|
||||
])),
|
||||
|
||||
|
23
InvenTree/build/migrations/0039_auto_20230317_0816.py
Normal file
23
InvenTree/build/migrations/0039_auto_20230317_0816.py
Normal file
@ -0,0 +1,23 @@
|
||||
# Generated by Django 3.2.18 on 2023-03-17 08:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('build', '0038_alter_build_responsible'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='build',
|
||||
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='builditem',
|
||||
name='metadata',
|
||||
field=models.JSONField(blank=True, help_text='JSON metadata field, for use by external plugins', null=True, verbose_name='Plugin Metadata'),
|
||||
),
|
||||
]
|
@ -33,6 +33,7 @@ import InvenTree.ready
|
||||
import InvenTree.tasks
|
||||
|
||||
from plugin.events import trigger_event
|
||||
from plugin.models import MetadataMixin
|
||||
|
||||
import common.notifications
|
||||
from part import models as PartModels
|
||||
@ -40,7 +41,7 @@ from stock import models as StockModels
|
||||
from users import models as UserModels
|
||||
|
||||
|
||||
class Build(MPTTModel, ReferenceIndexingMixin):
|
||||
class Build(MPTTModel, MetadataMixin, ReferenceIndexingMixin):
|
||||
"""A Build object organises the creation of new StockItem objects from other existing StockItem objects.
|
||||
|
||||
Attributes:
|
||||
@ -1140,7 +1141,7 @@ class BuildOrderAttachment(InvenTreeAttachment):
|
||||
build = models.ForeignKey(Build, on_delete=models.CASCADE, related_name='attachments')
|
||||
|
||||
|
||||
class BuildItem(models.Model):
|
||||
class BuildItem(MetadataMixin, models.Model):
|
||||
"""A BuildItem links multiple StockItem objects to a Build.
|
||||
|
||||
These are used to allocate part stock to a build. Once the Build is completed, the parts are removed from stock and the BuildItemAllocation objects are removed.
|
||||
|
@ -570,6 +570,29 @@ class BuildTest(BuildTestBase):
|
||||
|
||||
self.assertTrue(messages.filter(user__pk=4).exists())
|
||||
|
||||
def test_metadata(self):
|
||||
"""Unit tests for the metadata field."""
|
||||
|
||||
# Make sure a BuildItem exists before trying to run this test
|
||||
b = BuildItem(stock_item=self.stock_1_2, build=self.build, install_into=self.output_1, quantity=10)
|
||||
b.save()
|
||||
|
||||
for model in [Build, BuildItem]:
|
||||
p = model.objects.first()
|
||||
self.assertIsNone(p.metadata)
|
||||
|
||||
self.assertIsNone(p.get_metadata('test'))
|
||||
self.assertEqual(p.get_metadata('test', backup_value=123), 123)
|
||||
|
||||
# Test update via the set_metadata() method
|
||||
p.set_metadata('test', 3)
|
||||
self.assertEqual(p.get_metadata('test'), 3)
|
||||
|
||||
for k in ['apple', 'banana', 'carrot', 'carrot', 'banana']:
|
||||
p.set_metadata(k, k)
|
||||
|
||||
self.assertEqual(len(p.metadata.keys()), 4)
|
||||
|
||||
|
||||
class AutoAllocationTests(BuildTestBase):
|
||||
"""Tests for auto allocating stock against a build order"""
|
||||
|
Reference in New Issue
Block a user