Kohana_Model_Brand_Purchase_Shipping::name()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php defined('SYSPATH') OR die('No direct script access.');
2
3
use Clippings\Freezable\FreezableInterface;
4
use Clippings\Freezable\FreezableTrait;
5
6
/**
7
 * @package    openbuildings\shipping
8
 * @author     Ivan Kerin <[email protected]>
9
 * @copyright  (c) 2013 OpenBuildings Ltd.
10
 * @license    http://spdx.org/licenses/BSD-3-Clause
11
 */
12
class Kohana_Model_Brand_Purchase_Shipping extends Jam_Model implements Sellable, FreezableInterface {
13
14
	use FreezableTrait;
15
16
	/**
17
	 * @codeCoverageIgnore
18
	 */
19
	public static function initialize(Jam_Meta $meta)
20
	{
21
		$meta
22
			->associations(array(
23
				'brand_purchase' => Jam::association('belongsto', array('inverse_of' => 'shipping')),
24
				'items' => Jam::association('hasmany', array(
25
					'foreign_model' => 'shipping_item',
26
					'inverse_of' => 'brand_purchase_shipping',
27
					'delete_on_remove' => Jam_Association::DELETE,
28
					'dependent' => Jam_Association::DELETE,
29
				)),
30
			))
31
			->fields(array(
32
				'id' => Jam::field('primary'),
33
				'is_frozen' => Jam::field('boolean')
34
			))
35
			->validator('brand_purchase', 'items', array('present' => TRUE));
36
	}
37
38
	/**
39
	 * Implement Sellable
40
	 * Returns the computed price of all of its items
41
	 * @param  Model_Purchase_Item $item
42
	 * @return Jam_Price
43
	 */
44 2
	public function price_for_purchase_item(Model_Purchase_Item $item)
45
	{
46 2
		return $this->total_price();
47
	}
48
49 1
	public function name()
50
	{
51 1
		return 'Shipping';
52
	}
53
54 2
	public function total_price()
55
	{
56 2
		$total = $this->total_purchase_price();
57 2
		$items = $this->available_items();
58
59 2
		$items = Model_Shipping_Item::filter_discounted_items($items, $total);
60
61
		$groups = Array_Util::group_by($items, function($item){
62 2
			return $item->group_key();
63 2
		});
64
65
		$group_prices = array_map(function($grouped_items) use ($total) {
66 2
			$prices = Model_Shipping_Item::relative_prices($grouped_items);
67 2
			return Jam_Price::sum($prices, $total->currency(), $total->monetary(), $total->display_currency());
68 2
		}, $groups);
69
70 2
		return Jam_Price::sum($group_prices, $total->currency(), $total->monetary(), $total->display_currency());
71
	}
72
73 4
	public function available_items()
74
	{
75
		return array_filter($this->items->as_array(), function($item){
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
76 4
			return ($item->shipping_group AND $item->shipping_group->shipping AND $item->purchase_item);
77 4
		});
78
	}
79
80 1
	public function duplicate()
81
	{
82 1
		$duplicate = Jam::build('brand_purchase_shipping', array(
83 1
			'brand_purchase' => $this->brand_purchase
0 ignored issues
show
Documentation introduced by
The property brand_purchase does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
84
		));
85
86
		// This is needed to counteract inverse_of brand_purchase in brand_purchase_shipping
87 1
		$this->brand_purchase->shipping = $this;
0 ignored issues
show
Documentation introduced by
The property brand_purchase does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
88
89 1
		return $duplicate;
90
	}
91
92 1
	public function items_from(array $purchase_items)
93
	{
94 1
		Array_Util::validate_instance_of($purchase_items, 'Model_Purchase_Item');
95
96
		$purchase_item_ids = array_map(function($purchase_item){ return $purchase_item->id(); }, $purchase_items);
97
98 1
		$items = array();
99
100 1
		foreach ($this->items->as_array() as $index => $item)
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
101
		{
102 1
			if (in_array($item->purchase_item_id, $purchase_item_ids))
103
			{
104 1
				$items[$index] = $item;
105
			}
106
		}
107
108 1
		return $items;
109
	}
110
111
	/**
112
	 * Get the merge of all total_delivery_time ranges from the items
113
	 * By getting the maximum min and max amounts.
114
	 * @return Jam_Range
115
	 */
116 2
	public function total_delivery_time()
117
	{
118
		$times = array_map(function($item){
119 2
			return $item->total_delivery_time();
120 2
		}, $this->items->as_array());
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
121
122 2
		return Jam_Range::merge($times, 'Model_Shipping::format_shipping_time');
123
	}
124
125
	/**
126
	 * Return the day all the items should be shipped
127
	 * @return Jam_Range
128
	 */
129 1
	public function total_shipping_date()
130
	{
131 1
		$paid_at = $this->paid_at();
132 1
		$days = $this->total_delivery_time();
133
134 1
		$from_day = strtotime("{$paid_at} + {$days->min()} weekdays");
135 1
		$to_day = strtotime("{$paid_at} + {$days->max()} weekdays");
136
137 1
		return new Jam_Range(array($from_day, $to_day));
138
	}
139
140
	/**
141
	 * Total price for the purchased items
142
	 * @throws Kohana_Exception If brand_purchase is NULL
143
	 * @return Jam_Price
144
	 */
145 2
	public function total_purchase_price()
146
	{
147
		return $this
148 2
			->get_insist('brand_purchase')
149 2
				->total_price(array('is_payable' => TRUE, 'not' => 'shipping'));
150
	}
151
152
	/**
153
	 * Return the paid at date
154
	 * @return string
155
	 */
156 1
	public function paid_at()
157
	{
158 1
		return $this->get_insist('brand_purchase')->paid_at();
159
	}
160
161
	/**
162
	 * Get the currency to be used in all the calculations
163
	 * @return string
164
	 */
165 2
	public function currency()
166
	{
167
		return $this
168 2
			->get_insist('brand_purchase')
169 2
				->currency();
170
	}
171
172
	/**
173
	 * Get the location to be used in all the calculations
174
	 * @return string
175
	 */
176 2
	public function ship_to()
177
	{
178
		return $this
179 2
			->get_insist('brand_purchase')
180 2
				->get_insist('purchase')
181 2
					->shipping_country();
182
	}
183
184
	/**
185
	 * Get the monetary object to be used in all the calculations
186
	 * @return Monetary
187
	 */
188 2
	public function monetary()
189
	{
190
		return $this
191 2
			->get_insist('brand_purchase')
192 2
				->monetary();
193
	}
194
195
	/**
196
	 * Build Shipping_Items based on purchase items and method, as well as the ship_to() method
197
	 * @param  array                 $purchase_items array of Model_Purchase_Item objects
198
	 * @param  Model_Shipping_Method $method
199
	 * @return $this
200
	 */
201 1
	public function build_items_from(array $purchase_items, Model_Shipping_Method $method = NULL)
202
	{
203 1
		$this->items = $this->new_items_from($purchase_items, $this->ship_to(), $method);
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
$this->ship_to() is of type string, but the function expects a object<Model_Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
204
205 1
		return $this;
206
	}
207
208
	/**
209
	 * Build a single shipping_item and add it to the items of this brand_purchase_shipping.
210
	 * @param  Model_Purchase_Item $purchase_item
211
	 * @param  Model_Shipping_Method              $method
212
	 * @return Model_Brand_Purchase_Shipping
213
	 */
214 2
	public function build_item_from(Model_Purchase_Item $purchase_item, Model_Shipping_Method $method = NULL)
215
	{
216 2
		$this->items []= $this->new_item_from($purchase_item, $this->ship_to(), $method);
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
$this->ship_to() is of type string, but the function expects a object<Model_Location>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
217
218
		// Mark the shipping as changed so it can be properly saved
219 2
		$this->items = $this->items;
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
220
221 2
		return $this;
222
	}
223
224 1
	public function new_items_from(array $purchase_items, Model_Location $location, $method = NULL)
225
	{
226 1
		Array_Util::validate_instance_of($purchase_items, 'Model_Purchase_Item');
227
228 1
		$self = $this;
229
230
		return array_map(function($purchase_item) use ($location, $method, $self) {
231 1
			return $self->new_item_from($purchase_item, $location, $method);
232 1
		}, $purchase_items);
233
	}
234
235 2
	public function update_items_address(Model_Brand_Purchase_Shipping $brand_purchase_shipping)
236
	{
237 2
		foreach ($this->items->as_array() as $item)
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
238
		{
239 2
			$item->update_address($brand_purchase_shipping);
240
		}
241 2
	}
242
243 2
	public function new_item_from(Model_Purchase_Item $purchase_item, Model_Location $location, Model_Shipping_Method $method = NULL)
244
	{
245 2
		$shipping = $purchase_item->get_insist('reference')->shipping();
246
247
		$fields = array(
248 2
			'brand_purchase_shipping' => $this,
249 2
			'purchase_item' => $purchase_item,
250
		);
251
252 2
		return $shipping->new_shipping_item_from($fields, $location, $method);
253
	}
254
255 1
	public function freeze()
256
	{
257 1
		$this->performFreeze();
258 1
		$this->setFrozen(true);
259 1
		return $this;
260
	}
261
262
	public function unfreeze()
263
	{
264
		$this->performUnfreeze();
265
		$this->setFrozen(false);
266
		return $this;
267
	}
268
269
	public function isFrozen()
270
	{
271
		return $this->is_frozen;
0 ignored issues
show
Documentation introduced by
The property is_frozen does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
272
	}
273
274 1
	protected function setFrozen($frozen)
275
	{
276 1
		$this->is_frozen = (bool) $frozen;
0 ignored issues
show
Documentation introduced by
The property is_frozen does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
277
278 1
		return $this;
279
	}
280
281 1
	public function performFreeze()
282
	{
283 1
		$this->freezeCollection();
284
285 1
		return $this;
286
	}
287
288
	public function performUnfreeze()
289
	{
290
		$this->unfreezeCollection();
291
		return $this;
292
	}
293
294 1
	public function freezeCollection()
295
	{
296 1
		foreach ($this->items as $item)
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
297
		{
298 1
			$item->freeze();
299
		}
300 1
	}
301
302
	public function unfreezeCollection()
303
	{
304
		foreach ($this->items as $item)
0 ignored issues
show
Documentation introduced by
The property items does not exist on object<Kohana_Model_Brand_Purchase_Shipping>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
305
		{
306
			$item->unfreeze();
307
		}
308
	}
309
}
310