/**
  * the singleton pattern
  *
  * @return HumanResources_Controller_FreeTime
  */
 public static function getInstance()
 {
     if (self::$_instance === NULL) {
         self::$_instance = new HumanResources_Controller_FreeTime();
     }
     return self::$_instance;
 }
 /**
  * tests for the contract controller
  */
 public function testUpdateContract()
 {
     $contractController = HumanResources_Controller_Contract::getInstance();
     $employeeController = HumanResources_Controller_Employee::getInstance();
     $contractBackend = new HumanResources_Backend_Contract();
     $employee = $employeeController->create($this->_getEmployee('sclever'));
     $testDate = Tinebase_DateTime::now()->setDate(Tinebase_DateTime::now()->format('Y'), 5, 13);
     $inAMonth = clone $testDate;
     $inAMonth->addMonth(1);
     $threeHrAgo = clone $testDate;
     $threeHrAgo->subHour(3);
     $startDate1 = clone $testDate;
     $startDate1->subMonth(2);
     $startDate2 = clone $testDate;
     $startDate2->subMonth(1);
     $edate1 = clone $startDate2;
     $edate1->addYear(1);
     // contract1 in the past, but created a second ago
     $contract1 = $this->_getContract();
     $contract1->employee_id = $employee->getId();
     $contract1->start_date = $startDate1;
     $contract1->creation_time = $testDate;
     $contract1 = $contractBackend->create($contract1);
     $contract2 = $this->_getContract();
     $contract2->employee_id = $employee->getId();
     $contract2->start_date = $startDate2;
     $contract2->end_date = $edate1;
     $contract2 = $contractBackend->create($contract2);
     // account
     $accountInstance = HumanResources_Controller_Account::getInstance();
     $accountInstance->createMissingAccounts();
     $accountFilter = new HumanResources_Model_AccountFilter(array(array('field' => 'year', 'operator' => 'equals', 'value' => $testDate->format('Y'))));
     $accountFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $employee->getId())));
     $myAccount = $accountInstance->search($accountFilter)->getFirstRecord();
     $firstDayDate = clone $startDate2;
     $firstDayDate->addDay(3);
     $vacation = new HumanResources_Model_FreeTime(array('status' => 'ACCEPTED', 'employee_id' => $employee->getId(), 'account_id' => $myAccount->getId(), 'type' => 'vacation', 'freedays' => array(array('date' => $firstDayDate, 'duration' => 1))));
     $vacation = HumanResources_Controller_FreeTime::getInstance()->create($vacation);
     $newCalendar = $this->_getFeastCalendar(true);
     // LAST ASSERTION, do not add assertions after an expected Exception, they won't be executed
     $this->setExpectedException('HumanResources_Exception_ContractNotEditable');
     $contract2->feast_calendar_id = $newCalendar->getId();
     $contract2 = $contractController->update($contract2);
     // no more assertions here!
 }
 /**
  * update to 8.3 normalize contracts to have fields from update_1 set
  */
 public function update_2()
 {
     $c = HumanResources_Controller_FreeTime::getInstance();
     $d = HumanResources_Controller_FreeDay::getInstance();
     $allC = $c->getAll();
     $allD = $d->getAll();
     if ($allC->count() > 0) {
         try {
             $this->promptForUsername();
             foreach ($allC as $ct) {
                 $ct->freedays = $allD->filter('freetime_id', $ct->id)->toArray();
                 $c->update($ct);
             }
         } catch (Exception $e) {
             // do nothing, update not important
         }
     }
     $this->setApplicationVersion('HumanResources', '8.3');
 }
 /**
  * Creates an employee with contracts and contact, account etc.
  * tests auto end_date of old contract
  */
 public function testEmployee()
 {
     $date = new Tinebase_DateTime();
     $date->subYear(1);
     $date->setDate($date->format('Y'), 2, 1);
     $firstDate = substr($date->toString(), 0, 10);
     $startDate = clone $date;
     $costCenter1 = $this->_getCostCenter($date);
     $savedEmployee = $this->_saveEmployee($costCenter1);
     $this->assertArrayHasKey('account_id', $savedEmployee);
     $this->assertTrue(is_array($savedEmployee['account_id']));
     $this->assertArrayHasKey('contracts', $savedEmployee);
     $this->assertArrayHasKey('costcenters', $savedEmployee);
     $this->assertEquals(1, count($savedEmployee['contracts']));
     $this->assertEquals(1, count($savedEmployee['costcenters']));
     // check if accounts has been created properly on aftercreate
     $filter = new HumanResources_Model_AccountFilter(array());
     $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $savedEmployee['id'])));
     $result = HumanResources_Controller_Account::getInstance()->search($filter);
     $this->assertEquals(2, $result->count());
     $date->addMonth(2);
     $costCenter2 = $this->_getCostCenter($date);
     $newContract = $this->_getContract();
     $newContract->start_date->addMonth(5);
     $savedEmployee['contracts'][] = $newContract->toArray();
     $savedEmployee['costcenters'][] = $costCenter2->toArray();
     $savedEmployee = $this->_json->saveEmployee($savedEmployee);
     $this->assertEquals(2, count($savedEmployee['contracts']), 'There should be 2 Contracts');
     $this->assertEquals(2, count($savedEmployee['costcenters']), 'There should be 2 CostCenters');
     $this->assertEquals(null, $savedEmployee['contracts'][1]['end_date'], 'The end_date should have a null value.');
     $this->assertEquals($firstDate, substr($savedEmployee['costcenters'][0]['start_date'], 0, 10), 'The start_date of the first costcenter should begin with the first date of the employee!');
     $date1 = new Tinebase_DateTime($savedEmployee['contracts'][0]['end_date']);
     $date2 = new Tinebase_DateTime($savedEmployee['contracts'][1]['start_date']);
     // FIXME this is not working on daylight saving boundaries
     //$this->assertEquals($date1->addDay(1)->toString(), $date2->toString());
     $freeTimes = $this->_json->getFeastAndFreeDays($savedEmployee['id'], $date2->format('Y'));
     $this->assertEquals($savedEmployee['id'], $freeTimes['results']['contracts'][0]['employee_id']);
     // 0009592: Adding a new cost center to a employee fails
     // https://forge.tine20.org/mantisbt/view.php?id=9592
     $accountInstance = HumanResources_Controller_Account::getInstance();
     $accountInstance->createMissingAccounts((int) $startDate->format('Y'));
     $accountFilter = new HumanResources_Model_AccountFilter(array());
     $accountFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $savedEmployee['id'])));
     $myAccount = $accountInstance->search($accountFilter)->getFirstRecord();
     $firstDayDate = clone $startDate;
     $firstDayDate->addDay(3);
     while ($firstDayDate->format('N') != 1) {
         $firstDayDate->addDay(1);
     }
     $vacation = new HumanResources_Model_FreeTime(array('status' => 'ACCEPTED', 'employee_id' => $savedEmployee['id'], 'account_id' => $myAccount->getId(), 'type' => 'vacation', 'freedays' => array(array('date' => $firstDayDate, 'duration' => 1), array('date' => $firstDayDate->addDay(1), 'duration' => 1), array('date' => $firstDayDate->addDay(1), 'duration' => 1), array('date' => $firstDayDate->addDay(1), 'duration' => 1), array('date' => $firstDayDate->addDay(1), 'duration' => 1))));
     $vacation = HumanResources_Controller_FreeTime::getInstance()->create($vacation);
     $employee = $this->_json->getEmployee($savedEmployee['id']);
     $date->addMonth(2);
     $costCenter3 = $this->_getCostCenter($date);
     $employee['costcenters'][] = $costCenter3->toArray();
     $employee = $this->_json->saveEmployee($employee);
     $this->assertEquals(5, $employee['vacation'][0]['days_count']);
     $this->assertEquals(17, count($employee['vacation'][0]));
     $this->assertEquals(3, count($employee['costcenters']));
     // @see: 0010050: Delete last dependent record fails
     // if the property is set to null, no dependent record handling will be done
     $employee['costcenters'] = NULL;
     $employee = $this->_json->saveEmployee($employee);
     $this->assertEquals(3, count($employee['costcenters']));
     // if the property is set to an empty array, all dependent records will be removed
     $employee['costcenters'] = array();
     $employee = $this->_json->saveEmployee($employee);
     $this->assertEquals(0, count($employee['costcenters']));
 }
 /**
  * resolves virtual field "is_editable"
  * 
  * @param array $resultSet
  */
 public function getEditableState($resultSet)
 {
     for ($i = 0; $i < count($resultSet); $i++) {
         $sDate = new Tinebase_DateTime($resultSet[$i]['start_date']);
         $sDate->setTimezone(Tinebase_Core::getUserTimezone());
         $eDate = NULL;
         if ($resultSet[$i]['end_date']) {
             $eDate = new Tinebase_DateTime($resultSet[$i]['end_date']);
             $eDate->setTimezone(Tinebase_Core::getUserTimezone());
         }
         $freeTimeFilter = new HumanResources_Model_FreeTimeFilter(array(array('field' => 'firstday_date', 'operator' => 'after', 'value' => $sDate), array('field' => 'type', 'operator' => 'equals', 'value' => 'vacation')));
         if ($eDate) {
             $freeTimeFilter->addFilter(new Tinebase_Model_Filter_Date(array('field' => 'firstday_date', 'operator' => 'before', 'value' => $eDate)));
         }
         $freeTimeFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $resultSet[$i]['employee_id'])));
         $freeTimeController = HumanResources_Controller_FreeTime::getInstance();
         $resultSet[$i]['is_editable'] = $freeTimeController->search($freeTimeFilter)->count() > 0 ? FALSE : TRUE;
     }
     return $resultSet;
 }
 /**
  * delete linked objects (notes, relations, ...) of record
  *
  * @param Tinebase_Record_Interface $_record
  */
 protected function _deleteLinkedObjects(Tinebase_Record_Interface $_record)
 {
     // use textfilter for employee_id
     $eFilter = new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $_record->getId()));
     // delete free times
     $filter = new HumanResources_Model_FreeTimeFilter(array(), 'AND');
     $filter->addFilter($eFilter);
     HumanResources_Controller_FreeTime::getInstance()->deleteByFilter($filter);
     // delete contracts
     $filter = new HumanResources_Model_ContractFilter(array(), 'AND');
     $filter->addFilter($eFilter);
     HumanResources_Controller_Contract::getInstance()->deleteByFilter($filter);
     // delete costcenters
     if ($_record->has('costcenters')) {
         $filter = new HumanResources_Model_CostCenterFilter(array(), 'AND');
         $filter->addFilter($eFilter);
         HumanResources_Controller_CostCenter::getInstance()->deleteByFilter($filter);
     }
     // delete accounts
     $filter = new HumanResources_Model_AccountFilter(array());
     $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $_record->getId())));
     HumanResources_Controller_Account::getInstance()->deleteByFilter($filter);
     parent::_deleteLinkedObjects($_record);
 }
 /**
  * returns feast days and freedays of an employee for the freetime edit dialog
  * 
  * @param string $_employeeId
  * @param integer $_year
  * @param string $_freeTimeId
  * @param string $_accountId
  */
 public function getFeastAndFreeDays($_employeeId, $_year = NULL, $_freeTimeId = NULL, $_accountId = NULL)
 {
     $cController = HumanResources_Controller_Contract::getInstance();
     $eController = HumanResources_Controller_Employee::getInstance();
     $aController = HumanResources_Controller_Account::getInstance();
     $ftController = HumanResources_Controller_FreeTime::getInstance();
     $fdController = HumanResources_Controller_FreeDay::getInstance();
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $_employeeId ' . $_employeeId . ' $_year ' . $_year . ' $_freeTimeId ' . $_freeTimeId . ' $_accountId ' . $_accountId);
     }
     // validate employeeId
     $employee = $eController->get($_employeeId);
     $_freeTimeId = strlen($_freeTimeId) == 40 ? $_freeTimeId : NULL;
     // set period to search for
     $minDate = Tinebase_DateTime::now()->setTimezone(Tinebase_Core::getUserTimezone())->setTime(0, 0, 0);
     if ($_year && !$_freeTimeId) {
         $minDate->setDate($_year, 1, 1);
     } elseif ($_freeTimeId) {
         // if a freetime id is given, take the year of the freetime
         $myFreeTime = $ftController->get($_freeTimeId);
         $minDate->setDate($myFreeTime->firstday_date->format('Y'), 1, 1);
     } else {
         $minDate->setDate($minDate->format('Y'), 1, 1);
     }
     if (!$_accountId) {
         // find account
         $filter = new HumanResources_Model_AccountFilter(array(array('field' => 'year', 'operator' => 'equals', 'value' => intval($_year))));
         $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $_employeeId)));
         $account = $aController->search($filter)->getFirstRecord();
     } else {
         try {
             $account = $aController->get($_accountId);
         } catch (Exception $e) {
             // throws a few lines later: HumanResources_Exception_NoAccount
         }
     }
     if (!$account) {
         throw new HumanResources_Exception_NoAccount();
     }
     $accountYear = $account->year;
     $minAccountDate = Tinebase_DateTime::now()->setTimezone(Tinebase_Core::getUserTimezone())->setTime(0, 0, 0);
     $minAccountDate->setDate($accountYear, 1, 1);
     $maxAccountDate = clone $minAccountDate;
     $maxAccountDate->addYear(1)->subSecond(1);
     $maxDate = clone $minDate;
     $maxDate->addYear(1)->subSecond(1);
     // find contracts of the account year
     $contracts = $cController->getValidContracts($minAccountDate, $maxAccountDate, $_employeeId);
     $contracts->sort('start_date', 'ASC');
     if ($contracts->count() < 1) {
         throw new HumanResources_Exception_NoContract();
     }
     $remainingVacation = 0;
     $contracts->setTimezone(Tinebase_Core::getUserTimezone());
     // find out total amount of vacation days for the different contracts
     foreach ($contracts as $contract) {
         $remainingVacation += $cController->calculateVacationDays($contract, $minDate, $maxDate);
     }
     $remainingVacation = round($remainingVacation, 0);
     $allVacation = $remainingVacation;
     // find contracts of the year in which the vacation days will be taken
     $contracts = $cController->getValidContracts($minDate, $maxDate, $_employeeId);
     $contracts->sort('start_date', 'ASC');
     $excludeDates = array();
     if ($contracts->count() < 1) {
         throw new HumanResources_Exception_NoContract();
     }
     $first = TRUE;
     $feastDays = array();
     $contracts->setTimezone(Tinebase_Core::getUserTimezone());
     // find out disabled days for the different contracts
     foreach ($contracts as $contract) {
         $json = $contract->getWorkingTimeJson();
         $startDay = $contract->start_date == NULL ? $minDate : $contract->start_date < $minDate ? $minDate : $contract->start_date;
         $stopDay = $contract->end_date == NULL ? $maxDate : $contract->end_date > $maxDate ? $maxDate : $contract->end_date;
         if ($first) {
             $firstDay = clone $startDay;
             $first = FALSE;
         }
         // find out weekdays to disable
         if (is_object($json)) {
             foreach ($json->days as $index => $hours) {
                 $hours = intval($hours);
                 if ($hours === 0) {
                     $day = clone $startDay;
                     $day->setWeekDay($index + 1);
                     while ($day->compare($stopDay) == -1) {
                         $exdate = clone $day;
                         $exdate->setTimezone(Tinebase_Core::getUserTimezone());
                         $excludeDates[] = $exdate;
                         $day->addWeek(1);
                     }
                 }
             }
         }
         // search feast days
         $feastDays = array_merge($cController->getFeastDays($contract, $startDay, $stopDay), $feastDays);
     }
     // set time to 0
     foreach ($feastDays as &$feastDay) {
         $feastDay->setTimezone(Tinebase_Core::getUserTimezone())->setTime(0, 0, 0);
     }
     // search free times for the account and the interval
     // prepare free time filter, add employee_id
     $freeTimeFilter = new HumanResources_Model_FreeTimeFilter(array(), 'AND');
     $freeTimeFilter->addFilter(new Tinebase_Model_Filter_Id(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $_employeeId)));
     // don't search for freetimes belonging to the freetime handled itself
     if ($_freeTimeId) {
         $freeTimeFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'id', 'operator' => 'not', 'value' => $_freeTimeId)));
     }
     // prepare vacation times filter
     $vacationTimesFilter = clone $freeTimeFilter;
     $vacationTimesFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'type', 'operator' => 'equals', 'value' => 'vacation')));
     // search all vacation times belonging to the account, regardless which interval we want
     $accountFreeTimesFilter = clone $vacationTimesFilter;
     $accountFreeTimesFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'account_id', 'operator' => 'equals', 'value' => $account->getId())));
     $accountVacationTimeIds = $ftController->search($accountFreeTimesFilter)->id;
     // search all vacation times for the interval
     $fddMin = clone $minDate;
     $fddMin->subDay(1);
     $fddMax = clone $maxDate;
     $fddMax->addDay(1);
     $vacationTimesFilter->addFilter(new Tinebase_Model_Filter_Date(array('field' => 'firstday_date', 'operator' => 'after', 'value' => $fddMin)));
     $vacationTimesFilter->addFilter(new Tinebase_Model_Filter_Date(array('field' => 'firstday_date', 'operator' => 'before', 'value' => $fddMax)));
     $vacationTimes = $ftController->search($vacationTimesFilter);
     $acceptedVacationTimes = $vacationTimes->filter('status', 'ACCEPTED');
     // search all sickness times for the interval
     $sicknessTimesFilter = clone $freeTimeFilter;
     $sicknessTimesFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'type', 'operator' => 'equals', 'value' => 'sickness')));
     $sicknessTimesFilter->addFilter(new Tinebase_Model_Filter_Date(array('field' => 'firstday_date', 'operator' => 'after', 'value' => $fddMin)));
     $sicknessTimesFilter->addFilter(new Tinebase_Model_Filter_Date(array('field' => 'firstday_date', 'operator' => 'before', 'value' => $fddMax)));
     $sicknessTimes = $ftController->search($sicknessTimesFilter);
     // search free days belonging the found free times
     // prepare free day filter
     $freeDayFilter = new HumanResources_Model_FreeDayFilter(array(), 'AND');
     $freeDayFilter->addFilter(new Tinebase_Model_Filter_Int(array('field' => 'duration', 'operator' => 'equals', 'value' => 1)));
     // find vacation days belonging to the account (date doesn't matter, may be from another year, just count the days)
     if (count($accountVacationTimeIds)) {
         $accountFreeDayFilter = clone $freeDayFilter;
         $accountFreeDayFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'freetime_id', 'operator' => 'in', 'value' => $accountVacationTimeIds)));
         $remainingVacation = $remainingVacation - $fdController->search($accountFreeDayFilter)->count();
     }
     // find all vacation days of the period
     $vacationDayFilter = clone $freeDayFilter;
     $vacationDayFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'freetime_id', 'operator' => 'in', 'value' => $vacationTimes->id)));
     $vacationDays = $fdController->search($vacationDayFilter);
     // find out accepted vacation days. Vacation days will be substracted from remainingVacation only if they are accepted,
     // but they will be shown in the freetime edit dialog
     // TODO: discuss this
     $acceptedVacationDayFilter = clone $freeDayFilter;
     $acceptedVacationDayFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'freetime_id', 'operator' => 'in', 'value' => $acceptedVacationTimes->id)));
     $acceptedVacationDays = $fdController->search($acceptedVacationDayFilter);
     // calculate extra vacation days
     if ($account) {
         $filter = new HumanResources_Model_ExtraFreeTimeFilter(array());
         $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'account_id', 'operator' => 'equals', 'value' => $account->getId())));
         $account->extra_free_times = HumanResources_Controller_ExtraFreeTime::getInstance()->search($filter);
         $extraFreeTimes = $aController->calculateExtraFreeTimes($account, $acceptedVacationDays);
         $allVacation = $allVacation + $extraFreeTimes['remaining'];
         $remainingVacation = $remainingVacation + $extraFreeTimes['remaining'];
     } else {
         $extraFreeTimes = NULL;
     }
     // find all sickness days of the period
     $sicknessDayFilter = clone $freeDayFilter;
     $sicknessDayFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'freetime_id', 'operator' => 'in', 'value' => $sicknessTimes->id)));
     $sicknessDays = $fdController->search($sicknessDayFilter);
     $ownFreeDays = NULL;
     if ($_freeTimeId) {
         $ownFreeDaysFilter = clone $freeDayFilter;
         $ownFreeDaysFilter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'freetime_id', 'operator' => 'in', 'value' => array($_freeTimeId))));
         $ownFreeDays = $fdController->search($ownFreeDaysFilter);
         $remainingVacation = $remainingVacation - $ownFreeDays->count();
         $ownFreeDays = $ownFreeDays->toArray();
     }
     // TODO: remove results property, just return results array itself
     return array('results' => array('remainingVacation' => floor($remainingVacation), 'extraFreeTimes' => $extraFreeTimes, 'vacationDays' => $vacationDays->toArray(), 'sicknessDays' => $sicknessDays->toArray(), 'excludeDates' => $excludeDates, 'ownFreeDays' => $ownFreeDays, 'allVacation' => $allVacation, 'feastDays' => $feastDays, 'contracts' => $contracts->toArray(), 'employee' => $employee->toArray(), 'firstDay' => $firstDay, 'lastDay' => $stopDay));
 }
 /**
  * book remaining vacation days for the next year
  * 
  * @param array $accountIds
  * @return booleam
  */
 public function bookRemainingVacation($accountIds)
 {
     $filter = new HumanResources_Model_AccountFilter(array(array('field' => 'id', 'operator' => 'in', 'value' => $accountIds)));
     $accounts = $this->search($filter);
     $freeTimeController = HumanResources_Controller_FreeTime::getInstance();
     $freeDayController = HumanResources_Controller_FreeDay::getInstance();
     $configInstance = HumanResources_Config::getInstance();
     $extraFreeTimeController = HumanResources_Controller_ExtraFreeTime::getInstance();
     $db = method_exists($this->_backend, 'getAdapter') ? $this->_backend->getAdapter() : Tinebase_Core::getDb();
     $thisYear = (int) Tinebase_DateTime::now()->format('Y');
     try {
         foreach ($accounts as $account) {
             $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction($db);
             if ($account->year >= $thisYear) {
                 throw new HumanResources_Exception_RemainingNotBookable();
             }
             $data = $this->resolveVirtualFields($account);
             // do nothing if there are no remaining vacation days
             if ($data['remaining_vacation_days'] <= 0) {
                 continue;
             }
             $year = intval($account->year) + 1;
             // get account of next year
             $filter = new HumanResources_Model_AccountFilter(array(array('field' => 'year', 'operator' => 'equals', 'value' => $year)));
             $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'employee_id', 'operator' => 'equals', 'value' => $account->employee_id)));
             $result = $this->search($filter);
             if ($result->count() == 0) {
                 $ca = $this->createMissingAccounts($year, $account->employee_id);
                 $newAccount = $ca->getFirstRecord();
             } elseif ($result->count() > 1) {
                 throw new Tinebase_Exception_Record_NotAllowed('There is more than one account for the year ' . $year . '!');
             } else {
                 $newAccount = $result->getFirstRecord();
             }
             // create new extraFreetime for the new year
             $extraFreeTime = new HumanResources_Model_ExtraFreeTime(array('days' => $data['remaining_vacation_days'], 'account_id' => $newAccount->getId(), 'type' => 'PAYED', 'description' => 'Booked from last year', 'expires' => $configInstance->getVacationExpirationDate()));
             $extraFreeTimeController->create($extraFreeTime);
             // create freetimes for old year
             $freetime = $freeTimeController->create(new HumanResources_Model_FreeTime(array('type' => 'vacation', 'description' => 'Booked as extra freetime for next year.', 'status' => 'ACCEPTED', 'firstday_date' => NULL, 'employee_id' => $account->employee_id, 'account_id' => $account->getId())));
             $i = 0;
             while ($i < $data['remaining_vacation_days']) {
                 $freeDay = $freeDayController->create(new HumanResources_Model_FreeDay(array('freetime_id' => $freetime->getId(), 'duration' => 1, 'date' => null)));
                 $i++;
             }
         }
         Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId);
         return true;
     } catch (Exception $e) {
         Tinebase_TransactionManager::getInstance()->rollBack();
         throw $e;
     }
 }