Consolidation of PurchaseOrder API

This commit is contained in:
Oliver Walters 2020-04-20 09:41:21 +10:00
parent fee6246a8f
commit 99fcbcc646
2 changed files with 104 additions and 44 deletions

View File

@ -14,6 +14,7 @@ from django.conf import settings
from django.conf.urls import url from django.conf.urls import url
from InvenTree.status_codes import OrderStatus from InvenTree.status_codes import OrderStatus
from InvenTree.helpers import str2bool
import os import os
@ -34,66 +35,67 @@ class POList(generics.ListCreateAPIView):
queryset = PurchaseOrder.objects.all() queryset = PurchaseOrder.objects.all()
serializer_class = POSerializer serializer_class = POSerializer
def list(self, request, *args, **kwargs): def get_serializer(self, *args, **kwargs):
queryset = self.get_queryset().prefetch_related('supplier', 'lines') try:
kwargs['supplier_detail'] = str2bool(self.request.query_params.get('supplier_detail', False))
except AttributeError:
pass
queryset = self.filter_queryset(queryset) # Ensure the request context is passed through
kwargs['context'] = self.get_serializer_context()
return self.serializer_class(*args, **kwargs)
def get_queryset(self, *args, **kwargs):
queryset = super().get_queryset(*args, **kwargs)
queryset = queryset.prefetch_related(
'supplier',
'lines',
)
queryset = POSerializer.annotate_queryset(queryset)
return queryset
def filter_queryset(self, queryset):
# Perform basic filtering
queryset = super().filter_queryset(queryset)
params = self.request.query_params
# Special filtering for 'status' field # Special filtering for 'status' field
if 'status' in request.GET: status = params.get('status', None)
status = request.GET['status']
if status is not None:
# First attempt to filter by integer value # First attempt to filter by integer value
try: queryset = queryset.filter(status=status)
status = int(status)
queryset = queryset.filter(status=status)
except ValueError:
try:
value = OrderStatus.value(status)
queryset = queryset.filter(status=value)
except ValueError:
pass
# Attempt to filter by part # Attempt to filter by part
if 'part' in request.GET: part = params.get('part', None)
if part is not None:
try: try:
part = Part.objects.get(pk=request.GET['part']) part = Part.objects.get(pk=part)
queryset = queryset.filter(id__in=[p.id for p in part.purchase_orders()]) queryset = queryset.filter(id__in=[p.id for p in part.purchase_orders()])
except (Part.DoesNotExist, ValueError): except (Part.DoesNotExist, ValueError):
pass pass
# Attempt to filter by supplier part # Attempt to filter by supplier part
if 'supplier_part' in request.GET: supplier_part = params.get('supplier_part', None)
if supplier_part is not None:
try: try:
supplier_part = SupplierPart.objects.get(pk=request.GET['supplier_part']) supplier_part = SupplierPart.objects.get(pk=supplier_part)
queryset = queryset.filter(id__in=[p.id for p in supplier_part.purchase_orders()]) queryset = queryset.filter(id__in=[p.id for p in supplier_part.purchase_orders()])
except (ValueError, SupplierPart.DoesNotExist): except (ValueError, SupplierPart.DoesNotExist):
pass pass
data = queryset.values( return queryset
'pk',
'supplier',
'supplier_reference',
'supplier__name',
'supplier__image',
'reference',
'description',
'link',
'status',
'notes',
'creation_date',
)
for item in data:
order = queryset.get(pk=item['pk'])
item['supplier__image'] = os.path.join(settings.MEDIA_URL, item['supplier__image'])
item['status_text'] = OrderStatus.label(item['status'])
item['lines'] = order.lines.count()
return Response(data)
permission_classes = [ permission_classes = [
permissions.IsAuthenticated, permissions.IsAuthenticated,
@ -123,6 +125,31 @@ class PODetail(generics.RetrieveUpdateAPIView):
queryset = PurchaseOrder.objects.all() queryset = PurchaseOrder.objects.all()
serializer_class = POSerializer serializer_class = POSerializer
def get_serializer(self, *args, **kwargs):
try:
kwargs['supplier_detail'] = str2bool(self.request.query_params.get('supplier_detail', False))
except AttributeError:
pass
# Ensure the request context is passed through
kwargs['context'] = self.get_serializer_context()
return self.serializer_class(*args, **kwargs)
def get_queryset(self, *args, **kwargs):
queryset = super().get_queryset(*args, **kwargs)
queryset = queryset.prefetch_related(
'supplier',
'lines',
)
queryset = POSerializer.annotate_queryset(queryset)
return queryset
permission_classes = [ permission_classes = [
permissions.IsAuthenticated permissions.IsAuthenticated
] ]

View File

@ -5,7 +5,12 @@ JSON serializers for the Order API
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
from rest_framework import serializers
from django.db.models import Count
from InvenTree.serializers import InvenTreeModelSerializer from InvenTree.serializers import InvenTreeModelSerializer
from company.serializers import CompanyBriefSerializer
from .models import PurchaseOrder, PurchaseOrderLineItem from .models import PurchaseOrder, PurchaseOrderLineItem
@ -13,17 +18,45 @@ from .models import PurchaseOrder, PurchaseOrderLineItem
class POSerializer(InvenTreeModelSerializer): class POSerializer(InvenTreeModelSerializer):
""" Serializes an Order object """ """ Serializes an Order object """
def __init__(self, *args, **kwargs):
supplier_detail = kwargs.pop('supplier_detail', False)
super().__init__(*args, **kwargs)
if supplier_detail is not True:
self.fields.pop('supplier_detail')
@staticmethod
def annotate_queryset(queryset):
"""
Add extra information to the queryset
"""
return queryset.annotate(
line_items=Count('lines'),
)
supplier_detail = CompanyBriefSerializer(source='supplier', many=False, read_only=True)
line_items = serializers.IntegerField(read_only=True)
status_text = serializers.CharField(source='get_status_display', read_only=True)
class Meta: class Meta:
model = PurchaseOrder model = PurchaseOrder
fields = [ fields = [
'pk', 'pk',
'supplier',
'supplier_reference',
'reference',
'description', 'description',
'line_items',
'link', 'link',
'reference',
'supplier',
'supplier_detail',
'supplier_reference',
'status', 'status',
'status_text',
'notes', 'notes',
] ]