Passed
Push — master ( 6794ce...eae594 )
by Aimeos
05:31
created

Reduction::calcPrice()   B

Complexity

Conditions 8
Paths 4

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 16
nc 4
nop 1
dl 0
loc 30
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2014
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 * @package MShop
8
 * @subpackage Service
9
 */
10
11
12
namespace Aimeos\MShop\Service\Provider\Decorator;
13
14
15
/**
16
 * Decorator for reduction of service providers prices.
17
 *
18
 * @package MShop
19
 * @subpackage Service
20
 */
21
class Reduction
22
	extends \Aimeos\MShop\Service\Provider\Decorator\Base
23
	implements \Aimeos\MShop\Service\Provider\Decorator\Iface
24
{
25
	private $beConfig = array(
26
		'reduction.percent' => array(
27
			'code' => 'reduction.percent',
28
			'internalcode' => 'reduction.percent',
29
			'label' => 'Decimal value in percent (positive or negative)',
30
			'type' => 'number',
31
			'internaltype' => 'float',
32
			'default' => '',
33
			'required' => true,
34
		),
35
		'reduction.product-costs' => array(
36
			'code' => 'reduction.product-costs',
37
			'internalcode' => 'reduction.product-costs',
38
			'label' => 'Include product costs in reduction calculation',
39
			'type' => 'boolean',
40
			'internaltype' => 'boolean',
41
			'default' => '0',
42
			'required' => false,
43
		),
44
		'reduction.basket-value-min' => array(
45
			'code' => 'reduction.basket-value-min',
46
			'internalcode' => 'reduction.basket-value-min',
47
			'label' => 'Apply decorator over this basket value',
48
			'type' => 'map',
49
			'internaltype' => 'array',
50
			'default' => [],
51
			'required' => false,
52
		),
53
		'reduction.basket-value-max' => array(
54
			'code' => 'reduction.basket-value-max',
55
			'internalcode' => 'reduction.basket-value-max',
56
			'label' => 'Apply decorator up to this basket value',
57
			'type' => 'map',
58
			'internaltype' => 'array',
59
			'default' => [],
60
			'required' => false,
61
		),
62
	);
63
64
65
	/**
66
	 * Checks the backend configuration attributes for validity.
67
	 *
68
	 * @param array $attributes Attributes added by the shop owner in the administraton interface
69
	 * @return array An array with the attribute keys as key and an error message as values for all attributes that are
70
	 * 	known by the provider but aren't valid
71
	 */
72
	public function checkConfigBE( array $attributes )
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
73
	{
74
		$error = $this->getProvider()->checkConfigBE( $attributes );
75
		$error += $this->checkConfig( $this->beConfig, $attributes );
76
77
		return $error;
78
	}
79
80
81
	/**
82
	 * Returns the configuration attribute definitions of the provider to generate a list of available fields and
83
	 * rules for the value of each field in the administration interface.
84
	 *
85
	 * @return array List of attribute definitions implementing \Aimeos\MW\Common\Critera\Attribute\Iface
86
	 */
87
	public function getConfigBE()
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
88
	{
89
		return array_merge( $this->getProvider()->getConfigBE(), $this->getConfigItems( $this->beConfig ) );
90
	}
91
92
93
	/**
94
	 * Returns the price when using the provider.
95
	 * Usually, this is the lowest price that is available in the service item but can also be a calculated based on
96
	 * the basket content, e.g. 2% of the value as transaction cost.
97
	 *
98
	 * @param \Aimeos\MShop\Order\Item\Base\Iface $basket Basket object
99
	 * @return \Aimeos\MShop\Price\Item\Iface Price item containing the price, shipping, rebate
100
	 */
101
	public function calcPrice( \Aimeos\MShop\Order\Item\Base\Iface $basket )
102
	{
103
		$price = $this->getProvider()->calcPrice( $basket );
104
		$total = $basket->getPrice()->getValue() + $basket->getPrice()->getRebate();
105
		$currency = $price->getCurrencyId();
106
		$item = $this->getServiceItem();
107
		$costs = 0;
108
109
		if( ( $val = $item->getConfigValue( 'reduction.basket-value-min/' . $currency ) ) !== null && $val > $total ) {
110
			return $price;
111
		}
112
113
		if( ( $val = $item->getConfigValue( 'reduction.basket-value-max/' . $currency ) ) !== null && $val < $total ) {
114
			return $price;
115
		}
116
117
		if( $item->getConfigValue( 'reduction.product-costs' ) )
118
		{
119
			foreach( $basket->getProducts() as $orderProduct )
120
			{
121
				$costs += $orderProduct->getPrice()->getCosts();
122
123
				foreach( $orderProduct->getProducts() as $subProduct ) {
124
					$costs += $subProduct->getPrice()->getCosts();
125
				}
126
			}
127
		}
128
129
		$sub = ( $price->getCosts() + $costs ) * $item->getConfigValue( 'reduction.percent' ) / 100;
130
		return $price->setRebate( $price->getRebate() + $sub )->setCosts( $price->getCosts() - $sub );
131
	}
132
}