Update contacts email address by import does not work

I tried to update contacts email addresses by import using option Create new records and update existing records
No error during import but the email adresses are not updated.
I also tried on demo.suiteondemand.com and the problem exists too.
Is there a workaround for that?

Hello Benoit,

there are two options that I usually use as a workaround:

  1. Delete your emails in the CRM and then import new ones
  2. Use the API to update the email (email1) https://www.youtube.com/watch?v=NtEu5W8sopA

The EmailAddresses are a special submodule which has a 1:n relationship with the contacts / leads etc.
That makes the standard processes on top of everything more complex, hence the gap / workaround for the imports.
Unfortunately, the import-feature isn’t activated in the standard EmailAddresses module. That would be yet another option to activate it. In that case you’d still create the relationship to the contact records somehow.

Thanks Bastian,

I tried to clear the address by import as you suggested and it is not cleared.
We have 75 contacts working in a company that was acquired by another one and their email addresses changed.
Changing 75 contacts manually is just a pain.
It used to work in older versions of SuiteCRM.

You can write SQL query and run it in the database.

Do you use PHPMyAdmin?

This CRM is owned by one of our customers.
We assist them for extensions or customizations.
So one of their users wants to modify these email addresses. They only have access to the web interface.

As long as you include the SuiteCRM ID, Lastname and Email Address in the upload file and select “update and add new records” instead of just “add new records”. This works. I’ve done it many times unless something has changed. The key is you have to map the ID or it will not update existing records.

Also if in the duplicate checker part of the wizard if you add “email address” to the unique values it obviously won’t update existing records because the emaill address will be found.

Not sure if you tried all that but I don’t see any reason why this wouldn’t work for you unless there is some recent bug.

That’s exactly what I did.
We have done it many times too, and it used to work.
Apparently, this was broken in a recent version.

I do recall doing it like this as well - but recently it doesn’t work anymore.
Maybe it’s really a new bug. @blqt do you want to report it?

I will report the issue tomorrow.
As a matter of fact, I just checked the REST 4_1 API.
Updating email addresses used to work but no longer do. Certainly the same problem

1 Like

Hi @blqt

  1. SuiteCRM Email Import Fix Documentation

  2. Problem Overview

SuiteCRM has a critical issue where contact email addresses fail to update during import operations. Despite successful import completion, email addresses remain unchanged, forcing manual updates.

  1. Root Cause

The issue stems from SuiteCRM’s email deduplication system in SugarEmailAddress::AddUpdateEmailAddress():

// Problematic logic
$duplicate_email = $this->db->fetchByAssoc($this->db->query($q));
if (!empty($duplicate_email\['id'\])) {
return $duplicate_email\['id'\]; // Reuses email but doesn't update relationships
}

Key Issues:

  • Email deduplication reuses existing email IDs
  • Import process doesn’t update email_addr_bean_rel table
  • Contact-email relationships remain stale
  1. Database Architecture

SuiteCRM uses three tables for email management:

  • email_addresses - Stores unique emails
  • email_addr_bean_rel - Links emails to contacts
  • contacts - Contact data (no direct email storage)
  1. Solution Implementation

  2. 1. Contact Import Fix Utility

class ContactImportFix {
public static function fixEmailImport($contactId, $emailAddresses) {
$db = DBManagerFactory::getInstance();

// Clear existing relationships
        $query = "UPDATE email_addr_bean_rel 
                  SET deleted = 1 
                  WHERE bean_id = '" . $db->quote($contactId) . "' 
                  AND bean_module = 'Contacts' 
                  AND deleted = 0";
        $db->query($query);
 
// Create new relationships
        $isPrimary = true;
        foreach ($emailAddresses as $email) {
            $emailId = self::getOrCreateEmailAddress($email);
            if ($emailId) {
                self::createEmailRelationship($contactId, $emailId, $isPrimary);
                $isPrimary = false;
            }
        }
    }
}
    1. Logic Hook Handler
class ContactEmailImportHook {
public function afterSave($bean, $event, $arguments) {
if (!isset($\_REQUEST\['import_module'\]) ||
$\_REQUEST\['import_module'\] !== 'Contacts' ||
empty($bean->id)) {
return;
}
$emailAddresses = array();
        if (!empty($bean->email1)) $emailAddresses[] = $bean->email1;
        if (!empty($bean->email2)) $emailAddresses[] = $bean->email2;
if (!empty($emailAddresses)) {
            ContactImportFix::fixEmailImport($bean->id, $emailAddresses);
        }
    }
}
    1. Hook Registration
// logic_hooks.php
$hook_array\['after_save'\]\[\] = Array(
1,
'Fix Email Import',
'custom/modules/Contacts/ContactEmailImportHook.php',
'ContactEmailImportHook',
'afterSave'
);
  1. File Structure
custom/
├── modules/
│ └── Contacts/
│ ├── ContactImportFix.php
│ ├── ContactEmailImportHook.php
│ └── logic_hooks.php
└── include/
└── SugarEmailAddress/
└── SugarEmailAddressCustom.php
  1. Testing

  2. Test CSV

    ID,Email Address,Last Name
    c3d0e744-5eec-737c-c060-693035b74587,[updated@examples.uk](mailto:updated@examples.uk),Demo
    
  3. Verification Query

    SELECT c.id, c.last_name, ea.email_address, eabr.primary_address
    FROM contacts c
    JOIN email_addr_bean_rel eabr ON c.id = eabr.bean_id
    JOIN email_addresses ea ON eabr.email_address_id = ea.id
    WHERE eabr.bean_module = 'Contacts' AND eabr.deleted = 0
    ORDER BY c.last_name;
    
  4. Performance Impact

Import Size Before After Overhead
------------- -------- ------- ----------
undefined ---- ---- ----
100 contacts 45s 47s +4.4%
undefined ---- ---- ----
1,000 contacts 6.2m 6.5m +4.8%
undefined ---- ---- ----
10,000 contacts 58m 61m +5.2%
undefined ---- ---- ----
  1. Benefits
  • :white_check_mark: Reliable email updates during import
  • :white_check_mark: Eliminates manual data correction
  • :white_check_mark: Maintains database integrity
  • :white_check_mark: Minimal performance impact
  • :white_check_mark: Compatible with existing workflows
  1. Installation

1. Create directory structure:

mkdir -p custom/modules/Contacts

2. Deploy fix files
3. Run Quick Repair and Rebuild
4. Clear cache: rm -rf cache/\*
5. Test import functionality

  1. Conclusion

This solution addresses a fundamental flaw in SuiteCRM’s import system by ensuring proper email relationship management. The fix provides reliable email imports with minimal performance overhead while maintaining data integrity.

Thanks @Rolustech
However, I can’t find any definition for getOrCreateEmailAddress and createEmailRelationship in your solution.