dev/core#2758 - Fix contribution activity campaign propagation
authorPatrick Figel <pfigel@greenpeace.org>
Tue, 17 Aug 2021 09:34:43 +0000 (11:34 +0200)
committerPatrick Figel <pfigel@greenpeace.org>
Tue, 17 Aug 2021 09:34:43 +0000 (11:34 +0200)
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
tests/phpunit/CRM/Contribute/BAO/ContributionTest.php

index d4a199ebadff1452bb5f5200eb12be1cd2e46122..6e886dca521a8fd21fed85d3f680094af1177330 100644 (file)
@@ -538,8 +538,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
         ['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 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
         '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];
index 1eada5848275eb3615c9b14da201ed883ebf4768..9327c0d47da691304f77f3e2c6411aa96816a836 100644 (file)
@@ -9,6 +9,7 @@
  +--------------------------------------------------------------------+
  */
 use Civi\Api4\Activity;
+use Civi\Api4\Contribution;
 use Civi\Api4\PledgePayment;
 
 /**
@@ -1801,4 +1802,54 @@ WHERE eft.entity_id = %1 AND ft.to_financial_account_id <> %2";
     $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');
+  }
+
 }