2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-15 19:45:46 +00:00

Adds API endpoints for ReturnOrder

- Add list endpoint
- Add detail endpoint
- Adds required serializer models
This commit is contained in:
Oliver
2023-03-14 17:09:09 +11:00
parent 047e65cdce
commit ab1ed84636
4 changed files with 207 additions and 5 deletions

View File

@ -277,6 +277,19 @@ class SalesOrderAllocationAdmin(ImportExportModelAdmin):
autocomplete_fields = ('line', 'shipment', 'item',) autocomplete_fields = ('line', 'shipment', 'item',)
class ReturnOrderResource(InvenTreeResource):
"""Class for managing import / export of ReturnOrder data"""
class Meta:
"""Metaclass options"""
model = models.ReturnOrder
skip_unchanged = True
clean_model_instances = True
exclude = [
'metadata',
]
class ReturnOrderAdmin(ImportExportModelAdmin): class ReturnOrderAdmin(ImportExportModelAdmin):
"""Admin class for the ReturnOrder model""" """Admin class for the ReturnOrder model"""

View File

@ -28,7 +28,7 @@ from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
from order.admin import (PurchaseOrderExtraLineResource, from order.admin import (PurchaseOrderExtraLineResource,
PurchaseOrderLineItemResource, PurchaseOrderResource, PurchaseOrderLineItemResource, PurchaseOrderResource,
SalesOrderExtraLineResource, ReturnOrderResource, SalesOrderExtraLineResource,
SalesOrderLineItemResource, SalesOrderResource) SalesOrderLineItemResource, SalesOrderResource)
from part.models import Part from part.models import Part
from plugin.serializers import MetadataSerializer from plugin.serializers import MetadataSerializer
@ -1213,6 +1213,106 @@ class PurchaseOrderAttachmentDetail(AttachmentMixin, RetrieveUpdateDestroyAPI):
serializer_class = serializers.PurchaseOrderAttachmentSerializer serializer_class = serializers.PurchaseOrderAttachmentSerializer
class ReturnOrderFilter(OrderFilter):
"""Custom API filters for the ReturnOrderList endpoint"""
class Meta:
"""Metaclass options"""
model = models.ReturnOrder
fields = [
'customer',
]
class ReturnOrderList(APIDownloadMixin, ListCreateAPI):
"""API endpoint for accessing a list of ReturnOrder objects"""
queryset = models.ReturnOrder.objects.all()
serializer_class = serializers.ReturnOrderSerializer
filterset_class = ReturnOrderFilter
def get_serializer(self, *args, **kwargs):
"""Return serializer instance for this endpoint"""
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 download_queryset(self, queryset, export_format):
"""Download this queryset as a file"""
dataset = ReturnOrderResource().export(queryset=queryset)
filedata = dataset.export(export_format)
filename = f"InvenTree_ReturnOrders.{export_format}"
return DownloadFile(filedata, filename)
def filter_queryset(self, queryset):
"""Custom queryset filtering not supported by the ReturnOrderFilter class"""
return queryset
filter_backends = [
rest_filters.DjangoFilterBackend,
filters.SearchFilter,
InvenTreeOrderingFilter,
]
ordering_field_aliases = {
'reference': ['reference_int', 'reference'],
}
filterset_fields = [
'customer',
]
ordering_fields = [
'creation_date',
'reference',
'customer__name',
'customer_reference',
'status',
'target_date',
]
search_fields = [
'customer__name',
'reference',
'description',
'customer_reference',
]
ordering = '-reference'
class ReturnOrderDetail(RetrieveUpdateDestroyAPI):
"""API endpoint for detail view of a single ReturnOrder object"""
queryset = models.ReturnOrder.objects.all()
serializer_class = serializers.ReturnOrderSerializer
def get_serializer(self, *args, **kwargs):
"""Return the serializer instance for this endpoint"""
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)
class OrderCalendarExport(ICalFeed): class OrderCalendarExport(ICalFeed):
"""Calendar export for Purchase/Sales Orders """Calendar export for Purchase/Sales Orders
@ -1450,6 +1550,16 @@ order_api_urls = [
re_path(r'^.*$', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'), re_path(r'^.*$', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'),
])), ])),
# API endpoints for return orders
re_path(r'^return/', include([
# Return Order detail
path('<int:pk>/', ReturnOrderDetail.as_view(), name='api-return-order-detail'),
# Return Order list
re_path(r'^.*$', ReturnOrderList.as_view(), name='api-return-order-list'),
])),
# API endpoint for subscribing to ICS calendar of purchase/sales orders # API endpoint for subscribing to ICS calendar of purchase/sales orders
re_path(r'^calendar/(?P<ordertype>purchase-order|sales-order)/calendar.ics', OrderCalendarExport(), name='api-po-so-calendar'), re_path(r'^calendar/(?P<ordertype>purchase-order|sales-order)/calendar.ics', OrderCalendarExport(), name='api-po-so-calendar'),
] ]

