예제 #1
0
 /**
  * the singleton pattern
  *
  * @return Timetracker_Controller_Timeaccount
  */
 public static function getInstance()
 {
     if (self::$_instance === NULL) {
         self::$_instance = new Timetracker_Controller_Timeaccount();
     }
     return self::$_instance;
 }
예제 #2
0
 /**
  * search and show duplicate timeaccounts
  * 
  * @return void
  */
 public function searchDuplicateTimeaccounts()
 {
     $filter = new Timetracker_Model_TimeaccountFilter(array(array('field' => 'showClosed', 'operator' => 'equals', 'value' => FALSE)));
     $duplicates = parent::_searchDuplicates(Timetracker_Controller_Timeaccount::getInstance(), $filter, 'title');
     echo 'Found ' . count($duplicates) / 2 . ' Timeaccount duplicate(s):' . "\n";
     print_r($duplicates);
 }
 /**
  * creates shared tas
  */
 protected function _createSharedTimeaccounts()
 {
     // create 2 timeaccounts for each cc
     $taNumber = 1;
     $userGroup = Tinebase_Group::getInstance()->getGroupByName('Users');
     $developmentString = self::$_de ? 'Entwicklung' : 'Development';
     if (!$userGroup) {
         die('Could not find userGroup "Users", stopping.');
     }
     $grants = array(array('account_id' => $userGroup->getId(), 'account_type' => 'group', 'bookOwnGrant' => TRUE, 'viewAllGrant' => TRUE, 'bookAllGrant' => TRUE, 'manageBillableGrant' => TRUE, 'exportGrant' => TRUE, 'adminGrant' => TRUE));
     $contractsIndex = 0;
     foreach ($this->_costCenters as $costcenter) {
         $this->_timeAccounts[$costcenter->getId()] = new Tinebase_Record_RecordSet('Timetracker_Model_Timeaccount');
         $i = 0;
         while ($i < 2) {
             $i++;
             $ta = new Timetracker_Model_Timeaccount(array('number' => $taNumber, 'title' => Tinebase_Record_Abstract::generateUID(3), 'grants' => $grants, 'status' => 'billed', 'cleared_at' => $this->_clearedDate, 'budget' => NULL, 'description' => 'Created By Tine 2.0 DEMO DATA'));
             if ($costcenter->remark == 'Marketing' || $costcenter->remark == $developmentString) {
                 $contract = $costcenter->remark == 'Marketing' ? $this->_contractsMarketing->getByIndex(rand(0, $this->_contractsMarketing->count() - 1)) : $this->_contractsDevelopment->getByIndex(rand(0, $this->_contractsDevelopment->count() - 1));
                 $ta->budget = $costcenter->remark == 'Marketing' ? 100 : NULL;
                 $ta->relations = array(array('own_model' => 'Timetracker_Model_Timeaccount', 'own_backend' => 'SQL', 'own_id' => NULL, 'related_degree' => Tinebase_Model_Relation::DEGREE_SIBLING, 'related_model' => 'Sales_Model_CostCenter', 'related_backend' => Tasks_Backend_Factory::SQL, 'related_id' => $costcenter->getId(), 'type' => 'COST_CENTER'), array('own_model' => 'Timetracker_Model_Timeaccount', 'own_backend' => 'SQL', 'own_id' => NULL, 'related_degree' => Tinebase_Model_Relation::DEGREE_SIBLING, 'related_model' => 'Sales_Model_Contract', 'related_backend' => Tasks_Backend_Factory::SQL, 'related_id' => $contract->getId(), 'type' => 'TIME_ACCOUNT'));
                 $ta->title = (self::$_de ? 'Zeitkonto mit ' : 'Timeaccount for ') . $contract->getTitle();
             } else {
                 $ta->title = (self::$_de ? 'Zeitkonto mit KST ' : 'Timeaccount for CC ') . $costcenter->getTitle();
                 $ta->relations = array(array('own_model' => 'Timetracker_Model_Timeaccount', 'own_backend' => 'SQL', 'own_id' => NULL, 'related_degree' => Tinebase_Model_Relation::DEGREE_SIBLING, 'related_model' => 'Sales_Model_CostCenter', 'related_backend' => Tasks_Backend_Factory::SQL, 'related_id' => $costcenter->getId(), 'type' => 'COST_CENTER'));
             }
             $this->_timeAccounts[$costcenter->getId()]->addRecord($this->_taController->create($ta));
             $taNumber++;
         }
     }
 }
