Skip to content

Commit

Permalink
chore: improve complexity
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed-Hacene committed Oct 17, 2024
1 parent 5fbb9f7 commit d6923e8
Showing 1 changed file with 62 additions and 33 deletions.
95 changes: 62 additions & 33 deletions backend/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1178,49 +1178,78 @@ def handle(exc, context):


def duplicate_related_objects(
object, duplicate_object, target_folder, field_name, model_class
source_object, duplicate_object, target_folder, field_name, model_class
):
"""
Duplicates related objects (e.g., controls, threats, assets) from a source object to a duplicate object,
ensuring that objects are not duplicated if they already exist in the/a target/sub domain (folder).
Duplicates related objects from a source object to a duplicate object, avoiding duplicates in the target folder.
Parameters:
- object (object): The source object containing the related objects to be duplicated.
- duplicate_object (object): The duplicate object where the objects will be added.
- target_folder (object): The target folder where the duplicated objects will be stored.
- field_name (str): The field name representing the related objects to duplicate in the object.
- model_class (class): The model class of the related objects to be processed.
- source_object (object): The source object containing related objects to duplicate.
- duplicate_object (object): The object where duplicated objects will be linked.
- target_folder (object): The folder where duplicated objects will be stored.
- field_name (str): The field name representing the related objects in the source object.
- model_class (class): The model class of the related objects.
"""

def process_related_object(
obj, duplicate_object, target_folder, target_parent_folders, sub_folders, field_name, model_class
):
"""
Process a single related object: add, link, or duplicate it based on folder and existence checks.
"""

# Get parent folders of the target folder
target_parent_folders = target_folder.get_parent_folders()
sub_folders = target_folder.sub_folders()

# Fetch all related objects for the given field name
related_objects = getattr(object, field_name).all()

for obj in related_objects:
# Check if an object with the same name already exists in the target folder
existing_obj = model_class.objects.filter(
name=obj.name, folder=target_folder
).first()

# Check if the object already exists in the target folder
existing_obj = get_existing_object(obj, target_folder, model_class)

if existing_obj:
# If the object already exists in the targer folder, add the existing one to the duplicate object
getattr(duplicate_object, field_name).add(existing_obj)
# If the object exists in the target folder, link it to the duplicate object
link_existing_object(duplicate_object, existing_obj, field_name)

elif obj.folder in target_parent_folders and obj.is_published:
# If the object's folder is a parent of the targert folder and is published, add the object to the duplicate object
getattr(duplicate_object, field_name).add(obj)
# If the object's folder is a parent and it's published, link it
link_existing_object(duplicate_object, obj, field_name)

elif obj.folder in sub_folders:
# If the object's folder is a subfolder of the target folder, add the object to the duplicate object
getattr(duplicate_object, field_name).add(obj)
# If the object's folder is a subfolder of the target folder, link it
link_existing_object(duplicate_object, obj, field_name)

else:
# If the object doesn't exist, duplicate the object
duplicate_obj = obj
duplicate_obj.pk = None
duplicate_obj.folder = target_folder
duplicate_obj.save()
getattr(duplicate_object, field_name).add(duplicate_obj)
# Otherwise, duplicate the object and link it
duplicate_and_link_object(obj, duplicate_object, target_folder, field_name)


def get_existing_object(obj, target_folder, model_class):
"""
Check if an object with the same name already exists in the target folder.
"""
return model_class.objects.filter(name=obj.name, folder=target_folder).first()


def link_existing_object(duplicate_object, existing_obj, field_name):
"""
Link an existing object to the duplicate object by adding it to the related field.
"""
getattr(duplicate_object, field_name).add(existing_obj)


def duplicate_and_link_object(obj, duplicate_object, target_folder, field_name):
"""
Duplicate an object and link it to the duplicate object.
"""
duplicate_obj = obj
duplicate_obj.pk = None # Reset primary key to create a new object
duplicate_obj.folder = target_folder
duplicate_obj.save() # Save the new duplicated object
getattr(duplicate_object, field_name).add(duplicate_obj)

# Get parent and sub-folders of the target folder
target_parent_folders = target_folder.get_parent_folders()
sub_folders = target_folder.sub_folders()

# Get all related objects for the specified field
related_objects = getattr(source_object, field_name).all()

# Process each related object
for obj in related_objects:
# Determine if the object should be added, linked, or duplicated
process_related_object(obj, duplicate_object, target_folder, target_parent_folders, sub_folders, field_name, model_class)

0 comments on commit d6923e8

Please sign in to comment.