5 * Copyright (c) 2002-2009, Sebastian Bergmann <sb@sebastian-bergmann.de>.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * * Neither the name of Sebastian Bergmann nor the names of his
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
39 * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
40 * @copyright 2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
41 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43 * @link http://www.phpunit.de/
44 * @since File available since Release 2.3.0
47 require_once 'IMoney.php';
48 require_once 'Money.php';
55 * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
56 * @copyright 2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
57 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
58 * @version Release: 3.3.17
59 * @link http://www.phpunit.de/
60 * @since Class available since Release 2.3.0
62 class MoneyBag implements IMoney
64 protected $fMonies = array();
66 public static function create(IMoney $m1, IMoney $m2)
68 $result = new MoneyBag;
69 $m1->appendTo($result);
70 $m2->appendTo($result);
72 return $result->simplify();
75 public function add(IMoney $m)
77 return $m->addMoneyBag($this);
80 public function addMoney(Money $m)
82 return MoneyBag::create($m, $this);
85 public function addMoneyBag(MoneyBag $s)
87 return MoneyBag::create($s, $this);
90 public function appendBag(MoneyBag $aBag)
92 foreach ($aBag->monies() as $aMoney) {
93 $this->appendMoney($aMoney);
97 public function monies()
99 return $this->fMonies;
102 public function appendMoney(Money $aMoney)
104 if ($aMoney->isZero()) {
108 $old = $this->findMoney($aMoney->currency());
111 $this->fMonies[] = $aMoney;
115 $keys = array_keys($this->fMonies);
118 for ($i = 0; $i < $max; $i++) {
119 if ($this->fMonies[$keys[$i]] === $old) {
120 unset($this->fMonies[$keys[$i]]);
125 $sum = $old->add($aMoney);
127 if ($sum->isZero()) {
131 $this->fMonies[] = $sum;
134 public function equals($anObject)
136 if ($this->isZero() &&
137 $anObject instanceof IMoney) {
138 return $anObject->isZero();
141 if ($anObject instanceof MoneyBag) {
142 if (count($anObject->monies()) != count($this->fMonies)) {
146 foreach ($this->fMonies as $m) {
147 if (!$anObject->contains($m)) {
158 protected function findMoney($currency)
160 foreach ($this->fMonies as $m) {
161 if ($m->currency() == $currency) {
169 protected function contains(Money $m)
171 $found = $this->findMoney($m->currency());
173 if ($found == NULL) {
177 return $found->amount() == $m->amount();
180 public function hashCode()
184 foreach ($this->fMonies as $m) {
185 $hash ^= $m->hashCode();
191 public function isZero()
193 return count($this->fMonies) == 0;
196 public function multiply($factor)
198 $result = new MoneyBag;
201 foreach ($this->fMonies as $m) {
202 $result->appendMoney($m->multiply($factor));
209 public function negate()
211 $result = new MoneyBag;
213 foreach ($this->fMonies as $m) {
214 $result->appendMoney($m->negate());
220 protected function simplify()
222 if (count($this->fMonies) == 1) {
223 return array_pop($this->fMonies);
229 public function subtract(IMoney $m)
231 return $this->add($m->negate());
234 public function toString()
238 foreach ($this->fMonies as $m) {
239 $buffer .= $m->toString();
242 return $buffer . '}';
245 public function appendTo(MoneyBag $m)
247 $m->appendBag($this);