I was assigned a Magento 1.9.3 project that would take in products in JSON format, and save customer group prices. However, even though there are no errors, nothing gets saved. The group prices won't show in the admin panel nor in the catalogue as expected.
Why is this? I've looked up every single article or stackexchange cases concerning group prices, but none of these seem to solve my problem.
Currently using the catalog_block_product_list_collection event.
$group_prices = $theProduct->getData('group_price');
if (is_null($group_prices)) {
$attribute = $theProduct->getResource()->getAttribute('group_price');
if ($attribute) {
$attribute->getBackend()->afterLoad($theProduct);
$group_prices = $theProduct->getData('group_price');
}
}
if(!is_array($group_prices)){
$group_prices = array();
$theProduct->addData(array('group_price' => $group_prices));
$theProduct->save();
}
$new_price = array(array (
'website_id'=>Mage_Core_Model_App::ADMIN_STORE_ID,
'customer_group_id'=>$customerGroupId,
'price'=> $singleProduct->Price));
$group_prices = array_merge($group_prices, $new_price);
$currentStore = Mage::app()->getStore()->getId();
try{
Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
// First Delete all the group prices of product
$theProduct->setData('group_price', array());
$theProduct->save();
// Again save the old prices and new prices
$theProduct->setData('group_price', $group_prices);
$theProduct->save();
} catch(Exception $e) {
echo $e->getMessage();
}
Mage::app()->getStore()->setId($currentStore);
And yet, no group prices are saved when checking in the admin panel. Any help is appreciated.
For customer group field use cust_group instead of customer_group_id.
$new_price = array(array (
'website_id'=>Mage_Core_Model_App::ADMIN_STORE_ID,
'cust_group'=>$customerGroupId,
'price'=> $singleProduct->Price));
For details see:
app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Groupprice/Abstract.php line 299
there is condition:
if ($hasEmptyData || !isset($data['cust_group']) || !empty($data['delete'])) {
continue;}
Related
I trying to learn PS and i want to simple update all Prestsahop products state by external script.
I have something like this to disable all products by the supplier (example):
<?php
include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');
$default_lang = Configuration::get('PS_LANG_DEFAULT');
$product = new Product();
if ($product->id_supplier = 2) {
$product->active = 0;
$product->update();
}
But it failed throwing PrestaShopDatabaseException
It seems that you create a new product and don't fill the required fields. If you want to change the existing product you need to set its id during a product object creation.
So your code should be like
$product = new Product($id_product, true, $default_lang); // if you want to get certain language, if ont skip the last parameter
if ($product->id_supplier = 2) {
$product->active = 0;
$product->update();
}
as i understood you want to disable all products for a specific supplier
first you want to get list of all product ids from table ps_product in database. then instantiate a product object by each id_product and disable it if it has the id_supplier condition that you mentioned
require(dirname(__FILE__).'/../config/config.inc.php');
// getting list of product_id
$product_ids = Db::getInstance()->executeS('select id_product from ps_product');
foreach($product_ids as $item) {
$product = new Product($item['id_product']);
if ($product->id_supplier == 2) {
$product->active = false;
$product->update();
}
}
As above, I've got a strange issue where every other product I add isn't added to the cart or quote in Magento.
It's repeatable, in that I can add one product, then the next one doesn't add (but I do get a status messaging saying it was added), and then the next done after that adds as it should do.
It's not specific to a product, as if I add the same product a second time it will add as expected.
The only thing we have that's a little different is an observer called on the sales_quote_add_item event, but that's just changing the pricing:
public function update_book_price(Varien_Event_Observer $observer) {
//get the admin session
Mage::getSingleton('core/session', array('name'=>'adminhtml'));
if (!$quoteitem = $observer->getQuoteItem()){
$quoteitem = $observer->getItem();
}
if (!$item = $observer->getEvent()->getQuoteItem()){
$item = $quoteitem;
}
$quote = $item->getQuote();
$product = $item->getProduct();
$price = Mage::helper('users')->getCustomerProductPrice(false,Mage::getModel('catalog/product')->load($product['product_id']),false,true,$_POST['qtys'][$product['product_id']]);
echo "Price : $price \n";
//print_r($price);
$price = $price;
if(!$quoteitem->setOriginalCustomPrice($price)) {
echo "Couldn't set price";
}
else {
echo "price updated, save";
try {
$quoteitem->getProduct()->setIsSuperMode(true);
var_dump($quoteitem->save());
}catch(Exception $e){
echo $e->getMessage() . "\n";
}
}
return $this;
}
I've checked at a DB level, and the missing items are not even in the DB - sales_flat_quote_item has no record of them, but the 'working' items are in as normal.
Has anyone experienced anything like this before, or can anyone suggest where I might start investigating? Thanks!
You don't have to save quote item after changing price.
Delete var_dump($quoteitem->save()); and try again.
In Prestashop, I've created a custom form where I show a list with all products and the user can fill the corresponding quantities. By submitting the form, I clear the cart and fill it with the new values and finally redirect to the checkout page.
Everything's working fine, but only when the cart already exists. In a case of an empty cart (cart_id==null), I cannot add the products. I tried with several ways to create a $cart but I didn't manage to do so.
I don't get any exceptions, the code is executed without errors, it's just that at the end, in the checkout page, the cart remains empty; I repeat, only when the cart was already empty. In the case of a cart with products in it, then the process is just perfect!
I would appreciate some help on this.
Here is my small controller that gets the products and quantities from the form and adds them in the cart:
include('../../config/config.inc.php');
include('../../header.php');
// Filling the array of products
$products = array();
foreach ($_POST as $key => $value)
if (substr($key, 0, 9) === 'quantity_')
$products[substr($key, 9)] = $value;
// First of all, we remove all products
$prods = $cart->getProducts();
foreach ($prods as $prod)
$cart->deleteProduct($prod['id_product']);
// Adding the new products
foreach ($products as $product_id => $quantity)
if ($quantity > 0)
$cart->updateQty($quantity, $product_id);
// Redirecting to the checkout page.
header("Location: " . $_POST['redirect']);
exit();`
Thank you in advance!
I had the same problem with Prestashop not correctly creating a new cart upon calling the CartCore in many different ways - neither context or direct calls did work out.
Found this gem from someone else over here:
// get cart id if exists
if ($this->context->cookie->id_cart)
{
$cart = new Cart($this->context->cookie->id_cart);
}
// create new cart if needed
if (!isset($cart) OR !$cart->id)
{
$cart = new Cart();
$cart->id_customer = (int)($this->context->cookie->id_customer);
$cart->id_address_delivery = (int) (Address::getFirstCustomerAddressId($cart->id_customer));
$cart->id_address_invoice = $cart->id_address_delivery;
$cart->id_lang = (int)($this->context->cookie->id_lang);
$cart->id_currency = (int)($this->context->cookie->id_currency);
$cart->id_carrier = 1;
$cart->recyclable = 0;
$cart->gift = 0;
$cart->add();
$this->context->cookie->id_cart = (int)($cart->id);
$cart->update();
}
This is working for me now. As you see it goes a little more in depth than just asking the context to retrieve or create a new cart. hth.
You probably need to include this line when you are outside of a class
$context = Context::getContext();
And then add a cart variable that defines cart attributes ( in ur case assigns a id )
$cart = $context->cart; // gets the cart id or creates a new one
Should work fine now
BR's ( dont forget to accept the answer if it helps you :) )
As a complement to previous posts.
If you set that configuration : Configuration::updateValue('PS_CART_FOLLOWING', 1) (display the last cart of the customer instead of creating a new one each time).
You will always get the cart id $this->context->cart->id at NULL when trying to create a new cart at the customer's first log in (after creating a new account) using the following code:
if (is_null($this->context->cart)) {
$this->context->cart =
new Cart($this->context->cookie->id_cart);
}
I manage to solve the problem by adding some code to after the invalid cart creation.
/**
* Manage the possible errors when trying to create
* a new cart for a customer.
*
* The new cart is saved in the current context ($this->context->cart).
*/
private function createCart()
{
if (is_null($this->context->cart)) {
$this->context->cart =
new Cart($this->context->cookie->id_cart);
}
if (is_null($this->context->cart->id_lang)) {
$this->context->cart->id_lang = $this->context->cookie->id_lang;
}
if (is_null($this->context->cart->id_currency)) {
$this->context->cart->id_currency = $this->context->cookie->id_currency;
}
if (is_null($this->context->cart->id_customer)) {
$this->context->cart->id_customer = $this->context->cookie->id_customer;
}
if (is_null($this->context->cart->id_guest)) {
if (empty($this->context->cookie->id_guest)){
$this->context->cookie->__set(
'id_guest',
Guest::getFromCustomer($this->context->cookie->id_customer)
);
}
$this->context->cart->id_guest = $this->context->cookie->id_guest;
}
if (is_null($this->context->cart->id)) {
$this->context->cart->add();
$this->context->cookie->__set('id_cart', $this->context->cart->id);
}
}
After initializing the cart that way, I'm now able to add products to the cart with no problem.
Good success everyone
Restrict users to join competition if they buy products that are on sale
I want to create a condition where by if a customer buys a product that is on special he will get a message that says you got 10% discount else if a customer buys a product that's not on special he will get a message that says thank you for purchasing with us.
I checked the magento forum but no luck.
/*********************************************************************************************/
//how many vouchers the user wants to add
$voucher_products = 0;
//how many products vouchers can be used on
$vouchers_added = 0;
//grabbing the quote object from session
$quote = Mage::getSingleton('checkout/session')->getQuote();
//fetching all cart items from the quote
$items = $quote->getAllVisibleItems('name');
//We need to load the category for infantmilks
$category = Mage::getModel('catalog/category')->loadByAttribute('name', 'Infant Milks');
/* We need to perform a check to ensure that this category exists, by name. if it is not found using
* the name, the feature will not work. return an error message.
*/
if(!$category)
{
$this->addErrorMessage('There is an issue with the Voucher System. Please contact the site administrator.');
return;
}
//grab the production collection
$products_list = $category->getProductCollection();
/* Loop over all cart items, checking how many are
* part of the infantsmilk category. if an item is found
* that is part of the category, increment voucher_products.
*/
foreach ($items as $item) {
foreach ($products_list as $product){
if($item['product_id'] === $product->getId()){
$voucher_products = $voucher_products + 1;
}
}
}
//load the entires from the healthy start entity
$vouchers = Mage::getResourceModel('healthystart/voucher_collection');
//loop over all vouchers and checks if there are any vouchers in the current quote
foreach($vouchers as $voucher){
if ($voucher['quote_id'] === $item['quote_id']){
$vouchers_added = $vouchers_added + 1;
}
}
if ($voucher_products === 0){
$this->addErrorMessage('Healthy Start Vouchers can only be used on Infant Milks.
Please add an Infant Milks product to your basket to redeem your voucher.');
return;
}
else {
if($vouchers_added >= $voucher_products){
$this->addErrorMessage('You can not add another voucher.');
return;
}
}
/*****************************************************/
I can't seem to find anywhere documentation of the 'bundle_option' field in the product options array, when adding a bundled product to the cart programatically in Magento. So I can't be sure how to do this correctly.
But this is my attempt:
$json_obj = json_decode($json_string, true);
//define cart
$cart = Mage::getSingleton('checkout/cart');
$bundle = array();
$bundle_qty = array();
for ($i=0; $i<count($json_obj['basket']['products']); $i++) {
$product_id = int($json_obj['basket']['products'][$i]['id']);
#add individual products to cart
#$product = new Mage_Catalog_Model_Product();
#$product->load($product_id);
#$params = array('product'=>$product_id,'qty'=>1);
#if ($product->getName()) $cart->addProduct($product, $params);
#add products to bundle
$bundle[$i] = $product_id;
if (isset($bundle_qty[$product_id])) $bundle_qty[$product_id] += (int)1;
else $bundle_qty[$product_id] = (int)1;
}
#add to bundled product to cart
$product = new Mage_Catalog_Model_Product();
$product->load(833); #833 = test bundle
$cart->addProduct($product, array('product'=>833,
'qty'=>min(1,int($json_obj['basket']['quantity'])),
'bundle_option'=>$bundle,
'bundle_option_qty'=>$bundle_qty));
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
$message = $this->__('Notice: %s item(s) were successfully added to your shopping cart.', $i);
Mage::getSingleton('checkout/session')->addSuccess($message);
}
So the commented out code is adding products individually which works correctly. Now I'm trying to add the products to a 'Test Bundle' product instead.
What I'm now doing in the loop is compiling the arrays for 'bundle_option' and 'bundle_option_qty' fields. Once the loop has finished I'm adding the bundle product (ID:833) to the cart with the options array of the bundled items.
The result is that nothing is added to the cart. I've also played around with the code a bit to no success.
Can anyone see where I'm going wrong or if you could point me to a doc/tutorial of the product options parameter that details the bundle_option array (what the indexes are, and what the values are) that would also help?
I had to check the POST variables sent to the cart URL from the front-end to figure this one out.
These were the variables posted for one bundle:
bundle_option[1][] 17
bundle_option[1][] 19
bundle_option_qty[1][17] 1
bundle_option_qty[1][19] 1
product 833
qty 2
related_product
From that I figured out that bundle_option[1] referred to Option 1 in the bundle.
I also figured that the values of the indexes bundle_option[1][0]=17 and bundle_option[1][1]=19 - the 17 and 19 referred to selection_id.
Analysing the form on the front-end revealed my list of selection_id's. I figured that the selection ID's would change once the bundle was altered in Admin>Manage Products so I used a look-up to get the selection IDs rather than hard-coding them in.
The code I ended up with was this:
$json_string = isset($_POST["json"])? $_POST["json"] : null;
if (!is_null($json_string)) {
$json_obj = json_decode($json_string, true);
#define cart
$cart = Mage::getSingleton('checkout/cart');
#look-up bundle selection ids
$bundled_product = new Mage_Catalog_Model_Product();
$bundled_product->load(833); #833 = test bundle
$selectionCollection = $bundled_product->getTypeInstance(true)->getSelectionsCollection(
$bundled_product->getTypeInstance(true)->getOptionsIds($bundled_product), $bundled_product
);
$bundled_items = array();
foreach ($selectionCollection as $option) {
$bundled_items[$option->product_id] = $option->selection_id;
}
#get bundle items, quantities
$bundle = array();
$bundle_qty = array();
for ($i=0; $i<count($json_obj['basket']['products']); $i++) {
$product_id = (int)$json_obj['basket']['products'][$i]['id'];
$selection_id = $bundled_items[$product_id];
if(!in_array($selection_id,$bundle)) array_push($bundle,$selection_id);
if (isset($bundle_qty[$selection_id])) $bundle_qty[$selection_id] += (int)1;
else $bundle_qty[$selection_id] = (int)1;
}
#add to bundled product to cart
$options = array('product'=>833,
'related_product'=>null,
'bundle_option'=>array(1=>$bundle),
'bundle_option_qty'=>array(1=>$bundle_qty),
'qty'=>(int)$json_obj['basket']['quantity']
);
$cart->addProduct($bundled_product, $options);
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
$message = $this->__('Notice: %s item(s) were successfully added to your shopping cart.', $i);
Mage::getSingleton('checkout/session')->addSuccess($message);
}
I hope this saves somebody a lot of time!
Edit
Still trying to solve why bundle_option_qty is not setting the quantity (all items are qty:1 added to the bundle product)
Edit 2
It turned out the built-in front-end bundle add-to-cart feature couldn't add multiple quantities of items to the cart either! Looking into the issue I found that the bundle-quantity feature was an extension called Kabel BundlePlus, it probably wasn't installed correctly by the previous developers so I downloaded it again and reinstalled the plugin and now the bundle_option_qty is working in both the frontend and my plugin!