API endpoint for serializing SalesOrder objects

This commit is contained in:
Oliver Walters 2020-04-20 20:11:21 +10:00
parent 5901b21e78
commit 9f97d81e83
6 changed files with 206 additions and 12 deletions

View File

@ -18,9 +18,10 @@ from .version import inventreeVersion, inventreeInstanceName
from plugins import plugins as inventree_plugins from plugins import plugins as inventree_plugins
# Load barcode plugins # Load barcode plugins
print("INFO: Loading plugins") print("Loading barcode plugins")
barcode_plugins = inventree_plugins.load_barcode_plugins() barcode_plugins = inventree_plugins.load_barcode_plugins()
print("Loading action plugins")
action_plugins = inventree_plugins.load_action_plugins() action_plugins = inventree_plugins.load_action_plugins()

View File

@ -25,7 +25,7 @@ from part.api import part_api_urls, bom_api_urls
from company.api import company_api_urls from company.api import company_api_urls
from stock.api import stock_api_urls from stock.api import stock_api_urls
from build.api import build_api_urls from build.api import build_api_urls
from order.api import po_api_urls from order.api import order_api_urls
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
@ -49,7 +49,7 @@ apipatterns = [
url(r'^company/', include(company_api_urls)), url(r'^company/', include(company_api_urls)),
url(r'^stock/', include(stock_api_urls)), url(r'^stock/', include(stock_api_urls)),
url(r'^build/', include(build_api_urls)), url(r'^build/', include(build_api_urls)),
url(r'^po/', include(po_api_urls)), url(r'^order/', include(order_api_urls)),
# User URLs # User URLs
url(r'^user/', include(user_urls)), url(r'^user/', include(user_urls)),

View File

@ -19,9 +19,12 @@ from company.models import SupplierPart
from .models import PurchaseOrder, PurchaseOrderLineItem from .models import PurchaseOrder, PurchaseOrderLineItem
from .serializers import POSerializer, POLineItemSerializer from .serializers import POSerializer, POLineItemSerializer
from .models import SalesOrder, SalesOrderLineItem
from .serializers import SalseOrderSerializer
class POList(generics.ListCreateAPIView): class POList(generics.ListCreateAPIView):
""" API endpoint for accessing a list of Order objects """ API endpoint for accessing a list of PurchaseOrder objects
- GET: Return list of PO objects (with filters) - GET: Return list of PO objects (with filters)
- POST: Create a new PurchaseOrder object - POST: Create a new PurchaseOrder object
@ -184,10 +187,124 @@ class POLineItemDetail(generics.RetrieveUpdateAPIView):
] ]
po_api_urls = [ class SOList(generics.ListCreateAPIView):
url(r'^order/(?P<pk>\d+)/?$', PODetail.as_view(), name='api-po-detail'), """
url(r'^order/?$', POList.as_view(), name='api-po-list'), API endpoint for accessing a list of SalesOrder objects.
url(r'^line/(?P<pk>\d+)/?$', POLineItemDetail.as_view(), name='api-po-line-detail'), - GET: Return list of SO objects (with filters)
url(r'^line/?$', POLineItemList.as_view(), name='api-po-line-list'), - POST: Create a new SalesOrder
"""
queryset = SalesOrder.objects.all()
serializer_class = SalseOrderSerializer
def get_serializer(self, *args, **kwargs):
try:
kwargs['customer_detail'] = str2bool(self.request.query_params.get('customer_detail', False))
except AttributeError:
pass
# Ensure the context is passed through to the serializer
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(
'customer',
'lines'
)
queryset = SalseOrderSerializer.annotate_queryset(queryset)
return queryset
def filter_queryset(self, queryset):
"""
Perform custom filtering operations on the SalesOrder queryset.
"""
queryset = super().filter_queryset(queryset)
params = self.request.query_params
status = params.get('status', None)
if status is not None:
queryset = queryset.filter(status=status)
# TODO - Filter by part / stockitem / etc
return queryset
permission_classes = [
permissions.IsAuthenticated
]
filter_backends = [
DjangoFilterBackend,
filters.SearchFilter,
filters.OrderingFilter,
]
filter_fields = [
'customer',
]
ordering_fields = [
'creation_date',
'reference'
]
ordering = '-creation_date'
class SODetail(generics.RetrieveUpdateAPIView):
"""
API endpoint for detail view of a SalesOrder object.
"""
queryset = SalesOrder.objects.all()
serializer_class = SalseOrderSerializer
def get_serializer(self, *args, **kwargs):
try:
kwargs['customer_detail'] = str2bool(self.request.query_params.get('customer_detail', False))
except AttributeError:
pass
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('customer', 'lines')
queryset = SalseOrderSerializer.annotate_queryset(queryset)
return queryset
permission_classes = [permissions.IsAuthenticated]
order_api_urls = [
# API endpoints for purchase orders
url(r'^po/(?P<pk>\d+)/$', PODetail.as_view(), name='api-po-detail'),
url(r'^po/$', POList.as_view(), name='api-po-list'),
# API endpoints for purchase order line items
url(r'^po-line/(?P<pk>\d+)/$', POLineItemDetail.as_view(), name='api-po-line-detail'),
url(r'^po-line/$', POLineItemList.as_view(), name='api-po-line-list'),
# API endpoints for sales ordesr
url(r'^so/(?P<pk>\d+)/$', SODetail.as_view(), name='api-so-detail'),
url(r'^so/$', SOList.as_view(), name='api-so-list'),
] ]

