code comments including license information added, type hints added, minor rewrites...
[shipsimu.git] / application / ship-simu / main / companies / class_ShippingCompany.php
1 <?php
2 /**
3  * A shipping company may be founded with this class
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 ShippingCompany extends BaseSimulator implements Customer, ContractPartner {
25         /**
26          * Full name of this company
27          */
28         private $companyName     = "Namenlose Reederei";
29
30         /**
31          * Shorted name of this company
32          */
33         private $shortName       = "";
34
35         /**
36          * Instance of the founder
37          */
38         private $founderInstance = null;
39
40         /**
41          * Employed people by this company
42          */
43         private $employeeList    = null;
44
45         /**
46          * Headquarter harbor instance
47          */
48         private $hqInstance      = null;
49
50         /**
51          * List of all assigned shipyards
52          */
53         private $shipyardList   = null;
54
55         /**
56          * List of owned ships
57          */
58         private $ownedShips      = null;
59
60         /**
61          * Work constracts this company is currently working on
62          */
63         private $contractList    = null;
64
65         /**
66          * Main constructor
67          *
68          * @return      void
69          */
70         private function __construct () {
71                 // Call parent constructor
72                 parent::constructor(__CLASS__);
73
74                 // Debug message
75                 if (((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) && (defined('DEBUG_CONSTRUCT'))) {
76                         $this->getDebugInstance()->output(sprintf("[%s:%d] Konstruktor erreicht.<br />\n",
77                                 __CLASS__,
78                                 __LINE__
79                         ));
80                 }
81
82                 // Set description
83                 $this->setPartDescr("Reederei");
84
85                 // Generate unique ID number
86                 $this->createUniqueID();
87
88                 // Clean up a little
89                 $this->removeSystemArray();
90         }
91
92         // Reederei gruenden (create wegen Namenskonvention)
93         public static function createShippingCompany ($companyName, Harbor $hqInstance) {
94                 // Get new instance
95                 $companyInstance = new ShippingCompany();
96
97                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $companyInstance->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> wird gegr&uuml;ndet.<br />\n",
98                         __CLASS__,
99                         __LINE__,
100                         $companyName
101                 ));
102
103                 // Firmennamen setzen
104                 $companyInstance->setCompanyName($companyName);
105
106                 // Kuerzel setzen
107                 $companyInstance->createShortName();
108
109                 // Sitz festlegen
110                 $companyInstance->setHQInstance($hqInstance);
111
112                 // Werftenliste erstellen
113                 $companyInstance->createshipyardList();
114
115                 // Angestellten-Liste erstellen
116                 $companyInstance->createEmployeeList();
117
118                 // Auftragsliste erstellen
119                 $companyInstance->createContractList();
120
121                 // Clean up a little
122                 $companyInstance->removeWidth();
123                 $companyInstance->removeHeight();
124                 $companyInstance->removeLength();
125                 $companyInstance->removeDraught();
126                 $companyInstance->removePartInstance();
127
128                 // Instanz zurueckgeben
129                 return $companyInstance;
130         }
131
132         // Angestellten-Liste erstellen
133         private function createEmployeeList () {
134                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erh&auml;lt eine Angestelltenliste.<br />\n",
135                         __CLASS__,
136                         __LINE__,
137                         $this->getCompanyName()
138                 ));
139                 $this->employeeList = new FrameworkArrayObject();
140         }
141
142         // Werftenliste erstellen
143         public function createShipyardList () {
144                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erh&auml;lt eine Werftsliste.<br />\n",
145                         __CLASS__,
146                         __LINE__,
147                         $this->getCompanyName()
148                 ));
149                 $this->shipyardList = new FrameworkArrayObject();
150         }
151
152         // Auftragsliste erstellen
153         public function createContractList () {
154                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erh&auml;lt eine Auftragsliste.<br />\n",
155                         __CLASS__,
156                         __LINE__,
157                         $this->getCompanyName()
158                 ));
159                 $this->contractList = new FrameworkArrayObject();
160         }
161
162         // Setter-Methode fuer Firmennamen
163         public final function setCompanyName ($companyName) {
164                 $this->companyName = (string) $companyName;
165         }
166
167         // Getter-Methode fuer Firmennamen
168         public final function getCompanyName () {
169                 return $this->companyName;
170         }
171
172         // Setter-Methode fuer Firmensitz
173         public final function setHQInstance (Harbor $hqInstance) {
174                 $this->hqInstance = $hqInstance;
175         }
176
177         // Kuerzel setzen
178         private function createShortName () {
179                 // Mindestens eine Leerstelle?
180                 $dummy = explode(" ", $this->getCompanyName());
181                 foreach ($dummy as $part) {
182                         $this->shortName .= substr($part, 0, 1);
183                 }
184         }
185
186         // Reedereien Werften bauen lassen
187         public function createShipyardInHarbor($shipyardName, Harbor $harborInstance) {
188                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> baut im <strong>%s</strong> eine Werft <strong>%s</strong>.<br />\n",
189                         __CLASS__,
190                         __LINE__,
191                         $this->getCompanyName(),
192                         $harborInstance->getHarborName(),
193                         $shipyardName
194                 ));
195
196                 // Wird im HQ gebaut?
197                 if ($this->hqInstance->equals($harborInstance)) {
198                         // Die neue Werft wird im HQ gebaut!
199                         $this->hqInstance->addNewShipyardNotify($shipyardName, $this);
200                         // Die Werft drueber in Kenntnis setzen, welcher Reederei sie angehoert
201                 } else {
202                         // Ausserhalb des Heimathafens soll eine Werft gebaut werden
203                         $harborInstance->addNewShipyardNotify($shipyardName, $this);
204                 }
205         }
206
207         // Setter fuer Reederei-Gruender
208         public final function setCompanyFounder(CompanyEmployee $founderInstance) {
209                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> ist von <strong>%s %s</strong> gegr&uuml;ndet worden.<br />\n",
210                         __CLASS__,
211                         __LINE__,
212                         $this->getCompanyName(),
213                         $founderInstance->getSurname(),
214                         $founderInstance->getFamily()
215                 ));
216                 $this->founderInstance = $founderInstance;
217         }
218
219         // Getter for founder instance
220         public final function getFounderInstance () {
221                 return $this->founderInstance;
222         }
223
224         // Neue(n) Angestellte(n) in Angestellten-Liste aufnehmen
225         public function addNewEmployee (SimulatorPersonell $employeeInstance) {
226                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s %s</strong> tritt der Reederei <strong>%s</strong> als <strong>%s</strong> bei und erh&auml;lt ein Gehalt von <strong>%s</strong>.<br />\n",
227                         __CLASS__,
228                         __LINE__,
229                         $employeeInstance->getSurname(),
230                         $employeeInstance->getFamily(),
231                         $this->getCompanyName(),
232                         $employeeInstance->getPartDescr(),
233                         $this->formatCurrency($employeeInstance->getSalary())
234                 ));
235                 $this->employeeList->append($employeeInstance);
236         }
237
238         // Neue Werft in Liste aufnehmen
239         public function addNewShipyard (Shipyard $shipyardInstance) {
240                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erh&auml;lt die Werft <strong>%s</strong> hinzugef&uuml;gt.<br />\n",
241                         __CLASS__,
242                         __LINE__,
243                         $this->getCompanyName(),
244                         $shipyardInstance->getShipyardName()
245                 ));
246                 $this->shipyardList->append($shipyardInstance);
247         }
248
249         // Neue Mitarbeiter per Zufall einstellen/rekrutieren
250         public function recruitRandomEmployees($amount, SimulatorPersonell $personellInstance) {
251                 // Anzahl Mitarbeiter absichern
252                 $amount = (int) $amount;
253
254                 // Debug-Meldung ausgeben
255                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> stellt per Zufall <strong>%d</strong> neue Mitarbeiter ein.<br />\n",
256                         __CLASS__,
257                         __LINE__,
258                         $this->getCompanyName(),
259                         $amount
260                 ));
261
262                 // Gesamtanzahl verfuegbarer Erwerbsloser holen
263                 $totalUnemployed = $personellInstance->getAllUnemployed();
264
265                 // Existiert die gewuenschte Anzahl freier Arbeiter? (doppelt geht derzeit nicht)
266                 if ($totalUnemployed < $amount) {
267                         // Reichte nicht aus!
268                         throw new ToMuchEmployeesException(array($amount, $personellInstance->getAllUnemployed()), self::EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES);
269                 }
270
271                 // Get list for all unemployed people
272                 $list = $personellInstance->getSpecialPersonellList(false); // Should be cached
273
274                 // Get iterator of the list
275                 $iterator = $list->getIterator();
276
277                 // Get the requested amount of personell
278                 for ($idx = 0; $idx < $amount; $idx++) {
279                         $employee = null;
280                         // Is this personl unemployed?
281                         while (is_null($employee) || $employee->isEmployed()) {
282                                 // Generate random number
283                                 $pos = mt_rand(0, ($totalUnemployed - 1)); // Don't remove the -1 here:
284                                 // E.g. 100 entries means latest position is 99...
285
286                                 // Seek for the position
287                                 $iterator->seek($pos);
288
289                                 // Is the current position valid?
290                                 if ($iterator->valid()) {
291                                         // Element holen
292                                         $employee = $iterator->current();
293                                 } else {
294                                         // Should�normally not happen... :(
295                                         throw new StructuresOutOfBoundsException($idx, self::EXCEPTION_INDEX_OUT_OF_BOUNDS);
296                                 }
297                         }
298
299                         // A dummy just for the description and real class
300                         $dummy = CompanyEmployee::createCompanyEmployee("", "", "M", 1970, 1, 1, $employee->isMarried(), 0);
301
302                         // Make this person employed and give him some money to work
303                         $employee->setEmployed(true);
304                         $employee->setPartDescr($dummy->getPartDescr());
305                         $employee->setRealClass($dummy->__toString());
306                         $employee->increaseSalary((mt_rand(7, 14) * 100)); // Are 700 to 1400 EUR for the begin okay?
307
308                         // Debug message
309                         if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> stellt den/die Angestellte(n) <strong>%s %s</strong> ein.<br />\n",
310                                 __CLASS__,
311                                 __LINE__,
312                                 $this->getCompanyName(),
313                                 $employee->getSurname(),
314                                 $employee->getFamily()
315                         ));
316
317                         // Add this employee
318                         $this->addNewEmployee($employee);
319                 } // End - for
320
321                 // Cache resetten
322                 $personellInstance->resetCache();
323
324                 // Debug-Meldung ausgeben
325                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat per Zufall <strong>%d</strong> neue Mitarbeiter eingestellt.<br />\n",
326                         __CLASS__,
327                         __LINE__,
328                         $this->getCompanyName(),
329                         $amount
330                 ));
331         } // End - method
332
333         // Distribute all personells on all shipyards
334         public function distributeAllPersonellOnShipyards () {
335                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> verteilt alle ihre <strong>%d</strong> Mitarbeiter auf alle <strong>%d</strong> Werft(en).<br />\n",
336                         __CLASS__,
337                         __LINE__,
338                         $this->getCompanyName(),
339                         $this->getTotalEmployee(),
340                         $this->getTotalShipyards()
341                 ));
342
343                 // Do we have some shipyards?
344                 if (is_null($this->shipyardList)) {
345                         // No shipyards created
346                         throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS);
347                 }
348
349                 // Get iterator for shipyards
350                 $shipyardIter = $this->shipyardList->getIterator();
351
352                 // Iterate through all employees
353                 for ($idx = $this->employeeList->getIterator(); $idx->valid(); $idx->next()) {
354                         // Is the shipyard iterator still okay?
355                         if (!$shipyardIter->valid()) {
356                                 // Rewind to first position
357                                 $shipyardIter->seek(0);
358                         }
359
360                         // Get Shipyard object
361                         $shipyard = $shipyardIter->current();
362
363                         // Is this a Shipyard object?
364                         if (is_null($shipyard)) {
365                                 // No class returned
366                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
367                         } elseif (!is_object($shipyard)) {
368                                 // Not an object! ;-(
369                                 throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
370                         } elseif (!$shipyard->isSameClass("Shipyard")) {
371                                 // Nope, so throw exception
372                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
373                         }
374
375                         // Add employee to the shipyard
376                         $shipyard->addNewPersonell($idx->current());
377
378                         // Continue to next shipyard
379                         $shipyardIter->next();
380                 }
381         }
382
383         // Getter for total employees
384         public final function getTotalEmployee () {
385                 // Count all...
386                 $total = $this->employeeList->count();
387
388                 // Debug message
389                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat <strong>%d</strong> Mitarbeiter.<br />\n",
390                         __CLASS__,
391                         __LINE__,
392                         $this->getCompanyName(),
393                         $total
394                 ));
395
396                 // Return amount
397                 return $total;
398         }
399
400         // Getter for total shipyards
401         public final function getTotalShipyards () {
402                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] F&uuml;r die Reederei <strong>%s</strong> werden die Anzahl der Werften in allen H&auml;fen ermittelt.<br />\n",
403                         __CLASS__,
404                         __LINE__,
405                         $this->getCompanyName()
406                 ));
407
408                 // Do we have some shipyards?
409                 if (is_null($this->shipyardList)) {
410                         // No shipyards created
411                         throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS);
412                 }
413
414                 // Get iterator
415                 $total = $this->shipyardList->count();
416
417                 // Debug message
418                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat <strong>%d</strong> Werft(en).<br />\n",
419                         __CLASS__,
420                         __LINE__,
421                         $this->getCompanyName(),
422                         $total
423                 ));
424
425                 // Return amount
426                 return $total;
427         }
428
429         // Add a ship type (class) to all shipyards
430         public function addShipTypeToAllShipyards ($shipType) {
431                 // Secure strings
432                 $shipType = (string) $shipType;
433
434                 // Is the class there?
435                 if (!class_exists($shipType)) {
436                         // Throw exception
437                         throw new ClassNotFoundException($shipType, 0);
438                 }
439
440                 // Create dummy ship
441                 eval(sprintf("\$shipInstance = %s::create%s(\"M/S Dummy\");",
442                         $shipType,
443                         $shipType
444                 ));
445
446                 // Debug message
447                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> baut in allen Werften bald Schiffe vom Typ <strong>%s</strong>.<br />\n",
448                         __CLASS__,
449                         __LINE__,
450                         $this->getCompanyName(),
451                         $shipInstance->getPartDescr()
452                 ));
453
454                 // Iterate shipyard list
455                 for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) {
456                         // Get current element
457                         $shipyard = $idx->current();
458
459                         // Is this a shipyard?
460                         if (is_null($shipyard)) {
461                                 // Opps! Empty list?
462                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
463                         } elseif (!is_object($shipyard)) {
464                                 // Not an object! ;-(
465                                 throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
466                         } elseif (!$shipyard->isSameClass("Shipyard")) {
467                                 // Class is not a shipyard
468                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
469                         }
470
471                         // Add the new ship type to the shipyard
472                         $shipyard->addNewConstructableShipType($shipType);
473                 }
474         }
475
476         // Validate the requested ship type with the company if they can construct it
477         public function validateWorksContractShipType (SignableContract $contractInstance) {
478                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> pr&uuml;ft den Bauauftrag der <strong>%s</strong>.<br />\n",
479                         __CLASS__,
480                         __LINE__,
481                         $this->getCompanyName(),
482                         $contractInstance->getShipName()
483                 ));
484
485                 // First get the ship type
486                 $shipInstance = $contractInstance->getShipInstance();
487
488                 // Ist there a ship instance?
489                 if (is_null($shipInstance)) {
490                         // Opps! Empty entry?
491                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
492                 } elseif (!is_object($shipInstance)) {
493                         // Not an object! ;-(
494                         throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
495                 }
496
497                 // Get it's real class name
498                 $shipType = $shipInstance->__toString();
499
500                 // Debug message
501                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> pr&uuml;ft, ob die <strong>%s</strong> (Typ:<strong>%s</strong>) gebaut werden kann.<br />\n",
502                         __CLASS__,
503                         __LINE__,
504                         $this->getCompanyName(),
505                         $contractInstance->getShipName(),
506                         $shipInstance->getPartDescr()
507                 ));
508
509                 // Now check if the ship type is in any list and return the result
510                 return ($this->isShipTypeConstructable($shipType));
511         }
512
513         // Is the ship type constructable?
514         public function isShipTypeConstructable ($shipType) {
515                 // The type must be a string!
516                 $shipType = (string) $shipType;
517
518                 // Debug message
519                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> fragt alle Werften ab, ob diese Schiffe vom Typ <strong>%s</strong> bauen k&ouml;nnen.<br />\n",
520                         __CLASS__,
521                         __LINE__,
522                         $this->getCompanyName(),
523                         $shipType
524                 ));
525
526                 // First everthing is failed...
527                 $result = false;
528
529                 // Iterate through all shipyards
530                 for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) {
531                         // Get current Shipyard instance
532                         $shipyard = $idx->current();
533
534                         // Is this a shipyard?
535                         if (is_null($shipyard)) {
536                                 // Opps! Empty list?
537                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
538                         } elseif (!is_object($shipyard)) {
539                                 // Not an object! ;-(
540                                 throw new NoObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
541                         } elseif (!$shipyard->isSameClass("Shipyard")) {
542                                 // Class is not a shipyard
543                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
544                         }
545
546                         // Validate if the first found shipyard can construct the requested type
547                         $result = $shipyard->isShipTypeConstructable($shipType);
548
549                         // Does this shipyard construct the requested ship type?
550                         if ($result) break; // Then abort the search!
551                 }
552
553                 // Debug message
554                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat die Suche nach einer Werft beendet, die Schiffe vom Typ <strong>%s</strong> bauen kann.<br />\n",
555                         __CLASS__,
556                         __LINE__,
557                         $this->getCompanyName(),
558                         $shipType
559                 ));
560
561                 // Return result
562                 return $result;
563         }
564
565         // As a customer the shipping company can add new contracts
566         public function addNewWorksContract (SignableContract $contractInstance) {
567                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erstellt einen Bauauftrag f&uuml;r ein <strong>%s</strong> mit dem Namen <strong>%s</strong>.<br />\n",
568                         __CLASS__,
569                         __LINE__,
570                         $this->getCompanyName(),
571                         $contractInstance->getShipInstance()->getPartDescr(),
572                         $contractInstance->getShipInstance()->getShipName()
573                 ));
574                 $this->contractList->append($contractInstance);
575         }
576
577         // As a customer the shippng company can withdraw from a contract
578         public function withdrawFromContract (SignableContract $contractInstance) {
579                 ApplicationEntryPoint::app_die("WITHDRAW:<pre>".print_r($contractInstance, true)."</pre>");
580         }
581
582         // Get latest added contract instance
583         public final function getLastContractInstance () {
584                 // Get iterator
585                 $iter = $this->contractList->getIterator();
586
587                 // Get latest entry (total - 1)
588                 $iter->seek($iter->count() - 1);
589
590                 // Return entry
591                 return $iter->current();
592         }
593
594         // Sign a contract with an other party which must also implement Customer
595         public function signContract (SignableContract $contractInstance, ContractPartner $partnerInstance) {
596                 // Check wether the other party is our contract partner
597                 if (!$partnerInstance->isContractPartner($contractInstance)) {
598                         // Invalid contract partner!
599                         throw new InvalidContractPartnerException($partnerInstance, self::EXCEPTION_CONTRACT_PARTNER_INVALID);
600                 }
601
602                 // Determine if company "signs" own contract (must be done) or with an other party
603                 if ($this->equals($partnerInstance)) {
604                         // With itself
605                         if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> erteilt an sich selbst einen Bauauftrag f&uuml;r das <strong>%s</strong> &quot;<strong>%s</strong>&quot;.<br />\n",
606                                 __CLASS__,
607                                 __LINE__,
608                                 $this->getCompanyName(),
609                                 $contractInstance->getShipInstance()->getPartDescr(),
610                                 $contractInstance->getShipInstance()->getShipName()
611                         ));
612                 } else {
613                         // Other external company
614                         if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Die Reederei <strong>%s</strong> unterzeichnet einen Bauauftrag f&uuml;r das <strong>%s</strong> &quot;<strong>%s</strong>&quot; mit der <strong>%s</strong>.<br />\n",
615                                 __CLASS__,
616                                 __LINE__,
617                                 $this->getCompanyName(),
618                                 $contractInstance->getShipInstance()->getPartDescr(),
619                                 $contractInstance->getShipInstance()->getShipName(),
620                                 $partnerInstance->getCompanyName()
621                         ));
622                 }
623
624                 // Sign the contract
625                 $contractInstance->signContract($this, $partnerInstance);
626
627                 /**
628                  * @todo        Maybe do something more here...
629                  */
630         }
631
632         // Is this the right contract partner?
633         public function isContractPartner (SignableContract $contractInstance) {
634                 // Get contract partner instance and compare it with $this contract partner
635                 return ($this->equals($contractInstance->getContractPartner()));
636         }
637
638         // Setter for merchant instance
639         public final function setMerchantInstance (Merchant $merchantInstance) {
640                 // Get contract
641                 $contractInstance = $this->getLastContractInstance();
642
643                 if (is_null($contractInstance)) {
644                         // Opps! Empty contract instance?
645                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
646                 } elseif (!is_object($contractInstance)) {
647                         // Not an object! ;-(
648                         throw new NoObjectException($contractInstance, self::EXCEPTION_IS_NO_OBJECT);
649                 } elseif (!$contractInstance->isSameClass('WorksContract')) {
650                         // Is not a merchant
651                         throw new ClassMismatchException(array($contractInstance->__toString(), "WorksContract"), self::EXCEPTION_CLASSES_NOT_MATCHING);
652                 }
653
654                 // Set the merchant in the contract (for getting prices)
655                 $contractInstance->setMerchantInstance($merchantInstance);
656         }
657
658         /**
659          * Stub!
660          */
661         public function saveObjectToDatabase () {
662                 $this->getDebugInstance()->output(sprintf("[%s:] Stub <strong>%s</strong> erreicht.",
663                         $this->__toString(),
664                         __FUNCTION__
665                 ));
666         }
667
668         /**
669          * Limits this object with an ObjectLimits instance
670          */
671         public function limitObject (ObjectLimits $limitInstance) {
672                 ApplicationEntryPoint::app_die("".__METHOD__." reached! Stub!");
673         }
674 }
675
676 // [EOF]
677 ?>