From e4f3e4ce326b0ced340614ea85e20e9e1ec73ef3 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Tue, 3 Aug 2021 09:09:54 +1200 Subject: [PATCH] Switch contribution action schedule tokens to use advertised tokens for cancel_date & source Scheduled reminders was working with the incorrect and not advertised variants - this switches over and upgrades ( a bit precautionary since the removed ones were not in the widget) --- CRM/Contribute/Tokens.php | 60 +++++++++++++++---- CRM/Upgrade/Incremental/php/FiveFortyOne.php | 6 ++ .../Contribute/ActionMapping/ByTypeTest.php | 9 ++- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/CRM/Contribute/Tokens.php b/CRM/Contribute/Tokens.php index 52511402d4..3fe10f3ede 100644 --- a/CRM/Contribute/Tokens.php +++ b/CRM/Contribute/Tokens.php @@ -28,7 +28,7 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { /** * @return string */ - private function getEntityName(): string { + protected function getEntityName(): string { return 'contribution'; } @@ -44,7 +44,7 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { * * @var array */ - protected $entityFieldMetadata = []; + protected $fieldMetadata = []; /** * Get a list of tokens whose name and title match the DB fields. @@ -53,6 +53,8 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { protected function getPassthruTokens(): array { return [ 'contribution_page_id', + 'source', + 'id', 'receive_date', 'total_amount', 'fee_amount', @@ -60,7 +62,7 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { 'trxn_id', 'invoice_id', 'currency', - 'contribution_cancel_date', + 'cancel_date', 'receipt_date', 'thankyou_date', 'tax_amount', @@ -75,11 +77,8 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { */ protected function getAliasTokens(): array { return [ - 'id' => 'contribution_id', 'payment_instrument' => 'payment_instrument_id', - 'source' => 'contribution_source', 'type' => 'financial_type_id', - 'cancel_date' => 'contribution_cancel_date', ]; } @@ -108,9 +107,9 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { public function getPseudoTokens(): array { $return = []; foreach (array_keys($this->getBasicTokens()) as $fieldName) { - if (!empty($this->entityFieldMetadata[$fieldName]['pseudoconstant'])) { - $return[$fieldName . ':label'] = $this->entityFieldMetadata[$fieldName]['html']['label']; - $return[$fieldName . ':name'] = ts('Machine name') . ': ' . $this->entityFieldMetadata[$fieldName]['html']['label']; + if (!empty($this->fieldMetadata[$fieldName]['pseudoconstant'])) { + $return[$fieldName . ':label'] = $this->fieldMetadata[$fieldName]['html']['label']; + $return[$fieldName . ':name'] = ts('Machine name') . ': ' . $this->fieldMetadata[$fieldName]['html']['label']; } } return $return; @@ -120,9 +119,8 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { * Class constructor. */ public function __construct() { - $this->entityFieldMetadata = CRM_Contribute_DAO_Contribution::fields(); $tokens = CRM_Utils_Array::subset( - CRM_Utils_Array::collect('title', $this->entityFieldMetadata), + CRM_Utils_Array::collect('title', $this->getFieldMetadata()), $this->getPassthruTokens() ); $tokens['id'] = ts('Contribution ID'); @@ -155,7 +153,7 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { return; } - $fields = CRM_Contribute_DAO_Contribution::fields(); + $fields = $this->getFieldMetadata(); foreach ($this->getPassthruTokens() as $token) { $e->query->select("e." . $fields[$token]['name'] . " AS contrib_{$token}"); } @@ -193,11 +191,30 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { elseif (in_array($field, array_keys($this->getBasicTokens()))) { $row->tokens($entity, $field, $fieldValue); } + elseif (!array_key_exists($field, CRM_Contribute_BAO_Contribution::fields())) { + if ($this->isDateField($field)) { + $row->format('text/plain')->tokens($entity, $field, \CRM_Utils_Date::customFormat($fieldValue)); + } + else { + $row->format('text/plain')->tokens($entity, $field, $fieldValue); + } + } else { $row->dbToken($entity, $field, 'CRM_Contribute_BAO_Contribution', $field, $fieldValue); } } + /** + * Is the given field a date field. + * + * @param string $fieldName + * + * @return bool + */ + public function isDateField($fieldName): bool { + return $this->getFieldMetadata()[$fieldName]['type'] === (\CRM_Utils_Type::T_DATE + \CRM_Utils_Type::T_TIME); + } + /** * Get the value for the relevant pseudo field. * @@ -220,4 +237,23 @@ class CRM_Contribute_Tokens extends AbstractTokenSubscriber { return (string) $fieldValue; } + /** + * Get the metadata for the available fields. + * + * @return array + */ + protected function getFieldMetadata(): array { + if (empty($this->fieldMetadata)) { + $baoName = $this->getBAOName(); + $fields = (array) $baoName::fields(); + // re-index by real field name. I originally wanted to use apiv4 + // getfields - but it returns different stuff for 'type' and + // does not return 'pseudoconstant' as a key so for now... + foreach ($fields as $details) { + $this->fieldMetadata[$details['name']] = $details; + } + } + return $this->fieldMetadata; + } + } diff --git a/CRM/Upgrade/Incremental/php/FiveFortyOne.php b/CRM/Upgrade/Incremental/php/FiveFortyOne.php index aaa958a127..700735a430 100644 --- a/CRM/Upgrade/Incremental/php/FiveFortyOne.php +++ b/CRM/Upgrade/Incremental/php/FiveFortyOne.php @@ -74,6 +74,12 @@ class CRM_Upgrade_Incremental_php_FiveFortyOne extends CRM_Upgrade_Incremental_B $this->addTask('Replace contribution status token in action schedule', 'updateActionScheduleToken', 'contribution.status', 'contribution.contribution_status_id:label', $rev ); + $this->addTask('Replace contribution cancel_date token in action schedule', + 'updateActionScheduleToken', 'contribution.contribution_cancel_date', 'contribution.cancel_date', $rev + ); + $this->addTask('Replace contribution source token in action schedule', + 'updateActionScheduleToken', 'contribution.contribution_source', 'contribution.source', $rev + ); } /** diff --git a/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php b/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php index 896bc6e490..a512abec1b 100644 --- a/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php +++ b/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php @@ -150,7 +150,7 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr /** * Create a contribution record for Alice with type "Member Dues". */ - public function addAliceDues() { + public function addAliceDues(): void { $this->ids['Contribution']['alice'] = $this->callAPISuccess('Contribution', 'create', [ 'contact_id' => $this->contacts['alice']['id'], 'receive_date' => date('Ymd', strtotime($this->targetDate)), @@ -160,6 +160,8 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr 'fee_amount' => '5', 'net_amount' => '95', 'source' => 'SSF', + // Having a cancel date is a bit artificial here but we can test it.... + 'cancel_date' => '2021-08-09', 'contribution_status_id' => 1, 'soft_credit' => [ '1' => [ @@ -266,7 +268,8 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr new style label = {contribution.contribution_status_id:label} id {contribution.id} contribution_id {contribution.contribution_id} - not valid for action schedule - '; + cancel date {contribution.cancel_date} + source {contribution.source}'; $this->schedule->save(); $this->callAPISuccess('job', 'send_reminder', []); $expected = [ @@ -277,6 +280,8 @@ class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\Abstr 'new style label = Completed Label**', 'id ' . $this->ids['Contribution']['alice'], 'id - not valid for action schedule', + 'cancel date August 9th, 2021 12:00 AM', + 'source SSF', ]; $this->mut->checkMailLog($expected); -- 2.25.1