Magento – Merging customer accounts based on email, name and billing address

customermagento-1.7

I am trying to modify an extension that automatically creates a customer account at checkout by emailing a password. However, the ext. checks if the customer email already exists in the database and if it does it merges the order into the exisiting account.

I would like to add additional criteria before we safely merge i.e name and billing address. If there is a match we can safely merge otherwise create a new account.

I've add the following to the indexController.php

        $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByEmail($order->getCustomerEmail());
    $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByFirstName($order->getCustomerFirstName());
    $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByLastName($order->getCustomerLastName()); 
    $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByBillingPostcode($order->getCustomerBillingPostcode());

And the complete controller file:

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
class MyCustomExtension_MergeAccounts_IndexController extends Mage_Core_Controller_Front_Action
{
    public function indexAction() {
        $this->loadLayout();
        $this->renderLayout();
    }
    public function _CreateCustomerFromGuest($company="", $city, $telephone, $fax="", $email, $prefix="", $firstname, $middlename="", $lastname, $suffix="", $taxvat="", $street1, $street2="", $postcode, $region_id, $country_id, $customer_group_id, $storeId) {

                $customer = Mage::getModel('customer/customer');
                $street_r=array("0"=>$street1,"1"=>$street2);
                $group_id=$customer_group_id;
                $website_id=Mage::getModel('core/store')->load($storeId)->getWebsiteId();;


                $default_billing="_item1";
                $index="_item1";

                $customerData=array(
                        "prefix"=>$prefix,
                        "firstname"=>$firstname,
                        "middlename"=>$middlename,
                        "lastname"=>$lastname,
                        "suffix"=>$suffix,
                        "email"=>$email,
                        "group_id"=>$group_id,
                        "taxvat"=>$taxvat,
                        "website_id"=>$website_id,
                        "default_billing"=>$default_billing
                );

                $customer->addData($customerData); ///make sure this is enclosed in arrays correctly

                $addressData=array(
                        "prefix"=>$prefix,
                        "firstname"=>$firstname,
                        "middlename"=>$middlename,
                        "lastname"=>$lastname,
                        "suffix"=>$suffix,
                        "company"=>$company,
                        "street"=>$street_r,
                        "city"=>$city,
                        "region"=>$region_id,
                        "country_id"=>$country_id,
                        "postcode"=>$postcode,
                        "telephone"=>$telephone,
                        "fax"=>$fax
                );


                $address = Mage::getModel('customer/address');
                $address->setData($addressData);

                /// We need set post_index for detect default addresses
                ///pretty sure index is a 0 or 1
                $address->setPostIndex($index);
                $customer->addAddress($address);
                $customer->setIsSubscribed(false);
                $customer->setPassword($customer->generatePassword(8));

                ///adminhtml_customer_prepare_save
                $customer->save();
                $disable_new_customer_email = (bool)Mage::getStoreConfig('guesttoreg/guesttoreg/disable_new_customer_email');
                if ($disable_new_customer_email != true) {
                    $customer->sendNewAccountEmail();
                }

                ///adminhtml_customer_save_after
                $customerId=$customer->getId();

                Mage::log("customerId:$customerId");

                return $customerId;
    } 
    public function postAction() {
        if($this->getRequest()->getPost()) {

            $data = $this->getRequest()->getPost();
            #print_r($data);
            #echo "ORDER ID: " . $data['customer_order_id'];

            $resource = Mage::getSingleton('core/resource');
            $prefix = Mage::getConfig()->getNode('global/resources/db/table_prefix'); 
            $write = $resource->getConnection('core_write');
            $read = $resource->getConnection('core_read');

            $select_qry =$read->query("SELECT entity_id FROM `".$prefix."sales_flat_order` WHERE `increment_id`='".$data['customer_order_id']."'");
            $row = $select_qry->fetch();
            $entity_id = $row['entity_id'];

            $order = Mage::getModel('sales/order');
            $order->load($entity_id); //needs entity_id NOT order_Id

            $store_id = Mage::app()->getStore()->getId();
            $valueid = Mage::getModel('core/store')->load($store_id)->getWebsiteId();
            //DUPLICATE CUSTOMERS are appearing after import this value above is likely not found.. so we have a little check here
            if($valueid < 1) { $valueid =1; }
            #exit;

            $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByEmail($order->getCustomerEmail());
            $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByFirstName($order->getCustomerFirstName());
            $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByLastName($order->getCustomerLastName()); 
            $customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByBillingPostcode($order->getCustomerBillingPostcode());                        


            if ($customer->getId()) {
            $customerexistedmessage = true;
            $customerId = $customer->getId();
            /* SOME DIRECT SQL HERE. JUST MOVES THE ORDER OVER TO THE NEWLY CREATED CUSTOMER */
            $entityTypeId = Mage::getModel('eav/entity')->setType('order')->getTypeId();

            //1.3.x
            /*
            $select_qry = $read->query("SELECT attribute_id FROM `".$prefix."eav_attribute` WHERE attribute_code = 'customer_is_guest' AND entity_type_id = '". $entityTypeId ."'");
            $eav_attribute_row = $select_qry->fetch();
            $write_qry = $write->query("UPDATE `".$prefix."sales_order_int` SET value = '0' WHERE attribute_id = '". $eav_attribute_row['attribute_id'] ."' AND entity_id = '". $entity_id ."'");
            $write_qry = $write->query("UPDATE `".$prefix."sales_order` SET customer_id = '". $customerId ."' WHERE entity_id = '". $entity_id ."'");
            */

            //lets do a check first.. if we have existing guest orders prior to this point in time lets merge those too :)
            //1.3.x - 1.4.0.1
            #$select_qry = "SELECT ".$prefix."sales_flat_order.entity_id, ".$prefix."sales_order_varchar.value FROM `".$prefix."sales_flat_order` INNER JOIN ".$prefix."sales_order_varchar ON ".$prefix."sales_order_varchar.entity_id = ".$prefix."sales_flat_order.entity_id WHERE ".$prefix."sales_flat_order.customer_id IS NULL AND ".$prefix."sales_order_varchar.attribute_id = '".$attribute_id."'";

             $select_qry = "SELECT * FROM `".$prefix."sales_flat_order` WHERE customer_id IS NULL AND customer_email = '".$order->getCustomerEmail()."'";

             $rows = $read->fetchAll($select_qry);
             foreach($rows as $datafromexisting)
                { 
                         #print_r($datafromexisting);
                         $existingorder_entity_id = $datafromexisting['entity_id'];
                         #echo "CUSTY ID: " . $customerId . "<br/>";
                         #echo "ENTITY ID: " . $datafromexisting['entity_id'] . "<br/>";
            //1.4.x+
            $write_qry = $write->query("UPDATE `".$prefix."sales_flat_order` SET customer_id = '". $customerId ."', customer_is_guest = '0', customer_group_id = '1' WHERE entity_id = '". $existingorder_entity_id ."'");
            $write_qry = $write->query("UPDATE `".$prefix."sales_flat_order_grid` SET customer_id = '". $customerId ."' WHERE entity_id = '". $existingorder_entity_id ."'");
            //UPDATE FOR DOWNLOADABLE PRODUCTS
            $write_qry = $write->query("UPDATE `".$prefix."downloadable_link_purchased` SET customer_id = '". $customerId ."' WHERE order_id = '". $existingorder_entity_id ."'");

                }

            } else {
            $customerexistedmessage = false;

            $entityTypeId = Mage::getModel('eav/entity')->setType('order')->getTypeId();
            $resource = Mage::getSingleton('core/resource');
            $prefix = Mage::getConfig()->getNode('global/resources/db/table_prefix'); 
            $write = $resource->getConnection('core_write');
            $read = $resource->getConnection('core_read');
        $select_qry5 = $read->query("SELECT subscriber_status FROM `".$prefix."newsletter_subscriber` WHERE subscriber_email = '". $order->getCustomerEmail() ."'");
        $newsletter_subscriber_status = $select_qry5->fetch();

            $customerId = $this->_CreateCustomerFromGuest($order->getBillingAddress()->getData('company'), $order->getBillingAddress()->getData('city'), $order->getBillingAddress()->getData('telephone'), $order->getBillingAddress()->getData('fax'), $order->getCustomerEmail(), $order->getBillingAddress()->getData('prefix'), $order->getBillingAddress()->getData('firstname'), $middlename="", $order->getBillingAddress()->getData('lastname'), $suffix="", $taxvat="", $order->getBillingAddress()->getStreet(1), $order->getBillingAddress()->getStreet(2), $order->getBillingAddress()->getData('postcode'), $order->getBillingAddress()->getData('region'), $order->getBillingAddress()->getData('country_id'), "1", $store_id);


            /* SOME DIRECT SQL HERE. JUST MOVES THE ORDER OVER TO THE NEWLY CREATED CUSTOMER */
            //1.3.x
            /*
            $select_qry = $read->query("SELECT attribute_id FROM `".$prefix."eav_attribute` WHERE attribute_code = 'customer_is_guest' AND entity_type_id = '". $entityTypeId ."'");
            $eav_attribute_row = $select_qry->fetch();
            $write_qry = $write->query("UPDATE `".$prefix."sales_order_int` SET value = '0' WHERE attribute_id = '". $eav_attribute_row['attribute_id'] ."' AND entity_id = '". $entity_id ."'");
            $write_qry = $write->query("UPDATE `".$prefix."sales_order` SET customer_id = '". $customerId ."' WHERE entity_id = '". $entity_id ."'");
            */
            //1.4.x
            $write_qry = $write->query("UPDATE `".$prefix."sales_flat_order` SET customer_id = '". $customerId ."', customer_is_guest = '0', customer_group_id = '1' WHERE entity_id = '". $entity_id ."'");
            $write_qry = $write->query("UPDATE `".$prefix."sales_flat_order_grid` SET customer_id = '". $customerId ."' WHERE entity_id = '". $entity_id ."'");

            //UPDATE FOR DOWNLOADABLE PRODUCTS
            $write_qry = $write->query("UPDATE `".$prefix."downloadable_link_purchased` SET customer_id = '". $customerId ."' WHERE order_id = '". $entity_id ."'");
            //UPDATE FOR NEWSLETTER
            if($newsletter_subscriber_status['subscriber_status'] !="" && $newsletter_subscriber_status['subscriber_status'] > 0) {
            $write_qry = $write->query("UPDATE `".$prefix."newsletter_subscriber` SET subscriber_status = '". $newsletter_subscriber_status['subscriber_status'] ."' WHERE subscriber_email = '". $order->getCustomerEmail() ."'");
            }

            }
            if($customerexistedmessage == true){    
                $message = $this->__('The email address already exists so the order has been merged to the existing account.');
            } else {
                $message = $this->__('Your account has been created and a email has been sent to you with their username and password.');
            }
            Mage::getSingleton('core/session')->addSuccess($message);

        }
        else {
            Mage::getSingleton('core/session')->addError($this->__('Sorry this order could not be converted to a customer account.'));
        }
        #exit;

        if($this->getRequest()->getParam("backurl")!="")
            $this->_redirect($this->getRequest()->getParam("backurl"));
        else 
            $this->_redirect("/");
    }
}

However i get an error in var log

a:5:{i:0;s:84:"Invalid method Mage_Customer_Model_Customer::loadByFirstName(Array
(
    [0] => 
)
)";i:1;s:1190:"#0 /var/www/uk-dev3.thanedirect.com/htdocs/app/code/local/MyCustomExtension/MergeAccounts/controllers/IndexController.php(103): Varien_Object->__call('loadByFirstName', Array)

I know that the additional criteria I have added below:

$customer = Mage::getModel('customer/customer')->setWebsiteId($valueid)->loadByEmail($order->getCustomerEmail()); 

Is causing the error but I don't what the correct parameters should be.

Could anyone provide me with some guidance please..?

Best Answer

loadByEmail() looks for the customer entity with the e-mail address specified as a parameter. the methods you added do not exist. That's why you get that error.
What you are trying to do is not possible because Magento allows only one customer account per e-mail address. In other words, the e-mail address is unique.
That's why, the following scenario will fail. You have an account with the e-mail address test@example.com and with an address saved in the address book: '99th Some Road, London, UK'. A customer tries to checkout with the same e-mail address but sets the billing & shipping address to '77th Some Other Road, Liverpool, UK'. In this case, according to your specifications you will have to create a new account. That's not possible due to e-mail address already existing.