Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/core#2450 - Update source/target contacts on contribution updates #19820

Conversation

mflandorfer
Copy link
Contributor

Overview

https://lab.civicrm.org/dev/core/-/issues/2450

Update source/target activity contacts whenever a contribution is updated.

Before

Since PR #19202 CiviCRM would skip updates to source/target activity contact IDs when a contribution is updated, to prevent overwriting them with less accurate contact IDs. However, if a contribution is moved to another contact, the associated activity would still be stuck with the old contact.

After

When a contribution is updated and ...

  • a source and target contact exist, the target contact will be set to the contribution's contact_id. The source contact remains untouched.
  • only a source contact exists, the source contact will be set to the contribution's contact_id. This would be the case, if the contribution was originally created via the API.

Technical Details

Comments

@civicrm-builder
Copy link

Can one of the admins verify this patch?

@civibot civibot bot added the master label Mar 16, 2021
@civibot
Copy link

civibot bot commented Mar 16, 2021

(Standard links)

@colemanw
Copy link
Member

@civicrm-builder add to whitelist.
@mflandorfer thanks for the PR and extra thanks for including a test!

Copy link
Contributor

@MegaphoneJon MegaphoneJon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just reviewed the code, but haven't done an r-run.

I'll first say that this is incredible quality for someone who's never submitted a PR to Civi core before - or frankly, for someone who has. Very readable, uses modern Civi conventions, and a well-written test.

I spent some time worrying about the comment directly above this patch that says, "Don't update the activity target values when the contribution is updated" but I can't see a scenario where this patch doesn't create the correct values.

Part of me wonders if this update should happen in the movecontrib extension - but tbh I think that functionality belongs in core anyway.

}
else {
// If a target contact exists, update it
$activityParams['target_contact_id'] = $contribution->contact_id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On line 541 above, $activityParams['target_contact_id'] accepts an array; here, it's passed a scalar. Are both correct, or should this be an array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your feedback!

Yes, I think this should be an array.

@@ -539,6 +540,22 @@ public static function create(&$params) {
$activityParams['source_contact_id'] = (int) ($params['source_contact_id'] ?? (CRM_Core_Session::getLoggedInContactID() ?: $contribution->contact_id));
$activityParams['target_contact_id'] = ($activityParams['source_contact_id'] === (int) $contribution->contact_id) ? [] : [$contribution->contact_id];
}
else {
// Check if target contact exists
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments on lines 537-539 should be removed if we're now setting target contacts on update.

@MegaphoneJon
Copy link
Contributor

Many thanks @mflandorfer, my colleague is setting up to do a manual test now. The manual test plus my code review should be enough to get this approved for merge.

@megaphonetech-dennis
Copy link
Contributor

I just finished a manual test. Everything worked great. And, I didn't find anything odd or broken as a result of applying this patch.

['contact_id' => $contactId_1]
))['values'][0];

$activity = $this->callAPISuccess('Activity', 'get', [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to change this but one small shortcut is

$activity = $this->callAPISuccessGetSingle('Activity', ['source_record_id' => $contribution['id']])

of course you have to set a limit if there could be legimately more than one...

$activityParams['source_contact_id'] = (int) ($params['source_contact_id'] ?? (CRM_Core_Session::getLoggedInContactID() ?: $contribution->contact_id));
$activityParams['target_contact_id'] = ($activityParams['source_contact_id'] === (int) $contribution->contact_id) ? [] : [$contribution->contact_id];
}
else {
// Check if target contact exists
$targetContactQuery = ActivityContact::get(FALSE)->setLimit(1)->setWhere([
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is obviously a high-volume function & we need to be mindful of queries. In particular unnecessary updates can be locking queries - so I would do a bit more work here to check whether we are actually making a change of the contribution->contact is already the target - probably by opening up ['record_type_id:name', '=', 'Activity Targets'], to

['record_type_id:name', 'IN', ['Activity Targets', 'Activity Sources']],

and doing extra checks in the php layer. If it starts to get a bit long then extract it

@eileenmcnaughton
Copy link
Contributor

I agree with @MegaphoneJon - this looks really good. I think it's worth doing a bit more work to avoid doing updates if there is no change though as this is a high-volume function

@eileenmcnaughton
Copy link
Contributor

Test Result (3 failures / +3)CRM_Contribute_BAO_ContributionTest.testUpdateActivityContactOnContributionContactChangeCRM_Contribute_Form_Contribution_ConfirmTest.testPayNowPaymentapi_v3_SyntaxConformanceTest.testCreateSingleValueAlter with data set #82

@eileenmcnaughton
Copy link
Contributor

This looks good - are you able to squash the commits before we merge?

@mflandorfer mflandorfer force-pushed the GP-15884-activity-contact-not-updated branch from fe82d06 to 44679f8 Compare March 24, 2021 09:20
@eileenmcnaughton
Copy link
Contributor

@mflandorfer I just checked in on this again & it is now in conflict :-(

Can you ping me once it's fixed so I hopefully don't miss it again

@mflandorfer
Copy link
Contributor Author

@eileenmcnaughton I just resolved the merge conflict

@eileenmcnaughton
Copy link
Contributor

@mflandorfer jenkins is still not loving it - can you do a git pull --rebase with a force push in the hope it cheers up?

dev/core#2450 - Incorporate requested changes


dev/core#2450 - Make activity target contact parameter an array


dev/core#2450 - Delete now obsolete comment about target contact updates


dev/core#2450 - Compare activity contact IDs on contribution update

to avoid unnecessary updates
dev/core#2450 - Simplify API calls in unit test


dev/core#2450 - Remove limit from activity contact query
@mflandorfer mflandorfer force-pushed the GP-15884-activity-contact-not-updated branch from 5cc1674 to 6b5e660 Compare April 6, 2021 08:53
@mflandorfer
Copy link
Contributor Author

@eileenmcnaughton OK, looks good now

@eileenmcnaughton
Copy link
Contributor

@mflandorfer yay - let's lock it in!

@eileenmcnaughton eileenmcnaughton merged commit e050cce into civicrm:master Apr 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants