Thursday, August 22, 2013

Magento abandoned cart for guest/unconfirmed users

http://stackoverflow.com/questions/13584054/magento-abandoned-cart-for-guest-unconfirmed-users



SELECT entity_id, customer_firstname, customer_email, items_count, grand_total, created_at
FROM sales_flat_quote
WHERE entity_id NOT IN (SELECT quote_item_id AS quote_id FROM sales_flat_order_item) 
AND items_count >0
AND customer_email IS NOT NULL
ORDER BY `sales_flat_quote`.`created_at` DESC

http://stackoverflow.com/questions/15148275/when-does-magento-consider-a-cart-to-be-abandoned-wheres-that-time-limit-set
As you probably know the setting is located here:
Admin => system => Configuration => Sales => Checkout => Quote Lifetime (days)
This will add the setting to the database (core_config_data table) with path:
checkout/cart/delete_quote_after
This path is used in the code on:
app/code/core/Mage/Sales/Model/Observer.php line 54
So when someone is adding something to a cart it will be updated. When a customer logs in and his cart is there it will be updated. When a cart is not updated for the last 30 days. It will be removed.
Extra information:
In case you wonder when this code is used, It is used by the cronjob of magento.
check: App/code/core/Mage/Sales/etc/config.xml line 1732

    
        
            
                0 0 * * *
sales/observer::cleanExpiredQuotes
Hope this helps.

Magento Shopping Cart Abandonment



All this can be done using Magento, but as you said, this is a very broad question. I'll give answers to the specific topics, but I suggest you take time to study the fundamentals of Magento module development. Here is an excellent tutorial by Alan Storm (read the whole series).

Get list of abandoned carts

In Magento, the cart is simply a wrapper for the sales/quote object, so that is the entity you will be working with.
Instead of adding increments to a abandoned_duration attribute, I suggest simply checking against the updated_at field.

$adapter = Mage::getSingleton('core/resource')->getConnection('sales_read');
$minutes = 15;
$from = $adapter->getDateSubSql(
    $adapter->quote(now()), 
    $minutes, 
    Varien_Db_Adapter_Interface::INTERVAL_MINUTE
);
$quotes = Mage::getResourceModel('sales/quote_collection')
    ->addFieldToFilter('converted_at', $adapter->getSuggestedZeroDate())
    ->addFieldToFilter('updated_at', array('to' => $from));
This will give you a collection (think of it as an array with methods) of all quotes that haven't been updated for 15 minutes. You can iterate over them like an array
foreach ($quotes as $quote) {
    /* @var $quote Mage_Sales_Model_Quote */
}

Magento Cronjobs

In Magento, all cron jobs are listed in the configuration structure. So first you need to add it to the config.xml of your module (refer to the linked tutorial for more information on Magento configuration).
This XML registers a cronjob with Magento.

    
        
            
                */15 * * * *
your_module/observer::processAbandonedCarts Now, whenever Magento runs the cronjob, it will instantiate the class your_module/observer and call the processAbandonedCarts() method.
In order for Magento to process configured cronjobs, you need to set the system up to do so. This consists of two parts: the system configuration and the triggering of the cron jobs.
The system configuration is done in the administrative interface under System > Configuration > System > Cron (Scheduled Tasks)
The triggering consists of setting up a way to periodically execute the cron.php (or cron.sh) script in the Magento root directory. This can be done using a regular crontab entry (man 5 crontab on any decent unix system for more information). Another option preferred by many is to execute the cron.php script through a curl or wget call so the processing user ID matches the regular Magento user ID (i.e. the Apache user). This might be important if APC caching is configured, but this is getting off topic.
However, on topic is that you need to call it often enough so it matches the settings you specify in the administrative interface!
I generally recommend executing the cron.php script every 5 minutes. If there is nothing scheduled it will simply exit.
One really useful extension for Magento when working with cronjobs is Aoe_Scheduler. It adds much of the user interfaces for cronjobs and interactive functionality that should be part of the core system.

Other

Sending the data to a web service is not Magento specific, but rather regular PHP, so I'll wont go into more detail.
To delete a cart, simple call $quote->delete() on the loaded sales/quote instance.
Please ask mor specific questions for further information.



http://stackoverflow.com/questions/9223790/where-to-start-with-magento-shopping-cart-abandonment

Related Link
http://www.magentocommerce.com/magento-connect/anatta-design-abandoned-carts-2536.html


Monday, June 3, 2013

Creating a Downloadable Product in OpenCart

http://www.inmotionhosting.com/support/edu/opencart/303-creating-a-downloadable-product-in-opencart

http://www.opencarttutorial.com/how-to-setup-your-opencart-catalog/downloadable-products/
At times, you may want to sell a digital product such as an image, audio file, or e-book. This can be easily accomplished in OpenCart. To offer a downloadable product, you'll first have to upload the file within OpenCart and then you'll need to link the file to a product. 
Important! Remember to uncheck the "Requires Shipping" checkbox or your customers will be charged shipping fees by mistake.