예제 #4
0
 /**
  * calculate effective ta grants so the client doesn't need to calculate them
  *
  * @param  array  $_timesaccounts
  */
 protected function _resolveTimeaccountGrants(Tinebase_Record_RecordSet $_timesaccounts)
 {
     $manageAllRight = Timetracker_Controller_Timeaccount::getInstance()->checkRight(Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS, FALSE);
     foreach ($_timesaccounts as $timeaccount) {
         $timeaccountGrantsArray = $timeaccount->account_grants;
         $modifyGrant = $manageAllRight || $timeaccountGrantsArray[Timetracker_Model_TimeaccountGrants::GRANT_ADMIN];
         $timeaccountGrantsArray[Tinebase_Model_Grants::GRANT_READ] = true;
         $timeaccountGrantsArray[Tinebase_Model_Grants::GRANT_EDIT] = $modifyGrant;
         $timeaccountGrantsArray[Tinebase_Model_Grants::GRANT_DELETE] = $modifyGrant;
         $timeaccount->account_grants = $timeaccountGrantsArray;
         // also move the grants into the container_id property, as the clients expects records to
         // be contained in some kind of container where it searches the grants in
         $timeaccount->container_id = array('account_grants' => $timeaccountGrantsArray);
     }
 }
 /**
  * inspects delete action
  *
  * @param array $_ids
  * @return array of ids to actually delete
  */
 protected function _inspectDelete(array $_ids)
 {
     $records = $this->_backend->getMultiple($_ids);
     $records->setTimezone(Tinebase_Core::getUserTimezone());
     $invoicePositionController = Sales_Controller_InvoicePosition::getInstance();
     $contractController = Sales_Controller_Contract::getInstance();
     foreach ($records as $record) {
         if (!$record->is_auto) {
             continue;
         }
         if ($record->cleared == 'CLEARED') {
             // cleared invoices must not be deleted
             throw new Sales_Exception_InvoiceAlreadyClearedDelete();
         } else {
             // try to find a invoice after this one
             // there should be a contract
             $contractRelation = Tinebase_Relations::getInstance()->getRelations('Sales_Model_Invoice', 'Sql', $record->getId(), NULL, array(), TRUE, array('Sales_Model_Contract'))->getFirstRecord();
             if ($contractRelation) {
                 $contract = $contractRelation->related_record;
                 $contract->setTimezone(Tinebase_Core::getUserTimezone());
                 // get all invoices related to this contract. throw exception if a follwing invoice has been found
                 $invoiceRelations = Tinebase_Relations::getInstance()->getRelations('Sales_Model_Contract', 'Sql', $contract->getId(), NULL, array(), TRUE, array('Sales_Model_Invoice'));
                 foreach ($invoiceRelations as $invoiceRelation) {
                     $invoiceRelation->related_record->setTimezone(Tinebase_Core::getUserTimezone());
                     if ($record->getId() !== $invoiceRelation->related_record->getId() && $record->creation_time < $invoiceRelation->related_record->creation_time) {
                         throw new Sales_Exception_DeletePreviousInvoice();
                     }
                 }
                 $this->_currentBillingContract = $contract;
                 $productAggregates = $this->_findProductAggregates();
             } else {
                 if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
                     Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not find contract relation -> skip contract handling');
                 }
                 $contract = null;
                 $productAggregates = array();
             }
             // remove invoice_id from billables
             $filter = new Sales_Model_InvoicePositionFilter(array());
             $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $record->getId())));
             $invoicePositions = $invoicePositionController->search($filter);
             $allModels = array_unique($invoicePositions->model);
             foreach ($allModels as $model) {
                 if ($model == 'Sales_Model_ProductAggregate') {
                     continue;
                 }
                 $filteredInvoicePositions = $invoicePositions->filter('model', $model);
                 $billableControllerName = $model::getBillableControllerName();
                 $billableFilterName = $model::getBillableFilterName();
                 $filterInstance = new $billableFilterName(array());
                 $filterInstance->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $record->getId())));
                 $billableControllerName::getInstance()->updateMultiple($filterInstance, array('invoice_id' => NULL));
                 // set invoice ids of the timeaccounts
                 if ($model == 'Timetracker_Model_Timeaccount') {
                     $filterInstance = new Timetracker_Model_TimeaccountFilter(array());
                     $filterInstance->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $record->getId())));
                     Timetracker_Controller_Timeaccount::getInstance()->updateMultiple($filterInstance, array('invoice_id' => NULL));
                 }
             }
             // delete invoice positions
             $invoicePositionController->delete($invoicePositions->getId());
             // set last_autobill a period back
             if ($contract) {
                 //find the month of each productAggregate we have to set it back to
                 $undoProductAggregates = array();
                 $paController = Sales_Controller_ProductAggregate::getInstance();
                 foreach ($invoicePositions as $inPos) {
                     if ($inPos->model != 'Sales_Model_ProductAggregate') {
                         continue;
                     }
                     //if we didnt find a month for the productAggreagte yet or if the month found is greater than the one we have at hands
                     if (!isset($undoProductAggregates[$inPos->accountable_id]) || strcmp($undoProductAggregates[$inPos->accountable_id], $inPos->month) > 0) {
                         $undoProductAggregates[$inPos->accountable_id] = $inPos->month;
                     }
                 }
                 foreach ($productAggregates as $productAggregate) {
                     if (!$productAggregate->last_autobill) {
                         continue;
                     }
                     if (!isset($undoProductAggregates[$productAggregate->id])) {
                         $product = $this->_cachedProducts->getById($productAggregate->product_id);
                         if (!$product) {
                             $product = Sales_Controller_Product::getInstance()->get($productAggregate->product_id);
                             $this->_cachedProducts->addRecord($product);
                         }
                         if ($product->accountable == 'Sales_Model_Product' || $record->date != null && $record->date->isLater($productAggregate->last_autobill)) {
                             continue;
                         }
                         $productAggregate->last_autobill->subMonth($productAggregate->interval);
                     } else {
                         $productAggregate->last_autobill = new Tinebase_DateTime($undoProductAggregates[$productAggregate->id] . '-01 00:00:00', Tinebase_Core::getUserTimezone());
                         if ($productAggregate->billing_point == 'begin') {
                             $productAggregate->last_autobill->subMonth($productAggregate->interval);
                         }
                         if ($productAggregate->start_date && $productAggregate->last_autobill < $productAggregate->start_date) {
                             $tmp = clone $productAggregate->start_date;
                             $tmp->setTimezone(Tinebase_Core::getUserTimezone());
                             $tmp->setDate($tmp->format('Y'), $tmp->format('m'), 1);
                             $tmp->setTime(0, 0, 0);
                             if ($productAggregate->last_autobill < $tmp || $productAggregate->billing_point == 'end' && $productAggregate->last_autobill == $tmp) {
                                 $productAggregate->last_autobill = NULL;
                             }
                         }
                     }
                     $productAggregate->setTimezone('UTC');
                     $paController->update($productAggregate);
                     $productAggregate->setTimezone(Tinebase_Core::getUserTimezone());
                 }
             }
         }
     }
     return $_ids;
 }
 /**
  * tests the corret handling of the usertimezone in the date filter
  */
 public function testDateIntervalFilter()
 {
     $taController = Timetracker_Controller_Timeaccount::getInstance();
     $tsController = Timetracker_Controller_Timesheet::getInstance();
     $dateString = '2014-07-14 00:15:00';
     $date = new Tinebase_DateTime($dateString, Tinebase_Core::getUserTimezone());
     $ta = $taController->create(new Timetracker_Model_Timeaccount(array('number' => '123', 'title' => 'test')));
     $r = new Timetracker_Model_Timesheet(array('timeaccount_id' => $ta->getId(), 'account_id' => Tinebase_Core::getUser()->getId(), 'description' => 'lazy boring', 'start_date' => $date, 'duration' => 30));
     $r->setTimezone('UTC');
     $ts = $tsController->create($r);
     $filter = new Timetracker_Model_TimesheetFilter(array());
     $dateFilter = new Tinebase_Model_Filter_DateMock(array('field' => 'start_date', 'operator' => "within", "value" => "weekThis"));
     $dateFilter::$testDate = $date;
     $filter->addFilter($dateFilter);
     $results = $tsController->search($filter);
     $this->assertEquals(1, $results->count());
 }
 /**
  * 
  * @param array $recordData
  * @return Tinebase_Record_RecordSet
  */
 protected function _createTimeaccounts($recordData = NULL)
 {
     $this->_timeaccountRecords = new Tinebase_Record_RecordSet('Timetracker_Model_Timeaccount');
     $this->_timeaccountController = Timetracker_Controller_Timeaccount::getInstance();
     if (!$recordData) {
         // ta for customer 1 and 2 is budgeted AND to bill
         foreach ($this->_customerRecords as $customer) {
             $this->_timeaccountRecords->addRecord($this->_timeaccountController->create(new Timetracker_Model_Timeaccount(array('title' => 'TA-for-' . $customer->name, 'description' => 'blabla', 'is_open' => 1, 'status' => $customer->name == 'Customer4' ? 'billed' : 'to bill', 'budget' => $customer->name == 'Customer3' ? null : 100), TRUE)));
         }
     } else {
         foreach ($recordData as $taArray) {
             $this->_timeaccountRecords->addRecord($this->_timeaccountController->create(new Timetracker_Model_Timeaccount($taArray, TRUE)));
         }
     }
     return $this->_timeaccountRecords;
 }
 /**
  * get Timesheet (create timeaccount as well)
  *
  * @param array fields data
  * @param boolean force creation of the record
  * @return Timetracker_Model_Timesheet
  */
 protected function _getTimesheet($_data = array(), $_forceCreation = false)
 {
     $defaultData = array('account_id' => Tinebase_Core::getUser()->getId(), 'description' => 'blabla', 'duration' => 30, 'timeaccount_id' => NULL, 'start_date' => NULL);
     $data = array_replace($defaultData, $_data);
     if ($data['timeaccount_id'] === NULL) {
         $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->create($this->_getTimeaccount());
         $data['timeaccount_id'] = $timeaccount->getId();
     }
     if ($data['start_date'] === NULL) {
         $data['start_date'] = Tinebase_DateTime::now()->toString('Y-m-d');
     }
     $ts = new Timetracker_Model_Timesheet($data, TRUE);
     if ($_forceCreation) {
         $tsRec = $this->_json->saveTimesheet($ts->toArray());
         $this->_lastCreatedRecord = $tsRec;
     }
     return $ts;
 }
 /**
  * check grant for action
  *
  * @param Timetracker_Model_Timeaccount $_record
  * @param string $_action
  * @param boolean $_throw
  * @param string $_errorMessage
  * @param Timetracker_Model_Timesheet $_oldRecord
  * @return boolean
  * @throws Tinebase_Exception_AccessDenied
  * 
  * @todo think about just setting the default values when user 
  *       hasn't the required grant to change the field (instead of throwing exception) 
  */
 protected function _checkGrant($_record, $_action, $_throw = TRUE, $_errorMessage = 'No Permission.', $_oldRecord = NULL)
 {
     $isAdmin = false;
     // users with MANAGE_TIMEACCOUNTS have all grants here
     if ($this->checkRight(Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS, FALSE) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Tinebase_Model_Grants::GRANT_ADMIN)) {
         $isAdmin = true;
     }
     // only TA managers are allowed to alter TS of closed TAs, but they have to confirm first that they really want to do it
     if ($_action != 'get') {
         $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->get($_record->timeaccount_id);
         if (!$timeaccount->is_open) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' This Timeaccount is already closed!');
             }
             if ($isAdmin === true) {
                 if (is_array($this->_requestContext) && isset($this->_requestContext['skipClosedCheck']) && $this->_requestContext['skipClosedCheck']) {
                     return true;
                 }
             }
             if ($_throw) {
                 throw new Timetracker_Exception_ClosedTimeaccount();
             }
             return FALSE;
         }
         // check if timeaccount->is_billable is false => set default in fieldGrants to 0 and allow only managers to change it
         if (!$timeaccount->is_billable) {
             $this->_fieldGrants['is_billable']['default'] = 0;
             $this->_fieldGrants['is_billable']['requiredGrant'] = Tinebase_Model_Grants::GRANT_ADMIN;
         }
     }
     if ($isAdmin === true) {
         return true;
     }
     $hasGrant = FALSE;
     switch ($_action) {
         case 'get':
             $hasGrant = Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, array(Timetracker_Model_TimeaccountGrants::VIEW_ALL, Timetracker_Model_TimeaccountGrants::BOOK_ALL)) || $_record->account_id == Tinebase_Core::getUser()->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN);
             break;
         case 'create':
             $hasGrant = $_record->account_id == Tinebase_Core::getUser()->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_ALL);
             if ($hasGrant) {
                 foreach ($this->_fieldGrants as $field => $config) {
                     if (isset($_record->{$field}) && $_record->{$field} != $config['default']) {
                         $hasGrant &= Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, $config['requiredGrant']);
                     }
                 }
             }
             break;
         case 'update':
             $hasGrant = $_record->account_id == Tinebase_Core::getUser()->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_ALL);
             if ($hasGrant) {
                 foreach ($this->_fieldGrants as $field => $config) {
                     if (isset($_record->{$field}) && $_record->{$field} != $_oldRecord->{$field}) {
                         $hasGrant &= Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, $config['requiredGrant']);
                     }
                 }
             }
             break;
         case 'delete':
             $hasGrant = $_record->account_id == Tinebase_Core::getUser()->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_ALL);
             break;
     }
     if ($_throw && !$hasGrant) {
         throw new Tinebase_Exception_AccessDenied($_errorMessage);
     }
     return $hasGrant;
 }
 /**
  * @see: rt127444
  * 
  * make sure timeaccounts won't be billed if they shouldn't
  */
 public function testBudgetTimeaccountBilled()
 {
     $this->_createFullFixtures();
     $date = clone $this->_referenceDate;
     $i = 0;
     // do not set to bill, this ta has a budget
     $customer1Timeaccount = $this->_timeaccountRecords->filter('title', 'TA-for-Customer1')->getFirstRecord();
     $customer1Timeaccount->status = 'not yet billed';
     $tsController = Timetracker_Controller_Timesheet::getInstance();
     $taController = Timetracker_Controller_Timeaccount::getInstance();
     $taController->update($customer1Timeaccount);
     // this is a ts on 20xx-01-18
     $timesheet = new Timetracker_Model_Timesheet(array('account_id' => Tinebase_Core::getUser()->getId(), 'timeaccount_id' => $customer1Timeaccount->getId(), 'start_date' => $date->addDay(17), 'duration' => 120, 'description' => 'ts from ' . (string) $date));
     $tsController->create($timesheet);
     // this is a ts on 20xx-02-03
     $timesheet->id = NULL;
     $timesheet->start_date = $date->addDay(17);
     $timesheet->description = 'ts from ' . (string) $date;
     $tsController->create($timesheet);
     $date = clone $this->_referenceDate;
     $date->addMonth(1);
     $result = $this->_invoiceController->createAutoInvoices($date);
     $this->assertEquals(1, count($result['created']));
     $customer1Timeaccount->status = 'to bill';
     $taController->update($customer1Timeaccount);
     $date->addSecond(1);
     $result = $this->_invoiceController->createAutoInvoices($date);
     $this->assertEquals(1, count($result['created']));
     $invoiceId = $result['created'][0];
     $invoice = $this->_invoiceController->get($invoiceId);
     $found = FALSE;
     foreach ($invoice->relations as $relation) {
         if ($relation->related_model == 'Timetracker_Model_Timeaccount') {
             $this->assertEquals('TA-for-Customer1', $relation->related_record->title);
             $found = TRUE;
         }
     }
     $this->assertTrue($found, 'the timeaccount could not be found in the invoice!');
 }
 /**
  * set timeaccount grants
  *
  * @param Timetracker_Model_Timeaccount $_timeaccount
  * @param Tinebase_Record_RecordSet $_grants
  * @param boolean $_ignoreACL
  */
 public static function setTimeaccountGrants(Timetracker_Model_Timeaccount $_timeaccount, Tinebase_Record_RecordSet $_grants, $_ignoreACL = FALSE)
 {
     if (!$_ignoreACL) {
         if (!Timetracker_Controller_Timeaccount::getInstance()->checkRight(Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS, FALSE)) {
             if (!self::hasGrant($_timeaccount, Tinebase_Model_Grants::GRANT_ADMIN)) {
                 throw new Tinebase_Exception_AccessDenied("You nor have the RIGHT either the GRANT to get see all grants for this timeaccount");
             }
         }
     }
     Tinebase_Container::getInstance()->setGrants($_timeaccount->container_id, $_grants, TRUE, FALSE);
 }
