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

CRM-18081 Allow search of active relationships during a custom range of dates #10333

Merged
merged 3 commits into from
Jun 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
61 changes: 61 additions & 0 deletions CRM/Contact/BAO/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,8 @@ public function whereClauseSingle(&$values, $apiEntity = NULL) {
case 'relation_start_date_low':
case 'relation_end_date_high':
case 'relation_end_date_low':
case 'relation_active_period_date_high':
case 'relation_active_period_date_low':
case 'relation_target_name':
case 'relation_status':
case 'relation_date_low':
Expand Down Expand Up @@ -4130,6 +4132,7 @@ public function relationship(&$values) {
}

$this->addRelationshipDateClauses($grouping, $where);
$this->addRelationshipActivePeriodClauses($grouping, $where);
if (!empty($relationType) && !empty($rType) && isset($rType->id)) {
$where[$grouping][] = 'civicrm_relationship.relationship_type_id = ' . $rType->id;
}
Expand Down Expand Up @@ -4194,6 +4197,64 @@ public function addRelationshipDateClauses($grouping, &$where) {
}
}

/**
* Add start & end active period criteria in
* @param string $grouping
* @param array $where
* = array to add where clauses to, in case you are generating a temp table.
* not the main query.
*/
public function addRelationshipActivePeriodClauses($grouping, &$where) {
$dateValues = array();
$dateField = 'active_period_date';

$dateValueLow = $this->getWhereValues('relation_active_period_date_low', $grouping);
$dateValueHigh = $this->getWhereValues('relation_active_period_date_high', $grouping);
$dateValueLowFormated = $dateValueHighFormated = NULL;
if (!empty($dateValueLow) && !empty($dateValueHigh)) {
$dateValueLowFormated = date('Ymd', strtotime($dateValueLow[2]));
$dateValueHighFormated = date('Ymd', strtotime($dateValueHigh[2]));
$this->_qill[$grouping][] = (ts('Relationship was active between')) . " " . CRM_Utils_Date::customFormat($dateValueLowFormated) . " and " . CRM_Utils_Date::customFormat($dateValueHighFormated);
}
elseif (!empty($dateValueLow)) {
$dateValueLowFormated = date('Ymd', strtotime($dateValueLow[2]));
$this->_qill[$grouping][] = (ts('Relationship was active after')) . " " . CRM_Utils_Date::customFormat($dateValueLowFormated);
}
elseif (!empty($dateValueHigh)) {
$dateValueHighFormated = date('Ymd', strtotime($dateValueHigh[2]));
$this->_qill[$grouping][] = (ts('Relationship was active before')) . " " . CRM_Utils_Date::customFormat($dateValueHighFormated);
}

if ($activePeriodClauses = self::getRelationshipActivePeriodClauses($dateValueLowFormated, $dateValueHighFormated, TRUE)) {
$where[$grouping][] = $activePeriodClauses;
}
}

/**
* Get start & end active period criteria
*/
public static function getRelationshipActivePeriodClauses($from, $to, $forceTableName) {
$tableName = $forceTableName ? 'civicrm_relationship.' : '';
if (!is_null($from) && !is_null($to)) {
return '(((' . $tableName . 'start_date >= ' . $from . ' AND ' . $tableName . 'start_date <= ' . $to . ') OR
(' . $tableName . 'end_date >= ' . $from . ' AND ' . $tableName . 'end_date <= ' . $to . ') OR
(' . $tableName . 'start_date <= ' . $from . ' AND ' . $tableName . 'end_date >= ' . $to . ' )) OR
(' . $tableName . 'start_date IS NULL AND ' . $tableName . 'end_date IS NULL) OR
(' . $tableName . 'start_date IS NULL AND ' . $tableName . 'end_date >= ' . $from . ') OR
(' . $tableName . 'end_date IS NULL AND ' . $tableName . 'start_date <= ' . $to . '))';
}
elseif (!is_null($from)) {
return '((' . $tableName . 'start_date >= ' . $from . ') OR
(' . $tableName . 'start_date IS NULL AND ' . $tableName . 'end_date IS NULL) OR
(' . $tableName . 'start_date IS NULL AND ' . $tableName . 'end_date >= ' . $from . '))';
}
elseif (!is_null($to)) {
return '((' . $tableName . 'start_date <= ' . $to . ') OR
(' . $tableName . 'start_date IS NULL AND ' . $tableName . 'end_date IS NULL) OR
(' . $tableName . 'end_date IS NULL AND ' . $tableName . 'start_date <= ' . $to . '))';
}
}

