I asked a similar question but I did not provide sufficient details and I got no answers so I will try again.
The main task is to add fields to the CSV file that is exported under the magento admin sales->invoices. I found the main file to edit:
app/code/core/Mage/Adminhtml/Block/Sales/Invoice/Grid.php
This has the options to addColumn's like so:
$this->addColumn('increment_id', array(
'header' => Mage::helper('sales')->__('Invoice #'),
'index' => 'increment_id',
'type' => 'text',
));
Now when I try to add new Column's I change the index to the appropriate database field, lets say 'tax amount' for example. The only problem is that this new value is not in my Magento collection, so it simply populates an empty column in the table.
I am quite new to Magento so I don't fully understand how the Magento collection works or how I can access it for the scope of grid.php. Could someone please give me some direction in how to add to the collection?
I'm really stuck and would appreciate the help.
You basically need to edit the resource model to include the fields you want to include. You can edit the resource in code, I'm not sure what version your using but in the Grid.php file you'll see the _prepareCollection find the code that looks like,
$collection = Mage::getResourceModel('sales/order_invoice_collection')
->addAttributeToSelect('order_id')
->addAttributeToSelect('increment_id')
->addAttributeToSelect('created_at')
->addAttributeToSelect('state')
->addAttributeToSelect('grand_total') ...and so on!
add the line
->addAttributeToSelect('tax_amount')
to that list and the you should be able to use
$this->addColumn('tax_amount', array(
'header' => Mage::helper('sales')->__('Tax'),
'index' => 'tax_amount',
'type' => 'number',
));
This is as untest as I am away from my dev machine and dont have Mage to hand, but this should work or at very least point you in the right direction.
Edit:
Failing that you could try replacing your whole _prepareCollection
protected function _prepareCollection()
{
$collection = Mage::getResourceModel('sales/order_invoice_collection')
->addAttributeToSelect('order_id')
->addAttributeToSelect('increment_id')
->addAttributeToSelect('created_at')
->addAttributeToSelect('state')
->addAttributeToSelect('grand_total')
->addAttributeToSelect('tax_amount')
->addAttributeToSelect('order_currency_code')
->joinAttribute('billing_firstname', 'order_address/firstname', 'billing_address_id', null, 'left')
->joinAttribute('billing_lastname', 'order_address/lastname', 'billing_address_id', null, 'left')
->joinAttribute('order_increment_id', 'order/increment_id', 'order_id', null, 'left')
->joinAttribute('order_created_at', 'order/created_at', 'order_id', null, 'left');
$this->setCollection($collection);
return parent::_prepareCollection();
}
Again this is untested, from memory this is the _prepareCollection from the 1.3 range of magento so its a little old, but quite sure it should work.
Related
I have a base extension so i can version my website. That means i have not a controller or a repository on the extension. So what i want to do, is to create my own settings on existing elements. I was experimenting around with a text align values on the header content element.
Keep in mind, there is already a setting for this, but i am just
experimenting.
I figured out how to add them and the values are saved on the database.
What i now want to do, is to take the values and add them as a class on FLUID. This is where i stuck. I can not get the values. Any idea how to do it?
After this guide How to enable header_position in TYPO3 7.6
i manage to get my code that far:
On the folder /Configuration/TCA/Overrides/tt_content.php
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
ExtensionManagementUtility::addTCAcolumns('tt_content',[
'header_position_custom' => [
'exclude' => 1,
'label' => 'header position',
'config' => [
'type' => 'select',
'renderType' => 'selectSingle',
'items' => [
['left', 'left'],
['right', 'right'],
['center', 'center']
]
]
]
]);
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'header', '--linebreak--,header_position_custom', 'after:header_layout');
ExtensionManagementUtility::addFieldsToPalette('tt_content', 'headers', '--linebreak--,header_position_custom', 'after:header_layout');
On the folder /Configuration/Typoscript/Constants/Base.typoscript
styles.templates.templateRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Templates/
styles.templates.partialRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Partials/
styles.templates.layoutRootPath = EXT:my_website_base/Resources/Private/Extensions/Fluid_styled_content/Resources/Private/Layouts/
On the /Resources/Private/Extensions/Fluid_styled_content/Resourcs/Private/Partials/Header.html
<h1 class="{positionClass} {header_position_custom} {data.header_position_custom} showed">
<f:link.typolink parameter="{link}">{header}</f:link.typolink>
</h1>
I 've put the class showed just to make sure that i am reading the
file from the path i gave on the constants
File ext_tables.php
TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY,'Configuration/TypoScript', 'Website Base');
File ext_tables.sql
CREATE TABLE tt_content (
header_position_custom varchar(255) DEFAULT '' NOT NULL,
);
With all these i get my selectbox where i wanted to be and i get the values on the database. That means that if i select the value "Center" in the selectbox, then it will be saved on the database. How can i get this value and use it as class on the FLUID?
Thanks in advance,
You will find your field in the data object.
For inspecting your fluid variables you can use the f:debug-VH:
<f:debug title="the data">{data}</f:debug>
for inspecting all (in the current context) available variables you can debug _all:
<f:debug title="all data">{_all}</f:debug>
Hint: use the title attribute to identify the output
and don't forget to write a get* and set* function for new fields!
I have modified my model so that the data displayed in cgridview is unique per user, depending on the account type...
However I need to create a form from another model where I could get the data from the cgridview via dropdown...
I used this code at first...
<?php
$this->widget('ext.select2.ESelect2',array(
'model'=>$model,
'attribute'=>'pr_id',
'data'=>$model->searchPatient(),//function to provide data
// or
//'data'=>CHtml::listData(PatientRecord::model()->findAll(), 'id', 'first_name')
);
?>
but it returns all of the contents of the PatientRecord model, I tried using a condition before planning to retrieve the contents from the cgridview...
$doctor= Yii::app()->user->id;
CHtml::listData(PatientRecord::model()->findAll( array(
'condition'=>'doctor_id=:doctor_id',
'params' => array(':doctor_id' => $doctor)
)
);), 'id', 'first_name')
it didn't have an error but it didn't display anything on the dropdown either...
any suggestions?
I think the problem is with a ; and ) in your model code, try this:
$doctor= Yii::app()->user->id;
CHtml::listData(PatientRecord::model()->findAll( array(
'condition'=>'doctor_id=:doctor_id',
'params' => array(':doctor_id' => $doctor)
)
), 'id', 'first_name');
You should always enable error logging in local environment, this will help you find any errors in your code. Here is a link on how to enable error logging.
Hope that helps :)
My issue is two-fold. First, I'm unable to correctly set the keyField for CArrayDataProvider, all I'm getting back is a string instead of a value. Second, I'm trying to use the keyField inside of CArrayDataProvider to set an id on the button in each row inside of CGridView. The reason I want to do this is so that I can pass the id value onward to an ajax function (if there's a better way to do this in Yii, I'm all ears). Any help would be much appreciated, thanks in advance!
I also posted this question once on Yii's forums. I normally wouldn't repost, but I have had a hard time getting answers there, as opposed to stack overflow, you guys are the best! Here's the link to my original post if anyone is interested.
Here is how I'm building the array that I'm using as my RAW data:
foreach ($items as $item) {
$tableRow = array("id"=>$item["Id"], "Organization"=>$item["Organization"], "Roles"=>$item["Roles"]);
$return_items[] = $tableRow;
}
Here is the CArrayDataProvider setup I'm using. I noticed that 'keyField' is not being given the id value, just the string 'id':
$dataProvider=new CArrayDataProvider($return_items, array(
'keyField'=>'id',
'sort'=>array(
'attributes'=>array(
'Organization',
'Roles',
),
),
'pagination'=>array(
'pageSize'=>10,
),
));
Lastly, here is the CGridView I'm trying to setup in the view. All that appears on the button is the id tag, but no value:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$authItems,
'columns'=>array(
'Organization',
'Roles',
array('name'=>'',
'type'=>'raw',
'htmlOptions'=>array('id'=>'id'),
'value'=>'CHtml::button("Edit Roles", array("data-toggle"=>"modal", "data-target"=>"#roles-modal"))'),
),
));
Try passing it via CHtml::button which you have already applied. E.g.
'value'=>'CHtml::button("Edit Roles", array(
"id"=>$data["id"],
"data-toggle"=>"modal",
"data-target"=>"#roles-modal"
))'),
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.
I have rewritten the app/code/core/Mage/Adminhtml/Block/Sales/Order/Grid.php
with app/code/local/Mage/Adminhtml/Block/Sales/Order/Grid.php
& have created a renderer to display customer's email column in grid.
Here is my renderer file:
class Mage_Adminhtml_Block_Renderer_Customer extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
{
public function render(Varien_Object $row)
{
$model = Mage::getModel('customer/customer')->load($row->getCustomerId());
return $model->getEmail();
}
}
& here is my Grid changes (I just added a column, & I intend to make it search-able)
$this->addColumn('billing_name', array(
'header' => Mage::helper('sales')->__('Bill to Name'),
'index' => 'billing_name',
));
// this is new col.
$this->addColumn('customer_email', array(
'header' => Mage::helper('sales')->__('Customer Email'),
'renderer' => 'adminhtml/renderer_customer',
));
I am getting what I want. But this col/ has a lot of whitespace both leading & trailing
due to this I think this col. is not search-able.
Can Anybody suggest what can be done in order to remove these white spaces
Many thanks in advance
EDIT
After few days I have figured out that these white spaces are common in the grid & it has nothing to do with the search-able option.
Can anybody suggest that how to make a custom column in search-able that has been added to a grid by using a renderer ???
Thanks
2 EDIT
Guys According to the clockworkgeek I have customized
my _prepareCollection() method of the overwritten grid as follows
protected function _prepareCollection()
{
// 'sales/order_collection' is changed from 'sales/order_grid_collection'
$collection = Mage::getResourceModel('sales/order_collection');
$collection->addAttributeToSelect('*')
->joinAttribute('billing_firstname', 'order_address/firstname', 'billing_address_id', null, 'left')
->joinAttribute('billing_lastname', 'order_address/lastname', 'billing_address_id', null, 'left')
->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
->joinAttribute('billing_fax', 'order_address/fax', 'billing_address_id', null, 'left')
->joinAttribute('billing_telephone', 'order_address/telephone', 'billing_address_id', null, '')
->addExpressionAttributeToSelect('billing_name',
'CONCAT({{billing_firstname}}, " ", {{billing_lastname}})',
array('billing_firstname', 'billing_lastname'))
->addExpressionAttributeToSelect('shipping_name',
'CONCAT({{shipping_firstname}}, " ", {{shipping_lastname}})',
array('shipping_firstname', 'shipping_lastname'));
$this->setCollection($collection);
return parent::_prepareCollection();
}
I also have investigated that for Grid Magento obtains data from sales_flat_order_grid table not from sales_flat_order this is the reason it was reporting error of unknow column as per the clockworkgeek first solution
THe issue with current implementation is Magento reports an error Fatal error: Call to undefined method Mage_Sales_Model_Mysql4_Order_Collection::addExpressionAttributeToSelect()
as Mage_Sales_Model_Mysql4_Order_Collection does not have addExpressionAttributeToSelect method instead it has addExpressionFieldToSelect method
Now I need help to write a proper syntax for addExpressionAttributeToSelect method. Changing the method name only is not helping me. I also have referred the docs
Add 'index' => 'email' to your addColumn() in the Grid.php and then try something like this:
$emailaddress = trim($row->getData($this->getColumn()->getIndex()));
return ''.$emailaddress.'';
That way you strip the whitespace and also provide a clickable link for your admin users :)
In response to the second part of your question may I offer this little trick.
Adminhtml grid columns can take an extra filter_condition_callback parameter which takes a standard PHP callback type. In your case you might modify the grid like this:
protected function _prepareColumns() {
// ...
$this->addColumn('customer_email', array(
'header' => Mage::helper('sales')->__('Customer Email'),
'renderer' => 'adminhtml/renderer_customer',
'filter_condition_callback' => array($this, 'addCustomerEmailFilter'),
));
}
public function addCustomerEmailFilter(Mage_Eav_Model_Entity_Collection_Abstract $collection, Mage_Adminhtml_Block_Widget_Grid_Column $column) {
$collection->addAttributeToFilter('customer_email', $column->getFilter()->getValue());
}
But all that still feels a bit messy, especially if the attribute is not a first class column. For those unusual cases you can combine the output processing and searching in the collection class...
protected function _initSelect() {
parent::_initSelect();
// email is existing column, customer_email is generated column
$this->addExpressionAttributeToSelect(
'customer_email',
'TRIM({{email}})',
array('email')
);
return $this;
}
The addExpressionAttributeToSelect() method temporarily stores the SQL expression as a mapped field so that when a grid tries to search for customer_email it gets substituted by the expression instead.