mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Adds API endpoints for ReturnOrder
- Add list endpoint - Add detail endpoint - Adds required serializer models
This commit is contained in:
parent
047e65cdce
commit
ab1ed84636
@ -277,6 +277,19 @@ class SalesOrderAllocationAdmin(ImportExportModelAdmin):
|
||||
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):
|
||||
"""Admin class for the ReturnOrder model"""
|
||||
|
||||
|
@ -28,7 +28,7 @@ from InvenTree.mixins import (CreateAPI, ListAPI, ListCreateAPI,
|
||||
from InvenTree.status_codes import PurchaseOrderStatus, SalesOrderStatus
|
||||
from order.admin import (PurchaseOrderExtraLineResource,
|
||||
PurchaseOrderLineItemResource, PurchaseOrderResource,
|
||||
SalesOrderExtraLineResource,
|
||||
ReturnOrderResource, SalesOrderExtraLineResource,
|
||||
SalesOrderLineItemResource, SalesOrderResource)
|
||||
from part.models import Part
|
||||
from plugin.serializers import MetadataSerializer
|
||||
@ -1213,6 +1213,106 @@ class PurchaseOrderAttachmentDetail(AttachmentMixin, RetrieveUpdateDestroyAPI):
|
||||
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):
|
||||
"""Calendar export for Purchase/Sales Orders
|
||||
|
||||
@ -1450,6 +1550,16 @@ order_api_urls = [
|
||||
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
|
||||
re_path(r'^calendar/(?P<ordertype>purchase-order|sales-order)/calendar.ics', OrderCalendarExport(), name='api-po-so-calendar'),
|
||||
]
|
||||
|
@ -46,9 +46,13 @@ from users import models as UserModels
|
||||
logger = logging.getLogger('inventree')
|
||||
|
||||
|
||||
class TotalPriceMixin:
|
||||
class TotalPriceMixin(models.Model):
|
||||
"""Mixin which provides 'total_price' field for an order"""
|
||||
|
||||
class Meta:
|
||||
"""Meta for MetadataMixin."""
|
||||
abstract = True
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""Update the total_price field when saved"""
|
||||
|
||||
@ -1573,7 +1577,7 @@ class ReturnOrder(Order):
|
||||
@staticmethod
|
||||
def get_api_url():
|
||||
"""Return the API URL associated with the ReturnOrder model"""
|
||||
return reverse('api-return-list')
|
||||
return reverse('api-return-order-list')
|
||||
|
||||
@classmethod
|
||||
def api_defaults(cls, request):
|
||||
@ -1645,7 +1649,7 @@ class ReturnOrderAttachment(InvenTreeAttachment):
|
||||
def get_api_url():
|
||||
"""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):
|
||||
"""Return the directory path where ReturnOrderAttachment files are located"""
|
||||
|
@ -645,7 +645,7 @@ class PurchaseOrderAttachmentSerializer(InvenTreeAttachmentSerializer):
|
||||
|
||||
|
||||
class SalesOrderSerializer(AbstractOrderSerializer, InvenTreeModelSerializer):
|
||||
"""Serializers for the SalesOrder object."""
|
||||
"""Serializer for the SalesOrder model class"""
|
||||
|
||||
class Meta:
|
||||
"""Metaclass options."""
|
||||
@ -1398,3 +1398,78 @@ class SalesOrderAttachmentSerializer(InvenTreeAttachmentSerializer):
|
||||
fields = InvenTreeAttachmentSerializer.attachment_fields([
|
||||
'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',
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user