Monday, July 29, 2013

Magento : Install Magento 1.7.0.2 With Sample Data By SSH

mkdir myproject
cd myproject
wget http://www.magentocommerce.com/downloads/assets/1.7.0.2/magento-1.7.0.2.tar.gz
wget http://www.magentocommerce.com/downloads/assets/1.6.1.0/magento-sample-data-1.6.1.0.tar.gz
tar -zxvf magento-1.7.0.2.tar.gz
tar -zxvf magento-sample-data-1.6.1.0.tar.gz
mv magento-sample-data-1.6.1.0/media/* magento/media/
mv magento-sample-data-1.6.1.0/magento_sample_data_for_1.6.1.0.sql magento/data.sql
mv magento/* magento/.htaccess .
chmod o+w var var/.htaccess app/etc
chmod -R o+w media
mysql -h localhost -u -p myproject_db < data.sql
chmod 755 mage
./mage mage-setup.

Wednesday, July 17, 2013

Magento : Create/Collocate Magento System Configuration

First create a blank module with following files
 etc/modules/Bd_Systemconfigdemo.xml
Bd/Systemconfigdemo/etc/config.xml

Then create a system.xml file in  Bd/Systemconfigdemo/etc/system.xml with following code
<?xml version="1.0"?>
<config>
      <tabs>
        <demo_tab translate="label" module="systemconfigdemo">
            <label>Demo Tab</label>
            <sort_order>0</sort_order>
        </demo_tab>
      </tabs>
      <sections>
        <demo_section  translate="label" module="systemconfigdemo">                   
        <label>Demo Section</label>
        <tab>demo_tab</tab>
        <frontend_type>text</frontend_type>
        <sort_order>0</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>           
                    <groups>
                      <demo_group translate="label">
                      <label>Demo Group</label>
                      <frontend_type>text</frontend_type>
                      <sort_order>0</sort_order>
                      <show_in_default>1</show_in_default>
                      <show_in_website>1</show_in_website>
                      <show_in_store>1</show_in_store>
                       <fields>
                          <demo_field1 translate="label">
                            <label>Demo Field1</label>
                            <frontend_type>text</frontend_type>
                            <sort_order>0</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <comment>first</comment>
                          </demo_field1>
                          <demo_field2 translate="label">
                            <label>Demo Field2</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <sort_order>0</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <comment>second</comment>
                          </demo_field2>
                       </fields>
                       </demo_group>
                    </groups>
        </demo_section>
      </sections>
</config>


And adminhtml.xml with following code
<?xml version="1.0"?>
    <config>
        <acl>
            <resources>
                <admin>
                    <children>
                        <system>
                            <children>
                                <config>
                                    <children>
                                        <demo_section translate="title" module="systemconfigdemo">
                                            <title>Demo Section Section</title>
                                            <sort_order>0</sort_order>
                                        </demo_section>
                                    </children>
                                </config>
                            </children>
                        </system>
                    </children>
                </admin>
            </resources>
        </acl>
    </config>

Magento : Add New Order Total (fee or discount, like prepaid discount)

Here i consider that i need to give a discount when user make a order with prepaid method.

Consider, Bd_Prepaid is a custom module and prepaiddiscount_total is a variable,

First create a simple module
1. etc/modules/Bd_Prepaid
<?xml version="1.0"?>
<config>
  <modules>
    <Bd_Prepaid>
      <active>true</active>
      <codePool>local</codePool>
      <version>0.1.0</version>
    </Bd_Prepaid>
  </modules>
</config>

2.Then create a config file with following code
<?xml version="1.0"?>
<config>
  <modules>
    <Bd_Prepaid>
      <version>0.1.0</version>
    </Bd_Prepaid>
  </modules>
  <global>
    <helpers>
      <prepaid>
        <class>Bd_Prepaid_Helper</class>
      </prepaid>
    </helpers>
    <models>
      <prepaid>
        <class>Bd_Prepaid_Model</class>
        <resourceModel>prepaid_mysql4</resourceModel>
      </prepaid>
    </models>
    <resources>
      <salesattribute1374123678_setup>
        <setup>
          <module>Bd_Prepaid</module>
          <class>Mage_Sales_Model_Mysql4_Setup</class>
        </setup>
        <connection>
          <use>core_setup</use>
        </connection>
      </salesattribute1374123678_setup>
      <salesattribute1374123678_write>
        <connection>
          <use>core_write</use>
        </connection>
      </salesattribute1374123678_write>
      <salesattribute1374123678_read>
        <connection>
          <use>core_read</use>
        </connection>
      </salesattribute1374123678_read>
    </resources>
    <events>
    <checkout_type_onepage_save_order_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_type_onepage_save_order_after_prepaiddiscount_handler> <!-- identifier of the event handler -->
            <type>model</type> <!-- class method call type; valid are model, object and singleton -->
            <class>prepaid/newordertotalobserver</class> <!-- observers class alias -->
            <method>savePrepaiddiscountTotal</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_type_onepage_save_order_after_prepaiddiscount_handler>
        </observers>
      </checkout_type_onepage_save_order_after>       
    <checkout_type_multishipping_create_orders_single> <!-- identifier of the event we want to catch -->
        <observers>       
          <checkout_type_multishipping_create_orders_single_prepaiddiscount_handler> <!-- identifier of the event handler -->
            <type>model</type> <!-- class method call type; valid are model, object and singleton -->
            <class>prepaid/newordertotalobserver</class> <!-- observers class alias -->
            <method>savePrepaiddiscountTotalForMultishipping</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_type_multishipping_create_orders_single_prepaiddiscount_handler>       
        </observers>
      </checkout_type_multishipping_create_orders_single>
    </events>   
     <sales>
        <quote>
            <totals>               
                <prepaiddiscount_total>
                    <class>prepaid/quote_address_total_prepaiddiscount</class>
                    <after>subtotal,freeshipping,tax_subtotal,shipping</after>
                    <before>grand_total</before>
                </prepaiddiscount_total>
            </totals>
        </quote>
            <order_invoice>
                <totals>               
                <prepaiddiscount_total>
                    <class>prepaid/order_invoice_total_prepaiddiscount</class>
                    <after>subtotal,freeshipping,tax_subtotal,shipping</after>
                    <before>grand_total</before>
                </prepaiddiscount_total>
                </totals>
            </order_invoice>
            <order_creditmemo>
                <totals>               
                <prepaiddiscount_total>
                    <class>prepaid/order_invoice_total_prepaiddiscount</class>
                    <after>subtotal,freeshipping,tax_subtotal,shipping</after>
                    <before>grand_total</before>
                </prepaiddiscount_total>
                </totals>
            </order_creditmemo>
    </sales>
  </global>
</config>

3.Then create amysql file to create a order attribute
<?php
$installer = $this;
$installer->startSetup();

$installer->addAttribute("quote_address", "prepaiddiscount_total", array("type"=>"varchar"));
$installer->addAttribute("order", "prepaiddiscount_total", array("type"=>"varchar"));
$installer->endSetup();
    
4.Then create a observer as used in config file
Like Bd/Prepaid/Model/Newordertotalobserver.php
<?php
class Bd_Prepaid_Model_Newordertotalobserver
{
     public function savePrepaiddiscountTotal(Varien_Event_Observer $observer)
    {
         $order = $observer -> getEvent() -> getOrder();
         $quote = $observer -> getEvent() -> getQuote();
         $shippingAddress = $quote -> getShippingAddress();
         if($shippingAddress && $shippingAddress -> getData('prepaiddiscount_total')){
             $order -> setData('prepaiddiscount_total', $shippingAddress -> getData('prepaiddiscount_total'));
             }
        else{
             $billingAddress = $quote -> getBillingAddress();
             $order -> setData('prepaiddiscount_total', $billingAddress -> getData('prepaiddiscount_total'));
             }
         $order -> save();
     }
   
     public function savePrepaiddiscountTotalForMultishipping(Varien_Event_Observer $observer)
    {
         $order = $observer -> getEvent() -> getOrder();
         $address = $observer -> getEvent() -> getAddress();
         $order -> setData('prepaiddiscount_total', $shippingAddress -> getData('prepaiddiscount_total'));
         $order -> save();
     }
}

5.Then create a class file to collect the total (Bd/Prepaid/Model/Quote/Address/Total/Prepaiddiscount.php), which inherited from Mage_Sales_Model_Quote_Address_Total_Abstract with following code
<?php
class Bd_Prepaid_Model_Quote_Address_Total_Prepaiddiscount
extends Mage_Sales_Model_Quote_Address_Total_Abstract
{
     public function __construct()
    {
         $this -> setCode('prepaiddiscount_total');
         }
    /**
     * Collect totals information about prepaiddiscount
     *
     * @param Mage_Sales_Model_Quote_Address $address
     * @return Mage_Sales_Model_Quote_Address_Total_Shipping
     */
     public function collect(Mage_Sales_Model_Quote_Address $address)
    {
         parent :: collect($address);
         $items = $this->_getAddressItems($address);
         if (!count($items)) {
            return $this;
         }
         $quote= $address->getQuote();

         //amount definition

         $prepaiddiscountAmount = 0.01;

         //amount definition

         $prepaiddiscountAmount = $quote -> getStore() -> roundPrice($prepaiddiscountAmount);
         $this -> _setAmount($prepaiddiscountAmount) -> _setBaseAmount($prepaiddiscountAmount);
         $address->setData('prepaiddiscount_total',$prepaiddiscountAmount);

         return $this;
     }
   
    /**
     * Add prepaiddiscount totals information to address object
     *
     * @param Mage_Sales_Model_Quote_Address $address
     * @return Mage_Sales_Model_Quote_Address_Total_Shipping
     */
     public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
         parent :: fetch($address);
         $amount = $address -> getTotalAmount($this -> getCode());
         if ($amount != 0){
             $address -> addTotal(array(
                     'code' => $this -> getCode(),
                     'title' => $this -> getLabel(),
                     'value' => $amount
                    ));
         }
       
         return $this;
     }
   
    /**
     * Get label
     *
     * @return string
     */
     public function getLabel()
    {
         return Mage :: helper('prepaid') -> __('Prepaid Discount');
    }
}

