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, this is free software
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->setObjectDescription("Bauvertrag");
51 // Unique-ID generieren
52 $this->createUniqueID();
55 $this->removeSystemArray();
58 // Neuen Bauvertrag generieren
59 public final static function createWorksContract ($shipType, $shipName, ContractPartner $partnerInstance) {
61 $shipType = (string) $shipType;
62 $shipName = (string) $shipName;
64 // Is the other one a contract partner?
65 if (is_null($partnerInstance)) {
66 // Opps! Empty partner instance?
67 throw new NullPointerException($partnerInstance, self::EXCEPTION_IS_NULL_POINTER);
68 } elseif (!is_object($partnerInstance)) {
70 throw new NoObjectException($partnerInstance, self::EXCEPTION_IS_NO_OBJECT);
71 } elseif (!method_exists($partnerInstance, 'isContractPartner')) {
72 // Does not have the required feature (method)
73 throw new MissingMethodException(array($partnerInstance, 'isContractPartner'), self::EXCEPTION_MISSING_METHOD);
77 $contractInstance = new WorksContract();
79 // Debug-Meldung ausgeben
80 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $contractInstance->getDebugInstance()->output(sprintf("[%s:%d] Neuer Bauvertrag wird für das Schiff <strong>%s</strong> mit der <strong>%s</strong> <strong>%s</strong> erstellt.<br />\n",
84 $partnerInstance->getObjectDescription(),
85 $partnerInstance->getCompanyName()
88 // Schiffsnamen setzen
89 $contractInstance->setShipName($shipName);
91 // Existiert die Klasse ueberhaupt?
92 if (!class_exists($shipType)) {
93 // Klasse nicht gefunden
94 throw new ClassNotFoundException ($shipType, self::EXCEPTION_CLASS_NOT_FOUND);
97 // Schiff-Instanz temporaer erzeugen und in den Bauvertrag einfuegen
98 $eval = sprintf("\$contractInstance->setShipInstance(%s::create%s(\"%s\"));",
105 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $contractInstance->getDebugInstance()->output(sprintf("[%s:%d] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
111 // Execute constructed command
114 // Set itself as contract partner
115 $contractInstance->setContractPartner($partnerInstance);
117 // Instanz zurueckgeben
118 return $contractInstance;
121 // Setter for ship instance
122 private final function setShipInstance (ConstructableShip $shipInstance) {
123 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Das Schiff <strong>%s</strong> wird in den Bauvertrag aufgenommen.<br />\n",
126 $shipInstance->getShipName()
128 $this->shipInstance = $shipInstance;
131 // Setter for ship name
132 private final function setShipName ($shipName) {
133 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Das neue Schiff wird <strong>%s</strong> heissen.<br />\n",
138 $this->shipName = (string) $shipName;
141 // Getter for ship name
142 public final function getShipName () {
143 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiffsname <strong>%s</strong> angefordert.<br />\n",
148 return $this->shipName;
151 // Getter for ship instance
152 public final function getShipInstance () {
153 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiff-Instanz angefordert.<br />\n",
157 return $this->shipInstance;
160 // Add detail to the contract
161 public function addContractDetails ($shipPart, $parentPart, array $dataArray) {
163 $shipPart = (string) $shipPart;
164 $parentPart = (string) $parentPart;
167 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Das Schiffsteil <strong>%s</strong> wird zusammen mit dem Konstruktionsteil <strong>%s</strong> in den Bauvertrag aufgenommen.<br />\n",
174 // Initialize the instance (shall not be done within dynamic part)
177 // Prepare the big command for everthing
179 \$instance = ".$shipPart."::create".$shipPart."(";
180 foreach ($dataArray as $pIdx => $parts) {
181 if (is_string($parts)) {
183 $eval .= "\"".$parts."\", ";
184 } elseif (is_array($parts)) {
185 // Ist ein weiteres Array!
187 foreach ($parts as $idx2 => $sub) {
188 $eval .= "'".$idx2."' => ";
189 if (is_string($sub)) {
190 // Ist erneut ein String
191 $eval .= "\"".$sub."\"";
192 } elseif (is_array($sub)) {
193 // Wird nicht mehr unterstuetzt!
194 ApplicationEntryPoint::app_die("No more arrays!");
202 // Letztes Komma entfernen
203 $eval = substr($eval, 0, -2);
206 // Etwas anderes direkt!
207 $eval .= $parts.", ";
211 // Letztes Komma abhaengen
212 $eval = substr($eval, 0, -2);
214 } catch (DimNotFoundInArrayException \$e) {
215 \$this->getDebugInstance()->output(sprintf(\"[main:] Die <strong>%s</strong> konnte nicht vervollständigt werden. Grund: <strong>%s</strong><br />\\n\",
216 \$this->getShipInstance()->getShipName(),
223 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[Ship:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
230 // Try to add the ship part to the contract
232 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Versuche ein Schiffsteil in den Bauvertrag aufzunehmen.<br />\n",
236 if (!$instance instanceof ConstructableShipPart) {
237 // Ship part not constructable!
238 throw new ShipPartNotConstructableException(array($shipPart), self::EXCEPTION_NOT_CONSTRUCTABLE);
239 } elseif (!$this->getShipInstance()->createShipPart($instance, $parentPart)) {
240 // Schiff konnte nicht gebaut werden!
241 throw new ShipNotConstructedException(sprintf("Das Schiff <strong>%s</strong> konnte wegen eines Fehlers nicht gebaut werden. Siehe obere Meldungen.",
242 $this->getShipInstance()->getShipName()
245 } catch (ClassNotFoundException $e) {
247 throw new ClassNotFoundException($e->getMessage(), $e->getCode());
250 // Get price for this item
251 $price = $this->getMerchantInstance()->getPriceFromList($instance);
253 // Final debug message
254 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> kostet <strong>%s</strong>.<br />\n",
257 $instance->getObjectDescription(),
258 $this->getMerchantInstance()->formatCurrency($price)
262 $instance->setPrice($price);
264 // Final debug message
265 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> wurde in den Bauvertrag aufgenommen.<br />\n",
268 $instance->getObjectDescription()
272 // Setter for contract partner
273 public final function setContractPartner (ContractPartner $partnerInstance) {
274 $this->contractPartner = $partnerInstance;
277 // Getter for contract partner
278 public final function getContractPartner () {
279 return $this->contractPartner;
282 // Setter for contract party
283 public final function setContractParty (ContractPartner $partyInstance) {
284 $this->contractParty = $partyInstance;
287 // Getter for contract party
288 public final function getContractParty () {
289 return $this->contractParty;
292 // Setter for signature
293 public final function setSigned ($signed) {
294 $this->signed = (boolean) $signed;
297 // Getter for signature
298 public function isSigned () {
299 return $this->signed;
303 public function signContract (ContractPartner $partnerInstance, ContractPartner $partyInstance) {
304 // Is this contract already signed?
305 if ($this->isSigned()) {
306 // Throw an exception
307 throw new ContractAllreadySignedException(array($this, $this->getContractPartner(), $this->getContractParty()), self::EXCEPTION_CONTRACT_ALREADY_SIGNED);
310 // Is the first contract partner still the same?
311 if ($partnerInstance->equals($this->getContractPartner())) {
312 // Set contract party (other partner is already set)
313 $this->setContractParty($partyInstance);
316 $this->setSigned(true);
318 // Throw an exception
319 throw new ContractPartnerMismatchException(array($this, $this->getContractPartner(), $partyInstance), self::EXCEPTION_CONTRACT_PARTNER_MISMATCH);
323 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) {
324 if ($partnerInstance->equals($partyInstance)) {
326 $this->getDebugInstance()->output(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.<br />\n",
329 $partnerInstance->getObjectDescription(),
330 $partnerInstance->getCompanyName(),
331 $this->getShipInstance()->getObjectDescription(),
332 $this->getShipInstance()->getShipName()
335 // Other contract party
336 $this->getDebugInstance()->output(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.<br />\n",
339 $partnerInstance->getObjectDescription(),
340 $partnerInstance->getCompanyName(),
341 $partyInstance->getObjectDescription(),
342 $partyInstance->getCompanyName(),
343 $this->getShipInstance()->getObjectDescription(),
344 $this->getShipInstance()->getShipName()
350 // Setter for merchant instance
351 public final function setMerchantInstance (Merchant $merchantInstance) {
352 $this->merchantInstance = $merchantInstance;
355 // Getter for merchant instance
356 public final function getMerchantInstance () {
357 return $this->merchantInstance;
360 // Getter for total price
361 public final function getTotalPrice () {
363 $shipInstance = $this->getShipInstance();
366 if (is_null($shipInstance)) {
367 // Opps! Empty partner instance?
368 throw new NullPointerException($shipInstance, self::EXCEPTION_IS_NULL_POINTER);
369 } elseif (!is_object($shipInstance)) {
370 // Not an object! ;-(
371 throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
372 } elseif (!$shipInstance instanceof ConstructableShip) {
373 // Does not have the required feature (method)
374 throw new ShipIsInvalidException(array($shipInstance), self::EXCEPTION_INVALID_SHIP_INSTANCE);
377 // Get the structure array
378 $struct = $shipInstance->getStructuresArray();
381 if (is_null($struct)) {
382 // Opps! Empty partner instance?
383 throw new EmptyStructuresListException($this, self::EXCEPTION_EMPTY_STRUCTURES_ARRAY);
389 // Iterate through the list
390 for ($iter = $struct->getIterator(); $iter->valid(); $iter->next()) {
392 $item = $iter->current();
395 if (is_null($item)) {
396 // Opps! Empty partner instance?
397 throw new NullPointerException($item, self::EXCEPTION_IS_NULL_POINTER);
398 } elseif (!is_object($item)) {
399 // Not an object! ;-(
400 throw new NoObjectException($item, self::EXCEPTION_IS_NO_OBJECT);
401 } elseif (!method_exists($item, 'getPartInstance')) {
402 // Does not have the required feature (method)
403 throw new MissingMethodException(array($item, 'getPartInstance'), self::EXCEPTION_MISSING_METHOD);
407 $part = $item->getPartInstance();
410 if (is_null($part)) {
411 // Opps! Empty partner instance?
412 throw new NullPointerException($part, self::EXCEPTION_IS_NULL_POINTER);
413 } elseif (!is_object($part)) {
414 // Not an object! ;-(
415 throw new NoObjectException($part, self::EXCEPTION_IS_NO_OBJECT);
416 } elseif (!method_exists($part, 'getPrice')) {
417 // Does not have the required feature (method)
418 throw new MissingMethodException(array($part, 'getPrice'), self::EXCEPTION_MISSING_METHOD);
421 // Get price for one item
422 $price = $part->getPrice();
424 // Is there numCabin() available?
425 if (method_exists($item, 'getNumCabin')) {
426 // Get total cabin and multiply it with the price
427 $price = $price * $item->getNumCabin();
430 // Add price to total price
431 $totalPrice += $price;
434 // Total price calculated?
435 if ($totalPrice === 0) {
437 throw new TotalPriceNotCalculatedException($this, self::EXCEPTION_TOTAL_PRICE_NOT_CALCULATED);
440 // Return total price
447 public function saveObjectToDatabase () {
448 $this->getDebugInstance()->output(sprintf("[%s:] Stub <strong>%s</strong> erreicht.",