Development issueshttps://lab.civicrm.org/groups/dev/-/issues2023-12-13T09:20:59Zhttps://lab.civicrm.org/dev/core/-/issues/2991Proposal: rework name fields to make name entity2023-12-13T09:20:59ZAndie HuntProposal: rework name fields to make name entity## Overview
A recent [discussion with Guy](https://chat.civicrm.org/civicrm/pl/wwqowz635fbpifio7on4e8r8dw) and #2883, plus the ongoing mayhem of organization names and personal experience with a variety of great and terrible name handli...## Overview
A recent [discussion with Guy](https://chat.civicrm.org/civicrm/pl/wwqowz635fbpifio7on4e8r8dw) and #2883, plus the ongoing mayhem of organization names and personal experience with a variety of great and terrible name handling systems, have led me to think that the solution to names isn't creating more or better-labeled fields for more types of names but rather to make name its own entity akin to phone, email, address, website, etc.
Once name is an entity, each contact could have multiple names, one primary, but with a bunch of possible types:
- legal name
- trade name
- nickname
- former name
- name in other language/culture
- name in an external system
- common mistakes
There could also be a bunch of name renderings - ways the name is displayed or inserted:
- sort name
- display name
- name for greetings
- name for listings
The latter could generate the existing greetings and potentially others. In particular, I think there's a real gap for how you insert someone's name in emails where you don't want "Dear", "Hi", or any other greeting as such.
Finally, the duplicate matching process could look for any of the possible names, cutting down on duplicates.
## Example use-case
### Organization has multiple names
An organization has their corporate name, colloquial name, and the name of their main product. These all refer to the same contact, but employees might fill the current employer field as one of the various ways. As an admin, you want to avoid having to merge them all the time. As a routine user, you will want to know all the various ways an organization is termed. As a bookkeeper, you will want to send invoices, checks, receipts, etc. with the correct entity name.
In this case, there are three name entities:
| Organization name | Name type | Is primary |
| ------------------------ | --------- | ---------- |
| Widget Productions | General | true |
| Widget Productions, Inc. | Legal | false |
| WidgetPro | General | false |
| Widgetizer | Product | false |
There would be a couple of name renderings:
| Rendering type | Value |
| -------------- | ------------------------ |
| Display Name | Widget Productions |
| Sort Name | Widget Productions |
| Billing name | Widget Productions, Inc. |
### Minister has variety of prefixes
Someone's name is styled differently when it is listed versus when they are addressed. In this case, a minister is styled "The Reverend Sally Jones" or "Rev. Sally Jones" when listed somewhere but her salutation is "Ms. Jones".
I think she'd have only one entry as a name entity but several renderings:
| Prefix | Title | First name | Middle Name | Last name | Suffix | Name type | Is primary |
|--------|--------------|------------|-------------|-----------|--------|-----------|------------|
| Ms. | The Reverend | Sally | Lynn | Jones | *null* | General | true |
These values are going to depend upon your sitewide preferences and choices for this contact, but a reasonable default might produce the following:
| Rendering type | Value |
|-----------------|--------------------------|
| Display Name | Sally Lynn Jones |
| Sort Name | Jones, Sally Lynn |
| Addressee | The Reverend Sally Jones |
| Email greeting | Dear Sally |
| Postal greeting | Dear Ms. Jones |
| Short name | Sally |
### An organization has a different name in another language
This should be self-explanatory:
| Organization name | Name type | Is primary |
|--------------------------|-----------|------------|
| Médecins Sans Frontières | General | true |
| Doctors Without Borders | Localized | false |
| Rendering type | Value |
|----------------|--------------------------|
| Display Name | Médecins Sans Frontières |
| Sort Name | Médecins Sans Frontières |
| English Name | Doctors Without Borders |
### Someone's family name comes before their given name
I'm on the fence about how this should be handled, but all I know is that we currently handle it terribly (except maybe in translations that assume it?) One option might be to call the fields first, middle, and last names according to position (*Ai* being the family name, but it comes first):
| Prefix | Title | First name | Middle Name | Last name | Suffix | Name type | Is primary |
|--------|--------|------------|-------------|-----------|--------|-----------|------------|
| Mr. | *null* | Ai | *null* | Weiwei | *null* | General | true |
Alternatively, we could name the fields according to function:
| Prefix | Title | Given name | Additional name | Surname | Suffix | Name type | Is primary |
|--------|--------|------------|-----------------|---------|--------|-----------|------------|
| Mr. | *null* | Weiwei | *null* | Ai | *null* | General | true |
In either case, the renderings should be like
| Rendering type | Value |
|-----------------|---------------|
| Display Name | Ai Weiwei |
| Sort Name | Ai Weiwei |
| Addressee | Mr. Ai Weiwei |
| Email greeting | Dear Weiwei |
| Postal greeting | Dear Mr. Ai |
| Short name | Weiwei |
### Clinic needs to retain legal name for insurance billing
Someone's real name doesn't match their legal name, let alone their nickname. While most organizations wouldn't want or need to record a contact's dead name, a clinic might need it for billing correspondence. In this case, a patient is named Stephen, or Steve for short, but his legal name is Barbara.
| Prefix | Title | First name | Middle Name | Last name | Suffix | Name type | Is primary |
|--------|--------|------------|-------------|-----------|--------|-----------|------------|
| Mr. | *null* | Stephen | Wayne | Smith | *null* | General | true |
| Mr. | *null* | Steve | *null* | Smith | *null* | Nickname | false |
| *null* | *null* | Barbara | Wayne | Smith | *null* | Legal | false |
All of the name renderings would use the primary name or nickname, but the clinic could add an additional name rendering for how they refer to patients when billing to the insurance company.
| Rendering type | Value |
|-----------------|----------------------|
| Display Name | Stephen Wayne Smith |
| Sort Name | Smith, Stephen Wayne |
| Addressee | Mr. Stephen Smith |
| Email greeting | Dear Steve |
| Postal greeting | Dear Mr. Smith |
| Short name | Steve |
| Insurance name | Barbara Smith |
### Household name possibilities
The current household name field befuddles lots of people and, in my opinion, makes households less attractive to use. If a household can have multiple names, it might be more useful.
You might use a Household name field that has everyone all listed out, or you could use the Last name field.
| Household name | Last name | Name type | Is primary |
|-------------------------------------|----------------|-----------|------------|
| Katherine Williams and Kendra Green | *null* | General | true |
| *null* | Williams-Green | General | false |
| Rendering type | Value |
|-----------------|------------------------------------------|
| Display Name | Katherine Williams and Kendra Green |
| Sort Name | Katherine Williams and Kendra Green |
| Addressee | The Williams-Green Household |
| Email greeting | Dear Katherine Williams and Kendra Green |
| Postal greeting | Dear Katherine Williams and Kendra Green |
Or if everyone shares a last name, a single name entity could do it all:
| Given name | Surname | Name type | Is primary |
|---------------|---------|-----------|------------|
| Jack and Jill | Hill | General | true |
(If we don't feel the need to stick with the legacy name field names, there's really no reason that "Given name" couldn't replace Organization name and Household name, too, so this illustrates that.)
| Rendering type | Value |
|-----------------|-------------------------|
| Display Name | Jack and Jill Hill |
| Sort Name | Hill, Jack and Jill |
| Addressee | The Hill Household |
| Email greeting | Dear Jack and Jill |
| Postal greeting | Dear Jack and Jill Hill |
## Current behavior
Right now, each of these situations is pretty annoying. It might require a separate custom field, located away from the name fields. It might make it difficult to automatically and accurately generate greetings for many people.
Currently, there are fields in the `civicrm_contact` table for each name part, plus nickname and legal name.
The only name renderings are display name and sort name (set sitewide), and addressee and email and postal greetings (site-wide presets and defaults, with custom options).
There's no provision for additional renderings or any way to do fallbacks like pick a nickname and fall back to a first name.
There's a limited number of alternative names for a contact.
Alternative names are not compared against primary names when deduping.
## Proposed behavior
### Schema
The name fields would be gone from the contact entity, and a new `civicrm_contact_name` entity is added with one of the following sets of fields:
| Traditional | Radical |
|-------------------|-------------------|
| id | id |
| contact_id | contact_id |
| contact_name_type | contact_name_type |
| is_primary | is_primary |
| first_name | given_name |
| middle_name | additional_name |
| last_name | surname |
| prefix_id | prefix_id |
| suffix_id | suffix_id |
| formal_title | formal_title |
| household_name | |
| organization_name | |
The `contact_name_type` would have reserved options General, Nickname, Legal, and Localized, but more could be added.
A new `civicrm_contact_rendering` entity is added with the following set of fields:
| Fields |
|-------------------------------|
| id |
| contact_id |
| contact_rendering_type |
| contact_rendering_template_id |
| value |
The `contact_rendering_type` would have reserved options Display name, Sort name, Addressee, Email greeting, Postal greeting, and Short name, but more could be added.
The `contact_rendering_template_id` would be akin to the existing `addressee_id`, `email_greeting_id`, and `postal_greeting_id`, while `value` would be the actual generated or custom value.
### Upgrade
On upgrade, the `civicrm_contact_name` would be populated with the main name fields, with nickname and legal name as additional rows. On upgrade, the `civicrm_contact_rendering` would be populated with rows for each contact's display name, sort name, addressee, and greetings.
### Contact rendering templates
The contact rendering templates would have the option to specify a contact name type to provide the default value, with a fallback to the primary contact name. For example, email greeting might default to "Dear {nickname.first_name}", where it picks the value of `first_name` from a contact's name entry with the name type of Nickname, and if that isn't available, it picks the primary name entry's value for `first_name`.
### Dedupe
When matching contacts on any of the name fields, the dedupe process would compare against all rows in the `civicrm_contact_name` field, regardless of `contact_name_type` or if it's the primary name.
## Comments
This is all very early in the process: I think it's important to do something like this, but I don't have my heart on the specific mechanisms here. I think it would need to be evaluated for performance in a variety of ways, but I don't expect it would have too huge of an impact.https://lab.civicrm.org/dev/core/-/issues/2990CiviCampaign - Move data into a single table2024-03-11T20:47:07ZcolemanwCiviCampaign - Move data into a single tableBackground
------------
CiviCampaign is an optional component (disabled by default on new installs). It allows contributions, events, etc. to be associated with a campaign.
Campaigns are basically like tags. The campaign itself contain...Background
------------
CiviCampaign is an optional component (disabled by default on new installs). It allows contributions, events, etc. to be associated with a campaign.
Campaigns are basically like tags. The campaign itself contains a bit more data (type, start & end date, description, goal) than a Tag, but the mechanism for linking an entity with a campaign is a very simple foreign key.
How it works now
-------------
"Tagging" an entity with a campaign works via a column on that entity's table. E.g. `civicrm_contribution_page.campaign_id`. There are currently 10 entities with such a column, allowing them to be "tagged" with a campaign_id.
The problem
-----------
This design involves tight coupling between CiviCampaign and other components, as it involves adding a column to their tables. It also limits the possibilities for which entities can have a campaign_id.
The solution
----------
There is another common pattern in CiviCRM, which is to add a small "bridge" table to join two entities, which is a good alternative to adding a column. `civicrm_entity_tag` is one example. It includes `tag_id`, `entity_id` and `entity_table` columns, and an OptionGroup `tag_used_for` which lists all the possible values for `entity_table`. Importantly, it's easily added-on by extensions; if an extension provides a new entity type which should be taggable, is just adds it to the option list.
The migration
------------
If CiviCampaign were a greenfield project designed today, we wouldn't think twice about structuring the data with a bridge table instead of littering our database with `campaign_id` columns. As a brownfield problem, fixing the structure may be more trouble than it's worth, but I thought I'd at least articulate how it might be possible:
- APIv4 has a new concept of "Extra" calculated fields, which could provide a faux `campaign_id` column for backward compatibility.
- CiviCampaign could implement a post-hook to save campaign_id if it's passed into "create" params. This would keep create and update working as if that column still exists.
- APIv3 would require some hacking to make a pseudo-field to fill in for a missing `campaign_id`.
Random musings
-----------
While researching this, I stumbled across a table called `civicrm_campaign_group`. I have no idea what it does but it looks very similar to how I imagined the new bridge table would be. It includes a `campaign_id`, `entity_id` and `entity_table` column. Why does this table exist??https://lab.civicrm.org/dev/core/-/issues/2987API call Contribution.repeattransaction fails with recurring contributions th...2023-03-20T01:51:15ZandrewcormickdockeryAPI call Contribution.repeattransaction fails with recurring contributions that have a one-to-one custom group record attachedOverview
----------------------------------------
Re: https://chat.civicrm.org/civicrm/pl/i8fht46isjn5uj4dbdosrqpqmr
The API call Contribution.repeattransaction appears to write a custom group record twice when completing a transaction....Overview
----------------------------------------
Re: https://chat.civicrm.org/civicrm/pl/i8fht46isjn5uj4dbdosrqpqmr
The API call Contribution.repeattransaction appears to write a custom group record twice when completing a transaction. On the second attempt, a database error caused by the clashing unique key is generated. The transaction appears to end up being recorded correctly, however the fatal error means that processes which call this function repeatedly end up not completing. Our use case involves finding all Eway transactions whose next scheduled contribution date is today, and then calling Contribution.repeattransaction for each one.
Reproduction steps
----------------------------------------
1. Ensure a one-to-one custom group exists against contributions.
1. Ensure a recurring contribution exists with a record in that custom group against the transaction.
1. Run `drush cvapi Contribution.repeattransaction contribution_status_id=Completed total_amount=<some value> contribution_recur_id=<contribution_recur_id in previous step> trxn_id=<random unique number>`
Current behaviour
----------------------------------------
Failure message appears: `DB Error: already exists`; process terminates. Record appears to be correctly produced in CiviCRM.
Log details:
```
Dec 07 12:40:11 [error] $Fatal Error Details = Array
(
[callback] => Array
(
[0] => CRM_Core_Error
[1] => exceptionHandler
)
[code] => -5
[message] => DB Error: already exists
[mode] => 16
[debug_info] => INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_field_2`,`custom_field_3`,`custom_field_4`,`entity_id` ) VALUES ( 1,'Some Text','','22943426',123456 ) [nativecode=1062 ** Duplicate entry '123456' for key 'unique_entity_id']
[type] => DB_Error
[user_info] => INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_field_2`,`custom_field_3`,`custom_field_4`,`entity_id` ) VALUES ( 1,'Some Text','','22943426',123456 ) [nativecode=1062 ** Duplicate entry '123456' for key 'unique_entity_id']
[to_string] => [db_error: message="DB Error: already exists" code=-5 mode=callback callback=CRM_Core_Error::exceptionHandler prefix="" info="INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_field_2`,`custom_field_3`,`custom_field_4`,`entity_id` ) VALUES ( 1,'Some Text','','22943426',123456 ) [nativecode=1062 ** Duplicate entry '123456' for key 'unique_entity_id']"]
)
Dec 07 12:40:11 [debug] $backTrace = #0 /path/to/civi/root/civicrm/CRM/Core/Error.php(942): CRM_Core_Error::backtrace("backTrace", TRUE)
#1 /path/to/civi/root/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(922): CRM_Core_Error::exceptionHandler(Object(DB_Error))
#2 /path/to/civi/root/civicrm/vendor/pear/db/DB.php(997): PEAR_Error->__construct("DB Error: already exists", -5, 16, (Array:2), "INSERT INTO civicrm_value_contribution_custom_group_1 ( `hide_from_slider_182`,`custom_...")
#3 /path/to/civi/root/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(575): DB_Error->__construct(-5, 16, (Array:2), "INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...")
#4 /path/to/civi/root/civicrm/vendor/pear/pear-core-minimal/src/PEAR.php(223): PEAR->_raiseError(Object(DB_mysqli), NULL, -5, 16, (Array:2), "INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...", "DB_Error", TRUE)
#5 /path/to/civi/root/civicrm/vendor/pear/db/DB/common.php(1928): PEAR->__call("raiseError", (Array:7))
#6 /path/to/civi/root/civicrm/vendor/pear/db/DB/mysqli.php(936): DB_common->raiseError(-5, NULL, NULL, "INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...", "1062 ** Duplicate entry '123456' for key 'unique_entity_id'")
#7 /path/to/civi/root/civicrm/vendor/pear/db/DB/mysqli.php(406): DB_mysqli->mysqliRaiseError()
#8 /path/to/civi/root/civicrm/vendor/pear/db/DB/common.php(1234): DB_mysqli->simpleQuery("INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...")
#9 /path/to/civi/root/civicrm/packages/DB/DataObject.php(2696): DB_common->query("INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...")
#10 /path/to/civi/root/civicrm/packages/DB/DataObject.php(1829): DB_DataObject->_query("INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...")
#11 /path/to/civi/root/civicrm/CRM/Core/DAO.php(468): DB_DataObject->query("INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...")
#12 /path/to/civi/root/civicrm/CRM/Core/DAO.php(1621): CRM_Core_DAO->query("INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...", TRUE)
#13 /path/to/civi/root/civicrm/CRM/Core/BAO/CustomValueTable.php(271): CRM_Core_DAO::executeQuery("INSERT INTO civicrm_value_contribution_custom_group_1 ( `custom_field_1`,`custom_...", (Array:5))
#14 /path/to/civi/root/civicrm/CRM/Core/BAO/CustomValueTable.php(391): CRM_Core_BAO_CustomValueTable::create((Array:2), "create")
#15 /path/to/civi/root/civicrm/CRM/Core/BAO/CustomValueTable.php(411): CRM_Core_BAO_CustomValueTable::store((Array:5), "civicrm_contribution", 123456, "create")
#16 /path/to/civi/root/civicrm/CRM/Core/DAO.php(2022): CRM_Core_BAO_CustomValueTable::postProcess((Array:5), "civicrm_contribution", 123456, "Contribution", "create")
#17 /path/to/civi/root/civicrm/CRM/Contribute/BAO/Contribution.php(2394): CRM_Core_DAO->copyCustomFields(123455, 123456)
#18 /path/to/civi/root/civicrm/CRM/Contribute/BAO/Contribution.php(4000): CRM_Contribute_BAO_Contribution::repeatTransaction((Array:10), (Array:18))
#19 /path/to/civi/root/civicrm/api/v3/Contribution.php(687): CRM_Contribute_BAO_Contribution::completeOrder((Array:10), "2269", NULL, NULL)
#20 /path/to/civi/root/civicrm/api/v3/Contribution.php(635): _ipn_process_transaction((Array:7), Object(CRM_Contribute_BAO_Contribution), (Array:10), (Array:10))
#21 /path/to/civi/root/civicrm/Civi/API/Provider/MagicFunctionProvider.php(89): civicrm_api3_contribution_repeattransaction((Array:7))
#22 /path/to/civi/root/civicrm/Civi/API/Kernel.php(149): Civi\API\Provider\MagicFunctionProvider->invoke((Array:8))
#23 /path/to/civi/root/civicrm/Civi/API/Kernel.php(81): Civi\API\Kernel->runRequest((Array:8))
#24 /path/to/civi/root/civicrm/api/api.php(132): Civi\API\Kernel->runSafe("contribution", "repeattransaction", (Array:5))
#25 /path/to/civi/root/civicrm/drupal/drush/civicrm.drush.inc(1581): civicrm_api3("Contribution", "repeattransaction", Array:5))
#26 /usr/local/src/drush/includes/command.inc(422): drush_civicrm_api("Contribution.repeattransaction", "contribution_status_id=Completed", "total_amount=11.00", "contribution_recur_id=22663", "trxn_id=aa11bb22cc33dd47")
#27 /usr/local/src/drush/includes/command.inc(231): _drush_invoke_hooks((Array:38), (Array:5))
#28 /usr/local/src/drush/includes/command.inc(199): drush_command("Contribution.repeattransaction", "contribution_status_id=Completed", "total_amount=11.00", "contribution_recur_id=22663", "trxn_id=aa11bb22cc33dd47")
#29 /usr/local/src/drush/lib/Drush/Boot/BaseBoot.php(67): drush_dispatch((Array:38))
#30 /usr/local/src/drush/includes/preflight.inc(67): Drush\Boot\BaseBoot->bootstrap_and_dispatch()
#31 /usr/local/src/drush/drush.php(12): drush_main()
#32 {main}
```
Expected behaviour
----------------------------------------
Fatal error not raised; no attempt to write the exact same record twice.
I have mitigated this behaviour with the following patch, but this is clearly a temporary solution and the real root cause needs to be found:
```
diff --git a/CRM/Core/BAO/CustomValueTable.php b/CRM/Core/BAO/CustomValueTable.php
index 8556c4ec21..6773b994c4 100644
--- a/CRM/Core/BAO/CustomValueTable.php
+++ b/CRM/Core/BAO/CustomValueTable.php
@@ -55,7 +55,7 @@ class CRM_Core_BAO_CustomValueTable {
$hookOP = 'edit';
}
else {
- $sqlOP = "INSERT INTO $tableName ";
+ $sqlOP = "INSERT IGNORE INTO $tableName ";
$where = NULL;
$hookOP = 'create';
}
```
Environment information
----------------------------------------
* __Browser:__ _Firefox 94.0.2_
* __CiviCRM:__ _5.43.2_
* __PHP:__ _7.3_
* __CMS:__ _Drupal 7.82_
* __Database:__ _MariaDB 10.4.21_
* __Web Server:__ _Nginx 1.10.3_https://lab.civicrm.org/dev/drupal/-/issues/170kcfinder error 5002021-12-16T13:14:52Zolivierkcfinder error 500Civicrm 5.43 and 5.44 under Drupal 8, launching kcfinder from ckeditor give an 500 error.
Php script integration/civicrm.php try to call civicrm.config.php located in web/libraries/civicrm/, and this file does not exist.
Copying this fil...Civicrm 5.43 and 5.44 under Drupal 8, launching kcfinder from ckeditor give an 500 error.
Php script integration/civicrm.php try to call civicrm.config.php located in web/libraries/civicrm/, and this file does not exist.
Copying this file from an Drupal 7 installation is not sufficent, because civicrm.settings.php is not searched in correct location.
```
--- ../../mcm65/sites/all/modules/civicrm/civicrm.config.php 2021-11-15 21:42:13.000000000 +0100
+++ libraries/civicrm/civicrm.config.php 2021-12-07 21:14:33.380121826 +0100
@@ -87,6 +87,11 @@
return $confdir;
}
+ if (file_exists($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . 'default' .
+ DIRECTORY_SEPARATOR . 'civicrm.settings.php')) {
+ return $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . 'default';
+ }
+
if (!file_exists($confdir) && !$skipConfigError) {
echo "Could not find valid configuration dir, best guess: $confdir<br/><br/>\n";
exit();
```
Another point, .htaccess in /web directory Deny access to most php files in public directory.
We must allow access to php files under kcfinder directory :
```
# For security reasons, deny access to other PHP files on public sites.
# Note: The following URI conditions are not anchored at the start (^),
# because Drupal may be located in a subdirectory. To further improve
# security, you can replace '!/' with '!^/'.
# Allow access to PHP files in /core (like authorize.php or install.php):
RewriteCond %{REQUEST_URI} !/core/[^/]*\.php$
# Allow access to test-specific PHP files:
RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?.php
# Allow access to Statistics module's custom front controller.
# Copy and adapt this rule to directly execute PHP files in contributed or
# custom modules or to run another PHP application in the same directory.
RewriteCond %{REQUEST_URI} !/core/modules/statistics/statistics.php$
RewriteCond %{REQUEST_URI} !/libraries/civicrm/packages/kcfinder/[a-z_]+\.php$
RewriteCond %{REQUEST_URI} !/libraries/civicrm/packages/kcfinder/.*/[a-z_]+\.php$
# Deny access to any other PHP files that do not match the rules above.
# Specifically, disallow autoload.php from being served directly.
RewriteRule "^(.+/.*|autoload)\.php($|/)" - [F]
```https://lab.civicrm.org/dev/core/-/issues/2976Feature Request: Form Builder and Permissions - Provide ability to restrict a...2023-11-02T12:39:11Zjustinfreeman (Agileware)Feature Request: Form Builder and Permissions - Provide ability to restrict access to selected Roles rather than just specific Permission GrantsWould be great if the Form Builder, Permissions had the ability to restrict access to selected Roles rather than just specific Permission Grants.
Roles being far more flexible, can be automatically granted and removed for user accounts ...Would be great if the Form Builder, Permissions had the ability to restrict access to selected Roles rather than just specific Permission Grants.
Roles being far more flexible, can be automatically granted and removed for user accounts and this is a common pattern on Member websites. Whereas Permission Grants are not used in this way.
For example: When a user with the Member role views a Form Builder page, they are granted access to use the Form and view the Search Results because they have the Member role.
![Screenshot_20211202_130808](/uploads/25c2fbadece5eea59beb05d7b269e937/Screenshot_20211202_130808.png)
Agileware Ref: CIVICRM-1899https://lab.civicrm.org/dev/financial/-/issues/190Proposal: Add `created_id` to `civicrm_contribution`2021-11-23T17:28:24ZJonGoldProposal: Add `created_id` to `civicrm_contribution`This is fairly straightforward as a proposal. I think it's a good idea generally (for those who lack advanced logging) but could also solve financial#49 - it's impossible to know what individual gave on behalf of an organization based o...This is fairly straightforward as a proposal. I think it's a good idea generally (for those who lack advanced logging) but could also solve financial#49 - it's impossible to know what individual gave on behalf of an organization based on the existing data.JonGoldJonGoldhttps://lab.civicrm.org/dev/core/-/issues/2966Duplicate contacts when custom field value is 'email', 'phone', etc.2023-03-18T04:08:01Zrita_compucorpDuplicate contacts when custom field value is 'email', 'phone', etc.**Issue**:
when existing contacts are donating (without being logged in) with the same details (email, first name, last name) that are registered in the system, most of the times there is a new contact created instead of merging it to t...**Issue**:
when existing contacts are donating (without being logged in) with the same details (email, first name, last name) that are registered in the system, most of the times there is a new contact created instead of merging it to the existing contact automatically.
**Investigation**:
When a custom field with a checkbox had its title and value set to ‘email’ or 'phone' and the unsupervised dedupe rule was prepared to check for email or phone as well causing the problem. So the problem occurs when:
- the unsupervised dedupe rule has email in it AND
- the custom field’s value is set to ‘email’
However not only the email option can cause duplications, but if you prepare an:
- unsupervised dedupe rule with phone ![screenshot-dmaster.demo.civicrm.org-2021.11.22-08_34_24](/uploads/758592a6d5330c1133dcd1206e714daa/screenshot-dmaster.demo.civicrm.org-2021.11.22-08_34_24.png) AND
- the custom field’s value is set to ‘phone’ ![screenshot-dmaster.demo.civicrm.org-2021.11.22-08_35_12](/uploads/df40ee69692fda55f51e946b2c841b9d/screenshot-dmaster.demo.civicrm.org-2021.11.22-08_35_12.png)
And even though the clients enter the same email/phone numbers on the donation form, the dedupe rule will be skipped and a new contact with the same information will be created. Probably this can be reproduced with many fields in the system, but only tried these two.
I checked on a few **different civi versions:**
- 4.7.26 - couldn’t reproduce
- 5.35.2 - issue reproducible
- 5.45.alpha1 (core demo civi) - issue reproducible
**Reproduction steps:**
1. create an unsupervised individual rule with the following details: ![screenshot-dmaster.demo.civicrm.org-2021.11.22-08_34_24](/uploads/758592a6d5330c1133dcd1206e714daa/screenshot-dmaster.demo.civicrm.org-2021.11.22-08_34_24.png)
2. create a custom field set for Contacts with checkboxes like this: ![screenshot-dmaster.demo.civicrm.org-2021.11.22-08_35_12](/uploads/df40ee69692fda55f51e946b2c841b9d/screenshot-dmaster.demo.civicrm.org-2021.11.22-08_35_12.png)
3. add the custom field set that you created in previous step to a profile that can be added to a contribution page
4. create a new (or use an old) contribution page and add the profile that you created in previous step to it in the Profiles tab
5. create a new contact, and make sure it has a First name, Last name and Phone number
6. open the contribution page as anonymous and donate to it, using the exact same First name, Last name and Phone number that you entered in previous step AND select the ‘phone’ option at the custom field you created → _after you submit the donation, a new contact will be created instead of merging it to the existing one, which is wrong behaviour_
7. donate again on the same form, with the same details as before, but instead of selecting ‘phone’ select either the ‘email’ or ‘post’ options → _the contribution will be merged to the original contact, which is the correct behaviour. It is because email and post are not added to the unsupervised dedupe rule in this case._
I think most of the time civi admins create custom fields with values set as numbers, but in some cases they might configure it to be the same as the label name and in that case duplications might occur. I think it might be happening when the value of the custom field is the same as the name of the field in the database (just a thought, can't say for sure).https://lab.civicrm.org/dev/core/-/issues/2963Export file empty when utilizing "Display results as" and searching for custo...2023-01-10T16:46:00Zfabian_SYSTOPIAExport file empty when utilizing "Display results as" and searching for custom dataOverview
----------------------------------------
When exporting data after an advanced search the exported file is empty if:
* "Display results as" was set to "related contacts" AND
* one search criterium was a custom field
The expor...Overview
----------------------------------------
When exporting data after an advanced search the exported file is empty if:
* "Display results as" was set to "related contacts" AND
* one search criterium was a custom field
The export preview shows all information correctly but the exported file does not contain any data.
Reproduction steps
----------------------------------------
1. Create a contact custom field (if you do not have one already, ex: Favorite Color: A/B/C)
1. Perform an advanced search, set "Display results as" to "related contacts" and any relationship type (ex: 'Employee Of')
1. Choose at least one custom filed as a search criterium (the search result must contain at least one contact (you may have to create/edit a test contact so that the Custom Field has a value)
1. Export the contact(s) from the search result
Current behaviour
----------------------------------------
The export file is empty although the export's preview shows all information correctly (in case you choose data to export and not export primary fields). Note that the export will work as intended if you do not set "Display results as" to "related contacts" or do not have at least one search criterium was a custom field.
Expected behaviour
----------------------------------------
Export file should contain data of selected contacts
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. -->
* __Browser:__ all
* __CiviCRM:__ Master/5.35.x, probably also earlier versions
Comments
----------------------------------------
Possibly unrelated but referencing #2873 and assigning to @monish.deb as there is currently a fix for the export feature in progress.Monish DebMonish Debhttps://lab.civicrm.org/dev/core/-/issues/2957Possibility to add a status message (alert box) after screen submission in Fo...2023-09-13T10:33:15ZErikHommelPossibility to add a status message (alert box) after screen submission in FormBuilderOverview
----------------------------------------
I would like to be able to send a status message (for example: Activity saved etc.) once a form that I have created with the FormBuilder is submitted.
Current behaviour
-----------------...Overview
----------------------------------------
I would like to be able to send a status message (for example: Activity saved etc.) once a form that I have created with the FormBuilder is submitted.
Current behaviour
----------------------------------------
At the moment I have created a form with FormBuilder which I use to add data, for example an activity. Right now once I have entered data and hit the "submit" button I am returned to whatever page I have entered at the Post Submit Page, but I do not get confirmation that my data has been saved.
Proposed behaviour
----------------------------------------
I would like to be able to specify that I want a status message when I have created, updated or deleted data.https://lab.civicrm.org/dev/core/-/issues/2945Make CRM_Core_Smarty::singleton() use Civi::statics instead of a static var2023-10-13T05:11:14ZDaveDMake CRM_Core_Smarty::singleton() use Civi::statics instead of a static varDuring unit tests, static vars can be problematic because they don't get reset between tests. There's a point within smarty where if a test fails at that point then its secure mode doesn't get reset. It's come up a couple times and then ...During unit tests, static vars can be problematic because they don't get reset between tests. There's a point within smarty where if a test fails at that point then its secure mode doesn't get reset. It's come up a couple times and then all the tests that use smarty on certain forms fail after it. It's not easy to track down if you haven't seen it before.
There's an argument civi code should be smarty secure-mode-compliant instead, but it isn't at the moment.https://lab.civicrm.org/dev/core/-/issues/2940Remove requirement to have a bounce email account setup2022-09-30T20:45:40ZseamusleeRemove requirement to have a bounce email account setupWith some more modern SMTP providers bounce email accounts may not be necessary for CiviMail Bounces to work because e.g. with Amazon SES / Sendgrid you can get the bounces processed via webhooks instead.
However within the code base we...With some more modern SMTP providers bounce email accounts may not be necessary for CiviMail Bounces to work because e.g. with Amazon SES / Sendgrid you can get the bounces processed via webhooks instead.
However within the code base we assume we need a bounce account to generate stuff like [no-reply email address](https://github.com/civicrm/civicrm-core/blob/master/CRM/Core/BAO/Domain.php#L364) or when we are getting [message ids](https://github.com/civicrm/civicrm-core/blob/513f6a469927c5dc5a41905feb7c3cff2cf15f0b/CRM/Campaign/BAO/Petition.php#L548)
It would be nice to get rid of this reliance on it being the default mail account which is the bounce processing one https://github.com/civicrm/civicrm-core/blob/513f6a469927c5dc5a41905feb7c3cff2cf15f0b/CRM/Core/BAO/MailSettings.php#L59
cc @JoeMurrayMonish DebMonish Debhttps://lab.civicrm.org/dev/core/-/issues/2935Print/Merge produces blank results when using a docx or odt template file2023-07-27T10:57:01ZChrisHardiePrint/Merge produces blank results when using a docx or odt template fileOverview
----------------------------------------
When trying to generate thank you letters or other printed/merged documents, and when uploading a .docx or .odt template file to use, CiviCRM generates blank output (e.g. a blank PDF file...Overview
----------------------------------------
When trying to generate thank you letters or other printed/merged documents, and when uploading a .docx or .odt template file to use, CiviCRM generates blank output (e.g. a blank PDF file, a blank .docx file). When generating the same document without uploading a template file, CiviCRM successfully generates output that contains the desired document body.
Reproduction steps
----------------------------------------
1. Find one or more contacts, or contributions, or other entities that can be printed/merged
1. Select an action that involves print/merge (e.g. thank you letters)
1. Upload a template document to use for the printed/merged output, in .odt or .docx format
1. Generate the merged document in any format (pdf, docx, html, odt)
1. Observe that the resulting document is blank
Expected behaviour
----------------------------------------
When a merged/generated document is produced, it should use the uploaded template and the specified document body, and not be blank.
Environment information
----------------------------------------
* __Browser:__ Attempted with Safari 15.1 and Chrome 96.0.4664.27 on macOS
* __CiviCRM:__ 5.42.0
* __PHP:__ 7.4
* __CMS:__ WordPress 5.8.1https://lab.civicrm.org/dev/civicrm-asset-plugin/-/issues/19Issues with the extension name vs key while building2021-11-09T12:08:26ZVangelisPIssues with the extension name vs key while buildingI've found an issue that relates with the way this component is reading the information from the extension and creates the relevant folder.
One example is `stripe` (but many more are having the same issue). Here is how we include it int...I've found an issue that relates with the way this component is reading the information from the extension and creates the relevant folder.
One example is `stripe` (but many more are having the same issue). Here is how we include it into composer:
```json
{
"name": "civicrm/extensions",
"description": "CiviCRM extensions",
"type": "civicrm-extension",
"require": {
"civicrm/stripe": "6.6.3"
},
"repositories": [
{
"type": "vcs",
"url": "https://lab.civicrm.org/extensions/stripe.git"
}
]
}
```
Now, due to [this line](https://lab.civicrm.org/dev/civicrm-asset-plugin/-/blob/master/src/ExtensionAssetRule.php#L17) , what is actually being created under the folder `web/libraries/civicrm` is `com.drastikbydesign.stripe` which is the `key` of the extension and not the project name (shortname).
In the meantime, stripe is being downloaded under the vendor folder as `stripe` and not as `com.drastikbydesign.stripe`.
If stripe is including some JS/CSS, those will NOT be read in CiviCRM as Civi is searching for the folder `web/libraries/civicrm/stripe` and not `web/libraries/civicrm/com.drastikbydesign.stripe`.
I can think of 2 possible solutions here:
1. instead of the attribute `key`, use (?) the `<file>` tag?
2. keep reading the attribute `key` as-is but also pass the actual folder name (which should be under the attribute `file`)
Any thoughts?https://lab.civicrm.org/dev/core/-/issues/2929Geocoding failures kill contributions2023-10-23T16:08:42ZandrewcormickdockeryGeocoding failures kill contributionsOverview
----------------------------------------
Last night between about 6pm and midnight AEDT, it appears that Nominatim (the Open Street Map API provider) had an intermittent outage. Some requests were receiving a 502 error. We hav...Overview
----------------------------------------
Last night between about 6pm and midnight AEDT, it appears that Nominatim (the Open Street Map API provider) had an intermittent outage. Some requests were receiving a 502 error. We have configured this as our Geocoding provider in CiviCRM under /civicrm/admin/setting/mapping?reset=1
People who were using CiviCRM in ways which caused the Geomapping provider to be called were receiving fatal errors as a result. This included people who were making donations (i.e. entering their address on the form which in turn was handed to the Geomapping provider for geocoding).
Current behaviour
----------------------------------------
When a request to the Geomapping provider fails (for example with a 502 error), the generating transaction within CiviCRM returns a fatal error and does not complete. This includes financial transactions, and indeed any administrative function that involves adding or updating a contact's address.
Expected behaviour
----------------------------------------
A Geomapping provider failure should never cause financial transactions to fail. I can't think of any reason why adding or updating an address should fail either. Fatal errors should only occur when an issue occurs which genuinely prevent a transaction from succeeding. A payment can still be processed regardless of whether that person's address can be geocoded or not. I expect a 502 Bad Gateway error from Nominatim would be logged, but never cause an address to fail to be added/updated. Obviously that would occur without the latitude/longitude being recorded. I can't even see the utility in informing the user. It's a system admin problem.
Environment information
----------------------------------------
* __CiviCRM:__ _5.35.2_
* __PHP:__ _7.3__
* __CMS:__ _Drupal 7.82_
* __Database:__ _MariaDB 10.4.21_
* __Web Server:__ _Nginx 1.10.3_
Comments
----------------------------------------
_Anything else you would like the reviewer to note._https://lab.civicrm.org/dev/core/-/issues/2928Expand Gender options?2024-01-16T16:07:07ZJoeMurrayExpand Gender options?Overview
----------------------------------------
Currently core has a Gender field with options in tarball of: Male, Female, Other. There has been a great deal of social change in this area with widespread use of additional terms. In ad...Overview
----------------------------------------
Currently core has a Gender field with options in tarball of: Male, Female, Other. There has been a great deal of social change in this area with widespread use of additional terms. In addition, it might be useful to have default questions and options for whether a contact is transgendered and what pronouns they would like.
Example use-case
----------------------------------------
1. Click on **Contacts -> New Individual**.
1. Enter **First Name** and **Last Name** and click **Save**.
Current behaviour
----------------------------------------
![2021-10-26_11-46-51](/uploads/f5985494ccec6ce0c0c143cc688014b2/2021-10-26_11-46-51.png)
Proposed behaviour
----------------------------------------
I'm going to break up the proposal into several parts that can be discussed and possibly approved separately.
1. Add to the list of gender options after Other: Prefer not to specify.
2. After Male and before Other, insert new gender options: Non-binary, Genderfluid.
2. Change from Female to Female/woman and from Male to Male/man.
3. Change the Gender field from single select to multiselect.
4. Add a new core field under Gender: Are you transgender? Yes, No, Prefer not to specify.
5. Add a new core field under the above: What pronouns do you use? He/him/his, She/her/hers, They/them/theirs, Zie/hir/hirs, Other.
6. Make the field for Pronouns multiselect.
An alternative that might make sense is to do some of this in an extension. Another alternative would be to assist with best practices by providing questions or options but defaulting to disabled.
Comments
----------------------------------------
Here is a note from an organization that works in this area in response to my query on behalf of a client for a longer list of genders:
> Coming up with a universal list of terminology to describe trans people can be difficult, since the exact terms used to describe the concepts involved varies dramatically from language to language and culture to culture. While trans communities in Canada and the US tend to use the same terminology, it can vary even with other majority Anglophone countries, to say nothing of the rest of the world.
>
> There is a lot of discussion out there in the data world about how best to record sexual orientation and gender identity (or “SOGI”) data, and best practices depend on the field in question. That said, a good starting point is to divide things into four questions framed like so:
>
> 1. What is your gender? (select all that apply)
> a. Female/woman
> b. Male/man
> c. Non-binary
> d. Genderfluid
> e. Other
> f. Prefer not to specify
>
> 2. Are you transgender?
> a. Yes
> b. No
> c. Prefer not to specify
>
> 3. What pronouns do you use? (select all that apply)
> a. He/him/his
> b. She/her/hers
> c. They/them/theirs
> d. Zie/hir/hirs
> e. Other
>
> Breaking things out like this has several advantages. First, it recognizes that “transgender” is not itself a gender identity, but is an umbrella category that includes certain men, women, and non-binary and genderfluid people. It simplifies the first question, keeping a shorter list for people to have to scroll through to find the proper term to describe themselves. It also allows organizations to easily modify the list to fit their specific use cases – an organization working in Samoa or with a significant Samoan population could add “fa’afafine” to the list while one dealing with a significant Native/First Nations population could add “two-spirit.”
>
> It also permits trans individuals to interact with the organization without either lying or outing themselves, by not forcing them to select either (for example) “cisgender woman” or “transgender woman.” (If you’re not familiar with the term, ‘cisgender’ is a word indicating a person who is not ‘transgender’.) In fact, it also allows the organization to sort their data in such a way that they don’t unnecessarily out trans people to staff and volunteers, by allowing them to pull a list of all women or all men that doesn’t automatically flag whether or not they are transgender.
>
> In addition, it reflects the fact that not all non-binary and genderfluid people consider themselves to fit under the “transgender” umbrella – this is a complicated issue that’s largely unknown outside of the larger LGBTQ community, and is often disregarded by organizations working with these communities.
>
> Finally, it flags the most useful information – what pronouns to use when referring to the person – into a separate easy to reference field that can be included on a display screen or other record without being specifically tied to someone’s transgender status.
>
> Of course, this is only scratching the surface of the issues that might be relevant to a specific organization’s needs. For instance, they should also consider having a separate “legal name” and “preferred name” field – the former is something that would only be referenced when writing checks or otherwise transacting business in the person’s legal name, but have the “preferred name” be what actually displays for all other interactions with the person. This would also allow cisgender people who primarily go by a short form, initials, or nickname to have that be displayed instead of their full name.
>
> A medical organization, meanwhile, might need to collect information on whether or not someone is intersex, or what their “gender assigned at birth” is, and there can be a lot of ways to capture this information based on how the organization interacts with its staff and patients.
>
> For additional discussion on collecting SOGI data, with multiple examples, please take a look at these resources:
>
> https://www.thetrevorproject.org/wp-content/uploads/2021/07/Measuring-Youth-Sexual-Orientation-and-Gender-Identity.pdf
>
> https://williamsinstitute.law.ucla.edu/quick-facts/survey-measures/JoeMurrayJoeMurrayhttps://lab.civicrm.org/dev/financial/-/issues/189Creating an Order fails with `Line item total doesn't match total amount` due...2023-06-19T09:18:26ZhaystackCreating an Order fails with `Line item total doesn't match total amount` due to the mismatch of 2 vs 6 decimal placesOpening this instead of conflating two issues in #188 - specifically referring to [this thread](https://lab.civicrm.org/dev/financial/-/issues/188#note_66286). As the subject says, creating an Order can fail with the error `Line item tot...Opening this instead of conflating two issues in #188 - specifically referring to [this thread](https://lab.civicrm.org/dev/financial/-/issues/188#note_66286). As the subject says, creating an Order can fail with the error `Line item total doesn't match total amount` because of the mismatch of 2 vs 6 decimal places when calculating the Order total from the amounts and tax amounts in the Line Items.
Say, for example, I have two Taxable Line Items in an Order both of which have had their Tax Amount pre-calculated - in this case by WooCommerce but I assume this could equally be the result from any external Payment Processor. All the amounts in the following params are correct as far as WooCommerce is concerned. Both CiviCRM and WooCommerce have `19.37910000` configured as the relevant Tax Rate.
```
[params] => Array
(
[contact_id] => 210
[financial_type_id] => 5
[payment_instrument_id] => 4
[trxn_id] => WooCommerce Order - 2250
[invoice_id] => 2250_woocommerce
[receive_date] => 2021-10-13 19:34:30
[contribution_status_id] => Pending
[is_pay_later] => 1
[total_amount] => 77.59 <-- The pre-calculated Total Amount
[tax_amount] => 12.59 <-- The pre-calculated Total Tax Amount
[source] => Shop
[campaign_id] => 3
[note] => Solstice Ticket (Bass) x 1, Solstice Ticket (Tenor) x 1
[line_items] => Array
(
[17] => Array
(
[params] => Array
(
[event_id] => 2
[contact_id] => 210
[role_id] => 1
[price_set_id] => 8
[fee_level] => Bass
[fee_amount] => 29.84
[source] => Shop: Solstice Ticket (Bass)
[status_id] => Pending from pay later
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 9
[unit_price] => 25.00
[qty] => 1
[line_total] => 25.00 <-- The Line Total
[tax_amount] => 4.84 <-- The pre-calculated Tax Amount
[label] => Bass
[entity_table] => civicrm_participant
[financial_type_id] => 5
[price_field_value_id] => 19
)
)
)
[18] => Array
(
[params] => Array
(
[event_id] => 2
[contact_id] => 210
[role_id] => 1
[price_set_id] => 8
[fee_level] => Tenor
[fee_amount] => 47.75
[source] => Shop: Solstice Ticket (Tenor)
[status_id] => Pending from pay later
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 9
[unit_price] => 40.00
[qty] => 1
[line_total] => 40.00 <-- The Line Total
[tax_amount] => 7.75 <-- The pre-calculated Tax Amount
[label] => Tenor
[entity_table] => civicrm_participant
[financial_type_id] => 5
[price_field_value_id] => 20
)
)
)
)
)
```
The Order API recalculates `$order->getTotalAmount()` and [then compares it with what's passed in via the API](https://github.com/civicrm/civicrm-core/blob/f73d3ac9a9979d8a616b0e2df53a459f7e6a84d7/api/v3/Order.php#L113). However, the rounding to 6 decimal places (rather than 2) triggers `CRM_Contribute_Exception_CheckLineItemsException` because `$params['total_amount'] = 77.59` does not equal `$order->getTotalAmount() = 77.596415`.
WooCommerce appears to _round_ the Line Items before _summing_ them, so:
* Line Item 1: `1.193791 * 25 = 29.844775 => 29.84`
* Line Item 2: `1.193791 * 40 = 47.75164 => 47.75`
* Total of rounded Line Items: `77.59`
CiviCRM, appears to _sum_ the Line Items before _rounding_ them, so:
* Line Item 1: `1.193791 * 25 = 29.844775`
* Line Item 2: `1.193791 * 40 = 47.75164`
* Total of summed Line Items: `77.596415`
`CRM_Utils_Money::equals()` then rounds _up_ not _down_ because of the extra precision and :boom: the above params cannot successfully create an Order.
My suggestion is that CiviCRM should:
* Verify the amount in each Line Item to the number of decimal places for the given currency.
* Keep a running total of those amounts.
* Compare the final running total with the `total_amount`.https://lab.civicrm.org/dev/core/-/issues/2915Proposal: Remove the Group Visibility terminology "Expose Publicly" as it has...2024-02-08T23:31:11Zjustinfreeman (Agileware)Proposal: Remove the Group Visibility terminology "Expose Publicly" as it has unintended connotations and would be good to standardise the terminology to describe "Group Visibility" and its optionsThis is a proposal to:
1. Remove the **Group Visibility** terminology _Expose Publicly_ as it has unintended connotations (as pointed out to me today by a Lawyer) and
2. Would be good to standardise the terminology to describe **Group Vi...This is a proposal to:
1. Remove the **Group Visibility** terminology _Expose Publicly_ as it has unintended connotations (as pointed out to me today by a Lawyer) and
2. Would be good to standardise the terminology to describe **Group Visibility** and its options. Ideally making it more obvious as to the purpose of each option.
As described on https://docs.civicrm.org/user/en/latest/organising-your-data/groups-and-tags/#visibility
* **Group Visibility**: **Public pages / Expose Publicly** - if you want to allow contacts to join and remove themselves from this group via Registration and Account Profile forms
* **Group Visibility**: **User and User Admin Only** - if membership in this group is controlled only by authorised CiviCRM users
As I understand it, this option _only_ applies to **Mailing List, Group Types**.
# Expose Publicly
![expose-publicly](/uploads/8d44c054f82a86d8fe92f8f7cd535663/expose-publicly.png)
# Group Visibility and options
![visbility](/uploads/7c4069b330d413230996fab273d242f4/visbility.png)https://lab.civicrm.org/dev/financial/-/issues/188Financial Items incorrectly recorded when using Payment API2021-10-27T16:53:49ZhaystackFinancial Items incorrectly recorded when using Payment APIFinally found the time to return to the Order & Payment API and test the changes that @eileen and @KarinG have worked on. So much better now that I can update a contribution without the tax amounts being recalculated!
Warning, this is g...Finally found the time to return to the Order & Payment API and test the changes that @eileen and @KarinG have worked on. So much better now that I can update a contribution without the tax amounts being recalculated!
Warning, this is going to be a long issue because it seems to involve two (maybe overlapping) issues which I haven't been able to separate. So... the scenario that I'm testing is where:
* I create multiple Line Items in an Order that are a mix of taxable and non-taxable.
* They are also a mix of Participant and Membership Line Items.
* The Line Items can be in any sequence when the Order is created.
To tease out what's going on, I tested the following:
1. Taxable Participant ($25) followed by Non-taxable Membership ($50)
2. Non-taxable Membership ($50) followed by Taxable Participant ($25)
3. Taxable Participant ($50) followed by Non-taxable Membership ($50)
4. Non-taxable Membership ($50) followed by Taxable Participant ($50)
These happen to be for Events ("Summer Solstice Festival Day Concert" and "Fall Fundraiser Dinner") and Membership Types (Student) in the CiviCRM Sample Data - though if you want to use those to replicate then it should be noted that "Summer Solstice Festival Day Concert" is incorrectly set to the "Member Dues" Financial Type. @kcristiano was invaluable in setting up CiviCRM's Sample Data with correct Financial Types and I assume there's nothing amiss in that regard.
## Taxable Participant ($25) followed by Non-taxable Membership ($50)
The procedure is commented upon in full for this first test. I'll just post the annotated logs for the subsequent tests since the procedure is identical.
![civicrm-E25-M50-order](/uploads/74c5bdb91fb8ee46d73a0f525a7552ad/civicrm-E25-M50-order.png)
The params for Order.create are as follows:
```
[params] => Array
(
[contact_id] => 210
[financial_type_id] => 1 <-- Non-taxable Financial Type
[payment_instrument_id] => 4
[trxn_id] => WooCommerce Order - 2247
[invoice_id] => 2247_woocommerce
[receive_date] => 2021-10-11 11:28:21
[contribution_status_id] => Pending
[is_pay_later] => 1
[total_amount] => 79.84 <-- Note: Total Amount has 2 decimal places
[source] => Shop
[campaign_id] => 3
[note] => Solstice Ticket x 1, Student Membership x 1
[line_items] => Array
(
[17] => Array
(
[params] => Array
(
[event_id] => 2
[contact_id] => 210
[role_id] => 1
[source] => Shop: Solstice Ticket
[status_id] => Pending from pay later
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 1
[unit_price] => 25.00
[qty] => 1
[line_total] => 25.00
[tax_amount] => 4.84 <-- Note: Tax Amount has 2 decimal places
[label] => Solstice Ticket
[entity_table] => civicrm_participant
[financial_type_id] => 5 <-- Taxable Financial Type
)
)
)
[18] => Array
(
[params] => Array
(
[membership_type_id] => 2
[source] => Shop
[contact_id] => 210
[skipStatusCal] => 1
[status_id] => Pending
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 1
[unit_price] => 50.00
[qty] => 1
[line_total] => 50.00
[tax_amount] => 0.00
[label] => Student Membership
[entity_table] => civicrm_membership
[financial_type_id] => 2 <-- Non-taxable Financial Type
[membership_type_id] => 2
)
)
)
)
)
```
The CiviCRM API (yeah, I know I should convert to API4 but that's another story) returns:
```
[result] => Array
(
[is_error] => 0
[version] => 3
[count] => 1
[id] => 103
[values] => Array
(
[103] => Array
(
[id] => 103
[contact_id] => 210
[financial_type_id] => 1
[contribution_page_id] =>
[payment_instrument_id] => 4
[receive_date] => 20211011112821
[non_deductible_amount] =>
[total_amount] => 79.844775 <-- Note: Total has 6 decimal places
[fee_amount] => 0
[net_amount] => 79.844775 <-- Note: Net Amount has 6 decimal places
[trxn_id] => WooCommerce Order - 2247
[invoice_id] => 2247_woocommerce
[invoice_number] => INV_103
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] =>
[thankyou_date] =>
[source] => Shop
[amount_level] =>
[contribution_recur_id] =>
[is_test] =>
[is_pay_later] => 1
[contribution_status_id] => 2
[address_id] =>
[check_number] =>
[campaign_id] => 3
[creditnote_id] =>
[tax_amount] => 4.84 <-- Note: Tax Amount has 2 decimal places
[revenue_recognition_date] =>
[is_template] =>
[contribution_type_id] => 1
[line_item] => Array
(
[0] => Array
(
[qty] => 1
[price_field_id] => 1
[price_field_value_id] => 1
[entity_table] => civicrm_participant
[unit_price] => 25.00
[label] => Solstice Ticket
[line_total] => 25.00
[tax_amount] => 4.844775 <-- Note: Tax Amount has 6 decimal places
[financial_type_id] => 5
[entity_id] => 56
)
[1] => Array
(
[qty] => 1
[price_field_id] => 1
[price_field_value_id] => 1
[entity_table] => civicrm_membership
[unit_price] => 50.00
[label] => Student Membership
[line_total] => 50.00
[tax_amount] => 0
[financial_type_id] => 2
[membership_type_id] => 2
[entity_id] => 35
)
)
)
)
)
```
So far so good - though it seems odd that the Total Amount, Net Amount and Tax Amount are reported as having 6 decimal places given that a pre-calculated Tax Amount to 2 decimal places was passed in.
Let's have a look at the Bookkeeping Report at this stage:
![civicrm-E25-M50-pre](/uploads/0fa2ceec4ca463ce50a38bb0ff8b96ae/civicrm-E25-M50-pre.png)
Looks good. The database looks good too:
```
SELECT id, total_amount, fee_amount, net_amount, tax_amount FROM `civicrm_contribution` WHERE id = '103';
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 79.84 | 0.00 | 79.84 | 4.84 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_participant | 1.00 | 25.00 | 25.00 | 5 | 4.84 |
| 108 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 11:28:23 | 2021-10-11 11:28:21 | 210 | Solstice Ticket | 25.00 | USD | 15 | 3 | civicrm_line_item | 107 |
| 105 | 2021-10-11 11:28:23 | 2021-10-11 11:28:21 | 210 | Sales Tax | 4.84 | USD | 17 | 3 | civicrm_line_item | 107 |
| 106 | 2021-10-11 11:28:23 | 2021-10-11 11:28:21 | 210 | Student Membership | 50.00 | USD | 2 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 11:28:21 | 79.84 | 79.84 | 0 | 2 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 79.84 | <-- Correct Entity ID.
| 204 | civicrm_financial_item | 104 | 101 | 25.00 | <-- Correct Entity ID.
| 205 | civicrm_financial_item | 105 | 101 | 4.84 | <-- Correct Entity ID.
| 206 | civicrm_financial_item | 106 | 101 | 50.00 | <-- Correct Entity ID.
+-----+------------------------+-----------+-------------------+--------+
```
Submit the `Payment.create` with:
```
[params] => Array
(
[contribution_id] => 103
[total_amount] => 79.84
[trxn_date] => 2021-10-11 11:30:58
[trxn_id] => WooCommerce Order - 2247
[payment_instrument_id] => 4
)
```
And the logs show:
```
PHP Notice: Undefined variable: CRM16923AnUnreliableMethodHasBeenUserToDeterminePaymentProcessorFromEvent in /Users/interactivist/Sites/civicrm/civicrm.events.tec.latest/httpdocs/wp-content/plugins/civicrm/civicrm/CRM/Contribute/BAO/Contribution.php on line 2724
PHP Notice: Undefined variable: CRM16923AnUnreliableMethodHasBeenUserToDeterminePaymentProcessorFromEvent in /Users/interactivist/Sites/civicrm/civicrm.events.tec.latest/httpdocs/wp-content/plugins/civicrm/civicrm/CRM/Contribute/BAO/Contribution.php on line 2724
```
The API result is:
```
[result] => Array
(
[is_error] => 0
[version] => 3
[count] => 1
[id] => 102
[values] => Array
(
[102] => Array
(
[id] => 102
[from_financial_account_id] => 7
[to_financial_account_id] => 6
[trxn_date] => 2021-10-11 11:30:58
[total_amount] => 79.84
[fee_amount] => 0.00
[net_amount] => 79.84
[currency] => USD
[is_payment] => 1
[trxn_id] => WooCommerce Order - 2247
[trxn_result_code] =>
[status_id] => 1
[payment_processor_id] =>
)
)
)
```
Nice. So what's in the database?
```
SELECT id, total_amount, fee_amount, net_amount, tax_amount FROM `civicrm_contribution` WHERE id = '103';
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 79.84 | 0.00 | 79.84 | 4.84 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_participant | 1.00 | 25.00 | 25.00 | 5 | 4.84 |
| 108 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 11:28:23 | 2021-10-11 11:28:21 | 210 | Solstice Ticket | 25.00 | USD | 15 | 1 | civicrm_line_item | 107 |
| 105 | 2021-10-11 11:28:23 | 2021-10-11 11:28:21 | 210 | Sales Tax | 4.84 | USD | 17 | 3 | civicrm_line_item | 107 |
| 106 | 2021-10-11 11:28:23 | 2021-10-11 11:28:21 | 210 | Student Membership | 50.00 | USD | 2 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 11:28:21 | 79.84 | 79.84 | 0 | 2 | 4 |
| 102 | 7 | 6 | 2021-10-11 11:30:58 | 79.84 | 79.84 | 1 | 1 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 79.84 |
| 204 | civicrm_financial_item | 104 | 101 | 25.00 |
| 205 | civicrm_financial_item | 105 | 101 | 4.84 |
| 206 | civicrm_financial_item | 106 | 101 | 50.00 |
| 207 | civicrm_contribution | 103 | 102 | 79.84 | <-- Correct Entity ID.
| 208 | civicrm_financial_item | 104 | 102 | 25.00 | <-- Correct Entity ID.
| 209 | civicrm_financial_item | 105 | 102 | 4.84 | <-- Duplicated in 211?
| 210 | civicrm_financial_item | 104 | 102 | 50.00 | <-- Wrong Entity ID.
| 211 | civicrm_financial_item | 105 | 102 | 4.84 | <-- Duplicate of 209?
+-----+------------------------+-----------+-------------------+--------+
```
The Bookkeeping Report seems to reflect the odd assignment of Financial Items:
![civicrm-E25-M50-post](/uploads/2e550b6a4893a9d8960ec4b0a2bcff14/civicrm-E25-M50-post.png)
As you can see, it lists all of the `1100` entries as "Event Fee Taxable". The "Member Dues" item seems to have been switched to "Event Fee Taxable". There also seems to be a duplicate Tax Amount entry. This may be important below when the Financial Item amounts are identical.
## Non-taxable Membership ($50) followed by Taxable Participant ($25)
Sequence of Line Items is reversed:
![civicrm-M50-E25-order](/uploads/3fb49ce43318c51ba2da2f6cd8be3470/civicrm-M50-E25-order.png)
Order API params:
```
[params] => Array
(
[contact_id] => 210
[financial_type_id] => 1 <-- Non-taxable Financial Type
[payment_instrument_id] => 4
[trxn_id] => WooCommerce Order - 2247
[invoice_id] => 2247_woocommerce
[receive_date] => 2021-10-11 11:36:49
[contribution_status_id] => Pending
[is_pay_later] => 1
[total_amount] => 79.84 <-- Note: Total Amount has 2 decimal places
[source] => Shop
[campaign_id] => 3
[note] => Student Membership x 1, Solstice Ticket x 1
[line_items] => Array
(
[17] => Array
(
[params] => Array
(
[membership_type_id] => 2
[source] => Shop
[contact_id] => 210
[skipStatusCal] => 1
[status_id] => Pending
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 1
[unit_price] => 50.00
[qty] => 1
[line_total] => 50.00
[tax_amount] => 0.00
[label] => Student Membership
[entity_table] => civicrm_membership
[financial_type_id] => 2 <-- Non-taxable Financial Type
[membership_type_id] => 2
)
)
)
[18] => Array
(
[params] => Array
(
[event_id] => 2
[contact_id] => 210
[role_id] => 1
[source] => Shop: Solstice Ticket
[status_id] => Pending from pay later
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 1
[unit_price] => 25.00
[qty] => 1
[line_total] => 25.00
[tax_amount] => 4.84 <-- Note: Tax Amount has 2 decimal places
[label] => Solstice Ticket
[entity_table] => civicrm_participant
[financial_type_id] => 5 <-- Taxable Financial Type
)
)
)
)
)
```
API returns:
```
[result] => Array
(
[is_error] => 0
[version] => 3
[count] => 1
[id] => 103
[values] => Array
(
[103] => Array
(
[id] => 103
[contact_id] => 210
[financial_type_id] => 1
[contribution_page_id] =>
[payment_instrument_id] => 4
[receive_date] => 20211011113649
[non_deductible_amount] =>
[total_amount] => 79.844775 <-- Note: Total has 6 decimal places
[fee_amount] => 0
[net_amount] => 79.844775 <-- Note: Net Amount has 6 decimal places
[trxn_id] => WooCommerce Order - 2247
[invoice_id] => 2247_woocommerce
[invoice_number] => INV_103
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] =>
[thankyou_date] =>
[source] => Shop
[amount_level] =>
[contribution_recur_id] =>
[is_test] =>
[is_pay_later] => 1
[contribution_status_id] => 2
[address_id] =>
[check_number] =>
[campaign_id] => 3
[creditnote_id] =>
[tax_amount] => 4.84 <-- Note: Tax Amount has 2 decimal places
[revenue_recognition_date] =>
[is_template] =>
[contribution_type_id] => 1
[line_item] => Array
(
[0] => Array
(
[qty] => 1
[price_field_id] => 1
[price_field_value_id] => 1
[entity_table] => civicrm_membership
[unit_price] => 50.00
[label] => Student Membership
[line_total] => 50.00
[tax_amount] => 0
[financial_type_id] => 2
[membership_type_id] => 2
[entity_id] => 35
)
[1] => Array
(
[qty] => 1
[price_field_id] => 1
[price_field_value_id] => 1
[entity_table] => civicrm_participant
[unit_price] => 25.00
[label] => Solstice Ticket
[line_total] => 25.00
[tax_amount] => 4.844775 <-- Note: Tax Amount has 6 decimal places
[financial_type_id] => 5
[entity_id] => 56
)
)
)
)
)
```
Database looks good:
```
SELECT id, total_amount, fee_amount, net_amount, tax_amount FROM `civicrm_contribution` WHERE id = '103';
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 79.84 | 0.00 | 79.84 | 4.84 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
| 108 | civicrm_participant | 1.00 | 25.00 | 25.00 | 5 | 4.84 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 11:36:51 | 2021-10-11 11:36:49 | 210 | Student Membership | 50.00 | USD | 2 | 3 | civicrm_line_item | 107 |
| 105 | 2021-10-11 11:36:51 | 2021-10-11 11:36:49 | 210 | Solstice Ticket | 25.00 | USD | 15 | 3 | civicrm_line_item | 108 |
| 106 | 2021-10-11 11:36:51 | 2021-10-11 11:36:49 | 210 | Sales Tax | 4.84 | USD | 17 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 11:36:49 | 79.84 | 79.84 | 0 | 2 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 79.84 | <-- Correct Entity ID.
| 204 | civicrm_financial_item | 104 | 101 | 50.00 | <-- Correct Entity ID.
| 205 | civicrm_financial_item | 105 | 101 | 25.00 | <-- Correct Entity ID.
| 206 | civicrm_financial_item | 106 | 101 | 4.84 | <-- Correct Entity ID.
+-----+------------------------+-----------+-------------------+--------+
```
Bookkeeping confirms this:
![civicrm-M50-E25-pre](/uploads/87857b96e6fb0b8b2379c29e832da746/civicrm-M50-E25-pre.png)
Submit the `Payment.create` with:
```
[params] => Array
(
[contribution_id] => 103
[total_amount] => 79.84
[trxn_date] => 2021-10-11 11:38:59
[trxn_id] => WooCommerce Order - 2247
[payment_instrument_id] => 4
)
```
Logs again show:
```
[11-Oct-2021 10:39:00 UTC] PHP Notice: Undefined variable: CRM16923AnUnreliableMethodHasBeenUserToDeterminePaymentProcessorFromEvent in /Users/interactivist/Sites/civicrm/civicrm.events.tec.latest/httpdocs/wp-content/plugins/civicrm/civicrm/CRM/Contribute/BAO/Contribution.php on line 2724
[11-Oct-2021 10:39:01 UTC] PHP Notice: Undefined variable: CRM16923AnUnreliableMethodHasBeenUserToDeterminePaymentProcessorFromEvent in /Users/interactivist/Sites/civicrm/civicrm.events.tec.latest/httpdocs/wp-content/plugins/civicrm/civicrm/CRM/Contribute/BAO/Contribution.php on line 2724
```
API result:
```
[result] => Array
(
[is_error] => 0
[version] => 3
[count] => 1
[id] => 102
[values] => Array
(
[102] => Array
(
[id] => 102
[from_financial_account_id] => 7
[to_financial_account_id] => 6
[trxn_date] => 2021-10-11 11:38:59
[total_amount] => 79.84
[fee_amount] => 0.00
[net_amount] => 79.84
[currency] => USD
[is_payment] => 1
[trxn_id] => WooCommerce Order - 2247
[trxn_result_code] =>
[status_id] => 1
[payment_processor_id] =>
)
)
)
```
Database again shows the wrongly assigned Financial Items:
```
SELECT id, total_amount, fee_amount, net_amount, tax_amount FROM `civicrm_contribution` WHERE id = '103';
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 79.84 | 0.00 | 79.84 | 4.84 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
| 108 | civicrm_participant | 1.00 | 25.00 | 25.00 | 5 | 4.84 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 11:36:51 | 2021-10-11 11:36:49 | 210 | Student Membership | 50.00 | USD | 2 | 1 | civicrm_line_item | 107 |
| 105 | 2021-10-11 11:36:51 | 2021-10-11 11:36:49 | 210 | Solstice Ticket | 25.00 | USD | 15 | 3 | civicrm_line_item | 108 |
| 106 | 2021-10-11 11:36:51 | 2021-10-11 11:36:49 | 210 | Sales Tax | 4.84 | USD | 17 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 11:36:49 | 79.84 | 79.84 | 0 | 2 | 4 |
| 102 | 7 | 6 | 2021-10-11 11:38:59 | 79.84 | 79.84 | 1 | 1 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 79.84 |
| 204 | civicrm_financial_item | 104 | 101 | 50.00 |
| 205 | civicrm_financial_item | 105 | 101 | 25.00 |
| 206 | civicrm_financial_item | 106 | 101 | 4.84 |
| 207 | civicrm_contribution | 103 | 102 | 79.84 | <-- Correct Entity ID.
| 208 | civicrm_financial_item | 104 | 102 | 50.00 | <-- Correct Entity ID.
| 209 | civicrm_financial_item | 106 | 102 | 4.84 | <-- Duplicated in 211?
| 210 | civicrm_financial_item | 104 | 102 | 25.00 | <-- Wrong Entity ID.
| 211 | civicrm_financial_item | 106 | 102 | 4.84 | <-- Duplicate of 209?
+-----+------------------------+-----------+-------------------+--------+
```
Again, there also seems to be a duplicate Tax Amount entry.
Bookkeeping Report confirmation of the odd assignment:
![civicrm-M50-E25-post](/uploads/7124d730e050f3f288de87ed29bfeb1b/civicrm-M50-E25-post.png)
The "Event Fee Taxable" item seems to have been switched to "Member Dues".
## Taxable Participant ($50) followed by Non-taxable Membership ($50)
Sequence as per first test:
![civicrm-E50-M50-order](/uploads/3cadc61cf6ecceeb570c7298ae0aafb5/civicrm-E50-M50-order.png)
Order API params:
```
[params] => Array
(
[contact_id] => 210
[financial_type_id] => 1 <-- Non-taxable Financial Type
[payment_instrument_id] => 4
[trxn_id] => WooCommerce Order - 2247
[invoice_id] => 2247_woocommerce
[receive_date] => 2021-10-11 12:01:02
[contribution_status_id] => Pending
[is_pay_later] => 1
[total_amount] => 109.69 <-- Note: Total Amount has 2 decimal places
[source] => Shop
[campaign_id] => 3
[note] => Fundraiser Dinner Ticket x 1, Student Membership x 1
[line_items] => Array
(
[17] => Array
(
[params] => Array
(
[event_id] => 1
[contact_id] => 210
[role_id] => 1
[source] => Shop: Fundraiser Dinner Ticket
[status_id] => Pending from pay later
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 1
[unit_price] => 50.00
[qty] => 1
[line_total] => 50.00
[tax_amount] => 9.69 <-- Note: Tax Amount has 2 decimal places
[label] => Fundraiser Dinner Ticket
[entity_table] => civicrm_participant
[financial_type_id] => 5 <-- Taxable Financial Type
)
)
)
[18] => Array
(
[params] => Array
(
[membership_type_id] => 2
[source] => Shop
[contact_id] => 210
[skipStatusCal] => 1
[status_id] => Pending
)
[line_item] => Array
(
[0] => Array
(
[price_field_id] => 1
[unit_price] => 50.00
[qty] => 1
[line_total] => 50.00
[tax_amount] => 0.00
[label] => Student Membership
[entity_table] => civicrm_membership
[financial_type_id] => 2 <-- Non-taxable Financial Type
[membership_type_id] => 2
)
)
)
)
)
```
API return:
```
[result] => Array
(
[is_error] => 0
[version] => 3
[count] => 1
[id] => 103
[values] => Array
(
[103] => Array
(
[id] => 103
[contact_id] => 210
[financial_type_id] => 1
[contribution_page_id] =>
[payment_instrument_id] => 4
[receive_date] => 20211011120102
[non_deductible_amount] =>
[total_amount] => 109.68955 <-- Note: Total has 6 decimal places
[fee_amount] => 0
[net_amount] => 109.68955 <-- Note: Net Amount has 6 decimal places
[trxn_id] => WooCommerce Order - 2247
[invoice_id] => 2247_woocommerce
[invoice_number] => INV_103
[currency] => USD
[cancel_date] =>
[cancel_reason] =>
[receipt_date] =>
[thankyou_date] =>
[source] => Shop
[amount_level] =>
[contribution_recur_id] =>
[is_test] =>
[is_pay_later] => 1
[contribution_status_id] => 2
[address_id] =>
[check_number] =>
[campaign_id] => 3
[creditnote_id] =>
[tax_amount] => 9.69 <-- Note: Tax Amount has 2 decimal places
[revenue_recognition_date] =>
[is_template] =>
[contribution_type_id] => 1
[line_item] => Array
(
[0] => Array
(
[qty] => 1
[price_field_id] => 1
[price_field_value_id] => 1
[entity_table] => civicrm_participant
[unit_price] => 50.00
[label] => Fundraiser Dinner Ticket
[line_total] => 50.00
[tax_amount] => 9.68955 <-- Note: Tax Amount has 6 decimal places
[financial_type_id] => 5
[entity_id] => 56
)
[1] => Array
(
[qty] => 1
[price_field_id] => 1
[price_field_value_id] => 1
[entity_table] => civicrm_membership
[unit_price] => 50.00
[label] => Student Membership
[line_total] => 50.00
[tax_amount] => 0
[financial_type_id] => 2
[membership_type_id] => 2
[entity_id] => 35
)
)
)
)
)
```
Again, database looks good:
```
SELECT id, total_amount, fee_amount, net_amount, tax_amount FROM `civicrm_contribution` WHERE id = '103';
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 109.69 | 0.00 | 109.69 | 9.69 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_participant | 1.00 | 50.00 | 50.00 | 5 | 9.69 |
| 108 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 12:01:04 | 2021-10-11 12:01:02 | 210 | Fundraiser Dinner Ticket | 50.00 | USD | 15 | 3 | civicrm_line_item | 107 |
| 105 | 2021-10-11 12:01:04 | 2021-10-11 12:01:02 | 210 | Sales Tax | 9.69 | USD | 17 | 3 | civicrm_line_item | 107 |
| 106 | 2021-10-11 12:01:04 | 2021-10-11 12:01:02 | 210 | Student Membership | 50.00 | USD | 2 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 12:01:02 | 109.69 | 109.69 | 0 | 2 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 109.69 | <-- Correct Entity ID.
| 204 | civicrm_financial_item | 104 | 101 | 50.00 | <-- Correct Entity ID.
| 205 | civicrm_financial_item | 105 | 101 | 9.69 | <-- Correct Entity ID.
| 206 | civicrm_financial_item | 106 | 101 | 50.00 | <-- Correct Entity ID.
+-----+------------------------+-----------+-------------------+--------+
```
Bookkeeping Report confirms:
![civicrm-E50-M50-pre](/uploads/728d5845348f0f8bf289f5a7fbcb84f6/civicrm-E50-M50-pre.png)
This is where things get a bit weird(er).
Call `Payment.create` with:
```
[params] => Array
(
[contribution_id] => 103
[total_amount] => 109.69
[trxn_date] => 2021-10-11 12:04:49
[trxn_id] => WooCommerce Order - 2247
[payment_instrument_id] => 4
)
```
Logs (as usual) show:
```
[11-Oct-2021 11:04:50 UTC] PHP Notice: Undefined variable: CRM16923AnUnreliableMethodHasBeenUserToDeterminePaymentProcessorFromEvent in /Users/interactivist/Sites/civicrm/civicrm.events.tec.latest/httpdocs/wp-content/plugins/civicrm/civicrm/CRM/Contribute/BAO/Contribution.php on line 2724
[11-Oct-2021 11:04:51 UTC] PHP Notice: Undefined variable: CRM16923AnUnreliableMethodHasBeenUserToDeterminePaymentProcessorFromEvent in /Users/interactivist/Sites/civicrm/civicrm.events.tec.latest/httpdocs/wp-content/plugins/civicrm/civicrm/CRM/Contribute/BAO/Contribution.php on line 2724
```
API result is:
```
[result] => Array
(
[is_error] => 0
[version] => 3
[count] => 1
[id] => 102
[values] => Array
(
[102] => Array
(
[id] => 102
[from_financial_account_id] => 7
[to_financial_account_id] => 6
[trxn_date] => 2021-10-11 12:04:49
[total_amount] => 109.69
[fee_amount] => 0.00
[net_amount] => 109.69
[currency] => USD
[is_payment] => 1
[trxn_id] => WooCommerce Order - 2247
[trxn_result_code] =>
[status_id] => 1
[payment_processor_id] =>
)
)
)
```
Database has the same pattern of mis-assignment:
```
SELECT id, total_amount, fee_amount, net_amount, tax_amount FROM `civicrm_contribution` WHERE id = '103';
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 109.69 | 0.00 | 109.69 | 9.69 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_participant | 1.00 | 50.00 | 50.00 | 5 | 9.69 |
| 108 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 12:01:04 | 2021-10-11 12:01:02 | 210 | Fundraiser Dinner Ticket | 50.00 | USD | 15 | 1 | civicrm_line_item | 107 |
| 105 | 2021-10-11 12:01:04 | 2021-10-11 12:01:02 | 210 | Sales Tax | 9.69 | USD | 17 | 3 | civicrm_line_item | 107 |
| 106 | 2021-10-11 12:01:04 | 2021-10-11 12:01:02 | 210 | Student Membership | 50.00 | USD | 2 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 12:01:02 | 109.69 | 109.69 | 0 | 2 | 4 |
| 102 | 7 | 6 | 2021-10-11 12:04:49 | 109.69 | 109.69 | 1 | 1 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 109.69 |
| 204 | civicrm_financial_item | 104 | 101 | 50.00 |
| 205 | civicrm_financial_item | 105 | 101 | 9.69 |
| 206 | civicrm_financial_item | 106 | 101 | 50.00 |
| 207 | civicrm_contribution | 103 | 102 | 109.69 | <-- Correct Entity ID.
| 208 | civicrm_financial_item | 104 | 102 | 50.00 | <-- Correct Entity ID.
| 209 | civicrm_financial_item | 105 | 102 | 9.69 | <-- Duplicated in 211?
| 210 | civicrm_financial_item | 104 | 102 | 50.00 | <-- Wrong Entity ID.
| 211 | civicrm_financial_item | 105 | 102 | 9.69 | <-- Duplicate of 209?
+-----+------------------------+-----------+-------------------+--------+
```
However, this time the consequences of this combination of mismatch and duplicate entry gives a different result in the Bookkeeping Report:
![civicrm-E50-M50-post](/uploads/afb612896bb51e3db2afd7b67b176c9d/civicrm-E50-M50-post.png)
This time, it seems, there are only 5 Financial Items visible.
## Non-taxable Membership ($50) followed by Taxable Participant ($50)
![civicrm-M50-E50-order](/uploads/0f34a882ab9bfb12322254183951b89a/civicrm-M50-E50-order.png)
I'll skip the API calls for this one - if you want them, I'm happy to provide.
The `Order.create` process goes fine, but we're left with the following in the database:
```
+-----+--------------+------------+------------+------------+
| id | total_amount | fee_amount | net_amount | tax_amount |
+-----+--------------+------------+------------+------------+
| 103 | 109.69 | 0.00 | 109.69 | 9.69 |
+-----+--------------+------------+------------+------------+
SELECT id, entity_table, qty, unit_price, line_total, financial_type_id, tax_amount FROM `civicrm_line_item` WHERE contribution_id = '103';
+-----+---------------------+------+------------+------------+-------------------+------------+
| id | entity_table | qty | unit_price | line_total | financial_type_id | tax_amount |
+-----+---------------------+------+------------+------------+-------------------+------------+
| 107 | civicrm_membership | 1.00 | 50.00 | 50.00 | 2 | 0.00 |
| 108 | civicrm_participant | 1.00 | 50.00 | 50.00 | 5 | 9.69 |
+-----+---------------------+------+------------+------------+-------------------+------------+
SELECT * FROM `civicrm_financial_item` WHERE contact_id = '210';
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| id | created_date | transaction_date | contact_id | description | amount | currency | financial_account_id | status_id | entity_table | entity_id |
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
| 104 | 2021-10-11 12:21:33 | 2021-10-11 12:21:31 | 210 | Student Membership | 50.00 | USD | 2 | 1 | civicrm_line_item | 107 |
| 105 | 2021-10-11 12:21:33 | 2021-10-11 12:21:31 | 210 | Fundraiser Dinner Ticket | 50.00 | USD | 15 | 3 | civicrm_line_item | 108 |
| 106 | 2021-10-11 12:21:33 | 2021-10-11 12:21:31 | 210 | Sales Tax | 9.69 | USD | 17 | 3 | civicrm_line_item | 108 |
+-----+---------------------+---------------------+------------+--------------------------+--------+----------+----------------------+-----------+-------------------+-----------+
SELECT id, from_financial_account_id, to_financial_account_id, trxn_date, total_amount, net_amount, is_payment, status_id, payment_instrument_id FROM `civicrm_financial_trxn` WHERE id > '100';
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| id | from_financial_account_id | to_financial_account_id | trxn_date | total_amount | net_amount | is_payment | status_id | payment_instrument_id |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
| 101 | NULL | 7 | 2021-10-11 12:21:31 | 109.69 | 109.69 | 0 | 2 | 4 |
| 102 | 7 | 6 | 2021-10-11 12:25:19 | 109.69 | 109.69 | 1 | 1 | 4 |
+-----+---------------------------+-------------------------+---------------------+--------------+------------+------------+-----------+-----------------------+
SELECT * FROM `civicrm_entity_financial_trxn` WHERE financial_trxn_id > '100';
+-----+------------------------+-----------+-------------------+--------+
| id | entity_table | entity_id | financial_trxn_id | amount |
+-----+------------------------+-----------+-------------------+--------+
| 203 | civicrm_contribution | 103 | 101 | 109.69 |
| 204 | civicrm_financial_item | 104 | 101 | 50.00 |
| 205 | civicrm_financial_item | 105 | 101 | 50.00 |
| 206 | civicrm_financial_item | 106 | 101 | 9.69 |
| 207 | civicrm_contribution | 103 | 102 | 109.69 | <-- Correct Entity ID.
| 208 | civicrm_financial_item | 104 | 102 | 50.00 | <-- Correct Entity ID.
| 209 | civicrm_financial_item | 106 | 102 | 9.69 | <-- Duplicated in 211?
| 210 | civicrm_financial_item | 104 | 102 | 50.00 | <-- Wrong Entity ID.
| 211 | civicrm_financial_item | 106 | 102 | 9.69 | <-- Duplicate of 209?
+-----+------------------------+-----------+-------------------+--------+
```
The Bookkeeping Report shows the end result:
![civicrm-M50-E50-post](/uploads/4cefa4c34c1b02956fdc9ac3e62c8d4c/civicrm-M50-E50-post.png)
## Final thought
My best guess at the moment is that the combination of the mis-assigned `entity_id`s for the Financial Items _plus_ the effect of the extra entry in the `civicrm_entity_financial_trxn` table leads to the mix of 5 or 6 Items visible in the Bookkeeping Report.
If you've got to here, thanks for reading! Hope this helps fix what seemed to be mind-bending symptoms.https://lab.civicrm.org/dev/core/-/issues/2899DB error on updating multiple cases from the search form2022-09-20T10:50:03ZjitendraDB error on updating multiple cases from the search formTo replicate -
1. Navigate to https://dmaster.demo.civicrm.org/civicrm/case/search?reset=1
2. Search for cases. Select all results (ts_all radio button) => Update multiple cases action
![image](/uploads/fcbb716228f064c5cde2f8231a534e15...To replicate -
1. Navigate to https://dmaster.demo.civicrm.org/civicrm/case/search?reset=1
2. Search for cases. Select all results (ts_all radio button) => Update multiple cases action
![image](/uploads/fcbb716228f064c5cde2f8231a534e15/image.png)
3. Select Profile on the next step and hit Continue;
![image](/uploads/cb5fb171efd98f5014e5c822f367f717/image.png)https://lab.civicrm.org/dev/core/-/issues/2869Api4 explorer - Clicking the Debug checkbox on or off doesn't change the samp...2023-09-30T05:15:09ZDaveDApi4 explorer - Clicking the Debug checkbox on or off doesn't change the sample codeI think it should add setDebug()?
Issue needs debugging. I tried clicking the debug checkbox to ... oh, right.
FYI @colemanwI think it should add setDebug()?
Issue needs debugging. I tried clicking the debug checkbox to ... oh, right.
FYI @colemanw