1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00
invoiceninja/app/Ninja/Reports/AbstractReport.php

314 lines
8.7 KiB
PHP
Raw Normal View History

2017-01-22 11:09:29 +01:00
<?php
namespace App\Ninja\Reports;
2018-02-27 22:24:35 +01:00
use Utils;
2017-01-22 11:09:29 +01:00
use Auth;
2018-03-05 20:18:05 +01:00
use Carbon;
2018-02-26 23:07:08 +01:00
use DateInterval;
use DatePeriod;
use stdClass;
2018-02-28 09:12:23 +01:00
use App\Models\Client;
2017-01-22 11:09:29 +01:00
class AbstractReport
{
public $startDate;
public $endDate;
public $isExport;
public $options;
public $totals = [];
public $data = [];
2018-02-26 23:07:08 +01:00
public $chartData = [];
2017-01-22 11:09:29 +01:00
public function __construct($startDate, $endDate, $isExport, $options = false)
{
$this->startDate = $startDate;
$this->endDate = $endDate;
$this->isExport = $isExport;
$this->options = $options;
}
public function run()
{
2017-03-08 10:41:24 +01:00
2017-01-22 11:09:29 +01:00
}
2018-01-21 14:53:43 +01:00
public function getColumns()
{
return [];
}
2017-01-22 11:09:29 +01:00
public function results()
{
return [
2018-01-21 14:53:43 +01:00
'columns' => $this->getColumns(),
2017-01-22 11:09:29 +01:00
'displayData' => $this->data,
'reportTotals' => $this->totals,
];
}
protected function addToTotals($currencyId, $field, $value, $dimension = false)
{
$currencyId = $currencyId ?: Auth::user()->account->getCurrencyId();
2017-01-30 17:05:31 +01:00
if (! isset($this->totals[$currencyId][$dimension])) {
2017-01-22 11:09:29 +01:00
$this->totals[$currencyId][$dimension] = [];
}
2017-01-30 17:05:31 +01:00
if (! isset($this->totals[$currencyId][$dimension][$field])) {
2017-01-22 11:09:29 +01:00
$this->totals[$currencyId][$dimension][$field] = 0;
}
$this->totals[$currencyId][$dimension][$field] += $value;
}
2017-07-31 00:49:24 +02:00
public function tableHeaderArray() {
2017-08-01 15:37:33 +02:00
$columns_labeled = [];
2017-01-22 11:09:29 +01:00
2018-01-21 14:53:43 +01:00
foreach ($this->getColumns() as $key => $val) {
2017-01-22 11:09:29 +01:00
if (is_array($val)) {
$field = $key;
$class = $val;
} else {
$field = $val;
$class = [];
}
if (strpos($field, 'date') !== false) {
2018-02-27 21:20:27 +01:00
$class[] = 'group-date-' . (isset($this->options['group']) ? $this->options['group'] : 'monthyear');
2017-03-23 16:39:28 +01:00
} elseif (in_array($field, ['client', 'vendor', 'product', 'user', 'method', 'category', 'project'])) {
2017-01-22 11:09:29 +01:00
$class[] = 'group-letter-100';
} elseif (in_array($field, ['amount', 'paid', 'balance'])) {
$class[] = 'group-number-50';
2018-01-21 12:23:03 +01:00
} elseif (in_array($field, ['age'])) {
$class[] = 'group-number-30';
2017-01-22 11:09:29 +01:00
}
2018-01-21 14:53:43 +01:00
if (! in_array('custom', $class)) {
$label = trans("texts.{$field}");
} else {
$label = $field;
}
2017-01-22 11:09:29 +01:00
$class = count($class) ? implode(' ', $class) : 'group-false';
2017-07-31 00:49:24 +02:00
2018-01-21 11:16:02 +01:00
$columns_labeled[] = [
'label' => $label,
'class' => $class,
'key' => $field
];
2017-01-22 11:09:29 +01:00
}
2017-08-01 15:37:33 +02:00
return $columns_labeled;
2017-07-31 00:49:24 +02:00
}
public function tableHeader()
{
2017-08-01 15:37:33 +02:00
$columns_labeled = $this->tableHeaderArray();
2017-07-31 00:49:24 +02:00
$str = '';
2018-01-21 12:23:03 +01:00
foreach ($columns_labeled as $field => $attr) {
$str .= sprintf('<th class="%s" data-priorityx="3">%s</th>', $attr['class'], $attr['label']);
}
2017-01-22 11:09:29 +01:00
return $str;
}
// convert the date format to one supported by tablesorter
public function convertDateFormat()
{
$account = Auth::user()->account;
$format = $account->getMomentDateFormat();
$format = strtolower($format);
$format = str_replace('do', '', $format);
$orignalFormat = $format;
$format = preg_replace("/[^mdy]/", '', $format);
$lastLetter = false;
$reportParts = [];
$phpParts = [];
foreach (str_split($format) as $letter) {
if ($lastLetter && $letter == $lastLetter) {
continue;
}
$lastLetter = $letter;
if ($letter == 'm') {
$reportParts[] = 'mm';
$phpParts[] = 'm';
} elseif ($letter == 'd') {
$reportParts[] = 'dd';
$phpParts[] = 'd';
} elseif ($letter == 'y') {
$reportParts[] = 'yyyy';
$phpParts[] = 'Y';
}
}
return join('', $reportParts);
}
2018-02-26 23:07:08 +01:00
2018-02-27 21:52:57 +01:00
protected function getDimension($entity)
{
$subgroup = $this->options['subgroup'];
if ($subgroup == 'user') {
return $entity->user->getDisplayName();
} elseif ($subgroup == 'client') {
2018-02-28 09:12:23 +01:00
if ($entity instanceof Client) {
return $entity->getDisplayName();
} elseif ($entity->client) {
2018-02-27 21:52:57 +01:00
return $entity->client->getDisplayName();
} else {
return trans('texts.unset');
}
}
}
2018-02-26 23:07:08 +01:00
protected function addChartData($dimension, $date, $amount)
{
if (! isset($this->chartData[$dimension])) {
$this->chartData[$dimension] = [];
}
$date = $this->formatDate($date);
if (! isset($this->chartData[$dimension][$date])) {
$this->chartData[$dimension][$date] = 0;
}
$this->chartData[$dimension][$date] += $amount;
}
public function chartGroupBy()
{
2018-02-27 21:20:27 +01:00
$groupBy = empty($this->options['group']) ? 'day' : $this->options['group'];
2018-02-26 23:07:08 +01:00
if ($groupBy == 'monthyear') {
$groupBy = 'month';
}
return strtoupper($groupBy);
}
protected function formatDate($date)
{
2018-02-27 08:14:39 +01:00
if (! $date instanceof \DateTime) {
$date = new \DateTime($date);
}
2018-02-26 23:07:08 +01:00
$groupBy = $this->chartGroupBy();
$dateFormat = $groupBy == 'DAY' ? 'z' : ($groupBy == 'MONTH' ? 'm' : '');
return $date->format('Y' . $dateFormat);
}
2018-02-27 08:43:58 +01:00
public function getLineChartData()
2018-02-26 23:07:08 +01:00
{
$startDate = date_create($this->startDate);
$endDate = date_create($this->endDate);
$groupBy = $this->chartGroupBy();
$datasets = [];
$labels = [];
foreach ($this->chartData as $dimension => $data) {
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
2018-03-05 20:18:05 +01:00
$intervalStartDate = Carbon::instance($startDate);
$intervalEndDate = Carbon::instance($endDate);
// round dates to match grouping
$intervalStartDate->hour(0)->minute(0)->second(0);
$intervalEndDate->hour(24)->minute(0)->second(0);
if ($groupBy == 'MONTHYEAR' || $groupBy == 'YEAR') {
$intervalStartDate->day(1);
$intervalEndDate->addMonth(1)->day(1);
}
if ($groupBy == 'YEAR') {
$intervalStartDate->month(1);
$intervalEndDate->month(12);
}
$period = new DatePeriod($intervalStartDate, $interval, $intervalEndDate);
2018-02-26 23:07:08 +01:00
$records = [];
foreach ($period as $date) {
$labels[] = $date->format('m/d/Y');
$date = $this->formatDate($date);
$records[] = isset($data[$date]) ? $data[$date] : 0;
}
$record = new stdClass();
2018-02-27 22:24:35 +01:00
$datasets[] = $record;
$color = Utils::brewerColorRGB(count($datasets));
2018-02-26 23:07:08 +01:00
$record->data = $records;
2018-02-28 13:43:15 +01:00
$record->label = $dimension;
2018-02-26 23:07:08 +01:00
$record->lineTension = 0;
2018-02-27 20:19:46 +01:00
$record->borderWidth = 3;
2018-02-26 23:07:08 +01:00
$record->borderColor = "rgba({$color}, 1)";
2018-02-28 15:57:10 +01:00
$record->backgroundColor = "rgba(255,255,255,0)";
2018-02-26 23:07:08 +01:00
}
$data = new stdClass();
$data->labels = $labels;
$data->datasets = $datasets;
return $data;
}
2018-02-27 09:36:13 +01:00
2018-02-27 21:20:27 +01:00
public function isLineChartEnabled()
{
return $this->options['group'];
}
public function isPieChartEnabled()
{
return $this->options['subgroup'];
}
2018-02-27 09:36:13 +01:00
public function getPieChartData()
{
2018-02-27 21:20:27 +01:00
if (! $this->isPieChartEnabled()) {
return false;
}
2018-02-27 20:19:46 +01:00
$datasets = [];
$labels = [];
$totals = [];
foreach ($this->chartData as $dimension => $data) {
foreach ($data as $date => $value) {
if (! isset($totals[$dimension])) {
$totals[$dimension] = 0;
}
$totals[$dimension] += $value;
}
}
$response = new stdClass();
$response->labels = [];
$datasets = new stdClass();
$datasets->data = [];
$datasets->backgroundColor = [];
foreach ($totals as $dimension => $value) {
$response->labels[] = $dimension;
$datasets->data[] = $value;
$datasets->lineTension = 0;
$datasets->borderWidth = 3;
2018-02-27 22:24:35 +01:00
$color = count($totals) ? Utils::brewerColorRGB(count($response->labels)) : '51,122,183';
$datasets->borderColor[] = "rgba({$color}, 1)";
$datasets->backgroundColor[] = "rgba({$color}, 0.1)";
2018-02-27 20:19:46 +01:00
}
$response->datasets = [$datasets];
return $response;
2018-02-27 09:36:13 +01:00
}
2017-01-22 11:09:29 +01:00
}