2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-17 20:45:44 +00:00

Merge pull request #2957 from SchrodingersGat/locate-mixin

Adds plugin mixin to "locate" items
This commit is contained in:
Oliver
2022-05-16 22:57:20 +10:00
committed by GitHub
28 changed files with 789 additions and 32 deletions

View File

@ -27,6 +27,8 @@ import order.serializers as serializers
from part.models import Part
from users.models import Owner
from plugin.serializers import MetadataSerializer
class GeneralExtraLineList:
"""
@ -347,6 +349,15 @@ class PurchaseOrderIssue(PurchaseOrderContextMixin, generics.CreateAPIView):
serializer_class = serializers.PurchaseOrderIssueSerializer
class PurchaseOrderMetadata(generics.RetrieveUpdateAPIView):
"""API endpoint for viewing / updating PurchaseOrder metadata"""
def get_serializer(self, *args, **kwargs):
return MetadataSerializer(models.PurchaseOrder, *args, **kwargs)
queryset = models.PurchaseOrder.objects.all()
class PurchaseOrderReceive(PurchaseOrderContextMixin, generics.CreateAPIView):
"""
API endpoint to receive stock items against a purchase order.
@ -916,6 +927,15 @@ class SalesOrderComplete(SalesOrderContextMixin, generics.CreateAPIView):
serializer_class = serializers.SalesOrderCompleteSerializer
class SalesOrderMetadata(generics.RetrieveUpdateAPIView):
"""API endpoint for viewing / updating SalesOrder metadata"""
def get_serializer(self, *args, **kwargs):
return MetadataSerializer(models.SalesOrder, *args, **kwargs)
queryset = models.SalesOrder.objects.all()
class SalesOrderAllocateSerials(SalesOrderContextMixin, generics.CreateAPIView):
"""
API endpoint to allocation stock items against a SalesOrder,
@ -1138,10 +1158,13 @@ order_api_urls = [
# Individual purchase order detail URLs
re_path(r'^(?P<pk>\d+)/', include([
re_path(r'^issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'),
re_path(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'),
re_path(r'^cancel/', PurchaseOrderCancel.as_view(), name='api-po-cancel'),
re_path(r'^complete/', PurchaseOrderComplete.as_view(), name='api-po-complete'),
re_path(r'^issue/', PurchaseOrderIssue.as_view(), name='api-po-issue'),
re_path(r'^metadata/', PurchaseOrderMetadata.as_view(), name='api-po-metadata'),
re_path(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'),
# PurchaseOrder detail API endpoint
re_path(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'),
])),
@ -1178,10 +1201,13 @@ order_api_urls = [
# Sales order detail view
re_path(r'^(?P<pk>\d+)/', include([
re_path(r'^cancel/', SalesOrderCancel.as_view(), name='api-so-cancel'),
re_path(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'),
re_path(r'^allocate/', SalesOrderAllocate.as_view(), name='api-so-allocate'),
re_path(r'^allocate-serials/', SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials'),
re_path(r'^cancel/', SalesOrderCancel.as_view(), name='api-so-cancel'),
re_path(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'),
re_path(r'^metadata/', SalesOrderMetadata.as_view(), name='api-so-metadata'),
# SalesOrder detail endpoint
re_path(r'^.*$', SalesOrderDetail.as_view(), name='api-so-detail'),
])),

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.13 on 2022-05-16 11:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('order', '0066_alter_purchaseorder_supplier'),
]
operations = [
migrations.AddField(
model_name='purchaseorder',
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='salesorder',
name='metadata',
field=models.JSONField(blank=True, help_text='JSON metadata field, for use by external plugins', null=True, verbose_name='Plugin Metadata'),
),
]

View File

@ -30,7 +30,9 @@ from users import models as UserModels
from part import models as PartModels
from stock import models as stock_models
from company.models import Company, SupplierPart
from plugin.events import trigger_event
from plugin.models import MetadataMixin
import InvenTree.helpers
from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField
@ -97,7 +99,7 @@ def get_next_so_number():
return reference
class Order(ReferenceIndexingMixin):
class Order(MetadataMixin, ReferenceIndexingMixin):
""" Abstract model for an order.
Instances of this class:

View File

@ -306,6 +306,22 @@ class PurchaseOrderTest(OrderTest):
self.assertEqual(po.status, PurchaseOrderStatus.PLACED)
def test_po_metadata(self):
url = reverse('api-po-metadata', kwargs={'pk': 1})
self.patch(
url,
{
'metadata': {
'yam': 'yum',
}
},
expected_code=200
)
order = models.PurchaseOrder.objects.get(pk=1)
self.assertEqual(order.get_metadata('yam'), 'yum')
class PurchaseOrderReceiveTest(OrderTest):
"""
@ -875,6 +891,22 @@ class SalesOrderTest(OrderTest):
self.assertEqual(so.status, SalesOrderStatus.CANCELLED)
def test_so_metadata(self):
url = reverse('api-so-metadata', kwargs={'pk': 1})
self.patch(
url,
{
'metadata': {
'xyz': 'abc',
}
},
expected_code=200
)
order = models.SalesOrder.objects.get(pk=1)
self.assertEqual(order.get_metadata('xyz'), 'abc')
class SalesOrderAllocateTest(OrderTest):
"""