WPCV / wpcv-woo-civi-integration

A WordPress plugin that creates CiviCRM Contributions, Memberships and Participants from WordCommerce Orders and keeps WordCommerce Customer Accounts in sync with CiviCRM Contact data.
GNU Affero General Public License v3.0
4 stars 8 forks source link

Help with duplicate addresses #43

Closed cdhassell closed 1 year ago

cdhassell commented 1 year ago

The plugin is creating a new address within a contact each time an order occurs. An example of how this looks is here. I don't think this is related to the dedup rule, since it is not creating a duplicate contact. Can I get a suggestion on what I am doing wrong?

christianwach commented 1 year ago

@cdhassell Hard to assess, sorry. I'll keep an eye out and see if I spot this behaviour. Thanks for the report.

cdhassell commented 1 year ago

I have been dumping variables from the plugin code to get some insight into how this process works. Here is what I am seeing. In class-woo-civi-contact-address.php, function entities_update() does an exact match between existing addresses and the new address fields. So for example, the code tests $existing->street_address === $address['street_address'], and does a similar exact match on the city, postal code and supplemental address fields to determine whether to set $address_exists to TRUE or FALSE.

I think the main issue is that my site uses USPS address validation to check incoming addresses, which reformats the address fields. So for example the user enters street address '61 Kensington drive' and city 'Camp hill' in Woocommerce. The plugin sends these to Civicrm, which runs address validation and stores them as '61 KENSINGTON DR' and 'CAMP HILL'. Any future incoming address will fail the exact match to the existing address, and so will keep adding new copies of the address on each transaction.

Even without the USPS address validation, the code seems to depend on the address fields being entered in precisely the same way each time, which seems likely to fail sometimes due to users being inconsistent with capitalization, spelling and abbreviations.

So my theory is that the plugin's attempt to sync the addresses is defeated by the address validation, because Civicrm changes the address before storing it. Beyond that, depending on an exact match between two user-entered strings seems likely to fail sometimes even in the absence of address validation.

If this is correct, how can it be fixed? We can get closer by using strtoupper() on the strings before the comparison to at least eliminate any capitalization differences. That will not eliminate all the differences, like when 'drive' is changed to 'DR'. Maybe someone here can suggest a better solution to the issue.

christianwach commented 1 year ago

@cdhassell Thanks for the deep dive into the issue. Nothing jumps out at me at the moment as a solution. The case-normalised comparison does seem like a useful enhancement, however.

Could you perhaps alter your "user journey" or whatever it's called so that people who have existing accounts are strongly encouraged to log in? That way, their details would be auto-filled before submission.

cdhassell commented 1 year ago

Yes, I will talk to management about encouraging people to log in. I am sure they will not want to make it a requirement. I will work on a PR to implement case normalization as time allows. Thanks.

cdhassell commented 1 year ago

Circling back to this after a long delay: I found that the easiest approach is to periodically run a simple SQL query to find and delete duplicate addresses in the civicrm tables. Since these are all post-validation, the exact match works and can be triggered in cron. Unfortunately that is not going to be a solution for most users, if there are any others with this issue.

christianwach commented 1 year ago

@cdhassell I suspect that 6a1fe7f49d927e50c873474f33c0ebefe4bd4162 fixes this issue. Would be great if you can confirm.

christianwach commented 1 year ago

FWIW the is_match() method only determines whether to skip an Address update rather than whether to go ahead with an update. I think this means that it can remain as a strict check because any variation however small should trigger an update to the Billing and/or Shipping Address for the Contact.

The problem seems to have been the strict comparison of Location Type IDs. The PR explains why this failed.