protected function _setReferenceDate()
 {
     // set reference date to the 1st january of last year
     $this->_referenceDate = Tinebase_DateTime::now();
     $this->_referenceDate->setTimezone(Tinebase_Core::getUserTimezone());
     $this->_referenceDate->subYear(1);
     $this->_referenceDate->setDate($this->_referenceDate->format('Y'), 1, 1);
     $this->_referenceDate->setTime(0, 0, 0);
     $this->_referenceYear = $this->_referenceDate->format('Y');
     $this->_lastMonthDays = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
     // find out if year is a leap year
     if ((bool) $this->_referenceDate->format('L')) {
         $this->_isLeapYear = TRUE;
         $this->_lastMonthDays[1] = 29;
     }
 }
 /**
  * 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']));
 }
 /**
  * appends sql to given select statement
  *
  * @param Zend_Db_Select                $_select
  * @param Tinebase_Backend_Sql_Abstract $_backend
  */
 function appendFilterSql($_select, $_backend)
 {
     $months = array();
     $db = $_backend->getAdapter();
     $date = new Tinebase_DateTime();
     $format = 'Y-m';
     $like = FALSE;
     if ($this->_operator == 'within') {
         switch ($this->_value) {
             case 'monthThis':
                 $months = array($date->format($format));
                 break;
             case 'monthLast':
                 $months = array($date->subMonth(1)->format($format));
                 break;
             case 'beforeLastMonth':
                 $months = array($date->subMonth(2)->format($format));
                 break;
             case 'quarterThis':
                 $month = ceil(intval($date->format('m')) / 3) * 3;
                 $date->setDate($date->format('Y'), $month, 15);
                 $months = array($date->format($format), $date->subMonth(1)->format($format), $date->subMonth(1)->format($format));
                 break;
             case 'quarterLast':
                 $date->subMonth(3);
                 $month = ceil(intval($date->format('m')) / 3) * 3;
                 $date->setDate($date->format('Y'), $month, 15);
                 $months = array($date->format($format), $date->subMonth(1)->format($format), $date->subMonth(1)->format($format));
                 break;
             case 'beforeLastQuarter':
                 $date->subMonth(6);
                 $month = ceil(intval($date->format('m')) / 3) * 3;
                 $date->setDate($date->format('Y'), $month, 15);
                 $months = array($date->format($format), $date->subMonth(1)->format($format), $date->subMonth(1)->format($format));
                 break;
             case 'yearThis':
                 $like = $date->format('Y') . '-%';
                 break;
             case 'yearLast':
                 $date->subYear(1);
                 $like = $date->format('Y') . '-%';
                 break;
             default:
                 throw new Tinebase_Exception_InvalidArgument('The value for the within operator is not supported: ' . $this->_value);
         }
         if ($like) {
             $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " LIKE (?)", $like));
         } else {
             $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " IN (?)", $months));
         }
     } elseif ($this->_operator == 'equals') {
         if ('' == $this->_value) {
             $_select->where($this->_getQuotedFieldName($_backend) . " = '0000-00-00 00:00:00' OR " . $this->_getQuotedFieldName($_backend) . ' IS NULL');
         } else {
             $split = explode('-', $this->_value);
             if (!(strlen($this->_value) == 7 && (int) $split[0] > 1900 && (int) $split[1] > 0 && (int) $split[1] < 13)) {
                 throw new Tinebase_Exception_MonthFormat();
             }
             $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " = (?)", $this->_value));
         }
     } else {
         $date = new Tinebase_DateTime($this->_value);
         $date->setTimezone(Tinebase_Core::getUserTimezone());
         $dateString = $date->format('Y-m');
         switch ($this->_operator) {
             case 'before':
                 $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " < (?)", $dateString));
                 break;
             case 'after':
                 $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " > (?)", $dateString));
                 break;
             case 'before_or_equals':
                 $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " <= (?)", $dateString));
                 break;
             case 'after_or_equals':
                 $_select->where($db->quoteInto($this->_getQuotedFieldName($_backend) . " >= (?)", $dateString));
                 break;
             default:
                 throw new Tinebase_Exception_InvalidArgument('The operator ' . $this->_operator . ' is not supported for this filter!');
         }
     }
 }