diff --git a/application/forms/RotationConfigForm.php b/application/forms/RotationConfigForm.php index 070afaf3e..9f9a2e78a 100644 --- a/application/forms/RotationConfigForm.php +++ b/application/forms/RotationConfigForm.php @@ -174,6 +174,8 @@ public function loadRotation(int $rotationId): self $formData = [ 'mode' => $rotation->mode, 'name' => $rotation->name, + 'priority' => $rotation->priority, + 'schedule' => $rotation->schedule_id, 'options' => Json::decode($rotation->options, true) ]; @@ -194,42 +196,35 @@ public function loadRotation(int $rotationId): self } /** - * Add a new rotation to the database + * Insert a new rotation in the database * * @param int $scheduleId The ID of the schedule the rotation belongs to + * @param int $priority The priority of the rotation * - * @return int The ID of the newly created rotation + * @return DateTime The first handoff of the rotation */ - public function addRotation(int $scheduleId): int + private function createRotation(int $scheduleId, int $priority): DateTime { $data = $this->getValues(); $data['options'] = Json::encode($data['options']); $data['schedule_id'] = $scheduleId; + $data['priority'] = $priority; $members = array_map(function ($member) { return explode(':', $member, 2); }, explode(',', $this->getValue('members'))); - $transactionStarted = false; - if (! $this->db->inTransaction()) { - $transactionStarted = $this->db->beginTransaction(); - } - - $data['priority'] = $this->db->fetchScalar( - (new Select()) - ->from('rotation') - ->columns(new Expression('MAX(priority) + 1')) - ->where(['schedule_id = ?' => $scheduleId]) - ) ?? 0; - $this->db->insert('rotation', $data); $rotationId = $this->db->lastInsertId(); $this->db->insert('timeperiod', ['owned_by_rotation_id' => $rotationId]); $timeperiodId = $this->db->lastInsertId(); + $rules = $this->yieldRecurrenceRules(count($members)); + $firstHandoff = $rules->current()[0]->getStartDate(); + $knownMembers = []; - foreach ($this->yieldRecurrenceRules(count($members)) as $position => [$rrule, $shiftDuration]) { + foreach ($rules as $position => [$rrule, $shiftDuration]) { if (isset($knownMembers[$position])) { $memberId = $knownMembers[$position]; } else { @@ -263,11 +258,33 @@ public function addRotation(int $scheduleId): int ]); } + return $firstHandoff; + } + + /** + * Add a new rotation to the database + * + * @param int $scheduleId The ID of the schedule the rotation belongs to + * + * @return void + */ + public function addRotation(int $scheduleId): void + { + $transactionStarted = false; + if (! $this->db->inTransaction()) { + $transactionStarted = $this->db->beginTransaction(); + } + + $this->createRotation($scheduleId, $this->db->fetchScalar( + (new Select()) + ->from('rotation') + ->columns(new Expression('MAX(priority) + 1')) + ->where(['schedule_id = ?' => $scheduleId]) + ) ?? 0); + if ($transactionStarted) { $this->db->commitTransaction(); } - - return $rotationId; } /** @@ -279,23 +296,18 @@ public function addRotation(int $scheduleId): int */ public function editRotation(int $rotationId): void { - $data = $this->getValues(); - $data['options'] = Json::encode($data['options']); - - $members = array_map(function ($member) { - return explode(':', $member, 2); - }, explode(',', $this->getValue('members'))); - $transactionStarted = false; if (! $this->db->inTransaction()) { $transactionStarted = $this->db->beginTransaction(); } - $this->db->update('rotation', $data, ['id = ?' => $rotationId]); - $this->db->delete('rotation_member', ['rotation_id = ?' => $rotationId]); + $scheduleId = $this->getValue('schedule'); + $priority = $this->getValue('priority'); + if ($scheduleId === null || $priority === null) { + throw new LogicException('The schedule and priority must be populated'); + } - $rules = $this->yieldRecurrenceRules(count($members)); - $firstHandoff = $rules->current()[0]->getStartDate(); + $firstHandoff = $this->createRotation((int) $scheduleId, (int) $priority); $timeperiodEntries = TimeperiodEntry::on($this->db) ->filter(Filter::all( @@ -339,48 +351,6 @@ public function editRotation(int $rotationId): void } } - $timeperiodId = $this->db->fetchScalar( - (new Select()) - ->from('timeperiod') - ->columns('id') - ->where('owned_by_rotation_id = ?', $rotationId) - ); - - $knownMembers = []; - foreach ($rules as $position => [$rrule, $shiftDuration]) { - if (isset($knownMembers[$position])) { - $memberId = $knownMembers[$position]; - } else { - [$type, $id] = $members[$position]; - - if ($type === 'contact') { - $this->db->insert('rotation_member', [ - 'rotation_id' => $rotationId, - 'contact_id' => $id, - 'position' => $position - ]); - } elseif ($type === 'group') { - $this->db->insert('rotation_member', [ - 'rotation_id' => $rotationId, - 'contactgroup_id' => $id, - 'position' => $position - ]); - } - - $memberId = $this->db->lastInsertId(); - $knownMembers[$position] = $memberId; - } - - $this->db->insert('timeperiod_entry', [ - 'timeperiod_id' => $timeperiodId, - 'rotation_member_id' => $memberId, - 'start_time' => $rrule->getStartDate()->format('U.u') * 1000.0, - 'end_time' => (clone $rrule->getStartDate())->add($shiftDuration)->format('U.u') * 1000.0, - 'timezone' => $rrule->getStartDate()->getTimezone()->getName(), - 'rrule' => $rrule->getString(Rule::TZ_FIXED), - ]); - } - if ($transactionStarted) { $this->db->commitTransaction(); } @@ -797,6 +767,9 @@ protected function assemble() { $this->getAttributes()->add('class', 'rotation-config'); + $this->addElement('hidden', 'schedule', ['ignore' => true]); + $this->addElement('hidden', 'priority', ['ignore' => true]); + $mode = $this->assembleModeSelection(); $autoSubmittedBy = $this->getRequest()->getHeader('X-Icinga-Autosubmittedby')[0] ?? '';