From 62a14cf68e37204a7c55155c47c672e5a6d67fdc Mon Sep 17 00:00:00 2001 From: Ivan Kerin Date: Wed, 18 Sep 2013 15:07:22 +0300 Subject: [PATCH] add delivery_time calculations, make them freezable --- .../Jam/Behavior/Shippable/Purchase.php | 3 + classes/Kohana/Model/Shipping/Item.php | 41 +++++++++++++ classes/Kohana/Model/Shipping/Method.php | 7 ++- .../Kohana/Model/Store/Purchase/Shipping.php | 17 ++++++ composer.lock | 33 +++++------ tests/test_data/structure.sql | 13 +++-- tests/tests/Model/Shipping/ItemTest.php | 58 +++++++++++++++++++ .../Model/Store/Purchase/ShippingTest.php | 26 +++++++++ 8 files changed, 173 insertions(+), 25 deletions(-) diff --git a/classes/Kohana/Jam/Behavior/Shippable/Purchase.php b/classes/Kohana/Jam/Behavior/Shippable/Purchase.php index f4bf59f..e945c61 100644 --- a/classes/Kohana/Jam/Behavior/Shippable/Purchase.php +++ b/classes/Kohana/Jam/Behavior/Shippable/Purchase.php @@ -22,6 +22,9 @@ public function initialize(Jam_Meta $meta, $name) ->events() ->bind('model.update_items', array($this, 'update_shipping_items')) ->bind('model.filter_items', array($this, 'filter_shipping_items')); + + $behaviors = $meta->behaviors(); + $behaviors['freezable']->_associations[] = 'shipping'; } public function model_call_items_by_shipping_method(Model_Store_Purchase $store_purchase, Jam_Event_Data $data) diff --git a/classes/Kohana/Model/Shipping/Item.php b/classes/Kohana/Model/Shipping/Item.php index 97cf770..229016d 100644 --- a/classes/Kohana/Model/Shipping/Item.php +++ b/classes/Kohana/Model/Shipping/Item.php @@ -14,6 +14,9 @@ class Kohana_Model_Shipping_Item extends Jam_Model { public static function initialize(Jam_Meta $meta) { $meta + ->behaviors(array( + 'freezable' => Jam::behavior('freezable', array('fields' => 'total_delivery_time', 'parent' => 'store_purchase_shipping')), + )) ->associations(array( 'store_purchase_shipping' => Jam::association('belongsto', array('inverse_of' => 'items')), 'purchase_item' => Jam::association('belongsto'), @@ -21,6 +24,7 @@ public static function initialize(Jam_Meta $meta) )) ->fields(array( 'id' => Jam::field('primary'), + 'total_delivery_time' => Jam::field('range'), )) ->validator('purchase_item', 'shipping_group', array('present' => TRUE)); } @@ -236,6 +240,43 @@ public function total_price() return $this->price()->add($additional_items_price); } + /** + * Shipping group's delivery_time + * @return Jam_Range + */ + public function delivery_time() + { + return $this->get_insist('shipping_group')->delivery_time; + } + + /** + * Shipping's processing_time + * @return Jam_Range + */ + public function processing_time() + { + return $this->shipping_insist()->processing_time; + } + + /** + * Return the delivary time min / max days - summed processing and delivery times + * Freezable + * @return Jam_Range + */ + public function total_delivery_time() + { + if ($this->delivery_time) + { + $total_delivery_time = $this->delivery_time; + } + else + { + $total_delivery_time = Jam_Range::sum(array($this->delivery_time(), $this->processing_time())); + } + + return $total_delivery_time; + } + /** * Return additional_items_price() multiplied by quantity() * @return Jam_Price diff --git a/classes/Kohana/Model/Shipping/Method.php b/classes/Kohana/Model/Shipping/Method.php index 59023fa..3b87586 100644 --- a/classes/Kohana/Model/Shipping/Method.php +++ b/classes/Kohana/Model/Shipping/Method.php @@ -15,7 +15,12 @@ public static function initialize(Jam_Meta $meta) { $meta ->associations(array( - 'shipping' => Jam::association('belongsto', array('inverse_of' => 'methods')), + 'store' => Jam::association('belongsto', array('inverse_of' => 'methods')), + 'shippings' => Jam::association('manytomany', array( + 'foreign_key' => 'method_id', + 'join_table' => 'shipping_groups', + 'readonly' => TRUE, + )), 'shipping_groups' => Jam::association('hasmany', array('inverse_of' => 'method')), )) ->fields(array( diff --git a/classes/Kohana/Model/Store/Purchase/Shipping.php b/classes/Kohana/Model/Store/Purchase/Shipping.php index ddee0ba..1a3a213 100644 --- a/classes/Kohana/Model/Store/Purchase/Shipping.php +++ b/classes/Kohana/Model/Store/Purchase/Shipping.php @@ -14,6 +14,9 @@ class Kohana_Model_Store_Purchase_Shipping extends Jam_Model implements Sellable public static function initialize(Jam_Meta $meta) { $meta + ->behaviors(array( + 'freezable' => Jam::behavior('freezable', array('children' => 'items', 'parent' => 'store_purchase')), + )) ->associations(array( 'store_purchase' => Jam::association('belongsto'), 'location' => Jam::association('belongsto'), @@ -39,6 +42,20 @@ public function price(Model_Purchase_Item $item) return Model_Shipping_Item::compute_price($items, $total_price); } + /** + * Get the merge of all total_delivery_time ranges from the items + * By getting the maximum min and max amounts. + * @return Jam_Range + */ + public function total_delivery_time() + { + $times = array_map(function($item){ + return $item->total_delivery_time(); + }, $this->items->as_array()); + + return Jam_Range::merge($times); + } + /** * Total price for the purchased items * @throws Kohana_Exception If store_purchase is NULL diff --git a/composer.lock b/composer.lock index f41d562..5573d2e 100644 --- a/composer.lock +++ b/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "3e8075ec1ede9474fd51c06c31482496", + "hash": "d6f720982ad2db03b31ce6fbd3a56a64", "packages": [ { "name": "composer/installers", @@ -174,25 +174,22 @@ }, { "name": "openbuildings/emp", - "version": "0.1.2", + "version": "0.1.3", "source": { "type": "git", "url": "https://github.com/OpenBuildings/emp.git", - "reference": "22b174e5b301ae7de63383426277bf857aa83169" + "reference": "f54df4f41ce7264813225f93112ff9043d4b00ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/OpenBuildings/emp/zipball/22b174e5b301ae7de63383426277bf857aa83169", - "reference": "22b174e5b301ae7de63383426277bf857aa83169", + "url": "https://api.github.com/repos/OpenBuildings/emp/zipball/f54df4f41ce7264813225f93112ff9043d4b00ae", + "reference": "f54df4f41ce7264813225f93112ff9043d4b00ae", "shasum": "" }, "require": { "ext-curl": "*", "php": ">=5.3.0" }, - "suggest": { - "openbuildings/paypal": "Easy payments with PayPal: ExpressCheckout, AdaptivePayments, subscriptions" - }, "type": "library", "autoload": { "psr-0": { @@ -224,7 +221,7 @@ "money", "payments" ], - "time": "2013-09-02 11:27:01" + "time": "2013-09-16 14:45:22" }, { "name": "openbuildings/flex-storage", @@ -266,16 +263,16 @@ }, { "name": "openbuildings/jam", - "version": "0.4.10", + "version": "0.4.13", "source": { "type": "git", "url": "https://github.com/OpenBuildings/jam.git", - "reference": "99175a3373bf6bba597bac31e95b2712ddbb6ed0" + "reference": "d5310172ed9feabcbc7e332683e9718f3f19d991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/OpenBuildings/jam/zipball/99175a3373bf6bba597bac31e95b2712ddbb6ed0", - "reference": "99175a3373bf6bba597bac31e95b2712ddbb6ed0", + "url": "https://api.github.com/repos/OpenBuildings/jam/zipball/d5310172ed9feabcbc7e332683e9718f3f19d991", + "reference": "d5310172ed9feabcbc7e332683e9718f3f19d991", "shasum": "" }, "require": { @@ -309,7 +306,7 @@ "upload", "validation" ], - "time": "2013-09-05 08:39:03" + "time": "2013-09-18 09:35:48" }, { "name": "openbuildings/jam-auth", @@ -522,12 +519,12 @@ "source": { "type": "git", "url": "https://github.com/OpenBuildings/purchases.git", - "reference": "0274469f0d72d2f99eaedf034562cf9f58341cb4" + "reference": "209ef7ba452c77c36cb4869b9a084891606bd316" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/OpenBuildings/purchases/zipball/0274469f0d72d2f99eaedf034562cf9f58341cb4", - "reference": "0274469f0d72d2f99eaedf034562cf9f58341cb4", + "url": "https://api.github.com/repos/OpenBuildings/purchases/zipball/209ef7ba452c77c36cb4869b9a084891606bd316", + "reference": "209ef7ba452c77c36cb4869b9a084891606bd316", "shasum": "" }, "require": { @@ -567,7 +564,7 @@ "purchase", "store" ], - "time": "2013-09-12 11:03:41" + "time": "2013-09-17 15:13:07" }, { "name": "paypal/rest-api-sdk-php", diff --git a/tests/test_data/structure.sql b/tests/test_data/structure.sql index 16cdfa7..d265a21 100644 --- a/tests/test_data/structure.sql +++ b/tests/test_data/structure.sql @@ -163,14 +163,14 @@ DROP TABLE IF EXISTS `shipping_methods`; CREATE TABLE `shipping_methods` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, - `shipping_id` int(11) UNSIGNED NOT NULL, + `store_id` int(11) UNSIGNED NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `store_purchase_shippings`; CREATE TABLE `store_purchase_shippings` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `store_purchase_shipping_id` int(11) UNSIGNED NOT NULL, + `location_id` int(11) UNSIGNED NOT NULL, `store_purchase_id` int(11) UNSIGNED NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -180,6 +180,7 @@ CREATE TABLE `shipping_items` ( `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `purchase_item_id` int(11) UNSIGNED NOT NULL, `shipping_group_id` int(11) UNSIGNED NOT NULL, + `delivery_time` varchar(100) NOT NULL, `store_purchase_shipping_id` int(11) UNSIGNED NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -283,11 +284,11 @@ VALUES (2,'Green',298.90,1); -INSERT INTO `shipping_methods` (`id`, `name`, `shipping_id`) +INSERT INTO `shipping_methods` (`id`, `name`, `store_id`) VALUES (1,'Post', 0), (2,'Courier', 0), - (3,'Custom', 1); + (3,'Custom', 0); INSERT INTO `shippings` (`id`, `name`, `currency`, `processing_time`, `ships_from_id`, `store_id`) @@ -306,9 +307,9 @@ VALUES (5, '12.00', '2|4', 1, 1, 3), (6, '5.00', '2|3', 2, 1, 3); -INSERT INTO `store_purchase_shippings` (`id`, `store_purchase_id`) +INSERT INTO `store_purchase_shippings` (`id`, `store_purchase_id`, `location_id`) VALUES - (1, 1); + (1, 1, 3); INSERT INTO `shipping_items` (`id`, `store_purchase_shipping_id`, `purchase_item_id`, `shipping_group_id`) VALUES diff --git a/tests/tests/Model/Shipping/ItemTest.php b/tests/tests/Model/Shipping/ItemTest.php index 7202ece..d251f32 100644 --- a/tests/tests/Model/Shipping/ItemTest.php +++ b/tests/tests/Model/Shipping/ItemTest.php @@ -284,6 +284,64 @@ public function test_price() $this->assertEquals(new Jam_Price(7.5091987684914, 'EUR', $monetary), $price); } + /** + * @covers Model_Shipping_Item::delivery_time + */ + public function test_delivery_time() + { + $range = new Jam_Range(array(10, 12)); + + $item = Jam::build('shipping_item', array( + 'shipping_group' => array( + 'delivery_time' => $range, + ), + )); + + $this->assertEquals($range, $item->delivery_time()); + } + + /** + * @covers Model_Shipping_Item::processing_time + */ + public function test_processing_time() + { + $range = new Jam_Range(array(10, 12)); + + $item = Jam::build('shipping_item', array( + 'shipping_group' => array( + 'shipping' => array( + 'processing_time' => $range, + ) + ), + )); + + $this->assertEquals($range, $item->processing_time()); + } + + /** + * @covers Model_Shipping_Item::total_delivery_time + */ + public function test_total_delivery_time() + { + $item = $this->getMock('Model_Shipping_Item', array('processing_time', 'delivery_time'), array('shipping_item')); + + $item + ->expects($this->once()) + ->method('processing_time') + ->will($this->returnValue(new Jam_Range(array(10, 23)))); + + $item + ->expects($this->once()) + ->method('delivery_time') + ->will($this->returnValue(new Jam_Range(array(2, 13)))); + + $this->assertEquals(new Jam_Range(array(12, 36)), $item->total_delivery_time()); + + $item->delivery_time = new Jam_Range(array(4, 5)); + + $this->assertEquals(new Jam_Range(array(4, 5)), $item->total_delivery_time()); + } + /** * @covers Model_Shipping_Item::additional_item_price */ diff --git a/tests/tests/Model/Store/Purchase/ShippingTest.php b/tests/tests/Model/Store/Purchase/ShippingTest.php index be2d29a..aa54dd4 100644 --- a/tests/tests/Model/Store/Purchase/ShippingTest.php +++ b/tests/tests/Model/Store/Purchase/ShippingTest.php @@ -180,4 +180,30 @@ public function test_build_items_from_errors($wrong_object, $expected_exception_ $store_purchase_shipping->build_items_from($purchase_items, $post); } + + /** + * @covers Model_Store_Purchase_Shipping::total_delivery_time + */ + public function test_total_delivery_time() + { + $item1 = $this->getMock('Model_Shipping_Item', array('total_delivery_time'), array('shipping_item')); + + $item1 + ->expects($this->once()) + ->method('total_delivery_time') + ->will($this->returnValue(new Jam_Range(array(10, 23)))); + + $item2 = $this->getMock('Model_Shipping_Item', array('total_delivery_time'), array('shipping_item')); + + $item2 + ->expects($this->once()) + ->method('total_delivery_time') + ->will($this->returnValue(new Jam_Range(array(2, 34)))); + + $shipping = Jam::build('store_purchase_shipping', array( + 'items' => array($item1, $item2), + )); + + $this->assertEquals(new Jam_Range(array(10, 34)), $shipping->total_delivery_time()); + } } \ No newline at end of file