+--------------------------------------------------------------------+
*/
+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.
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.
*
+--------------------------------------------------------------------+
*/
+use Civi\Api4\Contribution;
use Civi\Api4\ContributionRecur;
+use Civi\Api4\LineItem;
/**
* Class CRM_Contribute_BAO_ContributionRecurTest
// 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)
$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,
'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();
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']);
}
/**