diff --git a/src/CommonDBChild.php b/src/CommonDBChild.php index 6c7539ef2fb..0742e929b76 100644 --- a/src/CommonDBChild.php +++ b/src/CommonDBChild.php @@ -997,7 +997,7 @@ public function affectChild($id, $items_id = 0, $itemtype = '') final public static function getItemField($itemtype): string { - if (is_subclass_of($itemtype, 'Rule')) { + if (is_subclass_of($itemtype, 'Rule') && !is_subclass_of($itemtype, 'LevelAgreementLevel')) { $itemtype = 'Rule'; } diff --git a/src/LevelAgreement.php b/src/LevelAgreement.php index d4ec0d37a56..e9c82e29354 100644 --- a/src/LevelAgreement.php +++ b/src/LevelAgreement.php @@ -1151,6 +1151,18 @@ public function cleanDBonPurge() Rule::cleanForItemAction($this); } + public function post_clone($source, $history) + { + // Clone levels + $classname = get_called_class(); + $fk = getForeignKeyFieldForItemType($classname); + $level = new static::$levelclass(); + foreach ($level->find([$fk => $source->getID()]) as $data) { + $level->getFromDB($data['id']); + $level->clone([$fk => $this->getID()]); + } + } + /** * Getter for the protected $levelclass static property * diff --git a/src/Rule.php b/src/Rule.php index 49e634dadf3..b4350d551fd 100644 --- a/src/Rule.php +++ b/src/Rule.php @@ -102,8 +102,8 @@ class Rule extends CommonDBTM public function getCloneRelations(): array { return [ - RuleAction::class, - RuleCriteria::class + $this->ruleactionclass, + $this->rulecriteriaclass ]; } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index a9405985f46..e6a5f65a04a 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -105,7 +105,6 @@ include_once __DIR__ . '/RuleBuilder.php'; include_once __DIR__ . '/functional/CommonITILRecurrent.php'; include_once __DIR__ . '/functional/Glpi/ContentTemplates/Parameters/AbstractParameters.php'; -include_once __DIR__ . '/functional/AbstractRightsDropdown.php'; // check folder exists instead of class_exists('\GuzzleHttp\Client'), to prevent global includes if (file_exists(__DIR__ . '/../vendor/autoload.php') && !file_exists(__DIR__ . '/../vendor/guzzlehttp/guzzle')) { diff --git a/tests/functional/SLM.php b/tests/functional/SLM.php index 014b8e113d7..b2127f269d3 100644 --- a/tests/functional/SLM.php +++ b/tests/functional/SLM.php @@ -1864,4 +1864,316 @@ public function testCannotExportSLALevel() // Check that the export action is not available $this->array($actions)->notHasKey(Rule::getType() . MassiveAction::CLASS_ACTION_SEPARATOR . 'export'); } + + public function testCloneSLA() + { + $this->login(); + + // Create an SLM + $slm = $this->createItem(\SLM::class, [ + 'name' => 'SLM', + ]); + + // Create an SLA + /** @var \SLA $sla */ + $sla = $this->createItem(\SLA::class, [ + 'name' => 'SLA', + 'slms_id' => $slm->getID(), + 'definition_time' => 'hour', + 'number_time' => 4, + ]); + + // Create multiple escalation levels + $sla_levels = $this->createItems(\SlaLevel::class, [ + [ + 'name' => 'SLA level 1', + 'slas_id' => $sla->getID(), + 'execution_time' => -HOUR_TIMESTAMP, + 'is_active' => true, + 'is_recursive' => true, + 'match' => 'AND', + ], + [ + 'name' => 'SLA level 2', + 'slas_id' => $sla->getID(), + 'execution_time' => -2 * HOUR_TIMESTAMP, + 'is_active' => true, + 'is_recursive' => true, + 'match' => 'AND', + ], + ]); + + // Create multiple escalation levels criteria + $sla_levels_criterias = $this->createItems(\SlaLevelCriteria::class, [ + [ + 'slalevels_id' => $sla_levels[0]->getID(), + 'criteria' => 'status', + 'pattern' => 1, + 'condition' => 0, + ], + [ + 'slalevels_id' => $sla_levels[1]->getID(), + 'criteria' => 'urgency', + 'pattern' => 5, + 'condition' => 0, + ], + ]); + + // Create multiple escalation levels actions + $sla_levels_actions = $this->createItems(\SlaLevelAction::class, [ + [ + 'slalevels_id' => $sla_levels[0]->getID(), + 'action_type' => 'assign', + 'field' => 'type', + 'value' => 1, + ], + [ + 'slalevels_id' => $sla_levels[1]->getID(), + 'action_type' => 'assign', + 'field' => 'type', + 'value' => 2, + ], + ]); + + // Clone the SLA + $sla_clone_id = $sla->clone(); + $sla_clone = \SLA::getById($sla_clone_id); + + // Check that the clone has the same fields as the original + $this->array($sla_clone->fields)->isEqualTo(array_merge( + $sla->fields, + [ + 'id' => $sla_clone_id, + 'name' => 'SLA (copy)', + ] + )); + + // Check that SLA levels have been cloned + $sla_clone_levels = (new \SlaLevel())->find(['slas_id' => $sla_clone_id]); + $this->array($sla_clone_levels)->hasSize(2); + $this->array(\SlaLevel::getById(current($sla_clone_levels)['id'])->fields)->isEqualTo( + array_merge( + $sla_levels[0]->fields, + [ + 'id' => current($sla_clone_levels)['id'], + 'name' => 'SLA level 1 (copy)', + 'uuid' => current($sla_clone_levels)['uuid'], + 'slas_id' => $sla_clone_id, + 'is_active' => 0, + ] + ) + ); + $this->array(\SlaLevel::getById(next($sla_clone_levels)['id'])->fields)->isEqualTo( + array_merge( + $sla_levels[1]->fields, + [ + 'id' => current($sla_clone_levels)['id'], + 'name' => 'SLA level 2 (copy 2)', + 'uuid' => current($sla_clone_levels)['uuid'], + 'slas_id' => $sla_clone_id, + 'is_active' => 0, + ] + ) + ); + + // Check that SLA levels criteria have been cloned + $sla_clone_criteria = (new \SlaLevelCriteria())->find(['slalevels_id' => array_column($sla_clone_levels, 'id')]); + $this->array($sla_clone_criteria)->hasSize(2); + $this->array(\SlaLevelCriteria::getById(current($sla_clone_criteria)['id'])->fields)->isEqualTo( + array_merge( + $sla_levels_criterias[0]->fields, + [ + 'id' => current($sla_clone_criteria)['id'], + 'slalevels_id' => reset($sla_clone_levels)['id'], + ] + ) + ); + $this->array(\SlaLevelCriteria::getById(next($sla_clone_criteria)['id'])->fields)->isEqualTo( + array_merge( + $sla_levels_criterias[1]->fields, + [ + 'id' => current($sla_clone_criteria)['id'], + 'slalevels_id' => next($sla_clone_levels)['id'], + ] + ) + ); + + // Check that SLA levels actions have been cloned + $sla_clone_actions = (new \SlaLevelAction())->find(['slalevels_id' => array_column($sla_clone_levels, 'id')]); + $this->array($sla_clone_actions)->hasSize(2); + $this->array(\SlaLevelAction::getById(current($sla_clone_actions)['id'])->fields)->isEqualTo( + array_merge( + $sla_levels_actions[0]->fields, + [ + 'id' => current($sla_clone_actions)['id'], + 'slalevels_id' => reset($sla_clone_levels)['id'], + ] + ) + ); + $this->array(\SlaLevelAction::getById(next($sla_clone_actions)['id'])->fields)->isEqualTo( + array_merge( + $sla_levels_actions[1]->fields, + [ + 'id' => current($sla_clone_actions)['id'], + 'slalevels_id' => next($sla_clone_levels)['id'], + ] + ) + ); + } + + public function testCloneOLA() + { + $this->login(); + + // Create an SLM + $slm = $this->createItem(\SLM::class, [ + 'name' => 'SLM', + ]); + + // Create an OLA + /** @var \OLA $ola */ + $ola = $this->createItem(\OLA::class, [ + 'name' => 'OLA', + 'slms_id' => $slm->getID(), + 'definition_time' => 'hour', + 'number_time' => 4, + ]); + + // Create multiple escalation levels + $ola_levels = $this->createItems(\OlaLevel::class, [ + [ + 'name' => 'OLA level 1', + 'olas_id' => $ola->getID(), + 'execution_time' => -HOUR_TIMESTAMP, + 'is_active' => true, + 'is_recursive' => true, + 'match' => 'AND', + ], + [ + 'name' => 'OLA level 2', + 'olas_id' => $ola->getID(), + 'execution_time' => -2 * HOUR_TIMESTAMP, + 'is_active' => true, + 'is_recursive' => true, + 'match' => 'AND', + ], + ]); + + // Create multiple escalation levels criteria + $ola_levels_criterias = $this->createItems(\OlaLevelCriteria::class, [ + [ + 'olalevels_id' => $ola_levels[0]->getID(), + 'criteria' => 'status', + 'pattern' => 1, + 'condition' => 0, + ], + [ + 'olalevels_id' => $ola_levels[1]->getID(), + 'criteria' => 'urgency', + 'pattern' => 5, + 'condition' => 0, + ], + ]); + + // Create multiple escalation levels actions + $ola_levels_actions = $this->createItems(\OlaLevelAction::class, [ + [ + 'olalevels_id' => $ola_levels[0]->getID(), + 'action_type' => 'assign', + 'field' => 'type', + 'value' => 1, + ], + [ + 'olalevels_id' => $ola_levels[1]->getID(), + 'action_type' => 'assign', + 'field' => 'type', + 'value' => 2, + ], + ]); + + // Clone the OLA + $ola_clone_id = $ola->clone(); + $ola_clone = \OLA::getById($ola_clone_id); + + // Check that the clone has the same fields as the original + $this->array($ola_clone->fields)->isEqualTo(array_merge( + $ola->fields, + [ + 'id' => $ola_clone_id, + 'name' => 'OLA (copy)', + ] + )); + + // Check that OLA levels have been cloned + $ola_clone_levels = (new \OlaLevel())->find(['olas_id' => $ola_clone_id]); + $this->array($ola_clone_levels)->hasSize(2); + $this->array(\OlaLevel::getById(current($ola_clone_levels)['id'])->fields)->isEqualTo( + array_merge( + $ola_levels[0]->fields, + [ + 'id' => current($ola_clone_levels)['id'], + 'name' => 'OLA level 1 (copy)', + 'uuid' => current($ola_clone_levels)['uuid'], + 'olas_id' => $ola_clone_id, + 'is_active' => 0, + ] + ) + ); + $this->array(\OlaLevel::getById(next($ola_clone_levels)['id'])->fields)->isEqualTo( + array_merge( + $ola_levels[1]->fields, + [ + 'id' => current($ola_clone_levels)['id'], + 'name' => 'OLA level 2 (copy 2)', + 'uuid' => current($ola_clone_levels)['uuid'], + 'olas_id' => $ola_clone_id, + 'is_active' => 0, + ] + ) + ); + + // Check that OLA levels criteria have been cloned + $ola_clone_criteria = (new \OlaLevelCriteria())->find(['olalevels_id' => array_column($ola_clone_levels, 'id')]); + $this->array($ola_clone_criteria)->hasSize(2); + $this->array(\OlaLevelCriteria::getById(current($ola_clone_criteria)['id'])->fields)->isEqualTo( + array_merge( + $ola_levels_criterias[0]->fields, + [ + 'id' => current($ola_clone_criteria)['id'], + 'olalevels_id' => reset($ola_clone_levels)['id'], + ] + ) + ); + $this->array(\OlaLevelCriteria::getById(next($ola_clone_criteria)['id'])->fields)->isEqualTo( + array_merge( + $ola_levels_criterias[1]->fields, + [ + 'id' => current($ola_clone_criteria)['id'], + 'olalevels_id' => next($ola_clone_levels)['id'], + ] + ) + ); + + // Check that OLA levels actions have been cloned + $ola_clone_actions = (new \OlaLevelAction())->find(['olalevels_id' => array_column($ola_clone_levels, 'id')]); + $this->array($ola_clone_actions)->hasSize(2); + $this->array(\OlaLevelAction::getById(current($ola_clone_actions)['id'])->fields)->isEqualTo( + array_merge( + $ola_levels_actions[0]->fields, + [ + 'id' => current($ola_clone_actions)['id'], + 'olalevels_id' => reset($ola_clone_levels)['id'], + ] + ) + ); + $this->array(\OlaLevelAction::getById(next($ola_clone_actions)['id'])->fields)->isEqualTo( + array_merge( + $ola_levels_actions[1]->fields, + [ + 'id' => current($ola_clone_actions)['id'], + 'olalevels_id' => next($ola_clone_levels)['id'], + ] + ) + ); + } }