mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on reports
This commit is contained in:
parent
374e34e733
commit
6660a7540b
@ -39,7 +39,7 @@ class InvoiceController extends \BaseController {
|
|||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
->where('clients.deleted_at', '=', null)
|
->where('clients.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', false)
|
->where('invoices.is_recurring', '=', false)
|
||||||
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'total', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name');
|
->select('clients.public_id as client_public_id', 'invoice_number', 'clients.name as client_name', 'invoices.public_id', 'amount', 'invoices.balance', 'invoice_date', 'due_date', 'invoice_statuses.name as invoice_status_name');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
@ -69,7 +69,7 @@ class InvoiceController extends \BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
return $table->addColumn('invoice_date', function($model) { return Utils::fromSqlDate($model->invoice_date); })
|
||||||
->addColumn('total', function($model) { return '$' . money_format('%i', $model->total); })
|
->addColumn('total', function($model) { return '$' . money_format('%i', $model->amount); })
|
||||||
->addColumn('balance', function($model) { return '$' . money_format('%i', $model->balance); })
|
->addColumn('balance', function($model) { return '$' . money_format('%i', $model->balance); })
|
||||||
->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); })
|
->addColumn('due_date', function($model) { return Utils::fromSqlDate($model->due_date); })
|
||||||
->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
|
->addColumn('invoice_status_name', function($model) { return $model->invoice_status_name; })
|
||||||
@ -99,7 +99,7 @@ class InvoiceController extends \BaseController {
|
|||||||
->where('invoices.account_id', '=', Auth::user()->account_id)
|
->where('invoices.account_id', '=', Auth::user()->account_id)
|
||||||
->where('invoices.deleted_at', '=', null)
|
->where('invoices.deleted_at', '=', null)
|
||||||
->where('invoices.is_recurring', '=', true)
|
->where('invoices.is_recurring', '=', true)
|
||||||
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'total', 'frequencies.name as frequency', 'start_date', 'end_date');
|
->select('clients.public_id as client_public_id', 'clients.name as client_name', 'invoices.public_id', 'amount', 'frequencies.name as frequency', 'start_date', 'end_date');
|
||||||
|
|
||||||
if ($clientPublicId) {
|
if ($clientPublicId) {
|
||||||
$query->where('clients.public_id', '=', $clientPublicId);
|
$query->where('clients.public_id', '=', $clientPublicId);
|
||||||
@ -129,7 +129,7 @@ class InvoiceController extends \BaseController {
|
|||||||
|
|
||||||
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
return $table->addColumn('start_date', function($model) { return Utils::fromSqlDate($model->start_date); })
|
||||||
->addColumn('end_date', function($model) { return Utils::fromSqlDate($model->end_date); })
|
->addColumn('end_date', function($model) { return Utils::fromSqlDate($model->end_date); })
|
||||||
->addColumn('total', function($model) { return '$' . money_format('%i', $model->total); })
|
->addColumn('total', function($model) { return '$' . money_format('%i', $model->amount); })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
@ -225,7 +225,7 @@ class InvoiceController extends \BaseController {
|
|||||||
$card = new CreditCard($data);
|
$card = new CreditCard($data);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'amount' => $invoice->total,
|
'amount' => $invoice->amount,
|
||||||
'card' => $card,
|
'card' => $card,
|
||||||
'currency' => 'USD',
|
'currency' => 'USD',
|
||||||
'returnUrl' => URL::to('complete'),
|
'returnUrl' => URL::to('complete'),
|
||||||
@ -255,13 +255,13 @@ class InvoiceController extends \BaseController {
|
|||||||
$payment = Payment::createNew();
|
$payment = Payment::createNew();
|
||||||
$payment->invitation_id = $invitation->id;
|
$payment->invitation_id = $invitation->id;
|
||||||
$payment->invoice_id = $invoice->id;
|
$payment->invoice_id = $invoice->id;
|
||||||
$payment->amount = $invoice->total;
|
$payment->amount = $invoice->amount;
|
||||||
$payment->client_id = $invoice->client_id;
|
$payment->client_id = $invoice->client_id;
|
||||||
//$payment->contact_id = 0; // TODO_FIX
|
//$payment->contact_id = 0; // TODO_FIX
|
||||||
$payment->transaction_reference = $ref;
|
$payment->transaction_reference = $ref;
|
||||||
$payment->save();
|
$payment->save();
|
||||||
|
|
||||||
$invoice->balance = floatval($invoice->total) - floatval($paymount->amount);
|
$invoice->balance = floatval($invoice->amount) - floatval($paymount->amount);
|
||||||
|
|
||||||
if ($response->isSuccessful())
|
if ($response->isSuccessful())
|
||||||
{
|
{
|
||||||
@ -538,11 +538,11 @@ class InvoiceController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$invoice->invoice_status_id = INVOICE_STATUS_SENT;
|
$invoice->invoice_status_id = INVOICE_STATUS_SENT;
|
||||||
|
|
||||||
$client->balance = $invoice->client->balance + $invoice->total;
|
$client->balance = $invoice->client->balance + $invoice->amount;
|
||||||
$client->save();
|
$client->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
$invoice->total = $total;
|
$invoice->amount = $total;
|
||||||
$invoice->save();
|
$invoice->save();
|
||||||
|
|
||||||
foreach ($contacts as $contact)
|
foreach ($contacts as $contact)
|
||||||
|
@ -48,7 +48,7 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
return $table->addColumn('invoice_number', function($model) { return $model->invoice_public_id ? link_to('invoices/' . $model->invoice_public_id . '/edit', $model->invoice_number) : ''; })
|
return $table->addColumn('invoice_number', function($model) { return $model->invoice_public_id ? link_to('invoices/' . $model->invoice_public_id . '/edit', $model->invoice_number) : ''; })
|
||||||
->addColumn('amount', function($model) { return '$' . $model->amount; })
|
->addColumn('amount', function($model) { return '$' . $model->amount; })
|
||||||
->addColumn('payment_date', function($model) { return Utils::timestampToDateString($model->payment_date); })
|
->addColumn('payment_date', function($model) { return Utils::dateToString($model->payment_date); })
|
||||||
->addColumn('dropdown', function($model)
|
->addColumn('dropdown', function($model)
|
||||||
{
|
{
|
||||||
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
return '<div class="btn-group tr-action" style="visibility:hidden;">
|
||||||
|
@ -2,45 +2,99 @@
|
|||||||
|
|
||||||
class ReportController extends \BaseController {
|
class ReportController extends \BaseController {
|
||||||
|
|
||||||
public function monthly()
|
public function report()
|
||||||
{
|
{
|
||||||
$records = DB::table('invoices')
|
if (Input::all())
|
||||||
->select(DB::raw('sum(total) as total, month(invoice_date) as month'))
|
{
|
||||||
->where('invoices.deleted_at', '=', null)
|
$groupBy = Input::get('group_by');
|
||||||
->where('invoices.invoice_date', '>', 0)
|
$chartType = Input::get('chart_type');
|
||||||
->groupBy('month');
|
$startDate = date_create(Input::get('start_date'));
|
||||||
|
$endDate = date_create(Input::get('end_date'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$groupBy = 'MONTH';
|
||||||
|
$chartType = 'Bar';
|
||||||
|
$startDate = date_create()->modify('-3 month');
|
||||||
|
$endDate = date_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
|
||||||
|
$endDate->modify('+1 '.$padding);
|
||||||
|
$datasets = [];
|
||||||
|
$labels = [];
|
||||||
|
$maxTotals = 0;
|
||||||
|
|
||||||
|
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType)
|
||||||
|
{
|
||||||
|
$records = DB::table($entityType.'s')
|
||||||
|
->select(DB::raw('sum(amount) as total, '.$groupBy.'('.$entityType.'_date) as '.$groupBy))
|
||||||
|
->where($entityType.'s.deleted_at', '=', null)
|
||||||
|
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d'))
|
||||||
|
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d'))
|
||||||
|
->groupBy($groupBy);
|
||||||
|
|
||||||
$totals = $records->lists('total');
|
$totals = $records->lists('total');
|
||||||
$dates = $records->lists('month');
|
$dates = $records->lists($groupBy);
|
||||||
$data = array_combine($dates, $totals);
|
$data = array_combine($dates, $totals);
|
||||||
|
|
||||||
$startDate = date_create('2013-06-30');
|
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
|
||||||
$endDate = date_create('2013-12-30');
|
|
||||||
$endDate = $endDate->modify('+1 month');
|
|
||||||
$interval = new DateInterval('P1M');
|
|
||||||
$period = new DatePeriod($startDate, $interval, $endDate);
|
$period = new DatePeriod($startDate, $interval, $endDate);
|
||||||
|
|
||||||
$totals = [];
|
$totals = [];
|
||||||
$dates = [];
|
|
||||||
|
|
||||||
foreach ($period as $d)
|
foreach ($period as $d)
|
||||||
{
|
{
|
||||||
$date = $d->format('Y-m-d');
|
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
|
||||||
$month = $d->format('n');
|
$date = $d->format($dateFormat);
|
||||||
|
$totals[] = isset($data[$date]) ? $data[$date] : 0;
|
||||||
|
|
||||||
$dates[] = $date;
|
if ($entityType == ENTITY_INVOICE)
|
||||||
$totals[] = isset($data[$month]) ? $data[$month] : 0;
|
{
|
||||||
|
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
|
||||||
|
$label = $d->format($labelFormat);
|
||||||
|
$labels[] = $label;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$width = (ceil( max($totals) / 100 ) * 100) / 10;
|
$max = max($totals);
|
||||||
|
|
||||||
$params = [
|
if ($max > 0)
|
||||||
'dates' => $dates,
|
{
|
||||||
|
$datasets[] = [
|
||||||
'totals' => $totals,
|
'totals' => $totals,
|
||||||
'scaleStepWidth' => $width,
|
'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107')
|
||||||
|
];
|
||||||
|
$maxTotals = max($max, $maxTotals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$width = (ceil( $maxTotals / 100 ) * 100) / 10;
|
||||||
|
$width = max($width, 10);
|
||||||
|
|
||||||
|
$dateTypes = [
|
||||||
|
'DAYOFYEAR' => 'Daily',
|
||||||
|
'WEEK' => 'Weekly',
|
||||||
|
'MONTH' => 'Monthly'
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('reports.monthly', $params);
|
$chartTypes = [
|
||||||
}
|
'Bar' => 'Bar',
|
||||||
|
'Line' => 'Line'
|
||||||
|
];
|
||||||
|
|
||||||
|
$params = [
|
||||||
|
'labels' => $labels,
|
||||||
|
'datasets' => $datasets,
|
||||||
|
'scaleStepWidth' => $width,
|
||||||
|
'dateTypes' => $dateTypes,
|
||||||
|
'chartTypes' => $chartTypes,
|
||||||
|
'chartType' => $chartType,
|
||||||
|
'startDate' => $startDate->format('m/d/Y'),
|
||||||
|
'endDate' => $endDate->modify('-1'.$padding)->format('m/d/Y'),
|
||||||
|
'groupBy' => $groupBy
|
||||||
|
];
|
||||||
|
|
||||||
|
return View::make('reports.report_builder', $params);
|
||||||
|
}
|
||||||
}
|
}
|
@ -270,7 +270,7 @@ class ConfideSetupUsersTable extends Migration {
|
|||||||
$t->unsignedInteger('recurring_invoice_id')->index()->nullable();
|
$t->unsignedInteger('recurring_invoice_id')->index()->nullable();
|
||||||
|
|
||||||
|
|
||||||
$t->decimal('total', 10, 2);
|
$t->decimal('amount', 10, 2);
|
||||||
$t->decimal('balance', 10, 2);
|
$t->decimal('balance', 10, 2);
|
||||||
|
|
||||||
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
$t->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
|
0
app/libraries/entity.php
Normal file → Executable file
0
app/libraries/entity.php
Normal file → Executable file
@ -63,10 +63,19 @@ class Utils
|
|||||||
return Utils::timestampToString($timestamp, $timezone, $format);
|
return Utils::timestampToString($timestamp, $timezone, $format);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function timestampToString($timestamp, $timzone, $format)
|
public static function dateToString($date) {
|
||||||
|
$dateTime = new DateTime($date);
|
||||||
|
$timestamp = $dateTime->getTimestamp();
|
||||||
|
$format = Session::get(SESSION_DATE_FORMAT, DEFAULT_DATE_FORMAT);
|
||||||
|
return Utils::timestampToString($timestamp, false, $format);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function timestampToString($timestamp, $timezone = false, $format)
|
||||||
{
|
{
|
||||||
$date = new Carbon($timestamp);
|
$date = Carbon::createFromTimeStamp($timestamp);
|
||||||
$date->tz = $timzone;
|
if ($timezone) {
|
||||||
|
$date->tz = $timezone;
|
||||||
|
}
|
||||||
if ($date->year < 1900) {
|
if ($date->year < 1900) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
0
app/models/Invitation.php
Normal file → Executable file
0
app/models/Invitation.php
Normal file → Executable file
@ -82,7 +82,8 @@ Route::group(array('before' => 'auth'), function()
|
|||||||
Route::get('api/credits/{client_id?}', array('as'=>'api.credits', 'uses'=>'CreditController@getDatatable'));
|
Route::get('api/credits/{client_id?}', array('as'=>'api.credits', 'uses'=>'CreditController@getDatatable'));
|
||||||
Route::post('credits/bulk', 'CreditController@bulk');
|
Route::post('credits/bulk', 'CreditController@bulk');
|
||||||
|
|
||||||
Route::get('reports', 'ReportController@monthly');
|
Route::get('reports', 'ReportController@report');
|
||||||
|
Route::post('reports', 'ReportController@report');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
71
app/views/reports/report_builder.blade.php
Executable file
71
app/views/reports/report_builder.blade.php
Executable file
@ -0,0 +1,71 @@
|
|||||||
|
@extends('header')
|
||||||
|
|
||||||
|
@section('head')
|
||||||
|
@parent
|
||||||
|
|
||||||
|
<script src="{{ asset('js/chart.js') }}" type="text/javascript"></script>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-3">
|
||||||
|
|
||||||
|
{{ Former::open() }}
|
||||||
|
{{ Former::populateField('start_date', $startDate) }}
|
||||||
|
{{ Former::populateField('end_date', $endDate) }}
|
||||||
|
{{ Former::select('chart_type')->options($chartTypes, $chartType) }}
|
||||||
|
{{ Former::select('group_by')->options($dateTypes, $groupBy) }}
|
||||||
|
{{ Former::text('start_date') }}
|
||||||
|
{{ Former::text('end_date') }}
|
||||||
|
{{ Former::actions( Button::primary_submit('Generate') ) }}
|
||||||
|
{{ Former::close() }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-9">
|
||||||
|
<canvas id="monthly-reports" width="850" height="400"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var ctx = document.getElementById('monthly-reports').getContext('2d');
|
||||||
|
var chart = {
|
||||||
|
labels: {{ json_encode($labels) }},
|
||||||
|
datasets: [
|
||||||
|
@foreach ($datasets as $dataset)
|
||||||
|
{
|
||||||
|
data: {{ json_encode($dataset['totals']) }},
|
||||||
|
fillColor : "rgba({{ $dataset['colors'] }},0.5)",
|
||||||
|
strokeColor : "rgba({{ $dataset['colors'] }},1)",
|
||||||
|
},
|
||||||
|
@endforeach
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
scaleOverride: true,
|
||||||
|
scaleSteps: 10,
|
||||||
|
scaleStepWidth: {{ $scaleStepWidth }},
|
||||||
|
scaleStartValue: 0,
|
||||||
|
scaleLabel : "<%=formatMoney(value)%>",
|
||||||
|
};
|
||||||
|
|
||||||
|
new Chart(ctx).{{ $chartType }}(chart, options);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('onReady')
|
||||||
|
|
||||||
|
$('#start_date, #end_date').datepicker({
|
||||||
|
autoclose: true,
|
||||||
|
todayHighlight: true
|
||||||
|
});
|
||||||
|
|
||||||
|
@stop
|
Loading…
x
Reference in New Issue
Block a user