mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-10-12 15:35:15 +00:00
All kinds of fixes and things. I should really start organizing.
This commit is contained in:
@@ -1,11 +1,62 @@
|
||||
<?php
|
||||
use Carbon\Carbon;
|
||||
use Firefly\Exception\FireflyException;
|
||||
|
||||
/**
|
||||
* Class GoogleTableController
|
||||
*/
|
||||
class GoogleTableController extends BaseController
|
||||
{
|
||||
|
||||
/**
|
||||
* @param $what
|
||||
*
|
||||
* @throws FireflyException
|
||||
*/
|
||||
public function accountList($what)
|
||||
{
|
||||
|
||||
/** @var \FireflyIII\Database\Account $acct */
|
||||
$acct = App::make('FireflyIII\Database\Account');
|
||||
|
||||
switch ($what) {
|
||||
default:
|
||||
throw new FireflyException('Cannot handle "' . e($what) . '" in accountList.');
|
||||
break;
|
||||
case 'asset':
|
||||
$list = $acct->getAssetAccounts();
|
||||
break;
|
||||
case 'expense':
|
||||
$list = $acct->getExpenseAccounts();
|
||||
break;
|
||||
case 'revenue':
|
||||
$list = $acct->getRevenueAccounts();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$chart = App::make('gchart');
|
||||
$chart->addColumn('ID', 'number');
|
||||
$chart->addColumn('ID_Edit', 'string');
|
||||
$chart->addColumn('ID_Delete', 'string');
|
||||
$chart->addColumn('Name_URL', 'string');
|
||||
$chart->addColumn('Name', 'string');
|
||||
$chart->addColumn('Balance', 'number');
|
||||
|
||||
/** @var \Account $entry */
|
||||
foreach ($list as $entry) {
|
||||
$edit = route('accounts.edit', $entry->id);
|
||||
$delete = route('accounts.delete', $entry->id);
|
||||
$show = route('accounts.show', $entry->id);
|
||||
$chart->addRow($entry->id, $edit, $delete, $show, $entry->name, $entry->balance());
|
||||
}
|
||||
|
||||
$chart->generate();
|
||||
return Response::json($chart->getData());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Account $account
|
||||
*/
|
||||
|
@@ -15,8 +15,8 @@ class HomeController extends BaseController
|
||||
protected $_journal;
|
||||
|
||||
/**
|
||||
* @param ARI $accounts
|
||||
* @param PHI $preferences
|
||||
* @param ARI $accounts
|
||||
* @param PHI $preferences
|
||||
* @param TJRI $journal
|
||||
*/
|
||||
public function __construct(ARI $accounts, PHI $preferences, TJRI $journal)
|
||||
@@ -115,4 +115,59 @@ class HomeController extends BaseController
|
||||
return View::make('index')->with('count', $count)->with('transactions', $transactions)->with('title', 'Firefly')
|
||||
->with('subTitle', 'What\'s playing?')->with('mainTitleIcon', 'fa-fire');
|
||||
}
|
||||
|
||||
public function cleanup()
|
||||
{
|
||||
/** @var \FireflyIII\Database\TransactionJournal $jrnls */
|
||||
$jrnls = App::make('FireflyIII\Database\TransactionJournal');
|
||||
|
||||
/** @var \FireflyIII\Database\Account $acct */
|
||||
$acct = \App::make('FireflyIII\Database\Account');
|
||||
|
||||
/** @var \FireflyIII\Database\AccountType $acctType */
|
||||
$acctType = \App::make('FireflyIII\Database\AccountType');
|
||||
$rightAcctType = $acctType->findByWhat('revenue');
|
||||
|
||||
$all = $jrnls->get();
|
||||
|
||||
/** @var \TransactionJournal $entry */
|
||||
foreach ($all as $entry) {
|
||||
$wrongFromType = false;
|
||||
$wrongToType = false;
|
||||
$transactions = $entry->transactions;
|
||||
if (count($transactions) == 2) {
|
||||
switch ($entry->transactionType->type) {
|
||||
case 'Deposit':
|
||||
/** @var \Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
if (floatval($transaction->amount) < 0) {
|
||||
$accountType = $transaction->account->accountType;
|
||||
if ($accountType->type == 'Beneficiary account') {
|
||||
// should be a Revenue account!
|
||||
$name = $transaction->account->name;
|
||||
/** @var \Account $account */
|
||||
$account = \Auth::user()->accounts()->where('name', $name)->where('account_type_id', $rightAcctType->id)->first();
|
||||
if (!$account) {
|
||||
$new = [
|
||||
'name' => $name,
|
||||
'what' => 'revenue'
|
||||
];
|
||||
$account = $acct->store($new);
|
||||
}
|
||||
$transaction->account()->associate($account);
|
||||
$transaction->save();
|
||||
}
|
||||
|
||||
echo 'Paid by: ' . $transaction->account->name . ' (' . $transaction->account->accountType->type . ')<br />';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -123,11 +123,7 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
|
||||
/*
|
||||
* If present, process parameters for sorting:
|
||||
*/
|
||||
if (isset($parameters['order'])) {
|
||||
foreach ($parameters['order'] as $instr) {
|
||||
$query->orderBy($instr['name'], $instr['dir']);
|
||||
}
|
||||
}
|
||||
$query->orderBy('name', 'ASC');
|
||||
|
||||
/*
|
||||
* If present, process parameters for searching.
|
||||
|
@@ -8,7 +8,6 @@ use LaravelBook\Ardent\Ardent;
|
||||
use FireflyIII\Database\Ifaces\AccountTypeInterface;
|
||||
use FireflyIII\Database\Ifaces\CommonDatabaseCalls;
|
||||
use FireflyIII\Database\Ifaces\CUD;
|
||||
use FireflyIII\Database\Ifaces\AccountTypeInterface;
|
||||
|
||||
/**
|
||||
* Class AccountType
|
||||
|
@@ -289,7 +289,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// TODO: Implement get() method.
|
||||
return $this->getUser()->transactionjournals()->get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -128,6 +128,7 @@ Route::group(
|
||||
Route::get('/prev', ['uses' => 'HomeController@sessionPrev', 'as' => 'sessionPrev']);
|
||||
Route::get('/next', ['uses' => 'HomeController@sessionNext', 'as' => 'sessionNext']);
|
||||
Route::get('/jump/{range}', ['uses' => 'HomeController@rangeJump', 'as' => 'rangeJump']);
|
||||
Route::get('/cleanup', ['uses' => 'HomeController@cleanup', 'as' => 'cleanup']);
|
||||
|
||||
// account controller:
|
||||
Route::get('/accounts/json/{what}', ['uses' => 'AccountController@json', 'as' => 'accounts.json'])->where('what', 'revenue|asset|expense');
|
||||
@@ -170,6 +171,7 @@ Route::group(
|
||||
|
||||
// google table controller
|
||||
Route::get('/table/account/{account}/transactions', ['uses' => 'GoogleTableController@transactionsByAccount']);
|
||||
Route::get('/table/accounts/{what}', ['uses' => 'GoogleTableController@accountList']);
|
||||
|
||||
|
||||
Route::get('/chart/home/info/{accountnameA}/{day}/{month}/{year}', ['uses' => 'ChartController@homeAccountInfo', 'as' => 'chart.info']);
|
||||
|
@@ -1,18 +0,0 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<p>
|
||||
<a href="{{route('accounts.create','asset')}}" class="btn btn-success btn-large">Create a new asset account</a>
|
||||
</p>
|
||||
@if(count($accounts) > 0)
|
||||
@include('accounts.list')
|
||||
<p>
|
||||
<a href="{{route('accounts.create','asset')}}" class="btn btn-success btn-large">Create a new asset account</a>
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div> <!-- TODO remove me -->
|
||||
|
||||
@stop
|
@@ -1,28 +0,0 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<p class="lead">
|
||||
Bla bla expense
|
||||
</p>
|
||||
<p class="text-info">
|
||||
Bla bla bla expense
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<p>
|
||||
<a href="{{route('accounts.create','expense')}}" class="btn btn-success">Create a new expense account</a>
|
||||
</p>
|
||||
@if(count($accounts) > 0)
|
||||
@include('accounts.list')
|
||||
<p>
|
||||
<a href="{{route('accounts.create','expense')}}" class="btn btn-success">Create a new expense account</a>
|
||||
</p>
|
||||
@endif
|
||||
</div><!-- TODO remove me -->
|
||||
|
||||
</div>
|
||||
|
||||
@stop
|
@@ -22,29 +22,25 @@
|
||||
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table id="accountTable" class="table table-striped table-bordered" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>balance</th>
|
||||
<th>ID</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div id="account-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
@section('scripts')
|
||||
{{HTML::script('assets/javascript/datatables/jquery.dataTables.min.js')}}
|
||||
{{HTML::script('assets/javascript/datatables/dataTables.bootstrap.js')}}
|
||||
<script type="text/javascript">
|
||||
var URL = '{{route('accounts.json',e($what))}}';
|
||||
var what = '{{{$what}}}';
|
||||
</script>
|
||||
|
||||
<!-- load the libraries and scripts necessary for Google Charts: -->
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||
{{HTML::script('assets/javascript/firefly/gcharts.options.js')}}
|
||||
{{HTML::script('assets/javascript/firefly/gcharts.js')}}
|
||||
|
||||
|
||||
<script src="assets/javascript/firefly/accounts.js"></script>
|
||||
@stop
|
||||
|
||||
@section('styles')
|
||||
{{HTML::style('assets/stylesheets/datatables/dataTables.bootstrap.css')}}
|
||||
@endsection
|
@@ -1,26 +0,0 @@
|
||||
<table class="table table-bordered table-striped">
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th style="width:30%;">Name</th>
|
||||
<th>Current balance</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
@foreach($accounts as $account)
|
||||
<tr>
|
||||
<td>
|
||||
@if($account->active == 0)
|
||||
<span title="This account is inactive." class="glyphicon glyphicon-ban-circle"></span>
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{route('accounts.show',$account->id)}}" title="Overview for account {{{$account->name}}}">{{{$account->name}}}</a></td>
|
||||
<td>{{mf($account->balance())}}</td>
|
||||
<td>
|
||||
<span class="btn-group-xs btn-group">
|
||||
<a href="{{route('accounts.edit',$account->id)}}" title="Edit {{{$account->name}}}" class="btn btn-default"><span class="glyphicon glyphicon-pencil"></span></a>
|
||||
<a href="{{route('accounts.delete',$account->id)}}" title="Edit {{{$account->name}}}" class="btn btn-danger"><span class="glyphicon glyphicon-trash"></span></a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table><!-- TODO remove me -->
|
@@ -1,28 +0,0 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<p class="lead">
|
||||
Bla bla revenue
|
||||
</p>
|
||||
<p class="text-info">
|
||||
Bla bla bla revenue
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<p>
|
||||
<a href="{{route('accounts.create','revenue')}}" class="btn btn-success">Create a new revenue account</a>
|
||||
</p>
|
||||
@if(count($accounts) > 0)
|
||||
@include('accounts.list')
|
||||
<p>
|
||||
<a href="{{route('accounts.create','revenue')}}" class="btn btn-success">Create a new revenue account</a>
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- TODO remove me -->
|
||||
@stop
|
@@ -1,44 +0,0 @@
|
||||
@extends('layouts.default')
|
||||
@section('content')
|
||||
|
||||
|
||||
<div id="sankey_multiple" style="width: 900px; height: 400px;"></div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@stop
|
||||
@section('scripts')
|
||||
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['sankey']}]}">
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
google.setOnLoadCallback(drawChart);
|
||||
function drawChart() {
|
||||
var data = new google.visualization.DataTable();
|
||||
data.addColumn('string', 'From');
|
||||
data.addColumn('string', 'To');
|
||||
data.addColumn('number', 'Weight');
|
||||
data.addRows([
|
||||
<?php $c = 0;?>
|
||||
@foreach($filtered as $index => $entry)
|
||||
[ '{{{$entry['from']}}}', '{{{$entry['to']}}}', {{{$entry['amount']}}} ], // {{$c}}
|
||||
<?php $c++ ?>
|
||||
@endforeach
|
||||
|
||||
]);
|
||||
|
||||
// Set chart options
|
||||
var options = {
|
||||
sankey: {
|
||||
link: { color: { fill: '#9fa8da', fillOpacity: 0.8 } },
|
||||
node: { color: { fill: '#000' },
|
||||
label: { color: '#000' } }
|
||||
}
|
||||
};
|
||||
|
||||
// Instantiate and draw our chart, passing in some options.
|
||||
var chart = new google.visualization.Sankey(document.getElementById('sankey_multiple'));
|
||||
chart.draw(data, options);
|
||||
}
|
||||
</script><!-- TODO remove me -->
|
||||
@stop
|
BIN
public/assets/images/error.png
Executable file
BIN
public/assets/images/error.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 666 B |
@@ -1,145 +1,20 @@
|
||||
$(function () {
|
||||
|
||||
if (typeof(googleLineChart) == "function") {
|
||||
if (typeof(googleLineChart) == "function" && typeof accountID != 'undefined') {
|
||||
googleLineChart('chart/account/' + accountID, 'overview-chart');
|
||||
}
|
||||
//
|
||||
if(typeof(googleSankeyChart) == 'function') {
|
||||
googleSankeyChart('chart/sankey/' + accountID + '/out','account-out-sankey');
|
||||
googleSankeyChart('chart/sankey/' + accountID + '/in','account-in-sankey');
|
||||
if (typeof(googleSankeyChart) == 'function' && typeof accountID != 'undefined') {
|
||||
googleSankeyChart('chart/sankey/' + accountID + '/out', 'account-out-sankey');
|
||||
googleSankeyChart('chart/sankey/' + accountID + '/in', 'account-in-sankey');
|
||||
}
|
||||
if(typeof(googleTable) == 'function') {
|
||||
googleTable('table/account/' + accountID + '/transactions','account-transactions');
|
||||
if (typeof(googleTable) == 'function') {
|
||||
if (typeof accountID != 'undefined') {
|
||||
googleTable('table/account/' + accountID + '/transactions', 'account-transactions');
|
||||
}
|
||||
if (typeof what != 'undefined') {
|
||||
googleTable('table/accounts/' + what, 'account-list');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($('#accountTable').length == 1) {
|
||||
drawDatatable();
|
||||
}
|
||||
//if ($('#overviewChart').length == 1) {
|
||||
// drawOverviewChart();
|
||||
//}
|
||||
|
||||
});
|
||||
|
||||
function drawDatatable() {
|
||||
var opt = {
|
||||
serverSide: true,
|
||||
ajax: URL,
|
||||
paging: true,
|
||||
processing: true,
|
||||
columns: [
|
||||
{
|
||||
name: 'name',
|
||||
data: 'name',
|
||||
searchable: true,
|
||||
render: function (data) {
|
||||
return '<a href="' + data.url + '">' + data.name + '</a>';
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
name: 'balance',
|
||||
data: 'balance',
|
||||
title: 'Amount (\u20AC)',
|
||||
searchable: false,
|
||||
sortable: true,
|
||||
render: function (data) {
|
||||
var amount = parseInt(data);
|
||||
if (amount < 0) {
|
||||
'<span class="text-danger">\u20AC ' + data.toFixed(2) + '</span>'
|
||||
}
|
||||
if (amount > 0) {
|
||||
'<span class="text-info">\u20AC ' + data.toFixed(2) + '</span>'
|
||||
}
|
||||
return '<span class="text-info">\u20AC ' + data.toFixed(2) + '</span>'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'id',
|
||||
data: 'id',
|
||||
title: '',
|
||||
render: function (data) {
|
||||
return '<div class="btn-group btn-group-xs">' +
|
||||
'<a class="btn btn-default btn-xs" href="' + data.edit + '">' +
|
||||
'<span class="glyphicon glyphicon-pencil"</a>' +
|
||||
'<a class="btn btn-danger btn-xs" href="' + data.delete + '">' +
|
||||
'<span class="glyphicon glyphicon-trash"</a>' +
|
||||
'</a></div>';
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
$('#accountTable').DataTable(opt);
|
||||
}
|
||||
|
||||
|
||||
function drawOverviewChart() {
|
||||
$.getJSON('chart/home/account/' + accountID).success(function (data) {
|
||||
var options = {
|
||||
chart: {
|
||||
renderTo: 'overviewChart',
|
||||
type: 'spline'
|
||||
},
|
||||
|
||||
series: data.series,
|
||||
title: {
|
||||
text: null
|
||||
},
|
||||
yAxis: {
|
||||
allowDecimals: false,
|
||||
labels: {
|
||||
formatter: function () {
|
||||
if (this.value >= 1000 || this.value <= -1000) {
|
||||
return '\u20AC ' + (this.value / 1000) + 'k';
|
||||
}
|
||||
return '\u20AC ' + this.value;
|
||||
|
||||
}
|
||||
},
|
||||
title: {text: null}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'datetime',
|
||||
dateTimeLabelFormats: {
|
||||
day: '%e %b',
|
||||
week: '%e %b'
|
||||
},
|
||||
title: {
|
||||
text: null
|
||||
}
|
||||
},
|
||||
legend: {enabled: false},
|
||||
tooltip: {
|
||||
formatter: function () {
|
||||
return this.series.name + ': \u20AC ' + Highcharts.numberFormat(this.y, 2);
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
line: {
|
||||
shadow: true
|
||||
},
|
||||
series: {
|
||||
cursor: 'pointer',
|
||||
negativeColor: '#FF0000',
|
||||
threshold: 0,
|
||||
lineWidth: 1,
|
||||
marker: {
|
||||
radius: 0
|
||||
},
|
||||
point: {
|
||||
events: {
|
||||
click: function (e) {
|
||||
alert('click!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
credits: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
$('#overviewChart').highcharts(options);
|
||||
});
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
google.load('visualization', '1.1', {'packages': ['corechart', 'bar','sankey', 'table']});
|
||||
google.load('visualization', '1.1', {'packages': ['corechart', 'bar', 'sankey', 'table']});
|
||||
|
||||
function googleLineChart(URL, container) {
|
||||
$.getJSON(URL).success(function (data) {
|
||||
@@ -187,24 +187,24 @@ function googleTable(URL, container) {
|
||||
/*
|
||||
Format a string using the previous column as URL.
|
||||
*/
|
||||
if (label == 'Description' || label == 'From' || label == 'To' || label == 'Budget' || label == 'Category') {
|
||||
if (label == 'Description' || label == 'From' || label == 'Name' || label == 'To' || label == 'Budget' || label == 'Category') {
|
||||
URLFormatter.format(gdata, [i - 1, i], i);
|
||||
columnsToHide.push(i - 1);
|
||||
}
|
||||
if(label == 'ID') {
|
||||
EditButtonFormatter.format(gdata, [i+1,i+2],i);
|
||||
columnsToHide.push(i+1,i+2);
|
||||
if (label == 'ID') {
|
||||
EditButtonFormatter.format(gdata, [i + 1, i + 2], i);
|
||||
columnsToHide.push(i + 1, i + 2);
|
||||
}
|
||||
|
||||
/*
|
||||
Format with buttons:
|
||||
Format with buttons:
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Format as money
|
||||
*/
|
||||
if (label == 'Amount') {
|
||||
if (label == 'Amount' || label == 'Balance') {
|
||||
money.format(gdata, i);
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,8 @@ body {
|
||||
}
|
||||
|
||||
.google-chart-error {
|
||||
border:1px red solid;height:20px;
|
||||
height:30px;
|
||||
background:url('../../images/error.png') no-repeat center center
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
|
Reference in New Issue
Block a user