/**
  * the singleton pattern
  *
  * @return Sales_Controller_Address
  */
 public static function getInstance()
 {
     if (self::$_instance === NULL) {
         self::$_instance = new self();
     }
     return self::$_instance;
 }
 /**
  * tests resolving the fulltext property of the address
  */
 public function testResolveVirtualFields()
 {
     $address = array('prefix1' => 'Meister', 'prefix2' => 'Eder', 'street' => 'Brunnengässla 4', 'postalcode' => '80331', 'locality' => 'Munich', 'region' => 'Bavaria', 'countryname' => 'DE', 'custom1' => 'de-234', 'type' => 'billing');
     $i18nTypeString = Tinebase_Translation::getTranslation('Sales')->_('billing');
     $result = Sales_Controller_Address::getInstance()->resolveVirtualFields($address);
     $this->assertEquals($result['fulltext'], "Meister Eder, Brunnengässla 4, 80331 Munich ({$i18nTypeString} - de-234)");
 }
 /**
  * create customers and their addresses
  * 
  * @param number $count
  * @return Tinebase_Record_RecordSet
  */
 protected function _createCustomers($count = 4)
 {
     if (!$this->_contactRecords) {
         // each customer may have 5 contacts
         $this->_createContacts($count * 5);
     }
     $this->_customerController = Sales_Controller_Customer::getInstance();
     $this->_customerRecords = new Tinebase_Record_RecordSet('Sales_Model_Customer');
     $this->_addressController = Sales_Controller_Address::getInstance();
     $this->_addressRecords = new Tinebase_Record_RecordSet('Sales_Model_Address');
     $countAll = 0;
     // customers
     $customers = array(array('name' => 'Customer1', 'url' => 'www.customer1.de', 'discount' => 0), array('name' => 'Customer2', 'url' => 'www.customer2.de', 'discount' => 5), array('name' => 'Customer3', 'url' => 'www.customer3.de', 'discount' => 10), array('name' => 'Customer4', 'url' => 'www.customer4.de', 'discount' => 0));
     $i = 0;
     foreach ($customers as $customer) {
         if ($countAll == $count) {
             break;
         }
         $countAll++;
         $customer['cpextern_id'] = $this->_contactRecords->getByIndex($i)->getId();
         $i++;
         $customer['cpintern_id'] = $this->_contactRecords->getByIndex($i)->getId();
         $i++;
         $customer['iban'] = Tinebase_Record_Abstract::generateUID(20);
         $customer['bic'] = Tinebase_Record_Abstract::generateUID(12);
         $customer['credit_term'] = 30;
         $customer['currency'] = 'EUR';
         $customer['currency_trans_rate'] = 1;
         $this->_customerRecords->addRecord($this->_customerController->create(new Sales_Model_Customer($customer)));
     }
     foreach ($this->_customerRecords as $customer) {
         foreach (array('postal', 'billing', 'delivery') as $type) {
             $caddress = $this->_contactRecords->getByIndex($i);
             $address = new Sales_Model_Address(array('customer_id' => $customer->getId(), 'type' => $type, 'prefix1' => $caddress->title, 'prefix2' => $caddress->n_fn, 'street' => $caddress->adr_two_street, 'postalcode' => $caddress->adr_two_postalcode, 'locality' => $caddress->adr_two_locality, 'region' => $caddress->adr_two_region, 'countryname' => $caddress->adr_two_countryname, 'custom1' => $type == 'billing' ? Tinebase_Record_Abstract::generateUID(5) : NULL));
             $this->_addressRecords->addRecord($this->_addressController->create($address));
             $i++;
         }
     }
     $this->_customerRecords->sort('name', 'ASC');
     return $this->_customerRecords;
 }
 /**
  * checks cleared state and sets the date to the current date, also sets all billables billed
  * 
  * @param Tinebase_Record_Interface $record
  * @param Tinebase_Record_Interface $oldRecord
  */
 protected function _checkCleared(Tinebase_Record_Interface &$record, Tinebase_Record_Interface $oldRecord = NULL)
 {
     $foundCustomer = NULL;
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Invoice: ' . print_r($record->toArray(), true));
     }
     if (is_array($record->relations)) {
         foreach ($record->relations as $relation) {
             if ($relation['related_model'] == 'Sales_Model_Customer') {
                 $foundCustomer = $relation['related_record'];
                 break;
             }
             if ($relation['related_model'] == 'Sales_Model_Contract') {
                 $foundContractRecord = Sales_Controller_Contract::getInstance()->get($relation['related_record']['id']);
                 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
                     Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Contract: ' . print_r($foundContractRecord->toArray(), true));
                 }
                 foreach ($foundContractRecord->relations as $relation) {
                     if ($relation['related_model'] == 'Sales_Model_Customer') {
                         $foundCustomer = $relation['related_record'];
                         break;
                     }
                 }
             }
         }
     }
     if (empty($record->address_id) && $foundCustomer) {
         $json = new Sales_Frontend_Json();
         $resolved = $json->getCustomer($foundCustomer->getId());
         if (!empty($resolved['billing'])) {
             $record->address_id = $resolved['billing'][0]['id'];
         } else {
             throw new Tinebase_Exception_Data('You have to set a billing address!');
         }
     }
     // if the record hasn't been cleared before, clear billables
     if ($record->cleared == 'CLEARED' && (!$oldRecord || $oldRecord->cleared != 'CLEARED')) {
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
             Tinebase_Core::getLogger()->log(__METHOD__ . '::' . __LINE__ . ' Clearing Invoice ' . print_r($record->toArray(), 1), Zend_Log::INFO);
         }
         if (!$record->date) {
             $record->date = new Tinebase_DateTime();
         }
         $this->_setNextNumber($record, isset($oldRecord));
         $address = Sales_Controller_Address::getInstance()->get(is_string($record->address_id) ? $record->address_id : $record->address_id . id);
         $string = $foundCustomer['name'] . PHP_EOL;
         $string .= $address->prefix1 ? $address->prefix1 . "\n" : '';
         $string .= $address->prefix2 ? $address->prefix2 . "\n" : '';
         $string .= $address->pobox ? $address->pobox . "\n" : '';
         $string .= $address->street ? $address->street . "\n" : '';
         $poloc = $address->postalcode ? $address->postalcode . " " : '';
         $poloc .= $address->locality ? $address->locality : '';
         if (!empty($poloc)) {
             $string .= $poloc . PHP_EOL;
         }
         $string .= $address->countryname ? $address->countryname : '';
         $record->fixed_address = $string;
         // clear all billables
         if (!empty($record->relations)) {
             foreach ($record->relations as $relation) {
                 if (in_array('Sales_Model_Accountable_Interface', class_implements($relation['related_model']))) {
                     if (is_array($relation['related_record'])) {
                         $rr = new $relation['related_model']($relation['related_record']);
                     } else {
                         $rr = $relation['related_record'];
                     }
                     $rr->clearBillables($record);
                     if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) {
                         Tinebase_Core::getLogger()->log(__METHOD__ . '::' . __LINE__ . ' Clearing billables ' . print_r($rr->toArray(), 1), Zend_Log::INFO);
                     }
                 }
             }
         }
     }
 }
 /**
  * resolves all virtual fields for the customer
  *
  * @param array $customer
  * @return array with property => value
  */
 public function resolveVirtualFields($customer)
 {
     $addressController = Sales_Controller_Address::getInstance();
     $filter = new Sales_Model_AddressFilter(array(array('field' => 'type', 'operator' => 'equals', 'value' => 'postal')));
     $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'customer_id', 'operator' => 'equals', 'value' => $customer['id'])));
     $postalAddressRecord = $addressController->search($filter)->getFirstRecord();
     if ($postalAddressRecord) {
         $customer['postal_id'] = $postalAddressRecord->toArray();
         foreach ($postalAddressRecord as $field => $value) {
             $customer['adr_' . $field] = $value;
         }
     }
     return $customer;
 }
 /**
  * Search for records matching given arguments
  *
  * @param  array $filter
  * @param  array $paging
  * @return array
  */
 public function searchAddresss($filter, $paging)
 {
     return $this->_search($filter, $paging, Sales_Controller_Address::getInstance(), 'Sales_Model_AddressFilter');
 }
 /**
  * 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 contracts - no containers, just "shared"
  */
 protected function _createSharedContracts()
 {
     $cNumber = 1;
     $container = $this->_contractController->getSharedContractsContainer();
     $cid = $container->getId();
     $ccs = array($this->_developmentCostCenter, $this->_marketingCostCenter);
     $i = 0;
     $this->_setReferenceDate();
     $customers = Sales_Controller_Customer::getInstance()->getAll();
     $addresses = Sales_Controller_Address::getInstance()->getAll();
     $customersCount = $customers->count();
     $ccIndex = 0;
     while ($i < $customersCount) {
         $costcenter = $ccs[$i % 2];
         $i++;
         $customer = $customers->getByIndex($ccIndex);
         $address = $addresses->filter('customer_id', $customer->getId())->filter('type', 'billing')->getFirstRecord();
         $addressId = $address ? $address->getId() : NULL;
         $title = self::$_de ? 'Vertrag für KST ' . $costcenter->number . ' - ' . $costcenter->remark : 'Contract for costcenter ' . $costcenter->number . ' - ' . $costcenter->remark . ' ' . Tinebase_Record_Abstract::generateUID(3);
         $ccid = $costcenter->getId();
         $contract = new Sales_Model_Contract(array('number' => $cNumber, 'title' => $title, 'description' => 'Created by Tine 2.0 DemoData', 'container_id' => $cid, 'status' => 'OPEN', 'cleared' => 'NOT_YET_CLEARED', 'start_date' => clone $this->_referenceDate, 'billing_address_id' => $addressId));
         $relations = array(array('own_model' => 'Sales_Model_Contract', 'own_backend' => Tasks_Backend_Factory::SQL, 'own_id' => NULL, 'own_degree' => Tinebase_Model_Relation::DEGREE_SIBLING, 'related_model' => 'Sales_Model_CostCenter', 'related_backend' => Tasks_Backend_Factory::SQL, 'related_id' => $ccid, 'type' => 'LEAD_COST_CENTER'), array('own_model' => 'Sales_Model_Contract', 'own_backend' => Tasks_Backend_Factory::SQL, 'own_id' => NULL, 'own_degree' => Tinebase_Model_Relation::DEGREE_SIBLING, 'related_model' => 'Sales_Model_Customer', 'related_backend' => Tasks_Backend_Factory::SQL, 'related_id' => $customer->getId(), 'type' => 'CUSTOMER'));
         $genericProduct = Sales_Controller_Product::getInstance()->create(new Sales_Model_Product(self::$_de ? array('name' => 'Generisches Produkt', 'description' => 'ein generisches produkt aus den demo daten', 'price' => 100) : array('name' => 'Generic Product', 'description' => 'this is a generic product used in demo data', 'price' => 100)));
         $contract->products = array(array('product_id' => $genericProduct->getId(), 'quantity' => 1));
         $contract->relations = $relations;
         $this->_contractController->create($contract);
         $cNumber++;
         $ccIndex++;
         if ($ccIndex == $customersCount) {
             $ccIndex = 0;
         }
     }
 }
 /**
  * add body rows
  * 
  * @alternate, kind of POC or VIP, overwrites the default one
  *
  * @param Tinebase_Record_RecordSet $records
  */
 public function processIteration($_records)
 {
     $json = new Tinebase_Convert_Json();
     $addressIds = array_unique($_records->address_id);
     $addresses = NULL;
     $resolved = $json->fromTine20RecordSet($_records);
     foreach ($resolved as $record) {
         $row = $this->_activeTable->appendRow();
         $customer = '';
         $contract = '';
         $debitor = '';
         foreach ($record['relations'] as $relation) {
             if ($relation['related_model'] == 'Sales_Model_Customer') {
                 $customer = $relation['related_record']['number'] . ' - ' . $relation['related_record']['name'];
             } elseif ($relation['related_model'] == 'Sales_Model_Contract') {
                 $contract = $relation['related_record']['number'] . ' - ' . $relation['related_record']['title'];
             }
         }
         $i18n = $this->_translate->getAdapter();
         foreach ($this->_config->columns->column as $field) {
             $identifier = $field->identifier;
             // TODO: use ModelConfig here to get the POC
             // get type and value for cell
             $cellType = $this->_getCellType($field->type);
             switch ($identifier) {
                 case 'costcenter_id':
                     $value = $record[$identifier]['number'] . ' - ' . $record[$identifier]['remark'];
                     break;
                 case 'customer':
                     $value = $customer;
                     break;
                 case 'contract':
                     $value = $contract;
                     break;
                 case 'fixed_address':
                     $value = str_replace("\n", ', ', $record[$identifier]);
                     break;
                 case 'date':
                     $value = substr($record[$identifier], 0, 10);
                     break;
                 case 'cleared':
                     $value = $i18n->_($record[$identifier] == 'CLEARED' ? 'cleared' : 'to clear');
                     break;
                 case 'type':
                     $value = $i18n->_($record[$identifier] == 'INVOICE' ? 'invoice' : 'Reversal Invoice');
                     break;
                 case 'debitor':
                     if (!$addresses) {
                         $filter = new Sales_Model_AddressFilter(array());
                         $filter->addFilter(new Tinebase_Model_Filter_Text(array('field' => 'id', 'operator' => 'in', 'value' => $addressIds)));
                         $addresses = Sales_Controller_Address::getInstance()->search($filter);
                     }
                     $address = $addresses->filter('id', $record['address_id']['id'])->getFirstRecord();
                     if ($address) {
                         $value = $address->custom1;
                     } else {
                         $value = '';
                     }
                     break;
                 default:
                     $value = $record[$identifier];
             }
             // create cell with type and value and add style
             $cell = $row->appendCell($value, $cellType);
             if ($field->customStyle) {
                 $cell->setStyle((string) $field->customStyle);
             }
         }
     }
 }