(app, shadow_parent)
return changes
Creates or deletes shadow child modules if the parent module requires

    Used primarily when changing the "source module id" of a shadow module
Creates or deletes shadow child modules if the parent module requires
Creates or deletes shadow child modules if the parent module requires
def handle_shadow_child_modules(app, shadow_parent):
    """Creates or deletes shadow child modules if the parent module requires

    Used primarily when changing the "source module id" of a shadow module
    """
    changes = False

    if shadow_parent.shadow_module_version == 1:
        # For old-style shadow modules, we don't create any child-shadows
        return False

    if not shadow_parent.source_module_id:
        return False

    # if the source module is a child, but not a shadow, then the shadow should have the same parent
    source = app.get_module_by_unique_id(shadow_parent.source_module_id)
    if source.root_module_id != shadow_parent.root_module_id:
        shadow_parent.root_module_id = source.root_module_id
        changes = True

    source_module_children = [
        m for m in app.get_modules()
        if m.root_module_id == shadow_parent.source_module_id
        and m.module_type != 'shadow'
    ]
    source_module_children_ids = [
        source_module_child.unique_id for source_module_child in source_module_children
    ]

    shadow_parent_children = [
        m for m in app.get_modules()
        if m.root_module_id == shadow_parent.unique_id
    ]  # All the child shadows that already exist

    # Delete child modules that no longer have a source
    unneeded_module_ids = [
        child.unique_id for child in shadow_parent_children
        if child.source_module_id not in source_module_children_ids
    ]
    for unneeded_module_id in unneeded_module_ids:
        changes = True
        app.delete_module(unneeded_module_id)

    # We need to create child modules for those source children that don't have them
    existing_child_shadow_sources = [
        child.source_module_id for child in shadow_parent_children
    ]  # The set of source children ids that already have shadows
    needed_modules = [
        source_child for source_child in source_module_children
        if source_child.unique_id not in existing_child_shadow_sources
    ]
    for source_child in needed_modules:
        changes = True
        new_shadow = ShadowModule.new_module(source_child.default_name(app=app), app.default_language)
        new_shadow.source_module_id = source_child.unique_id
        new_shadow.root_module_id = shadow_parent.unique_id

        # BaseModule properties
        for prop, transform in MODULE_BASE_PROPERTIES_TO_COPY:
            new_value = getattr(source_child, prop)
            setattr(new_shadow, prop, transform(new_value) if transform is not None else new_value)

        # ShadowModule properties
        for prop, transform in SHADOW_MODULE_PROPERTIES_TO_COPY:
            new_value = getattr(source_child, prop)
            setattr(new_shadow, prop, transform(new_value) if transform is not None else new_value)

        # move excluded form ids
        source_child_form_ids = set(
            f.unique_id
            for f in app.get_module_by_unique_id(new_shadow.source_module_id).get_forms()
        )
        new_shadow.excluded_form_ids = list(set(shadow_parent.excluded_form_ids) & source_child_form_ids)
        shadow_parent.excluded_form_ids = list(set(shadow_parent.excluded_form_ids) - source_child_form_ids)

        app.add_module(new_shadow)

    if changes:
        app.move_child_modules_after_parents()
        app.save()

    return changes
def handle_shadow_child_modules ( app , shadow_parent ) : changes = False if shadow_parent . shadow_module_version == 1 : # For old-style shadow modules, we don't create any child-shadows return False if not shadow_parent . source_module_id : return False # if the source module is a child, but not a shadow, then the shadow should have the same parent source = app . get_module_by_unique_id ( shadow_parent . source_module_id ) if source . root_module_id != shadow_parent . root_module_id : shadow_parent . root_module_id = source . root_module_id changes = True source_module_children = [ m for m in app . get_modules ( ) if m . root_module_id == shadow_parent . source_module_id and m . module_type != 'shadow' ] source_module_children_ids = [ source_module_child . unique_id for source_module_child in source_module_children ] shadow_parent_children = [ m for m in app . get_modules ( ) if m . root_module_id == shadow_parent . unique_id ] # All the child shadows that already exist # Delete child modules that no longer have a source unneeded_module_ids = [ child . unique_id for child in shadow_parent_children if child . source_module_id not in source_module_children_ids ] for unneeded_module_id in unneeded_module_ids : changes = True app . delete_module ( unneeded_module_id ) # We need to create child modules for those source children that don't have them existing_child_shadow_sources = [ child . source_module_id for child in shadow_parent_children ] # The set of source children ids that already have shadows needed_modules = [ source_child for source_child in source_module_children if source_child . unique_id not in existing_child_shadow_sources ] for source_child in needed_modules : changes = True new_shadow = ShadowModule . new_module ( source_child . default_name ( app = app ) , app . default_language ) new_shadow . source_module_id = source_child . unique_id new_shadow . root_module_id = shadow_parent . unique_id # BaseModule properties for prop , transform in MODULE_BASE_PROPERTIES_TO_COPY : new_value = getattr ( source_child , prop ) setattr ( new_shadow , prop , transform ( new_value ) if transform is not None else new_value ) # ShadowModule properties for prop , transform in SHADOW_MODULE_PROPERTIES_TO_COPY : new_value = getattr ( source_child , prop ) setattr ( new_shadow , prop , transform ( new_value ) if transform is not None else new_value ) # move excluded form ids source_child_form_ids = set ( f . unique_id for f in app . get_module_by_unique_id ( new_shadow . source_module_id ) . get_forms ( ) ) new_shadow . excluded_form_ids = list ( set ( shadow_parent . excluded_form_ids ) & source_child_form_ids ) shadow_parent . excluded_form_ids = list ( set ( shadow_parent . excluded_form_ids ) - source_child_form_ids ) app . add_module ( new_shadow ) if changes : app . move_child_modules_after_parents ( ) app . save ( ) return changes