diff --git a/CRM/Core/EntityTokens.php b/CRM/Core/EntityTokens.php index c1cb2fcbc414..f995bc365050 100644 --- a/CRM/Core/EntityTokens.php +++ b/CRM/Core/EntityTokens.php @@ -16,6 +16,7 @@ use Civi\Token\TokenRow; use Civi\ActionSchedule\Event\MailingQueryEvent; use Civi\Token\TokenProcessor; +use Brick\Money\Money; /** * Class CRM_Core_EntityTokens @@ -123,8 +124,15 @@ public function evaluateToken(TokenRow $row, $entity, $field, $prefetch = NULL) return $row->customToken($entity, \CRM_Core_BAO_CustomField::getKeyID($field), $this->getFieldValue($row, 'id')); } if ($this->isMoneyField($field)) { + $currency = $this->getCurrency($row); + if (!$currency) { + // too hard basket for now - just do what we always did. + return $row->format('text/plain')->tokens($entity, $field, + \CRM_Utils_Money::format($fieldValue, $currency)); + } return $row->format('text/plain')->tokens($entity, $field, - \CRM_Utils_Money::format($fieldValue, $this->getCurrency($row))); + Money::of($fieldValue, $currency)); + } if ($this->isDateField($field)) { try { diff --git a/Civi/Token/TokenProcessor.php b/Civi/Token/TokenProcessor.php index f2e32add9168..0451b2ae531e 100644 --- a/Civi/Token/TokenProcessor.php +++ b/Civi/Token/TokenProcessor.php @@ -1,6 +1,7 @@ $enqueue, ], $m[3]); if ($unmatched) { - throw new \CRM_Core_Exception("Malformed token parameters (" . $m[0] . ")"); + throw new \CRM_Core_Exception('Malformed token parameters (' . $m[0] . ')'); } } return $callback($m[0] ?? NULL, $m[1] ?? NULL, $m[2] ?? NULL, $filterParts); @@ -458,6 +459,10 @@ private function filterTokenValue($value, ?array $filter, TokenRow $row) { } } + if ($value instanceof Money && $filter === NULL) { + $filter = ['crmMoney']; + } + switch ($filter[0] ?? NULL) { case NULL: return $value; @@ -468,6 +473,11 @@ private function filterTokenValue($value, ?array $filter, TokenRow $row) { case 'lower': return mb_strtolower($value); + case 'crmMoney': + if ($value instanceof Money) { + return \Civi::format()->money($value->getAmount(), $value->getCurrency()); + } + case 'crmDate': if ($value instanceof \DateTime) { // @todo cludgey. diff --git a/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php b/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php index fa2a50b8dbc9..52f74d502f9a 100644 --- a/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php +++ b/tests/phpunit/CRM/Contribute/ActionMapping/ByTypeTest.php @@ -311,10 +311,10 @@ public function testTokenRendering(): void { 'payment instrument id = 4', 'payment instrument name = Check', 'payment instrument label = Check', - 'non_deductible_amount = € 10.00', - 'total_amount = € 100.00', - 'net_amount = € 95.00', - 'fee_amount = € 5.00', + 'non_deductible_amount = €10.00', + 'total_amount = €100.00', + 'net_amount = €95.00', + 'fee_amount = €5.00', 'campaign_id = 1', 'campaign name = big_campaign', 'campaign label = Campaign', @@ -362,10 +362,10 @@ public function testTokenRendering(): void { 'payment instrument label = Check', 'legacy source SSF', 'source SSF', - 'non_deductible_amount = € 10.00', - 'total_amount = € 100.00', - 'net_amount = € 95.00', - 'fee_amount = € 5.00', + 'non_deductible_amount = €10.00', + 'total_amount = €100.00', + 'net_amount = €95.00', + 'fee_amount = €5.00', 'campaign_id = 1', 'campaign name = big_campaign', 'campaign label = Campaign', diff --git a/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php b/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php index 54250b806d73..bfc2573b06d5 100644 --- a/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php +++ b/tests/phpunit/CRM/Contribute/Form/Task/PDFLetterCommonTest.php @@ -198,7 +198,6 @@ public function testPostProcess(): void { $this->createLoggedInUser();; foreach (['docx', 'odt'] as $docType) { $formValues = [ - 'is_unit_test' => TRUE, 'group_by' => NULL, 'document_file' => [ 'name' => __DIR__ . "/sample_documents/Template.$docType", @@ -297,10 +296,10 @@ public function testAllContributionTokens(): void {
id : 1 -total_amount : € 9,999.99 -fee_amount : € 1,111.11 -net_amount : € 7,777.78 -non_deductible_amount : € 2,222.22 +total_amount : €9,999.99 +fee_amount : €1,111.11 +net_amount : €7,777.78 +non_deductible_amount : €2,222.22 receive_date : July 20th, 2018 payment_instrument_id:label : Check trxn_id : 1234 diff --git a/tests/phpunit/CRM/Contribute/Form/UpdateSubscriptionTest.php b/tests/phpunit/CRM/Contribute/Form/UpdateSubscriptionTest.php index d758acedfe47..7cb3d3ee529f 100644 --- a/tests/phpunit/CRM/Contribute/Form/UpdateSubscriptionTest.php +++ b/tests/phpunit/CRM/Contribute/Form/UpdateSubscriptionTest.php @@ -50,7 +50,7 @@ public function getExpectedMailStrings(): array { 'Return-Path: bob@example.org', 'Dear Anthony,', 'Your recurring contribution has been updated as requested:', - 'Recurring contribution is for $ 10.00, every 1 month(s) for 12 installments.', + 'Recurring contribution is for $10.00, every 1 month(s) for 12 installments.', 'If you have questions please contact us at "Bob" .', ]; } diff --git a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php index e5878ab7848e..50176589f047 100644 --- a/tests/phpunit/CRM/Utils/TokenConsistencyTest.php +++ b/tests/phpunit/CRM/Utils/TokenConsistencyTest.php @@ -206,6 +206,28 @@ public function testContributionRecurTokenConsistency(): void { $this->assertEquals($this->getExpectedContributionRecurTokenOutPut(), $tokenProcessor->getRow(0)->render('html')); } + /** + * Test money format tokens can respect passed in locale. + */ + public function testMoneyFormat(): void { + // Our 'migration' off configured thousand separators at the moment is a define. + putenv('IGNORE_SEPARATOR_CONFIG=1'); + $this->createLoggedInUser(); + $tokenProcessor = new TokenProcessor(\Civi::dispatcher(), [ + 'controller' => __CLASS__, + 'smarty' => FALSE, + 'schema' => ['contribution_recurId'], + ]); + $tokenString = '{contribution_recur.amount}'; + $tokenProcessor->addMessage('html', $tokenString, 'text/plain'); + $tokenProcessor->addRow([ + 'contribution_recurId' => $this->getContributionRecurID(), + 'locale' => 'nb_NO', + ]); + $tokenProcessor->evaluate(); + $this->assertEquals('€ 5 990,99', $tokenProcessor->getRow(0)->render('html')); + } + /** * Get tokens that are not advertised via listTokens. * @@ -379,7 +401,7 @@ protected function getContributionRecurID(): int { */ protected function getExpectedContributionRecurTokenOutPut(): string { return 'contribution_recur.id :' . $this->getContributionRecurID() . ' -contribution_recur.amount :€ 5,990.99 +contribution_recur.amount :€5,990.99 contribution_recur.currency :EUR contribution_recur.frequency_unit :year contribution_recur.frequency_interval :2 @@ -533,7 +555,7 @@ protected function getExpectedParticipantTokenOutput(): string { participant.register_date :February 19th, 2007 participant.source :Wimbeldon participant.fee_level :steep -participant.fee_amount :$ 50.00 +participant.fee_amount :$50.00 participant.registered_by_id : participant.transferred_to_contact_id : participant.role_id:label :Attendee