Cart work for payments and Paypal work to test
This commit is contained in:
@@ -11,8 +11,14 @@
|
||||
* @license http://dev.leenooks.net/license.html
|
||||
*/
|
||||
class Cart {
|
||||
public static function instance() {
|
||||
return new Cart;
|
||||
private $id = NULL;
|
||||
|
||||
public function __construct($id=NULL) {
|
||||
$this->id = is_null($id) ? Session::instance()->id() : $id;
|
||||
}
|
||||
|
||||
public static function instance($id=NULL) {
|
||||
return new Cart($id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -20,7 +26,34 @@ class Cart {
|
||||
*/
|
||||
public function contents() {
|
||||
return ORM::factory('Cart')
|
||||
->where('session_id','=',Session::instance()->id());
|
||||
->where('session_id','=',$this->id)
|
||||
->find_all();
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
foreach (ORM::factory('Cart')->where('session_id','=',$this->id)->find_all() as $co)
|
||||
$co->delete();
|
||||
}
|
||||
|
||||
public function get($mid,$item) {
|
||||
return ORM::factory('Cart')
|
||||
->where('session_id','=',$this->id)
|
||||
->and_where('module_id','=',$mid)
|
||||
->and_where('module_item','=',$item)
|
||||
->find_all();
|
||||
}
|
||||
|
||||
public function id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function total($format=FALSE) {
|
||||
$total = 0;
|
||||
|
||||
foreach ($this->contents() as $cio)
|
||||
$total += $cio->item()->t;
|
||||
|
||||
return $format ? Currency::display($total) : $total;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,8 +62,10 @@ class Cart {
|
||||
* @param bool $detail List a detailed cart or a summary cart
|
||||
*/
|
||||
public function cart_block() {
|
||||
// @todo To implement.
|
||||
return '';
|
||||
// If the cart is empty, we'll return here.
|
||||
if (! $this->contents()->count_all())
|
||||
if (! count($this->contents()))
|
||||
return 'The cart is empty.';
|
||||
|
||||
Style::add(array(
|
||||
@@ -39,7 +74,7 @@ class Cart {
|
||||
));
|
||||
|
||||
$output = '<table class="cart_blocklist" border="0">';
|
||||
foreach ($this->contents()->find_all() as $item) {
|
||||
foreach ($this->contents() as $item) {
|
||||
$ppa = $item->product->get_price_array();
|
||||
$pdata = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
|
||||
|
||||
@@ -58,48 +93,5 @@ class Cart {
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if the cart has some trial options
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function has_trial() {
|
||||
foreach ($this->contents()->find_all() as $item)
|
||||
if ($item->product->is_trial())
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public function subtotal() {
|
||||
$total = 0;
|
||||
|
||||
foreach ($this->contents()->find_all() as $item) {
|
||||
$ppa = $item->product->get_price_array();
|
||||
$period = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
|
||||
|
||||
$total += $item->quantity*$ppa[$item->recurr_schedule]['price_base']*$period['prorata'];
|
||||
$total += $item->quantity*$ppa[$item->recurr_schedule]['price_setup'];
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Tax for the cart items
|
||||
*
|
||||
* @return unknown_type
|
||||
* @uses Tax
|
||||
*/
|
||||
public function tax() {
|
||||
// @todo Tax zone should come from somewhere else
|
||||
return Tax::detail(61,NULL,$this->subtotal());
|
||||
}
|
||||
|
||||
public function total() {
|
||||
// @todo Tax zone should come from somewhere else
|
||||
return $this->subtotal()+Tax::total(61,NULL,$this->subtotal());
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
37
modules/cart/classes/Cart/Item.php
Normal file
37
modules/cart/classes/Cart/Item.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides a Cart Item
|
||||
*
|
||||
* @package OSB
|
||||
* @subpackage Cart
|
||||
* @category Helpers
|
||||
* @author Deon George
|
||||
* @copyright (c) 2010 Deon George
|
||||
* @license http://dev.leenooks.net/license.html
|
||||
*/
|
||||
class Cart_Item {
|
||||
// Quantity
|
||||
private $q = 0;
|
||||
// Item
|
||||
private $i = 0;
|
||||
// Total
|
||||
private $t = 0;
|
||||
|
||||
public function __construct($q,$i,$t) {
|
||||
$this->q = $q;
|
||||
$this->i = $i;
|
||||
$this->t = $t;
|
||||
}
|
||||
|
||||
public function __get($key) {
|
||||
switch($key) {
|
||||
case 'i':
|
||||
case 'q': return $this->{$key};
|
||||
case 't': return Currency::display($this->{$key});
|
||||
|
||||
default: throw new Kohana_Exception('Unknown Key :key',array(':key',$key));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
19
modules/cart/classes/Cartable.php
Normal file
19
modules/cart/classes/Cartable.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This interface ensures that all cart processing objects have the right methods
|
||||
*
|
||||
* @package OSB
|
||||
* @subpackage Cart
|
||||
* @category Helpers
|
||||
* @author Deon George
|
||||
* @copyright (c) 2010 Deon George
|
||||
* @license http://dev.leenooks.net/license.html
|
||||
*/
|
||||
interface Cartable {
|
||||
// Render a cart line item.
|
||||
public function cart_item();
|
||||
// Return if this invoice is already in the cart
|
||||
public function cart_exists();
|
||||
}
|
||||
?>
|
@@ -12,71 +12,56 @@
|
||||
*/
|
||||
class Controller_Cart extends Controller_TemplateDefault {
|
||||
/**
|
||||
* Default action when called
|
||||
* List the cart contents
|
||||
*/
|
||||
public function action_index() {
|
||||
return $this->action_list();
|
||||
}
|
||||
|
||||
/**
|
||||
* List items in the cart
|
||||
*/
|
||||
public function action_list() {
|
||||
// @todo - this should be a global config item
|
||||
$mediapath = Route::get('default/media');
|
||||
$output = '';
|
||||
$co = Cart::instance();
|
||||
|
||||
// If the cart is empty, we'll return here.
|
||||
if (! Cart::instance()->contents()->count_all())
|
||||
if (! count($co->contents()))
|
||||
Block::add(array(
|
||||
'title'=>_('Empty Cart'),
|
||||
'body'=>_('The cart is empty')
|
||||
));
|
||||
|
||||
else {
|
||||
Style::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'css/cart_contents.css',
|
||||
));
|
||||
Block::add(array(
|
||||
'title'=>_('Cart Items'),
|
||||
'body'=>Table::display(
|
||||
$co->contents(),
|
||||
NULL,
|
||||
array(
|
||||
'item()->q'=>array('label'=>'Quantity'),
|
||||
'item()->i'=>array('label'=>'Item'),
|
||||
'item()->t'=>array('label'=>'Total','class'=>'right'),
|
||||
),
|
||||
array(
|
||||
'type'=>'list',
|
||||
)
|
||||
),
|
||||
));
|
||||
|
||||
$output = Form::open('checkout/noready');
|
||||
foreach (Cart::instance()->contents()->find_all() as $item) {
|
||||
$ppa = $item->product->get_price_array();
|
||||
$pdata = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
|
||||
$checkout = ORM::factory('Checkout')->where_active()->find_all()->as_array();
|
||||
|
||||
$price_box = View::factory('cart/list_pricebox')
|
||||
->set('price_recurring',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_base']))
|
||||
->set('price_firstinvoice',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_base']*$pdata['prorata']))
|
||||
->set('price_setup',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_setup']))
|
||||
->set('item',$item)
|
||||
->set('mediapath',$mediapath);
|
||||
foreach ($co->contents() as $cio)
|
||||
$checkout = array_intersect($checkout,$cio->checkout()->as_array());
|
||||
|
||||
$output .= View::factory('cart/list_item')
|
||||
->set('price_box',$price_box)
|
||||
->set('service_start',$pdata['date'])
|
||||
->set('service_end',$pdata['end'])
|
||||
->set('price_recurring',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_base']))
|
||||
->set('item',$item)
|
||||
->set('mediapath',$mediapath);
|
||||
$payopt = array();
|
||||
foreach ($checkout as $cko)
|
||||
$payopt[$cko->id] = $cko->name;
|
||||
|
||||
// If we are a plugin product, we might need more information
|
||||
// @todo If an admin, show a system message if cart_info doesnt exist.
|
||||
if ($item->product->prod_plugin AND method_exists($item->product->prod_plugin_file,'product_cart') AND Kohana::find_file('views',sprintf('%s/cart_info',strtolower($item->product->prod_plugin_file)))) {
|
||||
$output .= View::factory(sprintf('%s/cart_info',strtolower($item->product->prod_plugin_file)));
|
||||
|
||||
// @todo JS validation will need to verify data before submission
|
||||
}
|
||||
}
|
||||
$output .= '<div>'.Form::submit('submit',_('Checkout')).'</div>';
|
||||
$output .= _('Total amount due for payment').' '.$co->total(TRUE);
|
||||
$output .= Form::open('checkout/before');
|
||||
$output .= Form::select('checkout_id',$payopt);
|
||||
$output .= Form::submit('submit',_('Checkout'));
|
||||
$output .= Form::close();
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('Your Items'),
|
||||
'title'=>_('Payment'),
|
||||
'body'=>$output,
|
||||
));
|
||||
}
|
||||
|
||||
// Suppress our right hand tab
|
||||
$this->template->right = ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,13 +72,10 @@ class Controller_Cart extends Controller_TemplateDefault {
|
||||
|
||||
$cart->session_id = Session::instance()->id();
|
||||
|
||||
if (Auth::instance()->logged_in())
|
||||
$cart->account_id = Auth::instance()->get_user()->id;
|
||||
|
||||
if ($cart->values($_POST)->check())
|
||||
if ($cart->values(Request::current()->post())->check())
|
||||
$cart->save();
|
||||
else
|
||||
echo Kohana::debug($cart->validate()->errors());
|
||||
throw new Kohana_Exception('Unable to add to cart');
|
||||
|
||||
if ($cart->saved())
|
||||
HTTP::redirect('cart/index');
|
||||
@@ -102,10 +84,8 @@ class Controller_Cart extends Controller_TemplateDefault {
|
||||
}
|
||||
|
||||
public function action_empty() {
|
||||
$cart = ORM::factory('Cart')
|
||||
->where('session_id','=',session_id());
|
||||
|
||||
$cart->delete_all();
|
||||
foreach (ORM::factory('Cart')->where('session_id','=',Session::instance()->id())->find_all() as $co)
|
||||
$co->delete();
|
||||
|
||||
$this->template->content = _('Cart Emptied');
|
||||
}
|
||||
|
@@ -18,6 +18,10 @@ class Model_Cart extends ORM_OSB {
|
||||
// Cart doesnt use the update column
|
||||
protected $_updated_column = FALSE;
|
||||
|
||||
protected $_serialize_column = array(
|
||||
'module_data',
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters used to format the display of values into friendlier values
|
||||
*/
|
||||
@@ -26,5 +30,47 @@ class Model_Cart extends ORM_OSB {
|
||||
array('StaticList_RecurSchedule::display',array(':value')),
|
||||
),
|
||||
);
|
||||
|
||||
private $mo;
|
||||
|
||||
public function __construct($id = NULL) {
|
||||
// Load our Model
|
||||
parent::__construct($id);
|
||||
|
||||
// Autoload our Sub Items
|
||||
if ($this->loaded())
|
||||
$this->_load_sub_items();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function _load_sub_items() {
|
||||
$this->mo = ORM::factory('Module',$this->module_id)->instance($this->module_item);
|
||||
|
||||
if (! $this->mo->loaded())
|
||||
throw new Kohana_Exception('Item :item not loaded?',array(':item'=>$this->module_item));
|
||||
}
|
||||
|
||||
public function checkout() {
|
||||
if (! method_exists($this->mo,'checkout'))
|
||||
throw new Kohana_Exception('Module :module doesnt implement checkout?',array(':module'=>get_class($this->mo)));
|
||||
|
||||
return $this->mo->checkout();
|
||||
}
|
||||
|
||||
public function item() {
|
||||
if (! method_exists($this->mo,'cart_item'))
|
||||
throw new Kohana_Exception('Module :module doesnt implement cart_item?',array(':module'=>get_class($this->mo)));
|
||||
|
||||
return $this->mo->cart_item();
|
||||
}
|
||||
|
||||
public function mo() {
|
||||
return $this->mo;
|
||||
}
|
||||
|
||||
public function motype() {
|
||||
return strtolower(preg_replace('/^Model_/','',get_class($this->mo)));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@@ -1,32 +0,0 @@
|
||||
/** Cart Block Contents Style Sheet **/
|
||||
|
||||
table.cart_blocklist {
|
||||
/* margin-left: auto; */
|
||||
/* margin-right: auto; */
|
||||
width: 100%;
|
||||
background-color: #F9F9FA;
|
||||
border: 0px solid #AAAACC;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
table.cart_blocklist tr td.sku {
|
||||
color: #000000;
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
table.cart_blocklist tr td.price {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table.cart_blocklist tr td.schedule {
|
||||
font-size: 60%;
|
||||
}
|
||||
|
||||
table.cart_blocklist tr.submit td {
|
||||
text-align: center;
|
||||
}
|
||||
table.cart_blocklist tr.submit td button {
|
||||
font-size: 60%;
|
||||
font-weight: bold;
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
/** Cart Contents Style Sheet **/
|
||||
|
||||
table.cart_contents {
|
||||
/* margin-left: auto; */
|
||||
/* margin-right: auto; */
|
||||
width: 100%;
|
||||
background-color: #F9F9FA;
|
||||
border: 0px solid #AAAACC;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.title {
|
||||
color: #000000;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.title a {
|
||||
text-decoration: none;
|
||||
color: #0000AA;
|
||||
}
|
||||
|
||||
table.cart_contents tr td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.icon {
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.price_box {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.price_box table.cart_detail_pricebox {
|
||||
width: 100%;
|
||||
background-color: #FAFAFB;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.price_box table.cart_detail_pricebox td.head {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table.cart_contents tr td.price_box table.cart_detail_pricebox td.value {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
/** Checkout Cart Style Sheet **/
|
||||
|
||||
table.checkout_cartlist {
|
||||
/* margin-left: auto; */
|
||||
/* margin-right: auto; */
|
||||
width: 100%;
|
||||
background-color: #F9F9FA;
|
||||
border: 0px solid #AAAACC;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
table.checkout_cartlist tr td.title {
|
||||
color: #000000;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
table.checkout_cartlist tr td.title a {
|
||||
text-decoration: none;
|
||||
color: #0000AA;
|
||||
}
|
||||
|
||||
table.checkout_cartlist tr td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.checkout_cartlist tr td.icon {
|
||||
width: 22px;
|
||||
}
|
||||
|
||||
table.checkout_cartlist tr td.value {
|
||||
font-weight: bold;
|
||||
font-size: 120%;
|
||||
text-align: right;
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
<tr>
|
||||
<td class="sku"><?php echo $item->product->sku; ?></td>
|
||||
<td class="schedule"><?php echo $item->display('recurr_schedule');?></td>
|
||||
<td class="price"><?php echo Currency::display($price_firstinvoice+$price_setup); ?></td>
|
||||
</tr>
|
@@ -1,11 +0,0 @@
|
||||
<!-- @todo Translation required -->
|
||||
<tr>
|
||||
<td colspan="3" class="title"><b><?php echo HTML::anchor(sprintf('product/view/%s',$item->product->id),$item->product->product_translate->find()->name); ?></b></td>
|
||||
<td class="value"><?php echo Currency::display($price_firstinvoice+$price_setup); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Current Service Period:</td>
|
||||
<td><b><?php printf('%s -> %s',$service_start,$service_end);?></b></td>
|
||||
<td> </td>
|
||||
</tr>
|
@@ -1,25 +0,0 @@
|
||||
<table>
|
||||
<!-- @todo This rounding should be a global configuration item -->
|
||||
<tr>
|
||||
<td><?php echo Country::icon($country); ?></td>
|
||||
<td>Cart Sub-Total:</td>
|
||||
<td><?php echo Currency::display($cart->subtotal()); ?></td>
|
||||
</tr>
|
||||
<?php if ($cart->tax()) { ?>
|
||||
<?php foreach ($cart->tax() as $tax) { ?>
|
||||
<!-- @todo This rounding should be a global configuration item -->
|
||||
<!-- @todo Tax details should come from central configuration -->
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Tax (<?php echo $tax['description']; ?>):</td>
|
||||
<td><?php echo Currency::display($tax['amount']); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<!-- @todo This rounding should be a global configuration item -->
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>Cart Total:</td>
|
||||
<td><?php echo Currency::display($cart->total()); ?></td>
|
||||
</tr>
|
||||
</table>
|
@@ -1,17 +0,0 @@
|
||||
<!-- @todo Translation required -->
|
||||
<table class="cart_contents" border="0">
|
||||
<tr>
|
||||
<td colspan="3" class="title"><b><?php echo HTML::anchor(sprintf('product/view/%s',$item->product->id),$item->product->product_translate->find()->name); ?></b></td>
|
||||
<td class="icon"><?php echo HTML::image($mediapath->uri(array('file'=>'img/edit-delete.png')),array('alt'=>_('Remove'))); ?></td>
|
||||
<td rowspan="4" class="price_box"><?php echo $price_box; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td><td>Pricing Structure:</td><td colspan="2"><b><?php echo $item->product->display('price_type'); ?></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td><td>Invoice Frequency:</td><td colspan="2"><b><?php echo $item->display('recurr_schedule'); ?> (<?php echo $price_recurring; ?>)</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td><td>Current Service Period:</td><td><b><?php printf('%s -> %s',$service_start,$service_end); ?></b></td>
|
||||
</tr>
|
||||
</table>
|
@@ -1,27 +0,0 @@
|
||||
<!-- @todo translation needed -->
|
||||
<table class="cart_detail_pricebox" border="0">
|
||||
<tr>
|
||||
<td class="head">Re-Occuring Price</td>
|
||||
<td class="value"><?php echo $price_recurring; ?></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"> </td></tr>
|
||||
<tr>
|
||||
<td class="head">First Invoice</td>
|
||||
<td class="value"><?php echo $price_firstinvoice; ?></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<?php if ($price_setup) { ?>
|
||||
<tr>
|
||||
<td class="head">Setup</td>
|
||||
<td class="value"><?php echo $price_setup; ?></td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<td class="head">Quantity</td><!-- // @todo Quantity cannot be changed -->
|
||||
<td class="value"><?php echo Form::input('quantity',$item->quantity,array('size'=>2,'disabled'=>'disabled')); ?></td>
|
||||
<td class="icon"><?php echo HTML::image($mediapath->uri(array('file'=>'img/accessories-calculator-small.png')),array('alt'=>_('Re-Calc'))); ?></td>
|
||||
</tr>
|
||||
</table>
|
Reference in New Issue
Block a user