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 if (((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) && (defined('DEBUG_CONSTRUCT'))) {
50 $this->getDebugInstance()->output(sprintf("[%s:%d] Konstruktor erreicht.<br />\n",
57 $this->setObjectDescription("Bauvertrag");
59 // Unique-ID generieren
60 $this->createUniqueID();
63 $this->removeSystemArray();
66 // Neuen Bauvertrag generieren
67 public final static function createWorksContract ($shipType, $shipName, ContractPartner $partnerInstance) {
69 $shipType = (string) $shipType;
70 $shipName = (string) $shipName;
72 // Is the other one a contract partner?
73 if (is_null($partnerInstance)) {
74 // Opps! Empty partner instance?
75 throw new NullPointerException($partnerInstance, self::EXCEPTION_IS_NULL_POINTER);
76 } elseif (!is_object($partnerInstance)) {
78 throw new NoObjectException($partnerInstance, self::EXCEPTION_IS_NO_OBJECT);
79 } elseif (!method_exists($partnerInstance, 'isContractPartner')) {
80 // Does not have the required feature (method)
81 throw new MissingMethodException(array($partnerInstance, 'isContractPartner'), self::EXCEPTION_MISSING_METHOD);
85 $contractInstance = new WorksContract();
87 // Debug-Meldung ausgeben
88 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",
92 $partnerInstance->getObjectDescription(),
93 $partnerInstance->getCompanyName()
96 // Schiffsnamen setzen
97 $contractInstance->setShipName($shipName);
99 // Existiert die Klasse ueberhaupt?
100 if (!class_exists($shipType)) {
101 // Klasse nicht gefunden
102 throw new ClassNotFoundException ($shipType, 0);
105 // Schiff-Instanz temporaer erzeugen und in den Bauvertrag einfuegen
106 $eval = sprintf("\$contractInstance->setShipInstance(%s::create%s(\"%s\"));",
113 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $contractInstance->getDebugInstance()->output(sprintf("[%s:%d] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
119 // Execute constructed command
122 // Set itself as contract partner
123 $contractInstance->setContractPartner($partnerInstance);
125 // Instanz zurueckgeben
126 return $contractInstance;
129 // Setter for ship instance
130 private final function setShipInstance (ConstructableShip $shipInstance) {
131 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",
134 $shipInstance->getShipName()
136 $this->shipInstance = $shipInstance;
139 // Setter for ship name
140 private final function setShipName ($shipName) {
141 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Das neue Schiff wird <strong>%s</strong> heissen.<br />\n",
146 $this->shipName = (string) $shipName;
149 // Getter for ship name
150 public final function getShipName () {
151 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiffsname <strong>%s</strong> angefordert.<br />\n",
156 return $this->shipName;
159 // Getter for ship instance
160 public final function getShipInstance () {
161 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiff-Instanz angefordert.<br />\n",
165 return $this->shipInstance;
168 // Add detail to the contract
169 public function addContractDetails ($shipPart, $parentPart, array $dataArray) {
171 $shipPart = (string) $shipPart;
172 $parentPart = (string) $parentPart;
175 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",
182 // Initialize the instance (shall not be done within dynamic part)
185 // Prepare the big command for everthing
187 \$instance = ".$shipPart."::create".$shipPart."(";
188 foreach ($dataArray as $pIdx => $parts) {
189 if (is_string($parts)) {
191 $eval .= "\"".$parts."\", ";
192 } elseif (is_array($parts)) {
193 // Ist ein weiteres Array!
195 foreach ($parts as $idx2 => $sub) {
196 $eval .= "'".$idx2."' => ";
197 if (is_string($sub)) {
198 // Ist erneut ein String
199 $eval .= "\"".$sub."\"";
200 } elseif (is_array($sub)) {
201 // Wird nicht mehr unterstuetzt!
202 ApplicationEntryPoint::app_die("No more arrays!");
210 // Letztes Komma entfernen
211 $eval = substr($eval, 0, -2);
214 // Etwas anderes direkt!
215 $eval .= $parts.", ";
219 // Letztes Komma abhaengen
220 $eval = substr($eval, 0, -2);
222 } catch (DimNotFoundInArrayException \$e) {
223 \$this->getDebugInstance()->output(sprintf(\"[main:] Die <strong>%s</strong> konnte nicht vervollständigt werden. Grund: <strong>%s</strong><br />\\n\",
224 \$this->getShipInstance()->getShipName(),
231 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[Ship:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
238 // Try to add the ship part to the contract
240 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Versuche ein Schiffsteil in den Bauvertrag aufzunehmen.<br />\n",
244 if (!$instance instanceof ConstructableShipPart) {
245 // Ship part not constructable!
246 throw new ShipPartNotConstructableException(array($shipPart), self::EXCEPTION_NOT_CONSTRUCTABLE);
247 } elseif (!$this->getShipInstance()->createShipPart($instance, $parentPart)) {
248 // Schiff konnte nicht gebaut werden!
249 throw new ShipNotConstructedException(sprintf("Das Schiff <strong>%s</strong> konnte wegen eines Fehlers nicht gebaut werden. Siehe obere Meldungen.",
250 $this->getShipInstance()->getShipName()
253 } catch(ClassNotFoundException $e) {
255 throw new ClassNotFoundException($e->getMessage(), $e->getCode());
258 // Get price for this item
259 $price = $this->getMerchantInstance()->getPriceFromList($instance);
261 // Final debug message
262 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> kostet <strong>%s</strong>.<br />\n",
265 $instance->getObjectDescription(),
266 $this->getMerchantInstance()->formatCurrency($price)
270 $instance->setPrice($price);
272 // Final debug message
273 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> wurde in den Bauvertrag aufgenommen.<br />\n",
276 $instance->getObjectDescription()
280 // Setter for contract partner
281 public final function setContractPartner (ContractPartner $partnerInstance) {
282 $this->contractPartner = $partnerInstance;
285 // Getter for contract partner
286 public final function getContractPartner () {
287 return $this->contractPartner;
290 // Setter for contract party
291 public final function setContractParty (ContractPartner $partyInstance) {
292 $this->contractParty = $partyInstance;
295 // Getter for contract party
296 public final function getContractParty () {
297 return $this->contractParty;
300 // Setter for signature
301 public final function setSigned ($signed) {
302 $this->signed = (boolean) $signed;
305 // Getter for signature
306 public function isSigned () {
307 return $this->signed;
311 public function signContract (ContractPartner $partnerInstance, ContractPartner $partyInstance) {
312 // Is this contract already signed?
313 if ($this->isSigned()) {
314 // Throw an exception
315 throw new ContractAllreadySignedException(array($this, $this->getContractPartner(), $this->getContractParty()), self::EXCEPTION_CONTRACT_ALREADY_SIGNED);
318 // Is the first contract partner still the same?
319 if ($partnerInstance->equals($this->getContractPartner())) {
320 // Set contract party (other partner is already set)
321 $this->setContractParty($partyInstance);
324 $this->setSigned(true);
326 // Throw an exception
327 throw new ContractPartnerMismatchException(array($this, $this->getContractPartner(), $partyInstance), self::EXCEPTION_CONTRACT_PARTNER_MISMATCH);
331 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) {
332 if ($partnerInstance->equals($partyInstance)) {
334 $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",
337 $partnerInstance->getObjectDescription(),
338 $partnerInstance->getCompanyName(),
339 $this->getShipInstance()->getObjectDescription(),
340 $this->getShipInstance()->getShipName()
343 // Other contract party
344 $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",
347 $partnerInstance->getObjectDescription(),
348 $partnerInstance->getCompanyName(),
349 $partyInstance->getObjectDescription(),
350 $partyInstance->getCompanyName(),
351 $this->getShipInstance()->getObjectDescription(),
352 $this->getShipInstance()->getShipName()
358 // Setter for merchant instance
359 public final function setMerchantInstance (Merchant $merchantInstance) {
360 $this->merchantInstance = $merchantInstance;
363 // Getter for merchant instance
364 public final function getMerchantInstance () {
365 return $this->merchantInstance;
368 // Getter for total price
369 public final function getTotalPrice () {
371 $shipInstance = $this->getShipInstance();
374 if (is_null($shipInstance)) {
375 // Opps! Empty partner instance?
376 throw new NullPointerException($shipInstance, self::EXCEPTION_IS_NULL_POINTER);
377 } elseif (!is_object($shipInstance)) {
378 // Not an object! ;-(
379 throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
380 } elseif (!$shipInstance instanceof ConstructableShip) {
381 // Does not have the required feature (method)
382 throw new ShipIsInvalidException(array($shipInstance), self::EXCEPTION_INVALID_SHIP_INSTANCE);
385 // Get the structure array
386 $struct = $shipInstance->getStructuresArray();
389 if (is_null($struct)) {
390 // Opps! Empty partner instance?
391 throw new EmptyStructuresListException($this, self::EXCEPTION_EMPTY_STRUCTURES_ARRAY);
397 // Iterate through the list
398 for ($iter = $struct->getIterator(); $iter->valid(); $iter->next()) {
400 $item = $iter->current();
403 if (is_null($item)) {
404 // Opps! Empty partner instance?
405 throw new NullPointerException($item, self::EXCEPTION_IS_NULL_POINTER);
406 } elseif (!is_object($item)) {
407 // Not an object! ;-(
408 throw new NoObjectException($item, self::EXCEPTION_IS_NO_OBJECT);
409 } elseif (!method_exists($item, 'getPartInstance')) {
410 // Does not have the required feature (method)
411 throw new MissingMethodException(array($item, 'getPartInstance'), self::EXCEPTION_MISSING_METHOD);
415 $part = $item->getPartInstance();
418 if (is_null($part)) {
419 // Opps! Empty partner instance?
420 throw new NullPointerException($part, self::EXCEPTION_IS_NULL_POINTER);
421 } elseif (!is_object($part)) {
422 // Not an object! ;-(
423 throw new NoObjectException($part, self::EXCEPTION_IS_NO_OBJECT);
424 } elseif (!method_exists($part, 'getPrice')) {
425 // Does not have the required feature (method)
426 throw new MissingMethodException(array($part, 'getPrice'), self::EXCEPTION_MISSING_METHOD);
429 // Get price for one item
430 $price = $part->getPrice();
432 // Is there numCabin() available?
433 if (method_exists($item, 'getNumCabin')) {
434 // Get total cabin and multiply it with the price
435 $price = $price * $item->getNumCabin();
438 // Add price to total price
439 $totalPrice += $price;
442 // Total price calculated?
443 if ($totalPrice === 0) {
445 throw new TotalPriceNotCalculatedException($this, self::EXCEPTION_TOTAL_PRICE_NOT_CALCULATED);
448 // Return total price
455 public function saveObjectToDatabase () {
456 $this->getDebugInstance()->output(sprintf("[%s:] Stub <strong>%s</strong> erreicht.",