feat: add bulk module installation
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
from dcim.forms import ModuleForm
|
||||
from dcim.models import ModuleBay
|
||||
from django.db import IntegrityError, transaction
|
||||
|
||||
|
||||
class BulkModuleInstallError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def build_module_form_data(device, module_bay, module_type, status, replicate_components, description=""):
|
||||
return {
|
||||
"device": device.pk,
|
||||
"module_bay": module_bay.pk,
|
||||
"module_type": module_type.pk,
|
||||
"status": status,
|
||||
"replicate_components": replicate_components,
|
||||
"adopt_components": False,
|
||||
"description": description,
|
||||
}
|
||||
|
||||
|
||||
def _format_form_errors(form):
|
||||
messages = []
|
||||
for field_name, errors in form.errors.items():
|
||||
field = form.fields.get(field_name)
|
||||
label = field.label if field else "Allgemeiner Fehler"
|
||||
messages.append(f"{label}: {', '.join(str(error) for error in errors)}")
|
||||
return "; ".join(messages)
|
||||
|
||||
|
||||
def install_modules(
|
||||
*,
|
||||
device,
|
||||
module_type,
|
||||
module_bays,
|
||||
status,
|
||||
replicate_components=True,
|
||||
description="",
|
||||
permitted_modules=None,
|
||||
):
|
||||
module_bay_ids = {module_bay.pk for module_bay in module_bays}
|
||||
if not module_bay_ids:
|
||||
return []
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
locked_bays = list(ModuleBay.objects.select_for_update().filter(pk__in=module_bay_ids))
|
||||
if {module_bay.pk for module_bay in locked_bays} != module_bay_ids:
|
||||
raise BulkModuleInstallError("Mindestens ein ausgewählter Modulschacht existiert nicht mehr.")
|
||||
|
||||
installed_modules = []
|
||||
for module_bay in locked_bays:
|
||||
if (
|
||||
module_bay.device_id != device.pk
|
||||
or not module_bay.enabled
|
||||
or hasattr(module_bay, "installed_module")
|
||||
):
|
||||
raise BulkModuleInstallError(f'Der Modulschacht "{module_bay.name}" ist nicht mehr verfügbar.')
|
||||
|
||||
module_form = ModuleForm(
|
||||
data=build_module_form_data(
|
||||
device,
|
||||
module_bay,
|
||||
module_type,
|
||||
status,
|
||||
replicate_components,
|
||||
description,
|
||||
)
|
||||
)
|
||||
if not module_form.is_valid():
|
||||
raise BulkModuleInstallError(
|
||||
f'Fehler bei Modulschacht "{module_bay.name}": {_format_form_errors(module_form)}'
|
||||
)
|
||||
module = module_form.save()
|
||||
if permitted_modules is not None and not permitted_modules.filter(pk=module.pk).exists():
|
||||
raise BulkModuleInstallError(
|
||||
f'Keine Berechtigung zum Einbau eines Moduls in Modulschacht "{module_bay.name}".'
|
||||
)
|
||||
installed_modules.append(module)
|
||||
|
||||
return installed_modules
|
||||
except IntegrityError as error:
|
||||
raise BulkModuleInstallError(
|
||||
"Der Masseneinbau konnte wegen eines zwischenzeitlichen Datenkonflikts nicht gespeichert werden."
|
||||
) from error
|
||||
Reference in New Issue
Block a user