6.Then create a file to add this variable in invoice and an other file to add in memo
as
Bd/Prepaid/Model/Order/Invoice/Total/Prepaiddiscount.php
<?php
class Bd_Prepaid_Model_Order_Invoice_Total_Prepaiddiscount
extends Mage_Sales_Model_Order_Invoice_Total_Abstract
{
    public function collect(Mage_Sales_Model_Order_Invoice $invoice)
    {
        $order=$invoice->getOrder();
        $PrepaiddiscountTotal = $order->getPrepaiddiscountTotal();
        if ($PrepaiddiscountTotal&&count($order->getInvoiceCollection())==0) {
            $invoice->setGrandTotal($invoice->getGrandTotal()+$orderPrepaiddiscountTotal);
            $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal()+$orderPrepaiddiscountTotal);
        }
        return $this;
    }
}

Bd/Prepaid/Model/Order/Creditmemo/Total/Prepaiddiscount.php
<?php
class Bd_Prepaid_Model_Order_Creditmemo_Total_Prepaiddiscount
extends Mage_Sales_Model_Order_Creditmemo_Total_Abstract
{
    public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo)
    {

        return $this;

        $order = $creditmemo->getOrder();
        $orderPrepaiddiscountTotal        = $order->getPrepaiddiscountTotal();

        if ($orderPrepaiddiscountTotal) {
            $creditmemo->setGrandTotal($creditmemo->getGrandTotal()+$orderPrepaiddiscountTotal);
            $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal()+$orderPrepaiddiscountTotal);
        }

        return $this;
    }
}

