Skip to content

Commit

Permalink
Merge pull request civicrm#15709 from seamuslee001/report_jcalender_u…
Browse files Browse the repository at this point in the history
…pgrade

dev/core#561 Convert Reports from jcalender to datepicker format
  • Loading branch information
seamuslee001 authored Mar 20, 2020
2 parents 6769b88 + 6d6630c commit 1bb6e83
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 40 deletions.
16 changes: 13 additions & 3 deletions CRM/Core/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -1335,14 +1335,24 @@ public function addDateRange($name, $from = '_from', $to = '_to', $label = 'From
* @param bool $required
* @param string $fromLabel
* @param string $toLabel
* @param array $additionalOptions
* @param string $to string to append to the to field.
* @param string $from string to append to the from field.
*/
public function addDatePickerRange($fieldName, $label, $isDateTime = FALSE, $required = FALSE, $fromLabel = 'From', $toLabel = 'To') {
public function addDatePickerRange($fieldName, $label, $isDateTime = FALSE, $required = FALSE, $fromLabel = 'From', $toLabel = 'To', $additionalOptions = [],
$to = '_high', $from = '_low') {

$options = [
'' => ts('- any -'),
0 => ts('Choose Date Range'),
] + CRM_Core_OptionGroup::values('relative_date_filters');

if ($additionalOptions) {
foreach ($additionalOptions as $key => $optionLabel) {
$options[$key] = $optionLabel;
}
}

$this->add('select',
"{$fieldName}_relative",
$label,
Expand All @@ -1352,8 +1362,8 @@ public function addDatePickerRange($fieldName, $label, $isDateTime = FALSE, $req
);
$attributes = ['format' => 'searchDate'];
$extra = ['time' => $isDateTime];
$this->add('datepicker', $fieldName . '_low', ts($fromLabel), $attributes, $required, $extra);
$this->add('datepicker', $fieldName . '_high', ts($toLabel), $attributes, $required, $extra);
$this->add('datepicker', $fieldName . $from, ts($fromLabel), $attributes, $required, $extra);
$this->add('datepicker', $fieldName . $to, ts($toLabel), $attributes, $required, $extra);
}

/**
Expand Down
52 changes: 22 additions & 30 deletions CRM/Report/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -1345,14 +1345,12 @@ public function addFilters() {

case CRM_Report_Form::OP_DATE:
// build datetime fields
CRM_Core_Form_Date::buildDateRange($this, $fieldName, $count, '_from', '_to', ts('From:'), FALSE, $operations);
$count++;
$this->addDatePickerRange($fieldName, $field['title'], FALSE, FALSE, 'From', 'To', $operations, '_to', '_from');
break;

case CRM_Report_Form::OP_DATETIME:
// build datetime fields
CRM_Core_Form_Date::buildDateRange($this, $fieldName, $count, '_from', '_to', ts('From:'), FALSE, $operations, 'searchDate', TRUE);
$count++;
$this->addDatePickerRange($fieldName, $field['title'], TRUE, FALSE, 'From', 'To', $operations, '_to', '_from');
break;

case CRM_Report_Form::OP_INT:
Expand Down Expand Up @@ -2168,16 +2166,17 @@ public function dateClause(
return "( {$fieldName} {$sqlOP} )";
}

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

if ($from) {
$clauses[] = "( {$fieldName} >= $from )";
$clauses[] = "( {$fieldName} >= " . date('YmdHis', strtotime($from)) . ')';
}

if ($to) {
$clauses[] = "( {$fieldName} <= {$to} )";
$clauses[] = "( {$fieldName} <= " . date('YmdHis', strtotime($to)) . ')';
}

if (!empty($clauses)) {
return implode(' AND ', $clauses);
}
Expand All @@ -2199,13 +2198,10 @@ public function dateClause(
* @return array
*/
public function getFromTo($relative, $from, $to, $fromTime = NULL, $toTime = NULL) {
if (empty($toTime)) {
// odd legacy behaviour to treat NULL as 'end of the day'
// recommend updating reports to call CRM_Utils_Date::getFromTo
//directly (default on the function is the actual default there).
$toTime = '235959';
if (!empty($fromTime) || !empty($toTime)) {
throw new CRM_Core_Exception('Report template needs to be updated as getFromTo no longer supports fromTime or ToTime Parameters');
}
return CRM_Utils_Date::getFromTo($relative, $from, $to, $fromTime, $toTime);
return CRM_Utils_Date::getFromTo($relative, $from, $to);
}

/**
Expand Down Expand Up @@ -3295,21 +3291,19 @@ public function filterStat(&$statistics) {
CRM_Utils_Array::value('operatorType', $field) !=
CRM_Report_Form::OP_MONTH
) {
list($from, $to)
= $this->getFromTo(
CRM_Utils_Array::value("{$fieldName}_relative", $this->_params),
CRM_Utils_Array::value("{$fieldName}_from", $this->_params),
CRM_Utils_Array::value("{$fieldName}_to", $this->_params),
CRM_Utils_Array::value("{$fieldName}_from_time", $this->_params),
CRM_Utils_Array::value("{$fieldName}_to_time", $this->_params)
);
$from_time_format = !empty($this->_params["{$fieldName}_from_time"]) ? 'h' : 'd';
$from = CRM_Utils_Date::customFormat($from, NULL, [$from_time_format]);

$to_time_format = !empty($this->_params["{$fieldName}_to_time"]) ? 'h' : 'd';
$to = CRM_Utils_Date::customFormat($to, NULL, [$to_time_format]);
$from = $this->_params["{$fieldName}_from"] ?? NULL;
$to = $this->_params["{$fieldName}_to"] ?? NULL;
if (!empty($this->_params["{$fieldName}_relative"])) {
list($from, $to) = CRM_Utils_Date::getFromTo($this->_params["{$fieldName}_relative"], NULL, NULL);
}

if ($from || $to) {
if ($from) {
$from = date('l j F Y, g:iA', strtotime($from));
}
if ($to) {
$to = date('l j F Y, g:iA', strtotime($to));
}
$statistics['filters'][] = [
'title' => $field['title'],
'value' => ts("Between %1 and %2", [1 => $from, 2 => $to]),
Expand Down Expand Up @@ -5954,9 +5948,7 @@ protected function generateFilterClause($field, $fieldName) {
$relative = $this->_params["{$fieldName}_relative"] ?? NULL;
$from = $this->_params["{$fieldName}_from"] ?? NULL;
$to = $this->_params["{$fieldName}_to"] ?? NULL;
$fromTime = $this->_params["{$fieldName}_from_time"] ?? NULL;
$toTime = $this->_params["{$fieldName}_to_time"] ?? NULL;
return $this->dateClause($field['dbAlias'], $relative, $from, $to, $field['type'], $fromTime, $toTime);
return $this->dateClause($field['dbAlias'], $relative, $from, $to, $field['type']);
}
}
else {
Expand Down
7 changes: 2 additions & 5 deletions CRM/Report/Form/Contact/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -821,21 +821,18 @@ public function buildValidityQuery($valid) {
* @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
) {
$relative, $from, $to, $type = NULL) {
$clauses = [];
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);
list($from, $to) = $this->getFromTo($relative, $from, $to);

if ($from) {
$from = ($type == CRM_Utils_Type::T_DATE) ? substr($from, 0, 8) : $from;
Expand Down
61 changes: 61 additions & 0 deletions CRM/Upgrade/Incremental/php/FiveTwentyFive.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,65 @@ public function setPostUpgradeMessage(&$postUpgradeMessage, $rev) {
// return TRUE;
// }

/**
* Upgrade function.
*
* @param string $rev
*/
public function upgrade_5_25_alpha1($rev) {
$this->addTask(ts('Upgrade DB to %1: SQL', [1 => $rev]), 'runSql', $rev);
$this->addTask('Convert Report Form dates from jcalander to datepicker', 'convertReportsJcalendarToDatePicker');
}

/**
* Convert date fields stored in civicrm_report_instance to that format for datepicker
*/
public static function convertReportsJcalendarToDatePicker() {
$date_fields = [];
$reports = CRM_Core_DAO::executeQuery("SELECT id FROM civicrm_report_instance WHERE form_values like '%relative%'");
while ($reports->fetch()) {
$report = civicrm_api3('ReportInstance', 'getsingle', ['id' => $reports->id]);
$reportFormValues = unserialize($report['form_values']);
foreach ($reportFormValues as $index => $value) {
if (strpos($index, '_relative') !== FALSE) {
$date_fields[] = str_replace('_relative', '', $index);
}
}
foreach ($date_fields as $date_field) {
foreach ($reportFormValues as $index => $value) {
if ($index === $date_field . '_to' || $index === $date_field . '_from') {
$isEndOfDay = strpos($index, '_to') !== FALSE ? TRUE : FALSE;
// If We have stored in the database hours minutes seconds use them
if (!empty($reportFormValues[$index . '_time'])) {
$time = $reportFormValues[$index . '_time'];
}
else {
$time = NULL;
}
$dateValue = $value;
if (date('Y-m-d', strtotime($dateValue)) !== $dateValue
&& date('Y-m-d H:i:s', strtotime($dateValue)) !== $dateValue
&& !empty($dateValue)
) {
$dateValue = date('Y-m-d H:i:s', strtotime(CRM_Utils_Date::processDate($value, $time)));
if ($isEndOfDay) {
$dateValue = str_replace('00:00:00', '23:59:59', $dateValue);
}
}
$reportFormValues[$index] = $dateValue;
// Now remove the time keys as no longer needed.
if (!empty($reportFormValues[$index . '_time'])) {
unset($reportFormValues[$index . '_time']);
}
}
}
if (serialize($reportFormValues) !== $report['form_values']) {
civicrm_api3('ReportInstance', 'create', ['id' => $report['id'], 'form_values' => serialize($reportFormValues)]);
}
$date_fields = [];
}
}
return TRUE;
}

}
4 changes: 3 additions & 1 deletion templates/CRM/Core/DatePickerRangeWrapper.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@
{* Wrapper around DatePickerRange TPL file *}
<td {if $colspan} colspan="{$colspan}" {else} colspan="2" {/if} {if $class} class="{$class}" {/if}>
{assign var='hideRelativeLabel' value=$hideRelativeLabel|default:0}
{include file="CRM/Core/DatePickerRange.tpl" fieldName=$fieldName hideRelativeLabel=$hideRelativeLabel}
{assign var='from' value=$from|default:'_low'}
{assign var='to' value=$to|default:'_high'}
{include file="CRM/Core/DatePickerRange.tpl" fieldName=$fieldName hideRelativeLabel=$hideRelativeLabel to=$to from=$from}
</td>
2 changes: 1 addition & 1 deletion templates/CRM/Report/Form/Tabs/Filters.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
{if $field.operatorType & 4}
<tr class="report-contents crm-report crm-report-criteria-filter crm-report-criteria-filter-{$tableName}">
<td class="label report-contents">{$field.title}</td>
{include file="CRM/Core/DateRange.tpl" fieldName=$fieldName from='_from' to='_to'}
{include file="CRM/Core/DatePickerRangeWrapper.tpl" fieldName=$fieldName hideRelativeLabel=1, from='_from' to='_to'}
</tr>
{elseif $form.$fieldOp.html}
<tr class="report-contents crm-report crm-report-criteria-filter crm-report-criteria-filter-{$tableName}" {if $field.no_display} style="display: none;"{/if}>
Expand Down
137 changes: 137 additions & 0 deletions tests/phpunit/CRM/Upgrade/Incremental/BaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,4 +536,141 @@ public function testFixOptionGroupNameWithFixedNameInDatabase() {
$this->callAPISuccess('OptionGroup', 'delete', ['id' => $optionGroup2['id']]);
}

/**
* Test conversion between jcalendar and datepicker in reports
*/
public function testReportFormConvertDatePicker() {
$report = $this->callAPISuccess('ReportInstance', 'create', [
'report_id' => 'contribute/detail',
'form_values' => [
'fields' => [
'sort_name' => 1,
'email' => 1,
'phone' => 1,
'financial_type_id' => 1,
'receive_date' => 1,
'total_amount' => 1,
'country_id' => 1,
],
'sort_name_op' => 'has',
'sort_name_value' => '',
'id_min' => '',
'id_max' => '',
'id_op' => 'lte',
'id_value' => '',
'contact_type_op' => 'in',
'contact_type_value' => [],
'contact_sub_type_op' => 'in',
'contact_sub_type_value' => [],
'is_deleted_op' => 'eq',
'is_deleted_value' => 0,
'preferred_language_op' => 'in',
'preferred_language_value' => [],
'do_not_email_op' => 'eq',
'do_not_email_value' => '',
'do_not_phone_op' => 'eq',
'do_not_phone_value' => '',
'do_not_mail_op' => 'eq',
'do_not_mail_value' => '',
'do_not_sms_op' => 'eq',
'do_not_sms_value' => '',
'is_opt_out_op' => 'eq',
'is_opt_out_value' => '',
'first_name_op' => 'has',
'first_name_value' => '',
'prefix_id_op' => 'in',
'prefix_id_value' => [],
'suffix_id_op' => 'in',
'suffix_id_value' => [],
'gender_id_op' => 'in',
'gender_id_value' => [],
'birth_date_relative' => '',
'birth_date_from' => '',
'birth_date_to' => '',
'is_deceased_op' => 'eq',
'is_deceased_value' => '',
'contribution_or_soft_op' => 'eq',
'contribution_or_soft_value' => 'contributions_only',
'receive_date_relative' => 0,
'receive_date_from' => '11/01/1991',
'receive_date_to' => '',
'thankyou_date_relative' => '',
'thankyou_date_from' => '',
'thankyou_date_to' => '',
'contribution_source_op' => 'has',
'contribution_source_value' => '',
'currency_op' => 'in',
'currency_value' => [],
'non_deductible_amount_min' => '',
'non_deductible_amount_max' => '',
'non_deductible_amount_op' => 'lte',
'non_deductible_amount_value' => '',
'financial_type_id_op' => 'in',
'financial_type_id_value' => [],
'contribution_page_id_op' => 'in',
'contribution_page_id_value' => [],
'payment_instrument_id_op' => 'in',
'payment_instrument_id_value' => [],
'contribution_status_id_op' => 'in',
'contribution_status_id_value' => [0 => 1],
'total_amount_min' => '',
'total_amount_max' => '',
'total_amount_op' => 'lte',
'total_amount_value' => '',
'cancel_date_relative' => '',
'cancel_date_from' => '',
'cancel_date_to' => '',
'cancel_reason_op' => 'has',
'cancel_reason_value' => '',
'soft_credit_type_id_op' => 'in',
'soft_credit_type_id_value' => [],
'card_type_id_op' => 'in',
'card_type_id_value' => [],
'ordinality_op' => 'in',
'ordinality_value' => [],
'note_value' => '',
'street_address_op' => 'has',
'street_address_value' => '',
'postal_code_op' => 'has',
'postal_code_value' => '',
'city_op' => 'has',
'city_value' => '',
'country_id_op' => 'in',
'country_id_value' => [],
'state_province_id_op' => 'in',
'state_province_id_value' => [],
'county_id_op' => 'in',
'county_id_value' => [],
'tagid_op' => 'in',
'tagid_value' => [],
'gid_op' => 'in',
'gid_value' => [],
'group_bys' => ['contribution_id' => 1],
'order_bys' => [
1 => [
'column' => 'sort_name',
'order' => 'ASC',
],
],
'description' => 'Lists specific contributions by criteria including contact, time period, contribution type, contributor location, etc. Contribution summary report points to this report for contribution details.',
'email_subject' => '',
'email_to' => '',
'email_cc' => '',
'row_count' => '',
'view_mode' => 'criteria',
'cache_minutes' => 60,
'permission' => 'access CiviContribute',
'parent_id' => '',
'radio_ts' => '',
'groups' => '',
'report_id' => 'contribute/detail',
],
'title' => 'test Report',
]);
CRM_Upgrade_Incremental_php_FiveTwentyFive::convertReportsJcalendarToDatePicker();
$reportGet = $this->callAPISuccess('ReportInstance', 'getsingle', ['id' => $report['id']]);
$formValues = unserialize($reportGet['form_values']);
$this->assertEquals('1991-11-01 00:00:00', $formValues['receive_date_from']);
}

}

0 comments on commit 1bb6e83

Please sign in to comment.