Change Magento product's attribute set. - magento

I want to change the attribute set of Magento. I searched through, and everyone suggested to delete the product and re-import it with new attribute set.
I did the same however after importing the data I could not see product reviews and associated blog post with product.
Can anyone tell me is it possible to get product reviews and associated blog post after re-importing the product with new attribute set.

Once set you can't change the attribute set of a product. But it's possible using this module so you don't have to reimport your data
https://marketplace.magento.com/flagbit-magento-changeattributeset.html

It's also possible to change the attribute set directly in the database.
Look up the attribute set ID in table eav_attribute_set
Change the attribute set ID in catalog_product_entity
Of course, be careful when changing data this way.

It is fiddly to do and a bit messy:
Make sure new attribute set is set up
Export the products you want to change
Delete the products that you are changing on the site
Change the attribute set on the downloaded file
Import changed file again
Open each changed product, set their attribute values, save it
Or do what I do, install this great extension from Amasty http://amasty.com/mass-product-actions.html - it makes changing a breeze and gives many more time saving and enhancing options.

Once you delete the product you can't get the old review.
You don't need to delete the product . You can change the attribute set by editing and use.
other wise create a new attribute set and create new product.

Yes. We can change product attribute set programmatically.
I prefer to create massaction in catalog product grid to multiselect product and then select massaction for the products.
Creating massaction in grid.php
$sets = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
->load()
->toOptionHash();
$this->getMassactionBlock()->addItem('changeattributeset', array(
'label'=> Mage::helper('catalog')->__('Change attribute set'),
'url' => $block->getUrl('*/*/changeattributeset', array('_current'=>true)),
'additional' => array(
'visibility' => array(
'name' => 'attribute_set',
'type' => 'select',
'class' => 'required-entry',
'label' => Mage::helper('catalog')->__('Attribute Set'),
'values' => $sets
)
)
));
Creating controller action for change attribute sets of the selected products.
public function changeattributesetAction()
{
$productIds = $this->getRequest()->getParam('product');
$storeId = (int)$this->getRequest()->getParam('store', 0);
if (!is_array($productIds)) {
$this->_getSession()->addError($this->__('Please select product(s)'));
} else {
try {
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')
->unsetData()
->setStoreId($storeId)
->load($productId)
->setAttributeSetId($this->getRequest()->getParam('attribute_set'))
->setIsMassupdate(true)
->save();
}
Mage::dispatchEvent('catalog_product_massupdate_after', array('products'=>$productIds));
$this->_getSession()->addSuccess(
$this->__('Total of %d record(s) were successfully updated', count($productIds))
);
}
catch (Exception $e) {
$this->_getSession()->addException($e, $e->getMessage());
}
}
$this->_redirect('adminhtml/catalog_product/index/', array());
}

