From b2c27dc34f80977e4019ae843e7130a5e03380b0 Mon Sep 17 00:00:00 2001 From: Ben Smith Date: Wed, 30 Sep 2009 11:42:17 +1300 Subject: [PATCH] Added support for postage and packaging costs. --- .../controllers/admin_postage_bands.php | 154 ++++++++++++++++++ .../controllers/admin_product_lines.php | 9 +- modules/basket/controllers/basket.php | 8 +- modules/basket/helpers/basket.php | 15 +- modules/basket/helpers/basket_event.php | 5 + modules/basket/helpers/basket_installer.php | 53 +++++- modules/basket/helpers/postage_band.php | 99 +++++++++++ modules/basket/helpers/product.php | 11 +- modules/basket/libraries/Session_Basket.php | 31 ++++ modules/basket/models/postage_band.php | 26 +++ modules/basket/models/product.php | 2 + modules/basket/module.info | 2 +- .../basket/views/admin_postage_bands.html.php | 70 ++++++++ .../basket/views/admin_product_lines.html.php | 6 + modules/basket/views/confirm_order.html.php | 8 +- modules/basket/views/view_basket.html.php | 8 +- 16 files changed, 485 insertions(+), 22 deletions(-) create mode 100644 modules/basket/controllers/admin_postage_bands.php create mode 100644 modules/basket/helpers/postage_band.php create mode 100644 modules/basket/models/postage_band.php create mode 100644 modules/basket/views/admin_postage_bands.html.php diff --git a/modules/basket/controllers/admin_postage_bands.php b/modules/basket/controllers/admin_postage_bands.php new file mode 100644 index 00000000..f843d0ca --- /dev/null +++ b/modules/basket/controllers/admin_postage_bands.php @@ -0,0 +1,154 @@ +content = new View("admin_postage_bands.html"); + $view->content->postage_bands = ORM::factory("postage_band")->orderby("name")->find_all(); + + print $view; + } + + public function add_postage_band_form() { + print postage_band::get_add_form_admin(); + } + + + public function add_postage_band() { + access::verify_csrf(); + + $form = postage_band::get_add_form_admin(); + $valid = $form->validate(); + $name = $form->add_postage->inputs["name"]->value; + $postage = ORM::factory("postage_band")->where("name", $name)->find(); + if ($postage->loaded) { + $form->add_postage->inputs["name"]->add_error("in_use", 1); + $valid = false; + } + + if ($valid) { + $postage = postage_band::create( + $name, + $form->add_postage->flat_rate->value, + $form->add_postage->per_item->value + ); + + $postage->save(); + message::success(t("Created postage band %postage_name", array( + "postage_name" => html::clean($postage->name)))); + print json_encode(array("result" => "success")); + } else { + print json_encode(array("result" => "error", + "form" => $form->__toString())); + } + } + + public function delete_postage_band_form($id) { + $postage = ORM::factory("postage_band", $id); + if (!$postage->loaded) { + kohana::show_404(); + } + print postage_band::get_delete_form_admin($postage); + } + + public function delete_postage_band($id) { + access::verify_csrf(); + + if ($id == user::active()->id || $id == user::guest()->id) { + access::forbidden(); + } + + $postage = ORM::factory("postage_band", $id); + if (!$postage->loaded) { + kohana::show_404(); + } + + $form = postage_band::get_delete_form_admin($postage); + if($form->validate()) { + $name = $postage->name; + $postage->delete(); + } else { + print json_encode(array("result" => "error", + "form" => $form->__toString())); + } + + $message = t("Deleted user %postage_band", array("postage_band" => html::clean($name))); + log::success("user", $message); + message::success($message); + print json_encode(array("result" => "success")); + } + + public function edit_postage_band($id) { + access::verify_csrf(); + + $postage = ORM::factory("postage_band", $id); + if (!$postage->loaded) { + kohana::show_404(); + } + + $form = postage_band::get_edit_form_admin($postage); + $valid = $form->validate(); + if ($valid) { + $new_name = $form->edit_postage->inputs["name"]->value; + if ($new_name != $postage->name && + ORM::factory("postage_band") + ->where("name", $new_name) + ->where("id !=", $postage->id) + ->find() + ->loaded) { + $form->edit_postage->inputs["name"]->add_error("in_use", 1); + $valid = false; + } else { + $postage->name = $new_name; + } + } + + if ($valid) { + $postage->flat_rate = $form->edit_postage->flat_rate->value; + $postage->per_item = $form->edit_postage->per_item->value; + $postage->save(); + + message::success(t("Changed postage band %postage_name", + array("postage_name" => html::clean($postage->name)))); + print json_encode(array("result" => "success")); + } else { + print json_encode(array("result" => "error", + "form" => $form->__toString())); + } + } + + public function edit_postage_band_form($id) { + $postage = ORM::factory("postage_band", $id); + if (!$postage->loaded) { + kohana::show_404(); + } + + $form = postage_band::get_edit_form_admin($postage); + + print $form; + } + +} \ No newline at end of file diff --git a/modules/basket/controllers/admin_product_lines.php b/modules/basket/controllers/admin_product_lines.php index 1794bc28..f063ad36 100644 --- a/modules/basket/controllers/admin_product_lines.php +++ b/modules/basket/controllers/admin_product_lines.php @@ -51,7 +51,11 @@ class Admin_Product_Lines_Controller extends Controller if ($valid) { $product = product::create( - $name, $form->add_product->cost->value, $form->add_product->description->value); + $name, + $form->add_product->cost->value, + $form->add_product->description->value, + $form->add_product->postage_band->value + ); $product->save(); message::success(t("Created product %product_name", array( @@ -83,7 +87,7 @@ class Admin_Product_Lines_Controller extends Controller kohana::show_404(); } - $form = user::get_delete_form_admin($product); + $form = product::get_delete_form_admin($product); if($form->validate()) { $name = $product->name; $product->delete(); @@ -126,6 +130,7 @@ class Admin_Product_Lines_Controller extends Controller if ($valid) { $product->cost = $form->edit_product->cost->value; $product->description = $form->edit_product->description->value; + $product->postage_band_id = $form->edit_product->postage_band->value; $product->save(); message::success(t("Changed product %product_name", diff --git a/modules/basket/controllers/basket.php b/modules/basket/controllers/basket.php index 270c9ecb..2e85f60c 100644 --- a/modules/basket/controllers/basket.php +++ b/modules/basket/controllers/basket.php @@ -31,7 +31,7 @@ class Basket_Controller extends Controller { print $template; } - private function getCheckoutForm(){ + private function getCheckoutForm(){ $form = new Forge("basket/confirm", "", "post", array("id" => "checkout", "name" =>"checkout")); $group = $form->group("contact")->label(t("Contact Details")); $group->input("fullname")->label(t("Name"))->id("fullname"); @@ -110,6 +110,8 @@ class Basket_Controller extends Controller { $basket = Session_Basket::get(); //$admin_address = basket::getEmailAddress(); + $postage = $basket->postage_cost(); + $product_cost = $basket->cost(); $admin_email = "Order for : ".$basket->name." @@ -121,7 +123,9 @@ class Basket_Controller extends Controller { ".$basket->email." ".$basket->phone." Placed at ".date("d F Y - H:i" ,time())." -Total Owed ".$basket->cost()." in ".basket::getCurrency()." +Cost of Ordered Products = ".$product_cost." +Postage and Packaging Costs + ".$postage." +Total Owed ".($product_cost+$postage)." Total in ".basket::getCurrency()." Items Ordered: diff --git a/modules/basket/helpers/basket.php b/modules/basket/helpers/basket.php index 5e175303..45ab988f 100644 --- a/modules/basket/helpers/basket.php +++ b/modules/basket/helpers/basket.php @@ -42,9 +42,9 @@ class basket_Core { static $format= array( "AUD" => "$", "CAD" => "$", - "EUR" => "€", - "GBP" => "£", - "JPY" => "¥", + "EUR" => "€", + "GBP" => "£", + "JPY" => "¥", "USD" => "$", "NZD" => "$", "CHF" => "", @@ -114,7 +114,7 @@ class basket_Core { } static function formatMoney($money){ - return self::$format[self::getCurrency()].number_format($money); + return self::$format[self::getCurrency()].number_format($money,2); } static function setEmailAddress($email){ @@ -141,6 +141,12 @@ class basket_Core { "; + $postage = $session_basket->postage_cost(); + if ($postage > 0) { + $form = $form." +"; + } + $id = 1; foreach ($session_basket->contents as $key => $basket_item){ $form = $form." @@ -149,6 +155,7 @@ class basket_Core { quantity\"/>"; $id++; } + $form = $form.""; return $form; diff --git a/modules/basket/helpers/basket_event.php b/modules/basket/helpers/basket_event.php index 25b55f28..ade43e96 100644 --- a/modules/basket/helpers/basket_event.php +++ b/modules/basket/helpers/basket_event.php @@ -38,6 +38,11 @@ class basket_event_Core{ ->id("product_line") ->label(t("Product Lines")) ->url(url::site("admin/product_lines"))); + $basket_menu->append( + Menu::factory("link") + ->id("postage_bands") + ->label(t("Postage Bands")) + ->url(url::site("admin/postage_bands"))); } diff --git a/modules/basket/helpers/basket_installer.php b/modules/basket/helpers/basket_installer.php index 7100e76f..c514f4ca 100644 --- a/modules/basket/helpers/basket_installer.php +++ b/modules/basket/helpers/basket_installer.php @@ -21,17 +21,15 @@ class basket_installer { static function install(){ - module::set_version("basket", 1); - } - static function activate() { $db = Database::instance(); $db->query("CREATE TABLE IF NOT EXISTS {products} ( `id` int(9) NOT NULL auto_increment, `name` TEXT NOT NULL, - `cost` INTEGER(9) default 0, + `cost` DECIMAL(10,2) default 0, `description` varchar(1024), + `postage_band_id` int(9) default 1, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); @@ -47,20 +45,57 @@ class basket_installer `product_override_id` int(9) NOT NULL, `product_id` int(9) NOT NULL, `include` BOOLEAN default false, - `cost` INTEGER(9) default -1, + `cost` DECIMAL(10,2) default -1, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - product::create("4x6",5,"4\"x6\" print"); - product::create("8x10",25,"8\"x10\" print"); - product::create("8x12",30,"8\"x12\" print"); + $db->query("CREATE TABLE IF NOT EXISTS {postage_bands} ( + `id` int(9) NOT NULL auto_increment, + `name` TEXT NOT NULL, + `flat_rate` DECIMAL(10,2) default 0, + `per_item` DECIMAL(10,2) default 0, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + + postage_band::create("No Postage",0,0); + + product::create("4x6",5,"4\"x6\" print",1); + product::create("8x10",25,"8\"x10\" print",1); + product::create("8x12",30,"8\"x12\" print",1); + + + module::set_version("basket", 2); } - static function deactivate(){ + static function upgrade($version) { + $db = Database::instance(); + if ($version == 1) { + + // fix for allowing decimel place in money + $db->query("ALTER TABLE {products} CHANGE COLUMN `cost` `cost` DECIMAL(10,2) default 0;"); + $db->query("ALTER TABLE {item_products} CHANGE COLUMN `cost` `cost` DECIMAL(10,2) default -1;"); + + // postage bands + $db->query("ALTER TABLE {products} ADD COLUMN `postage_band_id` int(9) default 1"); + $db->query("CREATE TABLE IF NOT EXISTS {postage_bands} ( + `id` int(9) NOT NULL auto_increment, + `name` TEXT NOT NULL, + `flat_rate` DECIMAL(10,2) default 0, + `per_item` DECIMAL(10,2) default 0, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + postage_band::create("No Postage",0,0); + + module::set_version("basket", $version = 2); + } + } + + static function uninstall(){ $db = Database::instance(); $db->query("DROP TABLE IF EXISTS {products}"); $db->query("DROP TABLE IF EXISTS {product_overrides}"); $db->query("DROP TABLE IF EXISTS {item_products}"); + $db->query("DROP TABLE IF EXISTS {postage_bands}"); } } diff --git a/modules/basket/helpers/postage_band.php b/modules/basket/helpers/postage_band.php new file mode 100644 index 00000000..b69f84c4 --- /dev/null +++ b/modules/basket/helpers/postage_band.php @@ -0,0 +1,99 @@ + "gAddPostageForm")); + $group = $form->group("add_postage")->label(t("Add Postage Band")); + $group->input("name")->label(t("Name"))->id("gPostageName") + ->error_messages("in_use", t("There is already a postage band with that name")); + $group->input("flat_rate")->label(t("Flat Rate"))->id("gFlatRate"); + $group->input("per_item")->label(t("Per Item"))->id("gPetItem"); + $group->submit("")->value(t("Add Postage Band")); + $postage = ORM::factory("postage_band"); + $form->add_rules_from($postage); + return $form; + } + + static function get_edit_form_admin($postage) { + $form = new Forge("admin/postage_bands/edit_postage_band/$postage->id", "", "post", + array("id" => "gEditPostageForm")); + $group = $form->group("edit_postage")->label(t("Edit Postage Band")); + $group->input("name")->label(t("Name"))->id("gPostageName")->value($postage->name); + $group->inputs["name"]->error_messages( + "in_use", t("There is already a postage band with that name")); + $group->input("flat_rate")->label(t("Flat Rate"))->id("gFlatRate")->value($postage->flat_rate); + $group->input("per_item")->label(t("Per Item"))->id("gPetItem")-> + value($postage->per_item); + + $group->submit("")->value(t("Modify Postage Band")); + $form->add_rules_from($postage); + return $form; + } + + + static function get_delete_form_admin($postage) { + $form = new Forge("admin/postage_bands/delete_postage_band/$postage->id", "", "post", + array("id" => "gDeletePostageForm")); + $group = $form->group("delete_postage")->label( + t("Are you sure you want to delete postage band %name?", array("name" => $postage->name))); + $group->submit("")->value(t("Delete postage band %name", array("name" => $postage->name))); + return $form; + } + + /** + * Create a new postage band + * + * @param string $name + * @param string $full_name + * @param string $password + * @return User_Model + */ + static function create($name, $flatrate, $peritemcost) { + $postage = ORM::factory("postage_band")->where("name", $name)->find(); + if ($postage->loaded) { + throw new Exception("@todo postage already EXISTS $name"); + } + + $postage->name = $name; + $postage->flat_rate = $flatrate; + $postage->per_item = $peritemcost; + + $postage->save(); + return $postage; + } + + /** + * returns the array of postage bands + * @return an array of postage bands + */ + static function getPostageArray(){ + $postagea = array(); + + $postages = ORM::factory("postage_band")->find_all(); + foreach ($postages as $postage){ + $show = true; + $postagea[$postage->id] = $postage->name; + } + + return $postagea; + } + +} \ No newline at end of file diff --git a/modules/basket/helpers/product.php b/modules/basket/helpers/product.php index 27d01577..cb4261a0 100644 --- a/modules/basket/helpers/product.php +++ b/modules/basket/helpers/product.php @@ -26,6 +26,9 @@ class product_Core { ->error_messages("in_use", t("There is already a product with that name")); $group->input("cost")->label(t("Cost"))->id("gCost"); $group->input("description")->label(t("Description"))->id("gDescription"); + $group->dropdown("postage_band") + ->label(t("Postage Band")) + ->options(postage_band::getPostageArray()); $group->submit("")->value(t("Add Product")); $product = ORM::factory("product"); $form->add_rules_from($product); @@ -42,6 +45,10 @@ class product_Core { $group->input("cost")->label(t("Cost"))->id("gCost")->value($product->cost); $group->input("description")->label(t("Description"))->id("gDescription")-> value($product->description); + $group->dropdown("postage_band") + ->label(t("Postage Band")) + ->options(postage_band::getPostageArray()) + ->selected($product->postage_band_id); $group->submit("")->value(t("Modify Product")); $form->add_rules_from($product); @@ -66,7 +73,7 @@ class product_Core { * @param string $password * @return User_Model */ - static function create($name, $cost, $description) { + static function create($name, $cost, $description, $postage_band) { $product = ORM::factory("product")->where("name", $name)->find(); if ($product->loaded) { throw new Exception("@todo USER_ALREADY_EXISTS $name"); @@ -75,7 +82,7 @@ class product_Core { $product->name = $name; $product->cost = $cost; $product->description = $description; - + $product->postage_band_id = $postage_band; $product->save(); return $product; } diff --git a/modules/basket/libraries/Session_Basket.php b/modules/basket/libraries/Session_Basket.php index 3aa31f12..11de4db0 100644 --- a/modules/basket/libraries/Session_Basket.php +++ b/modules/basket/libraries/Session_Basket.php @@ -64,6 +64,11 @@ class basket_item return $prod->description; } + public function getProduct(){ + $prod = ORM::factory("product", $this->product); + return $prod; + } + public function getCode(){ $photo = ORM::factory("item", $this->item); $prod = ORM::factory("product", $this->product); @@ -122,6 +127,32 @@ class Session_Basket_Core { unset($this->contents[$key]); } + public function postage_cost(){ + $postage_cost = 0; + $postage_bands = array(); + $postage_quantities = array(); + if (isset($this->contents)){ + // create array of postage bands + foreach ($this->contents as $product => $basket_item){ + $postage_band = $basket_item->getProduct()->postage_band; + if (isset($postage_bands[$postage_band->id])) + { + $postage_quantities[$postage_band->id] += $basket_item->quantity; + } + else + { + $postage_quantities[$postage_band->id] = $basket_item->quantity; + $postage_bands[$postage_band->id] = $postage_band; + } + } + + foreach ($postage_bands as $id => $postage_band){ + $postage_cost += $postage_band->flat_rate + ($postage_band->per_item * $postage_quantities[$id]); + } + } + return $postage_cost; + } + public function cost(){ $cost = 0; if (isset($this->contents)){ diff --git a/modules/basket/models/postage_band.php b/modules/basket/models/postage_band.php new file mode 100644 index 00000000..83eb6e08 --- /dev/null +++ b/modules/basket/models/postage_band.php @@ -0,0 +1,26 @@ + "length[1,32]"); + + protected $has_many=array('products'); + +} diff --git a/modules/basket/models/product.php b/modules/basket/models/product.php index c89c7254..2bd6a59b 100644 --- a/modules/basket/models/product.php +++ b/modules/basket/models/product.php @@ -21,4 +21,6 @@ class Product_Model extends ORM { var $rules = array( "name" => "length[1,32]", "description" => "length[0,255]"); + protected $belongs_to=array('postage_band'); + } diff --git a/modules/basket/module.info b/modules/basket/module.info index 426ff687..5bf1f888 100644 --- a/modules/basket/module.info +++ b/modules/basket/module.info @@ -1,3 +1,3 @@ name = "Shopping Basket" description = "Provides a simple shopping basket and checkout with paypal integration" -version = 1 +version = 2 diff --git a/modules/basket/views/admin_postage_bands.html.php b/modules/basket/views/admin_postage_bands.html.php new file mode 100644 index 00000000..436c2a83 --- /dev/null +++ b/modules/basket/views/admin_postage_bands.html.php @@ -0,0 +1,70 @@ + +
+ + " + class="gDialogLink gButtonLink right ui-icon-left ui-state-default ui-corner-all" + title=""> + + + + +

+ +

+ + + +
\ No newline at end of file diff --git a/modules/basket/views/admin_product_lines.html.php b/modules/basket/views/admin_product_lines.html.php index c543afad..29cca094 100644 --- a/modules/basket/views/admin_product_lines.html.php +++ b/modules/basket/views/admin_product_lines.html.php @@ -37,6 +37,7 @@ + @@ -51,6 +52,11 @@ description) ?> + + postage_band->name) ?> + + + id") ?>" open_text="" diff --git a/modules/basket/views/confirm_order.html.php b/modules/basket/views/confirm_order.html.php index 0f6ebee9..a14305d8 100644 --- a/modules/basket/views/confirm_order.html.php +++ b/modules/basket/views/confirm_order.html.php @@ -52,8 +52,14 @@ function so(){document.confirm.submit();} + postage_cost();?> + 0):?> "> - Total Costcost())?> + Postage and Packaging + + + "> + Total Costcost() + $postage))?> diff --git a/modules/basket/views/view_basket.html.php b/modules/basket/views/view_basket.html.php index e1e51f17..94d9bf4a 100644 --- a/modules/basket/views/view_basket.html.php +++ b/modules/basket/views/view_basket.html.php @@ -88,8 +88,14 @@ + postage_cost();?> + 0):?> "> - Total Cost + Postage and Packaging + + + "> + Total Cost