/** * creates invoice positions by the billables per each month * * @param array $billables * @param Sales_Model_Accountable_Interface $accountable * @return Tinebase_Record_RecordSet */ protected function _getInvoicePositionsFromBillables(array $billables, Sales_Model_Accountable_Interface $accountable) { $invoicePositions = new Tinebase_Record_RecordSet('Sales_Model_InvoicePosition'); foreach ($billables as $month => $billablesPerMonth) { if ($accountable->sumBillables()) { $sumQuantity = 0.0; foreach ($billablesPerMonth as $billable) { $qty = $billable->getQuantity(); $sumQuantity = $sumQuantity + $qty; } $pos = array('month' => $month, 'model' => get_class($accountable), 'accountable_id' => $accountable->getId(), 'title' => $accountable->getTitle(), 'quantity' => $sumQuantity, 'unit' => $billable->getUnit()); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->log(__METHOD__ . '::' . __LINE__ . ' Create invoice position ' . print_r($pos, 1) . ' for contract: ' . $this->_currentBillingContract->getId(), Zend_Log::DEBUG); } $invoicePositions->addRecord(new Sales_Model_InvoicePosition($pos)); } else { foreach ($billablesPerMonth as $billable) { $pos = array('month' => $month, 'model' => get_class($accountable), 'accountable_id' => $accountable->getId(), 'title' => $accountable->getTitle(), 'quantity' => $billable->getQuantity(), 'unit' => $billable->getUnit()); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->log(__METHOD__ . '::' . __LINE__ . ' Create invoice position ' . print_r($pos, 1), Zend_Log::DEBUG); } $invoicePositions->addRecord(new Sales_Model_InvoicePosition($pos)); } } } return $invoicePositions; }
/** * returns timeaccount-contract relation * @param Sales_Model_Contract $contract * @param Timetracker_Model_Timeaccount $timeaccount */ protected function _getRelation($contract, $timeaccount) { $r = new Tinebase_Model_Relation(); $ra = array('own_model' => 'Timetracker_Model_Timeaccount', 'own_backend' => 'Sql', 'own_id' => $timeaccount->getId(), 'related_degree' => 'sibling', 'remark' => 'phpunit test', 'related_model' => 'Sales_Model_Contract', 'related_backend' => 'Sql', 'related_id' => $contract->getId(), 'type' => 'CONTRACT'); $r->setFromArray($ra); return $r; }
/** * merges source contracts into the target contract (relations and products) * * @param Sales_Model_Contract $targetContract * @param Tinebase_Record_RecordSet $sourceContracts */ public function mergeContracts(Sales_Model_Contract $targetContract, Tinebase_Record_RecordSet $sourceContracts) { // handle relations (duplicates get skipped) foreach ($sourceContracts as $sourceContract) { Tinebase_Relations::getInstance()->transferRelations($sourceContract->getId(), $targetContract->getId(), 'Sales_Model_Contract'); } // handle products $filter = new Sales_Model_ProductAggregateFilter(array()); $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'contract_id', 'operator' => 'in', 'value' => $sourceContracts->getId()))); $products = Sales_Controller_ProductAggregate::getInstance()->search($filter); foreach ($products as $product) { $product->contract_id = $targetContract->getId(); Sales_Controller_ProductAggregate::getInstance()->update($product); } return true; }
/** * 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); } } }
/** * set relations for contract * * @param array|Sales_Model_Contract $contract * @param array $contacts * @param string $type */ protected function _setContractRelations($contract, $contacts, $type = 'PARTNER') { $relationData = array(); foreach ($contacts as $contact) { $relationData[] = array('own_degree' => 'sibling', 'related_degree' => 'sibling', 'related_model' => 'Addressbook_Model_Contact', 'related_backend' => 'Sql', 'related_id' => $contact->getId(), 'type' => $type); } $contractId = $contract instanceof Sales_Model_Contract ? $contract->getId() : $contract['id']; Tinebase_Relations::getInstance()->setRelations('Sales_Model_Contract', 'Sql', $contractId, $relationData); }
/** * returns a temporarily productaggregate which contains the * default billing information of this accountable * * @param Sales_Model_Contract $contract * @return Sales_Model_ProductAggregate */ public function getDefaultProductAggregate(Sales_Model_Contract $contract) { $startDate = clone $contract->start_date; if ($contract->start_date->format('d') !== 1) { $startDate->setDate($startDate->format('Y'), $startDate->format('m'), 1); } $accountable = get_class($this); $filter = new Sales_Model_ProductFilter(array(array('field' => 'accountable', 'operator' => 'equals', 'value' => $accountable))); $product = Sales_Controller_Product::getInstance()->search($filter)->getFirstRecord(); // create product, if no product is found if (!$product) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' . ' Create Product for ' . $accountable); } $product = Sales_Controller_Product::getInstance()->create(new Sales_Model_Product(array('name' => $accountable, 'accountable' => $accountable, 'description' => 'auto generated on invoicing'))); } if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' . ' Create ProductAggregate for ' . $accountable . ' contract: ' . $contract->getId()); } $endDate = clone $startDate; $endDate->addMonth($this->_defaultInterval); $pa = new Sales_Model_ProductAggregate(array('interval' => $this->_defaultInterval, 'billing_point' => $this->_defaultBillingPoint, 'contract_id' => $contract->getId(), 'start_date' => $startDate, 'end_date' => NULL, 'last_autobill' => NULL, 'product_id' => $product->getId(), 'quantity' => $product->accountable ? NULL : 1)); return $pa; }
/** * creates the auto invoices, gets called by cli * * @param Tinebase_DateTime $currentDate * @param Sales_Model_Contract $contract */ public function createAutoInvoices(Tinebase_DateTime $currentDate, Sales_Model_Contract $contract = NULL) { $this->_autoInvoiceIterationResults = array(); $this->_autoInvoiceIterationFailures = array(); $contractBackend = new Sales_Backend_Contract(); $ids = $contract ? array($contract->getId()) : $contractBackend->getBillableContractIds($currentDate); $filter = new Sales_Model_ContractFilter(array()); $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'id', 'operator' => 'in', 'value' => $ids))); $iterator = new Tinebase_Record_Iterator(array('iteratable' => $this, 'controller' => Sales_Controller_Contract::getInstance(), 'filter' => $filter, 'options' => array('getRelations' => TRUE, 'limit' => $this->_autoInvoiceIterationLimit), 'function' => 'processAutoInvoiceIteration')); $iterator->iterate($currentDate); $result = array('failures' => $this->_autoInvoiceIterationFailures, 'failures_count' => count($this->_autoInvoiceIterationFailures), 'created' => $this->_autoInvoiceIterationResults, 'created_count' => count($this->_autoInvoiceIterationResults)); return $result; }