You can add to your data patch apply function something like this:
public function apply(): self
{
$this->moduleDataSetup->getConnection()->startSetup();
/** #var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttributeToSet(
Product::ENTITY,
'Default',
'General',
CustomAttributesInterface::ATTRIBUTE_CODE_MANUFACTURER
);
$this->moduleDataSetup->getConnection()->endSetup();
return $this;
}
This changes the manufacturer products attribute to the Default attribute set. (By default this attribute has no attribute set.)
Hope it helps :)

Related

cscart {{o._tax_name}} value in documents - invoice and order summary

I wish to add more values to product table in cs- cart documents.
In my country we have requirements for tax name for each product included in invoice.
How can I add value of {{o._tax_name}} into product table in documents invoice and order summary in cscart ?
You could modify or add inside your own addon at path:
/app/addons/my_changes/schemas/snippets/order_products_table.post.php
the code that looks something like this:
$schema['custom_tax_name'] = array(
'class' => '\Tygh\Template\Document\Variables\GenericVariable',
'data' => function (\Tygh\Template\Snippet\Table\ItemContext $context) {
$data = array();
$product = $context->getItem();
$data['tax_name'] = getTaxName($custom_val); //you could have function here to get whatever your needs are
return $data;
},
'arguments' => array('#context', '#config', '#formatter'),
'attributes' => array(
'tax_name'
)
);
After this, clear your cache and then you will see inside Menu: Documents - order.invoice the new value that already created, like this:
{{ custom_tax_name.tax_name }}

magento store data in custom columns

I added two text columns to sales_flat_quote_item in order to store data and for other reasons When i add product to cart. my problem is that i cant save the data. i tried a lot of examples but without any success.
here i add the coulmns :
$installer = $this;
$connection = $installer->getConnection();
$installer->startSetup();
$installer->getConnection()
->addColumn($installer->getTable('sales/quote_item'),
'pack_name',
array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,
'nullable' => true,
'default' => null,
'comment' => 'pack_name'
)
);
$installer->endSetup()
;
this is the code in my observer where i try to save the data :
$quote_item = Mage::getModel('sales/quote_item')->load($quote->Id);
$quote_item->setPackName($string);
$quote_item->save();
any help?
It's not advisable to add columns to flat tables like this. The magic methods aren't working because your update to the schema goes against Magento best practices. If you just want a quick fix though, you can do it with raw SQL queries:
<?php
$transaction = Mage::getSingleton('core/resource')->getConnection('core_write');
try {
$transaction->beginTransaction();
$query_string = "UPDATE sales_flat_quote_item
SET pack_name='packname'
WHERE id='id'";
$transaction->query($query_string);
$transaction->commit();
}
catch (Exception $e) {
$transaction->rollBack();
}
Be careful though, it's not secure. Make sure your data is sanitized.

How to find a list of editable attributes in a class - Magento

When creating a product I can use the following via the API:
$newProductData = array(
'name' => (string)$stockItem->STOCK_DESC,
'websites' => array(1,2), // array(1,2,3,...)
'short_description' => (string)$stockItem->STOCK_DESC,
'description' => (string)$stockItem->LONG_DESC,
'status' => 1,
'weight' => $stockItem->WEIGHT,
'tax_class_id' => 1,
'categories' => array(3108),
'price' => $stockItem->SELL_PRICE
);
$my_set_id = 9; // Use whatever set_id you want here
$type = 'simple';
$mc = new Mage_Catalog_Model_Product_Api();
$mc->create($type, $my_set_id, $stockItem->STOCK_CODE, $newProductData);
When I look into the $mc->create call I see that it does this:
foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) {
}
which indicates there is a list of attributes which can be edited against an object.
How do I find these? Is there a specific place this information is found?
Edit: I just did:
Mage::log($product->getTypeInstance(true)->getEditableAttributes($product));
and had a look at the results. It seems all the editable attributes are there which can be found under [attribute_code] => but I would still like a better method of knowing where to look to get this list.
This will depend entirely on the attribute set of the product you're trying to edit, and the configuration of each individual attribute. There's no place in the UI that will list these attributes out for you. Your best bet is to run some custom code for your product
$product = Mage::getModel('catalog/product')->load($product_id);
foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $code=>$attribute)
{
var_dump($code);
}
Here's how to track this information down. If you jump to the getEditableAttributes method
#File: app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php
public function getEditableAttributes($product = null)
{
$cacheKey = '_cache_editable_attributes';
if (!$this->getProduct($product)->hasData($cacheKey)) {
$editableAttributes = array();
foreach ($this->getSetAttributes($product) as $attributeCode => $attribute) {
if (!is_array($attribute->getApplyTo())
|| count($attribute->getApplyTo())==0
|| in_array($this->getProduct($product)->getTypeId(), $attribute->getApplyTo())) {
$editableAttributes[$attributeCode] = $attribute;
}
}
$this->getProduct($product)->setData($cacheKey, $editableAttributes);
}
return $this->getProduct($product)->getData($cacheKey);
}
You can see that this method gets a list of all the attributes set on a particular product.(i.e. All the attributes that are a member of the product's attribute set). Once it has this list, it goes through each and checks if its apply_to property matches the type id of the current product.
The Apply To attribute is set at
Catalog -> Attributes -> Manage Attributes -> [Pick Attribute]
This form field updates the database table catalog_eav_attribute. If you run the following query you can see examples of this value as is stored
select attribute_id, apply_to from catalog_eav_attribute where apply_to is NOT NULL;
75 simple,configurable,virtual,bundle,downloadable
76 simple,configurable,virtual,bundle,downloadable
77 simple,configurable,virtual,bundle,downloadable
78 simple,configurable,virtual,bundle,downloadable
79 virtual,downloadable
So, get your product's attribute set. Get a list of attributes in that set. Compare the value of the attribute's apply_to field vs. the value of your product's type_id. That will let you build a list of these attributes.

Magento New Cart Attribute

Hi well the problem I am facing seemed to be very simple at first but turned into a real nightmare now.
I was asked to add an attribute (namely point) to all the products (which was done pretty simple using the admin panel) and have its total as a cart attribute which rules can be set upon!?
I am quite positive that cart attributes are defined in:
class Mage_SalesRule_Model_Rule_Condition_Address extends Mage_Rule_Model_Condition_Abstract
{
public function loadAttributeOptions()
{
$attributes = array(
'base_subtotal' => Mage::helper('salesrule')->__('Subtotal'),
'total_qty' => Mage::helper('salesrule')->__('Total Items Quantity'),
'weight' => Mage::helper('salesrule')->__('Total Weight'),
'payment_method' => Mage::helper('salesrule')->__('Payment Method'),
'shipping_method' => Mage::helper('salesrule')->__('Shipping Method'),
'postcode' => Mage::helper('salesrule')->__('Shipping Postcode'),
'region' => Mage::helper('salesrule')->__('Shipping Region'),
'region_id' => Mage::helper('salesrule')->__('Shipping State/Province'),
'country_id' => Mage::helper('salesrule')->__('Shipping Country'),
);
$this->setAttributeOption($attributes);
return $this;
}
<...>
So if I overwrite this model and add an item to that array I will get the attribute shown in rule definition admin panel. It seems that all these attributes has a matching column in sales_flat_quote_address table except for total_qty and payment_method!
Now the problem is what should I do to have my new attribute be calculated and evaluated in rules processing? should I add a column to this table and update its value upon cart changes?
Any insight on how to do this would be of great value thanks.
I finally managed to accomplish the task and just for future reference I explain the procedure here.
The class mentioned in the question (ie: Mage_SalesRule_Model_Rule_Condition_Address) is the key to the problem. I had to rewrite it and for some odd reason I couldn't get what I needed by extending it so my class extended its parent class (ie: Mage_Rule_Model_Condition_Abstract).
As I said I added my attribute to $attributes like this:
'net_score' => Mage::helper('mymodule')->__('Net Score')
I also modified getInputType() method and declared my attribute as numeric
now what does the trick is the validate() method:
public function validate(Varien_Object $object)
{
$address = $object;
if (!$address instanceof Mage_Sales_Model_Quote_Address) {
if ($object->getQuote()->isVirtual()) {
$address = $object->getQuote()->getBillingAddress();
}
else {
$address = $object->getQuote()->getShippingAddress();
}
}
if ('payment_method' == $this->getAttribute() && ! $address->hasPaymentMethod()) {
$address->setPaymentMethod($object->getQuote()->getPayment()->getMethod());
}
return parent::validate($address);
}
as you can see it prepares an instance of Mage_Sales_Model_Quote_Address and sends it to its parent validate method. you can see that this object ($address) does not have payment_method by default so this method creates one and assigns it to it. So I did the same, simply I added the following code before the return:
if ('net_score' == $this->getAttribute() && ! $address->hasNetScore()) {
$address->setNetScore( /*the logic for retrieving the value*/);
}
and now I can set rules upon this attribute.
Hope that these information saves somebody's time in the future.

