mirror of
https://github.com/inventree/InvenTree.git
synced 2026-03-20 03:04:41 +00:00
Refactor part parameter exporter plugin
- Any model which supports parameters can use this now - Update documentation
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""Custom exporter for Parameter data."""
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import DataExportMixin
|
||||
|
||||
|
||||
class ParameterExportOptionsSerializer(serializers.Serializer):
|
||||
"""Custom export options for the ParameterExporter plugin."""
|
||||
|
||||
export_exclude_inactive_parameters = serializers.BooleanField(
|
||||
default=True,
|
||||
label=_('Exclude Inactive'),
|
||||
help_text=_('Exclude parameters which are inactive'),
|
||||
)
|
||||
|
||||
|
||||
class ParameterExporter(DataExportMixin, InvenTreePlugin):
|
||||
"""Builtin plugin for exporting Parameter data.
|
||||
|
||||
Extends the export process, to include all associated Parameter data.
|
||||
"""
|
||||
|
||||
NAME = 'Parameter Exporter'
|
||||
SLUG = 'parameter-exporter'
|
||||
TITLE = _('Parameter Exporter')
|
||||
DESCRIPTION = _('Exporter for model parameter data')
|
||||
VERSION = '2.0.0'
|
||||
AUTHOR = _('InvenTree contributors')
|
||||
|
||||
ExportOptionsSerializer = ParameterExportOptionsSerializer
|
||||
|
||||
def supports_export(
|
||||
self,
|
||||
model_class: type,
|
||||
user=None,
|
||||
serializer_class=None,
|
||||
view_class=None,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> bool:
|
||||
"""Supported if the base model implements the InvenTreeParameterMixin."""
|
||||
from InvenTree.models import InvenTreeParameterMixin
|
||||
|
||||
return issubclass(model_class, InvenTreeParameterMixin)
|
||||
|
||||
def update_headers(self, headers, context, **kwargs):
|
||||
"""Update headers for the export."""
|
||||
# Add in a header for each parameter
|
||||
for pk, name in self.parameters.items():
|
||||
headers[f'parameter_{pk}'] = str(name)
|
||||
|
||||
return headers
|
||||
|
||||
def prefetch_queryset(self, queryset):
|
||||
"""Ensure that the associated parameters are prefetched."""
|
||||
from InvenTree.models import InvenTreeParameterMixin
|
||||
|
||||
queryset = InvenTreeParameterMixin.annotate_parameters(queryset)
|
||||
return queryset
|
||||
|
||||
def export_data(
|
||||
self, queryset, serializer_class, headers, context, output, **kwargs
|
||||
):
|
||||
"""Export parameter data."""
|
||||
# Extract custom serializer options and cache
|
||||
queryset = self.prefetch_queryset(queryset)
|
||||
self.serializer_class = serializer_class
|
||||
|
||||
self.exclude_inactive = context.get('export_exclude_inactive_parameters', True)
|
||||
|
||||
# Keep a dict of observed parameters against their primary key
|
||||
self.parameters = {}
|
||||
|
||||
# Serialize the queryset using DRF first
|
||||
rows = self.serializer_class(
|
||||
queryset, parameters=True, exporting=True, many=True
|
||||
).data
|
||||
|
||||
for row in rows:
|
||||
# Extract the associated parameters from the serialized data
|
||||
for parameter in row.get('parameters', []):
|
||||
template_detail = parameter['template_detail']
|
||||
template_id = template_detail['pk']
|
||||
|
||||
active = template_detail.get('enabled', True)
|
||||
|
||||
if not active and self.exclude_inactive:
|
||||
continue
|
||||
|
||||
self.parameters[template_id] = template_detail['name']
|
||||
|
||||
row[f'parameter_{template_id}'] = parameter['data']
|
||||
|
||||
return rows
|
||||
@@ -1,132 +0,0 @@
|
||||
"""Custom exporter for PartParameters."""
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
from part.models import Part
|
||||
from part.serializers import PartSerializer
|
||||
from plugin import InvenTreePlugin
|
||||
from plugin.mixins import DataExportMixin
|
||||
|
||||
|
||||
class PartParameterExportOptionsSerializer(serializers.Serializer):
|
||||
"""Custom export options for the PartParameterExporter plugin."""
|
||||
|
||||
export_stock_data = serializers.BooleanField(
|
||||
default=True, label=_('Stock Data'), help_text=_('Include part stock data')
|
||||
)
|
||||
|
||||
export_pricing_data = serializers.BooleanField(
|
||||
default=True, label=_('Pricing Data'), help_text=_('Include part pricing data')
|
||||
)
|
||||
|
||||
|
||||
class PartParameterExporter(DataExportMixin, InvenTreePlugin):
|
||||
"""Builtin plugin for exporting Part Parameter data.
|
||||
|
||||
Extends the "part" export process, to include all associated PartParameter data.
|
||||
"""
|
||||
|
||||
NAME = 'Part Parameter Exporter'
|
||||
SLUG = 'parameter-exporter'
|
||||
TITLE = _('Part Parameter Exporter')
|
||||
DESCRIPTION = _('Exporter for part parameter data')
|
||||
VERSION = '1.0.0'
|
||||
AUTHOR = _('InvenTree contributors')
|
||||
|
||||
ExportOptionsSerializer = PartParameterExportOptionsSerializer
|
||||
|
||||
def supports_export(
|
||||
self,
|
||||
model_class: type,
|
||||
user=None,
|
||||
serializer_class=None,
|
||||
view_class=None,
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> bool:
|
||||
"""Supported if the base model is Part."""
|
||||
return model_class == Part and serializer_class == PartSerializer
|
||||
|
||||
def update_headers(self, headers, context, **kwargs):
|
||||
"""Update headers for the export."""
|
||||
if not self.export_stock_data:
|
||||
# Remove stock data from the headers
|
||||
for field in [
|
||||
'allocated_to_build_orders',
|
||||
'allocated_to_sales_orders',
|
||||
'available_stock',
|
||||
'available_substitute_stock',
|
||||
'available_variant_stock',
|
||||
'building',
|
||||
'can_build',
|
||||
'external_stock',
|
||||
'in_stock',
|
||||
'on_order',
|
||||
'ordering',
|
||||
'required_for_build_orders',
|
||||
'required_for_sales_orders',
|
||||
'stock_item_count',
|
||||
'total_in_stock',
|
||||
'unallocated_stock',
|
||||
'variant_stock',
|
||||
]:
|
||||
headers.pop(field, None)
|
||||
|
||||
if not self.export_pricing_data:
|
||||
# Remove pricing data from the headers
|
||||
for field in [
|
||||
'pricing_min',
|
||||
'pricing_max',
|
||||
'pricing_min_total',
|
||||
'pricing_max_total',
|
||||
'pricing_updated',
|
||||
]:
|
||||
headers.pop(field, None)
|
||||
|
||||
# Add in a header for each part parameter
|
||||
for pk, name in self.parameters.items():
|
||||
headers[f'parameter_{pk}'] = str(name)
|
||||
|
||||
return headers
|
||||
|
||||
def prefetch_queryset(self, queryset):
|
||||
"""Ensure that the part parameters are prefetched."""
|
||||
queryset = queryset.prefetch_related(
|
||||
'parameters_list', 'parameters_list__template'
|
||||
)
|
||||
|
||||
return queryset
|
||||
|
||||
def export_data(
|
||||
self, queryset, serializer_class, headers, context, output, **kwargs
|
||||
):
|
||||
"""Export part and parameter data."""
|
||||
# Extract custom serializer options and cache
|
||||
self.export_stock_data = context.get('export_stock_data', True)
|
||||
self.export_pricing_data = context.get('export_pricing_data', True)
|
||||
|
||||
queryset = self.prefetch_queryset(queryset)
|
||||
self.serializer_class = serializer_class
|
||||
|
||||
# Keep a dict of observed part parameters against their primary key
|
||||
self.parameters = {}
|
||||
|
||||
# Serialize the queryset using DRF first
|
||||
parts = self.serializer_class(
|
||||
queryset, parameters=True, exporting=True, many=True
|
||||
).data
|
||||
|
||||
for part in parts:
|
||||
# Extract the part parameters from the serialized data
|
||||
for parameter in part.get('parameters_list', []):
|
||||
if template := parameter.get('template_detail', None):
|
||||
template_id = template['pk']
|
||||
|
||||
if template_id not in self.parameters:
|
||||
self.parameters[template_id] = template['name']
|
||||
|
||||
part[f'parameter_{template_id}'] = parameter['data']
|
||||
|
||||
return parts
|
||||
Reference in New Issue
Block a user