View File

@ -0,0 +1,20 @@
# Generated by Django 3.0.5 on 2020-04-20 10:10
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('company', '0021_remove_supplierpart_manufacturer_name'),
('order', '0020_auto_20200420_0940'),
]
operations = [
migrations.AlterField(
model_name='salesorder',
name='customer',
field=models.ForeignKey(help_text='Customer', limit_choices_to={'is_customer': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sales_orders', to='company.Company'),
),
]

View File

@ -257,7 +257,7 @@ class SalesOrder(Order):
customer = models.ForeignKey(Company, customer = models.ForeignKey(Company,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
limit_choices_to={'is_supplier', True}, limit_choices_to={'is_customer': True},
related_name='sales_orders', related_name='sales_orders',
help_text=_("Customer"), help_text=_("Customer"),
) )

View File

@ -13,10 +13,11 @@ from InvenTree.serializers import InvenTreeModelSerializer
from company.serializers import CompanyBriefSerializer from company.serializers import CompanyBriefSerializer
from .models import PurchaseOrder, PurchaseOrderLineItem from .models import PurchaseOrder, PurchaseOrderLineItem
from .models import SalesOrder, SalesOrderLineItem
class POSerializer(InvenTreeModelSerializer): class POSerializer(InvenTreeModelSerializer):
""" Serializes an Order object """ """ Serializer for a PurchaseOrder object """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -83,3 +84,58 @@ class POLineItemSerializer(InvenTreeModelSerializer):
'part', 'part',
'received', 'received',
] ]
class SalseOrderSerializer(InvenTreeModelSerializer):
"""
Serializers for the SalesOrder object
"""
def __init__(self, *args, **kwargs):
customer_detail = kwargs.pop('customer_detail', False)
super().__init__(*args, **kwargs)
if customer_detail is not True:
self.fields.pop('customer_detail')
@staticmethod
def annotate_queryset(queryset):
"""
Add extra information to the queryset
"""
return queryset.annotate(
line_items=Count('lines'),
)
customer_detail = CompanyBriefSerializer(source='customer', 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:
model = SalesOrder
fields = [
'pk',
'issue_date',
'complete_date',
'creation_date',
'line_items',
'link',
'reference',
'customer',
'customer_detail',
'customer_reference',
'status',
'status_text',
'notes',
]
read_only_fields = [
'reference',
'status'
]