Adds model mixin for generically determining which fields can be imported on any particular model

This commit is contained in:
Oliver 2022-02-16 11:42:15 +11:00
parent 24f1491b8e
commit 58aa2adde7
2 changed files with 87 additions and 2 deletions

View File

@ -45,6 +45,62 @@ def rename_attachment(instance, filename):
return os.path.join(instance.getSubdir(), filename)
class DataImportMixin(object):
"""
Model mixin class which provides support for 'data import' functionality.
Models which implement this mixin should provide information on the fields available for import
"""
# Define a map of fields avaialble for import
IMPORT_FIELDS = {}
@classmethod
def get_import_fields(cls):
"""
Return all available import fields
Where information on a particular field is not explicitly provided,
introspect the base model to (attempt to) find that information.
"""
fields = cls.IMPORT_FIELDS
for name, field in fields.items():
# Attempt to extract base field information from the model
base_field = None
for f in cls._meta.fields:
if f.name == name:
base_field = f
break
if base_field:
if 'label' not in field:
field['label'] = base_field.verbose_name
if 'help_text' not in field:
field['help_text'] = base_field.help_text
fields[name] = field
return fields
@classmethod
def get_required_import_fields(cls):
""" Return all *required* import fields """
fields = {}
for name, field in cls.get_import_fields().items():
required = field.get('required', False)
if required:
fields[name] = field
return fields
class ReferenceIndexingMixin(models.Model):
"""
A mixin for keeping track of numerical copies of the "reference" field.

View File

@ -46,7 +46,7 @@ from common.models import InvenTreeSetting
from InvenTree import helpers
from InvenTree import validators
from InvenTree.models import InvenTreeTree, InvenTreeAttachment
from InvenTree.models import InvenTreeTree, InvenTreeAttachment, DataImportMixin
from InvenTree.fields import InvenTreeURLField
from InvenTree.helpers import decimal2string, normalize, decimal2money
import InvenTree.tasks
@ -2550,7 +2550,7 @@ class PartCategoryParameterTemplate(models.Model):
help_text=_('Default Parameter Value'))
class BomItem(models.Model):
class BomItem(models.Model, DataImportMixin):
""" A BomItem links a part to its component items.
A part can have a BOM (bill of materials) which defines
which parts are required (and in what quantity) to make it.
@ -2568,6 +2568,35 @@ class BomItem(models.Model):
allow_variants: Stock for part variants can be substituted for this BomItem
"""
# Fields available for bulk import
IMPORT_FIELDS = {
'quantity': {
'required': True
},
'optional': {},
'reference': {},
'overage': {},
'note': {},
'inherited': {},
'allow_variants': {},
'part': {
'label': _('Part'),
'help_text': _('Part ID or part name'),
},
'part_id': {
'label': _('Part ID'),
'help_text': _('Unique part ID value')
},
'part_name': {
'label': _('Part Name'),
'help_text': _('Part name'),
},
'part_ipn': {
'label': _('Part IPN'),
'help_text': _('Part IPN value'),
}
}
@staticmethod
def get_api_url():
return reverse('api-bom-list')