Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CATL-1114: Support Cases In Scheduled Reminders #31

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions CRM/Case/ActionMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public static function onRegisterActionMappings(\Civi\ActionSchedule\Event\Mappi
'entity_value_label' => ts('Case Type'),
'entity_status' => 'case_status',
'entity_status_label' => ts('Case Status'),
'entity_date_start' => 'case_start_date',
'entity_date_end' => 'case_end_date',
'entity_date_start' => 'start_date',
'entity_date_end' => 'end_date',
)));
}

Expand Down Expand Up @@ -84,6 +84,17 @@ public function getRecipientTypes() {
return array('case_roles' => 'Case Roles');
}

/**
* @inheritdoc
*/
public function getDateFields() {
return [
'start_date' => ts('Case Start Date'),
'end_date' => ts('Case End Date'),
'case_status' => ts('Case Status Change'),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Case status is not a date field, how come it is returned alongside other date fields?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case_status is not directly a date field but it is. It is the date on which that case status was updated.
So we dont have a direct way currently to find this date (its not stored).
Jamie said we would need to have discussions with core team to maybe add a new field or improve how case status changes are tracked.
But for now (before my last day), I was asked to see if there is a way to support this and using case activity was the only way I could do this.
I have explained this in the ticket CATL-1114.

];
}

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -126,7 +137,40 @@ public function createQuery($schedule, $phase, $defaultParams) {
throw new CRM_Core_Exception("Invalid date field");
}

$query['casDateField'] = $schedule->start_action_date;
if ($schedule->start_action_date == 'case_status') {
Copy link

@tunbola tunbola Sep 23, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think this looks right, for a date field to be returning the case status. Can you explain why it is like this? IT is a PR going to core and if it's not proper, we might not be able to get this in. Looks more like a hack.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the case_status that is used here. I have changed the name 'case_status' to 'case_status_change_date' to be a little better.
This might look a little hacky because we dont have a better way to get when a case status has changed in civicrm core currently.
Pls also see this comment #31 (comment)

// For this case, we use activity of type 'Change Case Status' and check if the case status has been changed
// from an indifferent status to the one configured in scheduled reminder.
$query->join('cac', "INNER JOIN civicrm_case_activity cac ON cac.case_id = c.id");
$query->where("cac.id = (SELECT MAX(cac2.id) FROM civicrm_case_activity cac2 WHERE cac2.case_id = c.id)");

$query->join('act', "INNER JOIN civicrm_activity act ON act.id = cac.activity_id");
$query->join('opt', "INNER JOIN civicrm_option_value opt ON opt.value = act.activity_type_id");
$query->join('opg', "INNER JOIN civicrm_option_group opg ON opg.id = opt.option_group_id");
$query->where("opt.name = 'Change Case Status'");
$query->where("opg.name = 'activity_type'");

// If start condition is 'after' we check for completed activity
// and if 'before' we check for scheduled activity.
if ($schedule->start_action_condition == 'after') {
$activityStatus = 'Completed';
}
else {
$activityStatus = 'Scheduled';
}

// Subquery to check for activity status.
$subQuery = \CRM_Utils_SQL_Select::from("civicrm_option_value opt2")->select('opt2.value');
$subQuery->join('opg2', 'INNER JOIN civicrm_option_group opg2 ON opg2.id = opt2.option_group_id');
$subQuery->where("opt2.name = @activityStatus")->param('activityStatus', $activityStatus);
$subQuery->where("opg2.name = 'activity_status'");
$query->where("act.status_id = (" . $subQuery->toSQL() . ")");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we build the activity statuses from this CRM_Activity_BAO_Activity::buildOptions('status_id') and use that in the query for the IN rather than using a subquery

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried using that but I cant really get the query result that I am looking. Maybe you can explain a bit more on that subquery part..


$query['casDateField'] = 'act.activity_date_time';
}
else {
$query['casDateField'] = 'c.' . $schedule->start_action_date;
}

$query['casAddlCheckFrom'] = 'civicrm_case c';
$query['casContactIdField'] = 'ct.id';
$query['casEntityIdField'] = 'r.case_id';
Expand Down