/** * @see Tinebase_Setup_DemoData_Abstract * */ protected function _beforeCreate() { $this->_ccController = Sales_Controller_CostCenter::getInstance(); $this->_taController = Timetracker_Controller_Timeaccount::getInstance(); $this->_taController->sendNotifications(FALSE); $this->_tsController = Timetracker_Controller_Timesheet::getInstance(); $this->_tsController->sendNotifications(FALSE); $this->_tsController->doContainerACLChecks(false); $this->_contractController = Sales_Controller_Contract::getInstance(); $contracts = $this->_contractController->getAll(); $developmentString = self::$_de ? 'Entwicklung' : 'Development'; $this->_contractsDevelopment = $contracts->filter('title', '/.' . $developmentString . '/', TRUE); $this->_contractsMarketing = $contracts->filter('title', '/.Marketing/', TRUE); $this->_loadCostCentersAndDivisions(); if (Tinebase_Application::getInstance()->isInstalled('HumanResources')) { $this->_empController = HumanResources_Controller_Employee::getInstance(); $filter = new HumanResources_Model_EmployeeFilter(array()); $this->_employees = $this->_empController->search($filter); } // set start date to start date of june 1st before last year $date = Tinebase_DateTime::now(); $this->_startDate = $date->subMonth(3)->setTime(8, 0, 0); // set clearedDate almost a month after $this->_clearedDate = clone $this->_startDate; $this->_clearedDate->addMonth(1)->subDay(2); }
/** * Sets up the fixture. * This method is called before a test is executed. * * @access protected */ protected function setUp() { // remove employees and costcenters, if there are some already $filter = new HumanResources_Model_EmployeeFilter(array()); HumanResources_Controller_Employee::getInstance()->deleteByFilter($filter); $filter = new Sales_Model_CostCenterFilter(array()); Sales_Controller_CostCenter::getInstance()->deleteByFilter($filter); Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb()); }
/** * export employee * * @param string $filter JSON encoded string with employee ids for multi export or employee filter * @param string $options format or export definition id */ public function exportEmployees($filter, $options) { $decodedFilter = Zend_Json::decode($filter); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Export filter: ' . print_r($decodedFilter, TRUE)); } if (!is_array($decodedFilter)) { $decodedFilter = array(array('field' => 'id', 'operator' => 'equals', 'value' => $decodedFilter)); } $filter = new HumanResources_Model_EmployeeFilter($decodedFilter); parent::_export($filter, Zend_Json::decode($options), HumanResources_Controller_Employee::getInstance()); }
/** * appends sql to given select statement * * @param Zend_Db_Select $_select * @param Tinebase_Backend_Sql_Abstract $_backend * * @todo to be removed once we split filter model / backend */ public function appendFilterSql($_select, $_backend) { $ec = HumanResources_Controller_Employee::getInstance(); $filter = new HumanResources_Model_EmployeeFilter(array()); $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'n_fn', 'operator' => 'contains', 'value' => $this->_value))); $employees = $ec->search($filter); $db = Tinebase_Core::getDb(); if ($employees->count()) { $_select->where($db->quoteInto($db->quoteIdentifier('employee_id') . ' IN (?) ', $employees->id, 'array')); } else { $_select->where($db->quoteInto($db->quoteIdentifier('employee_id') . ' = (?) ', 'xxxxxxxxxxxxxxx', 'array')); } }
/** * tests demo data creation for all applications having demodata prepared */ public function testCreateAllDemoData() { $adbController = Addressbook_Controller_Contact::getInstance(); $normalContactsFilter = new Addressbook_Model_ContactFilter(array(array('field' => 'type', 'operator' => 'not', 'value' => 'user'))); $existingContacts = $adbController->search($normalContactsFilter); // skip admin as it will be called before all tests $opts = new Zend_Console_Getopt('abp:', array('skipAdmin')); ob_start(); $this->_cli->createAllDemoData($opts); ob_end_clean(); // test addressbook contacts / admin user contacts $accountContactsFilter = new Addressbook_Model_ContactFilter(array(array('field' => 'type', 'operator' => 'equals', 'value' => 'user'))); $normalContactsFilter = new Addressbook_Model_ContactFilter(array(array('field' => 'type', 'operator' => 'equals', 'value' => 'contact'))); $normalContacts = $adbController->search($normalContactsFilter); $accountContacts = $adbController->search($accountContactsFilter); // shared should be 700 $this->assertEquals(700 + $existingContacts->count(), $normalContacts->count(), 'NormalContacts'); // internal contacts/accounts $this->assertEquals(6, $accountContacts->count(), 'AccountContacts'); // test calendar entries $calController = Calendar_Controller_Event::getInstance(); $allEventsFilter = new Calendar_Model_EventFilter(array()); $allEvents = $calController->search($allEventsFilter); $this->assertEquals(49, $allEvents->count(), 'Events'); // test crm leads $crmController = Crm_Controller_Lead::getInstance(); $allLeadsFilter = new Crm_Model_LeadFilter(array()); $allLeads = $crmController->search($allLeadsFilter); $this->assertEquals(1, $allLeads->count(), 'One shared lead should have been found'); // test human resources $employeeController = HumanResources_Controller_Employee::getInstance(); $allEmployeesFilter = new HumanResources_Model_EmployeeFilter(array()); $allEmployees = $employeeController->search($allEmployeesFilter); $this->assertEquals(6, $allEmployees->count()); // remove employees again $employeeController->delete($allEmployees->id); }
/** * test adding a contract with manually setting the end_date of the contract before */ public function testAddContract() { $sdate = new Tinebase_DateTime('2013-01-01 00:00:00'); $sdate->setTimezone(Tinebase_Core::getUserTimezone()); $employee = $this->_getEmployee('rwright'); $contractController = HumanResources_Controller_Contract::getInstance(); $employeeController = HumanResources_Controller_Employee::getInstance(); $employee = $employeeController->create($employee); $contract = $this->_getContract($sdate); $contract->workingtime_json = '{"days": [8,8,8,8,8,0,0]}'; $contract->employee_id = $employee->getId(); $feastCalendar = $this->_getFeastCalendar(); $contract->feast_calendar_id = $feastCalendar->getId(); $contract->start_date = $sdate; $contractController->create($contract); $employeeJson = $this->_json->getEmployee($employee->getId()); $accountController = HumanResources_Controller_Account::getInstance(); // should not be created, exist already $accountController->createMissingAccounts(2013, $employee); $account = $accountController->getAll()->getFirstRecord(); $employeeJson['vacation'] = array(array('account_id' => $account->getId(), 'type' => 'vacation', 'status' => 'ACCEPTED', 'freedays' => array(array('duration' => '1', 'date' => '2013-01-11 00:00:00')))); $employeeJson = $this->_json->saveEmployee($employeeJson); $this->assertEquals(1, count($employeeJson['vacation'])); // manually set the end date and add a new contract $employeeJson['contracts'][0]['end_date'] = '2013-05-31 00:00:00'; $employeeJson['contracts'][1] = array('start_date' => '2013-06-01 00:00:00', 'workingtime_json' => '{"days": [8,8,8,8,8,0,0]}', 'vacation_days' => 27, 'feast_calendar_id' => $feastCalendar->getId()); // no exception should be thrown $employeeJson = $this->_json->saveEmployee($employeeJson); $this->assertEquals(2, count($employeeJson['contracts'])); // an exception should be thrown $employeeJson['contracts'][0]['vacation_days'] = 31; $this->setExpectedException('HumanResources_Exception_ContractNotEditable'); $employeeJson = $this->_json->saveEmployee($employeeJson); }
/** * creates for each account an employee */ protected function _createSharedEmployees() { $controller = HumanResources_Controller_Employee::getInstance(); $this->_feastCalendar = Tinebase_Container::getInstance()->addContainer(new Tinebase_Model_Container(array('name' => 'Feast Calendar', 'type' => Tinebase_Model_Container::TYPE_SHARED, 'owner_id' => Tinebase_Core::getUser(), 'backend' => 'SQL', 'application_id' => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(), 'color' => '#00FF00'), TRUE)); $controller->transferUserAccounts(FALSE, $this->_feastCalendar->getId(), NULL, 27, TRUE); $employees = $controller->search(new HumanResources_Model_EmployeeFilter(array())); // get pwulf as supervisor $pwulf = $employees->filter('n_family', 'Wulf')->getFirstRecord(); $sdate = new Tinebase_DateTime(); $sdate->subMonth(6); $defaultData = array('supervisor_id' => $pwulf->getId(), 'countryname' => 'GB', 'region' => 'East Sussex', 'locality' => 'Brighton', 'employment_begin' => $sdate); foreach ($employees as $employee) { if (!$employee->account_id) { echo '=== SKIPPING ===' . PHP_EOL; echo 'There is no account_id for this employee: ' . PHP_EOL; echo print_r($employee->toArray(), 1); echo 'This employee won\'t have costcenters, contracts, etc.' . PHP_EOL; echo '=== SKIPPING ===' . PHP_EOL; } $user = Tinebase_User::getInstance()->getUserByProperty('accountId', $employee->account_id, 'Tinebase_Model_FullUser'); foreach (array_merge($defaultData, $this->_dataMapping[$user->accountLoginName]) as $key => $data) { $employee->{$key} = $data; $employee->employment_begin = $this->_startDate; } // add costcenter $scs = $this->_costCenters->getByIndex(0); $hrc = array('cost_center_id' => $scs->getId(), 'start_date' => $this->_startDate); $employee->costcenters = array($hrc); // add contract $contract = $this->_getContract($sdate); $employee->contracts = array($contract->toArray()); // add division $division = $this->_divisions->getByIndex(0); $employee->division_id = $division->getId(); // update and increment counter $controller->update($employee); } HumanResources_Controller_Account::getInstance()->createMissingAccounts(); }
/** * 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)); }
/** * tests set_contracts_end_date */ public function testSetContractsEndDate() { $this->_doImport(FALSE); $cc = HumanResources_Controller_Contract::getInstance(); $ec = HumanResources_Controller_Employee::getInstance(); $user = Tinebase_Core::getUser(); $begin = Tinebase_DateTime::now()->subYear(1); $end = clone $begin; $end->addMonth(11); $employee = new HumanResources_Model_Employee(array('account_id' => $user->getId(), 'n_family' => 'TEST', 'n_given' => 'UNIT', 'employment_begin' => $begin, 'employment_end' => NULL)); $employee = $ec->create($employee); $contract = new HumanResources_Model_Contract(array('employee_id' => $employee->getId(), 'start_date' => $begin, 'end_date' => NULL, 'workingtime_json' => '{days: [4,4,4,4,4,0,0]}', 'vacation_days' => 34)); $contract = $cc->create($contract); $this->assertEquals(NULL, $contract->end_date); $this->assertEquals(NULL, $employee->employment_end); $newEnd = Tinebase_DateTime::now()->subDay(1); $employee->employment_end = $newEnd; $employee->contracts = array($contract->toArray()); $ec->update($employee); $this->_cli->set_contracts_end_date(); $allContracts = $cc->getAll(); $updatedContract = $cc->get($contract->getId()); $this->assertEquals($newEnd, $updatedContract->end_date); }
/** * tests if the filter for the employee model gets created properly */ public function testFilters() { // prepare dates $today = new Tinebase_DateTime(); $oneMonthAgo = clone $today; $oneMonthAgo->subMonth(1); $oneMonthAhead = clone $today; $oneMonthAhead->addMonth(1); $twoMonthsAgo = clone $oneMonthAgo; $twoMonthsAgo->subMonth(1); $employeeController = HumanResources_Controller_Employee::getInstance(); $employee1 = $this->_getEmployee('pwulf'); $employee1->employment_begin = $oneMonthAgo; $employee1->employment_end = $oneMonthAhead; $employee1 = $employeeController->create($employee1); $employee2 = $this->_getEmployee('rwright'); $employee2->employment_begin = $oneMonthAgo; $employee2 = $employeeController->create($employee2); $filter = new HumanResources_Model_EmployeeFilter(array(array('field' => 'n_given', 'operator' => 'equals', 'value' => 'Paul'))); $result = $employeeController->search($filter); $this->assertEquals(1, $result->count()); $this->assertEquals('Paul', $result->getFirstRecord()->n_given); // test employed filter // employee3 is not yet employed $employee3 = $this->_getEmployee('jmcblack'); $employee3->employment_begin = $oneMonthAhead; $employee3 = $employeeController->create($employee3); // employee4 has been employed $employee4 = $this->_getEmployee('jsmith'); $employee4->employment_begin = $twoMonthsAgo; $employee4->employment_end = $oneMonthAgo; $employee4 = $employeeController->create($employee4); $this->assertEquals('Photographer', $employee4->position); $filter = new HumanResources_Model_EmployeeFilter(array(array('field' => 'is_employed', 'operator' => 'equals', 'value' => TRUE))); $result = $employeeController->search($filter); $msg = 'rwright and pwulf should have been found'; $this->assertEquals(2, $result->count(), $msg); $names = $result->n_fn; // just rwright and pwulf should have been found $this->assertContains('Roberta Wright', $names, $msg); $this->assertContains('Paul Wulf', $names, $msg); $filter = new HumanResources_Model_EmployeeFilter(array(array('field' => 'is_employed', 'operator' => 'equals', 'value' => FALSE))); $result = $employeeController->search($filter); $msg = 'jsmith and jmcblack should have been found'; $this->assertEquals(2, $result->count(), $msg); $names = $result->n_fn; // just jsmith and jmcblack should have been found $this->assertContains('John Smith', $names, $msg); $this->assertContains('James McBlack', $names, $msg); }
/** * sets the contracts end_date to the date of employment_begin of the corresponding * employee, if employee has an employment end date */ public function set_contracts_end_date() { $eController = HumanResources_Controller_Employee::getInstance(); $cController = HumanResources_Controller_Contract::getInstance(); $filter = new HumanResources_Model_EmployeeFilter(array(array('field' => 'is_employed', 'operator' => 'equals', 'value' => FALSE))); $oldEmployees = $eController->search($filter); foreach ($oldEmployees as $employee) { $contract = $cController->getContractsByEmployeeId($employee->getId())->sort('start_date', 'DESC')->getFirstRecord(); if ($contract) { $contract->end_date = $employee->employment_end; $cController->update($contract); } } }