Passed
Push — developer ( 5a7d78...6a35f4 )
by Radosław
17:06
created

Vtiger_Discount_InventoryField   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Test Coverage

Coverage 75.93%

Importance

Changes 0
Metric Value
wmc 31
eloc 70
dl 0
loc 155
ccs 41
cts 54
cp 0.7593
rs 9.92
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getDiscountValueByType() 0 16 3
A getDBValue() 0 6 3
A compare() 0 3 2
A getValueForSave() 0 16 6
B validate() 0 17 9
A getEditValue() 0 4 1
A getDiscountValue() 0 15 4
A getDisplayValue() 0 8 3
1
<?php
2
3
/**
4
 * Inventory Discount Field Class.
5
 *
6
 * @package   InventoryField
7
 *
8
 * @copyright YetiForce S.A.
9
 * @license   YetiForce Public License 5.0 (licenses/LicenseEN.txt or yetiforce.com)
10
 * @author    Mariusz Krzaczkowski <[email protected]>
11
 * @author    Radosław Skrzypczak <[email protected]>
12
 */
13
class Vtiger_Discount_InventoryField extends Vtiger_Basic_InventoryField
14
{
15
	/** {@inheritdoc} */
16
	protected $type = 'Discount';
17
	/** {@inheritdoc} */
18
	protected $defaultLabel = 'LBL_DISCOUNT';
19
	/** {@inheritdoc} */
20
	protected $defaultValue = 0;
21
	/** {@inheritdoc} */
22
	protected $columnName = 'discount';
23
	/** {@inheritdoc} */
24
	protected $dbType = 'decimal(28,8) DEFAULT 0';
25
	/** {@inheritdoc} */
26
	protected $customColumn = [
27
		'discountparam' => 'string',
28
	];
29
	/** {@inheritdoc} */
30
	protected $summationValue = true;
31
	/** {@inheritdoc} */
32
	protected $maximumLength = '99999999999999999999';
33
	/** {@inheritdoc} */
34
	protected $customMaximumLength = [
35
		'discountparam' => 255,
36
	];
37
	/** {@inheritdoc} */
38
	protected $purifyType = \App\Purifier::NUMBER;
39
	/** {@inheritdoc} */
40
	protected $customPurifyType = [
41
		'discountparam' => App\Purifier::TEXT,
42
	];
43
44
	/** {@inheritdoc} */
45
	public function getDisplayValue($value, array $rowData = [], bool $rawText = false)
46
	{
47
		$value = \App\Fields\Double::formatToDisplay($value);
48
		if (isset($rowData['currency']) && $currencySymbol = \App\Fields\Currency::getById($rowData['currency'])['currency_symbol'] ?? '') {
49
			$value = \CurrencyField::appendCurrencySymbol($value, $currencySymbol);
0 ignored issues
show
Bug introduced by
$value of type string is incompatible with the type double|integer expected by parameter $currencyValue of CurrencyField::appendCurrencySymbol(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
			$value = \CurrencyField::appendCurrencySymbol(/** @scrutinizer ignore-type */ $value, $currencySymbol);
Loading history...
50
		}
51
52 2
		return $value;
53
	}
54 2
55 2
	/** {@inheritdoc} */
56
	public function getEditValue(array $itemData, string $column = '')
57 2
	{
58
		$value = parent::getEditValue($itemData, $column);
59
		return \App\Fields\Double::formatToDisplay($value, false);
60
	}
61
62
	/** {@inheritdoc} */
63 2
	public function getDBValue($value, ?string $name = '')
64
	{
65 2
		if (!isset($this->dbValue["{$value}"])) {
66 2
			$this->dbValue["{$value}"] = $name === $this->getColumnName() ? App\Fields\Double::formatToDb($value) : $value;
0 ignored issues
show
Bug Best Practice introduced by
The property dbValue does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
67
		}
68
		return $this->dbValue["{$value}"];
69
	}
70
71
	/** {@inheritdoc} */
72 2
	public function validate($value, string $columnName, bool $isUserFormat, $originalValue = null)
73
	{
74
		if ($columnName === $this->getColumnName()) {
75 2
			if ($isUserFormat) {
76 2
				$value = $this->getDBValue($value, $columnName);
77
				if (null !== $originalValue) {
78 2
					$originalValue = $this->getDBValue($originalValue, $columnName);
79
				}
80
			}
81 2
			if ($this->maximumLength < $value || -$this->maximumLength > $value) {
82
				throw new \App\Exceptions\Security("ERR_VALUE_IS_TOO_LONG||$columnName||$value", 406);
83
			}
84
			if (null !== $originalValue && !\App\Validator::floatIsEqualUserCurrencyDecimals($value, $originalValue)) {
85
				throw new \App\Exceptions\Security('ERR_ILLEGAL_FIELD_VALUE||' . ($columnName ?? $this->getColumnName()) . "||{$this->getModuleName()}||$value($originalValue)", 406);
86 2
			}
87
		} elseif (App\TextUtils::getTextLength($value) > $this->customMaximumLength[$columnName]) {
88 2
			throw new \App\Exceptions\Security("ERR_VALUE_IS_TOO_LONG||$columnName||$value", 406);
89 2
		}
90 2
	}
91 2
92 2
	/** {@inheritdoc} */
93 2
	public function getValueForSave(array $item, bool $userFormat = false, string $column = null)
94
	{
95
		if ($column === $this->getColumnName() || null === $column) {
96 2
			$value = 0.0;
97
			if (!\App\Json::isEmpty($item['discountparam'] ?? '')) {
98 2
				$aggregation = $item['discount_aggreg'] ?? \Vtiger_Inventory_Model::getDiscountsConfig('aggregation');
99
				if (\is_numeric($aggregation)) {
100
					$discountParam = \App\Json::decode($item['discountparam']) ?? [];
101
					$totalPrice = static::getInstance($this->getModuleName(), 'TotalPrice')->getValueForSave($item, $userFormat);
102
					$value = $this->getDiscountValue($discountParam, $totalPrice, (int) $aggregation);
103
				}
104
			}
105
		} else {
106
			$value = $userFormat ? $this->getDBValue($item[$column]) : $item[$column];
107
		}
108
		return $value;
109
	}
110 2
111
	/**
112 2
	 * Calculate the discount value.
113 2
	 *
114 2
	 * @param array  $discountParam
115 2
	 * @param float  $totalPrice
116
	 * @param string $mode          0-can not be combined, 1-summary, 2-cascade
117 2
	 *
118 2
	 * @return float
119 2
	 */
120 2
	private function getDiscountValue(array $discountParam, float $totalPrice, int $mode): float
121
	{
122
		$value = $discountValue = 0.0;
0 ignored issues
show
Unused Code introduced by
The assignment to $discountValue is dead and can be removed.
Loading history...
123
		$types = $discountParam['aggregationType'] ?? [];
124 2
		if (!\is_array($types)) {
125
			$types = [$types];
126
		}
127
		foreach ($types as $type) {
128
			$discountValue = $this->getDiscountValueByType($type, $discountParam, $totalPrice);
129
			$value += $discountValue;
130
			if (2 === $mode) {
131
				$totalPrice -= $discountValue;
132
			}
133
		}
134
		return $value;
135
	}
136 2
137
	/**
138 2
	 * Gets the discount by type.
139 2
	 *
140 2
	 * @param string $aggregationType
141 2
	 * @param array  $discountParam
142 2
	 * @param float  $totalPrice
143
	 *
144
	 * @return float
145 2
	 */
146 2
	private function getDiscountValueByType(string $aggregationType, array $discountParam, float $totalPrice): float
147 2
	{
148
		$discountType = $discountParam["{$aggregationType}DiscountType"] ?? 'percentage';
149
		$discount = $discountParam["{$aggregationType}Discount"];
150
		$value = 0.0;
151 2
		switch ($discountType) {
152
			case 'amount':
153
				$value = $discount;
154
				break;
155
			case 'percentage':
156
				$value = $totalPrice * $discount / 100.00;
157
				break;
158
			default:
159
				throw new \App\Exceptions\Security("ERR_ILLEGAL_FIELD_VALUE||discountType||{$discountType}", 406);
160
		}
161
		return $value;
162
	}
163
164
	/** {@inheritdoc} */
165
	public function compare($value, $prevValue, string $column): bool
166
	{
167
		return $column === $this->getColumnName() ? \App\Validator::floatIsEqual((float) $value, (float) $prevValue, 8) : parent::compare($value, $prevValue, $column);
168
	}
169
}
170