Magento has a lot of options to accommodate a lot of different e-commerce websites but there will always be situations where Magento doesn’t have what you need. In this case, it’s to have a new field Weight for a product that has custom options so that the shipping rate will be better calculated.
For example, you’re selling a single product (not a configurable product) that comes in 1000 mL or 2000 mL. So it has a custom options with a drop-down for 1000 mL or 2000 mL. The weight of the 1000 mL is 1.101 kg and the 2000 mL is 2.202 kg. You can set a base weight in Magento but you cannot add a different weight for a custom options.
Here’s how to modify Magento to add this new information with a modification to MagMI so that you can import thousands of products with custom options and different weights. You could also apply this procedure for other uses too. This has been tested on Magento Community Edition 1.9.3.4 with MagMI v0.7.23-git.
Important note: This procedure will modify Magento’s core files, if you upgrade Magento to a newer version, you will have to apply these modifications again.
Here’s what it will look like in Magento’s Dashboard at the end:
It’s also worth noting that there’s different plugins for Magento available that will achieve this same result, one of them is Magento Advanced Product Options extension from Mageworx, it is not free but it does a lot more than just adding the weight in the custom options.
Step 1: Add the new weight field in the database by running this SQL command:
ALTER TABLE catalog_product_option_type_value ADD weight DECIMAL(12,3) DEFAULT 0.000 AFTER option_id;
This will add a decimal value with up to 3 decimal point.
Step 2: Add the new weight column in Magento’s Dashboard by modifying:
app/design/adminhtml/default/default/template/catalog/product/edit/options/type/select.phtml
Insert
'<th class="type-weight"><?php echo Mage::helper('catalog')->__('Weight') ?></th>' +
After
'<th class="type-type"><?php echo Mage::helper('core')->jsQuoteEscape(Mage::helper('catalog')->__('Price Type')) ?></th>' +
And insert
'<td><input type="text" class="input-text validate-number product-option-weight" id="product_option_{{id}}_select_{{select_id}}_weight" name="product[options][{{id}}][values][{{select_id}}][weight]" value="{{weight}}"></td>' +
After
'<td><?php echo $this->getPriceTypeSelectHtml() ?>{{checkboxScopePrice}}</td>' +
Step 3: Make Magento aware of the new weight custom options by modifying:
app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php
Insert
'weight' => $_value->getWeight(),
After
'price_type' => ($showPrice) ? $_value->getPriceType() : 0,
Step 4: Add the new weight custom option to the product when it is added to the cart by modifying:
app/code/core/Mage/Sales/Model/Quote/Item.php
Insert
$optionsWeight = 0; $options = $this->getOptions(); if (is_array($options)) { unset($options[0]); unset($options[1]); $read = Mage::getSingleton('core/resource')->getConnection('core_read'); foreach ($options as $option) { $temp = $read->fetchRow('SELECT * FROM `catalog_product_option_type_value` WHERE `option_type_id` = '.$option->getValue().' LIMIT 0, 1'); $optionsWeight += $temp['weight']; } } // $optionsWeight = 0; //if you want to turn off
Before
$this->setData('product', $product)
And modify
->setWeight($this->getProduct()->getWeight()
To
->setWeight($this->getProduct()->getWeight() + $optionsWeight)
Step 5: For testing only to see the weight for every different products on the Shopping Cart page, modify
app/design/frontend/default/default/template/checkout/cart/item/default.phtml
Or if you have a theme, you will have to modify
app/design/frontend/YOUR_THEME/default/template/checkout/cart/item/default.phtml
Insert
<strong>Base weight=<?php echo $_item->getWeight() ?> & New weight=<?php echo $_item->getRowWeight() ?></strong>
After
<a href="<?php echo $this->getProductUrl() ?>"><?php echo $this->escapeHtml($this->getProductName()) ?></a>
Step 6: Everything should work just as expected but if you have lots of products and you’re using MagMI, then it won’t work, we now have to modify MagMI v0.7.23-git manually by modifying
plugins/extra/itemprocessors/customoptions/pablo_customoptions.php
Change
(option_id, sku, sort_order) VALUES (?, ?, ?)"; $optionTypeId = $this->insert($sql, array($optid, $val["sku"], $val["sort_order"]));
To
(option_id, weight, sku, sort_order) VALUES (?, ?, ?, ?)"; $optionTypeId = $this->insert($sql, array($optid, $val["weight"], $val["sku"], $val["sort_order"]));
Insert
$weight = ($c > 5) ? $parts[5] : 0;
After
$sort_order = ($c > 4) ? $parts[4] : 0;
And insert
$ovalues["weight"] = $weight;
Before
$ovalues["price_type"] = $price_type;
At this point, you can add a weight in your MagMI’s CSV file at the end completely of a custom option. In this example with the bottle size of 1000 mL and 2000 mL, here’s how it will look like:
Bottle Size:drop_down:1 1000ml:fixed:0:1000ml:0:1.101|2000ml:fixed:10.00:2000ml:1:2.202
Many thanks to user_1076 for the original code modification.
I have a question. I added weight according to the method in this article. It works fine on our local computer (xampp+PHP 7.1.26), but when I upload it to my website(CWP7+PHP 7.2.30), I find that the value of weight cannot be saved. What is the problem?
That’s a good question, I really couldn’t say. Just make sure to flush the cache. I doubt the problem is the change of the web server or PHP version. Make sure there is no difference in htaccess or php.ini too and check the log when doing a test, might be something useful in it.
When implementing on 1.7.0.2 CE, code prevents from passing text values in Text Field / Area type of custom options (item cannot be added to cart error), instead only integer values can be passed.
The following change in Item.php did the trick:
$optionsWeight = 0;
$options = $this->getOptions();
if (is_array($options)) {
unset($options[0]);
unset($options[1]);
$read = Mage::getSingleton(‘core/resource’)->getConnection(‘core_read’);
foreach ($options as $option) {
if (ctype_digit($option->getValue())){
$temp = $read->fetchRow(‘SELECT * FROM `catalog_product_option_type_value` WHERE `option_type_id` = ‘.$option->getValue().’ LIMIT 0, 1′);
$optionsWeight += $temp[‘weight’];
}
}
}
// $optionsWeight = 0; //if you want to turn off