7. At last add following code to app\code\core\Mage\Sales\Block\Order\Totals.php
${code}Total=$source->getprepaiddiscountTotal();

if($source->getOrderId()) {
    ${code}Total=$source->getOrder()->getprepaiddiscountTotal();
}

$this->_totals['prepaiddiscount_total'] = new Varien_Object(array(
    'code'  => 'prepaiddiscount_total',
    'field' => 'prepaiddiscount_total',
    'value' => $prepaiddiscountTotal,
    'label' => $this->__('Prepaid Discount')
));


And following code to app\code\core\Mage\Adminhtml\Block\Sales\Totals.php
$prepaiddiscountTotal=$this->getSource()->getprepaiddiscountTotal();

if($this->getSource()->getOrderId()) {
    $prepaiddiscountTotal=$this->getSource()->getOrder()->getprepaiddiscountTotal();
}
$this->_totals['prepaiddiscount_total'] = new Varien_Object(array(
        'code'      => 'prepaiddiscount_total',
        'value'     => $prepaiddiscountTotal,
        'base_value'=> $prepaiddiscountTotal,
        'label'     => $this->__('Prepaid Discount')
));



 

Tuesday, July 2, 2013

Magento : Make 'Continue Shopping' button redirect to the last-added-to-cart product's category

Edit cart.phtml and replace following code

