mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-18 18:44:16 +00:00
Merge branch 'release/3.2.0'
Conflicts: app/config/app.php
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -18,3 +18,4 @@ firefly-iii-import-*.json
|
|||||||
tests/_output/*
|
tests/_output/*
|
||||||
testing.sqlite
|
testing.sqlite
|
||||||
c3.php
|
c3.php
|
||||||
|
_ide_helper_models.php
|
||||||
|
@@ -18,8 +18,8 @@ return [
|
|||||||
],
|
],
|
||||||
|
|
||||||
'accountRoles' => [
|
'accountRoles' => [
|
||||||
'default' => 'Default expense account',
|
'defaultExpense' => 'Default expense account',
|
||||||
'sharedExpense' => 'Shared expense account'
|
'sharedExpense' => 'Shared expense account'
|
||||||
],
|
],
|
||||||
|
|
||||||
'range_to_text' => [
|
'range_to_text' => [
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use FireflyIII\Database\Account as AccountRepository;
|
||||||
use FireflyIII\Exception\FireflyException;
|
use FireflyIII\Exception\FireflyException;
|
||||||
use Illuminate\Support\MessageBag;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
@@ -9,11 +9,53 @@ use Illuminate\Support\MessageBag;
|
|||||||
class AccountController extends BaseController
|
class AccountController extends BaseController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $_accountTypesByIdentifier
|
||||||
|
= [
|
||||||
|
'asset' => ['Default account', 'Asset account'],
|
||||||
|
'expense' => ['Expense account', 'Beneficiary account'],
|
||||||
|
'revenue' => ['Revenue account'],
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var AccountRepository */
|
||||||
|
protected $_repository;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $_shortNamesByFullName
|
||||||
|
= [
|
||||||
|
'Default account' => 'asset',
|
||||||
|
'Asset account' => 'asset',
|
||||||
|
'Expense account' => 'expense',
|
||||||
|
'Beneficiary account' => 'expense',
|
||||||
|
'Revenue account' => 'revenue',
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $_subIconsByIdentifier
|
||||||
|
= [
|
||||||
|
'asset' => 'fa-money',
|
||||||
|
'Asset account' => 'fa-money',
|
||||||
|
'Default account' => 'fa-money',
|
||||||
|
'expense' => 'fa-shopping-cart',
|
||||||
|
'Expense account' => 'fa-shopping-cart',
|
||||||
|
'Beneficiary account' => 'fa-shopping-cart',
|
||||||
|
'revenue' => 'fa-download',
|
||||||
|
'Revenue account' => 'fa-download',
|
||||||
|
];
|
||||||
|
/** @var array */
|
||||||
|
protected $_subTitlesByIdentifier
|
||||||
|
= [
|
||||||
|
'asset' => 'Asset accounts',
|
||||||
|
'expense' => 'Expense accounts',
|
||||||
|
'revenue' => 'Revenue accounts',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param AccountRepository $repository
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(AccountRepository $repository)
|
||||||
{
|
{
|
||||||
|
$this->_repository = $repository;
|
||||||
View::share('mainTitleIcon', 'fa-credit-card');
|
View::share('mainTitleIcon', 'fa-credit-card');
|
||||||
View::share('title', 'Accounts');
|
View::share('title', 'Accounts');
|
||||||
}
|
}
|
||||||
@@ -25,18 +67,8 @@ class AccountController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function create($what)
|
public function create($what)
|
||||||
{
|
{
|
||||||
switch ($what) {
|
$subTitleIcon = $this->_subIconsByIdentifier[$what];
|
||||||
case 'asset':
|
$subTitle = 'Create a new ' . $what . ' account';
|
||||||
$subTitleIcon = 'fa-money';
|
|
||||||
break;
|
|
||||||
case 'expense':
|
|
||||||
$subTitleIcon = 'fa-shopping-cart';
|
|
||||||
break;
|
|
||||||
case 'revenue':
|
|
||||||
$subTitleIcon = 'fa-download';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$subTitle = 'Create a new ' . $what . ' account';
|
|
||||||
|
|
||||||
return View::make('accounts.create', compact('subTitleIcon', 'what', 'subTitle'));
|
return View::make('accounts.create', compact('subTitleIcon', 'what', 'subTitle'));
|
||||||
}
|
}
|
||||||
@@ -61,28 +93,15 @@ class AccountController extends BaseController
|
|||||||
public function destroy(Account $account)
|
public function destroy(Account $account)
|
||||||
{
|
{
|
||||||
|
|
||||||
$type = $account->accountType->type;
|
$type = $account->accountType->type;
|
||||||
$name = $account->name;
|
$typeName = $this->_shortNamesByFullName[$type];
|
||||||
|
$name = $account->name;
|
||||||
|
|
||||||
/** @var \FireflyIII\Database\Account $acct */
|
$this->_repository->destroy($account);
|
||||||
$acct = App::make('FireflyIII\Database\Account');
|
|
||||||
|
|
||||||
$acct->destroy($account);
|
Session::flash('success', 'The ' . $typeName . ' account "' . e($name) . '" was deleted.');
|
||||||
|
|
||||||
$return = 'asset';
|
return Redirect::route('accounts.index', $type);
|
||||||
switch ($type) {
|
|
||||||
case 'Expense account':
|
|
||||||
case 'Beneficiary account':
|
|
||||||
$return = 'expense';
|
|
||||||
break;
|
|
||||||
case 'Revenue account':
|
|
||||||
$return = 'revenue';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', 'The ' . $return . ' account "' . e($name) . '" was deleted.');
|
|
||||||
|
|
||||||
return Redirect::route('accounts.index', $return);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,42 +111,24 @@ class AccountController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function edit(Account $account)
|
public function edit(Account $account)
|
||||||
{
|
{
|
||||||
$prefilled = [];
|
|
||||||
|
|
||||||
switch ($account->accountType->type) {
|
$openingBalance = $this->_repository->openingBalanceTransaction($account);
|
||||||
case 'Asset account':
|
$subTitleIcon = $this->_subIconsByIdentifier[$account->accountType->type];
|
||||||
case 'Default account':
|
$subTitle = 'Edit ' . strtolower($account->accountType->type) . ' "' . $account->name . '"';
|
||||||
$subTitleIcon = 'fa-money';
|
|
||||||
$prefilled['account_role'] = $account->getMeta('accountRole');
|
|
||||||
break;
|
|
||||||
case 'Expense account':
|
|
||||||
case 'Beneficiary account':
|
|
||||||
$subTitleIcon = 'fa-shopping-cart';
|
|
||||||
break;
|
|
||||||
case 'Revenue account':
|
|
||||||
$subTitleIcon = 'fa-download';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var \FireflyIII\Database\Account $acct */
|
// pre fill some useful values.
|
||||||
$acct = App::make('FireflyIII\Database\Account');
|
$preFilled = [
|
||||||
|
'account_role' => $account->getMeta('accountRole'),
|
||||||
|
'openingBalanceDate' => $openingBalance ? $openingBalance->date->format('Y-m-d') : null,
|
||||||
|
'openingBalance' => $openingBalance ? $openingBalance->getAmount($account) : null
|
||||||
|
];
|
||||||
|
Session::flash('preFilled', $preFilled);
|
||||||
|
|
||||||
$openingBalance = $acct->openingBalanceTransaction($account);
|
return View::make('accounts.edit', compact('account', 'subTitle', 'openingBalance', 'subTitleIcon'));
|
||||||
Session::forget('prefilled');
|
|
||||||
if (!is_null($openingBalance)) {
|
|
||||||
$prefilled['openingbalancedate'] = $openingBalance->date->format('Y-m-d');
|
|
||||||
$prefilled['openingbalance'] = floatval($openingBalance->transactions()->where('account_id', $account->id)->first()->amount);
|
|
||||||
}
|
|
||||||
Session::flash('prefilled', $prefilled);
|
|
||||||
|
|
||||||
return View::make('accounts.edit', compact('account', 'openingBalance', 'subTitleIcon'))->with(
|
|
||||||
'subTitle', 'Edit ' . strtolower(
|
|
||||||
$account->accountType->type
|
|
||||||
) . ' "' . $account->name . '"'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
*
|
||||||
* @param string $what
|
* @param string $what
|
||||||
*
|
*
|
||||||
* @return View
|
* @return View
|
||||||
@@ -135,94 +136,28 @@ class AccountController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function index($what = 'default')
|
public function index($what = 'default')
|
||||||
{
|
{
|
||||||
/** @var \FireflyIII\Database\Account $acct */
|
$subTitle = $this->_subTitlesByIdentifier[$what];
|
||||||
$acct = App::make('FireflyIII\Database\Account');
|
$subTitleIcon = $this->_subIconsByIdentifier[$what];
|
||||||
|
|
||||||
switch ($what) {
|
$accounts = $this->_repository->getAccountsByType($this->_accountTypesByIdentifier[$what]);
|
||||||
default:
|
|
||||||
throw new FireflyException('Cannot handle account type "' . e($what) . '".');
|
|
||||||
break;
|
|
||||||
case 'asset':
|
|
||||||
$subTitleIcon = 'fa-money';
|
|
||||||
$subTitle = 'Asset accounts';
|
|
||||||
$accounts = $acct->getAssetAccounts();
|
|
||||||
break;
|
|
||||||
case 'expense':
|
|
||||||
$subTitleIcon = 'fa-shopping-cart';
|
|
||||||
$subTitle = 'Expense accounts';
|
|
||||||
$accounts = $acct->getExpenseAccounts();
|
|
||||||
break;
|
|
||||||
case 'revenue':
|
|
||||||
$subTitleIcon = 'fa-download';
|
|
||||||
$subTitle = 'Revenue accounts';
|
|
||||||
$accounts = $acct->getRevenueAccounts();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$accounts->each(
|
|
||||||
function (Account $account) {
|
|
||||||
if (Cache::has('account.' . $account->id . '.lastActivityDate')) {
|
|
||||||
$account->lastActionDate = Cache::get('account.' . $account->id . '.lastActivityDate');
|
|
||||||
} else {
|
|
||||||
$transaction = $account->transactions()->orderBy('updated_at', 'DESC')->first();
|
|
||||||
if (is_null($transaction)) {
|
|
||||||
$account->lastActionDate = null;
|
|
||||||
Cache::forever('account.' . $account->id . '.lastActivityDate', 0);
|
|
||||||
} else {
|
|
||||||
$account->lastActionDate = $transaction->updated_at;
|
|
||||||
Cache::forever('account.' . $account->id . '.lastActivityDate', $transaction->updated_at);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return View::make('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts'));
|
return View::make('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Account $account
|
* @param Account $account
|
||||||
* @param string $view
|
* @param string $range
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function show(Account $account, $view = 'session')
|
public function show(Account $account, $range = 'session')
|
||||||
{
|
{
|
||||||
switch ($account->accountType->type) {
|
$subTitleIcon = $this->_subIconsByIdentifier[$account->accountType->type];
|
||||||
case 'Asset account':
|
$what = $this->_shortNamesByFullName[$account->accountType->type];
|
||||||
case 'Default account':
|
$journals = $this->_repository->getTransactionJournals($account, 50, $range);
|
||||||
$subTitleIcon = 'fa-money';
|
$subTitle = 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"';
|
||||||
$what = 'asset';
|
|
||||||
break;
|
|
||||||
case 'Expense account':
|
|
||||||
case 'Beneficiary account':
|
|
||||||
$subTitleIcon = 'fa-shopping-cart';
|
|
||||||
$what = 'expense';
|
|
||||||
break;
|
|
||||||
case 'Revenue account':
|
|
||||||
$subTitleIcon = 'fa-download';
|
|
||||||
$what = 'revenue';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get a paginated view of all transactions for this account:
|
return View::make('accounts.show', compact('account', 'what', 'range', 'subTitleIcon', 'journals', 'subTitle'));
|
||||||
/** @var \FireflyIII\Database\Account $acct */
|
|
||||||
$acct = App::make('FireflyIII\Database\Account');
|
|
||||||
switch ($view) {
|
|
||||||
default:
|
|
||||||
case 'session':
|
|
||||||
$journals = $acct->getTransactionJournals($account, 50);
|
|
||||||
break;
|
|
||||||
case 'all':
|
|
||||||
$journals = $acct->getAllTransactionJournals($account, 50);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return View::make('accounts.show', compact('account', 'what', 'view', 'subTitleIcon', 'journals'))->with('account', $account)->with(
|
|
||||||
'subTitle', 'Details for ' . strtolower($account->accountType->type) . ' "' . $account->name . '"'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,45 +167,36 @@ class AccountController extends BaseController
|
|||||||
public function store()
|
public function store()
|
||||||
{
|
{
|
||||||
|
|
||||||
$data = Input::all();
|
$data = Input::except('_token');
|
||||||
$data['what'] = isset($data['what']) && $data['what'] != '' ? $data['what'] : 'asset';
|
|
||||||
/** @var \FireflyIII\Database\Account $acct */
|
|
||||||
$acct = App::make('FireflyIII\Database\Account');
|
|
||||||
|
|
||||||
switch ($data['post_submit_action']) {
|
// always validate:
|
||||||
default:
|
$messages = $this->_repository->validate($data);
|
||||||
throw new FireflyException('Cannot handle post_submit_action "' . e($data['post_submit_action']) . '"');
|
|
||||||
break;
|
|
||||||
case 'return_to_edit':
|
|
||||||
case 'store':
|
|
||||||
$messages = $acct->validate($data);
|
|
||||||
/** @var MessageBag $messages ['errors'] */
|
|
||||||
if ($messages['errors']->count() > 0) {
|
|
||||||
Session::flash('warnings', $messages['warnings']);
|
|
||||||
Session::flash('successes', $messages['successes']);
|
|
||||||
Session::flash('error', 'Could not save account: ' . $messages['errors']->first());
|
|
||||||
|
|
||||||
return Redirect::route('accounts.create', $data['what'])->withInput()->withErrors($messages['errors']);
|
// flash messages:
|
||||||
}
|
Session::flash('warnings', $messages['warnings']);
|
||||||
// store!
|
Session::flash('successes', $messages['successes']);
|
||||||
$acct->store($data);
|
Session::flash('errors', $messages['errors']);
|
||||||
Session::flash('success', 'New account stored!');
|
if ($messages['errors']->count() > 0) {
|
||||||
|
Session::flash('error', 'Could not store account: ' . $messages['errors']->first());
|
||||||
if ($data['post_submit_action'] == 'create_another') {
|
|
||||||
return Redirect::route('accounts.create', $data['what']);
|
|
||||||
} else {
|
|
||||||
return Redirect::route('accounts.index', $data['what']);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'validate_only':
|
|
||||||
$messageBags = $acct->validate($data);
|
|
||||||
Session::flash('warnings', $messageBags['warnings']);
|
|
||||||
Session::flash('successes', $messageBags['successes']);
|
|
||||||
Session::flash('errors', $messageBags['errors']);
|
|
||||||
|
|
||||||
return Redirect::route('accounts.create', $data['what'])->withInput();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return to create screen:
|
||||||
|
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||||
|
return Redirect::route('accounts.create', $data['what'])->withInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
// store:
|
||||||
|
$this->_repository->store($data);
|
||||||
|
Session::flash('success', 'Account "' . e($data['name']) . '" stored.');
|
||||||
|
if ($data['post_submit_action'] == 'store') {
|
||||||
|
return Redirect::route('accounts.index', $data['what']);
|
||||||
|
}
|
||||||
|
// create another.
|
||||||
|
if ($data['post_submit_action'] == 'create_another') {
|
||||||
|
return Redirect::route('accounts.create', $data['what'])->withInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect::route('accounts.index', $data['what']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -281,62 +207,38 @@ class AccountController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function update(Account $account)
|
public function update(Account $account)
|
||||||
{
|
{
|
||||||
|
$data = Input::except('_token');
|
||||||
|
$data['what'] = $this->_shortNamesByFullName[$account->accountType->type];
|
||||||
|
|
||||||
/** @var \FireflyIII\Database\Account $acct */
|
// always validate:
|
||||||
$acct = App::make('FireflyIII\Database\Account');
|
$messages = $this->_repository->validate($data);
|
||||||
$data = Input::except('_token');
|
|
||||||
|
|
||||||
switch ($account->accountType->type) {
|
// flash messages:
|
||||||
default:
|
Session::flash('warnings', $messages['warnings']);
|
||||||
throw new FireflyException('Cannot handle account type "' . e($account->accountType->type) . '"');
|
Session::flash('successes', $messages['successes']);
|
||||||
break;
|
Session::flash('errors', $messages['errors']);
|
||||||
case 'Default account':
|
if ($messages['errors']->count() > 0) {
|
||||||
case 'Asset account':
|
Session::flash('error', 'Could not update account: ' . $messages['errors']->first());
|
||||||
$data['what'] = 'asset';
|
|
||||||
break;
|
|
||||||
case 'Expense account':
|
|
||||||
case 'Beneficiary account':
|
|
||||||
$data['what'] = 'expense';
|
|
||||||
break;
|
|
||||||
case 'Revenue account':
|
|
||||||
$data['what'] = 'revenue';
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Input::get('post_submit_action')) {
|
// return to update screen:
|
||||||
default:
|
if ($data['post_submit_action'] == 'validate_only' || $messages['errors']->count() > 0) {
|
||||||
throw new FireflyException('Cannot handle post_submit_action "' . e(Input::get('post_submit_action')) . '"');
|
return Redirect::route('accounts.edit', $account->id)->withInput();
|
||||||
break;
|
|
||||||
case 'create_another':
|
|
||||||
case 'update':
|
|
||||||
$messages = $acct->validate($data);
|
|
||||||
/** @var MessageBag $messages ['errors'] */
|
|
||||||
if ($messages['errors']->count() > 0) {
|
|
||||||
Session::flash('warnings', $messages['warnings']);
|
|
||||||
Session::flash('successes', $messages['successes']);
|
|
||||||
Session::flash('error', 'Could not save account: ' . $messages['errors']->first());
|
|
||||||
|
|
||||||
return Redirect::route('accounts.edit', $account->id)->withInput()->withErrors($messages['errors']);
|
|
||||||
}
|
|
||||||
// store!
|
|
||||||
$acct->update($account, $data);
|
|
||||||
Session::flash('success', 'Account updated!');
|
|
||||||
|
|
||||||
if ($data['post_submit_action'] == 'create_another') {
|
|
||||||
return Redirect::route('accounts.edit', $account->id);
|
|
||||||
} else {
|
|
||||||
return Redirect::route('accounts.index', $data['what']);
|
|
||||||
}
|
|
||||||
case 'validate_only':
|
|
||||||
$messageBags = $acct->validate($data);
|
|
||||||
Session::flash('warnings', $messageBags['warnings']);
|
|
||||||
Session::flash('successes', $messageBags['successes']);
|
|
||||||
Session::flash('errors', $messageBags['errors']);
|
|
||||||
|
|
||||||
return Redirect::route('accounts.edit', $account->id)->withInput();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update
|
||||||
|
$this->_repository->update($account, $data);
|
||||||
|
Session::flash('success', 'Account "' . e($data['name']) . '" updated.');
|
||||||
|
|
||||||
|
// go back to list
|
||||||
|
if ($data['post_submit_action'] == 'update') {
|
||||||
|
return Redirect::route('accounts.index', $data['what']);
|
||||||
|
}
|
||||||
|
// go back to update screen.
|
||||||
|
if ($data['post_submit_action'] == 'return_to_edit') {
|
||||||
|
return Redirect::route('accounts.edit', $account->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Redirect::route('accounts.index', $data['what']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@@ -1,21 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use FireflyIII\Database\Budget as BudgetRepository;
|
||||||
use FireflyIII\Exception\FireflyException;
|
use FireflyIII\Exception\FireflyException;
|
||||||
use Illuminate\Support\MessageBag;
|
use Illuminate\Support\MessageBag;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BudgetController
|
* Class BudgetController
|
||||||
*/
|
*/
|
||||||
class BudgetController extends BaseController
|
class BudgetController extends BaseController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** @var BudgetRepository */
|
||||||
|
protected $_repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @param BudgetRepository $repository
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(BudgetRepository $repository)
|
||||||
{
|
{
|
||||||
|
$this->_repository = $repository;
|
||||||
View::share('title', 'Budgets');
|
View::share('title', 'Budgets');
|
||||||
View::share('mainTitleIcon', 'fa-tasks');
|
View::share('mainTitleIcon', 'fa-tasks');
|
||||||
}
|
}
|
||||||
@@ -30,34 +33,8 @@ class BudgetController extends BaseController
|
|||||||
{
|
{
|
||||||
$amount = intval(Input::get('amount'));
|
$amount = intval(Input::get('amount'));
|
||||||
$date = Session::get('start');
|
$date = Session::get('start');
|
||||||
/** @var \Limit $limit */
|
$limit = $this->_repository->updateLimitAmount($budget, $date, $amount);
|
||||||
$limit = $budget->limits()->where('startdate', $date->format('Y-m-d'))->first();
|
|
||||||
if (!$limit) {
|
|
||||||
// create one!
|
|
||||||
$limit = new Limit;
|
|
||||||
$limit->budget()->associate($budget);
|
|
||||||
$limit->startdate = $date;
|
|
||||||
$limit->amount = $amount;
|
|
||||||
$limit->repeat_freq = 'monthly';
|
|
||||||
$limit->repeats = 0;
|
|
||||||
$limit->save();
|
|
||||||
/*
|
|
||||||
* A newly stored limit also created a limit repetition.
|
|
||||||
*/
|
|
||||||
Event::fire('limits.store', [$limit]);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if ($amount > 0) {
|
|
||||||
$limit->amount = $amount;
|
|
||||||
$limit->save();
|
|
||||||
/*
|
|
||||||
* An updated limit also updates the associated limit repetitions.
|
|
||||||
*/
|
|
||||||
Event::fire('limits.update', [$limit]);
|
|
||||||
} else {
|
|
||||||
$limit->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// try to find the limit repetition for this limit:
|
// try to find the limit repetition for this limit:
|
||||||
$repetition = $limit->limitrepetitions()->first();
|
$repetition = $limit->limitrepetitions()->first();
|
||||||
if ($repetition) {
|
if ($repetition) {
|
||||||
@@ -83,7 +60,9 @@ class BudgetController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function delete(Budget $budget)
|
public function delete(Budget $budget)
|
||||||
{
|
{
|
||||||
return View::make('budgets.delete')->with('budget', $budget)->with('subTitle', 'Delete budget "' . $budget->name . '"');
|
$subTitle = 'Delete budget "' . e($budget->name) . '"';
|
||||||
|
|
||||||
|
return View::make('budgets.delete', compact('budget', 'subTitle'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,10 +72,7 @@ class BudgetController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function destroy(Budget $budget)
|
public function destroy(Budget $budget)
|
||||||
{
|
{
|
||||||
/** @var \FireflyIII\Database\Budget $repos */
|
$this->_repository->destroy($budget);
|
||||||
$repos = App::make('FireflyIII\Database\Budget');
|
|
||||||
// remove budget
|
|
||||||
$repos->destroy($budget);
|
|
||||||
Session::flash('success', 'The budget was deleted.');
|
Session::flash('success', 'The budget was deleted.');
|
||||||
|
|
||||||
return Redirect::route('budgets.index');
|
return Redirect::route('budgets.index');
|
||||||
@@ -110,9 +86,9 @@ class BudgetController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function edit(Budget $budget)
|
public function edit(Budget $budget)
|
||||||
{
|
{
|
||||||
Session::flash('prefilled', ['name' => $budget->name]);
|
$subTitle = 'Edit budget "' . $budget->name . '"';
|
||||||
|
|
||||||
return View::make('budgets.edit')->with('budget', $budget)->with('subTitle', 'Edit budget "' . $budget->name . '"');
|
return View::make('budgets.edit', compact('budget', 'subTitle'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -103,16 +103,16 @@ class PiggybankController extends BaseController
|
|||||||
/*
|
/*
|
||||||
* Flash some data to fill the form.
|
* Flash some data to fill the form.
|
||||||
*/
|
*/
|
||||||
$prefilled = ['name' => $piggybank->name,
|
$preFilled = ['name' => $piggybank->name,
|
||||||
'account_id' => $piggybank->account_id,
|
'account_id' => $piggybank->account_id,
|
||||||
'targetamount' => $piggybank->targetamount,
|
'targetamount' => $piggybank->targetamount,
|
||||||
'targetdate' => !is_null($piggybank->targetdate) ? $piggybank->targetdate->format('Y-m-d') : null,
|
'targetdate' => !is_null($piggybank->targetdate) ? $piggybank->targetdate->format('Y-m-d') : null,
|
||||||
'reminder' => $piggybank->reminder,
|
'reminder' => $piggybank->reminder,
|
||||||
'remind_me' => intval($piggybank->remind_me) == 1 || !is_null($piggybank->reminder) ? true : false
|
'remind_me' => intval($piggybank->remind_me) == 1 || !is_null($piggybank->reminder) ? true : false
|
||||||
];
|
];
|
||||||
Session::flash('prefilled', $prefilled);
|
Session::flash('preFilled', $preFilled);
|
||||||
|
|
||||||
return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'prefilled'))->with('title', 'Piggybanks')->with(
|
return View::make('piggybanks.edit', compact('piggybank', 'accounts', 'periods', 'preFilled'))->with('title', 'Piggybanks')->with(
|
||||||
'mainTitleIcon', 'fa-sort-amount-asc'
|
'mainTitleIcon', 'fa-sort-amount-asc'
|
||||||
)->with('subTitle', 'Edit piggy bank "' . e($piggybank->name) . '"')->with('subTitleIcon', 'fa-pencil');
|
)->with('subTitle', 'Edit piggy bank "' . e($piggybank->name) . '"')->with('subTitleIcon', 'fa-pencil');
|
||||||
}
|
}
|
||||||
|
@@ -33,13 +33,13 @@ class ReminderController extends BaseController
|
|||||||
break;
|
break;
|
||||||
case 'Piggybank':
|
case 'Piggybank':
|
||||||
$amount = Reminders::amountForReminder($reminder);
|
$amount = Reminders::amountForReminder($reminder);
|
||||||
$prefilled = [
|
$preFilled = [
|
||||||
'amount' => round($amount, 2),
|
'amount' => round($amount, 2),
|
||||||
'description' => 'Money for ' . $reminder->remindersable->name,
|
'description' => 'Money for ' . $reminder->remindersable->name,
|
||||||
'piggybank_id' => $reminder->remindersable_id,
|
'piggybank_id' => $reminder->remindersable_id,
|
||||||
'account_to_id' => $reminder->remindersable->account_id
|
'account_to_id' => $reminder->remindersable->account_id
|
||||||
];
|
];
|
||||||
Session::flash('prefilled', $prefilled);
|
Session::flash('preFilled', $preFilled);
|
||||||
|
|
||||||
return Redirect::route('transactions.create', 'transfer');
|
return Redirect::route('transactions.create', 'transfer');
|
||||||
break;
|
break;
|
||||||
|
@@ -1,11 +1,41 @@
|
|||||||
<?php
|
<?php
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Database\Account as AccountRepository;
|
||||||
|
use FireflyIII\Database\Report as ReportRepository;
|
||||||
|
use FireflyIII\Database\TransactionJournal as TransactionJournalRepository;
|
||||||
|
use FireflyIII\Report\ReportInterface as ReportHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ReportController
|
* Class ReportController
|
||||||
*/
|
*/
|
||||||
class ReportController extends BaseController
|
class ReportController extends BaseController
|
||||||
{
|
{
|
||||||
|
/** @var AccountRepository */
|
||||||
|
protected $_accounts;
|
||||||
|
|
||||||
|
/** @var TransactionJournalRepository */
|
||||||
|
protected $_journals;
|
||||||
|
|
||||||
|
/** @var ReportHelper */
|
||||||
|
protected $_reports;
|
||||||
|
|
||||||
|
/** @var ReportRepository */
|
||||||
|
protected $_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AccountRepository $accounts
|
||||||
|
* @param TransactionJournalRepository $journals
|
||||||
|
* @param ReportHelper $reports
|
||||||
|
* @param ReportRepository $repository
|
||||||
|
*/
|
||||||
|
public function __construct(AccountRepository $accounts, TransactionJournalRepository $journals, ReportHelper $reports, ReportRepository $repository)
|
||||||
|
{
|
||||||
|
$this->_accounts = $accounts;
|
||||||
|
$this->_journals = $journals;
|
||||||
|
$this->_reports = $reports;
|
||||||
|
$this->_repository = $repository;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $year
|
* @param $year
|
||||||
@@ -115,38 +145,13 @@ class ReportController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
/** @var \FireflyIII\Database\TransactionJournal $journals */
|
$start = $this->_journals->firstDate();
|
||||||
$journals = App::make('FireflyIII\Database\TransactionJournal');
|
$months = $this->_reports->listOfMonths(clone $start);
|
||||||
/** @var TransactionJournal $journal */
|
$years = $this->_reports->listOfYears(clone $start);
|
||||||
$journal = $journals->first();
|
$title = 'Reports';
|
||||||
if (is_null($journal)) {
|
$mainTitleIcon = 'fa-line-chart';
|
||||||
$date = Carbon::now();
|
|
||||||
} else {
|
|
||||||
$date = clone $journal->date;
|
|
||||||
}
|
|
||||||
$years = [];
|
|
||||||
$months = [];
|
|
||||||
while ($date <= Carbon::now()) {
|
|
||||||
$years[] = $date->format('Y');
|
|
||||||
$date->addYear();
|
|
||||||
}
|
|
||||||
// months
|
|
||||||
if (is_null($journal)) {
|
|
||||||
$date = Carbon::now();
|
|
||||||
} else {
|
|
||||||
$date = clone $journal->date;
|
|
||||||
}
|
|
||||||
while ($date <= Carbon::now()) {
|
|
||||||
$months[] = [
|
|
||||||
'formatted' => $date->format('F Y'),
|
|
||||||
'month' => intval($date->format('m')),
|
|
||||||
'year' => intval($date->format('Y')),
|
|
||||||
];
|
|
||||||
$date->addMonth();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return View::make('reports.index', compact('years', 'months', 'title', 'mainTitleIcon'));
|
||||||
return View::make('reports.index', compact('years', 'months'))->with('title', 'Reports')->with('mainTitleIcon', 'fa-line-chart');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -235,40 +240,43 @@ class ReportController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function year($year)
|
public function year($year)
|
||||||
{
|
{
|
||||||
Config::set('app.debug', false);
|
|
||||||
try {
|
try {
|
||||||
$date = new Carbon('01-01-' . $year);
|
new Carbon('01-01-' . $year);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
App::abort(500);
|
App::abort(500);
|
||||||
}
|
}
|
||||||
$date = new Carbon('01-01-' . $year);
|
$date = new Carbon('01-01-' . $year);
|
||||||
|
$title = 'Reports';
|
||||||
|
$subTitle = $year;
|
||||||
|
$subTitleIcon = 'fa-bar-chart';
|
||||||
|
$mainTitleIcon = 'fa-line-chart';
|
||||||
|
|
||||||
/** @var \FireflyIII\Database\TransactionJournal $tj */
|
$balances = $this->_reports->yearBalanceReport($date);
|
||||||
$tj = App::make('FireflyIII\Database\TransactionJournal');
|
$groupedIncomes = $this->_reports->groupByRevenue($date, 'income');
|
||||||
|
$groupedExpenses = $this->_reports->groupByRevenue($date, 'expense');
|
||||||
|
|
||||||
/** @var \FireflyIII\Database\Account $accountRepository */
|
|
||||||
$accountRepository = App::make('FireflyIII\Database\Account');
|
|
||||||
|
|
||||||
/** @var \FireflyIII\Database\Report $reportRepository */
|
return View::make(
|
||||||
$reportRepository = App::make('FireflyIII\Database\Report');
|
'reports.year', compact('date', 'groupedIncomes', 'groupedExpenses', 'year', 'balances', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon')
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For this year, get:
|
||||||
|
* - the sum of all expenses.
|
||||||
|
* - the sum of all incomes
|
||||||
|
* - per month, the sum of all expenses
|
||||||
|
* - per month, the sum of all incomes
|
||||||
|
* - 2x for shared and not-shared alike.
|
||||||
|
*
|
||||||
|
* - balance difference for all accounts.
|
||||||
|
*/
|
||||||
|
|
||||||
$accounts = $accountRepository->getAssetAccounts();
|
$accounts = $accountRepository->getAssetAccounts();
|
||||||
|
|
||||||
// get some sums going
|
// get some sums going
|
||||||
$summary = [];
|
$summary = [];
|
||||||
|
|
||||||
/** @var \Account $account */
|
|
||||||
$accounts->each(
|
|
||||||
function (\Account $account) {
|
|
||||||
if ($account->getMeta('accountRole') == 'sharedExpense') {
|
|
||||||
$account->sharedExpense = true;
|
|
||||||
} else {
|
|
||||||
$account->sharedExpense = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
$end = clone $date;
|
$end = clone $date;
|
||||||
$end->endOfYear();
|
$end->endOfYear();
|
||||||
while ($date < $end) {
|
while ($date < $end) {
|
||||||
@@ -280,7 +288,7 @@ class ReportController extends BaseController
|
|||||||
$expenseShared = 0;
|
$expenseShared = 0;
|
||||||
|
|
||||||
foreach ($accounts as $account) {
|
foreach ($accounts as $account) {
|
||||||
if ($account->sharedExpense === true) {
|
if ($account->accountRole == 'sharedExpense') {
|
||||||
$incomeShared += $reportRepository->getIncomeByMonth($account, $date);
|
$incomeShared += $reportRepository->getIncomeByMonth($account, $date);
|
||||||
$expenseShared += $reportRepository->getExpenseByMonth($account, $date);
|
$expenseShared += $reportRepository->getExpenseByMonth($account, $date);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -103,14 +103,14 @@ class TransactionController extends BaseController
|
|||||||
/*
|
/*
|
||||||
* respond to a possible given values in the URL.
|
* respond to a possible given values in the URL.
|
||||||
*/
|
*/
|
||||||
$prefilled = Session::has('prefilled') ? Session::get('prefilled') : [];
|
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : [];
|
||||||
$respondTo = ['account_id', 'account_from_id'];
|
$respondTo = ['account_id', 'account_from_id'];
|
||||||
foreach ($respondTo as $r) {
|
foreach ($respondTo as $r) {
|
||||||
if (!is_null(Input::get($r))) {
|
if (!is_null(Input::get($r))) {
|
||||||
$prefilled[$r] = Input::get($r);
|
$preFilled[$r] = Input::get($r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Session::put('prefilled', $prefilled);
|
Session::put('preFilled', $preFilled);
|
||||||
|
|
||||||
return View::make('transactions.create')->with('accounts', $assetAccounts)->with('budgets', $budgets)->with('what', $what)->with('piggies', $piggies)
|
return View::make('transactions.create')->with('accounts', $assetAccounts)->with('budgets', $budgets)->with('what', $what)->with('piggies', $piggies)
|
||||||
->with('subTitle', 'Add a new ' . $what);
|
->with('subTitle', 'Add a new ' . $what);
|
||||||
@@ -244,7 +244,7 @@ class TransactionController extends BaseController
|
|||||||
/*
|
/*
|
||||||
* Data to properly display the edit form.
|
* Data to properly display the edit form.
|
||||||
*/
|
*/
|
||||||
$prefilled = [
|
$preFilled = [
|
||||||
'date' => $journal->date->format('Y-m-d'),
|
'date' => $journal->date->format('Y-m-d'),
|
||||||
'category' => '',
|
'category' => '',
|
||||||
'budget_id' => 0,
|
'budget_id' => 0,
|
||||||
@@ -256,7 +256,7 @@ class TransactionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
$category = $journal->categories()->first();
|
$category = $journal->categories()->first();
|
||||||
if (!is_null($category)) {
|
if (!is_null($category)) {
|
||||||
$prefilled['category'] = $category->name;
|
$preFilled['category'] = $category->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -267,33 +267,33 @@ class TransactionController extends BaseController
|
|||||||
case 'withdrawal':
|
case 'withdrawal':
|
||||||
if (floatval($journal->transactions[0]->amount) < 0) {
|
if (floatval($journal->transactions[0]->amount) < 0) {
|
||||||
// transactions[0] is the asset account that paid for the withdrawal.
|
// transactions[0] is the asset account that paid for the withdrawal.
|
||||||
$prefilled['account_id'] = $journal->transactions[0]->account->id;
|
$preFilled['account_id'] = $journal->transactions[0]->account->id;
|
||||||
$prefilled['expense_account'] = $journal->transactions[1]->account->name;
|
$preFilled['expense_account'] = $journal->transactions[1]->account->name;
|
||||||
$prefilled['amount'] = floatval($journal->transactions[1]->amount);
|
$preFilled['amount'] = floatval($journal->transactions[1]->amount);
|
||||||
} else {
|
} else {
|
||||||
// transactions[1] is the asset account that paid for the withdrawal.
|
// transactions[1] is the asset account that paid for the withdrawal.
|
||||||
$prefilled['account_id'] = $journal->transactions[1]->account->id;
|
$preFilled['account_id'] = $journal->transactions[1]->account->id;
|
||||||
$prefilled['expense_account'] = $journal->transactions[0]->account->name;
|
$preFilled['expense_account'] = $journal->transactions[0]->account->name;
|
||||||
$prefilled['amount'] = floatval($journal->transactions[0]->amount);
|
$preFilled['amount'] = floatval($journal->transactions[0]->amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$budget = $journal->budgets()->first();
|
$budget = $journal->budgets()->first();
|
||||||
if (!is_null($budget)) {
|
if (!is_null($budget)) {
|
||||||
$prefilled['budget_id'] = $budget->id;
|
$preFilled['budget_id'] = $budget->id;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'deposit':
|
case 'deposit':
|
||||||
if (floatval($journal->transactions[0]->amount) < 0) {
|
if (floatval($journal->transactions[0]->amount) < 0) {
|
||||||
// transactions[0] contains the account the money came from.
|
// transactions[0] contains the account the money came from.
|
||||||
$prefilled['account_id'] = $journal->transactions[1]->account->id;
|
$preFilled['account_id'] = $journal->transactions[1]->account->id;
|
||||||
$prefilled['revenue_account'] = $journal->transactions[0]->account->name;
|
$preFilled['revenue_account'] = $journal->transactions[0]->account->name;
|
||||||
$prefilled['amount'] = floatval($journal->transactions[1]->amount);
|
$preFilled['amount'] = floatval($journal->transactions[1]->amount);
|
||||||
} else {
|
} else {
|
||||||
// transactions[1] contains the account the money came from.
|
// transactions[1] contains the account the money came from.
|
||||||
$prefilled['account_id'] = $journal->transactions[0]->account->id;
|
$preFilled['account_id'] = $journal->transactions[0]->account->id;
|
||||||
$prefilled['revenue_account'] = $journal->transactions[1]->account->name;
|
$preFilled['revenue_account'] = $journal->transactions[1]->account->name;
|
||||||
$prefilled['amount'] = floatval($journal->transactions[0]->amount);
|
$preFilled['amount'] = floatval($journal->transactions[0]->amount);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,17 +301,17 @@ class TransactionController extends BaseController
|
|||||||
case 'transfer':
|
case 'transfer':
|
||||||
if (floatval($journal->transactions[0]->amount) < 0) {
|
if (floatval($journal->transactions[0]->amount) < 0) {
|
||||||
// zero = from account.
|
// zero = from account.
|
||||||
$prefilled['account_from_id'] = $journal->transactions[0]->account->id;
|
$preFilled['account_from_id'] = $journal->transactions[0]->account->id;
|
||||||
$prefilled['account_to_id'] = $journal->transactions[1]->account->id;
|
$preFilled['account_to_id'] = $journal->transactions[1]->account->id;
|
||||||
$prefilled['amount'] = floatval($journal->transactions[1]->amount);
|
$preFilled['amount'] = floatval($journal->transactions[1]->amount);
|
||||||
} else {
|
} else {
|
||||||
// one = from account
|
// one = from account
|
||||||
$prefilled['account_from_id'] = $journal->transactions[1]->account->id;
|
$preFilled['account_from_id'] = $journal->transactions[1]->account->id;
|
||||||
$prefilled['account_to_id'] = $journal->transactions[0]->account->id;
|
$preFilled['account_to_id'] = $journal->transactions[0]->account->id;
|
||||||
$prefilled['amount'] = floatval($journal->transactions[0]->amount);
|
$preFilled['amount'] = floatval($journal->transactions[0]->amount);
|
||||||
}
|
}
|
||||||
if ($journal->piggybankevents()->count() > 0) {
|
if ($journal->piggybankevents()->count() > 0) {
|
||||||
$prefilled['piggybank_id'] = $journal->piggybankevents()->first()->piggybank_id;
|
$preFilled['piggybank_id'] = $journal->piggybankevents()->first()->piggybank_id;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -322,7 +322,7 @@ class TransactionController extends BaseController
|
|||||||
|
|
||||||
return View::make('transactions.edit')->with('journal', $journal)->with('accounts', $accounts)->with(
|
return View::make('transactions.edit')->with('journal', $journal)->with('accounts', $accounts)->with(
|
||||||
'what', $what
|
'what', $what
|
||||||
)->with('budgets', $budgets)->with('data', $prefilled)->with('piggies', $piggies)->with(
|
)->with('budgets', $budgets)->with('data', $preFilled)->with('piggies', $piggies)->with(
|
||||||
'subTitle', 'Edit ' . $what . ' "' . $journal->description . '"'
|
'subTitle', 'Edit ' . $what . ' "' . $journal->description . '"'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -36,8 +36,6 @@ class CreateUsersTable extends Migration
|
|||||||
$table->string('password', 60);
|
$table->string('password', 60);
|
||||||
$table->string('reset', 32)->nullable();
|
$table->string('reset', 32)->nullable();
|
||||||
$table->string('remember_token', 255)->nullable();
|
$table->string('remember_token', 255)->nullable();
|
||||||
$table->boolean('migrated');
|
|
||||||
|
|
||||||
$table->unique('email');
|
$table->unique('email');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -32,7 +32,7 @@ class CreateAccountTypesTable extends Migration
|
|||||||
'account_types', function (Blueprint $table) {
|
'account_types', function (Blueprint $table) {
|
||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->string('type', 50);
|
$table->string('type', 30);
|
||||||
$table->boolean('editable');
|
$table->boolean('editable');
|
||||||
|
|
||||||
$table->unique('type');
|
$table->unique('type');
|
||||||
|
@@ -44,6 +44,7 @@ class CreateAccountsTable extends Migration
|
|||||||
// connect accounts to account_types
|
// connect accounts to account_types
|
||||||
$table->foreign('account_type_id')->references('id')->on('account_types')->onDelete('cascade');
|
$table->foreign('account_type_id')->references('id')->on('account_types')->onDelete('cascade');
|
||||||
|
|
||||||
|
// for a user, the account name must be unique.
|
||||||
$table->unique(['user_id', 'account_type_id', 'name']);
|
$table->unique(['user_id', 'account_type_id', 'name']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -40,6 +40,7 @@ class CreateComponentsTable extends Migration
|
|||||||
// connect components to users
|
// connect components to users
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
|
||||||
|
// for a user, the component type & name must be unique.
|
||||||
$table->unique(['user_id', 'class', 'name']);
|
$table->unique(['user_id', 'class', 'name']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -48,6 +48,8 @@ class CreatePiggybanksTable extends Migration
|
|||||||
|
|
||||||
// connect account to piggybank.
|
// connect account to piggybank.
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
|
|
||||||
|
// for an account, the name must be unique.
|
||||||
$table->unique(['account_id', 'name']);
|
$table->unique(['account_id', 'name']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,9 @@ class CreateTransactionCurrenciesTable extends Migration
|
|||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
$table->string('code', 3);
|
$table->string('code', 3);
|
||||||
|
|
||||||
|
// code must be unique.
|
||||||
|
$table->unique(['code']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,9 @@ class CreateTransactionTypesTable extends Migration
|
|||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
$table->string('type', 50);
|
$table->string('type', 50);
|
||||||
|
|
||||||
|
// type must be unique.
|
||||||
|
$table->unique(['type']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,10 @@ class CreateRecurringTransactionsTable extends Migration
|
|||||||
$table->enum('repeat_freq', ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly']);
|
$table->enum('repeat_freq', ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly']);
|
||||||
$table->smallInteger('skip')->unsigned();
|
$table->smallInteger('skip')->unsigned();
|
||||||
|
|
||||||
|
// connect user id to users
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
|
||||||
|
// for a user, the name must be unique
|
||||||
$table->unique(['user_id', 'name']);
|
$table->unique(['user_id', 'name']);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -41,6 +41,9 @@ class CreateTransactionJournalsTable extends Migration
|
|||||||
$table->boolean('completed');
|
$table->boolean('completed');
|
||||||
$table->date('date');
|
$table->date('date');
|
||||||
|
|
||||||
|
// connect users
|
||||||
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
|
||||||
// connect transaction journals to transaction types
|
// connect transaction journals to transaction types
|
||||||
$table->foreign('transaction_type_id')->references('id')->on('transaction_types')->onDelete('cascade');
|
$table->foreign('transaction_type_id')->references('id')->on('transaction_types')->onDelete('cascade');
|
||||||
|
|
||||||
@@ -50,8 +53,7 @@ class CreateTransactionJournalsTable extends Migration
|
|||||||
// connect transaction journals to transaction currencies
|
// connect transaction journals to transaction currencies
|
||||||
$table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
$table->foreign('transaction_currency_id')->references('id')->on('transaction_currencies')->onDelete('cascade');
|
||||||
|
|
||||||
// connect users
|
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -39,14 +39,18 @@ class CreateTransactionsTable extends Migration
|
|||||||
$table->string('description', 255)->nullable();
|
$table->string('description', 255)->nullable();
|
||||||
$table->decimal('amount', 10, 2);
|
$table->decimal('amount', 10, 2);
|
||||||
|
|
||||||
// connect transactions to transaction journals
|
// connect account id:
|
||||||
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
|
|
||||||
// connect piggy banks
|
// connect piggy banks
|
||||||
$table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('set null');
|
$table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('set null');
|
||||||
|
|
||||||
// connect account id:
|
// connect transactions to transaction journals
|
||||||
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -39,6 +39,9 @@ class CreateComponentTransactionTable extends Migration
|
|||||||
|
|
||||||
// connect to transactions
|
// connect to transactions
|
||||||
$table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
|
$table->foreign('transaction_id')->references('id')->on('transactions')->onDelete('cascade');
|
||||||
|
|
||||||
|
// combo must be unique:
|
||||||
|
$table->unique(['component_id', 'transaction_id']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,9 @@ class CreateComponentTransactionJournalTable extends Migration
|
|||||||
|
|
||||||
// link transaction journals with transaction_journal_id
|
// link transaction journals with transaction_journal_id
|
||||||
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
||||||
|
|
||||||
|
// combo must be unique:
|
||||||
|
$table->unique(['component_id', 'transaction_journal_id'],'cid_tjid_unique');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -38,6 +38,9 @@ class CreatePreferencesTable extends Migration
|
|||||||
|
|
||||||
// connect preferences to users
|
// connect preferences to users
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
|
||||||
|
// only one preference per name per user
|
||||||
|
$table->unique(['user_id', 'name']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -4,11 +4,11 @@ use Illuminate\Database\Migrations\Migration;
|
|||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RecurringTransactionsToComponents
|
* Class CreateComponentRecurringTransactionTable
|
||||||
*
|
*
|
||||||
* @SuppressWarnings(PHPMD.ShortMethodName)
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
*/
|
*/
|
||||||
class RecurringTransactionsToComponents extends Migration
|
class CreateComponentRecurringTransactionTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,6 +40,10 @@ class RecurringTransactionsToComponents extends Migration
|
|||||||
|
|
||||||
// link transaction journals with transaction_journal_id
|
// link transaction journals with transaction_journal_id
|
||||||
$table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('cascade');
|
$table->foreign('recurring_transaction_id')->references('id')->on('recurring_transactions')->onDelete('cascade');
|
||||||
|
|
||||||
|
// component and recurring transaction must be unique.
|
||||||
|
$table->unique(['component_id','recurring_transaction_id'],'cid_rtid_unique');
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
@@ -3,7 +3,12 @@
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
class CreatePiggyInstance extends Migration
|
/**
|
||||||
|
* Class CreatePiggyInstance
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
|
*/
|
||||||
|
class CreatePiggybankRepetitionsTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
@@ -3,7 +3,12 @@
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
class CreatePiggyEvents extends Migration
|
/**
|
||||||
|
* Class CreatePiggybankEventsTable
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
|
*/
|
||||||
|
class CreatePiggybankEventsTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,11 +33,16 @@ class CreatePiggyEvents extends Migration
|
|||||||
$table->increments('id');
|
$table->increments('id');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
$table->integer('piggybank_id')->unsigned();
|
$table->integer('piggybank_id')->unsigned();
|
||||||
|
$table->integer('transaction_journal_id')->unsigned()->nullable();
|
||||||
|
|
||||||
$table->date('date');
|
$table->date('date');
|
||||||
$table->decimal('amount', 10, 2);
|
$table->decimal('amount', 10, 2);
|
||||||
|
|
||||||
// connect instance to piggybank.
|
// connect instance to piggybank.
|
||||||
$table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade');
|
$table->foreign('piggybank_id')->references('id')->on('piggybanks')->onDelete('cascade');
|
||||||
|
|
||||||
|
// connect to journal:
|
||||||
|
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('set null');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
@@ -3,6 +3,11 @@
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CreateRemindersTable
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
|
*/
|
||||||
class CreateRemindersTable extends Migration
|
class CreateRemindersTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -31,6 +36,9 @@ class CreateRemindersTable extends Migration
|
|||||||
$table->date('startdate');
|
$table->date('startdate');
|
||||||
$table->date('enddate')->nullable();
|
$table->date('enddate')->nullable();
|
||||||
$table->boolean('active');
|
$table->boolean('active');
|
||||||
|
$table->boolean('notnow')->default(0);
|
||||||
|
$table->integer('remindersable_id')->unsigned()->nullable();
|
||||||
|
$table->string('remindersable_type')->nullable();
|
||||||
|
|
||||||
// connect reminders to users
|
// connect reminders to users
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||||
|
@@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
|
|
||||||
class CreateImportmapsTable extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::drop('importmaps');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create(
|
|
||||||
'importmaps', function (Blueprint $table) {
|
|
||||||
$table->increments('id');
|
|
||||||
$table->timestamps();
|
|
||||||
$table->integer('user_id')->unsigned();
|
|
||||||
$table->string('file', 500);
|
|
||||||
$table->integer('totaljobs')->unsigned();
|
|
||||||
$table->integer('jobsdone')->unsigned();
|
|
||||||
|
|
||||||
// connect maps to users
|
|
||||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,41 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
|
|
||||||
class CreateImportentriesTable extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::drop('importentries');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create(
|
|
||||||
'importentries', function (Blueprint $table) {
|
|
||||||
$table->increments('id');
|
|
||||||
$table->timestamps();
|
|
||||||
$table->string('class', 200);
|
|
||||||
$table->integer('importmap_id')->unsigned();
|
|
||||||
$table->integer('old')->unsigned();
|
|
||||||
$table->integer('new')->unsigned();
|
|
||||||
|
|
||||||
// connect import map.
|
|
||||||
$table->foreign('importmap_id')->references('id')->on('importmaps')->onDelete('cascade');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
|
|
||||||
class CreateFailedJobsTable extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::drop('failed_jobs');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create(
|
|
||||||
'failed_jobs', function (Blueprint $table) {
|
|
||||||
$table->increments('id');
|
|
||||||
$table->text('connection');
|
|
||||||
$table->text('queue');
|
|
||||||
$table->text('payload');
|
|
||||||
$table->timestamp('failed_at');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -3,7 +3,12 @@
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
class CreateAccountMeta extends Migration
|
/**
|
||||||
|
* Class CreateAccountMetaTable
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
|
*/
|
||||||
|
class CreateAccountMetaTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +38,8 @@ class CreateAccountMeta extends Migration
|
|||||||
$table->string('name');
|
$table->string('name');
|
||||||
$table->text('data');
|
$table->text('data');
|
||||||
|
|
||||||
|
$table->unique(['account_id', 'name']);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
@@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
|
|
||||||
class ExtendPiggybankEvents extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table(
|
|
||||||
'piggybank_events', function (Blueprint $table) {
|
|
||||||
$table->integer('transaction_journal_id')->unsigned()->nullable();
|
|
||||||
$table->foreign('transaction_journal_id')->references('id')->on('transaction_journals')->onDelete('set null');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
|
|
||||||
class EventTableAdditions1 extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
// remove some fields:
|
|
||||||
Schema::table(
|
|
||||||
'reminders', function (Blueprint $table) {
|
|
||||||
$table->boolean('notnow')->default(0);
|
|
||||||
$table->integer('remindersable_id')->unsigned()->nullable();
|
|
||||||
$table->string('remindersable_type')->nullable();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
|
|
||||||
class CacheTable extends Migration
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::drop('cache');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create(
|
|
||||||
'cache', function ($table) {
|
|
||||||
$table->string('key')->unique();
|
|
||||||
$table->text('value');
|
|
||||||
$table->integer('expiration');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -3,7 +3,12 @@
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
class Transactiongroups extends Migration
|
/**
|
||||||
|
* Class CreateTransactionGroupsTable
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
|
*/
|
||||||
|
class CreateTransactionGroupsTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
@@ -3,7 +3,12 @@
|
|||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
|
||||||
class Transactiongroupsjoin extends Migration
|
/**
|
||||||
|
* Class CreateTransactionGroupTransactionJournalTable
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.ShortMethodName)
|
||||||
|
*/
|
||||||
|
class CreateTransactionGroupTransactionJournalTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,9 +36,11 @@ class Transactiongroupsjoin extends Migration
|
|||||||
$table->integer('transaction_group_id')->unsigned();
|
$table->integer('transaction_group_id')->unsigned();
|
||||||
$table->integer('transaction_journal_id')->unsigned();
|
$table->integer('transaction_journal_id')->unsigned();
|
||||||
|
|
||||||
|
// link to foreign tables.
|
||||||
$table->foreign('transaction_group_id', 'tr_grp_id')->references('id')->on('transaction_groups')->onDelete('cascade');
|
$table->foreign('transaction_group_id', 'tr_grp_id')->references('id')->on('transaction_groups')->onDelete('cascade');
|
||||||
$table->foreign('transaction_journal_id', 'tr_trj_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
$table->foreign('transaction_journal_id', 'tr_trj_id')->references('id')->on('transaction_journals')->onDelete('cascade');
|
||||||
|
|
||||||
|
// add unique.
|
||||||
$table->unique(['transaction_group_id', 'transaction_journal_id'], 'tt_joined');
|
$table->unique(['transaction_group_id', 'transaction_journal_id'], 'tt_joined');
|
||||||
}
|
}
|
||||||
);
|
);
|
@@ -16,6 +16,9 @@ class DefaultUserSeeder extends Seeder
|
|||||||
User::create(
|
User::create(
|
||||||
['email' => 'acceptance@example.com', 'password' => 'acceptance', 'reset' => null, 'remember_token' => null, 'migrated' => 0]
|
['email' => 'acceptance@example.com', 'password' => 'acceptance', 'reset' => null, 'remember_token' => null, 'migrated' => 0]
|
||||||
);
|
);
|
||||||
|
User::create(
|
||||||
|
['email' => 'functional@example.com', 'password' => 'functional', 'reset' => null, 'remember_token' => null, 'migrated' => 0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -229,10 +229,10 @@ class Form
|
|||||||
$options['placeholder'] = ucfirst($name);
|
$options['placeholder'] = ucfirst($name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get prefilled value:
|
* Get pre filled value:
|
||||||
*/
|
*/
|
||||||
if (\Session::has('prefilled')) {
|
if (\Session::has('prefilled')) {
|
||||||
$prefilled = \Session::get('prefilled');
|
$preFilled = \Session::get('preFilled');
|
||||||
$value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value;
|
$value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -88,57 +88,47 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
|
|||||||
/*
|
/*
|
||||||
* Basic query:
|
* Basic query:
|
||||||
*/
|
*/
|
||||||
$query = $this->getUser()->accounts()->accountTypeIn($types)->withMeta();
|
$query = $this->getUser()->accounts()->accountTypeIn($types)->withMeta()->orderBy('name', 'ASC');;
|
||||||
|
$set = $query->get(['accounts.*']);
|
||||||
|
|
||||||
|
$set->each(
|
||||||
/*
|
function (\Account $account) {
|
||||||
* Without an opening balance, the rest of these queries will fail.
|
/*
|
||||||
*/
|
* Get last activity date.
|
||||||
|
*/
|
||||||
$query->leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id');
|
$account->lastActivityDate = $this->getLastActivity($account);
|
||||||
$query->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id');
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Not used, but useful for the balance within a certain month / year.
|
|
||||||
*/
|
|
||||||
$query->where(
|
|
||||||
function ($q) {
|
|
||||||
$q->where('transaction_journals.date', '<=', Carbon::now()->format('Y-m-d'));
|
|
||||||
$q->orWhereNull('transaction_journals.date');
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$query->groupBy('accounts.id');
|
return $set;
|
||||||
|
|
||||||
/*
|
|
||||||
* If present, process parameters for sorting:
|
|
||||||
*/
|
|
||||||
$query->orderBy('name', 'ASC');
|
|
||||||
|
|
||||||
return $query->get(['accounts.*', \DB::Raw('SUM(`transactions`.`amount`) as `balance`')]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all asset accounts. Optional JSON based parameters.
|
* Get all asset accounts. Optional JSON based parameters.
|
||||||
*
|
*
|
||||||
* @param array $parameters
|
* @param array $metaFilter
|
||||||
*
|
*
|
||||||
* @return Collection
|
* @return Collection
|
||||||
*/
|
*/
|
||||||
public function getAssetAccounts()
|
public function getAssetAccounts($metaFilter = [])
|
||||||
{
|
{
|
||||||
$list = $this->getAccountsByType(['Default account', 'Asset account']);
|
$list = $this->getAccountsByType(['Default account', 'Asset account']);
|
||||||
$list->each(
|
$list->each(
|
||||||
function (\Account $account) {
|
function (\Account $account) {
|
||||||
|
|
||||||
|
// get accountRole:
|
||||||
|
|
||||||
/** @var \AccountMeta $entry */
|
/** @var \AccountMeta $entry */
|
||||||
foreach ($account->accountmeta as $entry) {
|
$accountRole = $account->accountmeta()->whereName('accountRole')->first();
|
||||||
if ($entry->name == 'accountRole') {
|
if (!$accountRole) {
|
||||||
$account->accountRole = \Config::get('firefly.accountRoles.' . $entry->data);
|
$accountRole = new \AccountMeta;
|
||||||
}
|
$accountRole->account_id = $account->id;
|
||||||
}
|
$accountRole->name = 'accountRole';
|
||||||
if (!isset($account->accountRole)) {
|
$accountRole->data = 'defaultExpense';
|
||||||
$account->accountRole = 'Default expense account';
|
$accountRole->save();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
$account->accountRole = $accountRole->data;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -274,7 +264,8 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
|
|||||||
$q->where('accounts.active', 0);
|
$q->where('accounts.active', 0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})->delete();
|
}
|
||||||
|
)->delete();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -331,7 +322,7 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Eloquent $model
|
* @param \Eloquent $model
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -552,19 +543,49 @@ class Account implements CUD, CommonDatabaseCalls, AccountInterface
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTransactionJournals(\Account $account, $limit = 50)
|
/**
|
||||||
|
* @param \Account $account
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLastActivity(\Account $account)
|
||||||
|
{
|
||||||
|
$lastActivityKey = 'account.' . $account->id . '.lastActivityDate';
|
||||||
|
if (\Cache::has($lastActivityKey)) {
|
||||||
|
return \Cache::get($lastActivityKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
$transaction = $account->transactions()
|
||||||
|
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||||
|
->orderBy('transaction_journals.date', 'DESC')->first();
|
||||||
|
if ($transaction) {
|
||||||
|
$date = $transaction->transactionJournal->date;
|
||||||
|
} else {
|
||||||
|
$date = 0;
|
||||||
|
}
|
||||||
|
\Cache::forever($lastActivityKey, $date);
|
||||||
|
|
||||||
|
return $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTransactionJournals(\Account $account, $limit = 50, $range = 'session')
|
||||||
{
|
{
|
||||||
$start = \Session::get('start');
|
|
||||||
$end = \Session::get('end');
|
|
||||||
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0;
|
$offset = intval(\Input::get('page')) > 0 ? intval(\Input::get('page')) * $limit : 0;
|
||||||
$set = $this->getUser()->transactionJournals()->withRelevantData()->leftJoin(
|
|
||||||
'transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id'
|
|
||||||
)->where('transactions.account_id', $account->id)->take($limit)->offset($offset)->before($end)->after($start)->orderBy('date', 'DESC')->get(
|
|
||||||
['transaction_journals.*']
|
|
||||||
);
|
|
||||||
$count = $this->getUser()->transactionJournals()->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
|
||||||
->before($end)->after($start)->orderBy('date', 'DESC')->where('transactions.account_id', $account->id)->count();
|
|
||||||
$items = [];
|
$items = [];
|
||||||
|
$query = $this->getUser()
|
||||||
|
->transactionJournals()
|
||||||
|
->withRelevantData()
|
||||||
|
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||||
|
->where('transactions.account_id', $account->id)
|
||||||
|
->orderBy('date', 'DESC');
|
||||||
|
|
||||||
|
if ($range == 'session') {
|
||||||
|
$query->before(\Session::get('end'));
|
||||||
|
$query->after(\Session::get('start'));
|
||||||
|
}
|
||||||
|
$count = $query->count();
|
||||||
|
$set = $query->take($limit)->offset($offset)->get(['transaction_journals.*']);
|
||||||
|
|
||||||
foreach ($set as $entry) {
|
foreach ($set as $entry) {
|
||||||
$items[] = $entry;
|
$items[] = $entry;
|
||||||
}
|
}
|
||||||
|
@@ -61,7 +61,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Eloquent $model
|
* @param \Eloquent $model
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -263,4 +263,58 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
|
|||||||
|
|
||||||
return $sum;
|
return $sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Budget $budget
|
||||||
|
* @param Carbon $date
|
||||||
|
* @param $amount
|
||||||
|
*
|
||||||
|
* @return \Limit
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function updateLimitAmount(\Budget $budget, Carbon $date, $amount)
|
||||||
|
{
|
||||||
|
/** @var \Limit $limit */
|
||||||
|
$limit = $this->limitOnStartingOnDate($budget, $date);
|
||||||
|
if (!$limit) {
|
||||||
|
// create one!
|
||||||
|
$limit = new \Limit;
|
||||||
|
$limit->budget()->associate($budget);
|
||||||
|
$limit->startdate = $date;
|
||||||
|
$limit->amount = $amount;
|
||||||
|
$limit->repeat_freq = 'monthly';
|
||||||
|
$limit->repeats = 0;
|
||||||
|
$limit->save();
|
||||||
|
/*
|
||||||
|
* A newly stored limit also created a limit repetition.
|
||||||
|
*/
|
||||||
|
\Event::fire('limits.store', [$limit]);
|
||||||
|
} else {
|
||||||
|
if ($amount > 0) {
|
||||||
|
$limit->amount = $amount;
|
||||||
|
$limit->save();
|
||||||
|
/*
|
||||||
|
* An updated limit also updates the associated limit repetitions.
|
||||||
|
*/
|
||||||
|
\Event::fire('limits.update', [$limit]);
|
||||||
|
} else {
|
||||||
|
$limit->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $limit;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Budget $budget
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return \Limit
|
||||||
|
*/
|
||||||
|
public function limitOnStartingOnDate(\Budget $budget, Carbon $date)
|
||||||
|
{
|
||||||
|
return $budget->limits()->where('startdate', $date->format('Y-m-d'))->first();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -42,7 +42,7 @@ class Report implements ReportInterface
|
|||||||
$sum = 0;
|
$sum = 0;
|
||||||
|
|
||||||
// get all journals.
|
// get all journals.
|
||||||
$journals = \TransactionJournal::whereIn(
|
$journals = \TransactionJournal::with(['transactionType','transactions'])->whereIn(
|
||||||
'id', function ($query) use ($account, $start, $end) {
|
'id', function ($query) use ($account, $start, $end) {
|
||||||
$query->select('transaction_journal_id')
|
$query->select('transaction_journal_id')
|
||||||
->from('transactions')
|
->from('transactions')
|
||||||
@@ -125,7 +125,7 @@ class Report implements ReportInterface
|
|||||||
$sum = 0;
|
$sum = 0;
|
||||||
|
|
||||||
// get all journals.
|
// get all journals.
|
||||||
$journals = \TransactionJournal::whereIn(
|
$journals = \TransactionJournal::with(['transactionType','transactions'])->whereIn(
|
||||||
'id', function ($query) use ($account, $start, $end) {
|
'id', function ($query) use ($account, $start, $end) {
|
||||||
$query->select('transaction_journal_id')
|
$query->select('transaction_journal_id')
|
||||||
->from('transactions')
|
->from('transactions')
|
||||||
|
@@ -171,7 +171,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Eloquent $model
|
* @param \Eloquent $model
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
@@ -486,6 +486,19 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
|
|||||||
return $this->getUser()->transactionjournals()->with('transactions')->whereIn('id', $ids)->orderBy('date', 'ASC')->get();
|
return $this->getUser()->transactionjournals()->with('transactions')->whereIn('id', $ids)->orderBy('date', 'ASC')->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Carbon
|
||||||
|
*/
|
||||||
|
public function firstDate()
|
||||||
|
{
|
||||||
|
$journal = $this->first();
|
||||||
|
if ($journal) {
|
||||||
|
return $journal->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Carbon::now();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TransactionJournal
|
* @return TransactionJournal
|
||||||
*/
|
*/
|
||||||
|
@@ -15,7 +15,7 @@ class Budget
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
$end = DateKit::addPeriod(clone $limit->startdate, $limit->repeat_freq, 0);
|
$end = \DateKit::addPeriod(clone $limit->startdate, $limit->repeat_freq, 0);
|
||||||
$end->subDay();
|
$end->subDay();
|
||||||
|
|
||||||
$set = $limit->limitrepetitions()->where('startdate', $limit->startdate->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->get();
|
$set = $limit->limitrepetitions()->where('startdate', $limit->startdate->format('Y-m-d'))->where('enddate', $end->format('Y-m-d'))->get();
|
||||||
|
@@ -87,6 +87,10 @@ class FF3ServiceProvider extends ServiceProvider
|
|||||||
// registration and user mail:
|
// registration and user mail:
|
||||||
$this->app->bind('FireflyIII\Shared\Mail\RegistrationInterface', 'FireflyIII\Shared\Mail\Registration');
|
$this->app->bind('FireflyIII\Shared\Mail\RegistrationInterface', 'FireflyIII\Shared\Mail\Registration');
|
||||||
|
|
||||||
|
// reports
|
||||||
|
$this->app->bind('FireflyIII\Report\ReportInterface', 'FireflyIII\Report\Report');
|
||||||
|
|
||||||
|
|
||||||
// Shortcut so developers don't need to add an Alias in app/config/app.php
|
// Shortcut so developers don't need to add an Alias in app/config/app.php
|
||||||
$this->app->booting(
|
$this->app->booting(
|
||||||
function () {
|
function () {
|
||||||
|
@@ -57,11 +57,11 @@ class Form
|
|||||||
$options['placeholder'] = ucfirst($name);
|
$options['placeholder'] = ucfirst($name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get prefilled value:
|
* Get pre filled value:
|
||||||
*/
|
*/
|
||||||
if (\Session::has('prefilled')) {
|
if (\Session::has('preFilled')) {
|
||||||
$prefilled = \Session::get('prefilled');
|
$preFilled = \Session::get('preFilled');
|
||||||
$value = isset($prefilled[$name]) && is_null($value) ? $prefilled[$name] : $value;
|
$value = isset($preFilled[$name]) && is_null($value) ? $preFilled[$name] : $value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
125
app/lib/FireflyIII/Report/Report.php
Normal file
125
app/lib/FireflyIII/Report/Report.php
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Report;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use FireflyIII\Database\Account as AccountRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Report
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Report
|
||||||
|
*/
|
||||||
|
class Report implements ReportInterface
|
||||||
|
{
|
||||||
|
/** @var AccountRepository */
|
||||||
|
protected $_accounts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param AccountRepository $accounts
|
||||||
|
*/
|
||||||
|
public function __construct(AccountRepository $accounts)
|
||||||
|
{
|
||||||
|
$this->_accounts = $accounts;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $date
|
||||||
|
* @param string $direction
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function groupByRevenue(Carbon $date, $direction = 'income')
|
||||||
|
{
|
||||||
|
$operator = $direction == 'income' ? '<' : '>';
|
||||||
|
$type = $direction == 'income' ? 'Deposit' : 'Withdrawal';
|
||||||
|
$order = $direction == 'income' ? 'ASC' : 'DESC';
|
||||||
|
$start = clone $date;
|
||||||
|
$end = clone $date;
|
||||||
|
$start->startOfYear();
|
||||||
|
$end->endOfYear();
|
||||||
|
|
||||||
|
// TODO remove shared accounts
|
||||||
|
return \TransactionJournal::
|
||||||
|
leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
|
||||||
|
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
|
||||||
|
->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
|
||||||
|
->where('transaction_types.type', '=', $type)
|
||||||
|
->where('transactions.amount', $operator, 0)
|
||||||
|
->before($end)
|
||||||
|
->after($start)
|
||||||
|
->groupBy('accounts.id')
|
||||||
|
->where('transaction_journals.user_id', \Auth::user()->id)
|
||||||
|
->orderBy('sum', $order)
|
||||||
|
->take(10)
|
||||||
|
->get(['accounts.name', 'transactions.account_id', \DB::Raw('SUM(`transactions`.`amount`) as `sum`')]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $start
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listOfMonths(Carbon $start)
|
||||||
|
{
|
||||||
|
$end = Carbon::now();
|
||||||
|
$months = [];
|
||||||
|
while ($start <= $end) {
|
||||||
|
$months[] = [
|
||||||
|
'formatted' => $start->format('F Y'),
|
||||||
|
'month' => intval($start->format('m')),
|
||||||
|
'year' => intval($start->format('Y')),
|
||||||
|
];
|
||||||
|
$start->addMonth();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $months;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $start
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listOfYears(Carbon $start)
|
||||||
|
{
|
||||||
|
$end = Carbon::now();
|
||||||
|
$years = [];
|
||||||
|
while ($start <= $end) {
|
||||||
|
$years[] = $start->format('Y');
|
||||||
|
$start->addYear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $years;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearBalanceReport(Carbon $date)
|
||||||
|
{
|
||||||
|
$start = clone $date;
|
||||||
|
$end = clone $date;
|
||||||
|
// TODO filter accounts, no shared accounts.
|
||||||
|
$accounts = $this->_accounts->getAssetAccounts();
|
||||||
|
$report = [];
|
||||||
|
$start->startOfYear();
|
||||||
|
$end->endOfYear();
|
||||||
|
|
||||||
|
foreach ($accounts as $account) {
|
||||||
|
$report[] = [
|
||||||
|
'start' => \Steam::balance($account, $start),
|
||||||
|
'end' => \Steam::balance($account, $end),
|
||||||
|
'account' => $account,
|
||||||
|
'shared' => $account->accountRole == 'sharedExpense'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $report;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
42
app/lib/FireflyIII/Report/ReportInterface.php
Normal file
42
app/lib/FireflyIII/Report/ReportInterface.php
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace FireflyIII\Report;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface ReportInterface
|
||||||
|
*
|
||||||
|
* @package FireflyIII\Report
|
||||||
|
*/
|
||||||
|
interface ReportInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Carbon $date
|
||||||
|
* @param string $direction
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function groupByRevenue(Carbon $date, $direction = 'income');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $start
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listOfMonths(Carbon $start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $start
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listOfYears(Carbon $start);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Carbon $date
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function yearBalanceReport(Carbon $date);
|
||||||
|
}
|
@@ -23,13 +23,13 @@ class Steam
|
|||||||
*/
|
*/
|
||||||
public function balance(\Account $account, Carbon $date = null)
|
public function balance(\Account $account, Carbon $date = null)
|
||||||
{
|
{
|
||||||
$latest = false;
|
|
||||||
if (is_null($date)) {
|
if (is_null($date)) {
|
||||||
$latest = true;
|
$key = 'account.' . $account->id . '.latestBalance';
|
||||||
if (\Cache::has('account.' . $account->id . '.latestBalance')) {
|
} else {
|
||||||
|
$key = 'account.' . $account->id . '.balanceOn' . $date->format('dmy');
|
||||||
return \Cache::get('account.' . $account->id . '.latestBalance');
|
}
|
||||||
}
|
if (\Cache::has($key)) {
|
||||||
|
return \Cache::get($key);
|
||||||
}
|
}
|
||||||
$date = is_null($date) ? Carbon::now() : $date;
|
$date = is_null($date) ? Carbon::now() : $date;
|
||||||
$balance = floatval(
|
$balance = floatval(
|
||||||
@@ -37,9 +37,7 @@ class Steam
|
|||||||
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
'transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id'
|
||||||
)->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount')
|
)->where('transaction_journals.date', '<=', $date->format('Y-m-d'))->sum('transactions.amount')
|
||||||
);
|
);
|
||||||
if ($latest === true) {
|
\Cache::put($key, $balance, 20160);
|
||||||
\Cache::forever('account.' . $account->id . '.latestBalance', $balance);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $balance;
|
return $balance;
|
||||||
}
|
}
|
||||||
|
@@ -49,10 +49,13 @@ class TransactionJournal extends Eloquent
|
|||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public function getAmount()
|
public function getAmount(\Account $account = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach ($this->transactions as $t) {
|
foreach ($this->transactions as $t) {
|
||||||
|
if (!is_null($account) && $account->id == $t->account_id) {
|
||||||
|
return floatval($t->amount);
|
||||||
|
}
|
||||||
if (floatval($t->amount) > 0) {
|
if (floatval($t->amount) > 0) {
|
||||||
return floatval($t->amount);
|
return floatval($t->amount);
|
||||||
}
|
}
|
||||||
|
@@ -327,7 +327,6 @@ Route::group(
|
|||||||
// user controller
|
// user controller
|
||||||
Route::get('/login', ['uses' => 'UserController@login', 'as' => 'login']);
|
Route::get('/login', ['uses' => 'UserController@login', 'as' => 'login']);
|
||||||
Route::get('/register', ['uses' => 'UserController@register', 'as' => 'register']);
|
Route::get('/register', ['uses' => 'UserController@register', 'as' => 'register']);
|
||||||
Route::get('/verify/{verification}', ['uses' => 'UserController@verify', 'as' => 'verify']);
|
|
||||||
Route::get('/reset/{reset}', ['uses' => 'UserController@reset', 'as' => 'reset']);
|
Route::get('/reset/{reset}', ['uses' => 'UserController@reset', 'as' => 'reset']);
|
||||||
Route::get('/remindme', ['uses' => 'UserController@remindme', 'as' => 'remindme']);
|
Route::get('/remindme', ['uses' => 'UserController@remindme', 'as' => 'remindme']);
|
||||||
|
|
||||||
@@ -340,8 +339,8 @@ Route::group(
|
|||||||
['before' => 'csrf|guest'], function () {
|
['before' => 'csrf|guest'], function () {
|
||||||
|
|
||||||
// user controller
|
// user controller
|
||||||
Route::post('/login', ['uses' => 'UserController@postLogin']);
|
Route::post('/login', ['uses' => 'UserController@postLogin','as' => 'login.post']);
|
||||||
Route::post('/register', ['uses' => 'UserController@postRegister']);
|
Route::post('/register', ['uses' => 'UserController@postRegister','as' => 'register.post']);
|
||||||
Route::post('/remindme', ['uses' => 'UserController@postRemindme']);
|
Route::post('/remindme', ['uses' => 'UserController@postRemindme','as' => 'remindme.post']);
|
||||||
}
|
}
|
||||||
);
|
);
|
@@ -26,8 +26,8 @@
|
|||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{{Form::ffCheckbox('active','1')}}
|
{{Form::ffCheckbox('active','1')}}
|
||||||
@if($account->accounttype->type == 'Default account' || $account->accounttype->type == 'Asset account')
|
@if($account->accounttype->type == 'Default account' || $account->accounttype->type == 'Asset account')
|
||||||
{{Form::ffBalance('openingbalance')}}
|
{{Form::ffBalance('openingBalance')}}
|
||||||
{{Form::ffDate('openingbalancedate')}}
|
{{Form::ffDate('openingBalanceDate')}}
|
||||||
{{Form::ffSelect('account_role',Config::get('firefly.accountRoles'))}}
|
{{Form::ffSelect('account_role',Config::get('firefly.accountRoles'))}}
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<p>
|
<p>
|
||||||
@if($view == 'all')
|
@if($range == 'all')
|
||||||
<a href="{{route('accounts.show',$account->id)}}/session" class="btn btn-default">Stick to date-range</a>
|
<a href="{{route('accounts.show',$account->id)}}/session" class="btn btn-default">Stick to date-range</a>
|
||||||
@else
|
@else
|
||||||
<a href="{{route('accounts.show',$account->id)}}/all" class="btn btn-default">Show all transactions</a>
|
<a href="{{route('accounts.show',$account->id)}}/all" class="btn btn-default">Show all transactions</a>
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
@section('scripts')
|
@section('scripts')
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var accountID = {{{$account->id}}};
|
var accountID = {{{$account->id}}};
|
||||||
var view = '{{{$view}}}';
|
var view = '{{{$range}}}';
|
||||||
</script>
|
</script>
|
||||||
<!-- load the libraries and scripts necessary for Google Charts: -->
|
<!-- load the libraries and scripts necessary for Google Charts: -->
|
||||||
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{Form::open(['class' => 'form-horizontal','url' => route('budgets.update',$budget->id)])}}
|
{{Form::model($budget, ['class' => 'form-horizontal','url' => route('budgets.update',$budget->id)])}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6 col-md-12 col-sm-6">
|
<div class="col-lg-6 col-md-12 col-sm-6">
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if($account->lastActionDate)
|
@if($account->lastActivityDate)
|
||||||
{{{$account->lastActionDate->format('j F Y')}}}
|
{{{$account->lastActivityDate->format('j F Y')}}}
|
||||||
@else
|
@else
|
||||||
<em>Never</em>
|
<em>Never</em>
|
||||||
@endif
|
@endif
|
||||||
|
@@ -30,8 +30,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{{Form::ffDate('targetdate')}}
|
{{Form::ffDate('targetdate')}}
|
||||||
{{Form::ffCheckbox('remind_me','1',$prefilled['remind_me'],['label' => 'Remind me'])}}
|
{{Form::ffCheckbox('remind_me','1',$preFilled['remind_me'],['label' => 'Remind me'])}}
|
||||||
{{Form::ffSelect('reminder',$periods,$prefilled['reminder'],['label' => 'Remind every'])}}
|
{{Form::ffSelect('reminder',$periods,$preFilled['reminder'],['label' => 'Remind every'])}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -25,85 +25,72 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
<div class="col-lg-6 col-md-6 col-sm-6">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
Summary (without shared accounts)
|
Account balance
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-striped">
|
<table class="table">
|
||||||
<tr>
|
<?php
|
||||||
<td></td>
|
$start = 0;
|
||||||
@foreach($summary as $entry)
|
$end = 0;
|
||||||
<th>{{$entry['month']}}</th>
|
$diff = 0;
|
||||||
@endforeach
|
?>
|
||||||
<th>Sum</th>
|
@foreach($balances as $balance)
|
||||||
</tr>
|
<?php
|
||||||
<tr>
|
$start += $balance['start'];
|
||||||
<th>In</th>
|
$end += $balance['end'];
|
||||||
<?php $inSum = 0;?>
|
$diff += ($balance['end']-$balance['start']);
|
||||||
@foreach($summary as $entry)
|
?>
|
||||||
<td>{{mf($entry['income'])}}</td>
|
<tr>
|
||||||
<?php $inSum+=$entry['income'];?>
|
<td>
|
||||||
@endforeach
|
<a href="{{route('accounts.show',$balance['account']->id)}}">{{{$balance['account']->name}}}</a>
|
||||||
<td>{{mf($inSum)}}</td>
|
@if($balance['shared'])
|
||||||
</tr>
|
<small><em>shared</em></small>
|
||||||
<th>Out</th>
|
@endif
|
||||||
<?php $outSum = 0;?>
|
</td>
|
||||||
@foreach($summary as $entry)
|
<td>{{mf($balance['start'])}}</td>
|
||||||
<td>{{mf($entry['expense']*-1)}}</td>
|
<td>{{mf($balance['end'])}}</td>
|
||||||
<?php $outSum+=$entry['expense']*-1;?>
|
<td>{{mf($balance['end']-$balance['start'])}}</td>
|
||||||
@endforeach
|
</tr>
|
||||||
<td>{{mf($outSum)}}</td>
|
@endforeach
|
||||||
<tr>
|
<tr>
|
||||||
<th>Difference</th>
|
<td><em>Sum of sums</em></td>
|
||||||
@foreach($summary as $entry)
|
<td>{{mf($start)}}</td>
|
||||||
<td>{{mf($entry['income']- $entry['expense'])}}</td>
|
<td>{{mf($end)}}</td>
|
||||||
@endforeach
|
<td>{{mf($diff)}}</td>
|
||||||
<td>{{mf($inSum + $outSum)}}</td>
|
</tr>
|
||||||
</tr>
|
</table>
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-lg-3 col-md-3 col-sm-3">
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
Summary (shared accounts only)
|
Income
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-striped">
|
<table class="table">
|
||||||
<tr>
|
@foreach($groupedIncomes as $income)
|
||||||
<td></td>
|
<tr>
|
||||||
@foreach($summary as $entry)
|
<td><a href="{{route('accounts.show',$income->account_id)}}">{{{$income->name}}}</a></td>
|
||||||
<th>{{$entry['month']}}</th>
|
<td>{{mf(floatval($income->sum)*-1)}}</td>
|
||||||
@endforeach
|
</tr>
|
||||||
<th>Sum</th>
|
@endforeach
|
||||||
</tr>
|
</table>
|
||||||
<tr>
|
</div>
|
||||||
<th>In</th>
|
</div>
|
||||||
<?php $inSum = 0;?>
|
<div class="col-lg-3 col-md-3 col-sm-3">
|
||||||
@foreach($summary as $entry)
|
<div class="panel panel-default">
|
||||||
<td>{{mf($entry['incomeShared'])}}</td>
|
<div class="panel-heading">
|
||||||
<?php $inSum+=$entry['incomeShared'];?>
|
Expenses
|
||||||
@endforeach
|
</div>
|
||||||
<td>{{mf($inSum)}}</td>
|
<table class="table">
|
||||||
</tr>
|
@foreach($groupedExpenses as $expense)
|
||||||
<th>Out</th>
|
<tr>
|
||||||
<?php $outSum = 0;?>
|
<td><a href="{{route('accounts.show',$expense->account_id)}}">{{{$expense->name}}}</a></td>
|
||||||
@foreach($summary as $entry)
|
<td>{{mf(floatval($expense->sum)*-1)}}</td>
|
||||||
<td>{{mf($entry['expenseShared']*-1)}}</td>
|
</tr>
|
||||||
<?php $outSum+=$entry['expenseShared']*-1;?>
|
@endforeach
|
||||||
@endforeach
|
</table>
|
||||||
<td>{{mf($outSum)}}</td>
|
|
||||||
<tr>
|
|
||||||
<th>Difference</th>
|
|
||||||
@foreach($summary as $entry)
|
|
||||||
<td>{{mf($entry['incomeShared']- $entry['expenseShared'])}}</td>
|
|
||||||
@endforeach
|
|
||||||
<td>{{mf($inSum + $outSum)}}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -115,7 +102,7 @@
|
|||||||
Budgets
|
Budgets
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div id="budgets"></div>
|
<!-- <div id="budgets"></div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
{{Form::open()}}
|
{{Form::open(['id' => 'login'])}}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="email" class="form-control" id="inputEmail" name="email" placeholder="E-mail">
|
<input type="email" class="form-control" id="inputEmail" name="email" placeholder="E-mail">
|
||||||
</div>
|
</div>
|
||||||
|
@@ -13,3 +13,4 @@ modules:
|
|||||||
cleanup: false
|
cleanup: false
|
||||||
Laravel4:
|
Laravel4:
|
||||||
environment: 'testing'
|
environment: 'testing'
|
||||||
|
filters: false
|
@@ -1,4 +1,4 @@
|
|||||||
<?php //[STAMP] 783e39b9effa232e3a9a3fc0349ec983
|
<?php //[STAMP] defdb4be0e39e8a2ea8d92c0ff514877
|
||||||
|
|
||||||
// This class was automatically generated by build task
|
// This class was automatically generated by build task
|
||||||
// You should not change it manually as it will be overwritten on next build
|
// You should not change it manually as it will be overwritten on next build
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
<?php
|
|
||||||
$I = new FunctionalTester($scenario);
|
|
||||||
$I->wantTo('perform actions and see result');
|
|
@@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
$I = new FunctionalTester($scenario);
|
|
||||||
$I->wantTo('register a new account');
|
|
||||||
$I->amOnPage('/register');
|
|
||||||
$I->submitForm('#register', ['email' => 'noreply@gmail.com']);
|
|
||||||
$I->see('Password sent!');
|
|
||||||
$I->seeRecord('users', ['email' => 'noreply@gmail.com']);
|
|
104
tests/functional/UserControllerCest.php
Normal file
104
tests/functional/UserControllerCest.php
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class UserControllerCest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function _after(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function _before(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function login(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('login');
|
||||||
|
$I->amOnPage('/login');
|
||||||
|
$I->see('Sign In');
|
||||||
|
$I->submitForm('#login', ['email' => 'functional@example.com','password' => 'functional']);
|
||||||
|
$I->see('functional@example.com');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function logout(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('logout');
|
||||||
|
#$I->amOnPage('/logout');
|
||||||
|
#$I->am
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function postLogin(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('post login');
|
||||||
|
$I->amOnRoute('login');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function postRegister(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
// @codingStandardsIgnoreStart
|
||||||
|
$I->wantTo('post-register a new account');
|
||||||
|
$I->amOnPage('/register');
|
||||||
|
$token = $I->grabValueFrom('input[name=_token]');
|
||||||
|
$I->submitForm('#register', ['email' => 'noreply@gmail.com','_token' => $token]);
|
||||||
|
$I->see('Password sent!');
|
||||||
|
$I->seeRecord('users', ['email' => 'noreply@gmail.com']);
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function postRemindme(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('get a password reminder');
|
||||||
|
$I->amOnRoute('remindme');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function register(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('register a new account');
|
||||||
|
$I->amOnRoute('register');
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function remindme(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('reminded of my password');
|
||||||
|
$I->amOnRoute('remindme');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FunctionalTester $I
|
||||||
|
*/
|
||||||
|
public function reset(FunctionalTester $I)
|
||||||
|
{
|
||||||
|
$I->wantTo('reset my password');
|
||||||
|
$I->amOnRoute('reset');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user