Problem I am having here is that people go to a Product page, set a quantity on how much they want of that product and add to cart (which than takes them to the cart page). Client wants the ability to go back to the shop/product page if they want to make further changes to that product (honestly this is strange, since they can do this on the cart page, but whatever). But when people go to update the quantity on the product page, instead of updating the quantity, it adds to the existing quantity for that product.
How to get it to update the existing quantity when the quantity has been submitted more than once on the product page? Is there a woocommerce loop that I can take advantage of here?
Thanks guys, I have dug through the plugin and coded the solution below:
add_action('woocommerce_add_to_cart_handler', 'update_product_in_cart', 11, 2);
function update_product_in_cart($p, $q) {
global $woocommerce;
$cartItem = $woocommerce->cart->cart_contents;
$currentProductId = $q->id;
$wCart = $woocommerce->cart->get_cart();
// If cart already exists, and product exists, than remove product, and add the new product to it.
if ($wCart)
{
$cart_item_keys = array_keys($wCart);
foreach($cart_item_keys as $key)
{
foreach($cartItem as $item)
{
$productItemId = $item['product_id'];
if ($productItemId == $currentProductId)
{
// If you want to empty the entire cart...
// $woocommerce->cart->empty_cart();
// If you want to remove just the product from the cart...
$woocommerce->cart->set_quantity($key, 0);
}
}
}
}
// This adds the product to the cart...
return $q;
}
This gets added to functions.php, and basically, if the product id exists in the cart, it removes the product and the return of $q adds in the new product info.
Works a charm!
Related
I want only allow one purchase for each product, so I want to disable the add to cart for the user who already purchased that product.
I've been reading and I think I should use the woocommerce_is_purchasable hook
but I have no idea how to do it, I would appreciate the help, thank you.
Assuming you're talking about simple products*, you can do this by hooking into is_purchasable.
For the logged in customer, the following code gets the product ID's of all past orders. If the current product ID is in that collection, it returns false for is_purchasable.
Add it to the functions.php file of your child theme.
add_filter('woocommerce_is_purchasable', 'preventPurchaseIfAlreadyOrdered', 10, 2);
function preventPurchaseIfAlreadyOrdered($is_purchasable, $product) {
$productId = $product->get_id();
$orderedItemIdArray = getOrdersItemIdsForCurrentUser();
$is_purchasable = !in_array($productId, $orderedItemIdArray);
return $is_purchasable;
}
function getOrdersItemIdsForCurrentUser() {
$orders = wc_get_orders(['author' => get_current_user_id()]);
if (empty($orders)) return;
$orderedItemIdArray = [];
foreach ($orders as $order) {
$items = $order->get_items();
foreach ($items as $item) {
$orderedItemIdArray[] = $item->get_product_id();
}
}
return $orderedItemIdArray;
}
The code has been tested and works.
* for variable products, the selected variation can change without reloading the page, i.e. via Ajax. That process is more involved (but also possible).
My question and code is directly based off of this question -
"
I have a store containing 5 categories. It's multivendor and due to shipping complications, I can only sell products from one specific category ('paint') when they are alone in the cart. So I need to prevent add to cart of any non-paint products when the cart contains paint, and display an error message, and I need to prevent paint products being added to a cart containing any other categories, and disaply an error message.
I've tried to cobble together this code from snippets I've found lying around on Stackoverflow and elsewhere. The logic seems to work in my brain, but when I try to implement the code (through functions.php) it prevents any product from being added to the cart unless the cart is empty."
Link to question -
Prevent add to cart if cart contains a specific category (WooCommerce)
I have checked and modified the accepted answer to suit my needs however it doesnt seem to work at all as i have the same question just related to a different category (ie gas instead of paint), it was my understanding that I would just have to modify the "has_term" function in order to get this to work as it is just a matter of pointing to a particular category?
//*** Prevent mixture of gas and other prods in same cart ***//
function dont_add_gas_to_cart_containing_other($validation, $product_id) {
// Set flag false until we find a product in gas
$cart_has_gas = false;
// Set $cat_check true if a cart item is in gas cat
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
if (has_term('Gas', 'Gas Tanks & Accessories', $product->id)) {
$cart_has_gas = true;
// break because we only need one "true" to matter here
break;
}
}
$product_is_gas = false;
if (has_term('Gas', 'Gas Tanks & Accessories', $product_id)) {
$product_is_gas = true;
}
// Return true if cart empty
if (!WC()->cart->get_cart_contents_count() == 0) {
// If cart contains gas and product to be added is not gas, display error message and return false.
if ($cart_has_gas && !$product_is_gas) {
wc_add_notice('Sorry, you can only purchase Helium Gas products on their own. To purchase this product, please checkout your current cart or empty your cart and try again', 'error');
$validation = false;
}
// If cart contains a product that is not gas and product to be added is gas, display error message and return false.
elseif (!$cart_has_gas && $product_is_gas) {
wc_add_notice('Sorry, you can only purchase Helium Gas products on their own. To purchase this product, please checkout your current cart or empty your cart and try again', 'error');
$validation = false;
}
}
// Otherwise, return true.
return $validation;
}
add_filter('woocommerce_add_to_cart_validation', 'dont_add_gas_to_cart_containing_other', 10, 2);
Because you gave the category name to the function, you must give the function a slug, second parameter should be 'product_cat' and last parameter should be a Product ID.
$product = $cart_item['data'];
if( has_term( 'gas', 'product_cat', $product->get_id() ) ) {
......
}
Hi for a Magento website i need to load a custom attribute in the shopping cart.
i use getmodel function to load the items. but i have no clue how i load the attribute. maybe i haven't configure the attribute right. i have enabled yes for enable on product listing. de attribute code is 'staffel_percentage'. it is just a regular string
also when i change the price per product it doesn't change the subtotal maybe this is because we already change the price for the product on the rest of the website?
maybe it is in the event? i use this event: controller_action_layout_render_before.
this is the code in observer i use for it
$cart = Mage::getModel('checkout/cart')->getQuote(); // Gets the collection of checkout
foreach ($cart->getAllItems() as $item) { // adds all items to $item and does the following code for each item
if ($item->getParentItem()) { // If items is part of a parent
$item = $item->getParentItem(); // Get parentItem;
}
//echo 'ID: '.$item->getProductId().'<br />';
$percentage = 80;// init first percentage
$quantity = $item->getQty(); //quantity
//$staffelstring = loadattribute//loads attribute
//gives the right percentage per quantity
//$staffelarray = explode(';', ^);
//foreach($staffelarray as $staffels){
//$stafel = explode(':', $staffels);
//if($quantity >= $stafel[0]){
//$percentage = $Stafel[1];
//}
//}
$currency = Mage::app()->getStore()->getCurrentCurrencyRate(); // Currencyrate that is used currently
$specialPrice = (($this->CalculatePrice($item) * $currency)* $percentage) / 100; //New prices we want to give the products
if ($specialPrice > 0) { // Check if price isnt lower then 0
$item->setCustomPrice($specialPrice); //Custom Price will have our new price
$item->setOriginalCustomPrice($specialPrice); //Original Custom price will have our new price, if there was a custom price before
$item->getProduct()->setIsSuperMode(true); //set custom prices against the quote item
}
}
You need to load the product right after your first if statement
$product = Mage::getModel('catalog/product')->load($item->getId()); // may be $item->getProductId() instead here
Then on the next line after that you can add some logging statements that will appear in var/log/system.log
Mage::log($product->getData()); // this will output all of the product data and attributes. You will see your custom attribute value here if it is set on this product.
If there is a value set for your product for your custom attribute then you can get it like this
$value = $product->getData('staffel_percentage');
As for the prices changing, not sure how you have the prices set up. You need to set a positive or negative number to add or subtract from the price in the fields found in the parent product configuration page in Catalog > Products > Your product > Associated Products.
See this image for what the section looks like.
When the user selects their quantity and clicks the add to cart button, the item is added to the cart with the correct quantity. However, if the user clicks add to cart again for the same item but with a different quantity, then that will be added to the original quantity.
What I want to happen is the original item quantity to be removed and updated with the new item quantity.
How would this be possible?
Thanks to the help from Lucky Chingi I managed to make it work.
add_filter( 'woocommerce_add_to_cart_validation', 'woo_custom_add_to_cart_before' );
function woo_custom_add_to_cart_before( $cart_item_data ) {
$cart = WC()->instance()->cart;
$id = $_POST['product_id'];
$cart_id = $cart->generate_cart_id($id);
$cart_item_id = $cart->find_product_in_cart($cart_id);
if($cart_item_id){
$cart->set_quantity($cart_item_id,0);
}
return true;
}
I am currently working on the development of a management module Cart on Magento 1.9
I'm stuck on adding a product to my cart (I tried many different things) and that's why I solicits your help.
My module extends the rest API of magento and I have already managed update to my cart (quantity of products) but now I'll wish to add a new product via the POST method.
Of course I'm logged as customer. I defined the creation privileges for this role. (I can do the update without problems)
Here is my code :
protected function _create(array $data){
$store = $this->_getStore();
Mage::app()->setCurrentStore($store->getId());
$cart = Mage::getModel('checkout/cart');
$cart->init();
$productCollection = Mage::getModel('catalog/product')->load(4);
// Add product to cart
$cart->addProduct($productCollection,
array(
'product_id' => $productCollection->getId(),
'qty' => '1'
)
);
// Save cart
$cart->save();
}
In this simple example, I try to add the product id 4 in quantity 1.
My problem is that I have no error in the log, and everything seems to be past. But when I get my cart, there is no product to add...
in return I have a code 200 OK
Do you have any suggestions to help me?
Thanks a lot for your help
regards
I finally found the solution after traveling all internet;)
In fact when you want to reach the cart before checkout, magento uses the definition "Quote" ... Not easy to understand for a beginner on Magento....
So in order to facilitate research of those who are like me had troubles, here is my code to add a new product in the cart (before checkout) :
//$data['entity_id'] = The id of the product you want to add to the cart
//$data['qty'] = The quantity you want to specify
protected function _create(array $data)
{
$store = $this->_getStore();
Mage::app()->setCurrentStore($store->getId());
// Get Customer's ID
$customerID = $this->getApiUser()->getUserId();
// Load quote by Customer
$quote = Mage::getModel('sales/quote')
->loadByCustomer($customerID);
$product = Mage::getModel('catalog/product')
// set the current store ID
->setStoreId(Mage::app()->getStore()->getId())
// load the product object
->load($data['entity_id']);
// Add Product to Quote
$quote->addProduct($product,$data['qty']);
try {
// Calculate the new Cart total and Save Quote
$quote->collectTotals()->save();
} catch (Mage_Core_Exception $e) {
$this->_error($e->getMessage(),Mage_Api2_Model_Server::HTTP_INTERNAL_ERROR);
}
}
I hope this can help someone
Regards
Carniflex