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:
@ -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'),
|
||||
])),
|
||||
|
||||
|
23
InvenTree/order/migrations/0067_auto_20220516_1120.py
Normal file
23
InvenTree/order/migrations/0067_auto_20220516_1120.py
Normal 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'),
|
||||
),
|
||||
]
|
@ -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:
|
||||
|
@ -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):
|
||||
"""
|
||||
|
Reference in New Issue
Block a user