Friday 19 December 2014

Magento remove selected items from shopping cart

When you have too many products in you shopping cart and you want to remove particular products out of it, you only need to do it one-by-one. And its really frustrating especially for testers. Magento does not provide the feature to remove selected products by default.

I have developed a code that could allow users to select the products which they want to remove by simply checking the products and click the remove button. And they all will be removed at a time.


Please download the extension here. Extract it and move it inside appropriate folders.
Tested on Version 1.7.2 and 1.8.1 community edition.

Monday 8 December 2014

Magento update backorder programatically

To update a products backorder status i wrote a custom script. My script reads the SKU's from the csv file and checks if the product exists and updates its backorder status.

Below is the code.

$products = Mage::getModel('catalog/product')->loadByAttribute('sku', $sku);
if($products)
{     
   // get product's stock data such quantity, in_stock etc
   $stockData = Mage::getModel('cataloginventory/stock_item')->loadByProduct($products);
           
   //to update backorder
   $stockData->setData('use_config_backorders', '0'); //not to use config settings           
   /*0 = No Backorders
   1 = Allow Qty Below 0
   2 = Allow Qty Below 0 and Notify Customer*/
   $stockData->setData('backorders', '1');
                       
   // then set product's stock data to update
   $stockData->save();
           
   // call save() method to save your product with updated data
   $products->save();                
}


You can download the complete code here.  It reads the csv file and checks for the products, If it is found the data are updated. Upon running this file. It will output all the products status (Found, Not found, How many not found) in the webpage. It also Writes the missing sku's in a new CSV file.

Tuesday 25 November 2014

Magento CSV import error show which row value is skipped

During the Batch CSV import, some of the rows will be skipped due to missing required values or any such errors. On the import process page magento will throw error message like below by default.

BEFORE
From this error message we won't be able to identify exactly which row is skipped. So I have made a modification to the magento files and after that

AFTER

Now we will know which row is skipped and can check for errors in it. Let me explain the few modification which i did to achieve this.

Step 1:

copy the file Customer.php which is under the path "app/code/core/Mage/Customer/Model/Convert/Adaptor/" to this path "app/code/local/Mage/Customer/Model/Convert/Adaptor/"

DO NOT EDIT THE CORE FILE. ALWAYS OVERRIDE IT USING LOCAL FOLDER

Step 2:

open the Customer.php in your editor and look for the function name "saveRow". It will be around line 418.
Inside this function you will see the error messages text. For Example:

 $message = Mage::helper('customer')->__('Skipping import row, required field "%s" is not defined. ', 'website');

Replace above line with this.

 $message = Mage::helper('customer')->__('Skipping import row, required field "%s" is not defined. Unique value to identify in CSV <strong>%s</strong> ', 'website', $importData['email']);

There will be similar error messages thrown for various reasons like customer group not found. website id does not exist and so on.. You can use the above customization to all those errors thrown.

The $importData['email'] is the one which contains the row value which is unique in case on Customer import. you can also use $importData['firstname'] or $importData['lastname'] according to your needs. The values inside the quotes are the column names from the CSV.

Similarly For Product batch import you can modify the file which is under. app/code/core/Mage/Ccatalog/Model/Convert/Adaptor/Product.php 

NOTE: When you import the CSV. look for any Special characters. This may cause errors during import. To import CSV with special characters edit your .htaccess file and add this line to it AddDefaultCharset UTF-8

Magento Customer Import - Convert plain text password to magento format.

One of my recent task is to import about 10k customers into Magento database.

First thing came into my mind is to export the existing customer from magento and use the csv file to fill in the new customer values and import them back.
But after exporting the few existing customers, i came to know that the CSV header fields which Magento exported is not suitable for the import and missing fields for password, customer address etc.

After few searches, i found this SAMPLE CSV file. click to download

Filled in the CSV file and for the password_hash field, I had to develop a customer script to convert plain text password to Magento format password.

My custom script is below. It reads the CSV file which contains plain text password, Encrypts it and writes to a new CSV file. After you CSV file is ready go to the admin panel. In the menu select System -> Import/Export -> Dataflow- Profiles. You will see "import customer". Click on it and upload your CSV file and click "save & continue edit" button. Then Choose the imported file from the dropdown and click Run.

All the customers will be imported with their previous password and addresses.

<?php
$row = 1;
$fp = fopen('var/log/ss1-pass.csv', 'w');
$csvHeader = array('Text','Encrypted');
fputcsv( $fp, $csvHeader,",");

//generate random string for salt
function generateRandomString($length = 2) {
    $characters = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}

if (($handle = fopen("ss1.csv", "r")) !== FALSE) {

    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
      $row++;
      $plainText =  trim($data[0]);
      $salt = generateRandomString(2);
      $encrypted = md5($salt.$plainText).":".$salt;
      fputcsv($fp, array($plainText,$encrypted), ",");
      //if($row==20){break;}
    }
   
 fclose($handle);
 fclose($fp);
}
?>


Friday 18 July 2014

Magento fedex SoapFault exception

Well, when it comes to any third party Shipping API's it a big headache for the developers. Especially when the worlds largest Shipping company FedEx changed their URL for the webservice request without any prior notification and the URL's are hardcoded.

So, How does it affect Magento ?

I was using the FedEx shipping method and everything works good in the Frontend of the website. But when i create a Shipping Label from the Admin i got an error message "An error occured while creating shipping label". And when i checked the LOG file, there was only EXCEPTION log created.

Ok, so after checking the exception log i found that there was a "SoapFault exception" error.
Later i found that it was the FedEx the culprit.

FIXES

Go to the path: app/code/core/Mage/Usa/Model/Shipping/Carrier
open Fedex.php file