View File

@ -46,9 +46,13 @@ from users import models as UserModels
logger = logging.getLogger('inventree') logger = logging.getLogger('inventree')
class TotalPriceMixin: class TotalPriceMixin(models.Model):
"""Mixin which provides 'total_price' field for an order""" """Mixin which provides 'total_price' field for an order"""
class Meta:
"""Meta for MetadataMixin."""
abstract = True
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
"""Update the total_price field when saved""" """Update the total_price field when saved"""
@ -1573,7 +1577,7 @@ class ReturnOrder(Order):
@staticmethod @staticmethod
def get_api_url(): def get_api_url():
"""Return the API URL associated with the ReturnOrder model""" """Return the API URL associated with the ReturnOrder model"""
return reverse('api-return-list') return reverse('api-return-order-list')
@classmethod @classmethod
def api_defaults(cls, request): def api_defaults(cls, request):
@ -1645,7 +1649,7 @@ class ReturnOrderAttachment(InvenTreeAttachment):
def get_api_url(): def get_api_url():
"""Return the API URL associated with the ReturnOrderAttachment class""" """Return the API URL associated with the ReturnOrderAttachment class"""
return reverse('api-return-attachment-list') return reverse('api-return-order-attachment-list')
def getSubdir(self): def getSubdir(self):
"""Return the directory path where ReturnOrderAttachment files are located""" """Return the directory path where ReturnOrderAttachment files are located"""

View File

@ -645,7 +645,7 @@ class PurchaseOrderAttachmentSerializer(InvenTreeAttachmentSerializer):
class SalesOrderSerializer(AbstractOrderSerializer, InvenTreeModelSerializer): class SalesOrderSerializer(AbstractOrderSerializer, InvenTreeModelSerializer):
"""Serializers for the SalesOrder object.""" """Serializer for the SalesOrder model class"""
class Meta: class Meta:
"""Metaclass options.""" """Metaclass options."""
@ -1398,3 +1398,78 @@ class SalesOrderAttachmentSerializer(InvenTreeAttachmentSerializer):
fields = InvenTreeAttachmentSerializer.attachment_fields([ fields = InvenTreeAttachmentSerializer.attachment_fields([
'order', 'order',
]) ])
class ReturnOrderSerializer(InvenTreeModelSerializer):
"""Serializer for the ReturnOrder model class"""
class Meta:
"""Metaclass options"""
model = order.models.ReturnOrder
fields = [
'pk',
'creation_date',
'customer',
'customer_detail',
'customer_reference',
'description',
'link',
'notes',
'reference',
'responsible',
'responsible_detail',
'status',
'status_text',
]
read_only_fields = [
'status',
'creation_date',
]
def __init__(self, *args, **kwargs):
"""Initialization routine for the serializer"""
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):
"""Custom annotation for the serializer queryset"""
# TODO
return queryset
customer_detail = CompanyBriefSerializer(source='customer', many=False, read_only=True)
status_text = serializers.CharField(source='get_status_display', read_only=True)
responsible_detail = OwnerSerializer(source='responsible', read_only=True, many=False)
reference = serializers.CharField(required=True)
def validate_reference(self, reference):
"""Custom validation for the reference field"""
order.models.ReturnOrder.validate_reference_field(reference)
return reference
class ReturnOrderAttachmentSerializer(InvenTreeAttachmentSerializer):
"""Serializer for the ReturnOrderAttachment model"""
class Meta:
"""Metaclass options"""
model = order.models.ReturnOrderAttachment
fields = InvenTreeAttachmentSerializer.attachment_fields([
'order',
])