예제 #12
0
 /**
  * check grant for action
  *
  * @param Timetracker_Model_Timeaccount $_record
  * @param string $_action
  * @param boolean $_throw
  * @param string $_errorMessage
  * @param Timetracker_Model_Timesheet $_oldRecord
  * @return boolean
  * @throws Tinebase_Exception_AccessDenied
  * 
  * @todo think about just setting the default values when user 
  *       hasn't the required grant to change the field (instead of throwing exception) 
  */
 protected function _checkGrant($_record, $_action, $_throw = TRUE, $_errorMessage = 'No Permission.', $_oldRecord = NULL)
 {
     // users with MANAGE_TIMEACCOUNTS have all grants here
     if ($this->checkRight(Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS, FALSE) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Tinebase_Model_Grants::GRANT_ADMIN)) {
         return TRUE;
     }
     // only TA managers are allowed to alter TS of closed TAs
     if ($_action != 'get') {
         $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->get($_record->timeaccount_id);
         if (!$timeaccount->is_open) {
             return FALSE;
         }
         // check if timeaccount->is_billable is false => set default in fieldGrants to 0 and allow only managers to change it
         if (!$timeaccount->is_billable) {
             $this->_fieldGrants['is_billable']['default'] = 0;
             $this->_fieldGrants['is_billable']['requiredGrant'] = Tinebase_Model_Grants::GRANT_ADMIN;
         }
     }
     $hasGrant = FALSE;
     switch ($_action) {
         case 'get':
             $hasGrant = Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, array(Timetracker_Model_TimeaccountGrants::VIEW_ALL, Timetracker_Model_TimeaccountGrants::BOOK_ALL)) || $_record->account_id == $this->_currentAccount->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN);
             break;
         case 'create':
             $hasGrant = $_record->account_id == $this->_currentAccount->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_ALL);
             if ($hasGrant) {
                 foreach ($this->_fieldGrants as $field => $config) {
                     if (isset($_record->{$field}) && $_record->{$field} != $config['default']) {
                         $hasGrant &= Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, $config['requiredGrant']);
                     }
                 }
             }
             break;
         case 'update':
             $hasGrant = $_record->account_id == $this->_currentAccount->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_ALL);
             if ($hasGrant) {
                 foreach ($this->_fieldGrants as $field => $config) {
                     if (isset($_record->{$field}) && $_record->{$field} != $_oldRecord->{$field}) {
                         $hasGrant &= Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, $config['requiredGrant']);
                     }
                 }
             }
             break;
         case 'delete':
             $hasGrant = $_record->account_id == $this->_currentAccount->getId() && Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_OWN) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Timetracker_Model_TimeaccountGrants::BOOK_ALL);
             break;
     }
     if ($_throw && !$hasGrant) {
         throw new Tinebase_Exception_AccessDenied($_errorMessage);
     }
     return $hasGrant;
 }
 /**
  * resolve records
  *
  * @param Tinebase_Record_RecordSet $_records
  */
 protected function _resolveRecords(Tinebase_Record_RecordSet $_records)
 {
     parent::_resolveRecords($_records);
     $timeaccountIds = $_records->timeaccount_id;
     $this->_resolvedRecords['timeaccounts'] = Timetracker_Controller_Timeaccount::getInstance()->getMultiple(array_unique(array_values($timeaccountIds)));
 }
 /**
  * set each billable of this accountable billed
  *
  * @param Sales_Model_Invoice $invoice
  */
 public function clearBillables(Sales_Model_Invoice $invoice)
 {
     $tsController = Timetracker_Controller_Timesheet::getInstance();
     $this->_disableTimesheetChecks($tsController);
     $filter = new Timetracker_Model_TimesheetFilter(array(), 'AND');
     $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'is_cleared', 'operator' => 'equals', 'value' => 0)));
     $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'timeaccount_id', 'operator' => 'equals', 'value' => $this->getId())));
     $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $invoice->getId())));
     // if this timeaccount has a budget, close and bill this and set cleared at date
     if (intval($this->budget) > 0) {
         $this->is_open = 0;
         $this->status = 'billed';
         $this->cleared_at = Tinebase_DateTime::now();
         Timetracker_Controller_Timeaccount::getInstance()->update($this);
         // also clear all timesheets belonging to this invoice and timeaccount
         $tsController->updateMultiple($filter, array('is_cleared' => 1));
     } else {
         // otherwise clear all timesheets of this invoice
         $tsController->updateMultiple($filter, array('is_cleared' => 1));
     }
     $this->_enableTimesheetChecks($tsController);
 }
