Drupal Upgrade: How to Migrate data from Ecommerce module to Ubercart in a Drupal site
Ecommerce used to be the preferred ecommerce solution for Drupal before Ubercart came into the picture. We recently worked on upgrading a Drupal 5 site with Ecommerce to Drupal 7 with Ubercart. The challenge with this upgrade was that the source data existed only in the D5 database and the corresponding code to programmatically access the ecommerce data was in D5 as well while the destination tables existed only in the D7 database with the corresponding code existing only in the D7 database. The solution we went with was to go for a full SQL query based migration to copy over the Ecommerce data from its tables to the Ubercart tables.
The full migration process was created as a re-executable sql script because we had to iteratively fix issues in the migration. The following set of sql queries were used in the migration. We hope this helps someone trying to Migrate Drupal Ecommerce module to Ubercart. Contact Us if you need help with migrating from Ecommerce to Ubercart or for that matter migrating from any system to Drupal + Ubercart.
/* DROP table tmp_ec_migrate_products; DROP table tmp_ec_migrate_txnid_order_id; */ -- Temporary table to store the nid,vid pairs that are inserted into uc_products table CREATE TABLE IF NOT EXISTS tmp_ec_migrate_products ( id int(10) unsigned NOT NULL AUTO_INCREMENT, nid int(10), vid int(10), PRIMARY KEY (id), INDEX (nid), INDEX (vid) ); -- Temporary table to store the nid,vid pairs that are inserted into uc_products table CREATE TABLE IF NOT EXISTS tmp_ec_migrate_txnid_order_id ( id int(10) unsigned NOT NULL AUTO_INCREMENT, txnid int(10), order_id int(10), PRIMARY KEY (id), INDEX (txnid), INDEX (order_id) ); DELETE uop.* FROM uc_order_products uop JOIN tmp_ec_migrate_txnid_order_id tto ON uop.order_id = tto.order_id; DELETE upr.* FROM uc_payment_receipts upr JOIN tmp_ec_migrate_txnid_order_id tto ON upr.order_id = tto.order_id; DELETE uoc.* FROM uc_order_comments uoc JOIN tmp_ec_migrate_txnid_order_id tto ON uoc.order_id = tto.order_id; DELETE uol.* FROM uc_order_line_items uol JOIN tmp_ec_migrate_txnid_order_id tto ON uol.order_id = tto.order_id; DELETE uo.* FROM uc_orders uo JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id; DELETE up.* FROM uc_products up JOIN tmp_ec_migrate_products tp ON up.vid = tp.vid AND up.nid = tp.nid; DELETE tp.* FROM tmp_ec_migrate_products tp; DELETE tto.* FROM tmp_ec_migrate_txnid_order_id tto;
/**
* Migration of ec products
*/
-- Store the nids and vids to be deleted if the script is to be re-run
INSERT INTO tmp_ec_migrate_products (
nid, vid
)
SELECT
ep.nid, ep.vid
FROM
ec_product ep
LEFT JOIN ec_product_tangible ept ON ep.nid = ept.nid AND ep.vid = ept.vid
LEFT JOIN uc_products up ON up.nid = ep.nid AND up.vid = ep.vid WHERE up.nid IS NULL;
-- Load uc_products from ec_products tables
INSERT INTO uc_products (
vid, nid, model, list_price,
cost, sell_price, weight, weight_units,
length, width, height, length_units,
pkg_qty, default_qty, unique_hash, ordering,
shippable
)
SELECT
ep.vid, ep.nid, ep.sku, 0,
0, ep.price, 0, '',
0, 0, 0, '',
1, 1, MD5(CONCAT(ep.vid, ep.nid, ep.sku, ep.price, NOW())) AS unique_hash, 0,
CASE ept.nid WHEN NULL THEN 0 ELSE 1 END AS shippable
FROM
ec_product ep
LEFT JOIN ec_product_tangible ept ON ep.nid = ept.nid AND ep.vid = ept.vid
LEFT JOIN uc_products up ON up.nid = ep.nid AND up.vid = ep.vid WHERE up.nid IS NULL;
/**
* Migration of ec transactions
*/
SELECT @new_order_id := MAX(order_id)+1 FROM uc_orders;
-- Create and store order_ids for new orders to be imported from the ec_transaction table
INSERT INTO tmp_ec_migrate_txnid_order_id (
txnid, order_id
)
SELECT
txnid,
@new_order_id := @new_order_id + 1
FROM ec_transaction;
-- Load uc_orders from ec_transaction and ec_transaction_address tables
INSERT INTO uc_orders (
order_id,
uid,
order_status,
order_total,
primary_email,
delivery_first_name,
delivery_last_name,
delivery_phone,
delivery_company,
delivery_street1,
delivery_street2,
delivery_city,
delivery_zone,
delivery_postal_code,
delivery_country,
billing_first_name,
billing_last_name,
billing_phone,
billing_company,
billing_street1,
billing_street2,
billing_city,
billing_zone,
billing_postal_code,
billing_country,
payment_method,
data,
host,
created,
modified,
product_count,
currency
)
SELECT
tto.order_id,
et.uid,
CASE et.payment_status WHEN 1 THEN 'pending' WHEN 2 THEN 'completed'
ELSE 'pending' END AS order_status,
et.gross,
et.mail,
etas.firstname,
etas.lastname,
'' AS delivery_phone,
'' AS delivery_company,
etas.street1,
etas.street2,
etas.city,
0 AS delivery_zone,
etas.zip,
0 AS delivery_country,
etab.firstname,
etab.lastname,
'' AS billing_phone,
'' AS billing_company,
etab.street1,
etab.street2,
etab.city,
0 AS billing_zone,
etab.zip,
0 AS billing_country,
CASE et.payment_method WHEN 'authorize_net' THEN 'credit' WHEN 'manually_add'
THEN 'other' ELSE 'other' END AS payment_method,
'a:0:{}' AS data,
'127.0.0.1' AS host,
et.created,
et.changed,
0 AS product_count,
'USD' AS currency
FROM
ec_transaction et
JOIN tmp_ec_migrate_txnid_order_id tto ON et.txnid = tto.txnid
LEFT JOIN ec_transaction_address etab ON et.txnid = etab.txnid AND etab.type = 'billing'
LEFT JOIN ec_transaction_address etas ON et.txnid = etas.txnid AND etas.type = 'shipping';
-- Create temporary table with indexed fields for handling country and state data
CREATE TABLE IF NOT EXISTS tmp_ec_migrate_ect_address (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
txnid int(10),
state varchar(100),
country char(2),
type char(1),
PRIMARY KEY (id),
INDEX (txnid),
INDEX (state),
INDEX (country),
INDEX (type)
);
-- Load temporary table with country and state data for billing address
INSERT INTO tmp_ec_migrate_ect_address (
txnid,
state,
country,
type
)
SELECT
txnid,
UPPER(state),
UPPER(CASE country WHEN 'an' THEN 'CW' WHEN 'uk' THEN 'GB' WHEN 'Un'
THEN 'US' WHEN 'cs' THEN 'RS' WHEN '' THEN 'US' WHEN NULL THEN 'US'
ELSE country END) AS country_corrected,
'b'
FROM ec_transaction_address
WHERE type = 'billing';
-- Load temporary table with country and state data for shipping address
INSERT INTO tmp_ec_migrate_ect_address (
txnid,
state,
country,
type
)
SELECT
txnid,
UPPER(state),
UPPER(CASE country WHEN 'an' THEN 'CW' WHEN 'uk' THEN 'GB' WHEN 'Un'
THEN 'US' WHEN 'cs' THEN 'RS' WHEN '' THEN 'US' WHEN NULL THEN 'US'
ELSE country END) AS country_corrected,
's'
FROM ec_transaction_address
WHERE type = 'shipping';
-- Update billing_zone for orders loaded from ec_transaction table
UPDATE uc_orders uo
JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id
LEFT JOIN tmp_ec_migrate_ect_address etab ON tto.txnid = etab.txnid
AND etab.type = 'b'
LEFT JOIN uc_zones uczb ON etab.state = UPPER(uczb.zone_name)
SET uo.billing_zone = uczb.zone_id
WHERE uo.billing_zone = 0;
-- Update delivery_zone for orders loaded from ec_transaction table
UPDATE uc_orders uo
JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id
LEFT JOIN tmp_ec_migrate_ect_address etas ON tto.txnid = etas.txnid AND etas.type = 's'
LEFT JOIN uc_zones uczs ON etas.state = UPPER(uczs.zone_name)
SET uo.delivery_zone = uczs.zone_id
WHERE uo.delivery_zone = 0;
-- Update billing_country for orders loaded from ec_transaction table
UPDATE uc_orders uo
JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id
LEFT JOIN tmp_ec_migrate_ect_address etab ON etab.txnid = tto.txnid
LEFT JOIN uc_countries uccb ON etab.country = UPPER(uccb.country_iso_code_2)
SET uo.billing_country = uccb.country_id
WHERE uo.billing_country = 0;
-- Update delivery_country for orders loaded from ec_transaction table
UPDATE uc_orders uo
JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id
LEFT JOIN tmp_ec_migrate_ect_address etas ON etas.txnid = tto.txnid
AND etas.type = 's'
LEFT JOIN uc_countries uccs ON etas.country = UPPER(uccs.country_iso_code_2)
SET uo.delivery_country = uccs.country_id
WHERE uo.delivery_country = 0;
-- Drop temporary table
DROP TABLE tmp_ec_migrate_ect_address;
-- Update product counts for orders loaded from ec_transaction table
UPDATE uc_orders uo
JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id
LEFT JOIN (SELECT txnid, COUNT(txnid) AS product_count FROM
ec_transaction_product GROUP BY txnid) tpc ON tto.txnid = tpc.txnid
SET uo.product_count = tpc.product_count
WHERE tpc.product_count IS NOT NULL;
/**
* Migration of transaction products
*/
-- Load uc_order_products from ec_transaction_product table
INSERT INTO uc_order_products (
order_id,
nid,
title,
model,
qty,
cost,
price,
weight,
data,
weight_units
)
SELECT
tto.order_id,
etp.nid,
etp.title,
etp.title AS model,
etp.qty,
0 AS cost,
etp.price,
ctp.field_weight_0_value,
'a:1:{s:6:"module";s:10:"uc_product";}' AS data,
'lb' AS weight_units
FROM
ec_transaction_product etp
JOIN tmp_ec_migrate_txnid_order_id tto ON etp.txnid = tto.txnid
LEFT JOIN content_type_physical_item ctp ON etp.nid = ctp.nid AND
etp.vid = ctp.vid;
/**
* Migration of authorize.net payment transactions
*/
-- Load uc_payment_receipts from ec_authorize_net table
INSERT INTO uc_payment_receipts (
order_id,
method,
amount,
uid,
data,
comment,
received
)
SELECT
tto.order_id,
'Credit Card' AS method,
ea.amount,
uo.uid,
CONCAT('a:3:{s:6:"module";s:15:"uc_authorizenet";s:8:"txn_type";s:12:"auth_capture";s:6:"txn_id";s:10:"',
ea.anid, '";}') AS data,
CONCAT('Type: Authorization and capture
ID: ', ea.anid) AS comment,
uo.modified
FROM
uc_orders uo
JOIN tmp_ec_migrate_txnid_order_id tto ON uo.order_id = tto.order_id
JOIN ec_authorize_net ea ON tto.txnid = ea.txnid;
/**
* Migration of manually recorded receipts
*/
-- Load uc_payment_receipts for manually added payments recorded in ec_transaction
INSERT INTO uc_payment_receipts (
order_id,
method,
amount,
uid,
data,
comment,
received
)
SELECT
tto.order_id,
'Other' AS method,
et.gross,
et.uid,
'' AS data,
'' AS comment,
et.changed
FROM
tmp_ec_migrate_txnid_order_id tto
JOIN ec_transaction et ON tto.txnid = et.txnid
WHERE
et.payment_status = 2 AND et.payment_method = 'manually_add';
/**
* Migration of transaction notes
*/
-- Load uc_order_comments from ec_transaction_note table
INSERT INTO uc_order_comments (
order_id,
uid,
order_status,
notified,
message,
created
)
SELECT
tto.order_id,
et.uid,
CASE et.payment_status WHEN 1 THEN 'pending' WHEN 2 THEN 'completed'
ELSE 'pending' END AS order_status,
1 AS notified,
etn.note,
et.created
FROM
ec_transaction et
JOIN tmp_ec_migrate_txnid_order_id tto ON et.txnid = tto.txnid
JOIN ec_transaction_note etn ON et.txnid = etn.txnid;
/**
* Migration of transaction tax
*/
-- Load uc_order_line_items from ec_transaction_misc table
INSERT INTO uc_order_line_items (
order_id,
type,
title,
amount,
weight,
data
)
SELECT
tto.order_id,
'tax' AS type,
'California State Tax' AS title,
etm.price,
etm.weight,
CONCAT('{s:8:"tax_rate";s:5:"0.095";s:14:"taxable_amount";d:',
et.gross, ';s:16:"tax_jurisdiction";s:20:"California State Tax";}') AS
data
FROM
ec_transaction_misc etm
JOIN tmp_ec_migrate_txnid_order_id tto ON etm.txnid = tto.txnid
JOIN ec_transaction et ON tto.txnid = et.txnid;