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;
     }
 }
 /**
  * tests datetime conversion of dependent records
  */
 public function testDateTimeConversion()
 {
     $employmentBegin = new Tinebase_DateTime('2012-12-15');
     $employmentEnd = new Tinebase_DateTime('2014-06-30');
     $employmentBegin->setTime(12, 0, 0);
     $employee = $this->_getEmployee('unittest');
     $employee->employment_begin = $employmentBegin;
     $employee->employment_end = $employmentEnd;
     $contract = $this->_getContract();
     $contract->start_date = $employmentBegin;
     $contract->workingtime_json = '{"days": [8,8,8,8,8,0,0]}';
     $contract->vacation_days = 25;
     $employee->contracts = array($contract->toArray());
     $json = new HumanResources_Frontend_Json();
     $savedEmployee = $json->saveEmployee($json->saveEmployee($employee->toArray()));
     $this->assertStringEndsWith('12:00:00', $savedEmployee['employment_begin']);
     $this->assertStringEndsWith('12:00:00', $savedEmployee['contracts'][0]['start_date']);
 }
 /**
  * create auto invoices for one contract
  * 
  * @param Sales_Model_Contract $contract
  * @param Tinebase_DateTime $currentDate
  * @param boolean $merge
  */
 protected function _createAutoInvoicesForContract(Sales_Model_Contract $contract, Tinebase_DateTime $currentDate, $merge = false)
 {
     // set this current billing date (user timezone)
     $this->_currentBillingDate = clone $currentDate;
     $this->_currentBillingDate->setDate($this->_currentBillingDate->format('Y'), $this->_currentBillingDate->format('m'), 1);
     $this->_currentBillingDate->setTime(0, 0, 0);
     // check all prerequisites needed for billing of the contract
     if (!$this->_validateContract($contract)) {
         return false;
     }
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Processing contract "' . $this->_currentBillingContract->number . '"');
     }
     // fire event to allow other applications do some work before billing
     $this->_firePrebillEvent();
     // find product aggregates of the current contract
     $productAggregates = $this->_findProductAggregates();
     // find month that needs to be billed next (note: _currentMonthToBill is the 01-01 00:00:00 of the next month, its the border, like last_autobill)
     $this->_currentMonthToBill = null;
     foreach ($productAggregates as $productAggregate) {
         if (null != $productAggregate->last_autobill) {
             $tmp = clone $productAggregate->last_autobill;
             $tmp->setDate($tmp->format('Y'), $tmp->format('m'), 1);
             $tmp->setTime(0, 0, 0);
             if (null == $this->_currentMonthToBill || $tmp->isLater($this->_currentMonthToBill)) {
                 $this->_currentMonthToBill = $tmp;
             }
         }
     }
     // this contract has no productAggregates, maybe just time accounts? use last invoice to find already billed month
     if (null == $this->_currentMonthToBill) {
         // find newest invoice of contract (probably can be done more efficient!)
         $invoiceRelations = Tinebase_Relations::getInstance()->getRelations('Sales_Model_Contract', 'Sql', $contract->getId(), NULL, array(), TRUE, array('Sales_Model_Invoice'));
         // do not modify $newestInvoiceTime!!!! it does NOT get cloned!
         $newestInvoiceTime = null;
         $newestInvoice = null;
         foreach ($invoiceRelations as $invoiceRelation) {
             $invoiceRelation->related_record->setTimezone(Tinebase_Core::getUserTimezone());
             if (null == $newestInvoiceTime || $invoiceRelation->related_record->creation_time->isLater($newestInvoiceTime)) {
                 $newestInvoiceTime = $invoiceRelation->related_record->creation_time;
                 $newestInvoice = $invoiceRelation->related_record;
             }
         }
         if (null != $newestInvoice) {
             // we can only take the end_date because there are no product aggregates (that have a last_autobill set) in this contract, otherwise it might be one interval ahead!
             $this->_currentMonthToBill = clone $newestInvoice->end_date;
             $this->_currentMonthToBill->addDay(4);
             $this->_currentMonthToBill->subMonth(1);
             //$this->_currentMonthToBill->setTimezone(Tinebase_Core::getUserTimezone());
         }
     }
     $_addMonth = true;
     if (null == $this->_currentMonthToBill) {
         $this->_currentMonthToBill = clone $contract->start_date;
         $_addMonth = false;
     }
     $this->_currentMonthToBill->setTimezone(Tinebase_Core::getUserTimezone());
     $this->_currentMonthToBill->setDate($this->_currentMonthToBill->format('Y'), $this->_currentMonthToBill->format('m'), 1);
     $this->_currentMonthToBill->setTime(0, 0, 0);
     if ($_addMonth) {
         $this->_currentMonthToBill->addMonth(1);
     }
     $doSleep = false;
     if (($merge || $contract->merge_invoices) && $this->_currentMonthToBill->isEarlier($this->_currentBillingDate)) {
         $this->_currentMonthToBill = clone $this->_currentBillingDate;
     }
     while ($this->_currentMonthToBill->isEarlierOrEquals($this->_currentBillingDate)) {
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' $this->_currentMonthToBill: ' . $this->_currentMonthToBill . ' $this->_currentBillingDate ' . $this->_currentBillingDate);
             foreach ($productAggregates as $productAggregate) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $productAggregate->id . ' ' . $productAggregate->last_autobill . ' ' . $productAggregate->interval);
             }
         }
         //required to have one sec difference in the invoice creation_time, can be optimized to look for milliseconds
         if ($doSleep) {
             sleep(1);
             $doSleep = false;
         }
         // prepare relations and find all billable accountables of the current contract
         list($relations, $billableAccountables) = $this->_prepareInvoiceRelationsAndFindBillableAccountables($productAggregates);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' count $billableAccountables: ' . count($billableAccountables));
             foreach ($billableAccountables as $ba) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' accountable: ' . get_class($ba['ac']) . ' id: ' . $ba['ac']->getId());
             }
         }
         // find invoice positions and the first start date and last end date of all billables
         list($invoicePositions, $earliestStartDate, $latestEndDate) = $this->_findInvoicePositionsAndInvoiceInterval($billableAccountables);
         /**** TODO ****/
         // if there are no positions, no more bills need to be created,
         // but the last_autobill info is set, if the current date is later
         if ($invoicePositions->count() > 0) {
             // prepare invoice
             $invoice = new Sales_Model_Invoice(array('is_auto' => TRUE, 'description' => $this->_currentBillingContract->title . ' (' . $this->_currentMonthToBill->toString() . ')', 'type' => 'INVOICE', 'address_id' => $this->_currentBillingContract->billing_address_id, 'credit_term' => $this->_currentBillingCustomer['credit_term'], 'customer_id' => $this->_currentBillingCustomer['id'], 'costcenter_id' => $this->_currentBillingCostCenter->getId(), 'start_date' => $earliestStartDate, 'end_date' => $latestEndDate, 'positions' => $invoicePositions->toArray(), 'date' => clone $this->_currentMonthToBill, 'sales_tax' => 19));
             $invoice->relations = $relations;
             $invoice->setTimezone('UTC', TRUE);
             // create invoice
             $invoice = $this->create($invoice);
             $this->_autoInvoiceIterationResults[] = $invoice->getId();
             $this->_autoInvoiceIterationDetailResults[] = $invoice;
             $paToUpdate = array();
             // conjunct billables with invoice, find out which productaggregates to update
             foreach ($billableAccountables as $ba) {
                 $ba['ac']->conjunctInvoiceWithBillables($invoice);
                 if ($ba['pa']->getId()) {
                     $paToUpdate[$ba['pa']->getId()] = $ba['pa'];
                 }
             }
             foreach ($paToUpdate as $paId => $productAggregate) {
                 $firstBill = !$productAggregate->last_autobill;
                 $lab = $productAggregate->last_autobill ? clone $productAggregate->last_autobill : ($productAggregate->start_date ? clone $productAggregate->start_date : clone $this->_currentBillingContract->start_date);
                 $lab->setTimezone(Tinebase_Core::getUserTimezone());
                 $lab->setDate($lab->format('Y'), $lab->format('m'), 1);
                 $lab->setTime(0, 0, 0);
                 if (!$firstBill) {
                     $lab->addMonth($productAggregate->interval);
                 } else {
                     if ($productAggregate->billing_point == 'end') {
                         // if first bill, add interval on billing_point end
                         $lab->addMonth($productAggregate->interval);
                     }
                 }
                 while ($this->_currentMonthToBill->isLater($lab)) {
                     $lab->addMonth($productAggregate->interval);
                 }
                 if ($lab->isLater($this->_currentMonthToBill)) {
                     $lab->subMonth($productAggregate->interval);
                 }
                 $productAggregate->last_autobill = $lab;
                 $productAggregate->setTimezone('UTC');
                 if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                     Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Updating last_autobill of "' . $productAggregate->getId() . '": ' . $lab->__toString());
                 }
                 Sales_Controller_ProductAggregate::getInstance()->update($productAggregate);
                 $productAggregate->setTimezone(Tinebase_Core::getUserTimezone());
             }
             $doSleep = true;
         } elseif (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' $invoicePositions->count() == false');
         }
         $this->_currentMonthToBill->addMonth(1);
     }
 }
 /**
  * syncs all connections for the current user
  * @param Zend_Console_Getopt $_opts
  */
 public function sync_connections($_opts)
 {
     // resolve arguments
     $args = $this->_parseArgs($_opts, array());
     $initial = in_array('initial', $args['other']) ? true : false;
     $shared = in_array('shared', $args['other']) ? true : false;
     $verbose = in_array('verbose', $args['other']) ? true : false;
     if ($initial) {
         // sync last 2 months, day per day
         // prepare dates
         $now = new Tinebase_DateTime();
         $now->setTime(0, 0, 0);
         $from = clone $now;
         $from->subDay(1);
         $to = clone $now;
         $firstDay = clone $now;
         $firstDay->subMonth(2);
         // sync every day
         while (!$firstDay->isLater($from)) {
             Sipgate_Controller_Connection::getInstance()->syncLines($from, $to, $shared, $verbose);
             $from->subDay(1);
             $to->subDay(1);
         }
     } else {
         Sipgate_Controller_Connection::getInstance()->syncLines(NULL, NULL, $shared);
     }
 }
