I have the following issue:
I make calculations via jQuery in the frontend and want to add a product to the cart with the price calculated in the frontend.
I already wrote a custom module with an AjaxController to achieve the adding to cart part, but I know struggle with setting the custom price.
My script looks like this:
$_prod = json_decode(Mage::app()->getRequest()->getPost('zapfsaeule_product'));
$id = 347; // there is only this one bundle product added to the cart viar this scipt, so a static id is enough.
$params = array(
'product' => $id,
'related_product' => null,
'bundle_option' => array(
6 => 17, // static options for testing purpouses
5 => 13), //
'qty' => 1 // static qty for testing as well
);
$cart = Mage::getSingleton('checkout/cart');
$product = new Mage_Catalog_Model_Product();
$product->load($id);
$cart->addProduct($product, $params);
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
$this->getResponse()->setBody('true'); // setting response to true, because its an ajax request.
$this->getResponse()->setHeader('Content-type', 'text/plain');
That's the code for adding the product.
For setting the price I tried the approach as mentioned in this thread on stackexchange:
https://magento.stackexchange.com/questions/4318/dynamically-calculated-prices-save-before-add-to-cart
But it didn't work. I guess the event observed here doesn't occur in my case, because I wrote a custom script.
But then there still would be the problem, IF the observer approach would work, how would I pass the calculated price to the observer?
I hope you understand the problem and can help me solve it.
Thanks in advance!
Best regards,
Martin
Reading through Mage_Checkout_Model_Cart::addProduct(), there doesn't appear to be a way to set the item's price from the parameters. Instead, you'll need to add the product, then grab the resulting item, and set its price:
$cart->addProduct($product, $params)
->save();
// grab the corresponding item
$item = $cart->getQuote()->getItemByProduct($product);
// set its custom price
$item->setOriginalCustomPrice($customPrice)
->save();
Haven't had the time to try this out, but it should be the right idea. Make sure that you set the original_custom_price field (using setOriginalCustomPrice()), not one of the other prices. The other prices are recalculated during the totals process.
This comes pretty late, but I just stumbled upon this.
I got it to work like this:
$cart = Mage::getSingleton('checkout/cart');
$cart->addProduct($product, 1); // 1 = qty. Pass your qty and params.
$item = $cart->getQuote()->getItemByProduct($product);
$item->setCustomPrice(0); // or some other value
$item->setOriginalCustomPrice(0); // or some other value
$item->getProduct()->setIsSuperMode(true); // this is crucial
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
If the params don't work, fetch the returned item from $cart->addProduct and change the price on the item before saving the cart.
$item = $cart->addProduct(...);
$item->setCustomPrice(...); {or whatever price attribute you like to set}
$cart->save();
Related
I am getting an empty array from the woocommerce_add_cart_item_data filter when a product is added to the shopping cart. Example added to functions.php of WordPress theme;
function TEST_post_filter($a,$b,$c) {
print_r($a); //THIS IS EMPTY ARRAY ie returns Array()
return $a;
}
add_filter('woocommerce_add_cart_item_data', 'Test_post_filter',10,3);
Any idea why this might be? I have found no reference to this issue anywhere. I have tried both basket behaviours ie Redirect to the basket page after successful addition and/ or Enable AJAX add to basket buttons on archives. I can't get my head around it. Plugins I have activated are WooCommerce, and WooCommerce Stripe Gateway.
UPDATE - Code which adds product options to product screen
function option_add_to_product() {
global $product;
//get pizza categories
$categories = get_terms( 'product_cat', array(
'hide_empty' => false,
));
$use_product = [];
for($i=0;$i<count($categories);$i++) {
if(strtolower($categories[$i]->slug) === 'bespoke_product')
array_push($use_product,$categories[$i]->term_id);
}
$include_product = false;
if(! count($use_product))
return false;
for($i=0;$i<count($use_product);$i++) {
$this_product_categories = $product->get_category_ids();
for($ii=0;$ii<count($this_product_categories);$ii++) {
if($this_product_categories[$ii] === $use_prouduct[$i]) {
$include_product = true;
break;
}
}
}
if(! $include_product)
return false;
//template to add product option
require plugin_dir_path(__FILE__) . 'templates/add_product_option.php';
}
You can see the html from add_product_option.php will be added to the product if the product has a a category with the slug "bespoke_product". Note, this method of getting a match for a product is temporary (just technical debt for now).
When the filter woocommerce_add_cart_item_data is called the data posted from the product form is available to the corresponding function. Unsanitised data might read as follows:
[extra_option_one] => 0
[extra_option_two] => 0
[extra_options_three] => 1
[extra_option_four] => 0
[order_note] =>
Each of those options will have a lookup table with a related price e.g. extra_options_three might be £1.50. This cost of this option and any others selected needs to up the price of the specific item being added to the cart. It should not be represented separately. The definition of the option added should go into the product field everywhere that purchased item is shown. I'm working through step by step, but it's not easy at the point I am at! I'm guessing the next is tha I'm going to be able to update the item in this order?
The woocommerce_add_cart_item_data hook is used to add custom data to the cart item on simple add to cart submission, like additional fields included in the <form> where "add to cart" button is located…
So if you are not submitting extra custom data from custom fields on add to cart event on (from single product pages), the first function argument is going to be an empty array…
See those related answer threads using this hook.
How to add Custom option value on coupon rules Magneto 2. I have a product which have some custom option like size, color etc. with different value, I want give discount on basic of size = 7'. I don't want use sku custom option.. Let me know how I fix it.
https://github.com/Turiknox/magento2-custom-total
Moulde I use for Discount but i have face a problem.
one Data I can't get cart information
$obj = $bootstrap->getObjectManager();
// Set the state (not sure if this is neccessary)
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
// Getting the object managers dependencies
$quote = $obj->get('Magento\Checkout\Model\Session')->getQuote();
$helper = $obj->get('\Magento\Checkout\Helper\Cart');
// Get quote and cart items collection
$quote = $helper->getQuote();
$quoteitems = $quote->getAllItems();
$coupon_code = 'Test23';
// Get cart contents
$cart= $helper->getCart();
foreach ($quoteitems as $item)
{
}
It goes to the infinity loop.
This one Run fast that's why here we can't load quote total, For Discount given you must set session core cookies which allow giving discount...
I have test php script running outside of Magento that will add an item to the cart. Works great. This code was found here and used by many people in quite a few posts. When I place this code into an existing module, the item is not added, from a fresh session. If I go to the store and add a regular product (have an item in my cart) the module will add the item properly. I Know the code to add the item works. The problem I have is with creating the FIRST instance of a cart.
This code works just fine if already have a normal magento product in my cart:
// this section of code only works if the customer already has a cart item added (cart established)
// for some reason this script fails when no cart exists
$session = Mage::getSingleton('customer/session');
// Get cart instance
$cart = Mage::getSingleton('checkout/cart');
$cart->init();
$productId=971;
$productInstance = Mage::getModel('catalog/product')->load($productId);
$param = array(
'product' => $productId,
'qty' => $rfqdata['option_quantity'],
'options' => array(
27 => $rfqdata['option_layers'], // Layers
26 => $rfqdata['option_thickness'], // Thickness
25 => $rfqdata['option_length'], // Length
24 => $rfqdata['option_width'], // Width
23 => $rfqdata['option_color'], // Color
22 => $rfqdata['option_finish'], // Finish
29 => $rfqdata['option_rush'], // Rush
30 => 'tbd' // RFQ Number
)
);
$request = new Varien_Object();
$request->setData($param);
$cart->addProduct($productInstance, $param);
$session->setCartWasUpdated(true);
$cart->save();
This somehow causes an error, and the module addtocart action is not completed. I cannot find any useful error messages. I have searched 100s of pages on stack, google, and I can find nothing to resolve this issue. Obviously my module is worthless if it doesn't work from page load 1.
I tried to post this before and got no response. I really need some help. If you cannot answer, can you tell me where I can find paid Magento support?
here is the solution, it was very hard to find too....
if(empty($quote)){
$checkout = Mage::getSingleton('checkout/session');
$quote = $checkout->getQuote();
$session = Mage::getSingleton('customer/session');
if($session->isLoggedIn()) {
// look up customer
$customerSession = $session->getCustomer();
$customer = Mage::getModel('customer/customer')->load($customerSession->getId());
$quote->assignCustomer($customer);
$quote->setIsMultiShipping(false);
}
$quote->save();
}
Written external script file to load simple products sku that are related to configurable product
Please find the script below for updating simple product meta title
/* Configurable product collection in $_product */
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$simple_collection = $conf->getUsedProductCollection()->addAttributeToSelect(array('sku', 'name', 'meta_title'))->addFilterByRequiredOptions();
/* Making array of simple products from configurable product maping */
foreach($simple_collection as $simple_product) {
$simpleProductList[$simple_product->getId()] = $simple_product->getSku();
}
/* updating each simple product meta title */
foreach($simpleProductList as $key => $skuValue) {
$updPrd = Mage::getModel('catalog/product')->load($key);
$updPrd->setMetaTitle("[configurableProductMetaTitle]");
$updPrd->save();
}
Each configurable product having nearly 400 to 500 simple products mapped.
While executing the script, its take too long time to update.
Please suggest how to optimize the code to execute the script in minimum period
Try using something like this:
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($_product);
$simpleCollection = $conf->getUsedProductCollection()->addAttributeToSelect(array('sku', 'name', 'meta_title'))->addFilterByRequiredOptions();
$simpleIds = $simpleCollection->getAllIds();
$metaTitle = $conf->getProduct()->getMetaTitle();
$storeId = Mage::app()->getStore()->getStoreId(); // or define whatever store id you want
Mage::getSingleton('catalog/product_action')->updateAttributes($simpleIds, array('meta_title' => $metaTitle), $storeId);
Key method is located under app/code/core/Mage/Catalog/Model/Product/Action.php
public function updateAttributes($productIds, $attrData, $storeId) {
...
}
$productIds // Array of your product ids you want to edit
$attrData // Array of data to be updated; array($attributeCode => $value)
$storeId // Id of store where you want changes to be applied
Hopefully this will give you lower execution time.
Cheers!
I've set an observer for sales_quote_add_item in order to clear the cart whenever a certain product is going to be added (it's only supposed to be ordered alone).
I'm just not sure on how to get the product ID of the product that is about to get added. With some trial & error I've come up with this:
$tmp = $observer->getEvent()->getQuoteItem()->getData();
echo $tmp['product_id'];
Which seems to be quite an ugly solution. I'm sure there is some shortcut or proper function to call for this, any ideas?
Your solution is good enough
$productId = $observer->getEvent()->getQuoteItem()->getProductId();
You may load product after if is needed
$product = Mage::getModel('catalog/product')->load($productId);
Use the following code to get product id of quote item data
$cart = Mage::getModel('checkout/cart')->getQuote();
foreach ($cart->getAllItems() as $item)
{
$productId = $item->getProduct()->getId();
}
Hope this helps to you.