CurrencyCondition.php 3.63 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
<?php
/**
 * User: thorsten
 * Date: 27.07.16
 * Time: 09:39
 */

namespace Bnet\Cart;


11
use Bnet\Money\Currency;
12
use Bnet\Money\Money;
13
use Bnet\Money\MoneyException;
14
use Bnet\Money\TaxedMoney;
15 16 17

class CurrencyCondition extends Condition {

18 19 20 21 22 23 24 25 26 27
	/**
	 * @var Currency
	 */
	protected $currency;

	/**
	 * @var int tax percentage
	 */
	protected $tax;

28 29 30
	/**
	 * CurrencyCondition constructor.
	 * @param array $args
31 32
	 * @throws MoneyException
	 * @throws Exceptions\InvalidConditionException
33 34
	 */
	public function __construct(array $args) {
35 36 37 38
		if (isset($args['tax'])) {
			$this->tax = $args['tax'];
			unset($args['tax']);
		}
39 40 41 42 43 44 45
		/* when the value is a `TaxedMoney` we use its tax and check if there is a mismatch */
		if (isset($args['value']) && $args['value'] instanceof TaxedMoney) {
			if (isset($this->tax) && $this->tax != $args['value']->tax) {
				throw new MoneyException('The tax of the condition and the value do not match.');
			}
			$this->tax = $args['value']->tax;
		}
46 47 48 49 50
		// remove the "string" validator from the value field
		$this->rules['value'] = 'required';
		parent::__construct($args);
	}

Thorsten Buss's avatar
Thorsten Buss committed
51 52 53 54 55 56 57 58
	/**
	 * apply condition with the given quantity
	 *
	 * @param $totalOrSubTotalOrPrice
	 * @param $conditionValue
	 * @return int
	 */
	protected function applyWithQuantity($totalOrSubTotalOrPrice, $conditionValue, $quantity = 1) {
59
		return $this->getQuantityIndependent()
Thorsten Buss's avatar
Thorsten Buss committed
60 61 62 63
			? $this->apply($totalOrSubTotalOrPrice, $conditionValue)
			: $this->apply($totalOrSubTotalOrPrice, $conditionValue) * $quantity;
	}

64 65 66
	/**
	 * apply condition to total or subtotal
	 *
67
	 * @param Money|int $totalOrSubTotalOrPrice
68 69 70
	 * @return Money
	 */
	public function applyCondition($totalOrSubTotalOrPrice) {
71 72 73
		$totalOrSubTotalOrPrice = $totalOrSubTotalOrPrice instanceof Money
			? $totalOrSubTotalOrPrice->amount()
			: $totalOrSubTotalOrPrice;
74 75 76 77 78 79 80 81 82
		$price = (int)parent::applyCondition($totalOrSubTotalOrPrice);
		return $this->tax
			? new TaxedMoney($price, $this->currency, $this->tax)
			: new Money($price, $this->currency);
	}

	/**
	 * apply condition to total or subtotal
	 *
83
	 * @param Money|int $totalOrSubTotalOrPrice
84 85 86 87
	 * @param int $quantity
	 * @return Money
	 */
	public function applyConditionWithQuantity($totalOrSubTotalOrPrice, $quantity) {
88 89 90
		$totalOrSubTotalOrPrice = $totalOrSubTotalOrPrice instanceof Money
			? $totalOrSubTotalOrPrice->amount()
			: $totalOrSubTotalOrPrice;
91 92 93 94 95 96 97 98 99
		$price = (int)parent::applyConditionWithQuantity($totalOrSubTotalOrPrice, $quantity);
		return $this->tax
			? new TaxedMoney($price, $this->currency, $this->tax)
			: new Money($price, $this->currency);
	}

	/**
	 * get the calculated value of this condition supplied by the subtotal|price
	 *
100
	 * @param Money|int $totalOrSubTotalOrPrice
101 102 103
	 * @return mixed
	 */
	public function getCalculatedValue($totalOrSubTotalOrPrice) {
104 105 106
		$totalOrSubTotalOrPrice = $totalOrSubTotalOrPrice instanceof Money
			? $totalOrSubTotalOrPrice->amount()
			: $totalOrSubTotalOrPrice;
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
		$price = (int)parent::getCalculatedValue($totalOrSubTotalOrPrice);
		return $this->tax
			? new TaxedMoney($price, $this->currency, $this->tax)
			: new Money($price, $this->currency);
	}

	/**
	 * @param Currency $currency
	 */
	public function setCurrency(Currency $currency) {
		$this->currency = $currency;
	}

	/**
	 * @param int $tax tax percentage
	 */
	public function setTax($tax) {
		$this->tax = $tax;
	}
126 127 128 129 130 131 132 133

	/**
	 * removes some arithmetic signs (%,+,-) only
	 *
	 * @param mixed|Money $value
	 * @return mixed
	 */
	protected function cleanValue($value) {
134 135 136
		if ($this->tax && $value instanceof TaxedMoney) {
			return parent::cleanValue($value->amountWithoutTax());
		}
137 138 139
		return parent::cleanValue($value instanceof Money ? $value->amount() : $value);
	}

140
}