I am currently making a module so that users see on the checkout page something like: "People who purchased product X also purchased Y, Z and T".
I made a cronjob to calculate which are the related products for each product, and I added an attribute to products in the install script.
I decided (for simplicity) - to store the most related 5 products, so I want to store something like: 123-3-5543-1290-9911. But I don't want the administrator to see this anywhere, and I tried the following:
$setup->addAttribute('catalog_product', $attrCode, array(
// more stuff
'type' => 'hidden',
'input' => 'text',
'visible' => 0,
// more stuff
));
I looked here: http://blog.chapagain.com.np/magento-adding-attribute-from-mysql-setup-file/ and I found some interesting stuff, but not how to completely hide this field.
The alternative would be to create my own table, but this seems to be a slightly more elegant solution.
What do you think? Is it better to create my own table, or to add an attribute and hide it?
Thank you
Setting the 'is_visible' property to 0 for catalog attributes will hide them from the admin forms in the backend, as can be seen from this code (Mage_Adminhtml_Block_Widget_Form::_setFieldset()):
protected function _setFieldset($attributes, $fieldset, $exclude=array())
{
$this->_addElementTypes($fieldset);
foreach ($attributes as $attribute) {
/* #var $attribute Mage_Eav_Model_Entity_Attribute */
if (!$attribute || ($attribute->hasIsVisible() && !$attribute->getIsVisible())) {
continue;
}
So execute
$setup->updateAttribute('catalog_product', $attrCode, 'is_visible', '0');
I solve it in this way.
Go to Catalog >> Attributes >> Manage Attributes >> Add new attribute
Then, save. Then, Go to database and Run this query:
SELECT * FROM eav_attribute WHERE attribute_code ='attribute_code';
Change the column frontend_input value to hidden, then save.
Hope it helps.
Related
I need to add some fields to prestashop product (HSN code and one more). I am very new to prestashop and there is no guide to do the same with latest build 1.7.
I have followed answers made on stackoverflow and I am able to show the form fields but unable to save and validate the value.
Here is the code snippet I have used (I preferred this because it uses the hooks).
use PrestaShopBundle\Form\Admin\Type\TranslateType;
use PrestaShopBundle\Form\Admin\Type\FormattedTextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
public function hookDisplayAdminProductsExtra($params)
{
$productAdapter = $this->get('prestashop.adapter.data_provider.product');
$product = $productAdapter->getProduct($params['id_product']);
$formData = [
'ebay_reference' => $product->ebay_reference,
];
$formFactory = $this->get('form.factory');
$form = $formFactory->createBuilder(FormType::class, $formData)
->add('ebay_reference', TranslateType::class, array(
'required' => false,
'label' => 'Ebay reference',
'locales' => Language::getLanguages(),
'hideTabs' => true,
'required' => false
))
->getForm()
;
return $this->get('twig')->render(_PS_MODULE_DIR_.'MyModule/views/display-admin-products-extra.html.twig', [
'form' => $form->createView()
]) ;
}
public function hookActionAdminProductsControllerSaveBefore($params)
{
$productAdapter = $this->get('prestashop.adapter.data_provider.product');
$product = $productAdapter->getProduct($_REQUEST['form']['id_product']);
foreach(Language::getLanguages() as $language){
$product->ebay_reference[ $language['id_lang'] ] =
$_REQUEST['form']['ebay_reference'][$language['id_lang']];
}
$product->save();
}
I am stucked at data saving part. Need some guidance to it in recommended way. Also need the suggestion to read the code of any module bundled with prestashop to help in this.
Add field in product Prestashop 1.7
This part of the code just describes how to create a form with necessary fields but it doesn't handle product class extending. So if you would have this attribute(ebay_reference) with all relations in your product class everything would work. So I suppose that you need to implement steps for /classes/Product.php and for src/PrestaShopBundle/Model/Product/AdminModelAdapter.php from the original answer of here Add field in product Prestashop 1.7 and add necessary field to the DB.
Also, if you don't want to modify or override default product class, you can create own table(s) to keep your data there like with id_product key, but it could be more difficult to propagate that data to all product instances in the store.
Looking for some help adding sort by Rating in Magento. I have added code snippets to toolbar.php which seem to add the sort by Rating but when trying to select it, it gets stuck until I reload the page. Any help would be greatly appreciated. Code can be found below: This is the Toolbar.php file.
// Begin new Code
$this->getCollection()->joinField('rating',
'review/review_aggregate',
'rating_summary',
'entity_pk_value=entity_id',
'{{table}}.store_id=1',
'left');
// End new Code
AND
// Add rating to "Sort by"
$_availableOrder = $this->_availableOrder;
$_availableOrder['rating'] = 'Rating';
return $_availableOrder;
$this->_availableOrder = array(
‘rating_summary’ => Mage::helper(’catalog’)->__(’Rating’),
‘price’ => Mage::helper(’catalog’)->__(’Price’),
‘newest’ => Mage::helper(’catalog’)->__(’Newest’),
‘name’ => Mage::helper(’catalog’)->__(’Name’)
);
Best is to make this in a module but here you go:
First we shall alter the way products are retrieved from the database, to include the overall rating (shown as the number of stars on the product) along with the rest of the product attributes. Copy the file app/code/core/Mage/Catalog/Block/Product/List.php to app/code/local/Mage/Catalog/Block/Product/List.php and open it for editing.
In the new List.php file find the following line (around line 86):
$this->_productCollection = $layer->getProductCollection();
After this add the following:
$this->_productCollection->joinField('rating_summary', 'review_entity_summary', 'rating_summary', 'entity_pk_value=entity_id', array('entity_type'=>1, 'store_id'=> Mage::app()->getStore()->getId()), 'left');
Now we need to add in an option so that the customer can select "Rating" as an attribute to sort by. Copy the file app/code/core/Mage/Catalog/Model/Config.php to app/code/local/Mage/Catalog/Model/Config.php and edit.
In the new Config.php file find the following code (which should start around line 298):
$options = array(
'position' => Mage::helper('catalog')->__('Position')
);
Replace with code with:
$options = array(
'position' => Mage::helper('catalog')->__('Position'),
'rating_summary' => Mage::helper('catalog')->__('Rating')
);
Now when viewing categories on your website you should have an option of "Rating" in addition to the others. Note that the sort order defaults to ascending so the lowest rated products will be displayed first. The sort order can be changed by the customer by clicking the arrow next to the drop-down box. Aside from this caveat the new sort is fairly easy to implement and extends the usefulness of the ratings.
Credits: https://www.fontis.com.au/blog/sort-products-rating
Does anyone know how can I add a custom product attribute with a widget renderer?
You can see this in Promo rules if you select SKU you'll got an Ajax popup with product selection.
so how would I go about it?
in :
$installer->addAttribute(Mage_Catalog_Model_Product::ENTITY...
In other words, how can I use a widget to select custom attribute values?
EDIT:
The scenario is as follows:
I would like to create a product attribute that will, upon a button click, open a product selection widget.
After the selection, the selected SKU's will go in in a comma delimited format.
This behavior can be seen in the catalog and shopping cart price rules.
If you filter the rule by SKU (SKU attribute must be enabled to "apply to rules"), you'll get a field and a button that will open the product selection widget.
Here is some thoughts that should get you going on the right track:
First, in a setup script, create your entity:
$installer->addAttribute('catalog_product', 'frontend_display', array(
'label' => 'Display Test',
'type' => 'varchar',
'frontend_model' => 'Test_Module/Entity_Attribute_Frontend_CsvExport',
'input' => 'select',
'required' => 0,
'user_defined' => false,
'group' => 'General'
));
Make sure to set the frontend_model to the model that you are going to use. The frontend model affects the display of the attribute (both in the frontend and the adminhtml sections).
Next, create yourself the class, and override one or both of the following functions:
public function getInputType()
{
return parent::getInputType();
}
public function getInputRendererClass()
{
return "Test_Module_Block_Adminhtml_Entity_Renderer_CsvExport";
}
The first (getInputType()) is used to change the input type to a baked in input type (see Varien_Data_Form_Element_* for the options). However, to set your own renderer class, use the latter function - getInputRendererClass(). That is what I am going to demonstrate below:
public function getElementHtml()
{
return Mage::app()->getLayout()->createBlock('Test_Module/Adminhtml_ExportCsv', 'export')->toHtml();
}
Here, to clean things up, I am instantiating another block, as the element itself doesn't have the extra functions to display buttons and the like.
Then finally, create this file:
class Test_Module_Block_Adminhtml_ExportCsv extends Mage_Adminhtml_Block_Widget
{
protected function _prepareLayout()
{
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
->setData(array(
'label' => $this->__('Generate CSV'),
'onclick' => '',
'class' => 'ajax',
));
$this->setChild('generate', $button);
}
protected function _toHtml()
{
return $this->getChildHtml();
}
}
This doesn't cover the AJAX part, but will get you very close to getting the rest to work.
Hello I want to assign multiple groups to particular customer like "Rajat the customer" belogs to "Wholesale,retailer,electric". actually I saw the same thread on Multiple customer groups per customer but it is not helpful does there any update to make this change happen.
I am stuck what should I do because there aren't any extension available with the same functionality?
I found the solution,
First of all go to database and click on the eav_attribute and then search for group_id in the attribute code field and edit this record.
now Step 1:-
change frontend_input from select to multiselect.
step 2:-
change backend_type from static to varchar.
although it is not standard way but it worked for me. :)
PS. I'm using magento 1.7.0.2 community version.
Rajat Modi's solution worked pretty well for me thank you but doing this did break the display of the groups column on the customer grid if more than one is selected, plus broke the ability to filter customers by group.
To fix that, create this file to use as the renderer for customer groups: /app/code/local/Mage/Adminhtml/Block/Customer/Renderer/Group.php
<?php
class Mage_Adminhtml_Block_Customer_Renderer_Group
extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
public function render(Varien_Object $row)
{
$value = $row->getData($this->getColumn()->getIndex());
$groups = Mage::getModel('customer/group')->getCollection()
->addFieldToFilter('customer_group_id', array('in' => explode(',', $value)));
$groupNames = array();
foreach ($groups as $group)
{
$groupNames[] = $group->getCustomerGroupCode();
}
return implode(', ', $groupNames);
}
}
Then override /app/code/core/Mage/Adminhtml/Block/Customer/Grid.phpenter code here (copy it to /app/code/local/Mage/Adminhtml/Block/Customer/Grid.php)
In the _prepareColumns() function, change this (around line 95):
$this->addColumn('group', array(
'header' => Mage::helper('customer')->__('Group'),
'width' => '100',
'index' => 'group_id',
'type' => 'options',
'options' => $groups,
));
to this:
$this->addColumn('group_id', array(
'header' => Mage::helper('customer')->__('Group'),
'width' => '100',
'index' => 'group_id',
'type' => 'options',
'options' => $groups,
'renderer' => 'Mage_Adminhtml_Block_Customer_Renderer_Group',
'filter_condition_callback' => array($this, '_filterGroupCondition')
));
then it will use that class for rendering groups on the grid.
Also in the _prepareCollection() function, around line 52 find ->addAttributeToSelect('group_id') and add after: ->addAttributeToSelect('customer_group_id')
Having multiple groups per customer also seems to interfere with tiered pricing (where a product has a different price depending on customer group). To fix that on the frontend display...
Fix for customer group-based product pricing tiers when calculating on the front-end:
In /app/code/core/Mage/Catalog/Model/Product/Type/Price.php
Around line 138, FIND:
$customerGroup = $this->_getCustomerGroupId($product);
ADD AFTER:
$customerGroups = explode(',',$customerGroup);
FIND:
if ($groupPrice['cust_group'] == $customerGroup && $groupPrice['website_price'] < $matchedPrice) {
REPLACE WITH:
if (in_array($groupPrice['cust_group'],$customerGroups) && $groupPrice['website_price'] < $matchedPrice) {
Do the same thing in /app/code/core/Mage/Bundle/Model/Product/Price.php if you use bundles.
I do not yet have a fix for displaying the customer group tier price when creating an order or reorder from the backend dashboard - they just show up the standard product prices.
Finally, when figuring all this out we did have some instances where mgnt_catalog_product_entity_group_price got emptied and I'm still not sure why it happened, so do make sure to take backups. For that table I restored it from an SQL backup, but re-indexing things and maybe flushing the Magento cache is also often required when getting into this stuff.
When doing things such as searching for customers by group programmatically in your own scripts or modules you may have to take into account that it is now a multiselect for example by doing things like this:
$allowedGroups = array(
array(
"finset" => array(10)
),
array(
"finset" => array(42)
)
);
$collection = Mage::getModel('customer/customer')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('group_id', $allowedGroups);
Although I'm not sure that that piece of code will work right until all the customers have rows in the mgnt_customer_entity_varchar table which is where the new value for a customer's groups is stored when there are more than one group selected. Only a single group ID remains stored in mgnt_customer_entity as that field isn't varchar.
For that reason be aware that yes it can affect modules which extend or use the functionality of customer groups.
Im building an e-commerce site for wholesale foods and the pricing for products change depending on the user logged in. Ive looked at member pricing and basically every module i could find to do with altering the price but they are either for drupal 6 or not really what im after. Im using Drupal 7 with ubercart 3.
Ive found this module http://drupal.org/project/uc_custom_price. It adds a field within product creation that allows custom php code to be added to each individual product which is exactly what im after. however im not that good with php which is why ive been hunting modules instead of changing code.
What ive got at the moment is:
if ([roles] == 'test company') {
$item->price = $item->price*0.8;
}
Except the [roles] part is the wrong thing to use there and it just throws errors. Ive tried using things like $users->uid =='1' to try to hook onto a user like that but that didnt work either.
what would be the correct variable to put there?
thanks
try this Drupal 7 global $user object
global $user; // access the global user object
if(in_array("administrator",$user->roles)){ // if its administrator
$item->price = $item->price*0.8;
}elseif(in_array("vip",$user->roles)){ // if its a vip
//..
}elseif(in_array("UserCompanyX",$user->roles)){ // if its a user from company X
//..
}
or
if($user->roles[OFFSET] == "ROLE"){
// price calculation
}
$user->roles is an array of the roles assigned to the user.
hope it helped
Make your own module with UC Price API:
http://www.ubercart.org/docs/developer/11375/price_api
function example_uc_price_handler() {
return array(
'alter' => array(
'title' => t('Reseller price handler'),
'description' => t('Handles price markups by customer roles.'),
'callback' => 'example_price_alterer',
),
);
}
function example_price_alterer(&$price_info, $context, $options = array()){
global $user;
if (in_array("reseller", $user->roles)) { //Apply 30% reseller discount
$price_info["price"] = $context["subject"]["node"]->sell_price - (
$context["subject"]["node"]->sell_price * 0.30) ;
}
return;
}
See also: http://www.ubercart.org/forum/development/14381/price_alteration_hook