Uploading Your Digital Product

  1. Log into your OpenCart Dashboard
  2. Go to Catalog > Downloads
  3. Click “Insert” in the upper right corner
  4. opencart_digital_1
  5. Fill in the fields with a download name, Select the file to upload on your local computer, and type in the number of downloads allowed per user purchase
  6. opencart_digital_2
  7. Click “Save

Linking the download file to a product

  1. Log into your OpenCart Dashboard
  2. Go to Products
  3. Click “Insert” to create a new product or click “Edit” next to an existing product
  4. Click on the “links” tab
  5. Scroll towards the bottom of the page, go to the “Downloads” section and select the file you want to be made available on this product
  6. opencart_digital_3
  7. While still editing this product, click on the “Data” tab and scroll down to the section called “Weight”. Enter a weight of “0” (zero) in the field. This tells OpenCart it is a downloadable product
  8. Click on “Save” in the upper right corner
If you need further assistance please feel free to ask a question in our support center website.

Thursday, January 31, 2013

Google DFP setup

http://www.labnol.org/internet/google-dfp-tutorial/14099/


Friday, January 4, 2013

Compare directories via diff


diff -rq dirA dirB

diff -qr dirA dirB | grep -v -e 'DS_Store' -e 'Thumbs' | 
sort > diffs.txt


http://hints.macworld.com/article.php?story=20070408062023352

Wednesday, December 19, 2012

YII framework dynamic Table Model


/**
 * CActiveRecord implementation that allows specifying
 * DB table name instead of creating a class for each table.
 *
 * Usage (assuming table 'user' with columns 'id' and 'name'):
 *
 * $userModel = DynamicActiveRecord::forTable('user');
 * //list existing users
 * foreach ($userModel->findAll() as $user)
 * echo $user->id . ': ' . $user->name . '
';
 * //add new user
 * $userModel->name = 'Pavle Predic';
 * $userModel->save();
 *
 * @author Pavle Predic
 */
class DynamicActiveRecord extends CActiveRecord
{
/**
* Name of the DB table
* @var string
*/
protected $_tableName;

/**
* Table meta-data.
* Must redeclare, as parent::_md is private
* @var CActiveRecordMetaData
*/
protected $_md;

/**
* Constructor
* @param string $scenario (defaults to 'insert')
* @param string $tableName
*/
public function __construct($scenario = 'insert', $tableName = null)
{
$this->_tableName = $tableName;
parent::__construct($scenario);
}

/**
* Overrides default instantiation logic.
* Instantiates AR class by providing table name
* @see CActiveRecord::instantiate()
* @return DynamicActiveRecord
*/
protected function instantiate($attributes)
{
return new DynamicActiveRecord(null, $this->tableName());
}

/**
* Returns meta-data for this DB table
* @see CActiveRecord::getMetaData()
* @return CActiveRecordMetaData
*/
public function getMetaData()
{
if ($this->_md !== null)
return $this->_md;
else
return $this->_md = new CActiveRecordMetaData($this);
}

/**
* Returns table name
* @see CActiveRecord::tableName()
* @return string
*/
public function tableName()
{
if (!$this->_tableName)
$this->_tableName = parent::tableName();
return $this->_tableName;
}

/**
* Returns an instance of DynamicActiveRecord for the provided DB table.
* This is a helper method that may be used instead of constructor.
* @param string $tableName
* @param string $scenario
* @return DynamicActiveRecord
*/
public static function forTable($tableName, $scenario = 'insert')
{
return new DynamicActiveRecord($scenario, $tableName);
}
}

Thursday, December 6, 2012

YII Framework - Highcharts Extension - datetime issue Resolved


$this->Widget('ext.highcharts.HighchartsWidget', array(
   'options'=>'{
      "title": { "text": "MYSQL Replication" },
      "xAxis": {
      "title": { "text": "Month" },
"type": "datetime",
            "dateTimeLabelFormats": {
                "day": "%e"  
            }
      },
      "yAxis": {
         "title": { "text": "Time" },
"type": "datetime",
        "dateTimeLabelFormats": {
                "hour": "%H"
            }
      },
      "tooltip": {
            "xDateFormat": "%Y-%m-%d"
        },      
      "series": [
{ "name": "success", "data": [[x_ms,y_ms],[x_ms,y_ms]],"pointStart": utc_ms, "pointInterval": date_ms},
         { "name": "failure", "data": [[x_ms,y_ms],[x_ms,y_ms]],"pointStart": utc_ms, "pointInterval": date_ms}
      ]
   }'
));

<script src="http://code.highcharts.com/highcharts.js"></script>