예제 #15
0
 /**
  * try to search for Timesheets (with combined is_billable + cleared)
  */
 public function testSearchTimesheetsWithCombinedIsBillableAndCleared()
 {
     // create
     $timesheet = $this->_getTimesheet();
     $timesheetData = $this->_json->saveTimesheet($timesheet->toArray());
     // update timeaccount -> is_billable = false
     $ta = Timetracker_Controller_Timeaccount::getInstance()->get($timesheetData['timeaccount_id']['id']);
     $ta->is_billable = 0;
     Timetracker_Controller_Timeaccount::getInstance()->update($ta);
     // search & check
     $search = $this->_json->searchTimesheets($this->_getTimesheetFilter(array('field' => 'is_cleared_combined', 'operator' => 'equals', 'value' => FALSE)), $this->_getPaging('is_billable_combined'));
     $this->assertEquals(0, $search['results'][0]['is_billable_combined'], 'is_billable_combined mismatch');
     $this->assertEquals(0, $search['results'][0]['is_cleared_combined'], 'is_cleared_combined mismatch');
     $this->assertEquals(1, $search['totalcount']);
     $this->assertEquals(30, $search['totalsum']);
     $this->assertEquals(0, $search['totalsumbillable']);
     // search again with is_billable filter
     $search = $this->_json->searchTimesheets($this->_getTimesheetFilter(array('field' => 'is_billable_combined', 'operator' => 'equals', 'value' => FALSE)), $this->_getPaging('is_billable_combined'));
     $this->assertEquals(0, $search['results'][0]['is_billable_combined'], 'is_billable_combined mismatch');
     // search again with is_billable filter and no sorting
     $search = $this->_json->searchTimesheets($this->_getTimesheetFilter(array('field' => 'is_billable_combined', 'operator' => 'equals', 'value' => FALSE)), $this->_getPaging());
     $this->assertEquals(0, $search['results'][0]['is_billable_combined'], 'is_billable_combined mismatch');
 }
 /**
  * here we search for all timeaccounts, which are related to an contract with a special
  * internal contact assigned
  * 
  * @see: 0009752: create contract - internal/external contact person filter
  */
 public function testTimeaccountContractInternalContactFilter()
 {
     $this->markTestSkipped('0010492: fix failing invoices and timetracker tests');
     $this->_getTimeaccount(array('title' => 'to find'), true);
     $taController = Timetracker_Controller_Timeaccount::getInstance();
     $taToFind = $taController->get($this->_lastCreatedRecord['id']);
     $this->_getTimeaccount(array('title' => 'not to find'), true);
     $contact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array('n_family' => 'Green')));
     $contractController = Sales_Controller_Contract::getInstance();
     $contract = new Sales_Model_Contract(array('title' => 'xtestunit', 'description' => 'nothing'));
     $contract = $contractController->create($contract);
     $contract->relations = array(new Tinebase_Model_Relation(array('own_backend' => 'Sql', 'own_id' => $contract->getId(), 'own_model' => 'Sales_Model_Contract', 'own_degree' => 'sibling', 'remark' => 'PHP UNITTEST', 'related_model' => 'Addressbook_Model_Contact', 'related_backend' => 'Sql', 'related_id' => $contact->getId(), 'type' => 'RESPONSIBLE')));
     $contract = $contractController->update($contract);
     $taToFind->relations = array(new Tinebase_Model_Relation(array('own_backend' => 'Sql', 'own_degree' => 'sibling', 'own_id' => $taToFind->getId(), 'own_model' => 'Timetracker_Model_Timeaccount', 'remark' => 'PHP UNITTEST', 'related_model' => 'Sales_Model_Contract', 'related_backend' => 'Sql', 'related_id' => $contract->getId(), 'type' => 'CONTRACT')));
     $taToFind = $taController->update($taToFind);
     // build request with direct id
     $req = Zend_Json::decode('{"params":{"filter":[{"condition":"OR","filters":[{"condition":"AND","filters":
         [{"field":"contract","operator":"AND","value":[{"field":"contact_external","operator":"AND","value":
             [{"field":":id","operator":"equals","value":"' . $contact->getId() . '"}],"id":"ext-record-266"},
              {"field":":id","operator":"AND"}],"id":"ext-record-181"}],"id":"ext-comp-1350","label":"Zeitkonten"}]}],
         "paging":{"sort":"creation_time","dir":"DESC","start":0,"limit":50}}}');
     $filter = $req['params']['filter'];
     $paging = $req['params']['paging'];
     $result = $this->_json->searchTimeaccounts($filter, $paging);
     $this->assertEquals(1, $result['totalcount']);
     $this->assertEquals($taToFind->getId(), $result['results'][0]['id']);
     // build request with query=Green
     $req = Zend_Json::decode('{"jsonrpc":"2.0","method":"Timetracker.searchTimeaccounts","params":{"filter":[{"condition":"OR","filters":[{"condition":"AND","filters":[{"field":"contract","operator":"AND","value":[{"field":"foreignRecord","operator":"AND","value":{"appName":"Addressbook","modelName":"Contact","linkType":"relation","filters":[{"field":"query","operator":"contains","value":"Green","id":"ext-record-546"}]},"id":"ext-record-480"},{"field":":id","operator":"AND"}],"id":"ext-record-181"}],"id":"ext-comp-1350","label":"Zeitkonten"}]}],"paging":{"sort":"creation_time","dir":"DESC","start":0,"limit":50}},"id":62}');
     $filter = $req['params']['filter'];
     $paging = $req['params']['paging'];
     $result = $this->_json->searchTimeaccounts($filter, $paging);
     $this->assertEquals(1, $result['totalcount']);
     $this->assertEquals($taToFind->getId(), $result['results'][0]['id']);
 }
 /**
  * get Timesheet (create timeaccount as well)
  *
  * @return Timetracker_Model_Timesheet
  */
 protected function _getTimesheet()
 {
     $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->create($this->_getTimeaccount());
     return new Timetracker_Model_Timesheet(array('account_id' => Tinebase_Core::getUser()->getId(), 'timeaccount_id' => $timeaccount->getId(), 'description' => 'blabla', 'start_date' => Tinebase_DateTime::now()->toString('Y-m-d')), TRUE);
 }
 /**
  * create tine timeaccount
  *
  * @param array $_data with egw project data
  * @param string $_contractId
  * @return Tinebase_Record_RecordSet of Timetracker_Model_Timeaccount
  * 
  * @todo    add members as groups (which?)
  * @todo    add more fields?
  */
 protected function _createTimeaccount($_data, $_contractId)
 {
     $timeaccount = new Timetracker_Model_Timeaccount(array('title' => $this->_encode($_data['pm_title']), 'number' => $_data['pm_number'], 'description' => $this->_convertDescription($_data['pm_description']), 'budget' => $_data['pm_planned_budget'], 'is_open' => $_data['pm_status'] == 'archive' ? 0 : 1), TRUE);
     // link contract to timeaccount
     $timeaccount->relations = array(array('own_model' => 'Timetracker_Model_Timeaccount', 'own_backend' => Timetracker_Backend_Timeaccount::TYPE, 'own_degree' => Tinebase_Model_Relation::DEGREE_SIBLING, 'type' => Timetracker_Model_Timeaccount::RELATION_TYPE_CONTRACT, 'related_id' => $_contractId, 'related_model' => 'Sales_Model_Contract', 'related_backend' => Sales_Backend_Contract::TYPE, 'remark' => Timetracker_Model_Timeaccount::RELATION_TYPE_CONTRACT));
     $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->create($timeaccount);
     // add user grants to this timeaccount (container)
     $members = $this->_getProjectMembers($_data['pm_id']);
     echo "    Got " . count($members) . " members for that project.\n";
     foreach ($members as $userId => $role) {
         $timeaccountContainer = Tinebase_Container::getInstance()->getContainerById($timeaccount->container_id);
         // add more different grants depending on roles
         switch ($role) {
             case 4:
                 $grants = array(Tinebase_Model_Grants::GRANT_READ);
                 break;
             case 3:
                 $grants = array(Tinebase_Model_Grants::GRANT_READ, Tinebase_Model_Grants::GRANT_EDIT, Tinebase_Model_Grants::GRANT_ADD);
                 break;
             case 2:
                 $grants = array(Tinebase_Model_Grants::GRANT_READ, Tinebase_Model_Grants::GRANT_EDIT, Tinebase_Model_Grants::GRANT_ADD, Tinebase_Model_Grants::GRANT_DELETE);
                 break;
             case 1:
                 $grants = array(Tinebase_Model_Grants::GRANT_READ, Tinebase_Model_Grants::GRANT_EDIT, Tinebase_Model_Grants::GRANT_ADD, Tinebase_Model_Grants::GRANT_DELETE, Tinebase_Model_Grants::GRANT_ADMIN);
                 break;
         }
         Tinebase_Container::getInstance()->addGrants($timeaccountContainer, Tinebase_Acl_Rights::ACCOUNT_TYPE_USER, $userId, $grants, TRUE);
     }
     $this->_counters['timeaccounts']++;
     return $timeaccount;
 }
 /**
  * tests if timeaccounts/timesheets get cleared if the invoice get billed
  */
 public function testClearing()
 {
     if ($this->_dbIsPgsql()) {
         $this->markTestSkipped('0011670: fix Sales_Invoices Tests with postgresql backend');
     }
     $this->_createFullFixtures();
     // the whole year, 12 months
     $date = clone $this->_referenceDate;
     $date->addMonth(12);
     $this->_invoiceController->createAutoInvoices($date);
     $json = new Sales_Frontend_Json();
     // test if timesheets get cleared
     $invoices = $json->searchInvoices(array(array('field' => 'foreignRecord', 'operator' => 'AND', 'value' => array('appName' => 'Sales', 'linkType' => 'relation', 'modelName' => 'Customer', 'filters' => array(array('field' => 'name', 'operator' => 'equals', 'value' => 'Customer3'))))), array());
     $invoiceIds = array();
     $this->assertEquals(2, $invoices['totalcount']);
     foreach ($invoices['results'] as $invoice) {
         $invoiceIds[] = $invoice['id'];
         // fetch invoice by get to have all relations set
         $invoice = $json->getInvoice($invoice['id']);
         $invoice['cleared'] = 'CLEARED';
         $json->saveInvoice($invoice);
     }
     $tsController = Timetracker_Controller_Timesheet::getInstance();
     $timesheets = $tsController->getAll();
     foreach ($timesheets as $timesheet) {
         $this->assertTrue(in_array($timesheet->invoice_id, $invoiceIds), 'the invoice id must be set!');
         $this->assertEquals(1, $timesheet->is_cleared);
     }
     // test if timeaccounts get cleared
     $invoices = $json->searchInvoices(array(array('field' => 'foreignRecord', 'operator' => 'AND', 'value' => array('appName' => 'Sales', 'linkType' => 'relation', 'modelName' => 'Customer', 'filters' => array(array('field' => 'name', 'operator' => 'equals', 'value' => 'Customer1'))))), array());
     $invoiceIds = array();
     foreach ($invoices['results'] as $invoice) {
         $invoiceIds[] = $invoice['id'];
         // fetch invoice by get to have all relations set
         $invoice = $json->getInvoice($invoice['id']);
         $invoice['cleared'] = 'CLEARED';
         // check set empty number fields to an empty string
         $invoice['sales_tax'] = '';
         $invoice['price_gross'] = '';
         $invoice['price_net'] = '';
         $invoice = $json->saveInvoice($invoice);
         $this->assertEquals(0, $invoice['sales_tax']);
         $this->assertEquals(0, $invoice['price_gross']);
         $this->assertEquals(0, $invoice['price_net']);
     }
     $taController = Timetracker_Controller_Timeaccount::getInstance();
     $filter = new Timetracker_Model_TimeaccountFilter(array(array('field' => 'budget', 'operator' => 'greater', 'value' => 0), array('field' => 'is_open', 'operator' => 'equals', 'value' => 0)));
     $timeaccounts = $taController->search($filter);
     $this->assertEquals(1, $timeaccounts->count());
     foreach ($timeaccounts as $ta) {
         $this->assertTrue(in_array($ta->invoice_id, $invoiceIds), 'the invoice id id must be set!');
         $this->assertEquals('billed', $ta->status);
     }
 }
 /**
  * inspects delete action
  *
  * @param array $_ids
  * @return array of ids to actually delete
  */
 protected function _inspectDelete(array $_ids)
 {
     $records = $this->_backend->getMultiple($_ids);
     $records->setTimezone(Tinebase_Core::getUserTimezone());
     $invoicePositionController = Sales_Controller_InvoicePosition::getInstance();
     $contractController = Sales_Controller_Contract::getInstance();
     foreach ($records as $record) {
         if (!$record->is_auto) {
             continue;
         }
         if ($record->cleared == 'CLEARED') {
             // cleared invoices must not be deleted
             throw new Sales_Exception_InvoiceAlreadyClearedDelete();
         } else {
             // try to find a invoice after this one
             // there should be a contract
             $contractRelation = Tinebase_Relations::getInstance()->getRelations('Sales_Model_Invoice', 'Sql', $record->getId(), NULL, array(), TRUE, array('Sales_Model_Contract'))->getFirstRecord();
             if ($contractRelation) {
                 $contract = $contractRelation->related_record;
                 $contract->setTimezone(Tinebase_Core::getUserTimezone());
                 // get all invoices related to this contract. throw exception if a follwing invoice has been found
                 $invoiceRelations = Tinebase_Relations::getInstance()->getRelations('Sales_Model_Contract', 'Sql', $contract->getId(), NULL, array(), TRUE, array('Sales_Model_Invoice'));
                 foreach ($invoiceRelations as $invoiceRelation) {
                     $invoiceRelation->related_record->setTimezone(Tinebase_Core::getUserTimezone());
                     if ($record->getId() !== $invoiceRelation->related_record->getId() && $record->creation_time < $invoiceRelation->related_record->creation_time) {
                         throw new Sales_Exception_DeletePreviousInvoice();
                     }
                 }
             } else {
                 if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
                     Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not find contract relation -> skip contract handling');
                 }
                 $contract = null;
             }
             // remove invoice_id from billables
             $filter = new Sales_Model_InvoicePositionFilter(array());
             $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $record->getId())));
             $invoicePositions = $invoicePositionController->search($filter);
             $allModels = array_unique($invoicePositions->model);
             foreach ($allModels as $model) {
                 if ($model == 'Sales_Model_ProductAggregate') {
                     continue;
                 }
                 $filteredInvoicePositions = $invoicePositions->filter('model', $model);
                 $billableControllerName = $model::getBillableControllerName();
                 $billableFilterName = $model::getBillableFilterName();
                 $filterInstance = new $billableFilterName(array());
                 $filterInstance->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $record->getId())));
                 $billableControllerName::getInstance()->updateMultiple($filterInstance, array('invoice_id' => NULL));
                 // set invoice ids of the timeaccounts
                 if ($model == 'Timetracker_Model_Timeaccount') {
                     $filterInstance = new Timetracker_Model_TimeaccountFilter(array());
                     $filterInstance->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'equals', 'value' => $record->getId())));
                     Timetracker_Controller_Timeaccount::getInstance()->updateMultiple($filterInstance, array('invoice_id' => NULL));
                 }
             }
             // delete invoice positions
             $invoicePositionController->delete($invoicePositions->getId());
             // set last_autobill a period back
             if ($contract) {
                 // check product aggregates
                 $filter = new Sales_Model_ProductAggregateFilter(array());
                 $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'contract_id', 'operator' => 'equals', 'value' => $contract->getId())));
                 $paController = Sales_Controller_ProductAggregate::getInstance();
                 $productAggregates = $paController->search($filter);
                 $productAggregates->setTimezone(Tinebase_Core::getUserTimezone());
                 foreach ($productAggregates as $productAggregate) {
                     if ($productAggregate->last_autobill) {
                         $lab = clone $productAggregate->last_autobill;
                         $add = 0 - (int) $productAggregate->interval;
                         $productAggregate->last_autobill = $lab->addMonth($add);
                         $productAggregate->last_autobill->setTime(0, 0, 0);
                         // last_autobill may not be before aggregate starts (may run into this case if interval has been resized)
                         if (!$productAggregate->start_date || $productAggregate->last_autobill < $productAggregate->start_date) {
                             $productAggregate->last_autobill = NULL;
                         }
                     }
                     $productAggregate->setTimezone('UTC');
                     $paController->update($productAggregate);
                 }
             }
         }
     }
     return $_ids;
 }
 /**
  * 
  * @param Sales_Model_CostCenter|string $costCenterId
  * @return Tinebase_Record_RecordSet
  */
 public function getTimeaccountsBySalesCostCenter($costCenterId)
 {
     $costCenterId = is_string($costCenterId) ? $costCenterId : $costCenterId->getId();
     $filter = new Tinebase_Model_RelationFilter(array(array('field' => 'related_model', 'operator' => 'equals', 'value' => 'Sales_Model_CostCenter'), array('field' => 'related_id', 'operator' => 'equals', 'value' => $costCenterId), array('field' => 'own_model', 'operator' => 'equals', 'value' => 'Timetracker_Model_Timeaccount'), array('field' => 'type', 'operator' => 'equals', 'value' => 'COST_CENTER')), 'AND');
     return Timetracker_Controller_Timeaccount::getInstance()->getMultiple(Tinebase_Relations::getInstance()->search($filter)->own_id);
 }
 /**
  * create customfield value (tr_budget) for timeaccounts starting with S-AB and moves the value from budget to tr_budget
  */
 public function moveBudget()
 {
     $filter = new Timetracker_Model_TimeaccountFilter(array(array('field' => 'budget', 'operator' => 'greater', 'value' => 0), array('field' => 'number', 'operator' => 'startswith', 'value' => 'S-AB')));
     $taController = Timetracker_Controller_Timeaccount::getInstance();
     $tas = $taController->search($filter);
     $cfi = Tinebase_CustomField::getInstance();
     $cfb = new Tinebase_Backend_Sql(array('modelName' => 'Tinebase_Model_CustomField_Value', 'tableName' => 'customfield'));
     $trBudget = $cfi->getCustomFieldByNameAndApplication('Timetracker', 'tr_budget');
     if (!$trBudget) {
         die('No CustomField tr_budget found!');
     }
     foreach ($tas as $ta) {
         echo 'Working on ' . $ta->title . PHP_EOL;
         $cf = new Tinebase_Model_CustomField_Value(array('record_id' => $ta->getId(), 'customfield_id' => $trBudget->getId(), 'value' => $ta->budget));
         $cfb->create($cf);
         $ta->budget = NULL;
         $taController->update($ta);
     }
     echo PHP_EOL;
     echo 'done!' . PHP_EOL;
 }
 /**
  * returns array with the filter settings of this filter
  *
  * @param  bool $_valueToJson resolve value for json api?
  * @return array
  */
 public function toArray($_valueToJson = false)
 {
     $result = parent::toArray($_valueToJson);
     if ($_valueToJson == true) {
         $result['value'] = Timetracker_Controller_Timeaccount::getInstance()->get($result['value'])->toArray();
     }
     return $result;
 }
 /**
  * returns array with the filter settings of this filter group 
  *
  * @param  bool $_valueToJson resolve value for json api?
  * @return array
  */
 public function toArray($_valueToJson = false)
 {
     $result = parent::toArray($_valueToJson);
     foreach ($result as &$filterData) {
         if (isset($filterData['field']) && $filterData['field'] == 'id' && $_valueToJson == true && !empty($filterData['value']) && !is_array($filterData['value'])) {
             try {
                 $filterData['value'] = Timetracker_Controller_Timeaccount::getInstance()->get($filterData['value'])->toArray();
             } catch (Tinebase_Exception_NotFound $nfe) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                     Tinebase_Core::getLogger()->INFO(__METHOD__ . '::' . __LINE__ . " could not find and resolve timeaccount {$filterData['value']}");
                 }
             }
         }
     }
     return $result;
 }