<?php if($this->getContinueShoppingUrl()): ?>
    <button type="button" title="<?php echo $this->__('Continue Shopping') ?>" class="button btn-continue" onclick="setLocation('<?php echo $this->getContinueShoppingUrl(); ?>')"><span><span><?php echo $this->__('Continue Shopping') ?></span></span></button>
<?php endif; ?>

with

<?php
    $lastProductAddedToCartId = Mage::getSingleton('checkout/session')->getLastAddedProductId();
    if($lastProductAddedToCartId) {
        $productCategoryIdsArray = Mage::getModel('catalog/product')->load($lastProductAddedToCartId)->getCategoryIds();
        $continueShoppingCategoryUrl = Mage::getModel('catalog/category')->load($productCategoryIdsArray[0])->getUrl();
    }
?>
<?php if($this->getContinueShoppingUrl()): ?>
        <button type="button" title="<?php echo $this->__('Continue Shopping') ?>" class="button btn-continue" onclick="setLocation('<?php echo (isset($continueShoppingCategoryUrl)) ? $continueShoppingCategoryUrl : $this->getContinueShoppingUrl(); ?>')"><span><span><?php echo $this->__('Continue Shopping') ?></span></span></button>
 <?php endif; ?>

Thursday, June 20, 2013

Magento : Create CSV file for any custom data in magento

It can be done by using Varien_File_Csv class
Exp:

$file_path = '/your_dir_path/sample.csv';
$mage_csv = new Varien_File_Csv(); //mage CSV 
$products_ids = array(1,2,3); //product ids or make array of any data
$products_model = Mage::getModel('catalog/product');
$products_row = array();
foreach ($products_ids as $pid)
{
   $prod = $products_model->load($pid);
   $data = array();
   $data['sku'] = $prod->getSku();
   $data['name'] = $prod->getName();
   $data['price'] = $prod->getPrice();    
   $products_row[] = $data;              
}
$mage_csv->saveData($file_path, $products_row);

Sunday, June 16, 2013

Magento : Order State and Status in Magento

In Magento, there are two columns in sales_flat_order table.
These are state and status, They both are different. State is used by magento to tell if the order is new, processing, complete, holded, closed, canceled, etc.

while Statuses are the one that YOU would be defining at the backend in System -> Order Statuses. Magento displays order STATUSES and not STATES in the backend order detail page to let you know which status is assigned as per your mapping.

Remember, multiple statuses can be mapped with one state, while vice versa is not possible.

Also you may know more, reading file /app/code/core/Mage/Sales/etc/config.xml

