* @version 0.0.0
* @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 Ship-Simu Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.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__);
}
/**
* 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
* @todo Add functionality if user participates in a company
*/
public static final function createShippingCompany (ManageableAccount $userInstance) {
// Get new instance
$companyInstance = new ShippingCompany();
// Does the given user owns a company?
if ($companyInstance->ifUserParticipatesInCompany($userInstance)) {
// Then do some nasty 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 (ManageableAccount $userInstance) {
// By default no user owns any company... ;)
$participates = false;
// Get a company database wrapper class
$wrapperInstance = ObjectFactory::createObjectByConfiguredName('company_db_wrapper_class', array($this));
// 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
* @todo Check if user is 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
* @todo Check if user is 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;
}
//------------------------------------------------------------------------------\
// Below 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() === false) {
// Should normally not happen... :(
throw new StructuresOutOfBoundsException($idx, self::EXCEPTION_INDEX_OUT_OF_BOUNDS);
} // END - if
// Get current element
$employee = $iterator->current();
} // END - while
// 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->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() === false) {
// Rewind to first position
$shipyardIter->seek(0);
} // END - if
// 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 InvalidObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
} elseif ($shipyard->isClass("Shipyard") === false) {
// 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 NoClassException($shipType, self::EXCEPTION_CLASS_NOT_FOUND);
}
// Create dummy ship
eval(sprintf("\$shipInstance = %s::create%s(\"M/S Dummy\");",
$shipType,
$shipType
));
// 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 InvalidObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
} elseif ($shipyard->isClass("Shipyard") === false) {
// 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);
} // END - for
}
// Validate the requested ship type with the company if they can construct it
public function validateWorksContractShipType (SignableContract $contractInstance) {
// 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 InvalidObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
}
// Get it's real class name
$shipType = $shipInstance->__toString();
// Now check if 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 InvalidObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
} elseif ($shipyard->isClass("Shipyard") === false) {
// Class is not a shipyard
throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
}
// Validate if 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!
} // END - for
// 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) {
$this->contractList->append($contractInstance);
}
// As a customer the shippng company can withdraw from a contract
public function withdrawFromContract (SignableContract $contractInstance) {
ApplicationEntryPoint::app_exit("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) === false) {
// Invalid contract partner!
throw new InvalidContractPartnerException($partnerInstance, self::EXCEPTION_CONTRACT_PARTNER_INVALID);
} // END - if
// 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 InvalidObjectException($contractInstance, self::EXCEPTION_IS_NO_OBJECT);
} elseif ($contractInstance->isClass("WorksContract") === false) {
// 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);
}
}