mirror of
https://github.com/inventree/InvenTree.git
synced 2025-06-17 12:35:46 +00:00
[PUI] Stocktake (#7704)
* Adjust playwright test * Add StocktakeReport table in the "admin" section * Allow deletion of individual stocktake reports * Add placeholder buttons * Adds placeholder panel for stocktake data * Implement <PartStocktakeTable /> * Add modal to generate a new report * Generate stocktake report from part table * Adjust table value * panel display tweaks * Improve query efficiency for supplier price breaks * Refator part stocktake detail panel * Fix role checks * Cleanup code * Fix "double loader" in <InvenTreeTable /> * API efficiency improvements * Bump API version * Tweak playwright test * Update playwright test --------- Co-authored-by: Matthias Mair <code@mjmair.com>
This commit is contained in:
@ -1,13 +1,16 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 255
|
||||
INVENTREE_API_VERSION = 256
|
||||
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
|
||||
v256 - 2024-09-19 : https://github.com/inventree/InvenTree/pull/7704
|
||||
- Adjustments for "stocktake" (stock history) API endpoints
|
||||
|
||||
v255 - 2024-09-19 : https://github.com/inventree/InvenTree/pull/8145
|
||||
- Enables copying line items when duplicating an order
|
||||
|
||||
|
@ -436,6 +436,13 @@ class SupplierPriceBreakList(ListCreateAPI):
|
||||
serializer_class = SupplierPriceBreakSerializer
|
||||
filterset_class = SupplierPriceBreakFilter
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return annotated queryset for the SupplierPriceBreak list endpoint."""
|
||||
queryset = super().get_queryset()
|
||||
queryset = SupplierPriceBreakSerializer.annotate_queryset(queryset)
|
||||
|
||||
return queryset
|
||||
|
||||
def get_serializer(self, *args, **kwargs):
|
||||
"""Return serializer instance for this endpoint."""
|
||||
try:
|
||||
@ -468,6 +475,13 @@ class SupplierPriceBreakDetail(RetrieveUpdateDestroyAPI):
|
||||
queryset = SupplierPriceBreak.objects.all()
|
||||
serializer_class = SupplierPriceBreakSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return annotated queryset for the SupplierPriceBreak list endpoint."""
|
||||
queryset = super().get_queryset()
|
||||
queryset = SupplierPriceBreakSerializer.annotate_queryset(queryset)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
manufacturer_part_api_urls = [
|
||||
path(
|
||||
|
@ -512,6 +512,13 @@ class SupplierPriceBreakSerializer(
|
||||
if not part_detail:
|
||||
self.fields.pop('part_detail', None)
|
||||
|
||||
@staticmethod
|
||||
def annotate_queryset(queryset):
|
||||
"""Prefetch related fields for the queryset."""
|
||||
queryset = queryset.select_related('part', 'part__supplier', 'part__part')
|
||||
|
||||
return queryset
|
||||
|
||||
quantity = InvenTreeDecimalField()
|
||||
|
||||
price = InvenTreeMoneySerializer(allow_null=True, required=True, label=_('Price'))
|
||||
|
@ -991,11 +991,30 @@ class SalesOrderShipmentFilter(rest_filters.FilterSet):
|
||||
return queryset.filter(delivery_date=None)
|
||||
|
||||
|
||||
class SalesOrderShipmentList(ListCreateAPI):
|
||||
"""API list endpoint for SalesOrderShipment model."""
|
||||
class SalesOrderShipmentMixin:
|
||||
"""Mixin class for SalesOrderShipment endpoints."""
|
||||
|
||||
queryset = models.SalesOrderShipment.objects.all()
|
||||
serializer_class = serializers.SalesOrderShipmentSerializer
|
||||
|
||||
def get_queryset(self, *args, **kwargs):
|
||||
"""Return annotated queryset for this endpoint."""
|
||||
queryset = super().get_queryset(*args, **kwargs)
|
||||
|
||||
queryset = queryset.prefetch_related(
|
||||
'order',
|
||||
'order__customer',
|
||||
'allocations',
|
||||
'allocations__item',
|
||||
'allocations__item__part',
|
||||
)
|
||||
|
||||
return queryset
|
||||
|
||||
|
||||
class SalesOrderShipmentList(SalesOrderShipmentMixin, ListCreateAPI):
|
||||
"""API list endpoint for SalesOrderShipment model."""
|
||||
|
||||
filterset_class = SalesOrderShipmentFilter
|
||||
|
||||
filter_backends = SEARCH_ORDER_FILTER_ALIAS
|
||||
@ -1003,12 +1022,9 @@ class SalesOrderShipmentList(ListCreateAPI):
|
||||
ordering_fields = ['delivery_date', 'shipment_date']
|
||||
|
||||
|
||||
class SalesOrderShipmentDetail(RetrieveUpdateDestroyAPI):
|
||||
class SalesOrderShipmentDetail(SalesOrderShipmentMixin, RetrieveUpdateDestroyAPI):
|
||||
"""API detail endpooint for SalesOrderShipment model."""
|
||||
|
||||
queryset = models.SalesOrderShipment.objects.all()
|
||||
serializer_class = serializers.SalesOrderShipmentSerializer
|
||||
|
||||
|
||||
class SalesOrderShipmentComplete(CreateAPI):
|
||||
"""API endpoint for completing (shipping) a SalesOrderShipment."""
|
||||
|
@ -1715,6 +1715,13 @@ class PartStocktakeReportList(ListAPI):
|
||||
ordering = '-pk'
|
||||
|
||||
|
||||
class PartStocktakeReportDetail(RetrieveUpdateDestroyAPI):
|
||||
"""API endpoint for detail view of a single PartStocktakeReport object."""
|
||||
|
||||
queryset = PartStocktakeReport.objects.all()
|
||||
serializer_class = part_serializers.PartStocktakeReportSerializer
|
||||
|
||||
|
||||
class PartStocktakeReportGenerate(CreateAPI):
|
||||
"""API endpoint for manually generating a new PartStocktakeReport."""
|
||||
|
||||
@ -2184,6 +2191,11 @@ part_api_urls = [
|
||||
PartStocktakeReportGenerate.as_view(),
|
||||
name='api-part-stocktake-report-generate',
|
||||
),
|
||||
path(
|
||||
'<int:pk>/',
|
||||
PartStocktakeReportDetail.as_view(),
|
||||
name='api-part-stocktake-report-detail',
|
||||
),
|
||||
path(
|
||||
'',
|
||||
PartStocktakeReportList.as_view(),
|
||||
|
@ -1193,6 +1193,7 @@ class PartStocktakeReportSerializer(InvenTree.serializers.InvenTreeModelSerializ
|
||||
|
||||
model = PartStocktakeReport
|
||||
fields = ['pk', 'date', 'report', 'part_count', 'user', 'user_detail']
|
||||
read_only_fields = ['date', 'report', 'part_count', 'user']
|
||||
|
||||
user_detail = InvenTree.serializers.UserSerializer(
|
||||
source='user', read_only=True, many=False
|
||||
|
Reference in New Issue
Block a user