Add website field using event observer in magento admin role permissions - magento

I'm creating a module that allows the user to choose the website during creating a role permission (System -> Permission -> Role -> Add New role -> Role Resource). I'm using an observer to achieve this, however I cannot get the form object.
Observer.php
class Mymodule_Mycompany_Model_Observer
{
public function appendCustomRow(Varien_Event_Observer $observer)
{
$block = $observer->getEvent()->getBlock();
if (!isset($block)) {
return $this;
}
if ($block->getType() == 'adminhtml/permissions_editroles') {
//get form instance
$form = $observer->getEvent()->getForm();
//create new custom fieldset 'website'
$fieldset = $form->addFieldset('website', array(
'legend' => 'Website Extras',
'class' => 'fieldset-wide'
)
);
//add new field
$fieldset->addField('website', 'text', array(
'name' => 'website',
'label' => Mage::helper('adminhtml')->__('Website'),
'title' => Mage::helper('adminhtml')->__('Website'),
'disabled' => false,
));
}
}
}
Mymodule/Mycompany/etc/config.xml
<adminhtml>
<events>
<core_block_abstract_prepare_layout_before>
<observers>
<Event_column_append>
<type>model</type>
<class>Mymodule_Mycompany_Model_Observer</class>
<method>appendCustomColumn</method>
</Event_column_append>
</observers>
</core_block_abstract_prepare_layout_before>
</events>
</adminhtml>

I worked it out. Here is the modified piece of code that works
public function appendCustomColumn(Varien_Event_Observer $observer)
{
$block = $observer->getEvent()->getBlock();
if (!isset($block)) {
return $this;
}
if ($block->getType() == 'adminhtml/permissions_tab_roleinfo') {
//get form instance
$form = $block->getForm();
//create new custom fieldset 'website'
$fieldset = $form->addFieldset(
'website_field',
array(
'legend' => 'Website Extras',
'class' => 'fieldset-wide'
)
);
//add new field
$fieldset->addField('website', 'text', array(
'name' => 'website',
'label' => Mage::helper('adminhtml')->__('Website'),
'title' => Mage::helper('adminhtml')->__('Website'),
'disabled' => false,
));
}
}
XML Configuration:
<events>
<adminhtml_block_html_before>
<observers>
<Event_column_append>
<type>model</type>
<class>Mymodule_Mycompany_Model_Observer</class>
<method>appendCustomColumn</method>
</Event_column_append>
</observers>
</adminhtml_block_html_before>
</events>
You need to use the event 'adminhtml_block_html_before' as the event which you were using did not even create the form object. That is why you were nt able to access the form object.
The block that is creating this form elements was 'adminhtml/permissions_tab_roleinfo'.
The method you were using was the not same one in the observer.
Hope that helps :)...
Cheers,
Swapna

Related

Making Column Grid Filter Accept Complex Value In Magento

In Magento, there's a column in Product Grid/Table which is Name.
It only accepts or filter the table if you put the exact word/s.
Sample is "What Happened Last Night" (just an example)
If you put "What" it will filter correctly, if you add "Happened" it will still filter correctly but if you input "What Last" it will return 0 records unless there's a "What Last" record.
I have this code in the core itself.
$this->addColumn('name',
array(
'header'=> Mage::helper('catalog')->__('Name'),
'index' => 'name',
'filter_condition_callback' => array($this, '_customNameFilter'),
));
$store = $this->_getStore();
if ($store->getId()) {
$this->addColumn('name_search', array(
'header'=> Mage::helper('catalog')->__('Name in %s', $store->getName()),
'type' => 'text',
'filter_condition_callback' => array($this, '_customNameFilter'),
));
}
Based on this link, Grid filter for columns with complex values
I need to remove the index and adjust something or some files in which I'm totally lost as the author did not mention the file paths used.
Can anyone guide me on what file should I adjust or create if needed.
The Code above has the file path of
app\code\core\Mage\Adminhtml\Block\Catalog\Product\Grid.php
What other files/modules should I adjust an what lines of code should I'd be looking at to attain this result.
I could not thank you enough for assisting me.
here is a working solution for your case
protected function _customNameFilter($collection, $column)
{
if (!$value = $column->getFilter()->getValue()) {
return $this;
} else if (preg_match('/\s+/', $value)) {
$tokens = explode(' ', $value);
foreach($tokens as $token) {
$this->getCollection()->addAttributeToFilter($column->getData('index'), array('like' => '%'.$token.'%'));
}
} else {
$this->getCollection()->addAttributeToFilter($column->getData('index'), array('like' => '%'.$value.'%'));
}
return $this;
}
this space tokenizer filter will also work with any other grid field.
Atwix example will not solve the problem you described. If you want to make a filter smart enough to be on-the-fly tokenizer you will have to split the search string by spaces and add each token to where part of the query with "OR LIKE %'.$token.'%"
Solution
you will have to rewrite Mage_Adminhtml_Block_Catalog_Product_Grid in a local Module with following xml:
/app/code/local/Your/Module/etc/config.xml
<global>
<blocks>
<adminhtml>
<rewrite>
<catalog_product_grid>Your_Module_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
and add following methods into class
/app/code/local/Your/Module/Block/Adminhtml/Catalog/Product/Grid.php
class Your_Module_Block_Adminhtml_Catalog_Product_Grid extends Mage_Adminhtml_Block_Catalog_Product_Grid {
protected function _prepareColumns()
{
$this->addColumn('name_search', array(
'header'=> Mage::helper('catalog')->__('Name in %s', $store->getName()),
'type' => 'text',
'filter_condition_callback' => array($this, '_customNameFilter'),
));
return parent::_prepareColumns();
}
protected function _customNameFilter($collection, $column)
{
if (!$value = $column->getFilter()->getValue()) {
return $this;
}
$tokens = explode(' ', $value);
$where = "LIKE '%".$value."%'";
foreach($tokens as $token) {
$where .= " OR LIKE '%".$token."%'";
}
$this->getCollection()->getSelect()->where(
"(at_name.value ?)"
, $where);
return $this;
}
}
And dont forget to rename Your_Module with your own namespace and add module description xml to /app/etc/modules/
you're welcome

