3 * The work constract class which can be used for contract parties
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 Ship-Simu Developer Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class WorksContract extends BaseFrameworkSystem implements SignableContract {
25 // Zukuenftiger Schiffsname
26 private $shipName = "";
28 // Instanz zum Schiffstypen
29 private $shipInstance = null;
32 private $contractPartner = null;
34 // Other contract partner
35 private $contractParty = null;
37 // Is the contract signed?
38 private $signed = false;
41 private $merchantInstance = null;
44 protected function __construct () {
45 // Call parent constructor
46 parent::__construct(__CLASS__);
49 $this->removeSystemArray();
50 $this->removeNumberFormaters();
53 // Neuen Bauvertrag generieren
54 public final static function createWorksContract ($shipType, $shipName, ContractPartner $partnerInstance) {
56 $shipType = (string) $shipType;
57 $shipName = (string) $shipName;
60 $contractInstance = new WorksContract();
62 // Schiffsnamen setzen
63 $contractInstance->setShipName($shipName);
65 // Existiert die Klasse ueberhaupt?
66 if (!class_exists($shipType)) {
67 // Klasse nicht gefunden
68 throw new ClassNotFoundException ($shipType, self::EXCEPTION_CLASS_NOT_FOUND);
71 // Schiff-Instanz temporaer erzeugen und in den Bauvertrag einfuegen
72 $shipInstance = ObjectFactory::createObjectByName($shipType, array($shipName));
73 $contractInstance->setShipInstance($shipInstance);
75 // Remove the ship instance
78 // Set itself as contract partner
79 $contractInstance->setContractPartner($partnerInstance);
81 // Instanz zurueckgeben
82 return $contractInstance;
85 // Setter for ship instance
86 private final function setShipInstance (ConstructableShip $shipInstance) {
87 $this->shipInstance = $shipInstance;
90 // Setter for ship name
91 private final function setShipName ($shipName) {
92 $this->shipName = (string) $shipName;
95 // Getter for ship name
96 public final function getShipName () {
97 return $this->shipName;
100 // Getter for ship instance
101 public final function getShipInstance () {
102 return $this->shipInstance;
105 // Add detail to the contract
106 public function addContractDetails ($shipPart, $parentPart, array $dataArray) {
108 $shipPart = (string) $shipPart;
109 $parentPart = (string) $parentPart;
112 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Das Schiffsteil <strong>%s</strong> wird zusammen mit dem Konstruktionsteil <strong>%s</strong> in den Bauvertrag aufgenommen.",
119 // Initialize the instance (shall not be done within dynamic part)
120 $partInstance = null;
122 // Try to get an instance for this ship part
124 $partInstance = ObjectFactory::createObjectByName($shipPart, $dataArray);
125 } catch (DimNotFoundInArrayException $e) {
126 $this->debugOutput(sprintf("[main:] Die <strong>%s</strong> konnte nicht vervollständigt werden. Grund: <strong>%s</strong><br />",
127 $this->getShipInstance()->getShipName(),
132 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Versuche ein Schiffsteil in den Bauvertrag aufzunehmen.",
137 // Is this ship part constructable?
138 if (!$partInstance instanceof ConstructableShipPart) {
139 // Ship part not constructable!
140 throw new ShipPartNotConstructableException(array($shipPart), self::EXCEPTION_NOT_CONSTRUCTABLE);
141 } elseif ($this->getShipInstance()->createShipPart($partInstance, $parentPart) === false) {
142 // Schiff konnte nicht gebaut werden!
143 throw new ShipNotConstructedException(sprintf("Das Schiff <strong>%s</strong> konnte wegen eines Fehlers nicht gebaut werden. Siehe obere Meldungen.",
144 $this->getShipInstance()->getShipName()
147 } catch (ClassNotFoundException $e) {
149 throw new ClassNotFoundException($e->getMessage(), $e->getCode());
152 // Get price for this item
153 $price = $this->getMerchantInstance()->getPriceFromList($partInstance);
156 $partInstance->setPrice($price);
159 // Setter for contract partner
160 public final function setContractPartner (ContractPartner $partnerInstance) {
161 $this->contractPartner = $partnerInstance;
164 // Getter for contract partner
165 public final function getContractPartner () {
166 return $this->contractPartner;
169 // Setter for contract party
170 public final function setContractParty (ContractPartner $partyInstance) {
171 $this->contractParty = $partyInstance;
174 // Getter for contract party
175 public final function getContractParty () {
176 return $this->contractParty;
179 // Setter for signature
180 public final function setSigned ($signed) {
181 $this->signed = (boolean) $signed;
184 // Getter for signature
185 public function isSigned () {
186 return $this->signed;
190 public function signContract (ContractPartner $partnerInstance, ContractPartner $partyInstance) {
191 // Is this contract already signed?
192 if ($this->isSigned()) {
193 // Throw an exception
194 throw new ContractAllreadySignedException(array($this, $this->getContractPartner(), $this->getContractParty()), self::EXCEPTION_CONTRACT_ALREADY_SIGNED);
197 // Is the first contract partner still the same?
198 if ($partnerInstance->equals($this->getContractPartner())) {
199 // Set contract party (other partner is already set)
200 $this->setContractParty($partyInstance);
203 $this->setSigned(true);
205 // Throw an exception
206 throw new ContractPartnerMismatchException(array($this, $this->getContractPartner(), $partyInstance), self::EXCEPTION_CONTRACT_PARTNER_MISMATCH);
210 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) {
211 if ($partnerInstance->equals($partyInstance)) {
213 $this->debugOutput(sprintf("[%s:%d] Die <strong>%s</strong> <em><strong>%s</strong></em> stimmt einem Bauvertrag über das <strong>%s</strong> <em><strong>%s</strong></em> zu.",
216 $partnerInstance->getObjectDescription(),
217 $partnerInstance->getCompanyName(),
218 $this->getShipInstance()->getObjectDescription(),
219 $this->getShipInstance()->getShipName()
222 // Other contract party
223 $this->debugOutput(sprintf("[%s:%d] Die <strong>%s</strong> <em><strong>%s</strong></em> geht mit der <strong>%s</strong> <em><strong>%s</strong></em> einen Bauvertrag über das <strong>%s</strong> <em><strong>%s</strong></em> ein.",
226 $partnerInstance->getObjectDescription(),
227 $partnerInstance->getCompanyName(),
228 $partyInstance->getObjectDescription(),
229 $partyInstance->getCompanyName(),
230 $this->getShipInstance()->getObjectDescription(),
231 $this->getShipInstance()->getShipName()
237 // Setter for merchant instance
238 public final function setMerchantInstance (Merchant $merchantInstance) {
239 $this->merchantInstance = $merchantInstance;
242 // Getter for merchant instance
243 public final function getMerchantInstance () {
244 return $this->merchantInstance;
247 // Getter for total price
248 public final function getTotalPrice () {
250 $shipInstance = $this->getShipInstance();
253 if (is_null($shipInstance)) {
254 // Opps! Empty partner instance?
255 throw new NullPointerException($shipInstance, self::EXCEPTION_IS_NULL_POINTER);
256 } elseif (!is_object($shipInstance)) {
257 // Not an object! ;-(
258 throw new InvalidObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
259 } elseif (!$shipInstance instanceof ConstructableShip) {
260 // Does not have the required feature (method)
261 throw new ShipIsInvalidException(array($shipInstance), self::EXCEPTION_INVALID_SHIP_INSTANCE);
264 // Get the structure array
265 $struct = $shipInstance->getStructuresArray();
268 if (is_null($struct)) {
269 // Opps! Empty partner instance?
270 throw new EmptyStructuresListException($this, self::EXCEPTION_EMPTY_STRUCTURES_ARRAY);
276 // Iterate through the list
277 for ($iter = $struct->getIterator(); $iter->valid(); $iter->next()) {
279 $item = $iter->current();
282 if (is_null($item)) {
283 // Opps! Empty partner instance?
284 throw new NullPointerException($item, self::EXCEPTION_IS_NULL_POINTER);
285 } elseif (!is_object($item)) {
286 // Not an object! ;-(
287 throw new InvalidObjectException($item, self::EXCEPTION_IS_NO_OBJECT);
288 } elseif (!$item instanceof BaseSimulator) {
289 // Does not have the required feature (method)
290 throw new MissingMethodException(array($item, 'getPartInstance'), self::EXCEPTION_MISSING_METHOD);
294 $part = $item->getPartInstance();
297 if (is_null($part)) {
298 // Opps! Empty partner instance?
299 throw new NullPointerException($part, self::EXCEPTION_IS_NULL_POINTER);
300 } elseif (!is_object($part)) {
301 // Not an object! ;-(
302 throw new InvalidObjectException($part, self::EXCEPTION_IS_NO_OBJECT);
303 } elseif (!method_exists($part, 'getPrice')) {
304 // Does not have the required feature (method)
305 throw new MissingMethodException(array($part, 'getPrice'), self::EXCEPTION_MISSING_METHOD);
308 // Get price for one item
309 $price = $part->getPrice();
311 // Is there numCabin() available?
312 if (method_exists($item, 'getNumCabin')) {
313 // Get total cabin and multiply it with the price
314 $price = $price * $item->getNumCabin();
317 // Add price to total price
318 $totalPrice += $price;
321 // Total price calculated?
322 if ($totalPrice === 0) {
324 throw new TotalPriceNotCalculatedException($this, self::EXCEPTION_TOTAL_PRICE_NOT_CALCULATED);
327 // Return total price