Completed
Push — master ( cc2a69...ef614c )
by Philip
13s
created

Kohana_Model_Shipping::delivery_time()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 4
cts 5
cp 0.8
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
crap 2.032
1
<?php defined('SYSPATH') OR die('No direct script access.');
2
3
/**
4
 * @package    openbuildings\shipping
5
 * @author     Ivan Kerin <[email protected]>
6
 * @copyright  (c) 2013 OpenBuildings Ltd.
7
 * @license    http://spdx.org/licenses/BSD-3-Clause
8
 */
9
class Kohana_Model_Shipping extends Jam_Model {
10
11 4
	public static function format_shipping_time($min, $max)
12
	{
13 4
		if ($min === NULL AND $max === NULL)
14 1
			return '-';
15
16 3
		if ($min == 0 AND $max == 0)
17 1
			return 'same day';
18
19 2
		if ($min == 1 AND $max == 1)
20
			return '1 day';
21
22 2
		return $min == $max ? "{$min} days" : "{$min} - {$max} days";
23
	}
24
25
	/**
26
	 * @codeCoverageIgnore
27
	 */
28
	public static function initialize(Jam_Meta $meta)
29
	{
30
		$meta
31
			->behaviors(array(
32
				'paranoid' => Jam::behavior('paranoid'),
33
			))
34
			->associations(array(
35
				'groups' => Jam::association('hasmany', array(
36
					'foreign_model' => 'shipping_group',
37
					'foreign_key' => 'shipping_id',
38
					'inverse_of' => 'shipping',
39
					'delete_on_remove' => Jam_Association::DELETE,
40
				)),
41
				'methods' => Jam::association('manytomany', array(
42
					'foreign_model' => 'shipping_method',
43
					'association_foreign_key' => 'method_id',
44
					'join_table' => 'shipping_groups',
45
					'readonly' => TRUE,
46
					'join_table_paranoid' => TRUE,
47
				)),
48
				'locations' => Jam::association('manytomany', array(
49
					'foreign_key' => 'shipping_id',
50
					'join_table' => 'shipping_groups',
51
					'join_table_paranoid' => TRUE,
52
					'readonly' => TRUE,
53
				)),
54
				'ships_from' => Jam::association('belongsto', array(
55
					'foreign_model' => 'location',
56
				)),
57
				'brand' => Jam::association('belongsto', array(
58
					'inverse_of' => 'shippings'
59
				)),
60
			))
61
62
			->fields(array(
63
				'id' => Jam::field('primary'),
64
				'model' => Jam::field('polymorphic'),
65
				'name' => Jam::field('string'),
66
				'currency' => Jam::field('string'),
67
			))
68
69
			->validator('name', 'currency', array('present' => TRUE))
70
			->validator('currency', array('currency' => TRUE));
71
	}
72
73
	/**
74
	 * Use this currency throughout all the shipping calculations
75
	 * @return string ISO currency code
76
	 */
77 3
	public function currency()
78
	{
79 3
		return $this->currency;
0 ignored issues
show
Documentation introduced by
The property currency does not exist on object<Kohana_Model_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...
80
	}
81
82 4
	protected function groups_in(Model_Location $location)
83
	{
84 4
		$location = $this->most_specific_location_containing($location);
85
86 4
		if ( ! $location)
87
			return NULL;
88
89
		return array_filter($this->groups->as_array(), function($group) use ($location) {
0 ignored issues
show
Documentation introduced by
The property groups does not exist on object<Kohana_Model_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...
90 4
			return ($group->location_id == $location->id() AND $group->price);
91 4
		});
92
	}
93
94 2
	public function cheapest_group_in(Model_Location $location)
95
	{
96 2
		$groups = $this->groups_in($location);
97
98 2
		if ( ! $groups)
99 1
			return NULL;
100
101 2
		$groups = Model_Shipping_Group::sort_by_price($groups);
102
103 2
		return end($groups);
104
	}
105
106 4
	public function group_for(Model_Location $location, Model_Shipping_Method $method)
107
	{
108 4
		$location = $this->most_specific_location_containing($location);
109
110 4
		if ( ! $location)
111
			return NULL;
112
113 4
		foreach ($this->groups->as_array() as $group)
0 ignored issues
show
Documentation introduced by
The property groups does not exist on object<Kohana_Model_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...
114
		{
115 4
			if ($group->location_id == $location->id() AND $group->method_id == $method->id())
116 4
				return $group;
117
		}
118 1
	}
119
120 1
	public function methods_for($location)
121
	{
122 1
		$groups = $location ? $this->groups_in($location) : $this->groups;
0 ignored issues
show
Documentation introduced by
The property groups does not exist on object<Kohana_Model_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...
123 1
		$methods = array();
124 1
		foreach ($groups as $group)
125
		{
126 1
			$methods[$group->method_id] = $group->method;
127
		}
128 1
		return $methods;
129
	}
130
131 5
	public function ships_to(Model_Location $location)
132
	{
133 5
		return count($this->locations_containing($location)) > 0;
134
	}
135
136 1
	public function total_delivery_time_for(Model_Location $location)
137
	{
138 1
		return $this->delivery_time_for($location);
139
	}
140
141 1
	public function delivery_time_for(Model_Location $location)
142
	{
143 1
		$groups = $this->groups_in($location);
144
145 1
		if ( ! $groups)
146 1
			return NULL;
147
148
		$delivery_times = array_map(function($group) {
149 1
			return $group->delivery_time;
150 1
		}, $groups);
151
152 1
		return Jam_Range::merge($delivery_times, 'Model_Shipping::format_shipping_time');
153
	}
154
155 1
	public function delivery_time()
156
	{
157 1
		$delivery_times = $this->groups->as_array(NULL, 'delivery_time');
0 ignored issues
show
Documentation introduced by
The property groups does not exist on object<Kohana_Model_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...
158
159 1
		if ( ! $delivery_times)
160
			return NULL;
161
162 1
		return Jam_Range::merge(array_filter($delivery_times), 'Model_Shipping::format_shipping_time');
163
	}
164
165 4
	public function locations_containing(Model_Location $location)
166
	{
167
		// Get by unique id (flattening duplicates)
168 4
		$locations = $this->locations->as_array('id');
0 ignored issues
show
Documentation introduced by
The property locations does not exist on object<Kohana_Model_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...
169
170
		return array_filter($locations, function($item) use ($location) {
171 4
			return $item->contains($location);
172 4
		});
173
	}
174
175 4
	public function most_specific_location_containing(Model_Location $location)
176
	{
177 4
		$locations = $this->locations_containing($location);
178
179 4
		usort($locations, function($item_a, $item_b) {
180 4
			return $item_a->depth() - $item_b->depth();
181 4
		});
182
183 4
		return end($locations);
184
	}
185
186 2
	public function new_shipping_item_from(array $fields, Model_Location $location, Model_Shipping_Method $method = NULL)
187
	{
188 2
		$fields['shipping_group'] = $method ? $this->group_for($location, $method) : $this->cheapest_group_in($location);
189
190 2
		return Jam::build('shipping_item', $fields);
191
	}
192
193 1
	public function price_for_location(Model_Location $location)
194
	{
195 1
		$group = $this->cheapest_group_in($location);
196
197 1
		if ( ! $group)
198 1
			return NULL;
199
200 1
		return $group->price;
201
	}
202
203 1
	public function additional_price_for_location(Model_Location $location)
204
	{
205 1
		$group = $this->cheapest_group_in($location);
206
207 1
		if ( ! $group)
208 1
			return NULL;
209
210 1
		return $group->additional_item_price;
211
	}
212
213 1
	public function discount_threshold_for_location(Model_Location $location)
214
	{
215 1
		$group = $this->cheapest_group_in($location);
216
217 1
		if ( ! $group)
218 1
			return NULL;
219
220 1
		return $group->discount_threshold;
221
	}
222
}
223