CRM_Activity_BAO_Query::whereClauseSingle($values, $this);
return;
+ case 'age_low':
+ case 'age_high':
case 'birth_date_low':
case 'birth_date_high':
case 'deceased_date_low':
$this->demographics($values);
return;
+ case 'age_asof_date':
+ // handled by demographics
+ return;
+
case 'log_date_low':
case 'log_date_high':
$this->modifiedDates($values);
public function demographics(&$values) {
list($name, $op, $value, $grouping, $wildcard) = $values;
- if (($name == 'birth_date_low') || ($name == 'birth_date_high')) {
+ if (($name == 'age_low') || ($name == 'age_high')) {
+ $this->ageRangeQueryBuilder($values,
+ 'contact_a', 'age', 'birth_date', ts('Age')
+ );
+ }
+ elseif (($name == 'birth_date_low') || ($name == 'birth_date_high')) {
$this->dateQueryBuilder($values,
'contact_a', 'birth_date', 'birth_date', ts('Birth Date')
}
}
+
+ /**
+ * @param $values
+ * @param string $tableName
+ * @param string $fieldName
+ * @param string $dbFieldName
+ * @param $fieldTitle
+ * @param null $options
+ */
+ public function ageRangeQueryBuilder(
+ &$values,
+ $tableName, $fieldName,
+ $dbFieldName, $fieldTitle,
+ $options = NULL
+ ) {
+ list($name, $op, $value, $grouping, $wildcard) = $values;
+
+ $asofDateValues = $this->getWhereValues("{$fieldName}_asof_date", $grouping);
+ $asofDate = NULL; // will be treated as current day
+ if ($asofDateValues) {
+ $asofDate = CRM_Utils_Date::processDate($asofDateValues[2]);
+ $asofDateFormat = CRM_Utils_Date::customFormat(substr($asofDate, 0, 8));
+ $fieldTitle .= ' ' . ts('as of') . ' ' . $asofDateFormat;
+ }
+
+ if ($name == "{$fieldName}_low" ||
+ $name == "{$fieldName}_high"
+ ) {
+ if (isset($this->_rangeCache[$fieldName])) {
+ return;
+ }
+ $this->_rangeCache[$fieldName] = 1;
+
+ $secondOP = $secondPhrase = $secondValue = NULL;
+
+ if ($name == "{$fieldName}_low") {
+ $firstPhrase = ts('greater than or equal to');
+ // NB: age > X means date of birth < Y
+ $firstOP = '<=';
+ $firstDate = self::calcDateFromAge($asofDate, $value, 'min');
+
+ $secondValues = $this->getWhereValues("{$fieldName}_high", $grouping);
+ if (!empty($secondValues)) {
+ $secondOP = '>=';
+ $secondPhrase = ts('less than or equal to');
+ $secondValue = $secondValues[2];
+ $secondDate = self::calcDateFromAge($asofDate, $secondValue, 'max');
+ }
+ }
+ else {
+ $firstOP = '>=';
+ $firstPhrase = ts('less than or equal to');
+ $firstDate = self::calcDateFromAge($asofDate, $value, 'max');
+
+ $secondValues = $this->getWhereValues("{$fieldName}_low", $grouping);
+ if (!empty($secondValues)) {
+ $secondOP = '<=';
+ $secondPhrase = ts('greater than or equal to');
+ $secondValue = $secondValues[2];
+ $secondDate = self::calcDateFromAge($asofDate, $secondValue, 'min');
+ }
+ }
+
+
+ if ($secondOP) {
+ $this->_where[$grouping][] = "
+( {$tableName}.{$dbFieldName} $firstOP '$firstDate' ) AND
+( {$tableName}.{$dbFieldName} $secondOP '$secondDate' )
+";
+ $displayValue = $options ? $options[$value] : $value;
+ $secondDisplayValue = $options ? $options[$secondValue] : $secondValue;
+
+ $this->_qill[$grouping][]
+ = "$fieldTitle - $firstPhrase \"$displayValue\" " . ts('AND') . " $secondPhrase \"$secondDisplayValue\"";
+ }
+ else {
+ $this->_where[$grouping][] = "{$tableName}.{$dbFieldName} $firstOP '$firstDate'";
+ $displayValue = $options ? $options[$value] : $value;
+ $this->_qill[$grouping][] = "$fieldTitle - $firstPhrase \"$displayValue\"";
+ }
+ $this->_tables[$tableName] = $this->_whereTables[$tableName] = 1;
+ return;
+ }
+ }
+
+ public static function calcDateFromAge($asofDate, $age, $type) {
+ $date = new DateTime($asofDate);
+ if ($type == "min") {
+ // minimum age is $age: dob <= date - age "235959"
+ $date->sub(new DateInterval("P" . $age . "Y"));
+ return $date->format('Ymd') . "235959";
+ } else {
+ // max age is $age: dob >= date - (age + 1y) + 1d "000000"
+ $date->sub(new DateInterval("P" . ($age + 1) . "Y"))->add(new DateInterval("P1D"));
+ return $date->format('Ymd') . "000000";
+ }
+ }
+
/**
* Given the field name, operator, value & its data type
* builds the where Clause for the query
}
$form->addGroup($genderOptions, 'gender_id', ts('Gender'))->setAttribute('allowClear', TRUE);
+ $form->add('text', 'age_low', ts('Min Age'));
+ $form->addRule('age_low', ts('Please enter a positive integer'), 'positiveInteger');
+ $form->add('text', 'age_high', ts('Max Age'));
+ $form->addRule('age_high', ts('Please enter a positive integer'), 'positiveInteger');
+ $form->addDate('age_asof_date', ts('Age as of Date'), FALSE, array('formatType' => 'searchDate'));
+
CRM_Core_Form_Date::buildDateRange($form, 'birth_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');
CRM_Core_Form_Date::buildDateRange($form, 'deceased_date', 1, '_low', '_high', ts('From'), FALSE, FALSE, 'birth');
--- /dev/null
+{*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.6 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2014 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*}
+{*this is included inside a table row*}
+<td>
+ <span class="crm-age-range">
+ <span class="crm-age-range-min">
+ {assign var=minName value=$fieldName|cat:$from}
+ {$form.$minName.label}
+ {$form.$minName.html}
+ </span>
+ <span class="crm-age-range-max">
+ {assign var=maxName value=$fieldName|cat:$to}
+ {$form.$maxName.label}
+ {$form.$maxName.html}
+ </span>
+ </span>
+</td>
+<td>
+ <span class="crm-age-range-asofdate">
+ {assign var=dateName value=$fieldName|cat:$date}
+ {$form.$dateName.label}
+ {include file="CRM/common/jcalendar.tpl" elementName=$dateName}
+ </span>
+ {literal}
+ <script type="text/javascript">
+ cj(".crm-age-range").change(function() {
+ if (cj('.crm-age-range-min :text').val() || cj('.crm-age-range-max :text').val()) {
+ cj(".crm-age-range-asofdate").show();
+ } else {
+ cj(".crm-age-range-asofdate").hide();
+ }
+ }).change();
+ </script>
+ {/literal}
+</td>