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.
Related
When creating an invoice with SugarCRM, in the invoice detail there's number of unit and unit price. I would like to populate the field line price automatically, which is simply the product of those two fields above.
Here is what I added in the custom/modules/C_Inc_Invoice_Detail directory :
logic_hook.php
<?php
$hook_version = 1;
$hook_array = array();
$hook_array['after_save'] = array();
$hook_array['after_save'][] = array(
1,
'Auto Fill Line price',
'custom/modules/C_Inv_Invoice_Detail/autofilllineprice.php',
'AutoFillLinePrice',
'autofilllineprice'
);
?>
and the autofilllineprice.php :
<?php
//prevents directly accessing this file from a web browser
if
(!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');
class AutoFillLinePrice {
function autofilllineprice($bean, $event, $arguments){
$line_price = $bean->unit_price * $bean->number_units;
}
}
?>
Could you advise ?
This post does not answer this question directly, but it documents the steps involved in accomplishing a similar requirement. The Accounts module in SugarCE-6.5.22 has a field Annual Revenue and it's displayed in the DetailView as shown below.
The following are the steps involved in adding a new field that displays the value of this field converted to some other currency.
The first step is to create a non-db field that will hold the value of this new currency. For this, we need to create two files, one that defines the field("custom_fields.php") and the other that defines a language specific dispplay value for this field("en_us_custom_fields.php"). These two files are to be created in the below mentioned location. Please create the required directory structure if not present already.
custom\Extension\modules\Accounts\Ext\Vardefs\custom_fields.php
<?php
if (!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');
$dictionary['Account']['fields']['annual_revenue_inr'] = array(
'name' => 'annual_revenue_inr',
'vname' => 'LBL_ANNUAL_REVENUE_INR',
'label'=>'LBL_ANNUAL_REVENUE_INR',
'type' => 'name',
'module' => 'Accounts',
'source' => 'non-db',
'studio' => array('detailview'=>true),
'default_value' => '',
'help' => 'Annual Revenue(INR)',
'comment' => 'Annual Revenue(INR)',
'reportable' => true,
'audited' => false,
'duplicate_merge' => false,
'importable' => 'true',
);
?>
custom\Extension\modules\Accounts\Ext\Language\en_us_custom_fields.php
<?php
if (!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');
$mod_strings['LBL_ANNUAL_REVENUE_INR'] = 'Annual Revenue(INR)';
?>
After adding these two files, we need to run Admin-->Repair-->Quick Repair and Rebuild. After it's complete, if we open Admin-->Studio and expand Accounts-->Layouts-->DetailView, we should see our newly created field available there. We can drag and drop it inside the layout wherever we want it to appear and click Save & Deploy.
Now, this new field should be visible in the detail view of the account.
The next task is to populate the value for this new currency. This can be achieved using logic hooks provided by SugarCRM. We need to compute the value for this field everytime after an account data is retrieved from database. The after_retrieve event can be used for this. First, let's create a php file("annual_revenue_hook.php") with code that computes the value of this new currency field in the following location.
custom\Extension\modules\Accounts\Ext\hooks\annual_revenue_hook.php
<?php
if (!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');
class AnnualRevenue {
function computeAnnualRevenueINR($bean, $event, $arguments){
$bean->annual_revenue_inr = $bean->annual_revenue * 100;
}
}
?>
To register the above hook, we need to edit the logic_hooks.php file of the module and add the following lines:
custom\modules\Accounts\logic_hooks.php
//Create a new array that holds after_retrieve event hooks if not present already
$hook_array['after_retrieve'] = Array();
//Register our annual revenue hook for computing new currency value
$hook_array['after_retrieve'][]= Array(1, 'Compute Annual Revenue in INR', 'custom/Extension/modules/Accounts/Ext/hooks/annual_revenue_hook.php','AnnualRevenue', 'computeAnnualRevenueINR');
After completing these steps, we should see the value of the new currency populated in the detail view as shown below:
It's also possible to get data from associated modules. For example, let's say we need to calculate the sum of all Opportunities associated with this Account and add to our new field. The following are the steps to accomplish it:
The first step is to get the relationship information between the modules, in this case between Accounts and Opportunities. We need to open the file modules\Accounts\vardefs.php and search for Opportunities. It should give us the following information.
'opportunities' =>
array (
'name' => 'opportunities',
'type' => 'link',
'relationship' => 'accounts_opportunities',
'module'=>'Opportunities',
'bean_name'=>'Opportunity',
'source'=>'non-db',
'vname'=>'LBL_OPPORTUNITY',
),
Then, we can open Admin-->Studio, expand Accounts-->Relationships and find the type of relationship as shown below:
Now that we have identified the relationship information, we can edit our existing hook as shown below:
custom\Extension\modules\Accounts\Ext\hooks\annual_revenue_hook.php
<?php
if (!defined('sugarEntry') ||!sugarEntry) die('Not A Valid Entry Point');
class AnnualRevenue {
function computeAnnualRevenueINR($bean, $event, $arguments){
$bean->annual_revenue_inr = $bean->annual_revenue * 100;
$bean->load_relationship('opportunities');
$opportunities = $bean->opportunities->getBeans();
//Every account has multiple opportunities i.e array of Opportunity
foreach($opportunities as $opportunity){
$bean->annual_revenue_inr = $bean->annual_revenue_inr + $opportunity->amount;
}
}
}
?>
The above code should now multiply annual_revenue by 100 and also sum up all the associated Opportunities with it to calculate the value of annual_revenue_inr.
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
I'm planning to build an extension like Shopping Cart, Price Rule, or Catalog Price Rule.
I've already tried to learn something from existing Magento code, that you can see on:
app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Conditions.php
To show a Conditions Rule field, I've tried to add this script, but it didn't work properly
$fieldset->addField('conditions', 'text', array(
'name' => 'conditions',
'label' => Mage::helper('salesrule')->__('Conditions'),
'title' => Mage::helper('salesrule')->__('Conditions'),
))->setRule($model)->setRenderer(Mage::getBlockSingleton('rule/conditions'));
The question is:
How to display the conditional field properly on my custom field?
How to apply rule conditions on the front-end?
Thanks in advance.
update,
take a look at my screenshot
https://docs.google.com/file/d/0BwLN4KpQhoGbU181R0ZKanJSdVE/edit?usp=drivesdk
this is my form.php:
<?php
class KS_Kscoba_Block_Adminhtml_Tcoba_Edit_Tab_Form
extends Mage_Adminhtml_Block_Widget_Form
/*
extends Mage_Adminhtml_Block_Widget_Form
implements Mage_Adminhtml_Block_Widget_Tab_Interface
*/
{
protected function _prepareForm()
{
$model = Mage::registry('current_promo_quote_rule');
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset("kscoba_form", array("legend"=>Mage::helper("kscoba")->__("Item information")));
$fieldset->addField("kolom1", "text", array(
"label" => Mage::helper("kscoba")->__("Kolom 1"),
"name" => "kolom1",
));
$fieldset->addField('kolom2', 'select', array(
'label' => Mage::helper('kscoba')->__('Kolom 2'),
'values' => KS_Kscoba_Block_Adminhtml_Tcoba_Grid::getValueArray1(),
'name' => 'kolom2',
));
/*
problem start here
*/
$renderer = Mage::getBlockSingleton('adminhtml/widget_form_renderer_fieldset')
->setTemplate('promo/fieldset.phtml')
->setNewChildUrl($this->getUrl('*/promo_quote/newConditionHtml/form/rule_conditions_fieldset'));
$fieldset = $form->addFieldset('conditions_fieldset', array(
'legend'=>Mage::helper('salesrule')->__('Apply the rule only if the following conditions are met (leave blank for all products)')
))->setRenderer($renderer);
$fieldset->addField('conditions', 'text', array(
'name' => 'conditions',
'label' => Mage::helper('salesrule')->__('Conditions'),
'title' => Mage::helper('salesrule')->__('Conditions'),
))->setRule($model)->setRenderer(Mage::getBlockSingleton('rule/conditions'));
if (Mage::getSingleton("adminhtml/session")->getTcobaData())
{
$form->setValues(Mage::getSingleton("adminhtml/session")->getTcobaData());
Mage::getSingleton("adminhtml/session")->setTcobaData(null);
}
elseif(Mage::registry("tcoba_data")) {
$form->setValues(Mage::registry("tcoba_data")->getData());
}
return parent::_prepareForm();
}
}
am I missing something?
1. Conditions Field
I may be overlooking another issue, but when I tested your form.php, the conditions field was missing because Mage::registry('current_promo_quote_rule') was undefined. The conditions field appeared on the page after I populated $model with a Mage_SalesRule_Model_Rule object.
Magento 1.8 registers the current_promo_quote_rule in _initRule() and editAction() of the Mage_Adminhtml_Promo_QuoteController (app/code/core/Mage/Adminhtml/controllers/Promo/QuoteController.php).
2. Frontend
Using shopping cart price rules as an example, the discounted price is applied in the frontend through the checkout module.
Mage/Checkout/controllers/CartController.php has a couponPostAction() function which is called when the user submits a coupon code from the cart or checkout page. This function gets the cart's Mage_Sales_Model_Quote object, sets the coupon code on that object, and refreshes the totals of each item using the collectTotals() function of Mage_Sales_Model_Quote.
The quote object's collectTotals() gets the related Mage_Sales_Model_Quote_Address objects and calls their collectTotals() functions. Those functions get each of the collector objects associated with the address and call its collect() method.
One of those collector objects is a Mage_SalesRule_Model_Quote_Discount, whose collect() method gets each Mage_Sales_Model_Quote_Item associated with this address, then calculates and stores its discount using a Mage_SalesRule_Model_Validator.
The specific logic in the conditions is read and applied deeper in the SalesRule module.
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.
In the magento system, I added the columns subscriber_firstname and subscriber_lastname to the newsletter_subscriber db table.
In the admin area of magento, I want the Newsletter>Newsletter Subscribers grid table to show:
customer first name if it exists, otherwise show newsletter_subscriber.subscriber_firstname if it exists, otherwise show nothing
customer last name if it exists, otherwise show newsletter_subscriber.subscriber_lastname if it exists, otherwise show nothing
Which magento files do I need to edit to make this work? How do I go about editing the files to make this work?
app/code/core/Mage/Adminhtml/Block/Newsletter/Subscriber/Grid.php
You'll want to condition this based off if subscriber_firstname or subscriber_lastname have values or not:
$this->addColumn('subscribername', array(
'header' => Mage::helper('newsletter')->__('Subscriber First Name'),
'index' => 'subscriber_firstname',
'default' => '----'
));
Also, make sure to make a copy of the core files and NOT edit them directly!
the quick and easy solution is to create a column render and select the correct field based on the subscriber type e.g.
app/code/local/Mage/Adminhtml/Block/Newsletter/Subscriber/Renderer/FirstName.php
class Mage_Adminhtml_Block_Newsletter_Subscriber_Renderer_FirstName extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract {
public function render(Varien_Object $row) {
$value = '';
if ($row->getData('type') == 2) {
$value = $row->getData('customer_firstname');
}
else {
$value = $row->getData('subscriber_firstname');
}
return $value;
}
}
then add your render to a local copy of the subscriber grid class
app/code/local/Mage/Adminhtml/Block/Newsletter/Subscriber/Grid.php
$this->addColumn('firstname', array(
'header' => Mage::helper('newsletter')->__('First Name'),
'index' => 'customer_firstname',
'default' => '----',
'renderer' => 'Mage_Adminhtml_Block_Newsletter_Subscriber_Renderer_FirstName'
));
Note. the search and sort will not work on the subscriber name fields, to get this working you will need to extend app/code/core/Mage/Newsletter/Model/Mysql4/Subscriber/Collection.php