/**
* Default set of return properties.
*
Expand Down
2 changes: 2 additions & 0 deletions CRM/Contact/Form/Search/Criteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ public static function relationship(&$form) {
CRM_Core_Form_Date::buildDateRange($form, 'relation_start_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);
CRM_Core_Form_Date::buildDateRange($form, 'relation_end_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);

CRM_Core_Form_Date::buildDateRange($form, 'relation_active_period_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);

// Add reltionship dates
CRM_Core_Form_Date::buildDateRange($form, 'relation_date', 1, '_low', '_high', ts('From:'), FALSE, FALSE);

Expand Down
49 changes: 48 additions & 1 deletion CRM/Report/Form/Contact/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,10 @@ public function __construct() {
'title' => ts('End Date'),
'type' => CRM_Utils_Type::T_DATE,
),
'active_period_date' => array(
'title' => ts('Active Period'),
'type' => CRM_Utils_Type::T_DATE,
),
),
'grouping' => 'relation-fields',
),
Expand Down Expand Up @@ -438,7 +442,12 @@ public function where() {
$from = CRM_Utils_Array::value("{$fieldName}_from", $this->_params);
$to = CRM_Utils_Array::value("{$fieldName}_to", $this->_params);

$clause = $this->dateClause($field['name'], $relative, $from, $to, $field['type']);
if ($fieldName == 'active_period_date') {
$clause = $this->activeClause($field['name'], $relative, $from, $to, $field['type']);
}
else {
$clause = $this->dateClause($field['name'], $relative, $from, $to, $field['type']);
}
}
else {
$op = CRM_Utils_Array::value("{$fieldName}_op", $this->_params);
Expand Down Expand Up @@ -774,4 +783,42 @@ public function buildValidityQuery($valid) {
return $clause;
}

/**
* Get SQL where clause for a active period field.
*
* @param string $fieldName
* @param string $relative
* @param string $from
* @param string $to
* @param string $type
* @param string $fromTime
* @param string $toTime
*
* @return null|string
*/
public function activeClause(
$fieldName,
$relative, $from, $to, $type = NULL, $fromTime = NULL, $toTime = NULL
) {
$clauses = array();
if (in_array($relative, array_keys($this->getOperationPair(CRM_Report_Form::OP_DATE)))) {
return NULL;
}

list($from, $to) = $this->getFromTo($relative, $from, $to, $fromTime, $toTime);

if ($from) {
$from = ($type == CRM_Utils_Type::T_DATE) ? substr($from, 0, 8) : $from;
}

if ($to) {
$to = ($type == CRM_Utils_Type::T_DATE) ? substr($to, 0, 8) : $to;
}

if ($from || $to) {
return CRM_Contact_BAO_Query::getRelationshipActivePeriodClauses($from, $to, FALSE);
}
return NULL;
}

}
8 changes: 8 additions & 0 deletions templates/CRM/Contact/Form/Search/Advanced.hlp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@
<p>{ts}Use this filter to limit search results to relationships where the related contacts are part of a specific group or groups. For example, you might want to find all individuals who are employees ('Employee of' relationship type) of organizations which are in your 'Corporate Sponsors' group.{/ts}</p>
{/htxt}

{htxt id="id-relationship-active-period-title"}
{ts}Active Period{/ts}
{/htxt}
{htxt id="id-relationship-active-period"}
<p>{ts}Use this filter to limit search results to relationships which were active during the specified time period (e.g. this is useful if you need to search all volunteer relationships that were active during 2014).{/ts}</p>
<p>{ts}By definition a relationship is active if any of these conditions occurs: (1) Start Date <= Current Date <= End Date (2) Start Date <= Current Date and End Date is not defined (3) Start Date is not defined and Current Date <= End Date{/ts}</p>
{/htxt}

{htxt id="id-all-tags-title"}
{ts}Tags{/ts}
{/htxt}
Expand Down
6 changes: 6 additions & 0 deletions templates/CRM/Contact/Form/Search/Criteria/Relationship.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@
<tr>
{include file="CRM/Core/DateRange.tpl" fieldName="relation_end_date" from='_low' to='_high'}
</tr>
<tr>
<td colspan="2"><label>{ts}Active Period{/ts}</label> {help id="id-relationship-active-period" file="CRM/Contact/Form/Search/Advanced.hlp"}<br /></td>
</tr>
<tr>
{include file="CRM/Core/DateRange.tpl" fieldName="relation_active_period_date" from='_low' to='_high'}
</tr>
{if $relationshipGroupTree}
<tr>
<td colspan="2">
Expand Down