* @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; /** * Employed people by this company */ private $employeeList = null; /** * Headquarter harbor instance */ private $hqInstance = 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; /** * Main constructor * * @return void */ protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); // Set description $this->setObjectDescription("Reederei"); // Generate unique ID number $this->createUniqueID(); // Clean up a little $this->removeSystemArray(); } // Reederei gruenden (create wegen Namenskonvention) public final static function createShippingCompany ($companyName, Harbor $hqInstance) { // Get new instance $companyInstance = new ShippingCompany(); if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $companyInstance->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s wird gegründet.
\n", __CLASS__, __LINE__, $companyName )); // Firmennamen setzen $companyInstance->setCompanyName($companyName); // Kuerzel setzen $companyInstance->createShortName(); // Sitz festlegen $companyInstance->setHQInstance($hqInstance); // Werftenliste erstellen $companyInstance->createshipyardList(); // Angestellten-Liste erstellen $companyInstance->createEmployeeList(); // Auftragsliste erstellen $companyInstance->createContractList(); // Clean up a little $companyInstance->removeWidth(); $companyInstance->removeHeight(); $companyInstance->removeLength(); $companyInstance->removeDraught(); $companyInstance->removePartInstance(); // Instanz zurueckgeben return $companyInstance; } // Angestellten-Liste erstellen private function createEmployeeList () { if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s erhält eine Angestelltenliste.
\n", __CLASS__, __LINE__, $this->getCompanyName() )); $this->employeeList = new FrameworkArrayObject(); } // Werftenliste erstellen public function createShipyardList () { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s erhält eine Werftsliste.
\n", __CLASS__, __LINE__, $this->getCompanyName() )); $this->shipyardList = new FrameworkArrayObject(); } // Auftragsliste erstellen public function createContractList () { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s erhält eine Auftragsliste.
\n", __CLASS__, __LINE__, $this->getCompanyName() )); $this->contractList = new FrameworkArrayObject(); } // 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 createShortName () { // Mindestens eine Leerstelle? $dummy = explode(" ", $this->getCompanyName()); foreach ($dummy as $part) { $this->shortName .= substr($part, 0, 1); } } // Reedereien Werften bauen lassen public function createShipyardInHarbor($shipyardName, Harbor $harborInstance) { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s baut im %s eine Werft %s.
\n", __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) { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s ist von %s %s gegründet worden.
\n", __CLASS__, __LINE__, $this->getCompanyName(), $founderInstance->getSurname(), $founderInstance->getFamily() )); $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) { if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] %s %s tritt der Reederei %s als %s bei und erhält ein Gehalt von %s.
\n", __CLASS__, __LINE__, $employeeInstance->getSurname(), $employeeInstance->getFamily(), $this->getCompanyName(), $employeeInstance->getObjectDescription(), $this->formatCurrency($employeeInstance->getSalary()) )); $this->employeeList->append($employeeInstance); } // Neue Werft in Liste aufnehmen public function addNewShipyard (Shipyard $shipyardInstance) { if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s erhält die Werft %s hinzugefügt.
\n", __CLASS__, __LINE__, $this->getCompanyName(), $shipyardInstance->getShipyardName() )); $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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s stellt per Zufall %d neue Mitarbeiter ein.
\n", __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); } // 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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s stellt den/die Angestellte(n) %s %s ein.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s hat per Zufall %d neue Mitarbeiter eingestellt.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s verteilt alle ihre %d Mitarbeiter auf alle %d Werft(en).
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s hat %d Mitarbeiter.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Für die Reederei %s werden die Anzahl der Werften in allen Häfen ermittelt.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s hat %d Werft(en).
\n", __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, 0); } // Create dummy ship eval(sprintf("\$shipInstance = %s::create%s(\"M/S Dummy\");", $shipType, $shipType )); // Debug message if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s baut in allen Werften bald Schiffe vom Typ %s.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s prüft den Bauauftrag der %s.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s prüft, ob die %s (Typ:%s) gebaut werden kann.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s fragt alle Werften ab, ob diese Schiffe vom Typ %s bauen können.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s hat die Suche nach einer Werft beendet, die Schiffe vom Typ %s bauen kann.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s erstellt einen Bauauftrag für ein %s mit dem Namen %s.
\n", __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->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s erteilt an sich selbst einen Bauauftrag für das %s "%s".
\n", __CLASS__, __LINE__, $this->getCompanyName(), $contractInstance->getShipInstance()->getObjectDescription(), $contractInstance->getShipInstance()->getShipName() )); } else { // Other external company if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei %s unterzeichnet einen Bauauftrag für das %s "%s" mit der %s.
\n", __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); } /** * Stub! */ public function saveObjectToDatabase () { $this->getDebugInstance()->output(sprintf("[%s:] Stub %s erreicht.", $this->__toString(), __FUNCTION__ )); } /** * Limits this object with an ObjectLimits instance */ public function limitObject (ObjectLimits $limitInstance) { ApplicationEntryPoint::app_die("".__METHOD__." reached! Stub!"); } } // [EOF] ?>