On the line number 135 you will find such code with the fedex webservice url hardcoded

$client->__setLocation($this->getConfigFlag('sandbox_mode')
            ? 'https://wsbeta.fedex.com:443/web-services/rate'
            : 'https://ws.fedex.com:443/web-services/rate'
        );

Replace this with this new code.

$client->__setLocation($this->getConfigFlag('sandbox_mode')
            ? 'https://wsbeta.fedex.com:443/web-services'
            : 'https://ws.fedex.com:443/web-services'
        );


and that's it. The error must be Fixed. If it still exists please check your server configuration for the SOAP and WSDL configuration. It must be using older version. Try upgrading it.

NOTE: If you are creating Shipping Labels you Need to change the URL on the WSDL file also. The URL will be found at the very bottom of the code. 

Tuesday 1 July 2014

Magento Add to cart not working for new products block

I came across this Add to cart issue after upgrading from version 1.7.2 to 1.8.1.
Then after a long time search, luckly i found the cause.

In Magento version 1.8.1 there was an update to the add to cart feature with the inclusion of "Form keys". Magento has implemented this feature to prevent XSS attacks.

To know more about Form keys click here.

SOLUTION : Change the button type from "button" to "submit"

NOTE : Enabling All cache type may not solve the issue. Disable only "Blocks HTML output", you can enable other cache types.

Wednesday 19 February 2014

USPS API update january 2014

Usps have updated their API on January 2014. You can find the details of it here

And for those who have registered for the USPS developer or production account you would have been received mail from Usps about the API update.

According to the new update the shipping method "Standard Post" has been eliminated for Zones      1 to 4

Usps separates zipcodes with their zones. You can find your zone from here. FIND USPS ZONES
Go to "Get Zone for ZIP Code Pair" tab and enter your Origin and Destination zip code.

If your zone is numbered from 1 to 4, the "Standard Post" shipping method will not be applicable for you zipcode. Exception is given when you ship hazardous materials, live animals or other ground only items.

You can find more info about the API changes. 2014 January Release Notes (RTF)

Thursday 6 February 2014

Magento change product image on view page to associated product image

Magento's configurable product does not load its associated product image when we change the attribute value. To change the image of the product respective to the selected attribute value i have used this code. Magento website also offers a wiki to achieve this, but its pretty old and its written for magento version 1.5 and below. Link to wiki

I have tested this code in recent magento version which is 1.8 and the most famous 1.7.

Here is the code.

STEP 1:

Open template/catalog/product/view.phtml

and find the line var productAddToCartForm = new VarienForm('product_addtocart_form'); on the bottom of the page.

Add these code on top of that line.

var mainProductImgSrc = document.getElementById("image").src;
var assocIMG =

<?php
if ($_product->getTypeId() == "configurable") {
echo "{";
$associated_products = $_product->loadByAttribute('sku', $_product->getSku())->getTypeInstance()->getUsedProducts();
foreach ($associated_products as $assoc)
$dados[] = $assoc->getId().":'".($assoc->image == "no_selection" || $assoc->image == "" ? $this->helper('catalog/image')->init($_product, 'image', $_product->image)->resize(365,400) : $this->helper('catalog/image')->init($assoc, 'image', $assoc->image)->resize(365,400))."'";
} else {
$dados[] = "";
}
echo implode(',', $dados );
if ($_product->getTypeId() == "configurable") {
echo "}";
}

?>


STEP 2:

open js/varien/product.js and find the line

}.bind(this));
for (var i = 0; i < this.tierPrices.length; i++) {


and add the below given code above  this-> " }.bind(this)); " line.

//to change product image based on option select for configurable product
settings = $$('.super-attribute-select');
imgSrc = mainProductImgSrc;
settings.each(function(element)
 {
   attributeId = element.attributeId;
   if(element.options[element.selectedIndex].config)
   imgSrc = assocIMG[element.options[element.selectedIndex].config.products];
   $('image').src = imgSrc;
 });

//ends

Your are done now. Do remember to select the base image for the associated product. If there is no image set for the associated product and when you change the option the configurable product image will be used instead.

Saturday 1 February 2014

Magento import products with custom product type via csv

I was assigned a job to import products with custom product types through CSV

Magento's default product types are
  1. simple
  2. configurable
  3. virtual
  4. grouped
But when you import products with new product type other than the above mentioned. you will get this error

Product Type is invalid or not supported in rows... 

To overcome this error and import products with your custom product type you must follow these two steps.

1. Now am going to assume you have created an extension. On the config.xml file of your extension place this code under <global> tag.

<importexport>
    <import_product_types>
         <YOUR_MODULE>yourModule/import_entity_product_type_
YOUR_MODULE</YOUR_MODULE>
    </import_product_types>

</importexport>

Replace YOUR_MODULE with you module name.

2. Create a new model class to do the import. For this create this folder structure inside your model structure
Import\Entity\Product\Type\NEW-PRODUCT-TYPE

In my case i have a new product type "subscription_simple". so my folder structure will be
Import\Entity\Product\Type\Subscription\

Inside the folder i have a model class Simple.php file extending the magneto import class.\

place this code inside Simple.php file.

class NAMESPACE_MODULE_Model_Import_Entity_Product_Type_Subscription_Simple
    extends Mage_ImportExport_Model_Import_Entity_Product_Type_Abstract
{

}

Now you can do the import with your custom product type.

you can check out one of the inbuilt classes for an example Mage_ImportExport_Model_Import_Entity_Product_Type_Simple

INFO: http://stackoverflow.com/questions/8909405/product-type-is-invalid-or-not-supported-in-rows-for-custom-product-type