Esempio n. 5
0
 /**
  * checks deadline of record
  * 
  * @param Timetracker_Model_Timesheet $_record
  * @param boolean $_throwException
  * @return void
  * @throws Timetracker_Exception_Deadline
  */
 protected function _checkDeadline(Timetracker_Model_Timesheet $_record, $_throwException = TRUE)
 {
     // get timeaccount
     $timeaccount = Timetracker_Controller_Timeaccount::getInstance()->get($_record->timeaccount_id);
     if (isset($timeaccount->deadline) && $timeaccount->deadline == Timetracker_Model_Timeaccount::DEADLINE_LASTWEEK) {
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Check if deadline is exceeded for timeaccount ' . $timeaccount->title);
         }
         // it is only on monday allowed to add timesheets for last week
         $date = new Tinebase_DateTime();
         $date->setTime(0, 0, 0);
         $dayOfWeek = $date->get('w');
         if ($dayOfWeek >= 2) {
             // only allow to add ts for this week
             $date->sub($dayOfWeek, Tinebase_DateTime::MODIFIER_DAY);
         } else {
             // only allow to add ts for last week
             $date->sub($dayOfWeek + 7, Tinebase_DateTime::MODIFIER_DAY);
         }
         // convert start date to Tinebase_DateTime
         $startDate = new Tinebase_DateTime($_record->start_date);
         if ($date->compare($startDate) >= 0) {
             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Deadline exceeded: ' . $startDate . ' < ' . $date);
             }
             if ($this->checkRight(Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS, FALSE) || Timetracker_Model_TimeaccountGrants::hasGrant($_record->timeaccount_id, Tinebase_Model_Grants::GRANT_ADMIN)) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                     Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' User with admin / manage all rights is allowed to save Timesheet even if it exceeds the deadline.');
                 }
             } else {
                 if ($_throwException) {
                     throw new Timetracker_Exception_Deadline();
                 }
             }
         } else {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Valid date: ' . $startDate . ' >= ' . $date);
             }
         }
     }
 }
 /**
  * on saving 
  */
 public function testUpdateTimeaccountWithRelatedContact()
 {
     $this->_getTimeaccount(array(), TRUE);
     $ta = $this->_lastCreatedRecord;
     $contactController = Addressbook_Controller_Contact::getInstance();
     $taController = Timetracker_Controller_Timeaccount::getInstance();
     $bday = new Tinebase_DateTime();
     $bday->setDate(2013, 12, 24);
     $bday->setTime(0, 0, 0);
     $contact = $contactController->create(new Addressbook_Model_Contact(array('n_given' => 'Test', 'n_family' => 'Unit', 'bday' => $bday)));
     $bday = $contact['bday'];
     Tinebase_Relations::getInstance()->setRelations('Timetracker_Model_Timeaccount', 'Sql', $ta['id'], array(array('related_backend' => 'Sql', 'type' => 'RESPONSIBLE', 'related_model' => 'Addressbook_Model_Contact', 'related_id' => $contact->getId(), 'own_degree' => 'sibling')));
     // update a few times, bday of contract should not change
     $tajson = $this->_json->getTimeaccount($ta['id']);
     $this->_json->saveTimeaccount($tajson);
     $tajson = $this->_json->getTimeaccount($ta['id']);
     $this->_json->saveTimeaccount($tajson);
     $tajson = $this->_json->getTimeaccount($ta['id']);
     $ajson = new Addressbook_Frontend_Json();
     $contactJson = $ajson->getContact($contact->getId());
     $this->assertEquals($bday->setTimezone(Tinebase_Core::getUserTimezone())->toString(), $contactJson['bday']);
 }
 /**
  * creates the invoices - no containers, just "shared"
  */
 protected function _createSharedInvoices()
 {
     $sic = Sales_Controller_Invoice::getInstance();
     $now = new Tinebase_DateTime();
     $now->setTimezone(Tinebase_Core::getUserTimezone());
     $now->setDate($now->format('Y'), $now->format('m'), 1);
     $now->setTime(3, 0, 0);
     $date = clone $this->_referenceDate;
     while ($date < $now) {
         $sic->createAutoInvoices($date);
         $date->addMonth(1);
     }
 }