Magento order split through observer

I was wondering if we can split the order on onepage checkout before placing the order? And I want to do it Through observer.
I am using sales_order_place_before event to get the quote and split order.
I have tried to do it in observer like:
$productids=array(1,2);
$websiteId = Mage::app()->getWebsite()->getId();
$store = Mage::app()->getStore();
// Start New Sales Order Quote
$quote = Mage::getModel('sales/quote')->setStoreId($store->getId());
// Set Sales Order Quote Currency
$quote->setCurrency($order->AdjustmentAmount->currencyID);
$customer = Mage::getModel('customer/customer')
->setWebsiteId($websiteId)
->loadByEmail($email);
if($customer->getId()==""){
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId($websiteId)
->setStore($store)
->setFirstname('Jhon')
->setLastname('Deo')
->setEmail($email)
->setPassword("password");
$customer->save();
}
// Assign Customer To Sales Order Quote
$quote->assignCustomer($customer);
// Configure Notification
$quote->setSendCconfirmation(1);
foreach($productsids as $id){
$product=Mage::getModel('catalog/product')->load($id);
$quote->addProduct($product,new Varien_Object(array('qty' => 1)));
}
// Set Sales Order Billing Address
$billingAddress = $quote->getBillingAddress()->addData(array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => 'john',
'middlename' => '',
'lastname' =>'Deo',
'suffix' => '',
'company' =>'',
'street' => array(
'0' => 'Noida',
'1' => 'Sector 64'
),
'city' => 'Noida',
'country_id' => 'IN',
'region' => 'UP',
'postcode' => '201301',
'telephone' => '78676789',
'fax' => 'gghlhu',
'vat_id' => '',
'save_in_address_book' => 1
));
// Set Sales Order Shipping Address
$shippingAddress = $quote->getShippingAddress()->addData(array(
'customer_address_id' => '',
'prefix' => '',
'firstname' => 'john',
'middlename' => '',
'lastname' =>'Deo',
'suffix' => '',
'company' =>'',
'street' => array(
'0' => 'Noida',
'1' => 'Sector 64'
),
'city' => 'Noida',
'country_id' => 'IN',
'region' => 'UP',
'postcode' => '201301',
'telephone' => '78676789',
'fax' => 'gghlhu',
'vat_id' => '',
'save_in_address_book' => 1
));
if($shipprice==0){
$shipmethod='freeshipping_freeshipping';
}
// Collect Rates and Set Shipping & Payment Method
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod('flatrate_flatrate')
->setPaymentMethod('checkmo');
// Set Sales Order Payment
$quote->getPayment()->importData(array('method' => 'checkmo'));
// Collect Totals & Save Quote
$quote->collectTotals()->save();
// Create Order From Quote
$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$increment_id = $service->getOrder()->getRealOrderId();
// Resource Clean-Up
$quote = $customer = $service = null;
// Finished
return $increment_id;
But it is not proceeding further.
Any help with the observer code will be appreciated.
thanks
Here is what i have achieved until now
created new module
installation file
<?xml version="1.0"?>
<config>
<modules>
<PMTECH_Splitorder>
<active>true</active>
<codePool>local</codePool>
<version>0.1.0</version>
</PMTECH_Splitorder>
</modules>
</config>
and here is the config.xml
<?xml version="1.0"?>
<config>
<modules>
<PMTECH_Splitorder>
<version>0.1.0</version>
</PMTECH_Splitorder>
</modules>
<global>
<helpers>
<splitorder>
<class>PMTECH_Splitorder_Helper</class>
</splitorder>
</helpers>
<models>
<splitorder>
<class>PMTECH_Splitorder_Model</class>
<resourceModel>splitorder_mysql4</resourceModel>
</splitorder>
<checkout>
<rewrite>
<type_onepage>PMTECH_Splitorder_Model_Checkout_Type_Onepage</type_onepage>
</rewrite>
</checkout>
</models>
</global>
</config>
look at the rewrite
<checkout>
<rewrite>
<type_onepage>PMTECH_Splitorder_Model_Checkout_Type_Onepage</type_onepage>
</rewrite>
</checkout>
Bellow is the final thing, the extended function
<?php
class PMTECH_Splitorder_Model_Checkout_Type_Onepage extends Mage_Checkout_Model_Type_Onepage
{
/**
* Create order based on checkout type. Create customer if necessary.
*
* #return Mage_Checkout_Model_Type_Onepage
*/
public function saveOrder()
{
$this->validate();
$isNewCustomer = false;
switch ($this->getCheckoutMethod()) {
case self::METHOD_GUEST:
$this->_prepareGuestQuote();
break;
case self::METHOD_REGISTER:
$this->_prepareNewCustomerQuote();
$isNewCustomer = true;
break;
default:
$this->_prepareCustomerQuote();
break;
}
$cart = $this->getQuote();
$key=0;
foreach ($cart->getAllItems() as $item)
{
$key= $key+1;
$temparray[$key]['product_id']= $item->getProduct()->getId();
$temparray[$key]['qty']= $item->getQty();
$cart->removeItem($item->getId());
$cart->setSubtotal(0);
$cart->setBaseSubtotal(0);
$cart->setSubtotalWithDiscount(0);
$cart->setBaseSubtotalWithDiscount(0);
$cart->setGrandTotal(0);
$cart->setBaseGrandTotal(0);
$cart->setTotalsCollectedFlag(false);
$cart->collectTotals();
}
$cart->save();
foreach ($temparray as $key => $item)
{
$customer_id = Mage::getSingleton('customer/session')->getId();
$store_id = Mage::app()->getStore()->getId();
$customerObj = Mage::getModel('customer/customer')->load($customer_id);
$quoteObj = $cart;
$storeObj = $quoteObj->getStore()->load($store_id);
$quoteObj->setStore($storeObj);
$productModel = Mage::getModel('catalog/product');
$productObj = $productModel->load($item['product_id']);
$quoteItem = Mage::getModel('sales/quote_item')->setProduct($productObj);
$quoteItem->setBasePrice($productObj->getFinalPrice());
$quoteItem->setPriceInclTax($productObj->getFinalPrice());
$quoteItem->setData('original_price', $productObj->getPrice());
$quoteItem->setData('price', $productObj->getPrice());
$quoteItem->setRowTotal($productObj->getFinalPrice());
$quoteItem->setQuote($quoteObj);
$quoteItem->setQty($item['qty']);
$quoteItem->setStoreId($store_id);
$quoteObj->addItem($quoteItem);
$quoteObj->setBaseSubtotal($productObj->getFinalPrice());
$quoteObj->setSubtotal($productObj->getFinalPrice());
$quoteObj->setBaseGrandTotal($productObj->getFinalPrice());
$quoteObj->setGrandTotal($productObj->getFinalPrice());
$quoteObj->setStoreId($store_id);
$quoteObj->collectTotals();
$quoteObj->save();
$this->_quote=$quoteObj;
$service = Mage::getModel('sales/service_quote', $quoteObj);
$service->submitAll();
if ($isNewCustomer) {
try {
$this->_involveNewCustomer();
} catch (Exception $e) {
Mage::logException($e);
}
}
$this->_checkoutSession->setLastQuoteId($quoteObj->getId())
->setLastSuccessQuoteId($quoteObj->getId())
->clearHelperData();
$order = $service->getOrder();
if ($order) {
Mage::dispatchEvent('checkout_type_onepage_save_order_after',
array('order'=>$order, 'quote'=>$quoteObj));
$quoteObj->removeAllItems();
$quoteObj->setTotalsCollectedFlag(false);
$quoteObj->collectTotals();
}
/**
* a flag to set that there will be redirect to third party after confirmation
* eg: paypal standard ipn
*/
$redirectUrl = $this->getQuote()->getPayment()->getOrderPlaceRedirectUrl();
/**
* we only want to send to customer about new order when there is no redirect to third party
*/
if (!$redirectUrl && $order->getCanSendNewEmailFlag()) {
try {
$order->sendNewOrderEmail();
} catch (Exception $e) {
Mage::logException($e);
}
}
// add order information to the session
$this->_checkoutSession->setLastOrderId($order->getId())
->setRedirectUrl($redirectUrl)
->setLastRealOrderId($order->getIncrementId());
// as well a billing agreement can be created
$agreement = $order->getPayment()->getBillingAgreement();
if ($agreement) {
$this->_checkoutSession->setLastBillingAgreementId($agreement->getId());
}
}
// add recurring profiles information to the session
$profiles = $service->getRecurringPaymentProfiles();
if ($profiles) {
$ids = array();
foreach ($profiles as $profile) {
$ids[] = $profile->getId();
}
$this->_checkoutSession->setLastRecurringProfileIds($ids);
// TODO: send recurring profile emails
}
Mage::dispatchEvent(
'checkout_submit_all_after',
array('order' => $order, 'quote' => $this->getQuote(), 'recurring_profiles' => $profiles)
);
return $this;
}
}
NOTE this script still fails to split the order total, which i am working on and will update you once done
Here is the code on github, you are welcome to contribute

