Development issueshttps://lab.civicrm.org/groups/dev/-/issues2020-02-06T06:53:06Zhttps://lab.civicrm.org/dev/core/-/issues/1364CRM-21858 'Merge All Contacts with the Same Address' doesn't consider Househo...2020-02-06T06:53:06ZMonish DebCRM-21858 'Merge All Contacts with the Same Address' doesn't consider Household replace individuals that share same address.
Steps to replicate:
1. 5 contacts A,B,C, D, E where A, B and C individuals share same address.
2. D is a household but shares same address as of ABC.
3. E is a household which has a different address but Household head of A and B
4. On...
Steps to replicate:
1. 5 contacts A,B,C, D, E where A, B and C individuals share same address.
2. D is a household but shares same address as of ABC.
3. E is a household which has a different address but Household head of A and B
4. On exporting these 5 contacts and choosing merge same address:
Expected : 2 records i.e. D and E. Because D has a same address as of A,B and C so it would replace these 3. E is a household though but has different address so it should not be merged
Actual: 3 records i.e. combined record of (A,B,C) , D and E (Incorrect)
Ported from - https://issues.civicrm.org/jira/browse/CRM-21858Monish DebMonish Debhttps://lab.civicrm.org/dev/core/-/issues/1565Failing to copy file when creating new attachment with APIv32020-02-10T03:07:09ZalbionbrownFailing to copy file when creating new attachment with APIv3In this block of code in civicrm/api/v3/Attachment.php:
```
$path = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $fileDao->uri;
if (is_string($content)) {
file_put_contents($path, $content);
}
elseif (is_string($moveF...In this block of code in civicrm/api/v3/Attachment.php:
```
$path = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $fileDao->uri;
if (is_string($content)) {
file_put_contents($path, $content);
}
elseif (is_string($moveFile)) {
// CRM-17432 Do not use rename() since it will break file permissions.
// Also avoid move_uplaoded_file() because the API can use options.move-file.
copy($moveFile, $path);
unlink($moveFile);
}
```
Is there a reason why we can't check if the copy failed and throw an API_Exception if it did?
The reason being, is that I've had some issues with the new Catalina MacOS update and the NFS mounting option lately. I couldn't figure out why my file upload wasn't working. Ultimately it came down to directory permissions as a result of the Catalina update.
Is it possible we could change this to:
```
$path = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $fileDao->uri;
if (is_string($content)) {
file_put_contents($path, $content);
}
elseif (is_string($moveFile)) {
// CRM-17432 Do not use rename() since it will break file permissions.
// Also avoid move_uploaded_file() because the API can use options.move-file.
if (!copy($moveFile, $path)) {
throw new API_Exception("Cannot copy uploaded file ".$moveFile." to ".$path);
}
unlink($moveFile);
}
```
So we know when the move has failed?5.24.0https://lab.civicrm.org/dev/core/-/issues/1577Custom Group Types not filterable2020-02-10T04:27:09ZMonish DebCustom Group Types not filterableOn Manage groups, you can filter the group list by group type (e.g. Mailing List, Access Control). If you add an additional group type (add value to the respective option group). that works fine when managing groups (i.e. you can save th...On Manage groups, you can filter the group list by group type (e.g. Mailing List, Access Control). If you add an additional group type (add value to the respective option group). that works fine when managing groups (i.e. you can save the record with the custom group), but although the option is displayed in manage groups, the filter does not work. there must be some hardcoding for that filter field.
Issue:
![after](/uploads/09f8d3fbc1f672f23a297c1c9d5b999b/after.gif)
Custom group type filter doesn't work
Proposed fix:
Currently, the custom group type is available to choose as filter in 'Manage Group' but doesn't filter the list of groups. Fix the code to allow filtering of groups on basis of custom group type.5.24.0Monish DebMonish Debhttps://lab.civicrm.org/dev/core/-/issues/77CiviCRM 5.0 angular pages conflict with mootools.js in Joomla 2.52020-02-10T15:44:32Zjoels341CiviCRM 5.0 angular pages conflict with mootools.js in Joomla 2.5Hello CiviCRM team,
I noticed that even though CiviCRM 5.0 claims to be compatible with Joomla 2.5 (we have some sites that we can't upgrade), some of the angular pages such as the "status" page and "new mailing" page show up blank.
If...Hello CiviCRM team,
I noticed that even though CiviCRM 5.0 claims to be compatible with Joomla 2.5 (we have some sites that we can't upgrade), some of the angular pages such as the "status" page and "new mailing" page show up blank.
If I yank mootools.js out of Joomla 2.5, then all these pages work.
Could someone with more experience please fix the compatibility issues?
Best,
Joelhttps://lab.civicrm.org/dev/core/-/issues/1046Proposal to fix longstanding name vs label problems for case roles2020-02-10T15:53:18ZDaveDProposal to fix longstanding name vs label problems for case roles## Overview
At some point in time the xml case type definition started to use the label for the case role instead of the name. Currently you can't change the relationship type label in the UI without causing problems or in some cases a f...## Overview
At some point in time the xml case type definition started to use the label for the case role instead of the name. Currently you can't change the relationship type label in the UI without causing problems or in some cases a fatal error.
See
https://lab.civicrm.org/dev/core/issues/774
https://lab.civicrm.org/dev/core/issues/856
The first link also includes links to related instances over time.
## Proposal
Add a tag to the xml (e.g. `<name_for_real_this_time>` or `<lookupKey>` or `<optionValueName>` etc). When parsing the xml use this tag first, otherwise fall back to using `<name>` and compare it against label (same as current). This way it won't affect existing installs. For installs using database storage for case type definitions the upgrade script can add this tag to the xml. For sites using files people can add it as needed (possibly the upgrade script can suggest).
Ping @colemanw @eileen @jitendra @andrewhunt @totten
Also pinging @bgm since this issue causes language problems too.5.20.0https://lab.civicrm.org/dev/core/-/issues/262Drupal 8 cv & civix cli tools not working2020-02-10T15:54:48ZwannesderoyDrupal 8 cv & civix cli tools not workingIn our Drupal 8 - CiviCRM setup we found that both cv & civix were not working properly due to issues with the autoloading.
We fixed it by simplifying the $autoloader code in the loadBootStrap() method in CRM/Utils/System/Drupal8.php.
...In our Drupal 8 - CiviCRM setup we found that both cv & civix were not working properly due to issues with the autoloading.
We fixed it by simplifying the $autoloader code in the loadBootStrap() method in CRM/Utils/System/Drupal8.php.
The $autoloader var already contains the result of the getLoader() method by requiring the autoload from Drupal.
See my pull request on civicrm-core: https://github.com/civicrm/civicrm-core/pull/12496https://lab.civicrm.org/dev/core/-/issues/46Installer on new site doesn't take port number if different from 33062020-02-10T17:02:08Zbirgit.pauliInstaller on new site doesn't take port number if different from 3306I tried to set-up a CiviCRM install on top of WordPress and the hosting company (Pressable) doesn't use port 3306 for the database. Their port number is 3331. The install script still tried to access via 3306 port although we entered th...I tried to set-up a CiviCRM install on top of WordPress and the hosting company (Pressable) doesn't use port 3306 for the database. Their port number is 3331. The install script still tried to access via 3306 port although we entered the full ip:port string in the field. ![Screen_Shot_2018-04-04_at_7.16.42_PM](/uploads/1723045a9d3aaf24cde53cc46cc0f5c5/Screen_Shot_2018-04-04_at_7.16.42_PM.png)
CiviCRM 4.7.13
WordPress 4.9.5
See also discussion w/ @kcristiano on chat: https://chat.civicrm.org/civicrm/pl/734b4rooet8c7g6e6stpu16djrhttps://lab.civicrm.org/dev/financial/-/issues/117Payment edit link cannot be modified2020-02-11T20:07:09Zadrian@roomify.usPayment edit link cannot be modifiedOn the 'View Contribution' page, the payment details edit link is not currently modifiable via hook_civicrm_links. Related issue: https://issues.civicrm.org/jira/browse/CRM-13434
I'll be submitting a PR.On the 'View Contribution' page, the payment details edit link is not currently modifiable via hook_civicrm_links. Related issue: https://issues.civicrm.org/jira/browse/CRM-13434
I'll be submitting a PR.5.24.0https://lab.civicrm.org/dev/core/-/issues/1587Show full description under select2 options2020-02-12T02:11:04ZMonish DebShow full description under select2 optionsOverview
----------------------------------------
Show full description under select2 options
Current behavior
----------------------------------------
Visit the export field option or Event name select2 filter in 'Find Participant' se...Overview
----------------------------------------
Show full description under select2 options
Current behavior
----------------------------------------
Visit the export field option or Event name select2 filter in 'Find Participant' search form. It trims the description with a teaser.
![Screen_Shot_2020-02-11_at_8.29.30_PM](/uploads/ec0400cff8072e1a25f31aeeda449b5f/Screen_Shot_2020-02-11_at_8.29.30_PM.png)
![Screen_Shot_2020-02-11_at_8.30.03_PM](/uploads/3237148bddd75af1a1fc497a9139990a/Screen_Shot_2020-02-11_at_8.30.03_PM.png)
Proposed behavior
----------------------------------------
Show the full description of select2 options. Make the change option by introducing a special attribute and handle accordingly in js and css to support that. For further details check next section.
Technical details
----------------------------------------
Introduce a special boolean setting attribute to select2 option array (in PHP) say ```fullDescription``` = TRUE/FALSE. Based on these setting it will add a CSS class say ```crm-select2-row-full-description``` via js and then make style changes to show full description.5.24.0Monish DebMonish Debhttps://lab.civicrm.org/dev/core/-/issues/1517Permission error on event info page for anonymous users2020-02-14T12:03:41ZjitendraPermission error on event info page for anonymous usersGiving anonymous "access CiviEvent" in addition to "view event info" cause them to get "API permission check failed for Event/get call; insufficient permission: require access CiviCRM".
To replicate -
- Grant `access CiviEvent`, `view ...Giving anonymous "access CiviEvent" in addition to "view event info" cause them to get "API permission check failed for Event/get call; insufficient permission: require access CiviCRM".
To replicate -
- Grant `access CiviEvent`, `view event info`, `register for events` to anonymous.
- Navigate to the info page of any event.
![image](/uploads/3a7114e07ec47065b83a00e1a8488cb2/image.png)
- The registration page works fine.
Related SE - https://civicrm.stackexchange.com/questions/19038/api-permission-check-failed-civievents-fails-after-update-to-4-7-19-and-4-7-20/25326#253265.24.0https://lab.civicrm.org/dev/financial/-/issues/116Cancelling a payment thru the API2020-02-14T19:24:31ZalicefruminCancelling a payment thru the APIWhen a user updates a Contribution with the status "Completed" to have the status "Cancelled" thru the UI (or the API using Contribution.create and an id) a negative payment is created with a status of "Cancelled" like in the screen shot...When a user updates a Contribution with the status "Completed" to have the status "Cancelled" thru the UI (or the API using Contribution.create and an id) a negative payment is created with a status of "Cancelled" like in the screen shot below:
![cancelled](/uploads/04c0dcd8c7798a42184e2f0a902b1697/cancelled.png)
This works fine if you are cancelling a full contribution however there is now way in the UI or the API to cancel one of multiple payments.
For Example:
+ a user has a $10 contribution with two payments one for $2 and one for $8
+ The user wants to cancel the $2 contribution
If you cancel the contribution it will record a negative payment of $10.
IF you do `Payment.cancel` it will record a negative payment of $2 with a status "Refunded"
Using `FinancialTrxn.create` you can create a payment of -$2 with a status of "Cancelled" but it will not update the contribution status AND when you update the contribution status to "Cancelled" a new negative payment (of -$10) will be created with a status of cancelled.
PROPOSED SOLUTIONS:
+ Update the `Contribution.create` api so that there is a flag to not create new payments.
+ Allow 'status_id' to be passed to the Payment API and update the contribution and payment statuses based on the status_id if providedhttps://lab.civicrm.org/dev/core/-/issues/1589"DB Error: unknown error" when merging if duplicate contact has null created_...2020-02-14T20:27:09ZIan Wilson"DB Error: unknown error" when merging if duplicate contact has null created_dateThis is partly a data quality issue on our end, but when merging two contacts a DB error is thrown if the one on the left has a null created date (the default value for the column) and the one on the right doesn't.
I am able to reproduc...This is partly a data quality issue on our end, but when merging two contacts a DB error is thrown if the one on the left has a null created date (the default value for the column) and the one on the right doesn't.
I am able to reproduce this with latest CiviCRM on https://dmaster.demo.civicrm.org
**Steps to reproduce on dmaster.demo.civicrm.org:**
start the merge:
* get a listing of contacts
* go to find contacts - https://dmaster.demo.civicrm.org/civicrm/contact/search?reset=1
* click search
* check box next to two individual contacts (not organizations)
* select "merge contacts" from actions menu
* get the contact id for the contact on the left (hover over the name and remember the value of cid in the url that pops up)
use the api to set created_date to null for the duplicate contact:
* open a new tab and go to - https://dmaster.demo.civicrm.org/civicrm/api3
* entity: contact
* action: create
* parameter: contact id = {{ duplicate contact id }}
* parameter: created date = "" (two double quotes)
* execute
perform the merge:
* go back to the tab with the merge page and refresh it - "created" should now be empty on the duplicate
* click merge
**Information from logs:**
```sql
UPDATE civicrm_contact SET created_date = '' WHERE id = 123 [nativecode=1292 ** Incorrect datetime value: '' for column `dev_civicrm`.`civicrm_contact`.`created_date` at row 1]
```5.24.0https://lab.civicrm.org/dev/core/-/issues/1594Extension unit tests broken in master2020-02-14T23:48:22ZseamusleeExtension unit tests broken in masterOverview
----------------------------------------
Currently unable to run any extension unit tests in master branch
Reproduction steps
----------------------------------------
1. Download Flexmailer extension.
1. try to run unit tests u...Overview
----------------------------------------
Currently unable to run any extension unit tests in master branch
Reproduction steps
----------------------------------------
1. Download Flexmailer extension.
1. try to run unit tests using phpunit6.
1. Tests don't run.
Current behaviour
----------------------------------------
A bunch of notices show up as well
```
PHP Warning: file_get_contents(./xml/version.xml): failed to open stream: No such file or directory in...civicrm/CRM/Core/CodeGen/Util/Xml.php on line 16
PHP Warning: DOMDocument::loadXML(): Empty string supplied as input in...civicrm/CRM/Core/CodeGen/Util/Xml.php on line 17
PHP Warning: simplexml_import_dom(): Invalid Nodetype to import in...civicrm/CRM/Core/CodeGen/Util/Xml.php on line 20
PHP Notice: Trying to get property 'version_no' of non-object in...civicrm/CRM/Core/CodeGen/Main.php on line 79
Parsing schema description ./xml/schema/Schema.xml
PHP Warning: file_get_contents(./xml/schema/Schema.xml): failed to open stream: No such file or directory in...civicrm/CRM/Core/CodeGen/Util/Xml.php on line 16
PHP Warning: DOMDocument::loadXML(): Empty string supplied as input in...civicrm/CRM/Core/CodeGen/Util/Xml.php on line 17
PHP Warning: simplexml_import_dom(): Invalid Nodetype to import in...civicrm/CRM/Core/CodeGen/Util/Xml.php on line 20
Extracting database information
PHP Notice: Trying to get property 'name' of non-object in...civicrm/CRM/Core/CodeGen/Specification.php on line 70
Extracting table information
PHP Notice: Trying to get property 'tables' of non-object in...civicrm/CRM/Core/CodeGen/Specification.php on line 96
PHP Warning: Invalid argument supplied for foreach() in...civicrm/CRM/Core/CodeGen/Specification.php on line 96
```
Expected behaviour
----------------------------------------
PHP Unit tests run
Environment information
----------------------------------------
<!-- Some of the items below may not be relevant for every bug - if in doubt please include more information than you think is neccessary. -->
* __CiviCRM:__ _Master_
* __PHP:__ _7.1_
* __CMS:__ _Drupal 7.69
Comments
----------------------------------------
ping @totten @eileen5.24.0seamusleeseamusleehttps://lab.civicrm.org/dev/core/-/issues/1176Uncaught exception on missing extension2020-02-15T02:38:03ZJonGoldUncaught exception on missing extensionSteps to replicate:
* Install an extension.
* Delete the extension without uninstalling it.
* Visit the System Status screen.
The status screen doesn't appear, because you get an uncaught exception message, something like:
```
Uncaught ...Steps to replicate:
* Install an extension.
* Delete the extension without uninstalling it.
* Visit the System Status screen.
The status screen doesn't appear, because you get an uncaught exception message, something like:
```
Uncaught PHP Exception CRM_Extension_Exception_MissingException: "Unknown extension:
nz.co.fuzion.notificationlog" at /var/www/mysite.org/htdocs/vendor/civicrm/civicrm-core/CRM/Extension/Container/Collection.php line 166
```
Anecdotally, this may also cause issues like menus not loading (though I believe there's a second issue that must also be present). Regardless, catching this exception fixes a bug.
This is technically a very old regression since this wasn't the old behavior, but it's been happening long enough that there's no reason to put this in the RC.5.24.0JonGoldJonGoldhttps://lab.civicrm.org/dev/core/-/issues/1592Advanced Search: "active period" filter regression2020-02-15T21:47:10ZbgmAdvanced Search: "active period" filter regressionTo reproduce:
* Go to: https://dmaster.demo.civicrm.org/civicrm/contact/search/advanced?reset=1
* Under "Relationships", select "Relationship Status" = Active.
* Click search, notice you get 85 results.
Now under the relationships,
* ...To reproduce:
* Go to: https://dmaster.demo.civicrm.org/civicrm/contact/search/advanced?reset=1
* Under "Relationships", select "Relationship Status" = Active.
* Click search, notice you get 85 results.
Now under the relationships,
* Select "Relationship Status" = "All"
* then "Active Period" = "Today"
This should give the same number of results, but it returns zero results.
I traced it to a regression caused by 6245de60a716da2d16f124233789d57c48e49a45
https://github.com/civicrm/civicrm-core/pull/16287
I'm not sure how to fix this except from checking: `$fieldSpec['name'] == 'relation_active_period_date'` to reverse the date conditions.5.23.1https://lab.civicrm.org/dev/core/-/issues/1593E_WARNING on New/Edit Tag screen2020-02-16T04:00:24ZDaveDE_WARNING on New/Edit Tag screen`Warning: count(): Parameter must be an array or an object that implements Countable in include() (line 71 of blah\...\templates_c\en_US\%%4D\4D9\4D941223%%Edit.tpl.php`
I think this is new in master or 5.23 and at first glance it's bec...`Warning: count(): Parameter must be an array or an object that implements Countable in include() (line 71 of blah\...\templates_c\en_US\%%4D\4D9\4D941223%%Edit.tpl.php`
I think this is new in master or 5.23 and at first glance it's because $parent_tags is null when the template tries to do `{if $parent_tags|@count > 0}`
(Linking to 5.22.0 since then the ref won't change but I'm not sure yet if this affects 5.22.)
https://github.com/civicrm/civicrm-core/blob/5.22.0/templates/CRM/Tag/Form/Edit.tpl#L60
I might first look into why this changed to see if it's something deeper but the obvious quick fix is to check the variable exists first before applying count. Also this is a good candidate for a test as described at https://lab.civicrm.org/dev/core/issues/1536.5.24.0https://lab.civicrm.org/dev/core/-/issues/1588Positive integer expected for recurring interval even when user is not making...2020-02-16T20:02:17Zfreeform.stephPositive integer expected for recurring interval even when user is not making a recurring contributionOverview
----------------------------------------
If you enabled the recurring option "Support recurring intervals" on a contribution page you can no longer submit the contribution form unless you enter a value for the recurring interval...Overview
----------------------------------------
If you enabled the recurring option "Support recurring intervals" on a contribution page you can no longer submit the contribution form unless you enter a value for the recurring interval, even if you have not selected to make a recurring contribution.
Error: recurFrequencyInterval must be a positive integer
This appears to have been introduced with release 5.21.x. This is most likely a result of the work that was released in 5.21.0 with respect to the new class Civi\Payment\PropertyBag.
Reproduction steps (on demo)
----------------------------------------
1. duplicate the existing donation form
1. disable the pledge section
1. enable recurring contributions section, select "Support recurring intervals" + "Offer installments"
1. test the form, leaving the recurring options blank (ie attempt to make a single one-time donation)
Current behaviour
----------------------------------------
Returns:
```
Sorry, due to an error, we are unable to fulfill your request at the moment. You may want to contact your administrator or service provider with more details about what action you were performing when this occurred. recurFrequencyInterval must be a positive integer"
```
Expected behaviour
----------------------------------------
Should be able to submit a one-time donation without expectation of a recurring interval
Environment information
----------------------------------------
Running 5.21.1 on WordPress 5.3.2.
This is reproducible on https://dmaster.demo.civicrm.org/ (CiviCRM 5.23.alpha1) so is independent of CMS.
Comments
----------------------------------------
First reported on StackExchange: https://civicrm.stackexchange.com/questions/34436/positive-integer-expected-for-recurring-interval-even-when-user-is-not-making-a5.23.0https://lab.civicrm.org/dev/core/-/issues/1551Advanced search links on mailing reports page give "DB Error: syntax error"2020-02-16T20:02:37ZIan WilsonAdvanced search links on mailing reports page give "DB Error: syntax error"After a mailing has been sent, all of the "Advanced Search" links on the mailing report page give a "DB Error: syntax error" page.
Steps to reproduce:
1. create a new mailing
1. wait for cron or execute the mailings scheduler job from /...After a mailing has been sent, all of the "Advanced Search" links on the mailing report page give a "DB Error: syntax error" page.
Steps to reproduce:
1. create a new mailing
1. wait for cron or execute the mailings scheduler job from /civicrm/admin/job
1. go to /civicrm/mailing/browse/scheduled?reset=1&scheduled=true and click on the report link for the completed mailing
1. click any of the "Advanced Search" links on the right side of the rows
Logs from ConfigAndLog show:
```sql
SELECT DISTINCT LEFT(contact_a.sort_name, 1) as sort_name
FROM civicrm_contact contact_a
LEFT JOIN civicrm_mailing_recipients ON civicrm_mailing_recipients.contact_id = contact_a.id
LEFT JOIN civicrm_mailing ON civicrm_mailing.id = civicrm_mailing_recipients.mailing_id
WHERE ( AND civicrm_mailing.id IN (15403) ) AND (contact_a.is_deleted = 0)
GROUP BY sort_name
ORDER BY sort_name asc
[nativecode=1064 ** You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near
'AND civicrm_mailing.id IN (15403) ) AND (contact_a.is_deleted = 0)
```
The error occurs in 5.21.2 (we are testing this in preparation for the next ESR release) and I am also able to reproduce the problem on https://dmaster.demo.civicrm.org. The error doesn't occur in 5.13.8.5.23.0https://lab.civicrm.org/dev/core/-/issues/1583API v4 returning incorrect count of contributions under certain WHERE conditions2020-02-17T02:21:40ZjamieAPI v4 returning incorrect count of contributions under certain WHERE conditionsThe database has three contributions with the `contribution_recur_id` set to 19.
When I query for these via apiv4 using just the `contribution_recur_id`, I get three results from the database (and the `first()` function works properly)....The database has three contributions with the `contribution_recur_id` set to 19.
When I query for these via apiv4 using just the `contribution_recur_id`, I get three results from the database (and the `first()` function works properly).
When I query and limit to those with `is_template` set to 1 (there should be no matching results), I get a count of 1, but NULL when I call `first()`.
Here's the data:
```
MariaDB [ptp]> SELECT * FROM civicrm_contribution WHERE contribution_recur_id =19;
+------+------------+-------------------+----------------------+-----------------------+---------------------+-----------------------+--------------+------------+------------+-----------------------------+----------------------------------+----------+-------------+---------------+---------------------+---------------+---------------------------------------------------------------------------------+--------------+-----------------------+---------+--------------+------------------------+------------+--------------+-------------+------------+---------------+--------------------------+----------------+-------------+
| id | contact_id | financial_type_id | contribution_page_id | payment_instrument_id | receive_date | non_deductible_amount | total_amount | fee_amount | net_amount | trxn_id | invoice_id | currency | cancel_date | cancel_reason | receipt_date | thankyou_date | source | amount_level | contribution_recur_id | is_test | is_pay_later | contribution_status_id | address_id | check_number | campaign_id | tax_amount | creditnote_id | revenue_recognition_date | invoice_number | is_template |
+------+------------+-------------------+----------------------+-----------------------+---------------------+-----------------------+--------------+------------+------------+-----------------------------+----------------------------------+----------+-------------+---------------+---------------------+---------------+---------------------------------------------------------------------------------+--------------+-----------------------+---------+--------------+------------------------+------------+--------------+-------------+------------+---------------+--------------------------+----------------+-------------+
| 3928 | 10459 | 2 | 14 | 1 | 2019-12-02 13:07:59 | 0.00 | 296.00 | 8.88 | 287.12 | in_1FlKFWAwDzuDdbFCuWUlA4EZ | 0f3dd1eda0400becb9ecd33c58d28ae8 | USD | NULL | 0 | 2019-12-02 13:07:56 | NULL | Online Contribution: PowerBase Subscription Payment with Monthly Payment Option | NULL | 19 | 0 | 0 | 1 | 24745 | NULL | NULL | NULL | NULL | NULL | NULL | 0 |
| 3951 | 10459 | 2 | 14 | 1 | 2020-01-02 13:08:03 | 0.00 | 296.00 | 8.88 | 287.12 | in_1FwZ1bAwDzuDdbFCXoBfw8UM | NULL | USD | NULL | NULL | 2020-01-02 14:13:42 | NULL | Online Contribution: PowerBase Subscription Payment with Monthly Payment Option | NULL | 19 | 0 | 0 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 |
| 3999 | 10459 | 2 | 14 | 1 | 2020-02-02 13:08:03 | 0.00 | 296.00 | 8.88 | 287.12 | in_1G7nnbAwDzuDdbFCvncHVNPH | NULL | USD | NULL | NULL | 2020-02-07 15:03:30 | NULL | Online Contribution: PowerBase Subscription Payment with Monthly Payment Option | NULL | 19 | 0 | 0 | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 |
+------+------------+-------------------+----------------------+-----------------------+---------------------+-----------------------+--------------+------------+------------+-----------------------------+----------------------------------+----------+-------------+---------------+---------------------+---------------+---------------------------------------------------------------------------------+--------------+-----------------------+---------+--------------+------------------------+------------+--------------+-------------+------------+---------------+--------------------------+----------------+-------------+
3 rows in set (0.001 sec)
MariaDB [ptp]>
```
Here is the test code:
```
<?php
$res = \Civi\Api4\Contribution::get()
->setCheckPermissions(FALSE)
->addWhere('contribution_recur_id', '=', 19)
->execute();
echo "=== NOTE Results are correct ===\n\n";
echo "count is: " . $res->count() . "\n";
echo "First...\n";
print_r($res->first());
foreach ($res as $r) {
print_r($r);
}
$contribution_recur_id = 19;
$res = \Civi\Api4\Contribution::get()
->setCheckPermissions(FALSE)
->addWhere('contribution_recur_id', '=', 19)
->addWhere('is_template', '=', 1)
->execute();
echo "\n\n";
echo "=== NOTE: count is one, but no results from first() === \n";
echo "count is: " . $res->count() . "\n";
echo "First...\n";
print_r($res->first());
foreach ($res as $r) {
// No output from this call.
print_r($r);
}
```
And here is the output when running that code via `cv`:
```
=== NOTE Results are correct ===
count is: 4
First...
Array
(
[id] => 3928
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2019-12-02 13:07:59
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1FlKFWAwDzuDdbFCuWUlA4EZ
[invoice_id] => 0f3dd1eda0400becb9ecd33c58d28ae8
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] => 0
[receipt_date] => 2019-12-02 13:07:56
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] => 24745
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
Array
(
[id] => 3928
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2019-12-02 13:07:59
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1FlKFWAwDzuDdbFCuWUlA4EZ
[invoice_id] => 0f3dd1eda0400becb9ecd33c58d28ae8
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] => 0
[receipt_date] => 2019-12-02 13:07:56
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] => 24745
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
Array
(
[id] => 3951
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2020-01-02 13:08:03
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1FwZ1bAwDzuDdbFCXoBfw8UM
[invoice_id] =>
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] => 2020-01-02 14:13:42
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] =>
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
Array
(
[id] => 3999
[contact_id] => 10459
[financial_type_id] => 2
[contribution_page_id] => 14
[payment_instrument_id] => 1
[receive_date] => 2020-02-02 13:08:03
[non_deductible_amount] => 0.00
[total_amount] => 296.00
[fee_amount] => 8.88
[net_amount] => 287.12
[trxn_id] => in_1G7nnbAwDzuDdbFCvncHVNPH
[invoice_id] =>
[invoice_number] =>
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] => 2020-02-07 15:03:30
[thankyou_date] =>
[source] => Online Contribution: PowerBase Subscription Payment with Monthly Payment Option
[amount_level] =>
[contribution_recur_id] => 19
[is_test] => 0
[is_pay_later] => 0
[contribution_status_id] => 1
[address_id] =>
[check_number] =>
[campaign_id] =>
[creditnote_id] =>
[tax_amount] =>
[revenue_recognition_date] =>
[is_template] => 0
)
=== NOTE: count is one, but no results from first() ===
count is: 1
First...
www-data@fecbf38eb0bb:~/powerbase$
```https://lab.civicrm.org/dev/financial/-/issues/104CRM_Utils_Money::equals should round to monetary values then compare, not do ...2020-02-17T13:10:01ZFrancis (Agileware)CRM_Utils_Money::equals should round to monetary values then compare, not do a difference comparison.When comparing monetary amounts, e.g. via the `Order.create` API call, the `CRM_Utils_Money::equals` function is using a precision level one higher than the currency precision (currently always 2), i.e. instead of requiring the same cent...When comparing monetary amounts, e.g. via the `Order.create` API call, the `CRM_Utils_Money::equals` function is using a precision level one higher than the currency precision (currently always 2), i.e. instead of requiring the same cents value, the amounts must be within 1/10 of a cent.
This uses a calculation with an incorrect premise, and should instead round the values and compare them.
See [the comment for `CRM_Utils_Money::equals`](https://github.com/civicrm/civicrm-core/blob/5.19.1/CRM/Utils/Money.php#L155):
> So, if the currency has precision of 2 decimal points, a difference of more than 0.001 will cause the values to be considered as different.
Which seems like it's an order of magnitude out at first glance, but actually this is the wrong approach, as for example 0.0146 and 0.0154 are less than 0.001 apart, but round with a decimal precision of 2 places to 0.01 and 0.02 respectively. Yes, these two values are unlikely to come up for real, but similar cases could exist.
A practical example where this goes wrong (using Australian tax and currency rules, which are actually pretty simple):
1. We want to create an order with a single taxed line item of $84, including 10% tax.
2. The tax exclusive amount is ~ $76.36 (actually $76.3̅6̅),
3. and the tax amount is calculated to $7.636.
4. The software using the API calculates the total amount as $84.00.
5. Each line item is also added to the Order, using the exclusive and tax amounts.
6. The Order API diligently checks that the line items add up to the total, by checking whether $84 is equal to $76.36 + $7.636
7. `CRM_Utils_Money::equals(84, 83.996, 'AUD')` is called. According to the hard-coded currency precision of 2 decimal places, this should succeed, because $83.996 rounds to a whole dollar value of $84, but
8. The equals function compares to two values with a maximum difference of $0.001, which is less than the $0.004 between to two values.
9. The Order cannot be created.
Agileware ref CIVICRM-13685.24.0