Tag Archives: FeedTamper

Drupal Commerce Product Feeds – Problems Importing Prices

I’ve been playing around with Drupal to create an internal ordering system. However I was getting stumped setting up a feed, which contained price information.

I had a CSV field with price data which was just ‘0’ or empty in places, and I was trying to import it into a product field of type Price, which caused the Feeds Importer to die with following cryptic statement:

SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column
'commerce_price_amount' at row 1

Minor Unit

This is issue occurs because Drupal Commerce uses a Minor Unit format (prices without decimals) for its pricing data. For example, if you had a price of 1.50, you would write it as 150. It also seems that depending on how your data is quoted, or if it was missing in my caase, Drupal might struggle to bring in the price data correctly.

Solving the problem

Check that the data looks good.

Before fixing the actual problem, its best to first look at the logs button on the feeds import page. Check that parsed data matches up to your CSV. You may have inadvertent line breaks or other issues (such as the file not being in UTF-8 encoding) that is causing the data to import badly and you might need to simply fix up your feed.

Feeds Tamper

If you’re still having problem then the solution is Drupal’s Feeds Tamper module, which allows you to modify feeds data before its get written into Drupal.

Feeds Tamper comes with 10s of plugins that can alter data (setting a default value, doing string substition) as well as providing a path to write custom plugins.

Install the Feeds Tamper module

Don’t forget to set the Permissions for Feeds Tamper. Go to Modules->Feeds Tamper and activate the module, along with the Feed Tamper Admin UI.

Then set permissions Modules->Feeds Tamper->Permissions and give the right permissions by role to each existing importer.

Tamper with Your Feed

If everything is set-up correctly, you should be able to head to Structure->Feeds Importers and you should see Tamper now as option on the importers you enabled it for. Clicking this takes you to a list of all your feed mappings.

[Screenshot]

Hit add plugin on a mapping to start tampering with that field. The nice thing is that you can add multiple feed tampers and order them as appropriate to get some powerful data manipulation.

Writing your own Feeds Tamper

Returning to our problem, we can now easily fix the feed issue. First we’re going to set-up a custom module, which we’ll call pricefixer.

First create a pricefixer.info file and save it in the appropriate sites module directory (such as Sites/all/modules).

This should contain something like this:

name = PriceFixer
description = "Fixes price importation issues"
package = Feeds
dependencies[] = commerce
dependencies[] = feeds_tamper
core = 7.x

files[] = pricefixer.module

Then create the corresponding module file, in our case pricefixer.module, which contains a single hook based on MYMODULE_ctools_plugin_directory, which lets us tell Feed Tamper (via CTools) where our plugins are going to be. In this case they will be in a sub-folder of the module, PriceFixer/Plugins.

Finally create the feed tamper plugin iteself (which we will call pricefixer.inc) and save it into the plugins directory under our module:

/**
 * @file
 * Filter to convert prices to Drupals minor unit format
 */

$plugin = array(
  'form' => 'price_fixer_form',
  'callback' => 'price_fixer_callback',
  'validate' => 'wbr_price_filter_validate',
  'name' => 'Price Fixer',
  'multi' => 'skip',
  'category' => 'Filter',
);

function price_fixer_form($importer, $element_key, $settings) {
  $form = array();

  $form['convert_minor'] = array(
    '#type' => 'checkbox',
    '#title' => t('Convert to Minor Units'),
    '#default_value' => isset($settings['convert_minor']) ? $settings['convert_minor'] : TRUE,
    '#description' => t('If checked, then will convert to minor units (Drupals default value system). So 1.50 becomes 150.')
  );
  return $form;
}

/**
 * Called validate user settings in our ui element set up in price_fixer_form
 */
function price_fixer_validate (&$settings) {
  /* validate our settings in here */
}

/**
 * Called by the feed (via Feed Tamper) to modify data.
 */
function price_fixer_callback ($result, $item_key, $element_key, &$field, $settings) {

	if ( empty($field) ) {
		$field = 0.0;
	}
	else if ( $settings['strip_quotes'] ) {
		$field = strip_quotes($field);
	}

	// strip thousands separator if required
	if ( $settings['convert_minor'] ) {
		// convert to minor units
		$field = commerce_currency_decimal_to_amount($field, $settings['currency_code'], TRUE);
	}
}

And volia. Reload the Feed Tamper UI and you should be able to plugin this price fixer like any other feed tamper plugin. Obviously the code is incomplete because everyones feed is slightly different. I’ve include the call to commerce_currency_decimal_to_amount as it seems like a simple way to get into the Minor Unit value.

You can obviously do a lot more here, such as strip quotes, check field is numeric etc etc, but once you’ve written one feed tamper, a second or third is very easy.

The easiest way to see how things are set-up is to look at the installed Feed Tamper plugins, you’ll quickly see how to change the categories a plugin is listed under, add complex UI elements and really work that data.

Want to know more?