Magento 1.7 : Admin - Custom Customer Grid attribute - not filterable

I'm not sure why, but I can't filter my attribute (it works fine with defaults ones).
Here is my code :
Config.xml
<global>
<blocks>
<adminhtml>
<rewrite>
<customer_grid>SaponeWebConcept_PrivateSells_Adminhtml_Block_Customer_Grid</customer_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
Grid.php
public function setCollection($collection)
{
$collection->addAttributeToSelect('wants_to_be_vip');
parent::setCollection($collection);
}
protected function _prepareColumns()
{
parent::_prepareColumns();
$attributeCollection = Mage::getResourceModel('eav/entity_attribute_collection')
->setCodeFilter('wants_to_be_vip')
->getFirstItem();
$itemsOptions = $attributeCollection->getSource()->getAllOptions(false);
$optionsArr = array();
foreach ($itemsOptions as $option) {
$optionsArr[$option['value']] = $option['label'];
}
$this->addColumn('V.I.P', array(
'header'=> Mage::helper('customer')->__('Veut devenir V.I.P'),
'index' => 'wants_to_be_vip',
'type' => 'options',
'options' => $optionsArr,
));
$this->addColumnsOrder('customer_id','wants_to_be_vip');
}
Thanks for you help !
Edit : It may need some more infos :
- Values display ok.
- My select box is ok too.
- When I press the filter button, it loads, and nothing changes.