Sunday, April 14, 2013

Magento : Import Gmail Contact

1. Define a link in any phtml file as
<?php
    $client_id=  '';                  
    $redirect_uri='test/test/gooledata';
    $scope = "https://www.google.com/m8/feeds/"; //google scope to access
    $state = "profile"; //optional                   
    $loginUrl = sprintf("https://accounts.google.com/o/oauth2/auth?scope=%s&state=%s&redirect_uri=%s&response_type=code&client_id=%s",$scope,$state,$redirect_uri,$client_id);
?>
Import E-mail Addresses From:<br />
<a href="javascript:poptastic('<?php echo $loginUrl; ?>');">Import</a>



<script>
function poptastic(url) {
      var newWindow = window.open(url, 'name', 'height=600,width=450,top=100,left=500');
      if (window.focus) {
        newWindow.focus();
      }
     
 }
function showGmailData(){
       //location.reload();
       jQuery("#gmailloader").css('display', 'block');
            jQuery.ajax({
                    type: "POST",
                    data : jQuery("#form-validate").serialize(),
                    url: '/invitation/index/showgmaildata',
                    success: function(data) {
                    jQuery("#gmailloader").css('display', 'none');
                    result = jQuery.parseJSON(data);
                    if(!result.success) {
                    }
                    else    {

                    }
              }
            });
 }
</script>

2. Define Redirect action in controller
public function googledataAction(){        
              
        $authcode= $this->getRequest()->getParam('code');
        $importcontacts = array();
        if(isset($authcode) && $authcode != ''){
           $importcontacts = Mage::helper('test')->importGmailContacts($authcode);
           //print_r($importcontacts);
           //Mage::getSingleton('core/session')->setImportcontacts($importcontacts);
           echo '<html><body>Please wait....<script type="text/javascript">window.opener.showGmailData(); window.close();</script></body></html>';
           die();
          
        }       
    }

3. Define importGmailContacts() method in helper
public function importGmailContacts($authcode){       
            try{
            $clientid='';
            $clientsecret='';
            $redirecturi='test/test/googledata';
            $fields=array(
            'code'=>  urlencode($authcode),
            'client_id'=>  urlencode($clientid),
            'client_secret'=>  urlencode($clientsecret),
            'redirect_uri'=>  urlencode($redirecturi),
            'grant_type'=>  urlencode('authorization_code')
            );
            $fields_string='';
            foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
            $fields_string=rtrim($fields_string,'&');
            //open connection
            $ch = curl_init();
            //set the url, number of POST vars, POST data
            curl_setopt($ch,CURLOPT_URL,'https://accounts.google.com/o/oauth2/token');
            curl_setopt($ch,CURLOPT_POST,5);
            curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
            // Set so curl_exec returns the result instead of outputting it.
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            //to trust any ssl certificates
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            //execute post
            $result = curl_exec($ch);
            //close connection
            curl_close($ch);
            //extracting access_token from response string
            $response   =  json_decode($result);
            $accesstoken= $response->access_token;
            if( $accesstoken!='')
           
            $xmlresponse=  file_get_contents('https://www.google.com/m8/feeds/contacts/default/full?max-results=100&oauth_token='. $accesstoken);
            //reading xml using SimpleXML
            $xml=  new SimpleXMLElement($xmlresponse);
            $xml->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005');
            $result = $xml->xpath('//gd:email');
            foreach ($result as $title) {
                $importcontact[] = (string)$title->attributes()->address;
            }
            Mage::getSingleton('core/session')->setImportcontacts($importcontact);
            //return $importcontact;
            }  catch (Exception $e){ echo $e->getMessage();}
    }

4.Then use according to requirement in following action
public function showGmailDataAction(){
        $result = array(
                'success' => false,
                'message' => false,
                'count' => false,
            );
$importcontacts = Mage::getSingleton('core/session')->getImportcontacts();
$this->getResponse()->setBody(Zend_Json::encode($result));
        return;
    }