/** * export invoices * * @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 exportInvoices($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 Sales_Model_InvoiceFilter($decodedFilter); parent::_export($filter, Zend_Json::decode($options), Sales_Controller_Invoice::getInstance()); }
/** * the singleton pattern * * @return Sales_Controller_Invoice */ public static function getInstance() { if (self::$_instance === NULL) { self::$_instance = new self(); } return self::$_instance; }
protected function _removeFixtures() { if ($this->_customerRecords) { Sales_Controller_Customer::getInstance()->delete($this->_customerRecords->getId()); } if ($this->_contactRecords) { $this->_contactController->delete($this->_contactRecords->getId()); } if ($this->_addressRecords) { $this->_addressController->delete($this->_addressRecords->getId()); } if ($this->_contractRecords) { Sales_Controller_Contract::getInstance()->delete($this->_contractRecords->getId()); } $paController = Sales_Controller_ProductAggregate::getInstance(); $paController->deleteByFilter(new Sales_Model_ProductAggregateFilter(array())); $this->_invoiceController = Sales_Controller_Invoice::getInstance(); $this->_invoiceController->deleteByFilter(new Sales_Model_InvoiceFilter(array())); }
/** * processUpdateBillingInformation * * @param Tinebase_Record_RecordSet $contracts */ public function processUpdateLastAutobillOfProductAggregates(Tinebase_Record_RecordSet $contracts) { $now = Tinebase_DateTime::now(); $billingPoints = array('Timetracker_Model_Timeaccount' => 'end', 'Sales_Model_Product' => 'end', 'WebAccounting_Model_BackupPath' => 'end', 'WebAccounting_Model_StoragePath' => 'end', 'WebAccounting_Model_MailAccount' => 'end', 'WebAccounting_Model_DReg' => 'begin', 'WebAccounting_Model_CertificateDomain' => 'begin', 'WebAccounting_Model_IPNet' => 'end', '' => 'end', 'Sales_Model_ProductAgregate' => 'end'); foreach ($contracts as $contract) { if ($contract->end_date && $contract->end_date < $now) { continue; } // find product aggregates for this contract $filter = new Sales_Model_ProductAggregateFilter(array()); $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'contract_id', 'operator' => 'equals', 'value' => $contract->getId()))); $productAggregates = Sales_Controller_ProductAggregate::getInstance()->search($filter); foreach ($productAggregates as $pa) { // find all invoices for the contract $filter = new Sales_Model_InvoiceFilter(array(array('field' => 'contract', 'operator' => 'AND', 'value' => array(array('field' => ':id', 'operator' => 'equals', 'value' => $contract->getId()))))); $invoices = Sales_Controller_Invoice::getInstance()->search($filter); // find last invoice position for this aggregate $filter = new Sales_Model_InvoicePositionFilter(); $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'invoice_id', 'operator' => 'in', 'value' => $invoices->getArrayOfIds()))); $pagination = new Tinebase_Model_Pagination(array('limit' => 1, 'sort' => 'month', 'dir' => 'DESC')); $lastInvoicePosition = Sales_Controller_InvoicePosition::getInstance()->search($filter, $pagination)->getFirstRecord(); // set billing_point, if none given if (!$pa->billing_point) { $pa->billing_point = $billingPoints[$lastInvoicePosition->model]; } if (!$lastInvoicePosition) { // if no invoice position has been found, this is a new contract, so set start_date to the first day of the month of the contracts start_date $date = clone $contract->start_date; $date->setTimezone(Tinebase_Core::getUserTimezone()); $date->setTime(0, 0, 0); $date->setDate($date->format('Y'), $date->format('m'), 1); $date->setTimezone('UTC'); $startDate = clone $date; $labDate = NULL; } else { $split = explode('-', $lastInvoicePosition->month); $date = Tinebase_DateTime::now(); $date->setTimezone(Tinebase_Core::getUserTimezone()); $date->setTime(0, 0, 0); $date->setDate($split[0], $split[1], 1); // set to next billing date $date->addMonth(1); // if the billing point is at the begin of the interval, set date back one interval if ($pa->billing_point == 'begin') { $date->subMonth($pa->interval); } $date->setTimezone('UTC'); $labDate = clone $date; // find first invoice position to calculate start_date $pagination = new Tinebase_Model_Pagination(array('limit' => 1, 'sort' => 'month', 'dir' => 'ASC')); $firstInvoicePosition = Sales_Controller_InvoicePosition::getInstance()->search($filter, $pagination)->getFirstRecord(); $split = explode('-', $firstInvoicePosition->month); $startDate = Tinebase_DateTime::now()->setTimezone(Tinebase_Core::getUserTimezone()); $startDate->setTime(0, 0, 0); $startDate->setDate($split[0], $split[1], 1); $startDate->setTimezone('UTC'); } $pa->start_date = $startDate; $pa->last_autobill = $labDate; Sales_Controller_ProductAggregate::getInstance()->update($pa); } } }
/** * deletes existing records * * @param array $ids * @return string */ public function deleteInvoices($ids) { return $this->_delete($ids, Sales_Controller_Invoice::getInstance()); }
/** * removes unbilled auto invoices * * @param Sales_Model_Contract $contract */ public function removeUnbilledAutoInvoices(Sales_Model_Contract $contract = NULL) { if (!Sales_Config::getInstance()->featureEnabled(Sales_Config::FEATURE_INVOICES_MODULE)) { Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . ' removeUnbilledAutoInvoices ran allthoug feature ' . Sales_Config::FEATURE_INVOICES_MODULE . ' is disabled'); return false; } $c = Sales_Controller_Invoice::getInstance(); $f = new Sales_Model_InvoiceFilter(array(array('field' => 'is_auto', 'operator' => 'equals', 'value' => TRUE), array('field' => 'cleared', 'operator' => 'not', 'value' => 'CLEARED')), 'AND'); if ($contract) { $subf = new Tinebase_Model_Filter_ExplicitRelatedRecord(array('field' => 'contract', 'operator' => 'AND', 'value' => array(array('field' => ':id', 'operator' => 'equals', 'value' => $contract->getId())), 'options' => array('controller' => 'Sales_Controller_Contract', 'filtergroup' => 'Sales_Model_ContractFilter', 'own_filtergroup' => 'Sales_Model_InvoiceFilter', 'own_controller' => 'Sales_Controller_Invoice', 'related_model' => 'Sales_Model_Contract'))); $f->addFilter($subf); } $p = new Tinebase_Model_Pagination(array('sort' => 'start_date', 'dir' => 'DESC')); $invoiceIds = $c->search($f, $p, false, true); if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' About to delete ' . count($invoiceIds) . ' uncleared invoices ...'); } foreach ($invoiceIds as $invoiceId) { try { $c->delete(array($invoiceId)); } catch (Sales_Exception_DeletePreviousInvoice $sedpi) { Tinebase_Exception::log($sedpi); } } }
/** * tests special auto invoice creation */ public function testSpecialExportInvoice() { $this->_createFullFixtures(); $date = clone $this->_referenceDate; $i = 0; // until 1.7 while ($i < 8) { $this->_invoiceController->createAutoInvoices($date); $date->addMonth(1); $i++; } $definition = dirname(dirname(dirname(dirname(__FILE__)))) . '/tine20/Sales/Export/definitions/invoice_special_ods.xml'; $filter = new Sales_Model_InvoiceFilter(array()); $exporter = new Sales_Export_Ods_Invoice($filter, Sales_Controller_Invoice::getInstance(), array('definitionFilename' => $definition)); $doc = $exporter->generate(); $xml = $this->_getContentXML($doc); $ns = $xml->getNamespaces(true); $spreadsheetXml = $xml->children($ns['office'])->{'body'}->{'spreadsheet'}; // the product should be found here $this->assertEquals('Debitor', (string) $spreadsheetXml->children($ns['table'])->{'table'}->{'table-row'}->{1}->children($ns['table'])->{'table-cell'}->{3}->children($ns['text'])->{0}); }
/** * tests special auto invoice creation */ public function testSpecialExportInvoice() { if ($this->_dbIsPgsql()) { $this->markTestSkipped('0011670: fix Sales_Invoices Tests with postgresql backend'); } $this->_createFullFixtures(); $date = clone $this->_referenceDate; $i = 0; // until 1.7 while ($i < 8) { $this->_invoiceController->createAutoInvoices($date); $date->addMonth(1); $i++; } $definition = dirname(dirname(dirname(dirname(__FILE__)))) . '/tine20/Sales/Export/definitions/invoice_special_ods.xml'; $filter = new Sales_Model_InvoiceFilter(array()); $exporter = new Sales_Export_Ods_Invoice($filter, Sales_Controller_Invoice::getInstance(), array('definitionFilename' => $definition)); $doc = $exporter->generate(); $xml = $this->_getContentXML($doc); $ns = $xml->getNamespaces(true); $spreadsheetXml = $xml->children($ns['office'])->{'body'}->{'spreadsheet'}; $text = $spreadsheetXml->xpath('((.//table:table/table:table-row)[2]/table:table-cell)[4]/text:p'); $text = $text[0]; // the product should be found here $this->assertEquals('Debitor', (string) $text); }
/** * test if a user, who has no manage_invoices - right, is able tosave a timeaccount having an invoice linked */ public function testUpdateInvoiceLinkedTimeaccount() { $this->markTestSkipped('0010492: fix failing invoices and timetracker tests'); $ta = $this->_getTimeaccount(array('title' => 'to find'), true); $cc = Sales_Controller_CostCenter::getInstance()->create(new Sales_Model_CostCenter(array('number' => 1, 'title' => 'test'))); $customer = Sales_Controller_Customer::getInstance()->create(new Sales_Model_Customer(array('number' => 100, 'name' => 'test', 'description' => 'unittest', 'credit_term' => 1))); $address = Sales_Controller_Address::getInstance()->create(new Sales_Model_Address(array('street' => 'teststreet', 'locality' => 'testcity', 'customer_id' => $customer->id, 'postalcode' => 12345))); $invoice = Sales_Controller_Invoice::getInstance()->create(new Sales_Model_Invoice(array('description' => 'test', 'address_id' => $address->id, 'date' => Tinebase_DateTime::now(), 'credit_term' => 1, 'type' => 'INVOICE', 'start_date' => Tinebase_DateTime::now(), 'end_date' => Tinebase_DateTime::now()->addMonth(1), 'costcenter_id' => $cc->id))); Tinebase_Relations::getInstance()->setRelations('Sales_Model_Invoice', 'Sql', $invoice->id, array(array('related_id' => $ta->id, 'related_model' => 'Timetracker_Model_Timeaccount', 'related_record' => $ta, 'own_degree' => 'sibling', 'type' => 'INVOICE'))); // fetch user group $group = Tinebase_Group::getInstance()->getGroupByName('Users'); $groupId = $group->getId(); // create new user $user = new Tinebase_Model_FullUser(array('accountLoginName' => 'testuser', 'accountPrimaryGroup' => $groupId, 'accountDisplayName' => 'Test User', 'accountLastName' => 'User', 'accountFirstName' => 'Test', 'accountFullName' => 'Test User', 'accountEmailAddress' => '*****@*****.**')); $user = Admin_Controller_User::getInstance()->create($user, 'pw', 'pw'); // add tt-ta admin right to user role to allow user to update (manage) timeaccounts // user has no right to see sales contracts $fe = new Admin_Frontend_Json(); $userRoles = $fe->getRoles('user', array(), array(), 0, 1); $userRole = $fe->getRole($userRoles['results'][0]['id']); $roleRights = $fe->getRoleRights($userRole['id']); $roleMembers = $fe->getRoleMembers($userRole['id']); $roleMembers['results'][] = array('name' => 'testuser', 'type' => 'user', 'id' => $user->accountId); $app = Tinebase_Application::getInstance()->getApplicationByName('Timetracker'); $roleRights['results'][] = array('application_id' => $app->getId(), 'right' => Timetracker_Acl_Rights::MANAGE_TIMEACCOUNTS); $roleRights['results'][] = array('application_id' => $app->getId(), 'right' => Tinebase_Acl_Rights::ADMIN); $fe->saveRole($userRole, $roleMembers['results'], $roleRights['results']); // switch to other user $this->_testUser = Tinebase_Core::getUser(); Tinebase_Core::set(Tinebase_Core::USER, $user); $ta = $this->_json->getTimeaccount($ta->id); $this->assertTrue(empty($ta['relations']), 'relations are not empty: ' . print_r($ta['relations'], true)); // this must be possible $ta = $this->_json->saveTimeaccount($ta); Tinebase_Core::set(Tinebase_Core::USER, $this->_testUser); $ta = $this->_json->getTimeaccount($ta['id']); $this->assertTrue(count($ta['relations']) == 1); }
/** * 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); } }
/** * returns multiple records prepared for json transport * NOTE: we can't use parent::_multipleRecordsToJson here because of the different container handling * * @param Tinebase_Record_RecordSet $_records Tinebase_Record_Abstract * @param Tinebase_Model_Filter_FilterGroup * @param Tinebase_Model_Pagination $_pagination * @return array data * * @todo replace with Timetracker_Convert_* */ protected function _multipleRecordsToJson(Tinebase_Record_RecordSet $_records, $_filter = NULL, $_pagination = NULL) { if (count($_records) == 0) { return array(); } switch ($_records->getRecordClassName()) { case 'Timetracker_Model_Timesheet': // resolve timeaccounts $timeaccountIds = $_records->timeaccount_id; $timeaccounts = $this->_timeaccountController->getMultiple(array_unique(array_values($timeaccountIds))); $invoices = FALSE; Timetracker_Model_TimeaccountGrants::getGrantsOfRecords($timeaccounts, Tinebase_Core::get('currentAccount')); foreach ($_records as $record) { $idx = $timeaccounts->getIndexById($record->timeaccount_id); if ($idx !== FALSE) { $record->timeaccount_id = $timeaccounts[$idx]; $record->timeaccount_id->account_grants = $this->_resolveTimesheetGrantsByTimeaccountGrants($record->timeaccount_id->account_grants, $record->account_id); } else { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not resolve timeaccount (id: ' . $record->timeaccount_id . '). No permission?'); } } // resolve user afterwards because we compare ids in _resolveTimesheetGrantsByTimeaccountGrants() Tinebase_User::getInstance()->resolveMultipleUsers($_records, array('account_id', 'created_by', 'last_modified_by'), true); break; case 'Timetracker_Model_Timeaccount': // resolve timeaccounts grants Timetracker_Model_TimeaccountGrants::getGrantsOfRecords($_records, Tinebase_Core::get('currentAccount')); $this->_resolveTimeaccountGrants($_records); break; } if (Tinebase_Core::getUser()->hasRight('Sales', 'manage_invoices')) { $invoiceIds = array_unique(array_values($_records->invoice_id)); $invoices = Sales_Controller_Invoice::getInstance()->getMultiple($invoiceIds); foreach ($_records as $record) { if ($invoices && $record->invoice_id) { $record->invoice_id = $invoices->getById($record->invoice_id); } } } Tinebase_Tags::getInstance()->getMultipleTagsOfRecords($_records); $_records->setTimezone(Tinebase_Core::getUserTimezone()); $_records->convertDates = true; $result = $_records->toArray(); return $result; }