3 * The work constract class which can be used for contract parties
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright(c) 2007, 2008 Roland Haeder, this is free software
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class WorksContract extends BaseFrameworkSystem implements SignableContract {
25 // Zukuenftiger Schiffsname
26 private $shipName = "";
28 // Instanz zum Schiffstypen
29 private $shipInstance = null;
32 private $contractPartner = null;
34 // Other contract partner
35 private $contractParty = null;
37 // Is the contract signed?
38 private $signed = false;
41 private $merchantInstance = null;
44 protected function __construct () {
45 // Call parent constructor
46 parent::__construct(__CLASS__);
49 $this->setObjectDescription("Bauvertrag");
51 // Unique-ID generieren
52 $this->generateUniqueId();
55 $this->removeSystemArray();
58 // Neuen Bauvertrag generieren
59 public final static function createWorksContract ($shipType, $shipName, ContractPartner $partnerInstance) {
61 $shipType = (string) $shipType;
62 $shipName = (string) $shipName;
65 $contractInstance = new WorksContract();
67 // Debug-Meldung ausgeben
68 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $contractInstance->getDebugInstance()->output(sprintf("[%s:%d] Neuer Bauvertrag wird für das Schiff <strong>%s</strong> mit der <strong>%s</strong> <strong>%s</strong> erstellt.<br />\n",
72 $partnerInstance->getObjectDescription(),
73 $partnerInstance->getCompanyName()
76 // Schiffsnamen setzen
77 $contractInstance->setShipName($shipName);
79 // Existiert die Klasse ueberhaupt?
80 if (!class_exists($shipType)) {
81 // Klasse nicht gefunden
82 throw new ClassNotFoundException ($shipType, self::EXCEPTION_CLASS_NOT_FOUND);
85 // Schiff-Instanz temporaer erzeugen und in den Bauvertrag einfuegen
86 $shipInstance = ObjectFactory::createObjectByName($shipType, array($shipName));
87 $contractInstance->setShipInstance($shipInstance);
89 // Remove the ship instance
92 // Set itself as contract partner
93 $contractInstance->setContractPartner($partnerInstance);
95 // Instanz zurueckgeben
96 return $contractInstance;
99 // Setter for ship instance
100 private final function setShipInstance (ConstructableShip $shipInstance) {
101 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",
104 $shipInstance->getShipName()
106 $this->shipInstance = $shipInstance;
109 // Setter for ship name
110 private final function setShipName ($shipName) {
111 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Das neue Schiff wird <strong>%s</strong> heissen.<br />\n",
116 $this->shipName = (string) $shipName;
119 // Getter for ship name
120 public final function getShipName () {
121 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiffsname <strong>%s</strong> angefordert.<br />\n",
126 return $this->shipName;
129 // Getter for ship instance
130 public final function getShipInstance () {
131 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Schiff-Instanz angefordert.<br />\n",
135 return $this->shipInstance;
138 // Add detail to the contract
139 public function addContractDetails ($shipPart, $parentPart, array $dataArray) {
141 $shipPart = (string) $shipPart;
142 $parentPart = (string) $parentPart;
145 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",
152 // Initialize the instance (shall not be done within dynamic part)
153 $partInstance = null;
155 // Try to get an instance for this ship part
157 $partInstance = ObjectFactory::createObjectByName($shipPart, $dataArray);
158 } catch (DimNotFoundInArrayException $e) {
159 $this->getDebugInstance()->output(sprintf("[main:] Die <strong>%s</strong> konnte nicht vervollständigt werden. Grund: <strong>%s</strong><br />",
160 $this->getShipInstance()->getShipName(),
165 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] Versuche ein Schiffsteil in den Bauvertrag aufzunehmen.<br />\n",
170 // Is this ship part constructable?
171 if (!$partInstance instanceof ConstructableShipPart) {
172 // Ship part not constructable!
173 throw new ShipPartNotConstructableException(array($shipPart), self::EXCEPTION_NOT_CONSTRUCTABLE);
174 } elseif (!$this->getShipInstance()->createShipPart($partInstance, $parentPart)) {
175 // Schiff konnte nicht gebaut werden!
176 throw new ShipNotConstructedException(sprintf("Das Schiff <strong>%s</strong> konnte wegen eines Fehlers nicht gebaut werden. Siehe obere Meldungen.",
177 $this->getShipInstance()->getShipName()
180 } catch (ClassNotFoundException $e) {
182 throw new ClassNotFoundException($e->getMessage(), $e->getCode());
185 // Get price for this item
186 $price = $this->getMerchantInstance()->getPriceFromList($partInstance);
188 // Final debug message
189 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> kostet <strong>%s</strong>.<br />\n",
192 $partInstance->getObjectDescription(),
193 $this->getMerchantInstance()->formatCurrency($price)
197 $partInstance->setPrice($price);
199 // Final debug message
200 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) $this->getDebugInstance()->output(sprintf("[%s:%d] <strong>%s</strong> wurde in den Bauvertrag aufgenommen.<br />\n",
203 $partInstance->getObjectDescription()
207 // Setter for contract partner
208 public final function setContractPartner (ContractPartner $partnerInstance) {
209 $this->contractPartner = $partnerInstance;
212 // Getter for contract partner
213 public final function getContractPartner () {
214 return $this->contractPartner;
217 // Setter for contract party
218 public final function setContractParty (ContractPartner $partyInstance) {
219 $this->contractParty = $partyInstance;
222 // Getter for contract party
223 public final function getContractParty () {
224 return $this->contractParty;
227 // Setter for signature
228 public final function setSigned ($signed) {
229 $this->signed = (boolean) $signed;
232 // Getter for signature
233 public function isSigned () {
234 return $this->signed;
238 public function signContract (ContractPartner $partnerInstance, ContractPartner $partyInstance) {
239 // Is this contract already signed?
240 if ($this->isSigned()) {
241 // Throw an exception
242 throw new ContractAllreadySignedException(array($this, $this->getContractPartner(), $this->getContractParty()), self::EXCEPTION_CONTRACT_ALREADY_SIGNED);
245 // Is the first contract partner still the same?
246 if ($partnerInstance->equals($this->getContractPartner())) {
247 // Set contract party (other partner is already set)
248 $this->setContractParty($partyInstance);
251 $this->setSigned(true);
253 // Throw an exception
254 throw new ContractPartnerMismatchException(array($this, $this->getContractPartner(), $partyInstance), self::EXCEPTION_CONTRACT_PARTNER_MISMATCH);
258 if ((defined('DEBUG_CONTRACT')) || (defined('DEBUG_ALL'))) {
259 if ($partnerInstance->equals($partyInstance)) {
261 $this->getDebugInstance()->output(sprintf("[%s:%d] Die <strong>%s</strong> <em><strong>%s</strong></em> stimmt einem Bauvertrag über das <strong>%s</strong> <em><strong>%s</strong></em> zu.<br />\n",
264 $partnerInstance->getObjectDescription(),
265 $partnerInstance->getCompanyName(),
266 $this->getShipInstance()->getObjectDescription(),
267 $this->getShipInstance()->getShipName()
270 // Other contract party
271 $this->getDebugInstance()->output(sprintf("[%s:%d] Die <strong>%s</strong> <em><strong>%s</strong></em> geht mit der <strong>%s</strong> <em><strong>%s</strong></em> einen Bauvertrag über das <strong>%s</strong> <em><strong>%s</strong></em> ein.<br />\n",
274 $partnerInstance->getObjectDescription(),
275 $partnerInstance->getCompanyName(),
276 $partyInstance->getObjectDescription(),
277 $partyInstance->getCompanyName(),
278 $this->getShipInstance()->getObjectDescription(),
279 $this->getShipInstance()->getShipName()
285 // Setter for merchant instance
286 public final function setMerchantInstance (Merchant $merchantInstance) {
287 $this->merchantInstance = $merchantInstance;
290 // Getter for merchant instance
291 public final function getMerchantInstance () {
292 return $this->merchantInstance;
295 // Getter for total price
296 public final function getTotalPrice () {
298 $shipInstance = $this->getShipInstance();
301 if (is_null($shipInstance)) {
302 // Opps! Empty partner instance?
303 throw new NullPointerException($shipInstance, self::EXCEPTION_IS_NULL_POINTER);
304 } elseif (!is_object($shipInstance)) {
305 // Not an object! ;-(
306 throw new NoObjectException($shipInstance, self::EXCEPTION_IS_NO_OBJECT);
307 } elseif (!$shipInstance instanceof ConstructableShip) {
308 // Does not have the required feature (method)
309 throw new ShipIsInvalidException(array($shipInstance), self::EXCEPTION_INVALID_SHIP_INSTANCE);
312 // Get the structure array
313 $struct = $shipInstance->getStructuresArray();
316 if (is_null($struct)) {
317 // Opps! Empty partner instance?
318 throw new EmptyStructuresListException($this, self::EXCEPTION_EMPTY_STRUCTURES_ARRAY);
324 // Iterate through the list
325 for ($iter = $struct->getIterator(); $iter->valid(); $iter->next()) {
327 $item = $iter->current();
330 if (is_null($item)) {
331 // Opps! Empty partner instance?
332 throw new NullPointerException($item, self::EXCEPTION_IS_NULL_POINTER);
333 } elseif (!is_object($item)) {
334 // Not an object! ;-(
335 throw new NoObjectException($item, self::EXCEPTION_IS_NO_OBJECT);
336 } elseif (!method_exists($item, 'getPartInstance')) {
337 // Does not have the required feature (method)
338 throw new MissingMethodException(array($item, 'getPartInstance'), self::EXCEPTION_MISSING_METHOD);
342 $part = $item->getPartInstance();
345 if (is_null($part)) {
346 // Opps! Empty partner instance?
347 throw new NullPointerException($part, self::EXCEPTION_IS_NULL_POINTER);
348 } elseif (!is_object($part)) {
349 // Not an object! ;-(
350 throw new NoObjectException($part, self::EXCEPTION_IS_NO_OBJECT);
351 } elseif (!method_exists($part, 'getPrice')) {
352 // Does not have the required feature (method)
353 throw new MissingMethodException(array($part, 'getPrice'), self::EXCEPTION_MISSING_METHOD);
356 // Get price for one item
357 $price = $part->getPrice();
359 // Is there numCabin() available?
360 if (method_exists($item, 'getNumCabin')) {
361 // Get total cabin and multiply it with the price
362 $price = $price * $item->getNumCabin();
365 // Add price to total price
366 $totalPrice += $price;
369 // Total price calculated?
370 if ($totalPrice === 0) {
372 throw new TotalPriceNotCalculatedException($this, self::EXCEPTION_TOTAL_PRICE_NOT_CALCULATED);
375 // Return total price