Ensure comma not formatted into amount
authorEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 4 May 2022 07:14:19 +0000 (19:14 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Thu, 5 May 2022 07:03:58 +0000 (19:03 +1200)
Probably the function doesn't add anything as params['amount']
should be correctly formatted - however,
it shouldn't add a comma - per
https://github.com/eileenmcnaughton/nz.co.fuzion.omnipaymultiprocessor/issues/227

CRM/Core/Payment.php
Civi/Core/Format.php
ext/payflowpro/tests/phpunit/CRM/Core/Payment/PayflowProTest.php

index 7658750b995712b1006ca8cf4edadf8dbe2862e4..34d6363005ad1457f393bd67416146fb96241bca 100644 (file)
@@ -1155,20 +1155,20 @@ abstract class CRM_Core_Payment {
   }
 
   /**
-   * Legacy. Better for a method to work on its own PropertyBag,
-   * but also, this function does not do very much.
+   * Get the submitted amount, padded to 2 decimal places, if needed.
    *
    * @param array $params
    *
    * @return string
-   * @throws \CRM_Core_Exception
    */
   protected function getAmount($params = []) {
     if (!CRM_Utils_Rule::numeric($params['amount'])) {
       CRM_Core_Error::deprecatedWarning('Passing Amount value that is not numeric is deprecated please report this in gitlab');
       return CRM_Utils_Money::formatUSLocaleNumericRounded(filter_var($params['amount'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), 2);
     }
-    return CRM_Utils_Money::formatUSLocaleNumericRounded($params['amount'], 2);
+    // Amount is already formatted to a machine-friendly format but may NOT have
+    // decimal places - eg. it could be 1000.1 so this would return 1000.10.
+    return Civi::format()->machineMoney($params['amount']);
   }
 
   /**
index b3076d0e8dc6b6f314c941c47729ec54e4480fc0..2f127ee33210871745b953f12b3b90864f3c6a14 100644 (file)
@@ -93,8 +93,34 @@ class Format {
       return '';
     }
     $formatter = $this->getMoneyFormatter($currency, $locale, NumberFormatter::DECIMAL);
-    $money = Money::of($amount, $currency, NULL, RoundingMode::HALF_UP);
-    return $money->formatWith($formatter);
+    return Money::of($amount, $currency, NULL, RoundingMode::HALF_UP)->formatWith($formatter);
+  }
+
+  /**
+   * Get a number formatted to a machine format with padded decimal places.
+   *
+   * This is intended to be a machine-friendly format that is also suitable
+   * for sending out to other systems that might expect 2 digits after the
+   * decimal point.
+   *
+   * Most currencies format to 2 decimal places so the default of 'USD' will
+   * achieve that.
+   *
+   * For example an input of 1000.1 will return 1000.10.
+   *
+   * This will ensure that
+   *
+   * @param string|float|int $amount
+   * @param string $currency
+   *
+   * @return string
+   *
+   * @noinspection PhpDocMissingThrowsInspection
+   * @noinspection PhpUnhandledExceptionInspection
+   */
+  public function machineMoney($amount, string $currency = 'USD'): string {
+    $formatter = $this->getMoneyFormatter($currency, 'en_US', NumberFormatter::DECIMAL, [NumberFormatter::GROUPING_USED => FALSE]);
+    return Money::of($amount, $currency, NULL, RoundingMode::HALF_UP)->formatWith($formatter);
   }
 
   /**
index 2dae42df5131d9f79536d4a49c1fd8d9563f6405..93445de4b81fa4d64650631255b52c2f48a1a747 100644 (file)
@@ -48,7 +48,7 @@ class CRM_Core_Payment_PayflowProTest extends \PHPUnit\Framework\TestCase implem
   public function testSinglePayment(): void {
     $this->setupMockHandler();
     $params = $this->getBillingParams();
-    $params['amount'] = 20.00;
+    $params['amount'] = 1020.00;
     $params['currency'] = 'AUD';
     $params['description'] = 'Test Contribution';
     $params['invoiceID'] = 'xyz';
@@ -244,7 +244,7 @@ class CRM_Core_Payment_PayflowProTest extends \PHPUnit\Framework\TestCase implem
    */
   public function getExpectedSinglePaymentRequests(): array {
     return [
-      'USER[4]=test&VENDOR[4]=test&PARTNER[6]=PayPal&PWD[8]=test1234&TENDER[1]=C&TRXTYPE[1]=S&ACCT[16]=4111111111111111&CVV2[3]=123&EXPDATE[4]=1022&ACCTTYPE[4]=Visa&AMT[5]=20.00&CURRENCY[3]=AUD&FIRSTNAME[4]=John&LASTNAME[8]=O\'Connor&STREET[16]=8 Hobbitton Road&CITY[9]=The+Shire&STATE[3]=NSW&ZIP[4]=5010&COUNTRY[3]=AUS&EMAIL[24]=unittesteway@civicrm.org&CUSTIP[9]=127.0.0.1&COMMENT1[4]=4200&COMMENT2[4]=live&INVNUM[3]=xyz&ORDERDESC[17]=Test+Contribution&VERBOSITY[6]=MEDIUM&BILLTOCOUNTRY[3]=AUS',
+      'USER[4]=test&VENDOR[4]=test&PARTNER[6]=PayPal&PWD[8]=test1234&TENDER[1]=C&TRXTYPE[1]=S&ACCT[16]=4111111111111111&CVV2[3]=123&EXPDATE[4]=1022&ACCTTYPE[4]=Visa&AMT[7]=1020.00&CURRENCY[3]=AUD&FIRSTNAME[4]=John&LASTNAME[8]=O\'Connor&STREET[16]=8 Hobbitton Road&CITY[9]=The+Shire&STATE[3]=NSW&ZIP[4]=5010&COUNTRY[3]=AUS&EMAIL[24]=unittesteway@civicrm.org&CUSTIP[9]=127.0.0.1&COMMENT1[4]=4200&COMMENT2[4]=live&INVNUM[3]=xyz&ORDERDESC[17]=Test+Contribution&VERBOSITY[6]=MEDIUM&BILLTOCOUNTRY[3]=AUS',
     ];
   }