More renamed
[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@shipsimu.org>
6  * @version             0.0.0
7  * @copyright   Copyright (c) 2007, 2008 Roland Haeder, 2009 Ship-Simu Developer Team
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.shipsimu.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          * Headquarter harbor instance
42          */
43         private $hqInstance      = null;
44
45         /**
46          * Employed people by this company
47          */
48         private $employeeList    = 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         // Exception constants
66         const EXCEPTION_USER_OWNS_NO_COMPANY = 0x200;
67
68         /**
69          * Protected constructor
70          *
71          * @return      void
72          */
73         protected function __construct () {
74                 // Call parent constructor
75                 parent::__construct(__CLASS__);
76         }
77
78         /**
79          * Creates an instance of this company class or throws an exception if the
80          * given user owns no company.
81          *
82          * @param       $userInstance           A user class
83          * @return      $companyInstance        Prepared company instance
84          * @todo        Add functionality if user participates in a company
85          */
86         public static final function createShippingCompany (ManageableAccount $userInstance) {
87                 // Get new instance
88                 $companyInstance = new ShippingCompany();
89
90                 // Does the given user owns a company?
91                 if ($companyInstance->ifUserParticipatesInCompany($userInstance)) {
92                         // Then do some nasty caching here but don't throw an exception
93                         // because then you will hurt our web helpers... :/
94                         $companyInstance->partialStub("Don&#39;t throw exceptions here.");
95                 } // END - if
96
97                 // Init all lists
98                 $companyInstance->initCompanyLists();
99
100                 // Return instance
101                 return $companyInstance;
102         }
103
104         /**
105          * Checks wether the given user participates in a company
106          *
107          * @param       $userInstance   An instance of a user class
108          * @return      $participates   Wether the user participates at lease in one company
109          */
110         protected function ifUserParticipatesInCompany (ManageableAccount $userInstance)  {
111                 // By default no user owns any company... ;)
112                 $participates = false;
113
114                 // Get a company database wrapper class
115                 $wrapperInstance = ObjectFactory::createObjectByConfiguredName('company_db_wrapper_class', array($this));
116
117                 // Ask the wrapper if this user participates
118                 $participates = $wrapperInstance->ifUserParticipatesInCompany($userInstance);
119
120                 // Get the result instance
121                 $resultInstance = $wrapperInstance->getResultInstance();
122
123                 // Caches the result instance here, if set (we don't the wrapper anymore!)
124                 if ($resultInstance instanceof SearchableResult) {
125                         // Set the result instance
126                         $this->setResultInstance($resultInstance);
127                 } // END - if
128
129                 // Return result
130                 return $participates;
131         }
132
133         /**
134          * Checks wether the current user in registry is the company founder
135          *
136          * @return      $isFounder      Wether the current user is the company founder
137          * @todo        Check if user is company founder
138          */
139         public function ifUserIsFounder () {
140                 // Default is not the founder
141                 $isFounder = false;
142
143                 // Get result instance
144                 $resultInstance = $this->getResultInstance();
145
146                 // Is it set?
147                 if ($resultInstance instanceof SearchableResult) {
148                         // Result found so analyse it
149                         $this->partialStub("Check if user is company founder.");
150                 } // END - if
151
152                 // Return result
153                 return $isFounder;
154         }
155
156         /**
157          * Checks wether the current user in registry is the company owner
158          *
159          * @return      $isOwner        Wether the current user is the company owner
160          * @todo        Check if user is company owner
161          */
162         public function ifUserIsOwner () {
163                 // Default is not the owner
164                 $isOwner = false;
165
166                 // Get result instance
167                 $resultInstance = $this->getResultInstance();
168
169                 // Is it set?
170                 if ($resultInstance instanceof SearchableResult) {
171                         // Result found so analyse it
172                         $this->partialStub("Check if user is company owner.");
173                 } // END - if
174
175                 // Return result
176                 return $isOwner;
177         }
178
179         /**
180          * Checks wether the current user in registry is an employee in this company
181          *
182          * @return      $isOwner        Wether the current user is an employee in this company
183          */
184         public function ifUserIsEmployee () {
185                 // Default is no employee
186                 $isEmployee = false;
187
188                 // Get result instance
189                 $resultInstance = $this->getResultInstance();
190
191                 // Is it set?
192                 if ($resultInstance instanceof SearchableResult) {
193                         // Result found so he is employee
194                         $isEmployee = true;
195                 } // END - if
196
197                 // Return result
198                 return $isEmployee;
199         }
200
201         //------------------------------------------------------------------------------\
202         // Below here is very old code which needs to be translated and changed heavily |
203         //------------------------------------------------------------------------------/
204
205         /**
206          * Intialize all lists
207          *
208          * @return      void
209          * @todo        Maybe we don't need these big lists anymore?! So we can deprecate/remove it
210          */
211         protected function initCompanyLists () {
212                 // Employees
213                 $this->employeeList = new FrameworkArrayObject("FakedEmployeeList");
214
215                 // Ship yards
216                 $this->shipyardList = new FrameworkArrayObject("FakedShipyardList");
217
218                 // Contracts
219                 $this->contractList = new FrameworkArrayObject("FakedContractList");
220         }
221
222         // Setter-Methode fuer Firmennamen
223         public final function setCompanyName ($companyName) {
224                 $this->companyName = (string) $companyName;
225         }
226
227         // Getter-Methode fuer Firmennamen
228         public final function getCompanyName () {
229                 return $this->companyName;
230         }
231
232         // Setter-Methode fuer Firmensitz
233         public final function setHQInstance (Harbor $hqInstance) {
234                 $this->hqInstance = $hqInstance;
235         }
236
237         // Kuerzel setzen
238         private function initShortName () {
239                 // Mindestens eine Leerstelle?
240                 $dummy = explode(" ", $this->getCompanyName());
241                 foreach ($dummy as $part) {
242                         $this->shortName .= substr($part, 0, 1);
243                 } // END - if
244         }
245
246         // Reedereien Werften bauen lassen
247         public function createShipyardInHarbor($shipyardName, Harbor $harborInstance) {
248                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> baut im <strong>%s</strong> eine Werft <strong>%s</strong>.",
249                         __CLASS__,
250                         __LINE__,
251                         $this->getCompanyName(),
252                         $harborInstance->getHarborName(),
253                         $shipyardName
254                 ));
255
256                 // Wird im HQ gebaut?
257                 if ($this->hqInstance->equals($harborInstance)) {
258                         // Die neue Werft wird im HQ gebaut!
259                         $this->hqInstance->addNewShipyardNotify($shipyardName, $this);
260                         // Die Werft drueber in Kenntnis setzen, welcher Reederei sie angehoert
261                 } else {
262                         // Ausserhalb des Heimathafens soll eine Werft gebaut werden
263                         $harborInstance->addNewShipyardNotify($shipyardName, $this);
264                 }
265         }
266
267         // Setter fuer Reederei-Gruender
268         public final function setCompanyFounder(CompanyEmployee $founderInstance) {
269                 $this->founderInstance = $founderInstance;
270         }
271
272         // Getter for founder instance
273         public final function getFounderInstance () {
274                 return $this->founderInstance;
275         }
276
277         // Neue(n) Angestellte(n) in Angestellten-Liste aufnehmen
278         public function addNewEmployee (SimulatorPersonell $employeeInstance) {
279                 $this->employeeList->append($employeeInstance);
280         }
281
282         // Neue Werft in Liste aufnehmen
283         public function addNewShipyard (Shipyard $shipyardInstance) {
284                 $this->shipyardList->append($shipyardInstance);
285         }
286
287         // Neue Mitarbeiter per Zufall einstellen/rekrutieren
288         public function recruitRandomEmployees($amount, SimulatorPersonell $personellInstance) {
289                 // Anzahl Mitarbeiter absichern
290                 $amount = (int) $amount;
291
292                 // Debug-Meldung ausgeben
293                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> stellt per Zufall <strong>%d</strong> neue Mitarbeiter ein.",
294                         __CLASS__,
295                         __LINE__,
296                         $this->getCompanyName(),
297                         $amount
298                 ));
299
300                 // Gesamtanzahl verfuegbarer Erwerbsloser holen
301                 $totalUnemployed = $personellInstance->getAllUnemployed();
302
303                 // Existiert die gewuenschte Anzahl freier Arbeiter? (doppelt geht derzeit nicht)
304                 if ($totalUnemployed < $amount) {
305                         // Reichte nicht aus!
306                         throw new ToMuchEmployeesException(array($amount, $personellInstance->getAllUnemployed()), self::EXCEPTION_NOT_ENOUGTH_UNEMPLOYEES);
307                 } // END - if
308
309                 // Get list for all unemployed people
310                 $list = $personellInstance->getSpecialPersonellList(false); // Should be cached
311
312                 // Get iterator of the list
313                 $iterator = $list->getIterator();
314
315                 // Get the requested amount of personell
316                 for ($idx = 0; $idx < $amount; $idx++) {
317                         $employee = null;
318                         // Is this personl unemployed?
319                         while (is_null($employee) || $employee->isEmployed()) {
320                                 // Generate random number
321                                 $pos = mt_rand(0, ($totalUnemployed - 1)); // Don't remove the -1 here:
322                                 // E.g. 100 entries means latest position is 99...
323
324                                 // Seek for the position
325                                 $iterator->seek($pos);
326
327                                 // Is the current position valid?
328                                 if ($iterator->valid() === false) {
329                                         // Should normally not happen... :(
330                                         throw new StructuresOutOfBoundsException($idx, self::EXCEPTION_INDEX_OUT_OF_BOUNDS);
331                                 } // END - if
332
333                                 // Get current element
334                                 $employee = $iterator->current();
335                         } // END - while
336
337                         // A dummy just for the description and real class
338                         $dummy = CompanyEmployee::createCompanyEmployee("", "", "M", 1970, 1, 1, $employee->isMarried(), 0);
339
340                         // Make this person employed and give him some money to work
341                         $employee->setEmployed(true);
342                         $employee->setRealClass($dummy->__toString());
343                         $employee->increaseSalary((mt_rand(7, 14) * 100)); // Are 700 to 1400 EUR for the begin okay?
344
345                         // Debug message
346                         if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> stellt den/die Angestellte(n) <strong>%s %s</strong> ein.",
347                                 __CLASS__,
348                                 __LINE__,
349                                 $this->getCompanyName(),
350                                 $employee->getSurname(),
351                                 $employee->getFamily()
352                         ));
353
354                         // Add this employee
355                         $this->addNewEmployee($employee);
356                 } // End - for
357
358                 // Cache resetten
359                 $personellInstance->resetCache();
360
361                 // Debug-Meldung ausgeben
362                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat per Zufall <strong>%d</strong> neue Mitarbeiter eingestellt.",
363                         __CLASS__,
364                         __LINE__,
365                         $this->getCompanyName(),
366                         $amount
367                 ));
368         } // End - method
369
370         // Distribute all personells on all shipyards
371         public function distributeAllPersonellOnShipyards () {
372                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> verteilt alle ihre <strong>%d</strong> Mitarbeiter auf alle <strong>%d</strong> Werft(en).",
373                         __CLASS__,
374                         __LINE__,
375                         $this->getCompanyName(),
376                         $this->getTotalEmployee(),
377                         $this->getTotalShipyards()
378                 ));
379
380                 // Do we have some shipyards?
381                 if (is_null($this->shipyardList)) {
382                         // No shipyards created
383                         throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS);
384                 }
385
386                 // Get iterator for shipyards
387                 $shipyardIter = $this->shipyardList->getIterator();
388
389                 // Iterate through all employees
390                 for ($idx = $this->employeeList->getIterator(); $idx->valid(); $idx->next()) {
391                         // Is the shipyard iterator still okay?
392                         if ($shipyardIter->valid() === false) {
393                                 // Rewind to first position
394                                 $shipyardIter->seek(0);
395                         } // END - if
396
397                         // Get Shipyard object
398                         $shipyard = $shipyardIter->current();
399
400                         // Is this a Shipyard object?
401                         if (is_null($shipyard)) {
402                                 // No class returned
403                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
404                         } elseif (!is_object($shipyard)) {
405                                 // Not an object! ;-(
406                                 throw new InvalidObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
407                         } elseif ($shipyard->isClass("Shipyard") === false) {
408                                 // Nope, so throw exception
409                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
410                         }
411
412                         // Add employee to the shipyard
413                         $shipyard->addNewPersonell($idx->current());
414
415                         // Continue to next shipyard
416                         $shipyardIter->next();
417                 }
418         }
419
420         // Getter for total employees
421         public final function getTotalEmployee () {
422                 // Count all...
423                 $total = $this->employeeList->count();
424
425                 // Debug message
426                 if ((defined('DEBUG_COMPANY_EMPLOYEE')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat <strong>%d</strong> Mitarbeiter.",
427                         __CLASS__,
428                         __LINE__,
429                         $this->getCompanyName(),
430                         $total
431                 ));
432
433                 // Return amount
434                 return $total;
435         }
436
437         // Getter for total shipyards
438         public final function getTotalShipyards () {
439                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] F&uuml;r die Reederei <strong>%s</strong> werden die Anzahl der Werften in allen H&auml;fen ermittelt.",
440                         __CLASS__,
441                         __LINE__,
442                         $this->getCompanyName()
443                 ));
444
445                 // Do we have some shipyards?
446                 if (is_null($this->shipyardList)) {
447                         // No shipyards created
448                         throw new NoShipyardsConstructedException($this, self::EXCEPTION_HARBOR_HAS_NO_SHIPYARDS);
449                 }
450
451                 // Get iterator
452                 $total = $this->shipyardList->count();
453
454                 // Debug message
455                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat <strong>%d</strong> Werft(en).",
456                         __CLASS__,
457                         __LINE__,
458                         $this->getCompanyName(),
459                         $total
460                 ));
461
462                 // Return amount
463                 return $total;
464         }
465
466         // Add a ship type (class) to all shipyards
467         public function addShipTypeToAllShipyards ($shipType) {
468                 // Secure strings
469                 $shipType = (string) $shipType;
470
471                 // Is the class there?
472                 if (!class_exists($shipType)) {
473                         // Throw exception
474                         throw new NoClassException($shipType, self::EXCEPTION_CLASS_NOT_FOUND);
475                 }
476
477                 // Create dummy ship
478                 eval(sprintf("\$shipInstance = %s::create%s(\"M/S Dummy\");",
479                         $shipType,
480                         $shipType
481                 ));
482
483                 // Iterate shipyard list
484                 for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) {
485                         // Get current element
486                         $shipyard = $idx->current();
487
488                         // Is this a shipyard?
489                         if (is_null($shipyard)) {
490                                 // Opps! Empty list?
491                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
492                         } elseif (!is_object($shipyard)) {
493                                 // Not an object! ;-(
494                                 throw new InvalidObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
495                         } elseif ($shipyard->isClass("Shipyard") === false) {
496                                 // Class is not a shipyard
497                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
498                         }
499
500                         // Add the new ship type to the shipyard
501                         $shipyard->addNewConstructableShipType($shipType);
502                 } // END - for
503         }
504
505         // Validate the requested ship type with the company if they can construct it
506         public function validateWorksContractShipType (SignableContract $contractInstance) {
507                 // First get the ship type
508                 $shipInstance = $contractInstance->getShipInstance();
509
510                 // Ist there a ship instance?
511                 if (is_null($shipInstance)) {
512                         // Opps! Empty entry?
513                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
514                 } elseif (!is_object($shipInstance)) {
515                         // Not an object! ;-(
516                         throw new InvalidObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
517                 }
518
519                 // Get it's real class name
520                 $shipType = $shipInstance->__toString();
521
522                 // Now check if ship type is in any list and return the result
523                 return ($this->isShipTypeConstructable($shipType));
524         }
525
526         // Is the ship type constructable?
527         public function isShipTypeConstructable ($shipType) {
528                 // The type must be a string!
529                 $shipType = (string) $shipType;
530
531                 // Debug message
532                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> fragt alle Werften ab, ob diese Schiffe vom Typ <strong>%s</strong> bauen k&ouml;nnen.",
533                         __CLASS__,
534                         __LINE__,
535                         $this->getCompanyName(),
536                         $shipType
537                 ));
538
539                 // First everthing is failed...
540                 $result = false;
541
542                 // Iterate through all shipyards
543                 for ($idx = $this->shipyardList->getIterator(); $idx->valid(); $idx->next()) {
544                         // Get current Shipyard instance
545                         $shipyard = $idx->current();
546
547                         // Is this a shipyard?
548                         if (is_null($shipyard)) {
549                                 // Opps! Empty list?
550                                 throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
551                         } elseif (!is_object($shipyard)) {
552                                 // Not an object! ;-(
553                                 throw new InvalidObjectException($shipyard, self::EXCEPTION_IS_NO_OBJECT);
554                         } elseif ($shipyard->isClass("Shipyard") === false) {
555                                 // Class is not a shipyard
556                                 throw new ClassMismatchException(array($shipyard->__toString(), "Shipyard"), self::EXCEPTION_CLASSES_NOT_MATCHING);
557                         }
558
559                         // Validate if first found shipyard can construct the requested type
560                         $result = $shipyard->isShipTypeConstructable($shipType);
561
562                         // Does this shipyard construct the requested ship type?
563                         if ($result) break; // Then abort the search!
564                 } // END - for
565
566                 // Debug message
567                 if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(sprintf("[%s:%d] Die Reederei <strong>%s</strong> hat die Suche nach einer Werft beendet, die Schiffe vom Typ <strong>%s</strong> bauen kann.",
568                         __CLASS__,
569                         __LINE__,
570                         $this->getCompanyName(),
571                         $shipType
572                 ));
573
574                 // Return result
575                 return $result;
576         }
577
578         // As a customer the shipping company can add new contracts
579         public function addNewWorksContract (SignableContract $contractInstance) {
580                 $this->contractList->append($contractInstance);
581         }
582
583         // As a customer the shippng company can withdraw from a contract
584         public function withdrawFromContract (SignableContract $contractInstance) {
585                 ApplicationEntryPoint::app_die("WITHDRAW:<pre>".print_r($contractInstance, true)."</pre>");
586         }
587
588         // Get latest added contract instance
589         public final function getLastContractInstance () {
590                 // Get iterator
591                 $iter = $this->contractList->getIterator();
592
593                 // Get latest entry (total - 1)
594                 $iter->seek($iter->count() - 1);
595
596                 // Return entry
597                 return $iter->current();
598         }
599
600         // Sign a contract with an other party which must also implement Customer
601         public function signContract (SignableContract $contractInstance, ContractPartner $partnerInstance) {
602                 // Check wether the other party is our contract partner
603                 if ($partnerInstance->isContractPartner($contractInstance) === false) {
604                         // Invalid contract partner!
605                         throw new InvalidContractPartnerException($partnerInstance, self::EXCEPTION_CONTRACT_PARTNER_INVALID);
606                 } // END - if
607
608                 // Determine if company "signs" own contract (must be done) or with an other party
609                 if ($this->equals($partnerInstance)) {
610                         // With itself
611                         if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(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;.",
612                                 __CLASS__,
613                                 __LINE__,
614                                 $this->getCompanyName(),
615                                 $contractInstance->getShipInstance()->getObjectDescription(),
616                                 $contractInstance->getShipInstance()->getShipName()
617                         ));
618                 } else {
619                         // Other external company
620                         if ((defined('DEBUG_COMPANY')) || (defined('DEBUG_ALL'))) $this->debugOutput(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>.",
621                                 __CLASS__,
622                                 __LINE__,
623                                 $this->getCompanyName(),
624                                 $contractInstance->getShipInstance()->getObjectDescription(),
625                                 $contractInstance->getShipInstance()->getShipName(),
626                                 $partnerInstance->getCompanyName()
627                         ));
628                 }
629
630                 // Sign the contract
631                 $contractInstance->signContract($this, $partnerInstance);
632
633                 /**
634                  * @todo        Maybe do something more here...
635                  */
636         }
637
638         // Is this the right contract partner?
639         public function isContractPartner (SignableContract $contractInstance) {
640                 // Get contract partner instance and compare it with $this contract partner
641                 return ($this->equals($contractInstance->getContractPartner()));
642         }
643
644         // Setter for merchant instance
645         public final function setMerchantInstance (Merchant $merchantInstance) {
646                 // Get contract
647                 $contractInstance = $this->getLastContractInstance();
648
649                 if (is_null($contractInstance)) {
650                         // Opps! Empty contract instance?
651                         throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
652                 } elseif (!is_object($contractInstance)) {
653                         // Not an object! ;-(
654                         throw new InvalidObjectException($contractInstance, self::EXCEPTION_IS_NO_OBJECT);
655                 } elseif ($contractInstance->isClass("WorksContract") === false) {
656                         // Is not a merchant
657                         throw new ClassMismatchException(array($contractInstance->__toString(), "WorksContract"), self::EXCEPTION_CLASSES_NOT_MATCHING);
658                 }
659
660                 // Set the merchant in the contract (for getting prices)
661                 $contractInstance->setMerchantInstance($merchantInstance);
662         }
663 }
664
665 // [EOF]
666 ?>