diff --git a/plugins/configuration/tasks/class_tasks.inc b/plugins/configuration/tasks/class_tasks.inc
index c90dc1b602bd835364b3e84c266a353082c43c5c..02a4bdff06fbbda62c4216786bf79eae3018d16e 100644
--- a/plugins/configuration/tasks/class_tasks.inc
+++ b/plugins/configuration/tasks/class_tasks.inc
@@ -93,7 +93,6 @@ class tasks extends simplePlugin
 
   function __construct ($dn = NULL, $object = NULL, $parent = NULL, $mainTab = FALSE)
   {
-    global $config;
     parent::__construct($dn, $object, $parent, $mainTab);
 
     $this->attributesAccess['fdTasksRepeatable']->setManagedAttributes(
@@ -112,13 +111,117 @@ class tasks extends simplePlugin
   function save (): array
   {
     // Verification if the bool of activation is ticked and activate the last exec accordingly.
-    if ($this->fdSubTasksActivation == TRUE) {
+    if ($this->fdSubTasksActivation === TRUE) {
       $currentDateTime       = date("Y-m-d h:i:sa", time());
       $this->fdTasksLastExec = $currentDateTime;
     }
     return parent::save();
   }
 
+  public function createSlaveTasks (array $listOfDN, string $attributeType, array $attrs = NULL): void
+  {
+    global $config;
+    $ldap = $config->get_ldap_link();
+
+    // Take the attribute from the other tabs - attribute cannot be null or unset by default
+    $schedule = $this->fdTasksScheduleDate ?? NULL;
+    // Verify if members can have multiple sub-tasks for that main task.
+    $newMemberOnly = $this->fdTasksUpdatable;
+
+    // remove 'dn' keeping only 'cn'
+    $rmDn = preg_replace('/(?=,).*/', '', $this->dn);
+    // only take the cn without dc
+    preg_match('/cn=(.*)/', $rmDn, $matches);
+
+    if (!empty($listOfDN)) {
+      // Condition allowing the creation of subtasks for existing members
+      if ($newMemberOnly === TRUE) {
+        $ldap->cd($config->current['BASE']);
+        $filter = '(&(objectClass=fdTasksGranular)(fdTasksGranularMaster=' . $this->dn . '))';
+        $ldap->search($filter, [$attributeType]);
+
+        // The while loop is important to get all info from ldap into the array.
+        while ($info = $ldap->fetch()) {
+          $subTasks[] = $info;
+        }
+
+        if (!empty($subTasks)) {
+          // Recuperate members DN from the ldap search.
+          foreach ($subTasks as $subTask) {
+            $membersDN[] = $subTask['fdTasksGranularDN'][0];
+          }
+          // Verify the DN differences and only keep those.
+          if (!empty($membersDN)) {
+            $listOfDN = array_diff($listOfDN, $membersDN);
+          }
+          // Simple re-index the array.
+          $listOfDN = array_values($listOfDN);
+        }
+      }
+
+      foreach ($listOfDN as $dn) {
+        // Here we create the object taskGranular
+        $tabObject = objects::create('TasksGranular');
+
+        // Create a unique ID based on timestamp (Allowing duplicate subtasks for same members in case of repeat).
+        $timestamp = microtime(TRUE);  // Get the current timestamp with microseconds
+        $timestamp = (string)$timestamp; // Convert the float to a string, str_replace expect array or string.
+        $uniqueID  = str_replace(".", "_", $timestamp); // Remove . with _ for correct CN
+
+        // Array matches come from preg_match function above with rmDn
+        $subTaskName = $matches[1] . '-SubTask-' . $uniqueID;
+
+        // Define the type of the granular task based on the attribute type passed to this method.
+        $prepData = NULL;
+        switch ($attributeType) {
+          case 'fdTasksGranularMail':
+            $prepData['tasksGranular'] = [
+              "fdTasksGranularMail"     => $dn,
+              "fdTasksGranularType"     => 'Mail Object',
+              "fdTasksGranularRef"      => $attrs['ref'],
+              "fdTasksGranularMailFrom" => $attrs['from'],
+              "fdTasksGranularMailBCC"  => $attrs['bcc']
+            ];
+            break;
+          case 'fdTasksLifeCycle' :
+            $prepData['tasksGranular'] = [
+              "fdTasksGranularDN"   => $dn,
+              "fdTasksGranularType" => 'Life Cycle',
+            ];
+            break;
+        }
+
+        // Common attributes to be filled for object tasksGranular.
+        $defaultData['tasksGranular'] = [
+          "cn"                      => $subTaskName,
+          "fdTasksGranularMaster"   => $this->dn,
+          "fdTasksGranularSchedule" => $schedule,
+        ];
+        // Simply merged the common values and the custom ones depending on the attribute type passed.
+        $values['tasksGranular']      = array_merge($prepData['tasksGranular'], $defaultData['tasksGranular']);
+
+        foreach ($values as $tab => $tabvalues) {
+          if (!isset($tabObject->by_object[$tab])) {
+            echo "Error tab does not contains attributes values" . PHP_EOL;
+          }
+          $error = $tabObject->by_object[$tab]->deserializeValues($tabvalues);
+          if ($error !== TRUE) {
+            echo 'Error during deserializing' . $error . PHP_EOL;
+          }
+
+          $tabObject->current = $tab;
+          $tabObject->update();
+          $tabObject->loadTabs();
+        }
+        $errors = $tabObject->save();
+
+        if (!empty($errors)) {
+          msg_dialog::displayChecks($errors);
+        }
+      }
+    }
+  }
+
   /**
    * @param array $groups
    * @return array
@@ -127,7 +230,7 @@ class tasks extends simplePlugin
   {
     global $config;
 
-    $ldap = $config->get_ldap_link();
+    $ldap         = $config->get_ldap_link();
     $listMemberDN = [];
 
     if (!empty($groups)) {
diff --git a/plugins/configuration/tasks/class_tasksLifeCycle.inc b/plugins/configuration/tasks/class_tasksLifeCycle.inc
index 3915926b2f0b45ed353a40a6230d82cb3e83e0fe..e5af5416797e4ffe237ecfa68bc241c2ac7bd161 100644
--- a/plugins/configuration/tasks/class_tasksLifeCycle.inc
+++ b/plugins/configuration/tasks/class_tasksLifeCycle.inc
@@ -25,7 +25,7 @@ class tasksLifeCycle extends simplePlugin
   /**
    * @var array|array[]
    */
-  private $subStates;
+  private array $subStates;
 
   static function plInfo (): array
   {
@@ -186,93 +186,11 @@ class tasksLifeCycle extends simplePlugin
    */
   public function generateSlaveTasks ()
   {
-    global $config;
-    $ldap = $config->get_ldap_link();
-
-    $listOfDN = $this->attributesAccess['fdTasksLifeCycleListOfDN']->getValue();
-
-    // Take the attribute from the other tabs - attribute cannot be null or unset by default
-    $schedule = $this->parent->getBaseObject()->fdTasksScheduleDate ?? NULL;
-
-    // Verify if members can have multiple sub-tasks for that main task.
-    $newMemberOnly = $this->parent->getBaseObject()->fdTasksUpdatable;
-
-    // remove 'dn' keeping only 'cn'
-    $rmDn = preg_replace('/(?=,).*/', '', $this->dn);
-    // only take the cn without dc
-    preg_match('/cn=(.*)/', $rmDn, $matches);
-
-    if (!empty($listOfDN)) {
-      // Condition allowing the creation of subtasks for existing members
-      if ($newMemberOnly === TRUE) {
-        $ldap->cd($config->current['BASE']);
-        $filter = '(&(objectClass=fdTasksGranular)(fdTasksGranularMaster=' . $this->dn . '))';
-
-        $attrs = ['fdTasksLifeCycle'];
-        $ldap->search($filter, $attrs);
-
-        // The while loop is important to get all info from ldap into the array.
-        while ($info = $ldap->fetch()) {
-          $subTasks[] = $info;
-        }
-
-        if (!empty($subTasks)) {
-          // Recuperate members DN from the ldap search.
-          foreach ($subTasks as $subTask) {
-            $membersDN[] = $subTask['fdTasksGranularDN'][0];
-          }
-          // Verify the DN differences and only keep those.
-          if (!empty($membersDN)) {
-            $listOfDN = array_diff($listOfDN, $membersDN);
-          }
-          // Simple re-index the array.
-          $listOfDN = array_values($listOfDN);
-        }
-      }
+    $listOfDN      = $this->attributesAccess['fdTasksLifeCycleListOfDN']->getValue();
+    $attributeType = 'fdTasksLifeCycle';
 
-      foreach ($listOfDN as $dn) {
-        // Here we create the object taskGranular
-        $tabObject = objects::create('TasksGranular');
-
-        // Create a unique ID based on timestamp (Allowing duplicate subtasks for same members in case of repeat).
-        $timestamp = microtime(TRUE);  // Get the current timestamp with microseconds
-        $timestamp = (string)$timestamp; // Convert the float to a string, str_replace expect array or string.
-        $uniqueID  = str_replace(".", "_", $timestamp); // Remove . with _ for correct CN
-
-        // Array matches come from preg_match function above with rmDn
-        $subTaskName = $matches[1] . '-SubTask-' . $uniqueID;
-
-        $values['tasksGranular'] = [
-          "cn"                      => $subTaskName,
-          "fdTasksGranularType"     => 'Life Cycle',
-          "fdTasksGranularMaster"   => $this->dn,
-          "fdTasksGranularDN"       => $dn,
-          "fdTasksGranularSchedule" => $schedule,
-        ];
-
-        foreach ($values as $tab => $tabvalues) {
-          if (!isset($tabObject->by_object[$tab])) {
-            echo "Error tab does not contains attributes values" . PHP_EOL;
-          }
-          $error = $tabObject->by_object[$tab]->deserializeValues($tabvalues);
-          if ($error !== TRUE) {
-            echo 'Error during deserializing' . $error . PHP_EOL;
-          }
-
-          $tabObject->current = $tab;
-          $tabObject->update();
-          $tabObject->loadTabs();
-        }
-
-        $errors = $tabObject->save();
-
-        // Showing errors should be better, enhancement here required.
-        if (!empty($errors)) {
-          $show_error = new SimplePluginError($this, htmlescape(sprintf(_('Error : "%s", already exist ! Editing existing tasks is forbidden.'), $subTaskName)));
-          $show_error->display();
-        }
-      }
-    }
+    // Call the method from parent tasks object (first tab) to create sub-tasks.
+    $this->parent->getBaseObject()->createSlaveTasks($listOfDN, $attributeType);
   }
 
   public function update (): bool
diff --git a/plugins/configuration/tasks/class_tasksMail.inc b/plugins/configuration/tasks/class_tasksMail.inc
index 5da8ec361d57e1df765e50ae7446696a7dc7f97f..b8e71de320be8f754becd20498051841ed5b55a7 100644
--- a/plugins/configuration/tasks/class_tasksMail.inc
+++ b/plugins/configuration/tasks/class_tasksMail.inc
@@ -216,99 +216,15 @@ class tasksMail extends simplePlugin
    */
   public function generateSlaveTasks ()
   {
-    global $config;
-    $ldap = $config->get_ldap_link();
+    $listOfDN      = $this->attributesAccess['fdTasksEmailsFromDN']->getValue();
+    $attributeType = 'fdTasksGranularMail';
 
-    $emails = $this->attributesAccess['fdTasksEmailsFromDN']->getValue();
     // Ref is supposed to be the mail object CN in this class
-    $ref  = $this->attributesAccess['fdTasksMailObject']->getValue();
-    $from = $this->attributesAccess['fdTasksEmailSender']->getValue();
-    $bcc  = $this->attributesAccess['fdTasksEmailBCC']->getValue();
-
-    // Take the attribute from the other tabs - attribute cannot be null or unset by default
-    $schedule = $this->parent->getBaseObject()->fdTasksScheduleDate ?? NULL;
-
-    // Verify if members can have multiple sub-tasks for that main task.
-    $newMemberOnly = $this->parent->getBaseObject()->fdTasksUpdatable;
-
-    // remove 'dn' keeping only 'cn'
-    $rmDn = preg_replace('/(?=,).*/', '', $this->dn);
-    // only take the cn without dc
-    preg_match('/cn=(.*)/', $rmDn, $matches);
-
-    if (!empty($emails)) {
-      // Condition allowing the creation of subtasks for existing members
-      if ($newMemberOnly === TRUE) {
-        $ldap->cd($config->current['BASE']);
-        $filter = '(&(objectClass=fdTasksGranular)(fdTasksGranularMaster=' . $this->dn . '))';
-
-        $attrs = ['fdTasksGranularMail'];
-        $ldap->search($filter, $attrs);
-
-        // The while loop is important to get all info from ldap into the array.
-        while ($info = $ldap->fetch()) {
-          $subTasks[] = $info;
-        }
-
-        if (!empty($subTasks)) {
-          // Recuperate members email from the ldap search.
-          foreach ($subTasks as $subTask) {
-            $membersEmailsList[] = $subTask['fdTasksGranularMail'][0];
-          }
-          // Verify the emails differences and only keep those.
-          if (!empty($membersEmailsList)) {
-            $emails = array_diff($emails, $membersEmailsList);
-          }
-          // Simple re-index the array.
-          $emails = array_values($emails);
-        }
-      }
+    $attrs['ref']  = $this->attributesAccess['fdTasksMailObject']->getValue();
+    $attrs['from'] = $this->attributesAccess['fdTasksEmailSender']->getValue();
+    $attrs['bcc']  = $this->attributesAccess['fdTasksEmailBCC']->getValue();
 
-      foreach ($emails as $email) {
-        // Here we create the object taskGranular
-        $tabObject = objects::create('TasksGranular');
-
-        // Create a unique ID based on timestamp (Allowing duplicate subtasks for same members in case of repeat).
-        $timestamp = microtime(TRUE);  // Get the current timestamp with microseconds
-        $timestamp = (string)$timestamp; // Convert the float to a string, str_replace expect array or string.
-        $uniqueID  = str_replace(".", "_", $timestamp); // Remove . with _ for correct CN
-
-        // Array matches come from preg_match function above with rmDn
-        $subTaskName = $matches[1] . '-SubTask-' . $uniqueID;
-
-        $values['tasksGranular'] = [
-          "cn"                      => $subTaskName,
-          "fdTasksGranularType"     => 'Mail Object',
-          "fdTasksGranularMaster"   => $this->dn,
-          "fdTasksGranularMail"     => $email,
-          "fdTasksGranularSchedule" => $schedule,
-          "fdTasksGranularRef"      => $ref,
-          "fdTasksGranularMailFrom" => $from,
-          "fdTasksGranularMailBCC"  => $bcc
-        ];
-
-        foreach ($values as $tab => $tabvalues) {
-          if (!isset($tabObject->by_object[$tab])) {
-            echo "Error tab does not contains attributes values" . PHP_EOL;
-          }
-          $error = $tabObject->by_object[$tab]->deserializeValues($tabvalues);
-          if ($error !== TRUE) {
-            echo 'Error during deserializing' . $error . PHP_EOL;
-          }
-
-          $tabObject->current = $tab;
-          $tabObject->update();
-          $tabObject->loadTabs();
-        }
-
-        $errors = $tabObject->save();
-
-        // Showing errors should be better, enhancement here required.
-        if (!empty($errors)) {
-          $show_error = new SimplePluginError($this, htmlescape(sprintf(_('Error : "%s", already exist ! Editing existing tasks is forbidden.'), $subTaskName)));
-          $show_error->display();
-        }
-      }
-    }
+    // Call the method from parent tasks object (first tab) to create sub-tasks.
+    $this->parent->getBaseObject()->createSlaveTasks($listOfDN, $attributeType, $attrs);
   }
 }