new DateAndTime($user->date_format, $bean->getAttribute('start_date')),
new DateAndTime($user->date_format, $bean->getAttribute('end_date')));
}
- $where = " where l.status = 1 and l.date >= '".$period->getBeginDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
+ $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
" $user_list_part $dropdown_parts";
return $where;
}
new DateAndTime($user->date_format, $report['period_start']),
new DateAndTime($user->date_format, $report['period_end']));
}
- $where = " where l.status = 1 and l.date >= '".$period->getBeginDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
+ $where = " where l.status = 1 and l.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and l.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
" $user_list_part $dropdown_parts";
return $where;
}
new DateAndTime($user->date_format, $bean->getAttribute('start_date')),
new DateAndTime($user->date_format, $bean->getAttribute('end_date')));
}
- $where = " where ei.status = 1 and ei.date >= '".$period->getBeginDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
+ $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
" $user_list_part $dropdown_parts";
return $where;
}
new DateAndTime($user->date_format, $report['period_start']),
new DateAndTime($user->date_format, $report['period_end']));
}
- $where = " where ei.status = 1 and ei.date >= '".$period->getBeginDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
+ $where = " where ei.status = 1 and ei.date >= '".$period->getStartDate(DB_DATEFORMAT)."' and ei.date <= '".$period->getEndDate(DB_DATEFORMAT)."'".
" $user_list_part $dropdown_parts";
return $where;
}
$left_joins .= " left join tt_clients c on (c.id = l.client_id)";
if (($user->canManageTeam() || $user->isClient()) && $bean->getAttribute('chinvoice'))
$left_joins .= " left join tt_invoices i on (i.id = l.invoice_id and i.status = 1)";
- if ($user->canManageTeam() || $user->isClient() || in_array('ex', explode(',', $user->plugins)))
+ if ($user->canManageTeam() || $user->isClient() || $user->isPluginEnabled('ex'))
$left_joins .= " left join tt_users u on (u.id = l.user_id)";
if ($bean->getAttribute('chproject') || 'project' == $group_by_option)
$left_joins .= " left join tt_projects p on (p.id = l.project_id)";
// with an exception of sorting part, that is added in the end.
// However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table.
- if ($bean->getAttribute('chcost') && in_array('ex', explode(',', $user->plugins))) { // if ex(penses) plugin is enabled
+ if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled
$fields = array(); // An array of fields for database query.
array_push($fields, 'ei.id');
// Obtain items for report.
$res = $mdb2->query($sql);
- if (!is_a($res, 'PEAR_Error')) {
- while ($val = $res->fetchRow()) {
- if ($convertTo12Hour) {
- if($val['start'] != '')
- $val['start'] = ttTimeHelper::to12HourFormat($val['start']);
- if($val['finish'] != '')
- $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']);
- }
- if (isset($val['cost'])) {
- if ('.' != $user->decimal_mark)
- $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
- }
- if (isset($val['expense'])) {
- if ('.' != $user->decimal_mark)
- $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']);
- }
- if ('no_grouping' != $group_by_option) {
- $val['grouped_by'] = $val[$group_by_option];
- if ('date' == $group_by_option) {
- // This is needed to get the date in user date format.
- $o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']);
- $val['grouped_by'] = $o_date->toString($user->date_format);
- unset($o_date);
- }
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+
+ while ($val = $res->fetchRow()) {
+ if ($convertTo12Hour) {
+ if($val['start'] != '')
+ $val['start'] = ttTimeHelper::to12HourFormat($val['start']);
+ if($val['finish'] != '')
+ $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']);
+ }
+ if (isset($val['cost'])) {
+ if ('.' != $user->decimal_mark)
+ $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
+ }
+ if (isset($val['expense'])) {
+ if ('.' != $user->decimal_mark)
+ $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']);
+ }
+ if ('no_grouping' != $group_by_option) {
+ $val['grouped_by'] = $val[$group_by_option];
+ if ('date' == $group_by_option) {
+ // This is needed to get the date in user date format.
+ $o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']);
+ $val['grouped_by'] = $o_date->toString($user->date_format);
+ unset($o_date);
}
+ }
- // This is needed to get the date in user date format.
- $o_date = new DateAndTime(DB_DATEFORMAT, $val['date']);
- $val['date'] = $o_date->toString($user->date_format);
- unset($o_date);
+ // This is needed to get the date in user date format.
+ $o_date = new DateAndTime(DB_DATEFORMAT, $val['date']);
+ $val['date'] = $o_date->toString($user->date_format);
+ unset($o_date);
- $row = $val;
- $report_items[] = $row;
- }
- } else
- die($res->getMessage());
+ $row = $val;
+ $report_items[] = $row;
+ }
return $report_items;
}
static function getFavItems($report) {
global $user;
$mdb2 = getConnection();
-
+
$group_by_option = $report['group_by'];
$convertTo12Hour = ('%I:%M %p' == $user->time_format) && ($report['show_start'] || $report['show_end']);
-
+
// Prepare a query for time items in tt_log table.
$fields = array(); // An array of fields for database query.
array_push($fields, 'l.id as id');
$left_joins .= " left join tt_clients c on (c.id = l.client_id)";
if (($user->canManageTeam() || $user->isClient()) && $report['show_invoice'])
$left_joins .= " left join tt_invoices i on (i.id = l.invoice_id and i.status = 1)";
- if ($user->canManageTeam() || $user->isClient() || in_array('ex', explode(',', $user->plugins)))
+ if ($user->canManageTeam() || $user->isClient() || $user->isPluginEnabled('ex'))
$left_joins .= " left join tt_users u on (u.id = l.user_id)";
if ($report['show_project'] || 'project' == $group_by_option)
- $left_joins .= " left join tt_projects p on (p.id = l.project_id)";
+ $left_joins .= " left join tt_projects p on (p.id = l.project_id)";
if ($report['show_task'] || 'task' == $group_by_option)
- $left_joins .= " left join tt_tasks t on (t.id = l.task_id)";
+ $left_joins .= " left join tt_tasks t on (t.id = l.task_id)";
if ($include_cf_1) {
if ($cf_1_type == CustomFields::TYPE_TEXT)
$left_joins .= " left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1)";
}
if ($includeCost && MODE_TIME != $user->tracking_mode)
$left_joins .= " left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id)";
-
+
$where = ttReportHelper::getFavWhere($report);
-
- // Construct sql query for tt_log items.
+
+ // Construct sql query for tt_log items.
$sql = "select ".join(', ', $fields)." from tt_log l $left_joins $where";
// If we don't have expense items (such as when the Expenses plugin is desabled), the above is all sql we need,
// with an exception of sorting part, that is added in the end.
// However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table.
- if ($report['show_cost'] && in_array('ex', explode(',', $user->plugins))) { // if ex(penses) plugin is enabled
-
+ if ($report['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled
+
$fields = array(); // An array of fields for database query.
array_push($fields, 'ei.id');
array_push($fields, '2 as type'); // Type 2 is for tt_expense_items entries.
// Add invoice name if it is selected.
if (($user->canManageTeam() || $user->isClient()) && $report['show_invoice'])
array_push($fields, 'i.name as invoice');
-
+
// Prepare sql query part for left joins.
$left_joins = null;
if ($user->canManageTeam() || $user->isClient())
if ($report['show_client'] || 'client' == $group_by_option)
$left_joins .= " left join tt_clients c on (c.id = ei.client_id)";
if ($report['show_project'] || 'project' == $group_by_option)
- $left_joins .= " left join tt_projects p on (p.id = ei.project_id)";
+ $left_joins .= " left join tt_projects p on (p.id = ei.project_id)";
if (($user->canManageTeam() || $user->isClient()) && $report['show_invoice'])
$left_joins .= " left join tt_invoices i on (i.id = ei.invoice_id and i.status = 1)";
$where = ttReportHelper::getFavExpenseWhere($report);
-
+
// Construct sql query for expense items.
$sql_for_expense_items = "select ".join(', ', $fields)." from tt_expense_items ei $left_joins $where";
-
+
// Construct a union.
$sql = "($sql) union all ($sql_for_expense_items)";
}
-
+
// Determine sort part.
$sort_part = ' order by ';
if ($group_by_option == null || 'no_grouping' == $group_by_option || 'date' == $group_by_option) // TODO: fix DB for NULL values in group_by field.
if ($report['show_start'])
$sort_part .= ', unformatted_start';
$sort_part .= ', id';
-
+
$sql .= $sort_part;
// By now we are ready with sql.
// Obtain items for report.
$res = $mdb2->query($sql);
- if (!is_a($res, 'PEAR_Error')) {
- while ($val = $res->fetchRow()) {
- if ($convertTo12Hour) {
- if($val['start'] != '')
- $val['start'] = ttTimeHelper::to12HourFormat($val['start']);
- if($val['finish'] != '')
- $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']);
- }
- if (isset($val['cost'])) {
- if ('.' != $user->decimal_mark)
- $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
- }
- if (isset($val['expense'])) {
- if ('.' != $user->decimal_mark)
- $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']);
- }
- if ('no_grouping' != $group_by_option) {
- $val['grouped_by'] = $val[$group_by_option];
- if ('date' == $group_by_option) {
- // This is needed to get the date in user date format.
- $o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']);
- $val['grouped_by'] = $o_date->toString($user->date_format);
- unset($o_date);
- }
- }
-
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+
+ while ($val = $res->fetchRow()) {
+ if ($convertTo12Hour) {
+ if($val['start'] != '')
+ $val['start'] = ttTimeHelper::to12HourFormat($val['start']);
+ if($val['finish'] != '')
+ $val['finish'] = ttTimeHelper::to12HourFormat($val['finish']);
+ }
+ if (isset($val['cost'])) {
+ if ('.' != $user->decimal_mark)
+ $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
+ }
+ if (isset($val['expense'])) {
+ if ('.' != $user->decimal_mark)
+ $val['expense'] = str_replace('.', $user->decimal_mark, $val['expense']);
+ }
+ if ('no_grouping' != $group_by_option) {
+ $val['grouped_by'] = $val[$group_by_option];
+ if ('date' == $group_by_option) {
// This is needed to get the date in user date format.
- $o_date = new DateAndTime(DB_DATEFORMAT, $val['date']);
- $val['date'] = $o_date->toString($user->date_format);
+ $o_date = new DateAndTime(DB_DATEFORMAT, $val['grouped_by']);
+ $val['grouped_by'] = $o_date->toString($user->date_format);
unset($o_date);
-
- $row = $val;
- $report_items[] = $row;
}
- } else
- die($res->getMessage());
+ }
+
+ // This is needed to get the date in user date format.
+ $o_date = new DateAndTime(DB_DATEFORMAT, $val['date']);
+ $val['date'] = $o_date->toString($user->date_format);
+ unset($o_date);
+
+ $row = $val;
+ $report_items[] = $row;
+ }
return $report_items;
}
-
+
// getSubtotals calculates report items subtotals when a report is grouped by.
// Without expenses, it's a simple select with group by.
// With expenses, it becomes a select with group by from a combined set of records obtained with "union all".
static function getSubtotals($bean) {
- global $user;
-
+ global $user;
+
$group_by_option = $bean->getAttribute('group_by');
if ('no_grouping' == $group_by_option) return null;
-
+
$mdb2 = getConnection();
-
+
// Start with sql to obtain subtotals for time items. This simple sql will be used when we have no expenses.
-
+
// Determine group by field and a required join.
switch ($group_by_option) {
- case 'date':
+ case 'date':
$group_field = 'l.date';
$group_join = '';
break;
$group_join = 'left join tt_clients c on (l.client_id = c.id) ';
break;
case 'project':
- $group_field = 'p.name';
+ $group_field = 'p.name';
$group_join = 'left join tt_projects p on (l.project_id = p.id) ';
- break;
+ break;
case 'task':
- $group_field = 't.name';
+ $group_field = 't.name';
$group_join = 'left join tt_tasks t on (l.task_id = t.id) ';
- break;
+ break;
case 'cf_1':
- $group_field = 'cfo.value';
- $custom_fields = new CustomFields($user->team_id);
- if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT)
+ $group_field = 'cfo.value';
+ $custom_fields = new CustomFields($user->team_id);
+ if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT)
$group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) ';
elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)
$group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id) ';
- break;
+ break;
}
$where = ttReportHelper::getWhere($bean);
if ($bean->getAttribute('chcost')) {
if (MODE_TIME == $user->tracking_mode) {
- if ($group_by_option != 'user')
- $left_join = 'left join tt_users u on (l.user_id = u.id)';
+ if ($group_by_option != 'user')
+ $left_join = 'left join tt_users u on (l.user_id = u.id)';
$sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost,
null as expenses from tt_log l
- $group_join $left_join $where group by $group_field";
+ $group_join $left_join $where group by $group_field";
} else {
// If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table.
$sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost,
- null as expenses from tt_log l
+ null as expenses from tt_log l
$group_join
left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field";
}
} else {
- $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l
+ $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l
$group_join $where group by $group_field";
}
// By now we have sql for time items.
-
+
// However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table.
- if ($bean->getAttribute('chcost') && in_array('ex', explode(',', $user->plugins))) { // if ex(penses) plugin is enabled
-
+ if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled
+
// Determine group by field and a required join.
$group_join = null;
$group_field = 'null';
switch ($group_by_option) {
- case 'date':
+ case 'date':
$group_field = 'ei.date';
$group_join = '';
break;
$group_join = 'left join tt_clients c on (ei.client_id = c.id) ';
break;
case 'project':
- $group_field = 'p.name';
+ $group_field = 'p.name';
$group_join = 'left join tt_projects p on (ei.project_id = p.id) ';
- break;
+ break;
}
$where = ttReportHelper::getExpenseWhere($bean);
$group_join $where";
// Add a "group by" clause if we are grouping.
if ('null' != $group_field) $sql_for_expenses .= " group by $group_field";
-
+
// Create a combined query.
$sql = "select group_field, sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field";
}
-
+
// Execute query.
$res = $mdb2->query($sql);
- if (!is_a($res, 'PEAR_Error')) {
- while ($val = $res->fetchRow()) {
- if ('date' == $group_by_option) {
- // This is needed to get the date in user date format.
- $o_date = new DateAndTime(DB_DATEFORMAT, $val['group_field']);
- $val['group_field'] = $o_date->toString($user->date_format);
- unset($o_date);
- }
- $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
- if ($bean->getAttribute('chcost')) {
- if ('.' != $user->decimal_mark) {
- $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
- $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']);
- }
- $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']);
- } else
- $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time);
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+
+ while ($val = $res->fetchRow()) {
+ if ('date' == $group_by_option) {
+ // This is needed to get the date in user date format.
+ $o_date = new DateAndTime(DB_DATEFORMAT, $val['group_field']);
+ $val['group_field'] = $o_date->toString($user->date_format);
+ unset($o_date);
}
- } else
- die($res->getMessage());
+ $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
+ if ($bean->getAttribute('chcost')) {
+ if ('.' != $user->decimal_mark) {
+ $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
+ $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']);
+ }
+ $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']);
+ } else
+ $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time);
+ }
return $subtotals;
}
-
+
// getFavSubtotals calculates report items subtotals when a favorite report is grouped by.
// Without expenses, it's a simple select with group by.
// With expenses, it becomes a select with group by from a combined set of records obtained with "union all".
static function getFavSubtotals($report) {
- global $user;
-
+ global $user;
+
$group_by_option = $report['group_by'];
if ('no_grouping' == $group_by_option) return null;
-
+
$mdb2 = getConnection();
-
+
// Start with sql to obtain subtotals for time items. This simple sql will be used when we have no expenses.
-
+
// Determine group by field and a required join.
switch ($group_by_option) {
- case 'date':
+ case 'date':
$group_field = 'l.date';
$group_join = '';
break;
$group_join = 'left join tt_clients c on (l.client_id = c.id) ';
break;
case 'project':
- $group_field = 'p.name';
+ $group_field = 'p.name';
$group_join = 'left join tt_projects p on (l.project_id = p.id) ';
- break;
+ break;
case 'task':
- $group_field = 't.name';
+ $group_field = 't.name';
$group_join = 'left join tt_tasks t on (l.task_id = t.id) ';
- break;
+ break;
case 'cf_1':
- $group_field = 'cfo.value';
- $custom_fields = new CustomFields($user->team_id);
- if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT)
+ $group_field = 'cfo.value';
+ $custom_fields = new CustomFields($user->team_id);
+ if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT)
$group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.value = cfo.id) ';
elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)
$group_join = 'left join tt_custom_field_log cfl on (l.id = cfl.log_id and cfl.status = 1) left join tt_custom_field_options cfo on (cfl.option_id = cfo.id) ';
- break;
+ break;
}
$where = ttReportHelper::getFavWhere($report);
if ($report['show_cost']) {
if (MODE_TIME == $user->tracking_mode) {
- if ($group_by_option != 'user')
- $left_join = 'left join tt_users u on (l.user_id = u.id)';
+ if ($group_by_option != 'user')
+ $left_join = 'left join tt_users u on (l.user_id = u.id)';
$sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
sum(cast(l.billable * coalesce(u.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10, 2))) as cost,
null as expenses from tt_log l
- $group_join $left_join $where group by $group_field";
+ $group_join $left_join $where group by $group_field";
} else {
// If we are including cost and tracking projects, our query (the same as above) needs to join the tt_user_project_binds table.
$sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time,
left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where group by $group_field";
}
} else {
- $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l
+ $sql = "select $group_field as group_field, sum(time_to_sec(l.duration)) as time, null as expenses from tt_log l
$group_join $where group by $group_field";
}
// By now we have sql for time items.
-
+
// However, when we have expenses, we need to do a union with a separate query for expense items from tt_expense_items table.
- if ($report['show_cost'] && in_array('ex', explode(',', $user->plugins))) { // if ex(penses) plugin is enabled
-
+ if ($report['show_cost'] && $user->isPluginEnabled('ex')) { // if ex(penses) plugin is enabled
+
// Determine group by field and a required join.
$group_join = null;
$group_field = 'null';
switch ($group_by_option) {
- case 'date':
+ case 'date':
$group_field = 'ei.date';
$group_join = '';
break;
$group_join = 'left join tt_clients c on (ei.client_id = c.id) ';
break;
case 'project':
- $group_field = 'p.name';
+ $group_field = 'p.name';
$group_join = 'left join tt_projects p on (ei.project_id = p.id) ';
- break;
+ break;
}
$where = ttReportHelper::getFavExpenseWhere($report);
$group_join $where";
// Add a "group by" clause if we are grouping.
if ('null' != $group_field) $sql_for_expenses .= " group by $group_field";
-
+
// Create a combined query.
$sql = "select group_field, sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t group by group_field";
}
-
+
// Execute query.
$res = $mdb2->query($sql);
- if (!is_a($res, 'PEAR_Error')) {
- while ($val = $res->fetchRow()) {
- if ('date' == $group_by_option) {
- // This is needed to get the date in user date format.
- $o_date = new DateAndTime(DB_DATEFORMAT, $val['group_field']);
- $val['group_field'] = $o_date->toString($user->date_format);
- unset($o_date);
- }
- $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
- if ($report['show_cost']) {
- if ('.' != $user->decimal_mark) {
- $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
- $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']);
- }
- $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']);
- } else
- $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time);
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+
+ while ($val = $res->fetchRow()) {
+ if ('date' == $group_by_option) {
+ // This is needed to get the date in user date format.
+ $o_date = new DateAndTime(DB_DATEFORMAT, $val['group_field']);
+ $val['group_field'] = $o_date->toString($user->date_format);
+ unset($o_date);
}
- } else
- die($res->getMessage());
+ $time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
+ if ($report['show_cost']) {
+ if ('.' != $user->decimal_mark) {
+ $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
+ $val['expenses'] = str_replace('.', $user->decimal_mark, $val['expenses']);
+ }
+ $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time,'cost'=>$val['cost'],'expenses'=>$val['expenses']);
+ } else
+ $subtotals[$val['group_field']] = array('name'=>$val['group_field'],'time'=>$time);
+ }
return $subtotals;
}
-
+
// getTotals calculates total hours and cost for all report items.
static function getTotals($bean)
{
global $user;
-
+
$mdb2 = getConnection();
-
+
$where = ttReportHelper::getWhere($bean);
-
+
// Start with a query for time items.
if ($bean->getAttribute('chcost')) {
if (MODE_TIME == $user->tracking_mode) {
sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost,
null as expenses
from tt_log l
- left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where";
+ left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where";
}
} else
$sql = "select sum(time_to_sec(l.duration)) as time, null as cost, null as expenses from tt_log l $where";
-
+
// If we have expenses, query becomes a bit more complex.
- if ($bean->getAttribute('chcost') && in_array('ex', explode(',', $user->plugins))) {
+ if ($bean->getAttribute('chcost') && $user->isPluginEnabled('ex')) {
$where = ttReportHelper::getExpenseWhere($bean);
$sql_for_expenses = "select null as time, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where";
// Create a combined query.
$sql = "select sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t";
- }
+ }
- // Execute query.
+ // Execute query.
$res = $mdb2->query($sql);
- if (!is_a($res, 'PEAR_Error')) {
- $val = $res->fetchRow();
- $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
- if ($bean->getAttribute('chcost')) {
- $total_cost = $val['cost'];
- if (!$total_cost) $total_cost = '0.00';
- if ('.' != $user->decimal_mark)
- $total_cost = str_replace('.', $user->decimal_mark, $total_cost);
-
- $total_expenses = $val['expenses'];
- if (!$total_expenses) $total_expenses = '0.00';
- if ('.' != $user->decimal_mark)
- $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses);
- }
- } else
- die($res->getMessage());
-
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+
+ $val = $res->fetchRow();
+ $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
+ if ($bean->getAttribute('chcost')) {
+ $total_cost = $val['cost'];
+ if (!$total_cost) $total_cost = '0.00';
+ if ('.' != $user->decimal_mark)
+ $total_cost = str_replace('.', $user->decimal_mark, $total_cost);
+ $total_expenses = $val['expenses'];
+ if (!$total_expenses) $total_expenses = '0.00';
+ if ('.' != $user->decimal_mark)
+ $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses);
+ }
+
if ($bean->getAttribute('period'))
$period = new Period($bean->getAttribute('period'), new DateAndTime($user->date_format));
else {
new DateAndTime($user->date_format, $bean->getAttribute('end_date')));
}
- $totals['start_date'] = $period->getBeginDate();
- $totals['end_date'] = $period->getEndDate();
- $totals['time'] = $total_time;
- $totals['cost'] = $total_cost;
- $totals['expenses'] = $total_expenses;
+ $totals['start_date'] = $period->getStartDate();
+ $totals['end_date'] = $period->getEndDate();
+ $totals['time'] = $total_time;
+ $totals['cost'] = $total_cost;
+ $totals['expenses'] = $total_expenses;
return $totals;
}
-
+
// getFavTotals calculates total hours and cost for all favorite report items.
static function getFavTotals($report)
{
global $user;
-
+
$mdb2 = getConnection();
-
+
$where = ttReportHelper::getFavWhere($report);
-
+
// Start with a query for time items.
if ($report['show_cost']) {
if (MODE_TIME == $user->tracking_mode) {
sum(cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2))) as cost,
null as expenses
from tt_log l
- left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where";
+ left join tt_user_project_binds upb on (l.user_id = upb.user_id and l.project_id = upb.project_id) $where";
}
} else
$sql = "select sum(time_to_sec(l.duration)) as time, null as cost, null as expenses from tt_log l $where";
-
+
// If we have expenses, query becomes a bit more complex.
- if ($report['show_cost'] && in_array('ex', explode(',', $user->plugins))) {
+ if ($report['show_cost'] && $user->isPluginEnabled('ex')) {
$where = ttReportHelper::getFavExpenseWhere($report);
$sql_for_expenses = "select null as time, sum(cost) as cost, sum(cost) as expenses from tt_expense_items ei $where";
// Create a combined query.
$sql = "select sum(time) as time, sum(cost) as cost, sum(expenses) as expenses from (($sql) union all ($sql_for_expenses)) t";
- }
+ }
- // Execute query.
+ // Execute query.
$res = $mdb2->query($sql);
- if (!is_a($res, 'PEAR_Error')) {
- $val = $res->fetchRow();
- $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
- if ($report['show_cost']) {
- $total_cost = $val['cost'];
- if (!$total_cost) $total_cost = '0.00';
- if ('.' != $user->decimal_mark)
- $total_cost = str_replace('.', $user->decimal_mark, $total_cost);
-
- $total_expenses = $val['expenses'];
- if (!$total_expenses) $total_expenses = '0.00';
- if ('.' != $user->decimal_mark)
- $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses);
- }
- } else
- die($res->getMessage());
-
+ if (is_a($res, 'PEAR_Error')) die($res->getMessage());
+
+ $val = $res->fetchRow();
+ $total_time = $val['time'] ? sec_to_time_fmt_hm($val['time']) : null;
+ if ($report['show_cost']) {
+ $total_cost = $val['cost'];
+ if (!$total_cost) $total_cost = '0.00';
+ if ('.' != $user->decimal_mark)
+ $total_cost = str_replace('.', $user->decimal_mark, $total_cost);
+ $total_expenses = $val['expenses'];
+ if (!$total_expenses) $total_expenses = '0.00';
+ if ('.' != $user->decimal_mark)
+ $total_expenses = str_replace('.', $user->decimal_mark, $total_expenses);
+ }
+
if ($report['period'])
$period = new Period($report['period'], new DateAndTime($user->date_format));
else {
new DateAndTime($user->date_format, $report['period_end']));
}
- $totals['start_date'] = $period->getBeginDate();
- $totals['end_date'] = $period->getEndDate();
- $totals['time'] = $total_time;
- $totals['cost'] = $total_cost;
- $totals['expenses'] = $total_expenses;
+ $totals['start_date'] = $period->getStartDate();
+ $totals['end_date'] = $period->getEndDate();
+ $totals['time'] = $total_time;
+ $totals['cost'] = $total_cost;
+ $totals['expenses'] = $total_expenses;
return $totals;
}
-
+
// The assignToInvoice assigns a set of records to a specific invoice.
static function assignToInvoice($invoice_id, $time_log_ids, $expense_item_ids)
{
- $mdb2 = getConnection();
- if ($time_log_ids) {
+ $mdb2 = getConnection();
+ if ($time_log_ids) {
$sql = "update tt_log set invoice_id = ".$mdb2->quote($invoice_id).
" where id in(".join(', ', $time_log_ids).")";
$affected = $mdb2->exec($sql);
- if (is_a($affected, 'PEAR_Error'))
- die($affected->getMessage());
- }
+ if (is_a($affected, 'PEAR_Error')) die($affected->getMessage());
+ }
if ($expense_item_ids) {
$sql = "update tt_expense_items set invoice_id = ".$mdb2->quote($invoice_id).
" where id in(".join(', ', $expense_item_ids).")";
$affected = $mdb2->exec($sql);
- if (is_a($affected, 'PEAR_Error'))
- die($affected->getMessage());
- }
+ if (is_a($affected, 'PEAR_Error')) die($affected->getMessage());
+ }
}
// prepareReportBody - prepares an email body for report.
if ($group_by && 'no_grouping' != $group_by)
$subtotals = ttReportHelper::getSubtotals($bean);
$totals = ttReportHelper::getTotals($bean);
-
+
// Use custom fields plugin if it is enabled.
- if (in_array('cf', explode(',', $user->plugins)))
+ if ($user->isPluginEnabled('cf'))
$custom_fields = new CustomFields($user->team_id);
// Define some styles to use in email.
$cellRightAligned = 'text-align: right; vertical-align: top;';
$cellLeftAlignedSubtotal = 'font-weight: bold; text-align: left; vertical-align: top;';
$cellRightAlignedSubtotal = 'font-weight: bold; text-align: right; vertical-align: top;';
-
+
// Start creating email body.
$body = '<html>';
$body .= '<head><meta http-equiv="content-type" content="text/html; charset='.CHARSET.'"></head>';
$body .= '<body>';
-
+
// Output title.
$body .= '<p style="'.$style_title.'">'.$i18n->getKey('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'</p>';
-
+
// Output comment.
if ($comment) $body .= '<p>'.htmlspecialchars($comment).'</p>';
if ($bean->getAttribute('chtotalsonly')) {
// Totals only report. Output subtotals.
-
+
// Determine group_by header.
if ('cf_1' == $group_by)
$group_by_header = htmlspecialchars($custom_fields->fields[0]['label']);
$key = 'label.'.$group_by;
$group_by_header = $i18n->getKey($key);
}
-
+
$body .= '<table border="0" cellpadding="4" cellspacing="0" width="100%">';
$body .= '<tr>';
$body .= '<td style="'.$tableHeader.'">'.$group_by_header.'</td>';
}
$body .= '</tr>';
}
-
+
// Print totals.
$body .= '<tr><td> </td></tr>';
$body .= '<tr style="'.$rowSubtotal.'">';
$body .= '<td style="'.$cellLeftAlignedSubtotal.'">'.$i18n->getKey('label.total').'</td>';
if ($bean->getAttribute('chduration')) {
- $body .= '<td style="'.$cellRightAlignedSubtotal.'">';
- if ($totals['time'] <> '0:00') $body .= $totals['time'];
- $body .= '</td>';
+ $body .= '<td style="'.$cellRightAlignedSubtotal.'">';
+ if ($totals['time'] <> '0:00') $body .= $totals['time'];
+ $body .= '</td>';
}
if ($bean->getAttribute('chcost')) {
- $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
+ $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
$body .= ($user->canManageTeam() || $user->isClient()) ? $totals['cost'] : $totals['expenses'];
- $body .= '</td>';
+ $body .= '</td>';
}
$body .= '</tr>';
-
+
$body .= '</table>';
} else {
// Regular report.
-
+
// Print table header.
$body .= '<table border="0" cellpadding="4" cellspacing="0" width="100%">';
$body .= '<tr>';
if ($bean->getAttribute('chinvoice'))
$body .= '<td style="'.$tableHeader.'">'.$i18n->getKey('label.invoice').'</td>';
$body .= '</tr>';
-
+
// Initialize variables to print subtotals.
if ($items && 'no_grouping' != $group_by) {
$print_subtotals = true;
$prev_date = '';
$cur_date = '';
$row_style = $rowItem;
-
+
// Print report items.
if (is_array($items)) {
foreach ($items as $record) {
if ($bean->getAttribute('chduration')) $body .= '<td style="'.$cellRightAlignedSubtotal.'">'.$subtotals[$prev_grouped_by]['time'].'</td>';
if ($bean->getAttribute('chnote')) $body .= '<td></td>';
if ($bean->getAttribute('chcost')) {
- $body .= '<td style="'.$cellRightAlignedSubtotal.'">';
- $body .= ($user->canManageTeam() || $user->isClient()) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses'];
- $body .= '</td>';
+ $body .= '<td style="'.$cellRightAlignedSubtotal.'">';
+ $body .= ($user->canManageTeam() || $user->isClient()) ? $subtotals[$prev_grouped_by]['cost'] : $subtotals[$prev_grouped_by]['expenses'];
+ $body .= '</td>';
}
if ($bean->getAttribute('chinvoice')) $body .= '<td></td>';
$body .= '</tr>';
}
$first_pass = false;
}
-
+
// Print a regular row.
if ($cur_date != $prev_date)
$row_style = ($row_style == $rowItem) ? $rowItemAlt : $rowItem;
if ($bean->getAttribute('chinvoice'))
$body .= '<td style="'.$cellRightAligned.'">'.htmlspecialchars($record['invoice']).'</td>';
$body .= '</tr>';
-
+
$prev_date = $record['date'];
if ($print_subtotals)
$prev_grouped_by = $record['grouped_by'];
}
}
-
+
// Print a terminating subtotal.
if ($print_subtotals) {
$body .= '<tr style="'.$rowSubtotal.'">';
if ($bean->getAttribute('chinvoice')) $body .= '<td></td>';
$body .= '</tr>';
}
-
+
// Print totals.
$body .= '<tr><td> </td></tr>';
$body .= '<tr style="'.$rowSubtotal.'">';
if ($bean->getAttribute('chduration')) $body .= '<td style="'.$cellRightAlignedSubtotal.'">'.$totals['time'].'</td>';
if ($bean->getAttribute('chnote')) $body .= '<td></td>';
if ($bean->getAttribute('chcost')) {
- $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
- $body .= ($user->canManageTeam() || $user->isClient()) ? $totals['cost'] : $totals['expenses'];
- $body .= '</td>';
+ $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
+ $body .= ($user->canManageTeam() || $user->isClient()) ? $totals['cost'] : $totals['expenses'];
+ $body .= '</td>';
}
if ($bean->getAttribute('chinvoice')) $body .= '<td></td>';
$body .= '</tr>';
-
+
$body .= '</table>';
}
-
+
// Output footer.
if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false))
$body .= '<p style="text-align: center;">'.$i18n->getKey('form.mail.footer').'</p>';
return $body;
}
-
-// prepareFavReportBody - prepares an email body for a favorite report.
+
+ // checkFavReportCondition - checks whether it is okay to send fav report.
+ static function checkFavReportCondition($report, $condition)
+ {
+ $items = ttReportHelper::getFavItems($report);
+
+ $condition = str_replace('count', '', $condition);
+ $count_required = intval(trim(str_replace('>', '', $condition)));
+
+ if (count($items) > $count_required)
+ return true; // Condition ok.
+
+ return false;
+ }
+
+ // prepareFavReportBody - prepares an email body for a favorite report.
static function prepareFavReportBody($report)
{
- global $user;
- global $i18n;
-
- $items = ttReportHelper::getFavItems($report);
+ global $user;
+ global $i18n;
+
+ $items = ttReportHelper::getFavItems($report);
$group_by = $report['group_by'];
- if ($group_by && 'no_grouping' != $group_by)
- $subtotals = ttReportHelper::getFavSubtotals($report);
- $totals = ttReportHelper::getFavTotals($report);
-
+ if ($group_by && 'no_grouping' != $group_by)
+ $subtotals = ttReportHelper::getFavSubtotals($report);
+ $totals = ttReportHelper::getFavTotals($report);
+
// Use custom fields plugin if it is enabled.
- if (in_array('cf', explode(',', $user->plugins)))
+ if ($user->isPluginEnabled('cf'))
$custom_fields = new CustomFields($user->team_id);
// Define some styles to use in email.
$cellRightAligned = 'text-align: right; vertical-align: top;';
$cellLeftAlignedSubtotal = 'font-weight: bold; text-align: left; vertical-align: top;';
$cellRightAlignedSubtotal = 'font-weight: bold; text-align: right; vertical-align: top;';
-
+
// Start creating email body.
$body = '<html>';
$body .= '<head><meta http-equiv="content-type" content="text/html; charset='.CHARSET.'"></head>';
$body .= '<body>';
-
+
// Output title.
$body .= '<p style="'.$style_title.'">'.$i18n->getKey('form.mail.report_subject').': '.$totals['start_date'].' - '.$totals['end_date'].'</p>';
if ($report['show_totals_only']) {
// Totals only report. Output subtotals.
-
+
// Determine group_by header.
if ('cf_1' == $group_by)
$group_by_header = htmlspecialchars($custom_fields->fields[0]['label']);
$key = 'label.'.$group_by;
$group_by_header = $i18n->getKey($key);
}
-
+
$body .= '<table border="0" cellpadding="4" cellspacing="0" width="100%">';
$body .= '<tr>';
$body .= '<td style="'.$tableHeader.'">'.$group_by_header.'</td>';
}
$body .= '</tr>';
}
-
+
// Print totals.
$body .= '<tr><td> </td></tr>';
$body .= '<tr style="'.$rowSubtotal.'">';
$body .= '<td style="'.$cellLeftAlignedSubtotal.'">'.$i18n->getKey('label.total').'</td>';
if ($report['show_duration']) {
- $body .= '<td style="'.$cellRightAlignedSubtotal.'">';
- if ($totals['time'] <> '0:00') $body .= $totals['time'];
- $body .= '</td>';
+ $body .= '<td style="'.$cellRightAlignedSubtotal.'">';
+ if ($totals['time'] <> '0:00') $body .= $totals['time'];
+ $body .= '</td>';
}
if ($report['show_cost']) {
- $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
+ $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
$body .= ($user->canManageTeam() || $user->isClient()) ? $totals['cost'] : $totals['expenses'];
- $body .= '</td>';
+ $body .= '</td>';
}
$body .= '</tr>';
-
+
$body .= '</table>';
} else {
// Regular report.
-
+
// Print table header.
$body .= '<table border="0" cellpadding="4" cellspacing="0" width="100%">';
$body .= '<tr>';
if ($report['show_invoice'])
$body .= '<td style="'.$tableHeader.'">'.$i18n->getKey('label.invoice').'</td>';
$body .= '</tr>';
-
+
// Initialize variables to print subtotals.
if ($items && 'no_grouping' != $group_by) {
$print_subtotals = true;
$prev_date = '';
$cur_date = '';
$row_style = $rowItem;
-
+
// Print report items.
if (is_array($items)) {
foreach ($items as $record) {
}
if ($report['show_invoice']) $body .= '<td></td>';
$body .= '</tr>';
- $body .= '<tr><td> </td></tr>';
+ $body .= '<tr><td> </td></tr>';
}
$first_pass = false;
- }
-
+ }
+
// Print a regular row.
if ($cur_date != $prev_date)
$row_style = ($row_style == $rowItem) ? $rowItemAlt : $rowItem;
if ($report['show_invoice'])
$body .= '<td style="'.$cellRightAligned.'">'.htmlspecialchars($record['invoice']).'</td>';
$body .= '</tr>';
-
+
$prev_date = $record['date'];
if ($print_subtotals)
$prev_grouped_by = $record['grouped_by'];
}
}
-
+
// Print a terminating subtotal.
if ($print_subtotals) {
$body .= '<tr style="'.$rowSubtotal.'">';
if ($report['show_invoice']) $body .= '<td></td>';
$body .= '</tr>';
}
-
+
// Print totals.
$body .= '<tr><td> </td></tr>';
$body .= '<tr style="'.$rowSubtotal.'">';
if ($report['show_duration']) $body .= '<td style="'.$cellRightAlignedSubtotal.'">'.$totals['time'].'</td>';
if ($report['show_note']) $body .= '<td></td>';
if ($report['show_cost']) {
- $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
- $body .= ($user->canManageTeam() || $user->isClient()) ? $totals['cost'] : $totals['expenses'];
- $body .= '</td>';
+ $body .= '<td nowrap style="'.$cellRightAlignedSubtotal.'">'.htmlspecialchars($user->currency).' ';
+ $body .= ($user->canManageTeam() || $user->isClient()) ? $totals['cost'] : $totals['expenses'];
+ $body .= '</td>';
}
if ($report['show_invoice']) $body .= '<td></td>';
$body .= '</tr>';
-
+
$body .= '</table>';
}
-
+
// Output footer.
if (!defined('REPORT_FOOTER') || !(REPORT_FOOTER == false))
$body .= '<p style="text-align: center;">'.$i18n->getKey('form.mail.footer').'</p>';
return $body;
}
-
+
// sendFavReport - sends a favorite report to a specified email, called from cron.php
- static function sendFavReport($report, $email) {
+ static function sendFavReport($report, $subject, $email, $cc) {
// We are called from cron.php, we have no $bean in session.
- // cron.php set global $user and $i18n objects to match our favorite report user.
+ // cron.php sets global $user and $i18n objects to match our favorite report user.
global $user;
global $i18n;
-
+
// Prepare report body.
$body = ttReportHelper::prepareFavReportBody($report);
-
+
import('mail.Mailer');
$mailer = new Mailer();
$mailer->setCharSet(CHARSET);
$mailer->setContentType('text/html');
$mailer->setSender(SENDER);
+ if (!empty($cc))
+ $mailer->setReceiverCC($cc);
+ if (!empty($user->bcc_email))
+ $mailer->setReceiverBCC($user->bcc_email);
$mailer->setReceiver($email);
- $mailer->setSendType(MAIL_MODE);
- if (!$mailer->send($report['name'], $body))
+ $mailer->setMailMode(MAIL_MODE);
+ if (empty($subject)) $subject = $report['name'];
+ if (!$mailer->send($subject, $body))
return false;
-
+
return true;
}
}