* @version 0.0.0 * @copyright Copyright (c) 2007, 2008 Roland Haeder, this is free software * @license GNU GPL 3.0 or any newer version * @link http://www.ship-simu.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ class ShippingCompany extends BaseSimulator implements Customer, ContractPartner { /** * Full name of this company */ private $companyName = "Namenlose Reederei"; /** * Shorted name of this company */ private $shortName = ""; /** * Instance of the founder */ private $founderInstance = null; /** * Headquarter harbor instance */ private $hqInstance = null; /** * Employed people by this company */ private $employeeList = null; /** * List of all assigned shipyards */ private $shipyardList = null; /** * List of owned ships */ private $ownedShips = null; /** * Work constracts this company is currently working on */ private $contractList = null; // Exception constants const EXCEPTION_USER_OWNS_NO_COMPANY = 0x200; /** * Protected constructor * * @return void */ protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); // Set description $this->setObjectDescription("A shipping company class"); // Generate unique ID number $this->generateUniqueId(); // Clean up a little $this->removeSystemArray(); } /** * Creates an instance of this company class or throws an exception if the * given user owns no company. * * @param $userInstance A user class * @return $companyInstance Prepared company instance */ public final static function createShippingCompany (BaseUser $userInstance) { // Get new instance $companyInstance = new ShippingCompany(); // Does the given user owns a company? if ($companyInstance->ifUserParticipatesInCompany($userInstance)) { // Then do some nastly caching here but don't throw an exception // because then you will hurt our web helpers... :/ $companyInstance->partialStub("Don't throw exceptions here."); } // END - if // Init all lists $companyInstance->initCompanyLists(); // Return instance return $companyInstance; } /** * Checks wether the given user participates in a company * * @param $userInstance An instance of a user class * @return $participates Wether the user participates at lease in one company */ protected function ifUserParticipatesInCompany (BaseUser $userInstance) { // By default no user owns any company... ;) $participates = false; // Get a company database wrapper class $wrapperInstance = ObjectFactory::createObjectByConfiguredName('company_db_wrapper_class'); // Ask the wrapper if this user participates $participates = $wrapperInstance->ifUserParticipatesInCompany($userInstance); // Get the result instance $resultInstance = $wrapperInstance->getResultInstance(); // Caches the result instance here, if set (we don't the wrapper anymore!) if ($resultInstance instanceof SearchableResult) { // Set the result instance $this->setResultInstance($resultInstance); } // END - if // Return result return $participates; } /** * Checks wether the current user in registry is the company founder * * @return $isFounder Wether the current user is the company founder */ public function ifUserIsFounder () { // Default is not the founder $isFounder = false; // Get result instance $resultInstance = $this->getResultInstance(); // Is it set? if ($resultInstance instanceof SearchableResult) { // Result found so analyse it $this->partialStub("Check if user is company founder."); } // END - if // Return result return $isFounder; } /** * Checks wether the current user in registry is the company owner * * @return $isOwner Wether the current user is the company owner */ public function ifUserIsOwner () { // Default is not the owner $isOwner = false; // Get result instance $resultInstance = $this->getResultInstance(); // Is it set? if ($resultInstance instanceof SearchableResult) { // Result found so analyse it $this->partialStub("Check if user is company owner."); } // END - if // Return result return $isOwner; } /** * Checks wether the current user in registry is an employee in this company * * @return $isOwner Wether the current user is an employee in this company */ public function ifUserIsEmployee () { // Default is no employee $isEmployee = false; // Get result instance $resultInstance = $this->getResultInstance(); // Is it set? if ($resultInstance instanceof SearchableResult) { // Result found so he is employee $isEmployee = true; } // END - if // Return result return $isEmployee; } //---------------------------------------------------------------------------- // From here is very old code which needs to be translated and changed heavily //---------------------------------------------------------------------------- /** * Intialize all lists * * @return void * @todo Maybe we don't need these big lists anymore?! So we can deprecate/remove it */ protected function initCompanyLists () { // Employees $this->employeeList = new FrameworkArrayObject("FakedEmployeeList"); // Ship yards $this->shipyardList = new FrameworkArrayObject("FakedShipyardList"); // Contracts $this->contractList = new FrameworkArrayObject("FakedContractList"); } // Setter-Methode fuer Firmennamen public final function setCompanyName ($companyName) { $this->companyName = (string) $companyName; } // Getter-Methode fuer Firmennamen public final function getCompanyName () { return $this->companyName; } // Setter-Methode fuer Firmensitz public final function setHQInstance (Harbor $hqInstance) { $this->hqInstance = $hqInstance; } // Kuerzel setzen private function initShortName () { // Mindestens eine Leerstelle? $dummy = explode(" ", $this->getCompanyName()); foreach ($dummy as $part) { $this->shortName .= substr($part, 0, 1); } // END - if } // Reedereien Werften bauen lassen public function createShipyardInHarbor($shipyardName, Harbor $harborInstance) { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s baut im %s eine Werft %s.", __CLASS__, __LINE__, $this->getCompanyName(), $harborInstance->getHarborName(), $shipyardName )); // Wird im HQ gebaut? if ($this->hqInstance->equals($harborInstance)) { // Die neue Werft wird im HQ gebaut! $this->hqInstance->addNewShipyardNotify($shipyardName, $this); // Die Werft drueber in Kenntnis setzen, welcher Reederei sie angehoert } else { // Ausserhalb des Heimathafens soll eine Werft gebaut werden $harborInstance->addNewShipyardNotify($shipyardName, $this); } } // Setter fuer Reederei-Gruender public final function setCompanyFounder(CompanyEmployee $founderInstance) { $this->founderInstance = $founderInstance; } // Getter for founder instance public final function getFounderInstance () { return $this->founderInstance; } // Neue(n) Angestellte(n) in Angestellten-Liste aufnehmen public function addNewEmployee (SimulatorPersonell $employeeInstance) { $this->employeeList->append($employeeInstance); } // Neue Werft in Liste aufnehmen public function addNewShipyard (Shipyard $shipyardInstance) { $this->shipyardList->append($shipyardInstance); } // Neue Mitarbeiter per Zufall einstellen/rekrutieren public function recruitRandomEmployees($amount, SimulatorPersonell $personellInstance) { // Anzahl Mitarbeiter absichern $amount = (int) $amount; // Debug-Meldung ausgeben if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s stellt per Zufall %d neue Mitarbeiter ein.", __CLASS__, __LINE__, $this->getCompanyName(), $amount )); // Gesamtanzahl verfuegbarer Erwerbsloser holen $totalUnemployed = $personellInstance->getAllUnemployed(); // Existiert die gewuenschte Anzahl freier Arbeiter? (doppelt geht derzeit nicht) if ($totalUnemployed < $amount) { // Reichte nicht aus! throw new ToMuchEmployeesException(array($amount, $personellInstance->getAllUnemployed()), self::EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES); } // END - if // Get list for all unemployed people $list = $personellInstance->getSpecialPersonellList(false); // Should be cached // Get iterator of the list $iterator = $list->getIterator(); // Get the requested amount of personell for ($idx = 0; $idx < $amount; $idx++) { $employee = null; // Is this personl unemployed? while (is_null($employee) || $employee->isEmployed()) { // Generate random number $pos = mt_rand(0, ($totalUnemployed - 1)); // Don't remove the -1 here: // E.g. 100 entries means latest position is 99... // Seek for the position $iterator->seek($pos); // Is the current position valid? if ($iterator->valid()) { // Element holen $employee = $iterator->current(); } else { // Should normally not happen... :( throw new StructuresOutOfBoundsException($idx, self::EXCEPTION_INDEX_OUT_OF_BOUNDS); } } // A dummy just for the description and real class $dummy = CompanyEmployee::createCompanyEmployee("", "", "M", 1970, 1, 1, $employee->isMarried(), 0); // Make this person employed and give him some money to work $employee->setEmployed(true); $employee->setObjectDescription($dummy->getObjectDescription()); $employee->setRealClass($dummy->__toString()); $employee->increaseSalary((mt_rand(7, 14) * 100)); // Are 700 to 1400 EUR for the begin okay? // Debug message if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s stellt den/die Angestellte(n) %s %s ein.", __CLASS__, __LINE__, $this->getCompanyName(), $employee->getSurname(), $employee->getFamily() )); // Add this employee $this->addNewEmployee($employee); } // End - for // Cache resetten $personellInstance->resetCache(); // Debug-Meldung ausgeben if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s hat per Zufall %d neue Mitarbeiter eingestellt.", __CLASS__, __LINE__, $this->getCompanyName(), $amount )); } // End - method // Distribute all personells on all shipyards public function distributeAllPersonellOnShipyards () { if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s verteilt alle ihre %d Mitarbeiter auf alle %d Werft(en).", __CLASS__, __LINE__, $this->getCompanyName(), $this->getTotalEmployee(), $this->getTotalShipyards() )); // Do we have some shipyards? if (is_null($this->shipyardList)) { // No shipyards created throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS); } // Get iterator for shipyards $shipyardIter = $this->shipyardList->getIterator(); // Iterate through all employees for ($idx = $this->employeeList->getIterator(); $idx->valid(); $idx->next()) { // Is the shipyard iterator still okay? if (!$shipyardIter->valid()) { // Rewind to first position $shipyardIter->seek(0); } // Get Shipyard object $shipyard = $shipyardIter->current(); // Is this a Shipyard object? if (is_null($shipyard)) { // No class returned throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); } elseif (!is_object($shipyard)) { // Not an object! ;-( throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT); } elseif (!$shipyard->isClass("Shipyard")) { // Nope, so throw exception throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING); } // Add employee to the shipyard $shipyard->addNewPersonell($idx->current()); // Continue to next shipyard $shipyardIter->next(); } } // Getter for total employees public final function getTotalEmployee () { // Count all... $total = $this->employeeList->count(); // Debug message if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s hat %d Mitarbeiter.", __CLASS__, __LINE__, $this->getCompanyName(), $total )); // Return amount return $total; } // Getter for total shipyards public final function getTotalShipyards () { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Für die Reederei %s werden die Anzahl der Werften in allen Häfen ermittelt.", __CLASS__, __LINE__, $this->getCompanyName() )); // Do we have some shipyards? if (is_null($this->shipyardList)) { // No shipyards created throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS); } // Get iterator $total = $this->shipyardList->count(); // Debug message if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s hat %d Werft(en).", __CLASS__, __LINE__, $this->getCompanyName(), $total )); // Return amount return $total; } // Add a ship type (class) to all shipyards public function addShipTypeToAllShipyards ($shipType) { // Secure strings $shipType = (string) $shipType; // Is the class there? if (!class_exists($shipType)) { // Throw exception throw new ClassNotFoundException($shipType, self::EXCEPTION_CLASS_NOT_FOUND); } // Create dummy ship eval(sprintf("\$shipInstance = %s::create%s(\"M/S Dummy\");", $shipType, $shipType )); // Debug message if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s baut in allen Werften bald Schiffe vom Typ %s.", __CLASS__, __LINE__, $this->getCompanyName(), $shipInstance->getObjectDescription() )); // Iterate shipyard list for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) { // Get current element $shipyard = $idx->current(); // Is this a shipyard? if (is_null($shipyard)) { // Opps! Empty list? throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); } elseif (!is_object($shipyard)) { // Not an object! ;-( throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT); } elseif (!$shipyard->isClass("Shipyard")) { // Class is not a shipyard throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING); } // Add the new ship type to the shipyard $shipyard->addNewConstructableShipType($shipType); } } // Validate the requested ship type with the company if they can construct it public function validateWorksContractShipType (SignableContract $contractInstance) { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s prüft den Bauauftrag der %s.", __CLASS__, __LINE__, $this->getCompanyName(), $contractInstance->getShipName() )); // First get the ship type $shipInstance = $contractInstance->getShipInstance(); // Ist there a ship instance? if (is_null($shipInstance)) { // Opps! Empty entry? throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); } elseif (!is_object($shipInstance)) { // Not an object! ;-( throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT); } // Get it's real class name $shipType = $shipInstance->__toString(); // Debug message if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s prüft, ob die %s (Typ:%s) gebaut werden kann.", __CLASS__, __LINE__, $this->getCompanyName(), $contractInstance->getShipName(), $shipInstance->getObjectDescription() )); // Now check if the ship type is in any list and return the result return ($this->isShipTypeConstructable($shipType)); } // Is the ship type constructable? public function isShipTypeConstructable ($shipType) { // The type must be a string! $shipType = (string) $shipType; // Debug message if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s fragt alle Werften ab, ob diese Schiffe vom Typ %s bauen können.", __CLASS__, __LINE__, $this->getCompanyName(), $shipType )); // First everthing is failed... $result = false; // Iterate through all shipyards for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) { // Get current Shipyard instance $shipyard = $idx->current(); // Is this a shipyard? if (is_null($shipyard)) { // Opps! Empty list? throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); } elseif (!is_object($shipyard)) { // Not an object! ;-( throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT); } elseif (!$shipyard->isClass("Shipyard")) { // Class is not a shipyard throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING); } // Validate if the first found shipyard can construct the requested type $result = $shipyard->isShipTypeConstructable($shipType); // Does this shipyard construct the requested ship type? if ($result) break; // Then abort the search! } // Debug message if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s hat die Suche nach einer Werft beendet, die Schiffe vom Typ %s bauen kann.", __CLASS__, __LINE__, $this->getCompanyName(), $shipType )); // Return result return $result; } // As a customer the shipping company can add new contracts public function addNewWorksContract (SignableContract $contractInstance) { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s erstellt einen Bauauftrag für ein %s mit dem Namen %s.", __CLASS__, __LINE__, $this->getCompanyName(), $contractInstance->getShipInstance()->getObjectDescription(), $contractInstance->getShipInstance()->getShipName() )); $this->contractList->append($contractInstance); } // As a customer the shippng company can withdraw from a contract public function withdrawFromContract (SignableContract $contractInstance) { ApplicationEntryPoint::app_die("WITHDRAW:
".print_r($contractInstance, true)."
"); } // Get latest added contract instance public final function getLastContractInstance () { // Get iterator $iter = $this->contractList->getIterator(); // Get latest entry (total - 1) $iter->seek($iter->count() - 1); // Return entry return $iter->current(); } // Sign a contract with an other party which must also implement Customer public function signContract (SignableContract $contractInstance, ContractPartner $partnerInstance) { // Check wether the other party is our contract partner if (!$partnerInstance->isContractPartner($contractInstance)) { // Invalid contract partner! throw new InvalidContractPartnerException($partnerInstance, self::EXCEPTION_CONTRACT_PARTNER_INVALID); } // Determine if company "signs" own contract (must be done) or with an other party if ($this->equals($partnerInstance)) { // With itself if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s erteilt an sich selbst einen Bauauftrag für das %s "%s".", __CLASS__, __LINE__, $this->getCompanyName(), $contractInstance->getShipInstance()->getObjectDescription(), $contractInstance->getShipInstance()->getShipName() )); } else { // Other external company if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei %s unterzeichnet einen Bauauftrag für das %s "%s" mit der %s.", __CLASS__, __LINE__, $this->getCompanyName(), $contractInstance->getShipInstance()->getObjectDescription(), $contractInstance->getShipInstance()->getShipName(), $partnerInstance->getCompanyName() )); } // Sign the contract $contractInstance->signContract($this, $partnerInstance); /** * @todo Maybe do something more here... */ } // Is this the right contract partner? public function isContractPartner (SignableContract $contractInstance) { // Get contract partner instance and compare it with $this contract partner return ($this->equals($contractInstance->getContractPartner())); } // Setter for merchant instance public final function setMerchantInstance (Merchant $merchantInstance) { // Get contract $contractInstance = $this->getLastContractInstance(); if (is_null($contractInstance)) { // Opps! Empty contract instance? throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); } elseif (!is_object($contractInstance)) { // Not an object! ;-( throw new NoObjectException($contractInstance, self::EXCEPTION_IS_NO_OBJECT); } elseif (!$contractInstance->isClass('WorksContract')) { // Is not a merchant throw new ClassMismatchException(array($contractInstance->__toString(), "WorksContract"), self::EXCEPTION_CLASSES_NOT_MATCHING); } // Set the merchant in the contract (for getting prices) $contractInstance->setMerchantInstance($merchantInstance); } } // [EOF] ?>