store transaction Id into magento order payment table

I have created my own payment method by taking reference of another method. I wannt to store my payment gateway's transaction id to order payment details (sales/order_payment) on successful payment action.
How can I store transaction id to this table ?
1) Add an SQL install script to your module, where we will add a new attribute to the order object
$installer = new Mage_Sales_Model_Mysql4_Setup;
$attribute = array(
'type' => 'text',
'backend_type' => 'text',
'frontend_input' => 'text',
'is_user_defined' => true,
'label' => 'Transaction Code',
'visible' => true,
'required' => false,
'user_defined' => false,
'searchable' => false,
'filterable' => false,
'comparable' => false,
'default' => ''
);
$installer->addAttribute('order', 'new_transaction_id', $attribute);
$installer->endSetup();
you could then add a observer to hook the payment event, so you would need to add code to yoru config.xml to enable your observer to hook onto the event:
<events>
<sales_order_payment_pay>
<observers>
<my_observer>
<type>singleton</type>
<class>mymodule/observer</class>
<method>save_transaction</method>
</my_observer>
</observers>
</sales_order_payment_pay>
</events>
You would then add an observer model to your module:
<?php
class Company_Mymodule_Model_Observer
{
public function save_transaction($event)
{
$order = $event->getInvoice()->getOrder(); // Mage_Sales_Model_Order
/**
* You would need to have your tranaction id from your gateway
* which would depend on how you have made your module..
* ....
*/
try {
$order->setNewTransactionId($transactionId);
$order->save();
}
catch(Exception $e) {
// do something nice
}
return $this;
}
}
While the above answer works I think there may be a better way to store the information.
Add the following method to your payment modules model.
public function assignData($data)
{
if (!($data instanceof Varien_Object)) {
$data = new Varien_Object($data);
}
$info = $this->getInfoInstance();
$info->setYourCustomTransactionId($data->getYourCustomTransactionId());
return $this;
}
While this would work. I would suggest using adding another method to your payment module. setAdditionalInformation and set the data via the assignData method. I'm not sure this method is already there if your payment method is derived from another magento payment class.
public function setAdditionalInformation($key, $value)
{
if (is_object($value)) {
Mage::throwException(Mage::helper('paypal')->__('Payment transactions disallow storing objects.'));
}
$info = $this->_getData('additional_information');
if (!$info) {
$info = array();
}
$info[$key] = $value;
return $this->setData('additional_information', $info);
}
Then you would do this in assign data.
public function assignData($data)
{
if (!($data instanceof Varien_Object)) {
$data = new Varien_Object($data);
}
$info = $this->getInfoInstance();
$info->setAdditionalInformation(array(
'trans_id' => $data->getYourCustomTransactionId()
));
return $this;
}
This may not work for your implementation, but I think it might be a little cleaner way of storing the info.
In my case I've sorted this Issue doing the following:
Change the function capture() at app/code/local/SecurePay/Sxml/Model/Sxml.php to something like that:
if($approved)
{
$transaction_id = $sxml->getResult('transaction_id');
$xmlResponse = $sxml->getResult('response');
$response = simplexml_load_string(htmlspecialchars_decode($xmlResponse))->children();
$payment->setAdditionalInformation('txnID', (string) $response->Payment->TxnList->Txn->txnID);
$payment->setAdditionalInformation('purchaseOrderNo', (string) $response->Payment->TxnList->Txn->purchaseOrderNo);
$payment->setCcTransId(''.$transaction_id);
That is all.

Show out of Stock For Configurable Products in magento

I have attribute set for my configurable products
i want to show out of stock for the L size of product in my select size drop down
i got a code for this but that is for magento 1.4 and am using magento 1.6
the Code is
in mage/catalog/block/product/view/type/configurable.php, in line ~85 you have something like this :
foreach ($this->getAllowAttributes() as $attribute) {
$productAttribute = $attribute->getProductAttribute();
$attributeValue = $product->getData($productAttribute->getAttributeCode());
if (!isset($options[$productAttribute->getId()])) {
$options[$productAttribute->getId()] = array();
}
if (!isset($options[$productAttribute->getId()][$attributeValue])) {
$options[$productAttribute->getId()][$attributeValue] = array();
}
$options[$productAttribute->getId()][$attributeValue][] = $productId;
}
so, in that foreach loop , preferably right after the foreach line, insert this code:
$options['qty'][$product -> getAttributeText($productAttribute->getName())] = floor($product->getStockItem()->getQty());
after, in line ~128 you have something like this:
$info['options'][] = array(
'id' => $value['value_index'],
'label' => $value['label'] ,
'price' => $this->_preparePrice($value['pricing_value'], $value['is_percent']),
'products' => isset($options[$attributeId][$value['value_index']]) ? $options[$attributeId][$value['value_index']] : array(),
);
replace it with this :
$info['options'][] = array(
'id' => $value['value_index'],
'label' => ($options['qty'][$value['label']] <= 0) ? $value['label'] . ' * out of stock' : $value['label'] . " * (".$options['qty'][$value['label']]." in stock)",
'price' => $this->_preparePrice($value['pricing_value'], $value['is_percent']),
'products' => isset($options[$attributeId][$value['value_index']]) ? $options[$attributeId][$value['value_index']] : array(),
);
can anyone please tell me what will be changes according to magento1.6 ?
Create your own module, and in the config.xml file add these 2 events inside the tag:
<events>
<controller_action_layout_render_before_catalog_product_view>
<observers>
<namespace_module>
<class>module/observer</class>
<method>showOutOfStock</method>
</namespace_module>
</observers>
</controller_action_layout_render_before_catalog_product_view>
<controller_action_layout_render_before_checkout_cart_configure>
<observers>
<namespace_module>
<class>module/observer</class>
<method>showOutOfStock</method>
</namespace_module>
</observers>
</controller_action_layout_render_before_checkout_cart_configure>
</events>
Now create an observer inside app/code/local/Namespace/Module/Model/Observer.php
class Namespace_Module_Model_Observer {
public function showOutOfStock($observer){
Mage::helper('catalog/product')->setSkipSaleableCheck(true);
}
}

Resources