Debug mailer finished and debug messages removed:
[shipsimu.git] / application / ship-simu / main / class_WorksContract.php
1 <?php
2 /**
3  * The work constract class which can be used for contract parties
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0.0
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
10  *
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.
15  *
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.
20  *
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/>.
23  */
24 class WorksContract extends BaseFrameworkSystem implements SignableContract {
25         // Zukuenftiger Schiffsname
26         private $shipName         = "";
27
28         // Instanz zum Schiffstypen
29         private $shipInstance     = null;
30
31         // Contract partner
32         private $contractPartner  = null;
33
34         // Other contract partner
35         private $contractParty    = null;
36
37         // Is the contract signed?
38         private $signed           = false;
39
40         // Merchant instance
41         private $merchantInstance = null;
42
43         // Konstruktor
44         protected function __construct () {
45                 // Call parent constructor
46                 parent::__construct(__CLASS__);
47
48                 // Set description
49                 $this->setObjectDescription("Bauvertrag");
50
51                 // Unique-ID generieren
52                 $this->generateUniqueId();
53
54                 // Clean up a little
55                 $this->removeSystemArray();
56         }
57
58         // Neuen Bauvertrag generieren
59         public final static function createWorksContract ($shipType, $shipName, ContractPartner $partnerInstance) {
60                 // Strings absichern
61                 $shipType = (string) $shipType;
62                 $shipName = (string) $shipName;
63
64                 // Get new instance
65                 $contractInstance = new WorksContract();
66
67                 // Debug-Meldung ausgeben
68                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $contractInstance->debugOutput(sprintf("[%s:%d] Neuer Bauvertrag wird f&uuml;r das Schiff <strong>%s</strong> mit der <strong>%s</strong> <strong>%s</strong> erstellt.",
69                         __CLASS__,
70                         __LINE__,
71                         $shipName,
72                         $partnerInstance->getObjectDescription(),
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, self::EXCEPTION_CLASS_NOT_FOUND);
83                 }
84
85                 // Schiff-Instanz temporaer erzeugen und in den Bauvertrag einfuegen
86                 $shipInstance = ObjectFactory::createObjectByName($shipType, array($shipName));
87                 $contractInstance->setShipInstance($shipInstance);
88
89                 // Remove the ship instance
90                 unset($shipInstance);
91
92                 // Set itself as contract partner
93                 $contractInstance->setContractPartner($partnerInstance);
94
95                 // Instanz zurueckgeben
96                 return $contractInstance;
97         }
98
99         // Setter for ship instance
100         private final function setShipInstance (ConstructableShip $shipInstance) {
101                 $this->shipInstance = $shipInstance;
102         }
103
104         // Setter for ship name
105         private final function setShipName ($shipName) {
106                 $this->shipName = (string) $shipName;
107         }
108
109         // Getter for ship name
110         public final function getShipName () {
111                 return $this->shipName;
112         }
113
114         // Getter for ship instance
115         public final function getShipInstance () {
116                 return $this->shipInstance;
117         }
118
119         // Add detail to the contract
120         public function addContractDetails ($shipPart, $parentPart, array $dataArray) {
121                 // Secure strings
122                 $shipPart   = (string) $shipPart;
123                 $parentPart = (string) $parentPart;
124
125                 // Debug message
126                 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.",
127                         __CLASS__,
128                         __LINE__,
129                         $shipPart,
130                         $parentPart
131                 ));
132
133                 // Initialize the instance (shall not be done within dynamic part)
134                 $partInstance = null;
135
136                 // Try to get an instance for this ship part
137                 try {
138                         $partInstance = ObjectFactory::createObjectByName($shipPart, $dataArray);
139                 } catch (DimNotFoundInArrayException $e) {
140                         $this->debugOutput(sprintf("[main:] Die <strong>%s</strong> konnte nicht vervollst&auml;ndigt werden. Grund: <strong>%s</strong><br />",
141                                 $this->getShipInstance()->getShipName(),
142                                 $e->getMessage()
143                         ));
144
145                         // Debug message
146                         if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Versuche ein Schiffsteil in den Bauvertrag aufzunehmen.",
147                                 __CLASS__,
148                                 __LINE__
149                         ));
150
151                         // Is this ship part constructable?
152                         if (!$partInstance instanceof ConstructableShipPart) {
153                                 // Ship part not constructable!
154                                 throw new ShipPartNotConstructableException(array($shipPart), self::EXCEPTION_NOT_CONSTRUCTABLE);
155                         } elseif (!$this->getShipInstance()->createShipPart($partInstance, $parentPart)) {
156                                 // Schiff konnte nicht gebaut werden!
157                                 throw new ShipNotConstructedException(sprintf("Das Schiff <strong>%s</strong> konnte wegen eines Fehlers nicht gebaut werden. Siehe obere Meldungen.",
158                                         $this->getShipInstance()->getShipName()
159                                 ));
160                         }
161                 } catch (ClassNotFoundException $e) {
162                         // Throw it again...
163                         throw new ClassNotFoundException($e->getMessage(), $e->getCode());
164                 }
165
166                 // Get price for this item
167                 $price = $this->getMerchantInstance()->getPriceFromList($partInstance);
168
169                 // Final debug message
170                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] <strong>%s</strong> kostet <strong>%s</strong>.",
171                         __CLASS__,
172                         __LINE__,
173                         $partInstance->getObjectDescription(),
174                         $this->getMerchantInstance()->formatCurrency($price)
175                 ));
176
177                 // Add price
178                 $partInstance->setPrice($price);
179
180                 // Final debug message
181                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] <strong>%s</strong> wurde in den Bauvertrag aufgenommen.",
182                         __CLASS__,
183                         __LINE__,
184                         $partInstance->getObjectDescription()
185                 ));
186         }
187
188         // Setter for contract partner
189         public final function setContractPartner (ContractPartner $partnerInstance) {
190                 $this->contractPartner = $partnerInstance;
191         }
192
193         // Getter for contract partner
194         public final function getContractPartner () {
195                 return $this->contractPartner;
196         }
197
198         // Setter for contract party
199         public final function setContractParty (ContractPartner $partyInstance) {
200                 $this->contractParty = $partyInstance;
201         }
202
203         // Getter for contract party
204         public final function getContractParty () {
205                 return $this->contractParty;
206         }
207
208         // Setter for signature
209         public final function setSigned ($signed) {
210                 $this->signed = (boolean) $signed;
211         }
212
213         // Getter for signature
214         public function isSigned () {
215                 return $this->signed;
216         }
217
218         // Sign the contract
219         public function signContract (ContractPartner $partnerInstance, ContractPartner $partyInstance) {
220                 // Is this contract already signed?
221                 if ($this->isSigned()) {
222                         // Throw an exception
223                         throw new ContractAllreadySignedException(array($this, $this->getContractPartner(), $this->getContractParty()), self::EXCEPTION_CONTRACT_ALREADY_SIGNED);
224                 }
225
226                 // Is the first contract partner still the same?
227                 if ($partnerInstance->equals($this->getContractPartner())) {
228                         // Set contract party (other partner is already set)
229                         $this->setContractParty($partyInstance);
230
231                         // Finally sign it
232                         $this->setSigned(true);
233                 } else {
234                         // Throw an exception
235                         throw new ContractPartnerMismatchException(array($this, $this->getContractPartner(), $partyInstance), self::EXCEPTION_CONTRACT_PARTNER_MISMATCH);
236                 }
237
238                 // Debug message
239                 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) {
240                         if ($partnerInstance->equals($partyInstance)) {
241                                 // With itself
242                                 $this->debugOutput(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.",
243                                         __CLASS__,
244                                         __LINE__,
245                                         $partnerInstance->getObjectDescription(),
246                                         $partnerInstance->getCompanyName(),
247                                         $this->getShipInstance()->getObjectDescription(),
248                                         $this->getShipInstance()->getShipName()
249                                 ));
250                         } else {
251                                 // Other contract party
252                                 $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 &uuml;ber das <strong>%s</strong> <em><strong>%s</strong></em> ein.",
253                                         __CLASS__,
254                                         __LINE__,
255                                         $partnerInstance->getObjectDescription(),
256                                         $partnerInstance->getCompanyName(),
257                                         $partyInstance->getObjectDescription(),
258                                         $partyInstance->getCompanyName(),
259                                         $this->getShipInstance()->getObjectDescription(),
260                                         $this->getShipInstance()->getShipName()
261                                 ));
262                         }
263                 }
264         }
265
266         // Setter for merchant instance
267         public final function setMerchantInstance (Merchant $merchantInstance) {
268                 $this->merchantInstance = $merchantInstance;
269         }
270
271         // Getter for merchant instance
272         public final function getMerchantInstance () {
273                 return $this->merchantInstance;
274         }
275
276         // Getter for total price
277         public final function getTotalPrice () {
278                 // Get ship instance
279                 $shipInstance = $this->getShipInstance();
280
281                 // Is this a ship?
282                 if (is_null($shipInstance)) {
283                         // Opps! Empty partner instance?
284                         throw new NullPointerException($shipInstance, self::EXCEPTION_IS_NULL_POINTER);
285                 } elseif (!is_object($shipInstance)) {
286                         // Not an object! ;-(
287                         throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
288                 } elseif (!$shipInstance instanceof ConstructableShip) {
289                         // Does not have the required feature (method)
290                         throw new ShipIsInvalidException(array($shipInstance), self::EXCEPTION_INVALID_SHIP_INSTANCE);
291                 }
292
293                 // Get the structure array
294                 $struct = $shipInstance->getStructuresArray();
295
296                 // Is this a ship?
297                 if (is_null($struct)) {
298                         // Opps! Empty partner instance?
299                         throw new EmptyStructuresListException($this, self::EXCEPTION_EMPTY_STRUCTURES_ARRAY);
300                 }
301
302                 // Init total price
303                 $totalPrice = 0;
304
305                 // Iterate through the list
306                 for ($iter = $struct->getIterator(); $iter->valid(); $iter->next()) {
307                         // Get item
308                         $item = $iter->current();
309
310                         // Is this a ship?
311                         if (is_null($item)) {
312                                 // Opps! Empty partner instance?
313                                 throw new NullPointerException($item, self::EXCEPTION_IS_NULL_POINTER);
314                         } elseif (!is_object($item)) {
315                                 // Not an object! ;-(
316                                 throw new NoObjectException($item, self::EXCEPTION_IS_NO_OBJECT);
317                         } elseif (!$item instanceof BaseSimulator) {
318                                 // Does not have the required feature (method)
319                                 throw new MissingMethodException(array($item, 'getPartInstance'), self::EXCEPTION_MISSING_METHOD);
320                         }
321
322                         // Get part instance
323                         $part = $item->getPartInstance();
324
325                         // Is this a ship?
326                         if (is_null($part)) {
327                                 // Opps! Empty partner instance?
328                                 throw new NullPointerException($part, self::EXCEPTION_IS_NULL_POINTER);
329                         } elseif (!is_object($part)) {
330                                 // Not an object! ;-(
331                                 throw new NoObjectException($part, self::EXCEPTION_IS_NO_OBJECT);
332                         } elseif (!method_exists($part, 'getPrice')) {
333                                 // Does not have the required feature (method)
334                                 throw new MissingMethodException(array($part, 'getPrice'), self::EXCEPTION_MISSING_METHOD);
335                         }
336
337                         // Get price for one item
338                         $price = $part->getPrice();
339
340                         // Is there numCabin() available?
341                         if (method_exists($item, 'getNumCabin')) {
342                                 // Get total cabin and multiply it with the price
343                                 $price = $price * $item->getNumCabin();
344                         }
345
346                         // Add price to total price
347                         $totalPrice += $price;
348                 }
349
350                 // Total price calculated?
351                 if ($totalPrice === 0) {
352                         // Throw exception
353                         throw new TotalPriceNotCalculatedException($this, self::EXCEPTION_TOTAL_PRICE_NOT_CALCULATED);
354                 }
355
356                 // Return total price
357                 return $totalPrice;
358         }
359 }
360
361 // [EOF]
362 ?>