Updating price programmatically - magento

I am trying to update several products that are fed from an XML file using:
$productid = Mage::getModel('catalog/product')->getIdBySku($url->product);
echo 'Loaded Product: ' . $url->product;
// Initiate product model
$product = Mage::getModel('catalog/product');
$product->setPrice($url->price);
try
{
$product->save();
echo "Save / Updated"."\r\n";
}
catch (Exception $ex) {
echo "<pre>".$ex."</pre>";
}
The problem I'm getting a SQL error:
exception 'Mage_Eav_Model_Entity_Attribute_Exception' with message 'SQLSTATE[23000]:
Integrity constraint violation: 1062 Duplicate entry '531-0-82-1.0000-0'
The product with the ID of 531 does exist in my db, all I'm wanting to do is update it's price.
What could be causing this?

Try this to update
$product = Mage::getModel('catalog/product');
change to
$product = Mage::getModel('catalog/product')->load($productid);
You have to load a product to update its attributes.

Well it seemed to not like the fact I had tiered prices on that product.
Cleared them, re-indexed, re-created tiered pricing, all seems good

Related

Magento - How to check if Cross Sell products exist.

In view.phtml I want to check if the product has any cross sell products associated with it.
I've done the same with related products:
$relatedProductsId=$_product->getRelatedProductIds();
$relatedProducts=array();
$i=0;
foreach($relatedProductsId as $relatedProductId)
{
$relatedProducts[$i] = array(Mage::getModel('catalog/product')- >load($relatedProductId)->getProductUrl(),
Mage::getModel('catalog/product')->load($relatedProductId)->getName(),
Mage::getModel('catalog/product')->load($relatedProductId)->getImageUrl(),
Mage::getModel('catalog/product')->load($relatedProductId)->getFormat()
);
$i++;
}
I'm not sure what the function used is for the Cross Sells products.
Please can someone help.
Did you try
$crossSellProducts = $_product->getCrossSellProducts()
?
It will return an array of cross-sell product objects.

Magento Import - FK Integrity Constraint Violation

I'm progmatically importing products into Magento 1.7.0.2 from an XML feed.
The script has run fine for the best part of a week, but now I'm getting the error shown below when products are saving.
How serious is this error, what can cause it?
I've tried reindexing everything and truncating a bunch of tables, the error seems to persist.
The Error:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '51-1' for key 'UNQ_CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID'
Import php (sample):
$sProduct = $this->_productModel;
$sProduct->setTypeId($this->_productTypeSimple)
->setWebsiteIds(array(1))
->setStatus($this->_productStatusDisabled)
->setVisibility($this->_productVisibilityNotVisible)
->setTaxClassId(2) //Taxable Good
->setAttributeSetId(XML_FEED_PRODUCT_ATTRIBUTE_SET)
->setSku($arrayProductData['ProductSKU'])
->setName($arrayProductData['ProductName'])
->setShortDescription($arrayProductData['ProductShortDescription'])
->setDescription($arrayProductData['ProductLongDescription'])
->setPrice(sprintf("%0.2f", $arrayProductData['ProductPrice']))
->setRRP(sprintf("%0.2f", $arrayProductData['ProductPrice']))
->setWeight(0)
->setCategoryIds($arrayProductData['ProductCategories'])
->setUrlKey(str_replace(array(" ","'","&"),"-",$arrayProductData['ProductName']) . "-" . $arrayProductData['ProductSKU']);
$sProduct->setStockData(
array(
'use_config_manage_stock' => 1,
'is_in_stock' =>1,
'qty' => $arrayProductData['ProductStockQty']
)
);
$sProduct->setMetaTitle($arrayProductData['ProductName'])
->setMetaDescription(str_replace("<<THE_PRODUCT>>",$arrayProductData['ProductName'], DEFAULT_META_DESC));
if(isset($arrayProductData['ProductSize'])) {
$sProduct->setData("sizes", $arrayProductData['ProductSize']);
}
if(isset($arrayProductData['ProductColour'])) {
$sProduct->setData("color", $arrayProductData['ProductColour']);
}
try {
$sProduct->save();
}
catch (Mage_Core_Exception $e) {
echo $e->getMessage();
}
Thanks for looking.
As the error show
UNQ_CATALOGINVENTORY_STOCK_ITEM_PRODUCT_ID_STOCK_ID
There is duplicate entry in DB table ( cataloginventory_stock_item ) for the same product_id / stock_id
This could happen for different reasons
You can solve this by setting the ID of the product manually before save so it won't conflict get the last product ID and increment it.
or delete the row related to this new product from the table before save
Further down the script I was creating configurable products based on certain criteria.
For reasons I've not yet uncovered the SKU of this configurable product doesn't appear to be unique, causing the issue above.
Thanks anyway Meabed.

Update in sales order table - Magento Model

