I've already reported this as a bug but would love to help solve this - am hoping you guys can help point me in the right direction. (https://lab.civicrm.org/dev/core/issues/893)

When 'Record generated letters' is set to "Multiple activities (one per contact)" and you print/merge documents, they don't file on the correct contact.

With a list of cases, select all and then choose Print/merge document. The letters are generated in case ID order but they are filed in the order your search screen was last sorted.

For example, the letters are issued in this order:

  • Case 1 - Lawrence Ivanov
  • Case 2 - Carlos Jacobs
  • Case 3 - Sanford Blackwell

But, the default sort if alpha by contact last name:

  • Sanford Blackwell (gets Lawrence Ivanov's - case 1 activity)
  • Lawrence Ivanov (gets Carlos Jacob's - case 2 activity)
  • Carlos Jacobs (gets Sanford Blackwell's - case 3 activity)

I think it can be tracked to the Contact > Form > Task > PDFLetterCommon.php file but I'm having a little trouble wrapping my brain around what's happening in the for each statement in the 'multiple' case.


2 Answers 2


At long last, I have a fix to share. Here's the PR that was just merged https://github.com/civicrm/civicrm-core/pull/15626

  • Yay! Thanks for sticking with it.
    – Demerit
    Oct 29, 2019 at 22:12

I think the problem might be the way it gets the contact list. It does it in a way that might work sometimes but might not other times.

What it does is gets the list of cases from your selection, which is fine, but then later it retrieves the associated clients in CRM_Case_Form_Task::setContactIds by calling a function CRM_Core_DAO::getContactIDsFromComponent which does it like so:

SELECT contact_id FROM civicrm_case_contact WHERE case_id IN (1,2,3);

The thing is I don't think there's any guarantee the results will be returned in the 1,2,3 order, but they might be returned in order sometimes. One solution is slower but should work:

Change these lines

$IDs = implode(',', $componentIDs); $query = " SELECT contact_id FROM $tableName WHERE $idField IN ( $IDs ) "; $dao = CRM_Core_DAO::executeQuery($query); while ($dao->fetch()) { $contactIDs[] = $dao->contact_id; }


$query = " SELECT contact_id FROM $tableName WHERE $idField = %1 "; foreach( $componentIDs as $id ) { $query_params = array(1 => array($id, 'Integer')); $dao = CRM_Core_DAO::executeQuery($query, $query_params); while ($dao->fetch()) { $contactIDs[] = $dao->contact_id; } }

I haven't tested that. One problem would still be if you had a case with more than one client, but that would also be a problem currently.

  • Thanks for the help! I tested this but to no effect. I think I have a grasp on what you're saying - the current query that originates from Case_Form_Task and touches Core_DAO, doesn't necessarily return items in any order. But so far for me for PDF generation, all I've experienced is it returning items in case order. What I think is going wrong is that the list of case_ids it's pulling from the form is not then related to what contact the case belongs to. It just has a list of 3 cases (1, 2, 3) and it attaches them to the 3 contacts in whatever order the form is in (3,1,2 etc.)
    – RayWright
    Apr 29, 2019 at 18:37
  • Follow up: agreed that cases with more than one client could cause problems (with or without a fix to this), we don't currently have any cases set up that way.
    – RayWright
    Apr 29, 2019 at 18:38
  • If you're able to set up a debugger (e.g. xdebug + an IDE) you can trace what it's doing and that might help find the problem more exactly. e.g. xdebug.org/docs/install#configure-php.
    – Demerit
    Apr 29, 2019 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.