assign new attribute to all attribute sets by coding in magento

I created a new attribute ("for example my_attribute"). Magento's store already has many attribute sets (approx 20).
It's a very time consuming process if I manually add the attribute to the sets because my server is very slow.
I want to assign this new attribute("my_attribute") to all attribute sets programmatically.
Can anyone can help me?
Thanks in advance.
It's quite simple. In a custom module setup script:
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$installer->addAttribute(
'catalog_product',
'your_attribute_code',
array(
'label' => 'Attribute Label',
'group' => 'General', // this will add to all attribute sets in the General group
// ...
)
)
$installer->endSetup();
For other utilities, see Mage_Eav_Model_Entity_Setup.
Here's something quick, dirty, and untested :)
<?php
$attributeId = ID_HERE;
$installer = new Mage_Catalog_Model_Resource_Eav_Mysql4_Setup('core_setup');
$entityType = Mage::getModel('catalog/product')->getResource()->getEntityType();
$collection = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter($entityType->getId());
foreach ($collection as $attributeSet) {
$attributeGroupId = $installer->getDefaultAttributeGroupId('catalog_product', $attributeSet->getId());
$installer->addAttributeToSet('catalog_product', $attributeSet->getId(), $attributeGroupId, $attributeId);
}
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$attributeCode = 'my_attribute';
$entity = Mage_Catalog_Model_Product::ENTITY;
// create a new attribute if it doesn't exist
$existingAttribute = $installer->getAttribute($entity, $attributeCode);
if (empty($existingAttribute)) {
$installer->addAttribute($entity, $attributeCode, array(<configure your attribute here>));
}
$attributeId = $installer->getAttributeId($entity, $attributeCode);
// add it to all attribute sets' default group
foreach ($installer->getAllAttributeSetIds($entity) as $setId) {
$installer->addAttributeToSet(
$entity,
$setId,
$installer->getDefaultAttributeGroupId($entity, $setId),
$attributeId
);
}
$installer->endSetup();
As Attributes are not assigned with any attribute set then, you can delete that attribute you created and then create required attribute programmatically.
In the Magento wiki's Programmatically Adding Attributes and Attribute Sets Section, It describes createAttribute as the function that will solve your problem because it will create attributes and also assign them to attribute sets.
Hope This Helps!!
Additionally, Mage_Eav_Model_Entity_Setup and Mage_Catalog_Model_Resource_Setup, which extends from the aforementioned class, have all of the methods that you need to create attributes, sets, and groups. They are fairly straightforward, and they will help you understand how you're supposed to do it properly and prevent you from from writing bad or redundant code. I find most of the articles floating around the Internet and even Magento's own wiki entries feature poorly written code.

Resources