public function checkForContractOrInvoiceUpdates(Sales_Model_Contract $contract = null)
 {
     $contractController = Sales_Controller_Contract::getInstance();
     //get ids of invoices of which the contract was changed
     $ids = $this->getInvoicesWithChangedContract(null !== $contract ? $contract->getId() : null);
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' found ' . count($ids) . ' invoices with a contract change after creation time');
     }
     $excludeIds = array();
     $contracts = array();
     $result = array();
     foreach ($ids as $row) {
         $excludeIds[$row[0]] = true;
         if (!isset($contracts[$row[1]])) {
             $contracts[$row[1]] = array($row[0]);
         } else {
             $contracts[$row[1]][] = $row[0];
         }
     }
     foreach ($contracts as $contractId => $ids) {
         $tmpContract = $contractController->get($contractId);
         if (!$tmpContract) {
             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' could not get contract with id: ' . $contractId);
             continue;
         }
         $this->checkForRecreation($ids, $tmpContract);
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' checkForRecreation result: ' . print_r($this->_autoInvoiceIterationResults, 1));
         }
         $result = array_merge($result, $this->_autoInvoiceIterationResults);
     }
     //get ids of invoices that are not billed and which are not part of the above list
     $tmp = array(array('field' => 'is_auto', 'operator' => 'equals', 'value' => TRUE), array('field' => 'cleared', 'operator' => 'not', 'value' => 'CLEARED'));
     if ($contract && $contract->last_modified_time) {
         $tmp[] = array('field' => 'creation_time', 'operator' => 'after', 'value' => $contract->last_modified_time);
     }
     $f = new Sales_Model_InvoiceFilter($tmp, '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);
     }
     // ASC is important, we want to update the oldest invoice first! otherwise a newer invoice might take away data from an older one! Though not severely bad, we want to maintain order, do we?
     $p = new Tinebase_Model_Pagination(array('sort' => 'creation_time', 'dir' => 'ASC'));
     $invoices = $this->search($f, $p, false, true);
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' found ' . count($invoices) . ' invoices which are not yet cleared');
     }
     foreach ($invoices as $id) {
         if (!isset($excludeIds[$id])) {
             $result = array_merge($result, $this->checkForUpdate($id));
         }
     }
     return $result;
 }
 /**
  * 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);
         }
     }
 }