From b89a5f6fb1367b116868b332c786a14baf8b029d Mon Sep 17 00:00:00 2001 From: Patrick Figel Date: Tue, 17 Aug 2021 11:34:43 +0200 Subject: [PATCH] dev/core#2758 - Fix contribution activity campaign propagation This fixes an issue where contribution campaigns may not be propagated to the corresponding contribution activity when the request that triggers activity creation does not explicitly set the campaign_id parameter. --- CRM/Contribute/BAO/Contribution.php | 6 +-- .../CRM/Contribute/BAO/ContributionTest.php | 51 +++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index d4a199ebadff..6e886dca521a 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -538,8 +538,7 @@ public static function create(&$params) { ['activity_type_id:name', '=', 'Contribution'], ])->execute()->first(); - $campaignParams = isset($params['campaign_id']) ? ['campaign_id' => ($params['campaign_id'] ?? NULL)] : []; - $activityParams = array_merge([ + $activityParams = [ 'activity_type_id:name' => 'Contribution', 'source_record_id' => $contribution->id, 'activity_date_time' => $contribution->receive_date, @@ -547,8 +546,9 @@ public static function create(&$params) { 'status_id:name' => $isCompleted ? 'Completed' : 'Scheduled', 'skipRecentView' => TRUE, 'subject' => CRM_Activity_BAO_Activity::getActivitySubject($contribution), + 'campaign_id' => $contribution->campaign_id, 'id' => $existingActivity['id'] ?? NULL, - ], $campaignParams); + ]; if (!$activityParams['id']) { $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]; diff --git a/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php b/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php index 1eada5848275..9327c0d47da6 100644 --- a/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/BAO/ContributionTest.php @@ -9,6 +9,7 @@ +--------------------------------------------------------------------+ */ use Civi\Api4\Activity; +use Civi\Api4\Contribution; use Civi\Api4\PledgePayment; /** @@ -1801,4 +1802,54 @@ public function testUpdateActivityContactOnContributionContactChange(): void { $this->assertEquals($activityContact['contact_id'], $contactId_2, 'Check target contact ID matches the second contact'); } + /** + * Test status updates triggering activity creation and value propagation + * + * @throws \API_Exception + * @throws \Civi\API\Exception\UnauthorizedException + */ + public function testContributionStatusUpdateActivityPropagation() { + $contactId = $this->individualCreate(); + $campaignId = $this->campaignCreate(); + $contribution = Contribution::create() + ->addValue('contact_id', $contactId) + ->addValue('campaign_id', $campaignId) + ->addValue('financial_type_id:name', 'Donation') + ->addValue('total_amount', 50) + ->addValue('contribution_status_id:name', 'Pending') + ->execute() + ->first(); + $activityWhere = [ + ['source_record_id', '=', $contribution['id']], + ['activity_type_id:name', '=', 'Contribution'], + ]; + $activity = Activity::get()->setWhere($activityWhere)->execute()->first(); + $this->assertNull($activity, 'Should not create contribution activity for pending contribution'); + + Contribution::update() + ->addWhere('id', '=', $contribution['id']) + ->addValue('contribution_status_id:name', 'Completed') + ->execute(); + + $activity = Activity::get()->setWhere($activityWhere)->execute()->first(); + $this->assertEquals($campaignId, $activity['campaign_id'], 'Should have created contribution activity with campaign'); + + $newCampaignId = $this->campaignCreate(); + Contribution::update() + ->addWhere('id', '=', $contribution['id']) + ->addValue('campaign_id', $newCampaignId) + ->execute(); + + $activity = Activity::get()->setWhere($activityWhere)->execute()->first(); + $this->assertEquals($newCampaignId, $activity['campaign_id'], 'Should have updated contribution activity to new campaign'); + + Contribution::update() + ->addWhere('id', '=', $contribution['id']) + ->addValue('campaign_id', NULL) + ->execute(); + + $activity = Activity::get()->setWhere($activityWhere)->execute()->first(); + $this->assertNull($activity['campaign_id'], 'Should have removed campaign from contribution activity'); + } + }