`
kirenenko04
  • 浏览: 146343 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

Add check box before cart item

 
阅读更多

需求:

在shopping cart页面 每一个Item 前增加checkobx控件,

让购买者可以选中需要购买的物品。

然后点击购买按钮执行购买流程。

再完成购买或者回到上一页按钮的时候恢复原本的item到购物车内。

 

解决思路:利用临时表存储未选中的item数据。

在完成结算或者取消结算的时候从临时表中恢复数据到正式表。

 

解剖一下相关表结构

magento 关于cart item的表有两个:`sales_flat_quote_item`,`sales_flat_quote_item_option`

这两个表前一个的主见是后一个的外键 item_id 。

为了完成需求我们可以创建两个零时表,针对上面两个表,

另外还要在sales_flat_quote_item中添加一个是否被选中的标记,这些数据库操作通过升级脚本实现:

 

定义升级脚本集成的类:写在<global>下

     <resources>
         <bysoft_mycheckout_setup>
              <setup>
                  <module>Bysoft_Mycheckout</module>
                  <class>Mage_Sales_Model_Mysql4_Setup</class>
              </setup>
         </bysoft_mycheckout_setup>
     </resources>

 增加是否选中状态字段

<?php
$installer = $this;
$installer->startSetup();
$installer->addAttribute(
		'quote_item',
		'selected_item',
		array(
				'type' => 'int', 
				'grid' => false
		)
);

$installer->endSetup(); 

 

增加临时表:

 

<?php
$installer = $this;
$installer->startSetup();
$installer->run("
	create table `bysoft_sales_flat_quote_item` like sales_flat_quote_item;
	create table `bysoft_sales_flat_quote_item_option` like sales_flat_quote_item_option;
    ");
$installer->endSetup(); 

 

 

点击确认选中的item的ajax方法

 

checkbox 控件:

<input <?php if ($_item->getData('selected_item')):?>checked="checked"<?php endif;?> type="checkbox"  item_id="<?php echo $_item->getId();?>"  is_imported="<?php echo $_product->getData('is_imported');?>" name="selectitem[<?php echo $_item->getId();?>]" class="selectitem"  />

 

确认按钮:

 <button type="button" id="select_need_btn" name="select_need_btn" value="empty_cart" title="<?php echo $this->__('Checkout'); ?>" class="button btn-empty" ><span><span><?php echo $this->__('Proceed to Checkout'); ?></span></span></button>
                           

 

前台ajax:

<script>
(function($){
	
	$('.btn-proceed-checkout').hide();
	
	//全选
	$('.select_all_cb').click(function(){
		if (this.checked) {
			$('.selectitem').attr('checked',true);
		} else {
			$('.selectitem').attr('checked',false);
		}
	})
	$('#select_need_btn').click(function(){
		//点击需要结账的按钮。选好复选框。
		var item_id_str = '';
		$('.selectitem:checked').each(function() {
				item_id_str += ($(this).attr('item_id')) + ',';
			})
		if (item_id_str == '') {
			
			alert('<?php echo $this->__('Please check items!');?>');
			
			return ;
			
		}
		$.ajax({   
		    url:'<?php echo $this->getUrl('checkout/cart/selectitem')?>',   
		    type:'post',   
		    data:'item_id_str='+item_id_str,   
		    async : false, //默认为true 异步   
		    error:function(){   
		       alert('error');   
		    },   
		    success:function(data){   
			    if (data == '0') {
				    alert('Please specify only imported or domesitc products');
				    return;
				 } else {
			       $(".item_tbody").html(data);   
			       $('.select_all_cb').attr('checked',false);
			       $('.btn-proceed-checkout').click();
				 }
		    }
		});
		
	})
})(jQuery);  

</script>

 

处理选中的item, 这里有个额外需求。将进口商品和国内商品分开结算,也就是当选中商品既包含国外也包含国内的时候不执行任何操作,返回错误代码0. 如果只选中了国内,或者只选中了进口,就把未选中的数据从数据库备份起来以备之后的回复,然后讲他们从从原生表里删除,重新计算购物车价格:

 

继承声明:

<frontend>
    <routers>
        <checkout>
            <use>standard</use>
            <args>
               <modules>
                  <Super_Awesome before="Mage_Checkout">Bysoft_Mycheckout</Super_Awesome>
               </modules>
            </args>
        </checkout>
    </routers>
</frontend>

 

 

 继承类具体实现:

class Bysoft_Mycheckout_CartController extends Mage_Checkout_CartController
{
	public function selectitemAction(){
		$item_id_str = Mage::app()->getRequest()->getParam('item_id_str');
	    $item_id_arr = explode(',' , $item_id_str);
	    $the_item_ids = array();
	    foreach ($item_id_arr as $key=>$val) {
	    	if ((int)trim($val)!= '0') {
	    		$the_item_ids[] = $item_id_arr[$key] = (int)trim($val);
	    	}
	    }
	    
	    $quote = Mage::getSingleton('checkout/session')->getQuote();
	    $cartItems = $quote->getAllVisibleItems();
	 
        $exists_imported = false;
        $exists_domesitc = false;
        foreach ($cartItems as $item) {
        	if (in_array($item->getId(), $the_item_ids)) {
        		$product_id = $item->getProductId();
        		$product = Mage::getModel('catalog/product')->load($product_id);
        		if ($product->getData('is_imported') == 1) {
        			$exists_imported = true;
        			break;
        		}
        	}
        }
        
        foreach ($cartItems as $item) {
        	if (in_array($item->getId(), $the_item_ids)) {
        		$product_id = $item->getProductId();
        		$product = Mage::getModel('catalog/product')->load($product_id);
        		if ($product->getData('is_imported') == 0) {
        			$exists_domesitc = true;
        			break;
        		}
        	}
        }
        
        if ($exists_imported && $exists_domesitc) {
        	echo 0;
        } else {
        
	       $write = Mage::getSingleton('core/resource')->getConnection('core_write');  
	       $cartData = array();
	        //set staus for quote item
	       $cartHelper = Mage::helper('checkout/cart');
			$items = $cartHelper->getCart()->getItems();
		
	        foreach ($items as $item) {
	        	if (in_array($item->getId(), $the_item_ids) || in_array($item->getData('parent_item_id'),$the_item_ids)) {        		
	        		//需要保留的行
	        		$this->set_selected_item($item->getId(),1);
	        		//从备份表里删除
	        		$this->delete_from_back($item->getId());
	        	} else {
	        		//需要移动的行
	        		$this->set_selected_item($item->getId(),0);
	        		//放入备份表
	        		$this->move_core_to_back($item->getId());
	        	}
	        }
	   
	        //重新计算购物车总价
	        $quote->setTotalsCollectedFlag(false)->collectTotals();
	        $quote->save();

	        $simple_block =  $this->getLayout()->createBlock('checkout/cart_item_renderer');
	        $config_block =  $this->getLayout()->createBlock('checkout/cart_item_renderer_configurable');
	        $group_block = $this->getLayout()->createBlock('checkout/cart_item_renderer_grouped');
	        $html = '';
	        foreach($cartItems as $item) {
	        	if ($item->getData('product_type') == 'simple') {
	        		$block = $simple_block;
	        	} else if ($item->getData('product_type')  == 'configurable') {
	        		$block = $config_block;
	        	} else {
	        		$block = $group_block;
	        	}
	        		$html .= $block->setTemplate('checkout/cart/item/default.phtml')->setItem($item)->toHtml();
	        }
	       
	        if ($exists_domesitc && $exists_imported) {
	        	echo $html;
	        } else {
	        	echo $html;
	        }
        }
	    
	}
	
	protected function _getCart()
	{
		return Mage::getSingleton('checkout/cart');
	}
	
	/**
	 * 移动未选中数据到备份表
	 * @param unknown $item_id
	 */
	public function move_core_to_back($item_id) {
		$write = Mage::getSingleton('core/resource')->getConnection('core_write');
		$sql ="delete  from bysoft_sales_flat_quote_item where item_id = ?";
	    $write->query($sql,array($item_id));
		$sql = "insert into bysoft_sales_flat_quote_item select * from sales_flat_quote_item where item_id = ?";
		$write->query($sql,array($item_id));
		$sql  = "delete from bysoft_sales_flat_quote_item_option where item_id = ?";
		$write->query($sql,array($item_id));
		$sql = "insert into bysoft_sales_flat_quote_item_option select * from sales_flat_quote_item_option where item_id = ?";
		$write->query($sql,array($item_id));
	}
	
	/**
	 * 将item从备份表删除
	 */
	public function delete_from_back($item_id) {
		$write = Mage::getSingleton('core/resource')->getConnection('core_write');
		$sql ="delete  from bysoft_sales_flat_quote_item where item_id = ?";
		$write->query($sql,array($item_id));
		
		$sql  = "delete from bysoft_sales_flat_quote_item_option where item_id = ?";
		$write->query($sql,array($item_id));
	}
	
	/**
	 * 设定Item的选中状态
	 * @param unknown $item_id
	 * @param unknown $status
	 */
	public function set_selected_item($item_id, $status) {
		$write = Mage::getSingleton('core/resource')->getConnection('core_write');
		$sql = "update sales_flat_quote_item set selected_item = ? where item_id = ?";
		$write->query($sql, array($status, $item_id));
	}

 

在完成选择Item之后页面就到了checkout页面。

 

选好支付和shipping之后,有两种步骤。

 

第一种是返回上一页。恢复item到核心表。

public function recover_item() {
		$quote_id = Mage::getSingleton('checkout/session')->getQuoteId();
		$write = Mage::getSingleton('core/resource')->getConnection('core_write');
		
		
		$sql = "insert into sales_flat_quote_item select * from bysoft_sales_flat_quote_item where quote_id = ? and item_id not in (select item_id from sales_flat_quote_item)";
		$write->query($sql, array($quote_id));
		$sql = "insert into sales_flat_quote_item_option select * from bysoft_sales_flat_quote_item_option where item_id in (select item_id from bysoft_sales_flat_quote_item where quote_id = ? ) and option_id not in (select option_id from sales_flat_quote_item_option)";
		$write->query($sql, array($quote_id));
		
		$sql = "delete from bysoft_sales_flat_quote_item_option where item_id  in (select item_id from bysoft_sales_flat_quote_item where quote_id =?)";
		$write->query($sql, array($quote_id));
		
		$sql = "delete from bysoft_sales_flat_quote_item where quote_id = ?";
		 
		$write->query($sql, array($quote_id));
		try {
			$quote = Mage::getSingleton('checkout/session')->getQuote();
			$quote->setTotalsCollectedFlag(false)->collectTotals();
			$quote->save();
		} catch (Exception $e) {
			echo $e->getMessage();
			exit();
		}
	}
	
	public function indexAction(){
		$this->recover_item();
		$cart = $this->_getCart();
		if ($cart->getQuote()->getItemsCount()) {
			$cart->init();
			$cart->save();
		
			if (!$this->_getQuote()->validateMinimumAmount()) {
				$minimumAmount = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())
				->toCurrency(Mage::getStoreConfig('sales/minimum_order/amount'));
		
				$warning = Mage::getStoreConfig('sales/minimum_order/description')
				? Mage::getStoreConfig('sales/minimum_order/description')
				: Mage::helper('checkout')->__('Minimum order amount is %s', $minimumAmount);
		
				$cart->getCheckoutSession()->addNotice($warning);
			}
		}
		
		// Compose array of messages to add
		$messages = array();
		foreach ($cart->getQuote()->getMessages() as $message) {
			if ($message) {
				// Escape HTML entities in quote message to prevent XSS
				$message->setCode(Mage::helper('core')->escapeHtml($message->getCode()));
				$messages[] = $message;
			}
		}
		$cart->getCheckoutSession()->addUniqueMessages($messages);
		
		/**
		 * if customer enteres shopping cart we should mark quote
		 * as modified bc he can has checkout page in another window.
		*/
		$this->_getSession()->setCartWasUpdated(true);
		
		Varien_Profiler::start(__METHOD__ . 'cart_display');
		$this
		->loadLayout()
		->_initLayoutMessages('checkout/session')
		->_initLayoutMessages('catalog/session')
		->getLayout()->getBlock('head')->setTitle($this->__('Shopping Cart'));
		$this->renderLayout();
		Varien_Profiler::stop(__METHOD__ . 'cart_display');
	}
	

 

第二种则是下单,在下单完成后恢复备份表里的数据到核心表

需要覆盖原生OnepageController内的successAction

	
	public function successAction()
	{
		$session = $this->getOnepage()->getCheckout();
		if (!$session->getLastSuccessQuoteId()) {
			$this->_redirect('checkout/cart');
			return;
		}
	
		$lastQuoteId = $session->getLastQuoteId();
		$lastOrderId = $session->getLastOrderId();
		$lastRecurringProfiles = $session->getLastRecurringProfileIds();
		if (!$lastQuoteId || (!$lastOrderId && empty($lastRecurringProfiles))) {
			$this->_redirect('checkout/cart');
			return;
		}
	
		$session->clear();
		
		$this->add_back_cart_item($lastQuoteId);
		
		$this->loadLayout();
		$this->_initLayoutMessages('checkout/session');
		Mage::dispatchEvent('checkout_onepage_controller_success_action', array('order_ids' => array($lastOrderId)));
		$this->renderLayout();
	}
	
	public function add_back_cart_item($old_quote_id) {
	
		// get logged in cusomer id
		$customerAccountNo = Mage::getModel('customer/session')->getCustomer()->getId();
		// load customer object
		$customerObj = Mage::getModel('customer/customer')->load($customerAccountNo);
		// assign this customer to quote object, before any type of magento order, first create quote.
		$quoteObj = Mage::getModel('sales/quote')->assignCustomer($customerObj);
		$quoteObj->setStoreId(Mage::app()->getStore()->getId())->save();
		 
		$new_quote_id = $quoteObj->getData('entity_id');
		 
		Mage::log($quoteObj->getData('entity_id'));
		 
		$write = Mage::getSingleton('core/resource')->getConnection('core_write');
		$sql = "update bysoft_sales_flat_quote_item set quote_id = ? where quote_id=?";
		$write->query($sql, array($new_quote_id, $old_quote_id));
		 
		 
		$sql = "insert into sales_flat_quote_item select * from bysoft_sales_flat_quote_item where quote_id = ?";
		$write->query($sql, array($new_quote_id));
		$sql = "insert into sales_flat_quote_item_option select * from bysoft_sales_flat_quote_item_option where item_id in (select item_id from bysoft_sales_flat_quote_item where quote_id =?)";
		$write->query($sql, array($new_quote_id));
		 
		$quote = Mage::getSingleton('checkout/session')->getQuote();
		$quote->setTotalsCollectedFlag(false)->collectTotals();
		$quote->save();
	}

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics