c1e3dab65b97446c17156416c0ab1053805eadec
[shipsimu.git] / application / ship-simu / main / class_WorksContract.php
1 <?php
2
3 // Bauvertrag-Klasse
4 class WorksContract extends BaseFrameworkSystem implements SignableContract {
5         // Zukuenftiger Schiffsname
6         private $shipName         = "";
7
8         // Instanz zum Schiffstypen
9         private $shipInstance     = null;
10
11         // Contract partner
12         private $contractPartner  = null;
13
14         // Other contract partner
15         private $contractParty    = null;
16
17         // Is the contract signed?
18         private $signed           = false;
19
20         // Merchant instance
21         private $merchantInstance = null;
22
23         // Konstruktor
24         private function __construct () {
25                 // Call parent constructor
26                 parent::constructor(__CLASS__);
27
28                 // Debug message
29                 if (((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) && (defined('DEBUG_CONSTRUCT'))) {
30                         $this->getDebugInstance()->output(sprintf("[%s:%d] Konstruktor erreicht.<br />\n",
31                                 __CLASS__,
32                                 __LINE__
33                         ));
34                 }
35
36                 // Set description
37                 $this->setPartDescr("Bauvertrag");
38
39                 // Unique-ID generieren
40                 $this->createUniqueID();
41
42                 // Clean up a little
43                 $this->removeSystemArray();
44         }
45
46         // Neuen Bauvertrag generieren
47         public static function createWorksContract ($shipType, $shipName, ContractPartner $partnerInstance) {
48                 // Strings absichern
49                 $shipType = (string) $shipType;
50                 $shipName = (string) $shipName;
51
52                 // Is the other one a contract partner?
53                 if (is_null($partnerInstance)) {
54                         // Opps! Empty partner instance?
55                         throw new NullPointerException($partnerInstance, self::EXCEPTION_IS_NULL_POINTER);
56                 } elseif (!is_object($partnerInstance)) {
57                         // Not an object! ;-(
58                         throw new NoObjectException($partnerInstance, self::EXCEPTION_IS_NO_OBJECT);
59                 } elseif (!method_exists($partnerInstance, 'isContractPartner')) {
60                         // Does not have the required feature (method)
61                         throw new MissingMethodException(array($partnerInstance, 'isContractPartner'), self::EXCEPTION_MISSING_METHOD);
62                 }
63
64                 // Instanz holen
65                 $contractInstance = new WorksContract();
66
67                 // Debug-Meldung ausgeben
68                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $contractInstance->getDebugInstance()->output(sprintf("[%s:%d] Neuer Bauvertrag wird f&uuml;r das Schiff <strong>%s</strong> mit der <strong>%s</strong> <strong>%s</strong> erstellt.<br />\n",
69                         __CLASS__,
70                         __LINE__,
71                         $shipName,
72                         $partnerInstance->getPartDescr(),
73                         $partnerInstance->getCompanyName()
74                 ));
75
76                 // Schiffsnamen setzen
77                 $contractInstance->setShipName($shipName);
78
79                 // Existiert die Klasse ueberhaupt?
80                 if (!class_exists($shipType)) {
81                         // Klasse nicht gefunden
82                         throw new ClassNotFoundException ($shipType, 0);
83                 }
84
85                 // Schiff-Instanz temporaer erzeugen und in den Bauvertrag einfuegen
86                 $eval = sprintf("\$contractInstance->setShipInstance(%s::create%s(\"%s\"));",
87                         $shipType,
88                         $shipType,
89                         $shipName
90                 );
91
92                 // Debug message
93                 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $contractInstance->getDebugInstance()->output(sprintf("[%s:%d] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
94                         __CLASS__,
95                         __LINE__,
96                         htmlentities($eval)
97                 ));
98
99                 // Execute constructed command
100                 @eval($eval);
101
102                 // Set itself as contract partner
103                 $contractInstance->setContractPartner($partnerInstance);
104
105                 // Instanz zurueckgeben
106                 return $contractInstance;
107         }
108
109         // Setter for ship instance
110         private function setShipInstance (ConstructableShip $shipInstance) {
111                 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",
112                         __CLASS__,
113                         __LINE__,
114                         $shipInstance->getShipName()
115                 ));
116                 $this->shipInstance = $shipInstance;
117         }
118
119         // Setter for ship name
120         private function setShipName ($shipName) {
121                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Das neue Schiff wird <strong>%s</strong> heissen.<br />\n",
122                         __CLASS__,
123                         __LINE__,
124                         $shipName
125                 ));
126                 $this->shipName = (string) $shipName;
127         }
128
129         // Getter for ship name
130         public function getShipName () {
131                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiffsname <strong>%s</strong> angefordert.<br />\n",
132                         __CLASS__,
133                         __LINE__,
134                         $this->shipName
135                 ));
136                 return $this->shipName;
137         }
138
139         // Getter for ship instance
140         public function getShipInstance () {
141                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiff-Instanz angefordert.<br />\n",
142                         __CLASS__,
143                         __LINE__
144                 ));
145                 return $this->shipInstance;
146         }
147
148         // Add detail to the contract
149         public function addContractDetails ($shipPart, $parentPart, array $dataArray) {
150                 // Secure strings
151                 $shipPart   = (string) $shipPart;
152                 $parentPart = (string) $parentPart;
153
154                 // Debug message
155                 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",
156                         __CLASS__,
157                         __LINE__,
158                         $shipPart,
159                         $parentPart
160                 ));
161
162                 // Initialize the instance (shall not be done within dynamic part)
163                 $instance = null;
164
165                 // Prepare the big command for everthing
166                 $eval = "try {
167         \$instance = ".$shipPart."::create".$shipPart."(";
168                 foreach ($dataArray as $pIdx => $parts) {
169                         if (is_string($parts)) {
170                                 // String einbauen
171                                 $eval .= "\"".$parts."\", ";
172                         } elseif (is_array($parts)) {
173                                 // Ist ein weiteres Array!
174                                 $eval .= "array(";
175                                 foreach ($parts as $idx2 => $sub) {
176                                         $eval .= "'".$idx2."' => ";
177                                         if (is_string($sub)) {
178                                                 // Ist erneut ein String
179                                                 $eval .= "\"".$sub."\"";
180                                         } elseif (is_array($sub)) {
181                                                 // Wird nicht mehr unterstuetzt!
182                                                 ApplicationEntryPoint::app_die("No more arrays!");
183                                         } else {
184                                                 // Direkt anhaengen
185                                                 $eval .= $sub;
186                                         }
187                                         $eval .= ", ";
188                                 }
189
190                                 // Letztes Komma entfernen
191                                 $eval = substr($eval, 0, -2);
192                                 $eval .= "), ";
193                         } else {
194                                 // Etwas anderes direkt!
195                                 $eval .= $parts.", ";
196                         }
197                 }
198
199                 // Letztes Komma abhaengen
200                 $eval = substr($eval, 0, -2);
201                 $eval .= ");
202 } catch (DimNotFoundInArrayException \$e) {
203         \$this->getDebugInstance()->output(sprintf(\"[main:] Die <strong>%s</strong> konnte nicht vervollst&auml;ndigt werden. Grund: <strong>%s</strong><br />\\n\",
204                 \$this->getShipInstance()->getShipName(),
205                 \$e->getMessage()
206         ));
207         \$instance = null;
208 }";
209
210                 // Debug message
211                 if ((defined('DEBUG_EVAL')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[Ship:] Konstruierte PHP-Anweisung: <pre><em>%s</em></pre><br />\n",
212                         htmlentities($eval)
213                 ));
214
215                 // Code ausfuhren
216                 @eval($eval);
217
218                 // Try to add the ship part to the contract
219                 try {
220                         if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Versuche ein Schiffsteil in den Bauvertrag aufzunehmen.<br />\n",
221                                 __CLASS__,
222                                 __LINE__
223                         ));
224                         if (!$instance instanceof ConstructableShipPart) {
225                                 // Ship part not constructable!
226                                 throw new ShipPartNotConstructableException(array($shipPart), self::EXCEPTION_NOT_CONSTRUCTABLE);
227                         } elseif (!$this->getShipInstance()->createShipPart($instance, $parentPart)) {
228                                 // Schiff konnte nicht gebaut werden!
229                                 throw new ShipNotConstructedException(sprintf("Das Schiff <strong>%s</strong> konnte wegen eines Fehlers nicht gebaut werden. Siehe obere Meldungen.",
230                                         $this->getShipInstance()->getShipName()
231                                 ));
232                         }
233                 } catch(ClassNotFoundException $e) {
234                         // Throw it again...
235                         throw new ClassNotFoundException($e->getMessage(), $e->getCode());
236                 }
237
238                 // Get price for this item
239                 $price = $this->getMerchantInstance()->getPriceFromList($instance);
240
241                 // Final debug message
242                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> kostet <strong>%s</strong>.<br />\n",
243                         __CLASS__,
244                         __LINE__,
245                         $instance->getPartDescr(),
246                         $this->getMerchantInstance()->formatCurrency($price)
247                 ));
248
249                 // Add price
250                 $instance->setPrice($price);
251
252                 // Final debug message
253                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> wurde in den Bauvertrag aufgenommen.<br />\n",
254                         __CLASS__,
255                         __LINE__,
256                         $instance->getPartDescr()
257                 ));
258         }
259
260         // Setter for contract partner
261         public function setContractPartner (ContractPartner $partnerInstance) {
262                 $this->contractPartner = $partnerInstance;
263         }
264
265         // Getter for contract partner
266         public function getContractPartner () {
267                 return $this->contractPartner;
268         }
269
270         // Setter for contract party
271         public function setContractParty (ContractPartner $partyInstance) {
272                 $this->contractParty = $partyInstance;
273         }
274
275         // Getter for contract party
276         public function getContractParty () {
277                 return $this->contractParty;
278         }
279
280         // Setter for signature
281         public function setSigned ($signed) {
282                 $this->signed = (boolean) $signed;
283         }
284
285         // Getter for signature
286         public function isSigned () {
287                 return $this->signed;
288         }
289
290         // Sign the contract
291         public function signContract (ContractPartner $partnerInstance, ContractPartner $partyInstance) {
292                 // Is this contract already signed?
293                 if ($this->isSigned()) {
294                         // Throw an exception
295                         throw new ContractAllreadySignedException(array($this, $this->getContractPartner(), $this->getContractParty()), self::EXCEPTION_CONTRACT_ALREADY_SIGNED);
296                 }
297
298                 // Is the first contract partner still the same?
299                 if ($partnerInstance->equals($this->getContractPartner())) {
300                         // Set contract party (other partner is already set)
301                         $this->setContractParty($partyInstance);
302
303                         // Finally sign it
304                         $this->setSigned(true);
305                 } else {
306                         // Throw an exception
307                         throw new ContractPartnerMismatchException(array($this, $this->getContractPartner(), $partyInstance), self::EXCEPTION_CONTRACT_PARTNER_MISMATCH);
308                 }
309
310                 // Debug message
311                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) {
312                         if ($partnerInstance->equals($partyInstance)) {
313                                 // With itself
314                                 $this->getDebugInstance()->output(sprintf("[%s:%d] Die <strong>%s</strong> <em><strong>%s</strong></em> stimmt einem Bauvertrag &uuml;ber das <strong>%s</strong> <em><strong>%s</strong></em> zu.<br />\n",
315                                         __CLASS__,
316                                         __LINE__,
317                                         $partnerInstance->getPartDescr(),
318                                         $partnerInstance->getCompanyName(),
319                                         $this->getShipInstance()->getPartDescr(),
320                                         $this->getShipInstance()->getShipName()
321                                 ));
322                         } else {
323                                 // Other contract party
324                                 $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 &uuml;ber das <strong>%s</strong> <em><strong>%s</strong></em> ein.<br />\n",
325                                         __CLASS__,
326                                         __LINE__,
327                                         $partnerInstance->getPartDescr(),
328                                         $partnerInstance->getCompanyName(),
329                                         $partyInstance->getPartDescr(),
330                                         $partyInstance->getCompanyName(),
331                                         $this->getShipInstance()->getPartDescr(),
332                                         $this->getShipInstance()->getShipName()
333                                 ));
334                         }
335                 }
336         }
337
338         // Setter for merchant instance
339         public function setMerchantInstance (Merchant $merchantInstance) {
340                 $this->merchantInstance = $merchantInstance;
341         }
342
343         // Getter for merchant instance
344         public function getMerchantInstance () {
345                 return $this->merchantInstance;
346         }
347
348         // Getter for total price
349         public function getTotalPrice () {
350                 // Get ship instance
351                 $shipInstance = $this->getShipInstance();
352
353                 // Is this a ship?
354                 if (is_null($shipInstance)) {
355                         // Opps! Empty partner instance?
356                         throw new NullPointerException($shipInstance, self::EXCEPTION_IS_NULL_POINTER);
357                 } elseif (!is_object($shipInstance)) {
358                         // Not an object! ;-(
359                         throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
360                 } elseif (!$shipInstance instanceof ConstructableShip) {
361                         // Does not have the required feature (method)
362                         throw new ShipIsInvalidException(array($shipInstance), self::EXCEPTION_INVALID_SHIP_INSTANCE);
363                 }
364
365                 // Get the structure array
366                 $struct = $shipInstance->getStructuresArray();
367
368                 // Is this a ship?
369                 if (is_null($struct)) {
370                         // Opps! Empty partner instance?
371                         throw new EmptyStructuresListException($this, self::EXCEPTION_EMPTY_STRUCTURES_ARRAY);
372                 }
373
374                 // Init total price
375                 $totalPrice = 0;
376
377                 // Iterate through the list
378                 for ($iter = $struct->getIterator(); $iter->valid(); $iter->next()) {
379                         // Get item
380                         $item = $iter->current();
381
382                         // Is this a ship?
383                         if (is_null($item)) {
384                                 // Opps! Empty partner instance?
385                                 throw new NullPointerException($item, self::EXCEPTION_IS_NULL_POINTER);
386                         } elseif (!is_object($item)) {
387                                 // Not an object! ;-(
388                                 throw new NoObjectException($item, self::EXCEPTION_IS_NO_OBJECT);
389                         } elseif (!method_exists($item, 'getPartInstance')) {
390                                 // Does not have the required feature (method)
391                                 throw new MissingMethodException(array($item, 'getPartInstance'), self::EXCEPTION_MISSING_METHOD);
392                         }
393
394                         // Get part instance
395                         $part = $item->getPartInstance();
396
397                         // Is this a ship?
398                         if (is_null($part)) {
399                                 // Opps! Empty partner instance?
400                                 throw new NullPointerException($part, self::EXCEPTION_IS_NULL_POINTER);
401                         } elseif (!is_object($part)) {
402                                 // Not an object! ;-(
403                                 throw new NoObjectException($part, self::EXCEPTION_IS_NO_OBJECT);
404                         } elseif (!method_exists($part, 'getPrice')) {
405                                 // Does not have the required feature (method)
406                                 throw new MissingMethodException(array($part, 'getPrice'), self::EXCEPTION_MISSING_METHOD);
407                         }
408
409                         // Get price for one item
410                         $price = $part->getPrice();
411
412                         // Is there numCabin() available?
413                         if (method_exists($item, 'getNumCabin')) {
414                                 // Get total cabin and multiply it with the price
415                                 $price = $price * $item->getNumCabin();
416                         }
417
418                         // Add price to total price
419                         $totalPrice += $price;
420                 }
421
422                 // Total price calculated?
423                 if ($totalPrice === 0) {
424                         // Throw exception
425                         throw new TotalPriceNotCalculatedException($this, self::EXCEPTION_TOTAL_PRICE_NOT_CALCULATED);
426                 }
427
428                 // Return total price
429                 return $totalPrice;
430         }
431
432         /**
433          * Stub!
434          */
435         public function saveObjectToDatabase () {
436                 $this->getDebugInstance()->output(sprintf("[%s:] Stub <strong>%s</strong> erreicht.",
437                         $this->__toString(),
438                         __FUNCTION__
439                 ));
440         }
441 }
442
443 // [EOF]
444 ?>