Fix bug whereby editing contribution_recur.amount was not updating single-row line...
authorEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 16 Jun 2022 00:25:15 +0000 (12:25 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 17 Jun 2022 10:27:32 +0000 (22:27 +1200)
Update CRM/Contribute/BAO/ContributionRecur.php

yep - I got away with this in the test / my step through cos they were both one - Thanks

Co-authored-by: Rich Lott <artfulrobot@users.noreply.github.com>
Update tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php

Co-authored-by: Rich Lott <artfulrobot@users.noreply.github.com>
Update tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php

Co-authored-by: Rich Lott <artfulrobot@users.noreply.github.com>
Update tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php

Co-authored-by: Rich Lott <artfulrobot@users.noreply.github.com>
Update CRM/Contribute/BAO/ContributionRecur.php

Co-authored-by: Matthew Wire <devel@mrwire.co.uk>
CRM/Contribute/BAO/ContributionRecur.php
tests/phpunit/CRM/Contribute/BAO/ContributionRecurTest.php

index 5928599940e9db7b9a19533446ca13e2a37fcd55..5b24f6196490bd662fa2901178ba1d76d363038f 100644 (file)
@@ -9,15 +9,17 @@
  +--------------------------------------------------------------------+
  */
 
+use Brick\Money\Money;
 use Civi\Api4\Contribution;
 use Civi\Api4\ContributionRecur;
+use Civi\Api4\LineItem;
 
 /**
  *
  * @package CRM
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
-class CRM_Contribute_BAO_ContributionRecur extends CRM_Contribute_DAO_ContributionRecur {
+class CRM_Contribute_BAO_ContributionRecur extends CRM_Contribute_DAO_ContributionRecur implements Civi\Test\HookInterface {
 
   /**
    * Create recurring contribution.
@@ -94,6 +96,40 @@ class CRM_Contribute_BAO_ContributionRecur extends CRM_Contribute_DAO_Contributi
     return $recurring;
   }
 
+  /**
+   * Event fired after modifying a recurring contribution.
+   * @param \Civi\Core\Event\PostEvent $event
+   */
+  public static function self_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) {
+    if ($event->action === 'edit') {
+      if (is_numeric($event->object->amount)) {
+        $templateContribution = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($event->object->id);
+        if (empty($templateContribution['id'])) {
+          return;
+        }
+        $lines = LineItem::get(FALSE)
+          ->addWhere('contribution_id', '=', $templateContribution['id'])
+          ->addWhere('contribution_id.is_template', '=', TRUE)
+          ->addSelect('contribution_id.total_amount')
+          ->execute();
+        if (count($lines) === 1) {
+          $contributionAmount = $lines->first()['contribution_id.total_amount'];
+          // USD here is just ensuring both are in the same format.
+          if (Money::of($contributionAmount, 'USD')->compareTo(Money::of($event->object->amount, 'USD'))) {
+            // If different then we need to update
+            // the contribution. Note that if this is being called
+            // as a result of the contribution having been updated then there will
+            // be no difference.
+            Contribution::update(FALSE)
+              ->addWhere('id', '=', $templateContribution['id'])
+              ->setValues(['total_amount' => $event->object->amount])
+              ->execute();
+          }
+        }
+      }
+    }
+  }
+
   /**
    * Check if there is a recurring contribution with the same trxn_id or invoice_id.
    *
index fe83485bcfbd4e8eafccead009a4000fe1ea047f..6ad62e3ad6443aeeff268aaebfe156f694fc2072 100644 (file)
@@ -9,7 +9,9 @@
  +--------------------------------------------------------------------+
  */
 
+use Civi\Api4\Contribution;
 use Civi\Api4\ContributionRecur;
+use Civi\Api4\LineItem;
 
 /**
  * Class CRM_Contribute_BAO_ContributionRecurTest
@@ -284,7 +286,7 @@ class CRM_Contribute_BAO_ContributionRecurTest extends CiviUnitTestCase {
     // Make sure a template contribution exists.
     $templateContributionId = CRM_Contribute_BAO_ContributionRecur::ensureTemplateContributionExists($contributionRecur['id']);
     $fetchedTemplate = CRM_Contribute_BAO_ContributionRecur::getTemplateContribution($contributionRecur['id']);
-    $templateContribution = \Civi\Api4\Contribution::get(FALSE)
+    $templateContribution = Contribution::get(FALSE)
       ->addSelect('*', 'custom.*')
       ->addWhere('contribution_recur_id', '=', $contributionRecur['id'])
       ->addWhere('is_template', '=', 1)
@@ -378,7 +380,7 @@ class CRM_Contribute_BAO_ContributionRecurTest extends CiviUnitTestCase {
     $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', $this->_params);
     $contributionRecur = reset($contributionRecur['values']);
     // Create the template
-    $templateContrib = $this->callAPISuccess('Contribution', 'create', [
+    $templateContribution = $this->callAPISuccess('Contribution', 'create', [
       'contribution_recur_id' => $contributionRecur['id'],
       'total_amount' => '3.00',
       'financial_type_id' => 1,
@@ -390,13 +392,14 @@ class CRM_Contribute_BAO_ContributionRecurTest extends CiviUnitTestCase {
       'receive_date' => 'yesterday',
       'is_template' => 1,
     ]);
+    // Now update the template amount so we can test that this route updates the recur.
     $this->callAPISuccess('Contribution', 'create', [
-      'id' => $templateContrib['id'],
+      'id' => $templateContribution['id'],
       'contribution_recur_id' => $contributionRecur['id'],
       'total_amount' => '2.00',
       'currency' => 'USD',
     ]);
-    $updatedContributionRecur = \Civi\Api4\ContributionRecur::get(FALSE)
+    $updatedContributionRecur = ContributionRecur::get()
       ->addWhere('id', '=', $contributionRecur['id'])
       ->execute()
       ->first();
@@ -406,6 +409,20 @@ class CRM_Contribute_BAO_ContributionRecurTest extends CiviUnitTestCase {
       strtotime($contributionRecur['modified_date']),
       strtotime($updatedContributionRecur['modified_date'])
     );
+    // Now check the reverse - update the recur & the template should update as there
+    // is a single line item.
+    ContributionRecur::update()
+      ->addWhere('id', '=', $contributionRecur['id'])
+      ->setValues(['amount' => 6])
+      ->execute();
+
+    $this->assertEquals(6, Contribution::get()
+      ->addWhere('id', '=', $templateContribution['id'])
+      ->addSelect('total_amount')->execute()->first()['total_amount']);
+    $this->assertEquals(6, LineItem::get()
+      ->addWhere('contribution_id', '=', $templateContribution['id'])
+      ->addGroupBy('contribution_id')
+      ->addSelect('SUM(line_total) AS total_amount')->execute()->first()['total_amount']);
   }
 
   /**