Search the Community

Showing results for tags 'отчёты'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Found 3 results

  1. Сегодня столкнулся с ошибкой, присутствовавшей в SuiteCRM 7.3.2 (а возможно и в более ранних и более поздних модификациях этой CRM): Если создать новый отчет в модуле Отчеты (AOR_Reports), и одним из параметров фильтрации указать поле типа Datetime, то при построении отчета записи по этому полю не ищутся. У меня это проявилось, когда я хотел найти все Задачи, созданные за определенный день (по календарику). Вот как выглядел отчет: Таким образом у нас отчет будет состоять из трех колонок: ID записи, Название и Дата создания записи. А фильтровать данные мы по идее должны по Дате создания записей: Но если заполнить поле в колонке "Значение" инажать на кнопку "Обновить", то ничего не происходит. Записи не ищутся, хотя я точно знаю, что они есть на указанную дату. В результате разбора модуляAOR_Reports было выявлено, что непосредственно генерацией WHERE-условия для выборки по отчету занимается функцияbuild_report_query_where, находящаяся в классеAOR_Report в файлеmodules/AOR_Reports/AOR_Report.php Результатом работы функцииbuild_report_query_where являлся массив: Array ( [select] => Array ( [0] => `project_task`.id AS 'project_task_id' [1] => `project_task`.id AS 'ID0' [2] => `project_task`.name AS 'Название1' [3] => `project_task`.date_entered AS 'Дата_создания2' ) [where] => Array ( [0] => `project_task`.date_entered = '23.12.2015' [1] => project_task.deleted = 0 который потом уже далее собирался в конечный SQL-запрос: SELECT `project_task`.id AS 'project_task_id', `project_task`.id AS 'ID0', `project_task`.name AS 'Название1', `project_task`.date_entered AS 'Дата_создания2' FROM `project_task` WHERE `project_task`.date_entered = '23.12.2015' AND project_task.deleted = 0 Как мы видим,`project_task`.date_entered = '23.12.2015' - абсолютно не то, что нам надо, чтобы корректно найти данные. Мало того, что формат даты указан не верный, так еще подвешенным остается что делать с временем. Ведьdate_entered (дата создания) у нас в базе имеет значения что то типа такого: 2015-12-23 12:34:02, что никак не идентично23.12.2015, хотя по логике это должно быть наше значение. В общем нам надо преобразовать наш запрос таким образом, чтобы занчения в базе уравнялись в формате с вводимыми значениями. Я решил, что самым оптимальным будет введенное значение оставить как есть, а модернизации подвергнуть указание поля в базе данных: у нас должен на выходе получиться вот такой запрос: SELECT `project_task`.id AS 'project_task_id', `project_task`.id AS 'ID0', `project_task`.name AS 'Название1', `project_task`.date_entered AS 'Дата_создания2' FROM `project_task` WHERE DATE_FORMAT(`project_task`.date_entered, '%d.%m.%Y') = '23.12.2015' AND project_task.deleted = 0 Таким образом прибегнув к функцииDATE_FORMAT мы сможем сделать эти значения идентичными по своему формату, что позволит их начать сравнивать. Реализация: Во первых в функциюbuild_report_query_where в самый верх добавляем строку с подключением глобальной переменной$timedate, из которой мы в последствии сможем извлечь текущие настройки формата даты для текущего пользователя: /** * @param array $query * @return array */ function build_report_query_where($query = array()){ global $beanList, $app_list_strings, $sugar_config; global $timedate; а чуть дальше в этой же функции ищем строчки: if ((isset($data['source']) && $data['source'] == 'custom_fields')) { $field = $this->db->quoteIdentifier($table_alias . '_cstm') . '.' . $condition->field; $query = $this->build_report_query_join($table_alias . '_cstm', $table_alias . '_cstm', $oldAlias, $condition_module, 'custom', $query); } else { $field = $this->db->quoteIdentifier($table_alias) . '.' . $condition->field; $condition->value = date($timedate->get_date_format(), strtotime("+{$timedate->getUserUTCOffset()} minutes", strtotime($condition->value))); } Здесь переменная $field - это название нашего поля в базе данных (`project_task`.date_entered). Нам надо указать его не как просто`project_task`.date_entered, а какDATE_FORMAT(`project_task`.date_entered, '%d.%m.%Y') Для этого модернизируем этот участок кода следующим образом: if ((isset($data['source']) && $data['source'] == 'custom_fields')) { $field = $this->db->quoteIdentifier($table_alias . '_cstm') . '.' . $condition->field; $query = $this->build_report_query_join($table_alias . '_cstm', $table_alias . '_cstm', $oldAlias, $condition_module, 'custom', $query); } elseif($condition_module->field_defs[$condition->field]['type'] == 'datetime') { // Для случая, когда поле с типом Datetime $field = "DATE_FORMAT(". $this->db->quoteIdentifier($table_alias) . '.' . $condition->field.", '" . $timedate->get_cal_date_format() . "')"; } else { // Все остальные стандартные случаи $field = $this->db->quoteIdentifier($table_alias) . '.' . $condition->field; } Теперь у нас для всех полей с типом Datetime будет происходить корректное применение фильтров в Отчетах. Ну а в нашем случае получился запрос: SELECT `project_task`.id AS 'project_task_id', `project_task`.id AS 'ID0', `project_task`.name AS 'Название1', `project_task`.date_entered AS 'Дата_создания2' FROM `project_task` WHERE DATE_FORMAT(`project_task`.date_entered, '%d.%m.%Y') = '23.12.2015' AND project_task.deleted = 0 И вот его результат работы: Патч для SuiteCRM, который исправляет описанную ошибку:
  2. Сегодня столкнулся с ошибкой, присутствовавшей в SuiteCRM 7.3.2 (а возможно и в более ранних и более поздних модификациях этой CRM): Если создать новый отчет в модуле Отчеты (AOR_Reports), и одним из параметров фильтрации указать поле типа Datetime, то при построении отчета записи по этому полю не ищутся. У меня это проявилось, когда я хотел найти все Задачи, созданные за определенный день (по календарику). Вот как выглядел отчет: Таким образом у нас отчет будет состоять из трех колонок: ID записи, Название и Дата создания записи. А фильтровать данные мы по идее должны по Дате создания записей: Но если заполнить поле в колонке "Значение" инажать на кнопку "Обновить", то ничего не происходит. Записи не ищутся, хотя я точно знаю, что они есть на указанную дату. В результате разбора модуляAOR_Reports было выявлено, что непосредственно генерацией WHERE-условия для выборки по отчету занимается функцияbuild_report_query_where, находящаяся в классеAOR_Report в файлеmodules/AOR_Reports/AOR_Report.php Результатом работы функцииbuild_report_query_where являлся массив: Array ( [select] => Array ( [0] => `project_task`.id AS 'project_task_id' [1] => `project_task`.id AS 'ID0' [2] => `project_task`.name AS 'Название1' [3] => `project_task`.date_entered AS 'Дата_создания2' ) [where] => Array ( [0] => `project_task`.date_entered = '23.12.2015' [1] => project_task.deleted = 0 который потом уже далее собирался в конечный SQL-запрос: SELECT `project_task`.id AS 'project_task_id', `project_task`.id AS 'ID0', `project_task`.name AS 'Название1', `project_task`.date_entered AS 'Дата_создания2' FROM `project_task` WHERE `project_task`.date_entered = '23.12.2015' AND project_task.deleted = 0 Как мы видим,`project_task`.date_entered = '23.12.2015' - абсолютно не то, что нам надо, чтобы корректно найти данные. Мало того, что формат даты указан не верный, так еще подвешенным остается что делать с временем. Ведьdate_entered (дата создания) у нас в базе имеет значения что то типа такого: 2015-12-23 12:34:02, что никак не идентично23.12.2015, хотя по логике это должно быть наше значение. В общем нам надо преобразовать наш запрос таким образом, чтобы занчения в базе уравнялись в формате с вводимыми значениями. Я решил, что самым оптимальным будет введенное значение оставить как есть, а модернизации подвергнуть указание поля в базе данных: у нас должен на выходе получиться вот такой запрос: SELECT `project_task`.id AS 'project_task_id', `project_task`.id AS 'ID0', `project_task`.name AS 'Название1', `project_task`.date_entered AS 'Дата_создания2' FROM `project_task` WHERE DATE_FORMAT(`project_task`.date_entered, '%d.%m.%Y') = '23.12.2015' AND project_task.deleted = 0 Таким образом прибегнув к функцииDATE_FORMAT мы сможем сделать эти значения идентичными по своему формату, что позволит их начать сравнивать. Реализация: Во первых в функциюbuild_report_query_where в самый верх добавляем строку с подключением глобальной переменной$timedate, из которой мы в последствии сможем извлечь текущие настройки формата даты для текущего пользователя: /** * @param array $query * @return array */ function build_report_query_where($query = array()){ global $beanList, $app_list_strings, $sugar_config; global $timedate; а чуть дальше в этой же функции ищем строчки: if ((isset($data['source']) && $data['source'] == 'custom_fields')) { $field = $this->db->quoteIdentifier($table_alias . '_cstm') . '.' . $condition->field; $query = $this->build_report_query_join($table_alias . '_cstm', $table_alias . '_cstm', $oldAlias, $condition_module, 'custom', $query); } else { $field = $this->db->quoteIdentifier($table_alias) . '.' . $condition->field; $condition->value = date($timedate->get_date_format(), strtotime("+{$timedate->getUserUTCOffset()} minutes", strtotime($condition->value))); } Здесь переменная $field - это название нашего поля в базе данных (`project_task`.date_entered). Нам надо указать его не как просто`project_task`.date_entered, а какDATE_FORMAT(`project_task`.date_entered, '%d.%m.%Y') Для этого модернизируем этот участок кода следующим образом: if ((isset($data['source']) && $data['source'] == 'custom_fields')) { $field = $this->db->quoteIdentifier($table_alias . '_cstm') . '.' . $condition->field; $query = $this->build_report_query_join($table_alias . '_cstm', $table_alias . '_cstm', $oldAlias, $condition_module, 'custom', $query); } elseif($condition_module->field_defs[$condition->field]['type'] == 'datetime') { // Для случая, когда поле с типом Datetime $field = "DATE_FORMAT(". $this->db->quoteIdentifier($table_alias) . '.' . $condition->field.", '" . $timedate->get_cal_date_format() . "')"; } else { // Все остальные стандартные случаи $field = $this->db->quoteIdentifier($table_alias) . '.' . $condition->field; } Теперь у нас для всех полей с типом Datetime будет происходить корректное применение фильтров в Отчетах. Ну а в нашем случае получился запрос: SELECT `project_task`.id AS 'project_task_id', `project_task`.id AS 'ID0', `project_task`.name AS 'Название1', `project_task`.date_entered AS 'Дата_создания2' FROM `project_task` WHERE DATE_FORMAT(`project_task`.date_entered, '%d.%m.%Y') = '23.12.2015' AND project_task.deleted = 0 И вот его результат работы:
  3. Version 1.0.0

    7 downloads

    Патч исправляет ошибку в работе модуля Отчёты: поиск по дате и поиск в диапазоне. Про ручное устранение этой ошибки я писал в статье: Но потом родилась мысль: а почему бы не начать писать расширения под SuiteCRM? Скачать и установить расширении ведь удобнее, чем руками лазить по коду! Вот так и родилась эта идея. И вот предлагаю дебютный мой выход в этом направлении: Патч устраняет указанные выше недостатки. Кстати, для желающих поучавствовать вот проект на Bitbucket.org:http://bitbucket.org/crmhosting/suitecrm_bugfix_reports