[6.1-oldstable] IntegrityError when a customer changes his email address and create a new account with the first email

Bug #1083592 reported by Guewen Baconnier @ Camptocamp
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
Magento OpenERP Connector
Fix Released
High
Yannick Vaucher @ Camptocamp

Bug Description

revision-id: <email address hidden>

It happens when:
 1. Customer A creates an account on Magento. It uses the e-mail "<email address hidden>"
 2. Customer A is imported in OpenERP with the email "<email address hidden>"
 3. Customer A changes his email on Magento to "<email address hidden>"
    * OpenERP still knows the email "<email address hidden>" for customer A
 4. Customer A forget his password and creates a new account on Magento
    with the email "<email address hidden>"
 5. Customer A orders some stuff on Magento with his new account
    * OpenERP import the sale order.
      It doesn't know the customer, but in such case, it tries to find
      an existing record with the same email.
      It finds the first account of customer A and rebind it with the new Magento account
      (instead of creating a new partner).
      A duplicate key error is thrown because only 1 Magento customer is allowed
      for 1 OpenERP partner.

Traceback with some slight changes on the path to shorten it.

2012-11-26 14:00:19,759 4344 ERROR ? openerp.addons.base_external_referentials.external_osv: error in _import of {'store_id': '1', 'website_id': '1', 'updated_at': '2012-11-21 09:12:33', 'prefix': None, 'created_in': u'English', 'password_hash': 'e4672724ce98cad7d892b99970aac2f8:Uu', 'taxvat': 'FR', 'increment_id': '', 'default_billing': '33006', 'tax_class_id': '3', 'customer_id': '31064', 'default_shipping': '33006', 'email': '<email address hidden>', 'confirmation': None, 'firstname': 'Homer', 'middlename': None, 'lastname': 'SIMPSON', 'dob': None, 'gender': None, 'created_at': '2012-11-21 09:11:01', 'suffix': None, 'group_id': '1', 'external_id': '31064'} with external_id 1. Creating report
Traceback (most recent call last):
  File "/srv/openerp/src/server/openerp/addons/base_external_referentials/external_osv.py", line 548, in _ext_import_one_cr
    context=import_ctx)
  File "/srv/openerp/src/server/openerp/addons/base_external_referentials/external_osv.py", line 498, in _ext_import_one
    self.create_external_id_vals(cr, uid, existing_rec_id, external_id, referential_id, context=context)
  File "/srv/openerp/src/server/openerp/addons/base_external_referentials/external_osv.py", line 917, in create_external_id_vals
    return self.pool.get('ir.model.data').create(cr, uid, ir_model_data_vals, context=context)
  File "/srv/openerp/src/server/openerp/osv/orm.py", line 4179, in create
    cr.execute('insert into "'+self._table+'" (id'+upd0+") values ("+str(id_new)+upd1+')', tuple(upd2))
  File "/srv/openerp/src/server/openerp/sql_db.py", line 152, in wrapper
    return f(self, *args, **kwargs)
  File "/srv/openerp/src/server/openerp/sql_db.py", line 212, in execute
    res = self._obj.execute(query, params)
IntegrityError: duplicate key value violates unique constraint "ir_model_data_external_reference_uniq_per_object"
DETAIL: Key (model, res_id, external_referential_id)=(res.partner, 7204, 1) already exists

To solve this issue, we have to never bind new Magento accounts to already bound partners.
We should bind a new Magento account only if a partner with the same email is found,
but is not already bound to a Magento customer.

(By bound, I means linked with Magento customer)

It should be as simple as:

=== modified file 'magentoerpconnect/partner.py'
--- magentoerpconnect/partner.py2012-05-21 05:43:21 +0000
+++ magentoerpconnect/partner.py2012-11-27 13:44:15 +0000
@@ -312,7 +312,7 @@
             cr,cr uid,
             vals['emailid'],
             vals.get('website_id', False),
- is_bound=None,
+ is_bound=False,
             context=context)

         return False, partner_id

BUT, we'll have issues with the following unique constraint, because we'll have 2 accounts with the same email and website...

    _sql_constraints = [('emailid_uniq', 'unique(emailid, website_id)', 'A partner already exists with this email address on the selected website.')]

The last and the better option would be to allows to have 1 partner
for multiple customers on Magento, but so far I do not measure the consequences.
And as the ir_model_data table is shared for all the external ids, we can't actually
remove the ir_model_data_external_reference_uniq_per_object constraint.

Related branches

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

Another solution could be to add a new cron job which updates regularly the customers, but it would not really solve the issue, just reduce the chances to issue it.

Revision history for this message
Kyle Waid (midwest) wrote :

Hello Guewen,

I have seen many issues related to customer accounts in the connector. I do not understand the design decision to use the customer email address as a primary identifier. IMO this idea should be scrapped completely. The email address should be mapped as a simple field. The primary identifier needs to be the external database primary key (entity_id).

In the case of guest checkout, there needs to be a generic partner called "Guest Checkout". This is only to satisfy the OpenERP requirement of a partner record. All new billing/shipping should import as addresses of the guest checkout user. This user should be created via xml in the install of MagentoERPConnect. The core partner record should be readonly.

IMO the entire partner mapping feature needs to be reworked.

Kyle

Revision history for this message
Kyle Waid (midwest) wrote :

If we user only entity_id as the primary identifier, then we will not have such issues as reported above. You can update these partners in 2 ways. You can use a synchronize partner feature like import partners with increment id gt, lt,

and you can synchronize onfly.

if partner entity_id is matched, and email passed != stored record in ERP, it is updated automatically

Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

Hi Kyle,

Thanks for your input on that.

The email is not the primary identifier, the primary identifier is the entity_id at least in oldstable6.1 (but I would be surprised if this wasn't the case in stable6.1).

But, the mechanism on the email is only there to try to "reconcile" partners.
Example:
 1. I create manually a partner on OpenERP with my email
 2. I create and import a customer with my email => the connector first search if it founds a partner with the same email and will consider that's the one to use. Afterwards, the entity_id will well be used as the identifier.

Second Example:
 1. I create a customer on Magento with my email (> imported in openerp)
 2. I create a guest order with the same email on Magento => I expect that it will be linked with the partner created in step 1.

I'm not sure that the generic guest partner is a good idea for some accounting reasons.

I don't know if you speak about the stable or oldstable version for your issues with customer accounts, but I did not encountered issues on oldstable for a while, except this one.

Update the partners in 2 ways would be totally possible, that's just not implemented.

Here, it doesn't fails because the email != than the stored one but because the first account has not been updated, and the second account (different entity_id) has the same email.

Basically, the change I wrote in the initial report would do the trick, it would just means that I would need to remove the unique constraint on the mail. And I start to think that's the way to go.

Thanks
Guewen

Changed in magentoerpconnect:
assignee: nobody → Yannick Vaucher @ Camptocamp (yvaucher-c2c)
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

I added a branch in which I do a check to know if the partner emailid exists in openerp but under a different external_reference.

When it happen, the partner which might be an old outdated partner I update the old partner before we try to update the partner of the sale order.

So this error shouldn't be raised again unless you have some inconsistent data.

Regards,
Yannick

Changed in magentoerpconnect:
status: New → Confirmed
importance: Undecided → High
Revision history for this message
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote :

I set this bug as high importance as it can block the import of sale orders.

Changed in magentoerpconnect:
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.