I want to update one field value in magento I am using
$data = array('xxx'=>$xxx);
$orderModel = Mage::getModel('sales/order')->load($orderId)->addData($data);
try {
$orderModel->setId($orderId)->save();
echo "Data updated successfully.";
} catch (Exception $e){
echo $e->getMessage();
}
But it is not working, Any one can suggest me what I am doing the create problem in updating data.
you can do the MAGIC function, get and set function
try directly:
// if your attribute is column named is_active then you can getIsActive() or setIsActive(1)
$orderModel = Mage::getModel('sales/order')->load($orderId)->setYourAttribute($data);
// it means you can set and get column named by ['your_attribute']
try {
$orderModel->setId($orderId)->save();
echo "Data updated successfully.";
} catch (Exception $e){
echo $e->getMessage();
}
hmmm. i don't know why you set the entity_id of sales/order model. but it won't work because the entity_id can be the foreign key on another table, example : sales_flat_order_payment
Your code setId($orderId) looks like you either want to explicitely set an order entity_id (that is, create an order), or you're just not aware of the fact, that you don't need setId($orderId) after loading, if you only want to update the given order.
In case you're trying to create an order: the sales/order model normally does not allow to explicitely set an order's entity_id, because it uses a primary key being auto-incremented by default.
In case you're trying to update an existing order: remove the setId($orderId) from the save() chain.
Second, you need to extend the sales/order model with an xxx attribute first, if you want to be able to save its value to the database.
There are several ways to extend the sales/order model to have a custom attribute. For example you could have your own setup script in your app/code/local/Mycompany/Mymodule/sql/myresource/ folder:
// Mage_Eav_Model_Entity_Setup
$oInstaller = $this;
// Add EAV attribute
$oInstaller->startSetup();
$oInstaller->addAttribute(
'order',
'my_attribute',
array(
'type' => 'int'
)
);
$oInstaller->endSetup();
// Add flat attribute
if (Mage::getVersion() >= 1.1) {
$oInstaller->startSetup();
$oConnection = $oInstaller->getConnection();
$oConnection->addColumn(
$oInstaller->getTable('sales_flat_order'),
'my_attribute',
'TINYINT(1) NOT NULL'
);
$oInstaller->endSetup();
}

Magento: How to get the id of the just duplicated product programmatically

How can I get the id of the just duplicated product programmatically in Magento ?
(or the last inserted product id, if the first solution don't exits)
Thanks for help.
[EDIT]
Here is the code that I have used to duplicate my product:
$sku = '123456';
$product = Mage::getModel('catalog/product')
->loadByAttribute('sku',$sku);
$newProduct = $product->duplicate();
$newProduct->setStatus(1);
$newProduct->setSku($sku.'-v2');
$newProduct->save();
Thanks for help.
you can find the new prodect ID in:
$newProduct->getId()
This is available just after calling :
$newProduct = $product->duplicate();
FYI: to get the last insertedId (in general) you can use:
Mage::getSingleton('core/resource')->getConnection('core_read')->fetchOne('SELECT last_insert_id()')

How to select from magento EAV tables when flat catalog product data is on

I have this code for selecting best selling products from Magento:
$productCollection = Mage::getResourceModel('reports/product_collection')
->addOrderedQty($startTime, $currentTime)
->addAttributeToSelect('*')
->setStoreId($storeId)
->addStoreFilter($storeId)
->setOrder('ordered_qty', 'desc')
->setPageSize($this->limit());
}
and it works fine, until I set "use flat catalog product" in backend to yes.
Is there any way to tell magento to not use flat tables, and use EAV instead?
Can any one help me with this.
Create a new model class ('mycatalog/product') that extends the original product class but hard code it to use the EAV resource model and EAV resource collection, and then use that model in your query code.
I'd been running my code from a stand alone php file, as soon as i moved my code into an admin module it stopped using the flat_file and went back to eav.
If you look at: Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
There's a method:
public function isEnabledFlat()
{
if (Mage::app()->getStore()->isAdmin()) {
return false;
}
if (!isset($this->_flatEnabled[$this->getStoreId()])) {
$this->_flatEnabled[$this->getStoreId()] = $this->getFlatHelper()
->isEnabled($this->getStoreId());
}
return $this->_flatEnabled[$this->getStoreId()];
}
You could modify this to add an extra condition that returns false based on your own criteria.
BTW, The reports collection mentioned in the first post by Blazo is an extension of this collection.
To expand on Alan's answer:
class Namespace_Module_Model_Category extends Mage_Catalog_Model_Category
{
protected function _construct()
{
$this->_init('catalog/category');
}
}
The above removes the check to see if flat was enabled and only inits the standard eav verson of the catalog/category resource.
And then when you wish to load your model ensuring that you get the eav model regardless of wither the flat data is enabled:
$category = Mage::getModel('namespace_module/category')->load($id)
I have use
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
before
Mage::getModel('catalog/product')->getCollection()
And it start fetching data from eav based system.
This is an old post but I thought one important point was not stated.
1. Once you set flat catalog to on you need to run indexer via cron or via admin/shell so that flat catalog tables get populated.
If you do have many products in your search bypassing flat catalog table will slow down your site and each search code will consume lots of resources.
I found that the easiest solution was to turn off the flat tables and then get the SQL query that magento executes using the ->load(true) parameter
e.g.
$collection = Mage::getModel('catalog/category')->getCollection();
$collection
->setStoreId($store->getId())
->addAttributeToSelect('*')
->addAttributeToFilter(array(array('attribute'=>'ig_unifeed_ids', 'like'=>"%:".$this->getId().":%")))
->load(true);
then turn flat tables back on and replace this code with:
$resource = Mage::getSingleton('core/resource');
$readConnection = $resource->getConnection('core_read');
$query = "SELECT `e`.*, `at_ig_unifeed_ids`.`value` AS `ig_unifeed_ids` FROM `catalog_category_entity` AS `e` INNER JOIN `catalog_category_entity_varchar` AS `at_ig_unifeed_ids` ON (`at_ig_unifeed_ids`.`entity_id` = `e`.`entity_id`) AND (`at_ig_unifeed_ids`.`attribute_id` = '139') AND (`at_ig_unifeed_ids`.`store_id` = 0) WHERE (`e`.`entity_type_id` = '3') AND ((at_ig_unifeed_ids.value LIKE '%:".$this->getId().":%'))";
$collection = $readConnection->fetchAll($query);
From this point on you will probably need to change other code like replacing
$category->getId()
with
$category["entity_id"]
I hope this helps a bit...
NOTE: this is a real solution for the IG_Unifeed module magento bug that disregards category filtering when using flat tables.

Resources