mirror of
https://github.com/inventree/InvenTree.git
synced 2025-12-14 16:29:57 +00:00
Refactor part parameter exporter plugin
- Any model which supports parameters can use this now - Update documentation
This commit is contained in:
@@ -21,7 +21,7 @@ The following builtin plugins are available in InvenTree:
|
||||
| Barcodes | [TME](./barcode_tme.md) | TME barcode support | No |
|
||||
| Data Export | [BOM Exporter](./bom_exporter.md) | Custom [exporter](../mixins/export.md) for BOM data | Yes |
|
||||
| Data Export | [InvenTree Exporter](./inventree_exporter.md) | Custom [exporter](../mixins/export.md) for InvenTree data | Yes |
|
||||
| Data Export | [Parameter Exporter](./part_parameter_exporter.md) | Custom [exporter](../mixins/export.md) for part parameter data | Yes |
|
||||
| Data Export | [Parameter Exporter](./parameter_exporter.md) | Custom [exporter](../mixins/export.md) for parameter data | Yes |
|
||||
| Data Export | [Stocktake Exporter](./stocktake_exporter.md) | Custom [exporter](../mixins/export.md) for stocktake data | No |
|
||||
| Events | [Auto Create Child Builds](./auto_create_builds.md) | Automatically create child build orders for sub-assemblies | No |
|
||||
| Events | [Auto Issue Orders](./auto_issue.md) | Automatically issue pending orders when target date is reached | No |
|
||||
|
||||
27
docs/docs/plugins/builtin/parameter_exporter.md
Normal file
27
docs/docs/plugins/builtin/parameter_exporter.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: Parameter Exporter
|
||||
---
|
||||
|
||||
## Parameter Exporter
|
||||
|
||||
The **Parameter Exporter** plugin provides custom export functionality for models which support custom [Parameter](../../concepts/parameters.md) data.
|
||||
|
||||
It utilizes the [ExporterMixin](../mixins/export.md) mixin to provide a custom export format for part parameter data.
|
||||
|
||||
In addition to the standard exported fields, this plugin also exports all associated parameter data for each row of the export.
|
||||
|
||||
### Activation
|
||||
|
||||
This plugin is a *mandatory* plugin, and is always enabled.
|
||||
|
||||
### Plugin Settings
|
||||
|
||||
This plugin has no configurable settings.
|
||||
|
||||
## Usage
|
||||
|
||||
This plugin is used in the same way as the [InvenTree Exporter Plugin](./inventree_exporter.md), but provides a custom export format for part parameter data.
|
||||
|
||||
When exporting parameter data, the *Parameter Exporter* plugin is available for selection in the export dialog. When selected, the plugin provides some additional export options to control the data export process.
|
||||
|
||||
{{ image("parameter_export_options.png", base="plugin/builtin", title="Parameter Export Options") }}
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
title: Part Parameter Exporter
|
||||
---
|
||||
|
||||
## Part Parameter Exporter
|
||||
|
||||
The **Part Parameter Exporter** plugin provides custom export functionality for [Parameter](../../concepts/parameters.md) data.
|
||||
|
||||
It utilizes the [ExporterMixin](../mixins/export.md) mixin to provide a custom export format for part parameter data.
|
||||
|
||||
### Activation
|
||||
|
||||
This plugin is a *mandatory* plugin, and is always enabled.
|
||||
|
||||
### Plugin Settings
|
||||
|
||||
This plugin has no configurable settings.
|
||||
|
||||
## Usage
|
||||
|
||||
This plugin is used in the same way as the [InvenTree Exporter Plugin](./inventree_exporter.md), but provides a custom export format for part parameter data.
|
||||
|
||||
When exporting part parameter data, the *Part Parameter Exporter* plugin is available for selection in the export dialog. When selected, the plugin provides some additional export options to control the data export process.
|
||||
|
||||
{{ image("parameter_export_options.png", base="plugin/builtin", title="Part Parameter Export Options") }}
|
||||
@@ -545,11 +545,11 @@ You can add asset images to the reports and labels by using the `{% raw %}{% ass
|
||||
{% endraw %}
|
||||
```
|
||||
|
||||
## Part Parameters
|
||||
## Parameters
|
||||
|
||||
If you need to load a part parameter for a particular Part, within the context of your template, you can use the `part_parameter` template tag:
|
||||
If you need to load a parameter value for a particular model instance, within the context of your template, you can use the `parameter` template tag:
|
||||
|
||||
::: report.templatetags.report.part_parameter
|
||||
::: report.templatetags.report.parameter
|
||||
options:
|
||||
show_docstring_description: false
|
||||
show_source: False
|
||||
@@ -562,7 +562,7 @@ The following example assumes that you have a report or label which contains a v
|
||||
{% raw %}
|
||||
{% load report %}
|
||||
|
||||
{% part_parameter part "length" as length %}
|
||||
{% parameter part "length" as length %}
|
||||
|
||||
Part: {{ part.name }}<br>
|
||||
Length: {{ length.data }} [{{ length.units }}]
|
||||
|
||||
@@ -239,7 +239,7 @@ nav:
|
||||
- Export Plugins:
|
||||
- BOM Exporter: plugins/builtin/bom_exporter.md
|
||||
- InvenTree Exporter: plugins/builtin/inventree_exporter.md
|
||||
- Parameter Exporter: plugins/builtin/part_parameter_exporter.md
|
||||
- Parameter Exporter: plugins/builtin/parameter_exporter.md
|
||||
- Stocktake Exporter: plugins/builtin/stocktake_exporter.md
|
||||
- Label Printing:
|
||||
- Label Printer: plugins/builtin/inventree_label.md
|
||||
|
||||
@@ -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