Code cleanup.

This commit is contained in:
James Cole 2014-12-14 20:40:02 +01:00
parent 8e6ca0dd05
commit 900dea2c66
36 changed files with 384 additions and 1094 deletions

View File

@ -1,8 +1,8 @@
<?php
use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
//use Symfony\Component\Console\Input\InputArgument;
//use Symfony\Component\Console\Input\InputOption;
/**
* Class Cleanup
@ -15,13 +15,17 @@ class Cleanup extends Command
*
* @var string
*/
// @codingStandardsIgnoreStart
protected $description = 'Clean caches, regenerate some stuff.';
// @codingStandardsIgnoreEnd
/**
* The console command name.
*
* @var string
*/
// @codingStandardsIgnoreStart
protected $name = 'firefly:cleanup';
// @codingStandardsIgnoreEnd
/**
*
@ -43,7 +47,7 @@ class Cleanup extends Command
$this->info('Cleared compiled...');
Artisan::call('ide-helper:generate');
$this->info('IDE helper, done...');
Artisan::call('ide-helper:models', ['write']);
Artisan::call('ide-helper:models', ['nowrite']);
$this->info('IDE models, done...');
Artisan::call('optimize');
$this->info('Optimized...');

View File

@ -67,9 +67,7 @@ class GoogleChartController extends BaseController
*/
public function allAccountsBalanceChart()
{
/** @var \Grumpydictator\Gchart\GChart $chart */
$chart = App::make('gchart');
$chart->addColumn('Day of the month', 'date');
$this->_chart->addColumn('Day of the month', 'date');
/** @var \FireflyIII\Shared\Preferences\Preferences $preferences */
$preferences = App::make('FireflyIII\Shared\Preferences\Preferences');
@ -83,35 +81,26 @@ class GoogleChartController extends BaseController
$accounts = $acct->getAssetAccounts();
}
/*
* Add a column for each account.
*/
/** @var Account $account */
foreach ($accounts as $account) {
$chart->addColumn('Balance for ' . $account->name, 'number');
$this->_chart->addColumn('Balance for ' . $account->name, 'number');
}
/*
* Loop the date, then loop the accounts, then add balance.
*/
$start = Session::get('start', Carbon::now()->startOfMonth());
$end = Session::get('end');
$current = clone $start;
while ($end >= $current) {
$row = [clone $current];
foreach ($accounts as $account) {
$row[] = Steam::balance($account, $current);
}
$chart->addRowArray($row);
$this->_chart->addRowArray($row);
$current->addDay();
}
$chart->generate();
$this->_chart->generate();
return Response::json($chart->getData());
return Response::json($this->_chart->getData());
}
@ -537,16 +526,16 @@ class GoogleChartController extends BaseController
$chart->addColumn('Income', 'number');
$chart->addColumn('Expenses', 'number');
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $tj */
$tj = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $repository */
$repository = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
$end = clone $start;
$end->endOfYear();
while ($start < $end) {
// total income:
$income = $tj->getSumOfIncomesByMonth($start);
$expense = $tj->getSumOfExpensesByMonth($start);
$income = $repository->getSumOfIncomesByMonth($start);
$expense = $repository->getSumOfExpensesByMonth($start);
$chart->addRow(clone $start, $income, $expense);
$start->addMonth();
@ -577,8 +566,8 @@ class GoogleChartController extends BaseController
$chart->addColumn('Income', 'number');
$chart->addColumn('Expenses', 'number');
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $tj */
$tj = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $repository */
$repository = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
$end = clone $start;
$end->endOfYear();
@ -588,8 +577,8 @@ class GoogleChartController extends BaseController
while ($start < $end) {
// total income:
$income += $tj->getSumOfIncomesByMonth($start);
$expense += $tj->getSumOfExpensesByMonth($start);
$income += $repository->getSumOfIncomesByMonth($start);
$expense += $repository->getSumOfExpensesByMonth($start);
$count++;
$start->addMonth();

View File

@ -12,11 +12,9 @@ class HelpController extends BaseController
*/
public function show($route)
{
// no valid route
$helpText = '<p>There is no help for this route!</p>';
$helpTitle = 'Help';
if (!Route::has($route)) {
$helpText = '<p>There is no help for this route!</p>';
$helpTitle = 'Help';
return Response::json(['title' => $helpTitle, 'text' => $helpText]);
}
@ -28,25 +26,17 @@ class HelpController extends BaseController
return Response::json(['title' => $helpTitle, 'text' => $helpText]);
}
// get the help-content from Github:
$uri = 'https://raw.githubusercontent.com/JC5/firefly-iii-help/master/' . e($route) . '.md';
try {
$content = file_get_contents($uri);
} catch (ErrorException $e) {
$content = '<p>There is no help for this route.</p>';
}
if (strlen($content) > 0) {
$helpText = \Michelf\Markdown::defaultTransform($content);
$helpTitle = $route;
$helpText = \Michelf\Markdown::defaultTransform($content);
$helpTitle = $route;
Cache::put('help.' . $route . '.text', $helpText, 10080); // a week.
Cache::put('help.' . $route . '.title', $helpTitle, 10080);
return Response::json(['title' => $helpTitle, 'text' => $helpText]);
}
$helpText = '<p>There is no help for this route!</p>';
$helpTitle = 'Help';
Cache::put('help.' . $route . '.text', $helpText, 10080); // a week.
Cache::put('help.' . $route . '.title', $helpTitle, 10080);
return Response::json(['title' => $helpTitle, 'text' => $helpText]);

View File

@ -316,8 +316,11 @@ class PiggybankController extends BaseController
{
/** @var \FireflyIII\Database\PiggyBank\PiggyBank $repos */
$repos = App::make('FireflyIII\Database\PiggyBank\PiggyBank');
$data = Input::except('_token');
$repos = App::make('FireflyIII\Database\PiggyBank\PiggyBank');
$data = Input::except('_token');
$data['rep_every'] = 0;
$data['reminder_skip'] = 0;
$data['order'] = 0;
switch (Input::get('post_submit_action')) {
default:

View File

@ -27,6 +27,7 @@ class ProfileController extends BaseController
/**
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
* @SuppressWarnings("CyclomaticComplexity")
*/
public function postChangePassword()
{

View File

@ -73,7 +73,7 @@ class RepeatedExpenseController extends BaseController
$repetitions = $piggyBank->piggybankrepetitions()->get();
$repetitions->each(
function (PiggybankRepetition $repetition) use ($repository) {
$repository->calculateParts($repetition);
$repetition->bars = $repository->calculateParts($repetition);
}
);

View File

@ -7,6 +7,7 @@ use FireflyIII\Report\ReportInterface as Report;
/**
* @SuppressWarnings("CamelCase")
*
*
* Class ReportController
*/
class ReportController extends BaseController
@ -33,109 +34,6 @@ class ReportController extends BaseController
}
/**
* @param $year
* @param $month
*
* @return \Illuminate\View\View
*/
public function budgets($year, $month)
{
try {
$start = new Carbon($year . '-' . $month . '-01');
} catch (Exception $e) {
App::abort(500);
}
$end = clone $start;
$title = 'Reports';
$subTitle = 'Budgets in ' . $start->format('F Y');
$mainTitleIcon = 'fa-line-chart';
$subTitleIcon = 'fa-bar-chart';
$end->endOfMonth();
// get a list of all budgets and expenses.
/** @var \FireflyIII\Database\Budget\Budget $budgetRepository */
$budgetRepository = App::make('FireflyIII\Database\Budget\Budget');
/** @var \FireflyIII\Database\Account\Account $accountRepository */
$accountRepository = App::make('FireflyIII\Database\Account\Account');
$budgets = $budgetRepository->get();
// calculate some stuff:
$budgets->each(
function (Budget $budget) use ($start, $end, $budgetRepository) {
$limitRepetitions = $budget->limitrepetitions()->where('limit_repetitions.startdate', '>=', $start->format('Y-m-d'))->where(
'enddate', '<=', $end->format(
'Y-m-d'
)
)->get();
$repInfo = [];
/** @var LimitRepetition $repetition */
foreach ($limitRepetitions as $repetition) {
$spent = $budgetRepository->spentInPeriod($budget, $start, $end);
if ($spent > floatval($repetition->amount)) {
// overspent!
$overspent = true;
$pct = floatval($repetition->amount) / $spent * 100;
} else {
$overspent = false;
$pct = $spent / floatval($repetition->amount) * 100;
}
$pctDisplay = $spent / floatval($repetition->amount) * 100;
$repInfo[] = [
'date' => DateKit::periodShow($repetition->startdate, $repetition->budgetLimit->repeat_freq),
'spent' => $spent,
'budgeted' => floatval($repetition->amount),
'left' => floatval($repetition->amount) - $spent,
'pct' => ceil($pct),
'pct_display' => ceil($pctDisplay),
'overspent' => $overspent,
];
}
$budget->repInfo = $repInfo;
}
);
$accounts = $accountRepository->getAssetAccounts();
$accounts->each(
function (Account $account) use ($start, $end, $accountRepository) {
$journals = $accountRepository->getTransactionJournalsInRange($account, $start, $end);
$budgets = [];
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$budgetId = isset($journal->budgets[0]) ? $journal->budgets[0]->id : 0;
$budgetName = isset($journal->budgets[0]) ? $journal->budgets[0]->name : '(no budget)';
if (!isset($budgets[$budgetId])) {
$arr = [
'budget_id' => $budgetId,
'budget_name' => $budgetName,
'spent' => floatval($journal->getAmount()),
'budgeted' => 0,
];
$budgets[$budgetId] = $arr;
} else {
$budgets[$budgetId]['spent'] += floatval($journal->getAmount());
}
}
foreach ($budgets as $budgetId => $budget) {
$budgets[$budgetId]['left'] = $budget['budgeted'] - $budget['spent'];
}
$account->budgetInfo = $budgets;
}
);
return View::make('reports.budgets', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'budgets', 'accounts'));
}
/**
*
*/
@ -154,6 +52,9 @@ class ReportController extends BaseController
* @param $year
* @param $month
*
* @SuppressWarnings("CyclomaticComplexity")
* @SuppressWarnings("MethodLength")
*
* @return \Illuminate\View\View
*/
public function unbalanced($year, $month)
@ -173,59 +74,35 @@ class ReportController extends BaseController
/** @var \FireflyIII\Database\TransactionJournal\TransactionJournal $journalRepository */
$journalRepository = App::make('FireflyIII\Database\TransactionJournal\TransactionJournal');
$journals = $journalRepository->getInDateRange($start, $end);
/*
* Get all journals from this month:
*/
$journals = $journalRepository->getInDateRange($start, $end);
/*
* Filter withdrawals:
*/
$withdrawals = $journals->filter(
function (TransactionJournal $journal) {
if ($journal->transactionType->type == 'Withdrawal' && count($journal->budgets) == 0) {
// count groups related to balance.
if ($journal->transactiongroups()->where('relation', 'balance')->count() == 0) {
return $journal;
}
$relations = $journal->transactiongroups()->where('relation', 'balance')->count();
$budgets = $journal->budgets()->count();
$type = $journal->transactionType->type;
if ($type == 'Withdrawal' && $budgets == 0 && $relations == 0) {
return $journal;
}
return null;
}
);
/*
* Filter deposits.
*/
$deposits = $journals->filter(
function (TransactionJournal $journal) {
if ($journal->transactionType->type == 'Deposit' && count($journal->budgets) == 0) {
// count groups related to balance.
if ($journal->transactiongroups()->where('relation', 'balance')->count() == 0) {
return $journal;
}
$relations = $journal->transactiongroups()->where('relation', 'balance')->count();
$budgets = $journal->budgets()->count();
$type = $journal->transactionType->type;
if ($type == 'Deposit' && $budgets == 0 && $relations == 0) {
return $journal;
}
return null;
}
);
/*
* Filter transfers (not yet used)
*/
// $transfers = $journals->filter(
// function (TransactionJournal $journal) {
// if ($journal->transactionType->type == 'Transfer') {
// return $journal;
// }
// }
// );
$journals = $withdrawals->merge($deposits);
return View::make('reports.unbalanced', compact('start', 'end', 'title', 'subTitle', 'subTitleIcon', 'mainTitleIcon', 'journals'));
}

View File

@ -71,10 +71,6 @@ class TransactionController extends BaseController
*/
public function create($what = 'deposit')
{
/*
* The repositories we need:
*/
/** @var \FireflyIII\Database\Account\Account $accountRepository */
$accountRepository = App::make('FireflyIII\Database\Account\Account');
@ -100,9 +96,6 @@ class TransactionController extends BaseController
$piggies[0] = '(no piggy bank)';
asort($piggies);
/*
* respond to a possible given values in the URL.
*/
$preFilled = Session::has('preFilled') ? Session::get('preFilled') : [];
$respondTo = ['account_id', 'account_from_id'];
foreach ($respondTo as $r) {
@ -222,24 +215,8 @@ class TransactionController extends BaseController
// get asset accounts with names and id's.
$accounts = FFForm::makeSelectList($accountRepository->getAssetAccounts());
// get budgets as a select list.
$budgets = FFForm::makeSelectList($budgetRepository->get());
$budgets[0] = '(no budget)';
/*
* Get all piggy banks plus (if any) the relevant piggy bank. Since just one
* of the transactions in the journal has this field, it should all fill in nicely.
*/
// get the piggy banks.
$piggies = FFForm::makeSelectList($piggyRepository->get());
$piggies[0] = '(no piggy bank)';
$piggyBankId = 0;
foreach ($journal->transactions as $t) {
if (!is_null($t->piggybank_id)) {
$piggyBankId = $t->piggybank_id;
}
}
$budgets = FFForm::makeSelectList($budgetRepository->get(), true);
$piggies = FFForm::makeSelectList($piggyRepository->get(), true);
/*
* Data to properly display the edit form.
@ -248,7 +225,7 @@ class TransactionController extends BaseController
'date' => $journal->date->format('Y-m-d'),
'category' => '',
'budget_id' => 0,
'piggybank_id' => $piggyBankId
'piggybank_id' => 0
];
/*
@ -482,11 +459,7 @@ class TransactionController extends BaseController
* Trigger a search for the related (if selected)
* piggy bank and store an event.
*/
$piggyID = null;
if (!is_null(Input::get('piggybank_id')) && intval(Input::get('piggybank_id')) > 0) {
$piggyID = intval(Input::get('piggybank_id'));
}
Event::fire('transactionJournal.store', [$journal, $piggyID]); // new and used.
Event::fire('transactionJournal.store', [$journal, Input::get('piggybank_id')]); // new and used.
/*
* Also trigger on both transactions.
*/

View File

@ -46,7 +46,7 @@ class CreatePiggybanksTable extends Migration
$table->boolean('remind_me');
$table->integer('order')->unsigned();
// connect account to piggybank.
// connect account to piggy bank.
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
// for an account, the name must be unique.

View File

@ -3,6 +3,8 @@
use Illuminate\Database\Migrations\Migration;
/**
* SuppressWarnings(PHPMD.ShortMethodName)
*
* Class ChangesForV321
*/
class ChangesForV321 extends Migration
@ -15,9 +17,9 @@ class ChangesForV321 extends Migration
*/
public function down()
{
DB::update(DB::raw('RENAME TABLE `budget_limits` TO `limits`;'));
Schema::rename('budget_limits','limits');
DB::update(DB::raw('ALTER TABLE `limit_repetitions` ALGORITHM=INPLACE, CHANGE `budget_limit_id` `limit_id` INT UNSIGNED NOT NULL'));
DB::update(DB::Raw('ALTER TABLE `transactions` ADD `piggybank_id` int(10) unsigned DEFAULT NULL AFTER `account_id`;'));
}
/**
@ -27,8 +29,9 @@ class ChangesForV321 extends Migration
*/
public function up()
{
DB::update(DB::raw('RENAME TABLE `limits` TO `budget_limits`;'));
Schema::rename('limits','budget_limits');
DB::update(DB::raw('ALTER TABLE `limit_repetitions` ALGORITHM=INPLACE, CHANGE `limit_id` `budget_limit_id` INT UNSIGNED NOT NULL'));
DB::update(DB::Raw('ALTER TABLE `transactions` DROP `piggybank_id`'));
}

View File

@ -28,6 +28,7 @@ class TestContentSeeder extends Seeder
// create two asset accounts.
$checking = Account::create(['user_id' => $user->id, 'account_type_id' => $assetType->id, 'name' => 'Checking account', 'active' => 1]);
$savings = Account::create(['user_id' => $user->id, 'account_type_id' => $assetType->id, 'name' => 'Savings account', 'active' => 1]);
/** @noinspection PhpUnusedLocalVariableInspection */
$deleteMe = Account::create(['user_id' => $user->id, 'account_type_id' => $assetType->id, 'name' => 'Delete me', 'active' => 1]);
// create two budgets:

View File

@ -38,6 +38,11 @@ class PiggybankPart
*/
public function getReminder()
{
if(is_null($this->reminder)) {
$this->reminder = $this->repetition->piggybank->reminders()->where('startdate', $bar->getStartdate()->format('Y-m-d'))->where(
'enddate', $bar->getTargetdate()->format('Y-m-d')
)->first();
}
return $this->reminder;
}

View File

@ -5,6 +5,7 @@ use Carbon\Carbon;
use FireflyIII\Database\CommonDatabaseCalls;
use FireflyIII\Database\CUD;
use FireflyIII\Database\SwitchUser;
use FireflyIII\Exception\FireflyException;
use FireflyIII\Exception\NotImplementedException;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
@ -42,6 +43,7 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
* @param array $data
*
* @return \Eloquent
* @throws FireflyException
*/
public function store(array $data)
{
@ -51,8 +53,8 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
$budget->class = 'Budget';
if (!$budget->isValid()) {
var_dump($budget->getErrors()->all());
exit;
\Log::error('Could not store budget: ' . $budget->getErrors()->toJson());
throw new FireflyException($budget->getErrors()->first());
}
$budget->save();
@ -68,12 +70,6 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
public function update(\Eloquent $model, array $data)
{
$model->name = $data['name'];
if (!$model->isValid()) {
var_dump($model->getErrors()->all());
exit;
}
$model->save();
return true;
@ -91,25 +87,8 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
{
$warnings = new MessageBag;
$successes = new MessageBag;
$errors = new MessageBag;
if (isset($model['name'])) {
if (strlen($model['name']) < 1) {
$errors->add('name', 'Name is too short');
}
if (strlen($model['name']) > 200) {
$errors->add('name', 'Name is too long');
}
} else {
$errors->add('name', 'Name is mandatory');
}
$validator = \Validator::make($model, \Component::$rules);
if ($validator->invalid()) {
$errors->merge($validator->errors());
}
$errors = $validator->errors();
if (!$errors->has('name')) {
$successes->add('name', 'OK');
@ -274,12 +253,12 @@ class Budget implements CUD, CommonDatabaseCalls, BudgetInterface
// Add expenses that have no budget:
return $this->getUser()->transactionjournals()->whereNotIn(
'transaction_journals.id', function ($query) use ($start, $end) {
$query->select('transaction_journals.id')->from('transaction_journals')->leftJoin(
'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
)->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->where(
'transaction_journals.date', '>=', $start->format('Y-m-d')
)->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where('components.class', 'Budget');
}
$query->select('transaction_journals.id')->from('transaction_journals')->leftJoin(
'component_transaction_journal', 'component_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'
)->leftJoin('components', 'components.id', '=', 'component_transaction_journal.component_id')->where(
'transaction_journals.date', '>=', $start->format('Y-m-d')
)->where('transaction_journals.date', '<=', $end->format('Y-m-d'))->where('components.class', 'Budget');
}
)->before($end)->after($start)->lessThan(0)->transactionTypes(['Withdrawal'])->get();
}

View File

@ -5,6 +5,7 @@ use Carbon\Carbon;
use FireflyIII\Database\CommonDatabaseCalls;
use FireflyIII\Database\CUD;
use FireflyIII\Database\SwitchUser;
use FireflyIII\Exception\FireflyException;
use FireflyIII\Exception\NotImplementedException;
use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag;
@ -43,6 +44,7 @@ class Category implements CUD, CommonDatabaseCalls
* @param array $data
*
* @return \Eloquent
* @throws FireflyException
*/
public function store(array $data)
{
@ -51,8 +53,8 @@ class Category implements CUD, CommonDatabaseCalls
$category->class = 'Category';
$category->user()->associate($this->getUser());
if (!$category->isValid()) {
var_dump($category->getErrors());
exit();
\Log::error('Could not store category: ' . $category->getErrors()->toJson());
throw new FireflyException($category->getErrors()->first());
}
$category->save();
@ -61,16 +63,17 @@ class Category implements CUD, CommonDatabaseCalls
/**
* @param \Eloquent $model
* @param array $data
* @param array $data
*
* @return bool
* @throws FireflyException
*/
public function update(\Eloquent $model, array $data)
{
$model->name = $data['name'];
if (!$model->isValid()) {
var_dump($model->getErrors()->all());
exit;
\Log::error('Could not store category: ' . $model->getErrors()->toJson());
throw new FireflyException($model->getErrors()->first());
}
@ -91,25 +94,8 @@ class Category implements CUD, CommonDatabaseCalls
{
$warnings = new MessageBag;
$successes = new MessageBag;
$errors = new MessageBag;
if (isset($model['name'])) {
if (strlen($model['name']) < 1) {
$errors->add('name', 'Name is too short');
}
if (strlen($model['name']) > 200) {
$errors->add('name', 'Name is too long');
}
} else {
$errors->add('name', 'Name is mandatory');
}
$validator = \Validator::make($model, \Component::$rules);
if ($validator->invalid()) {
$errors->merge($validator->getErrors());
}
$errors = $validator->errors();
if (!$errors->has('name')) {
$successes->add('name', 'OK');
@ -171,7 +157,7 @@ class Category implements CUD, CommonDatabaseCalls
/**
* @param $name
*
* @return static
* @return \Category
*/
public function firstOrCreate($name)
{
@ -203,11 +189,12 @@ class Category implements CUD, CommonDatabaseCalls
* @param Carbon $date
*
* @return null
* @throws NotImplementedException
* @internal param \Category $budget
*/
public function repetitionOnStartingOnDate(\Category $category, Carbon $date)
{
return null;
throw new NotImplementedException;
}
/**

View File

@ -42,34 +42,22 @@ class PiggyBank implements CUD, CommonDatabaseCalls, PiggybankInterface
* @param array $data
*
* @return \Eloquent
* @throws FireflyException
*/
public function store(array $data)
{
$data['rep_every'] = isset($data['rep_every']) ? $data['rep_every'] : 0;
$data['reminder_skip'] = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0;
$data['order'] = isset($data['order']) ? $data['order'] : 0;
$data['remind_me'] = isset($data['remind_me']) ? intval($data['remind_me']) : 0;
$data['startdate'] = isset($data['startdate']) ? $data['startdate'] : Carbon::now()->format('Y-m-d');
$data['targetdate'] = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null;
if ($data['remind_me'] == 0) {
if (!isset($data['remind_me']) || (isset($data['remind_me']) && $data['remind_me'] == 0)) {
$data['reminder'] = null;
}
$piggyBank = new \Piggybank($data);
$piggyBank->save();
$piggybank = new \Piggybank($data);
if (!$piggybank->isValid()) {
var_dump($piggybank->getErrors()->all());
exit;
}
$piggybank->save();
return $piggybank;
return $piggyBank;
}
/**
* @param \Eloquent $model
* @param array $data
* @param array $data
*
* @return bool
*/
@ -80,21 +68,16 @@ class PiggyBank implements CUD, CommonDatabaseCalls, PiggybankInterface
$model->account_id = intval($data['account_id']);
$model->targetamount = floatval($data['targetamount']);
$model->targetdate = isset($data['targetdate']) && $data['targetdate'] != '' ? $data['targetdate'] : null;
$model->rep_every = isset($data['rep_every']) ? $data['rep_every'] : 0;
$model->reminder_skip = isset($data['reminder_skip']) ? $data['reminder_skip'] : 0;
$model->order = isset($data['order']) ? $data['order'] : 0;
$model->remind_me = isset($data['remind_me']) ? intval($data['remind_me']) : 0;
$model->rep_every = intval($data['rep_every']);
$model->reminder_skip = intval($data['reminder_skip']);
$model->order = intval($data['order']);
$model->remind_me = intval($data['remind_me']);
$model->reminder = isset($data['reminder']) ? $data['reminder'] : 'month';
if ($model->remind_me == 0) {
$model->reminder = null;
}
if (!$model->isValid()) {
var_dump($model->getErrors());
exit();
}
$model->save();
return true;
@ -241,8 +224,7 @@ class PiggyBank implements CUD, CommonDatabaseCalls, PiggybankInterface
* @throws FireflyException
* @throws NotImplementedException
*/
public function findRepetitionByDate(\Piggybank $piggybank, /** @noinspection PhpUnusedParameterInspection */
Carbon $date)
public function findRepetitionByDate(\Piggybank $piggybank, Carbon $date)
{
$reps = $piggybank->piggybankrepetitions()->get();
if ($reps->count() == 1) {

View File

@ -37,245 +37,64 @@ class RepeatedExpense implements CUD, CommonDatabaseCalls, PiggybankInterface
*
* @param \PiggybankRepetition $repetition
*
* @return \PiggybankRepetition
* @return Collection
*/
public function calculateParts(\PiggybankRepetition $repetition)
{
\Log::debug('NOW in calculateParts()');
\Log::debug('Repetition id is ' . $repetition->id);
/** @var \Piggybank $piggyBank */
$piggyBank = $repetition->piggybank()->first();
$bars = new Collection;
\Log::debug('connected piggy bank is: ' . $piggyBank->name . ' (#' . $piggyBank->id . ')');
/*
* If no reminders are set, the repetition is split in exactly one part:
*/
if (is_null($piggyBank->reminder)) {
$part = new PiggybankPart;
$part->setRepetition($repetition);
$part->setAmountPerBar(floatval($piggyBank->targetamount));
$part->setCurrentamount($repetition->currentamount);
$part->setCumulativeAmount($piggyBank->targetamount);
$part->setStartdate(clone $repetition->startdate);
$part->setTargetdate(clone $repetition->targetdate);
$bars->push($part);
$repetition->bars = $bars;
return $repetition;
}
$piggyBank = $repetition->piggybank()->first();
$bars = new Collection;
$currentStart = clone $repetition->startdate;
/*
* Loop between start and target instead of counting manually.
*/
$index = 0;
//echo 'Looping!<br>';
//echo $repetition->startdate . ' until ' . $repetition->targetdate . '<br>';
if (is_null($piggyBank->reminder)) {
$entry = ['repetition' => $repetition, 'amountPerBar' => floatval($piggyBank->targetamount),
'currentAmount' => floatval($repetition->currentamount), 'cumulativeAmount' => floatval($piggyBank->targetamount),
'startDate' => clone $repetition->startdate, 'targetDate' => clone $repetition->targetdate];
$bars->push($this->createPiggyBankPart($entry));
return $bars;
}
while ($currentStart < $repetition->targetdate) {
$currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder);
if ($currentTarget > $repetition->targetdate) {
$currentTarget = clone $repetition->targetdate;
}
// create a part:
$part = new PiggybankPart;
$part->setRepetition($repetition);
$part->setCurrentamount($repetition->currentamount);
$part->setStartdate($currentStart);
$part->setTargetdate($currentTarget);
$bars->push($part);
//echo 'Loop #' . $index . ', from ' . $currentStart . ' until ' . $currentTarget . '<br />';
/*
* Jump to the next period by adding a day.
*/
$currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder, $repetition->targetdate);
$entry = ['repetition' => $repetition, 'amountPerBar' => null, 'currentAmount' => floatval($repetition->currentamount),
'cumulativeAmount' => null, 'startDate' => $currentStart, 'targetDate' => $currentTarget];
$bars->push($this->createPiggyBankPart($entry));
$currentStart = clone $currentTarget;
$currentStart->addDay();//\DateKit::addPeriod($currentTarget, $piggyBank->reminder, 0);
$index++;
$currentStart->addDay();
}
/*
* Loop parts again to add some
*/
$parts = $bars->count();
$amountPerBar = floatval($piggyBank->targetamount) / $parts;
$amountPerBar = floatval($piggyBank->targetamount) / $bars->count();
$cumulative = $amountPerBar;
/** @var PiggybankPart $bar */
foreach ($bars as $index => $bar) {
$bar->setAmountPerBar($amountPerBar);
$bar->setCumulativeAmount($cumulative);
if ($parts - 1 == $index) {
if ($bars->count() - 1 == $index) {
$bar->setCumulativeAmount($piggyBank->targetamount);
}
$reminder = $piggyBank->reminders()
->where('startdate', $bar->getStartdate()->format('Y-m-d'))
->where('enddate', $bar->getTargetdate()->format('Y-m-d'))
->first();
if ($reminder) {
$bar->setReminder($reminder);
}
$cumulative += $amountPerBar;
}
$repetition->bars = $bars;
return $bars;
}
return $repetition;
//
// // if($parts > 12) {
// // $parts = 12;
// // $currentStart = \DateKit::startOfPeriod(Carbon::now(), $piggyBank->reminder);
// // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder);
// // }
//
// for ($i = 0; $i < $parts; $i++) {
// /*
// * If it's not the first repetition, jump the start date a [period]
// * and jump the target date a [period]
// */
// if ($i > 0) {
// $currentStart = clone $currentTarget;
// $currentStart->addDay();
// $currentTarget = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// }
// /*
// * If it's the first one, and has reminders, jump to the end of the [period]
// */
// if ($i == 0 && !is_null($piggyBank->reminder)) {
// $currentTarget = \DateKit::endOfX($currentStart, $piggyBank->reminder);
// }
// if ($currentStart > $repetition->targetdate) {
// break;
// }
//
//
// /*
// * Jump one month ahead after the first instance:
// */
// // if ($i > 0) {
// // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// // /*
// // * Jump to the start of the period too:
// // */
// // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// //
// // }
//
//
// /*
// * Move the current start to the actual start of
// * the [period] once the first iteration has passed.
// */
// // if ($i != 0) {
// // $currentStart = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// // }
// // if($i == 0 && !is_null($piggyBank->reminder)) {
// // $currentEnd = \DateKit::startOfPeriod($currentStart, $piggyBank->reminder);
// // $currentEnd = \DateKit::endOfPeriod($currentEnd, $piggyBank->reminder);
// // }
//
// $part = new PiggybankPart;
// $part->setRepetition($repetition);
// $part->setAmount($currentAmount);
// $part->setAmountPerBar($amountPerBar);
// $part->setCurrentamount($repetition->currentamount);
// $part->setStartdate($currentStart);
// $part->setTargetdate($currentTarget);
// if (!is_null($piggyBank->reminder)) {
// // might be a reminder for this range?
// $reminder = $piggyBank->reminders()
// ->where('startdate', $currentStart->format('Y-m-d'))
// ->where('enddate', $currentTarget->format('Y-m-d'))
// ->first();
// if ($reminder) {
// $part->setReminder($reminder);
// }
//
// }
//
// // if (!is_null($piggyBank->reminder)) {
// // $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// // $currentEnd = \DateKit::endOfPeriod($currentStart, $piggyBank->reminder);
// // }
//
//
// $bars->push($part);
// $currentAmount += $amountPerBar;
// }
// $repetition->bars = $bars;
//
// return $repetition;
// exit;
//
//
// $repetition->hello = 'World!';
//
// return $repetition;
//
// $return = new Collection;
// $repetitions = $piggyBank->piggybankrepetitions()->get();
// /** @var \PiggybankRepetition $repetition */
// foreach ($repetitions as $repetition) {
//
//
// if (is_null($piggyBank->reminder)) {
// // simple, one part "repetition".
// $part = new PiggybankPart;
// $part->setRepetition($repetition);
// } else {
// $part = new PiggybankPart;
// }
//
//
// // end!
// $return->push($part);
// }
//
// exit;
//
// return $return;
// $piggyBank->currentRelevantRep(); // get the current relevant repetition.
// if (!is_null($piggyBank->reminder)) {
// switch ($piggyBank->reminder) {
// default:
// throw new FireflyException('Cannot handle "' . $piggyBank->reminder . '" reminders for repeated expenses');
// break;
// case 'month':
// $start = clone $piggyBank->currentRep->startdate;
// $start->startOfMonth();
// $end = clone $piggyBank->currentRep->targetdate;
// $end->endOfMonth();
// $piggyBank->parts = $start->diffInMonths($end);
// unset($start, $end);
// break;
// }
//
// } else {
// $piggyBank->parts = 1;
// }
//
// // number of bars:
// $piggyBank->barCount = floor(12 / $piggyBank->parts) == 0 ? 1 : floor(12 / $piggyBank->parts);
// $amountPerBar = floatval($piggyBank->targetamount) / $piggyBank->parts;
// $currentAmount = floatval($amountPerBar);
// $bars = [];
// $currentStart = clone $piggyBank->currentRep->startdate;
// for ($i = 0; $i < $piggyBank->parts; $i++) {
// // niet elke keer een andere dinges pakken? om target te redden?
// if (!is_null($piggyBank->reminder)) {
// $currentStart = \DateKit::addPeriod($currentStart, $piggyBank->reminder, 0);
// }
// $bars[] = [
// 'amount' => $currentAmount,
// 'date' => $currentStart
// ];
//
//
// $currentAmount += $amountPerBar;
// }
// $piggyBank->bars = $bars;
/**
* @param array $data
*
* @return PiggybankPart
*/
public function createPiggyBankPart(array $data)
{
$part = new PiggybankPart;
$part->setRepetition($data['repetition']);
$part->setAmountPerBar($data['amountPerBar']);
$part->setCurrentamount($data['currentAmount']);
$part->setCumulativeAmount($data['cumulativeAmount']);
$part->setStartdate($data['startDate']);
$part->setTargetdate($data['targetDate']);
return $part;
}
/**

View File

@ -47,7 +47,6 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
*/
public function store(array $data)
{
var_dump($data);
$recurring = new \RecurringTransaction;
$recurring->user()->associate($this->getUser());
$recurring->name = $data['name'];
@ -58,22 +57,17 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
$date = new Carbon($data['date']);
$recurring->active = isset($data['active']) && intval($data['active']) == 1 ? 1 : 0;
$recurring->automatch = isset($data['automatch']) && intval($data['automatch']) == 1 ? 1 : 0;
$recurring->active = intval($data['active']);
$recurring->automatch = intval($data['automatch']);
$recurring->repeat_freq = $data['repeat_freq'];
/*
* Jump to the start of the period.
*/
$date = DateKit::startOfPeriod($date, $data['repeat_freq']);
$date = \DateKit::startOfPeriod($date, $data['repeat_freq']);
$recurring->date = $date;
$recurring->skip = intval($data['skip']);
if (!$recurring->isValid()) {
var_dump($recurring->getErrors());
exit();
}
$recurring->save();
return $recurring;
@ -87,8 +81,6 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
*/
public function update(\Eloquent $model, array $data)
{
var_dump($data);
$model->name = $data['name'];
$model->match = $data['match'];
$model->amount_max = floatval($data['amount_max']);
@ -97,16 +89,10 @@ class RecurringTransaction implements CUD, CommonDatabaseCalls, RecurringTransac
$date = new Carbon($data['date']);
$model->date = $date;
$model->active = isset($data['active']) && intval($data['active']) == 1 ? 1 : 0;
$model->automatch = isset($data['automatch']) && intval($data['automatch']) == 1 ? 1 : 0;
$model->active = intval($data['active']);
$model->automatch = intval($data['automatch']);
$model->repeat_freq = $data['repeat_freq'];
$model->skip = intval($data['skip']);
if (!$model->isValid()) {
var_dump($model->getErrors());
exit();
}
$model->save();
return true;

View File

@ -78,64 +78,19 @@ class Transaction implements CUD, CommonDatabaseCalls
*
* @param array $model
*
* @return array
* @return MessageBag
*/
public function validate(array $model)
{
$warnings = new MessageBag;
$successes = new MessageBag;
$errors = new MessageBag;
if (!isset($model['account_id']) && !isset($model['account'])) {
$errors = new MessageBag;
if (is_null($model['account'])) {
$errors->add('account', 'No account present');
}
if (isset($model['account']) && !($model['account'] instanceof \Account)) {
$errors->add('account', 'No valid account present');
}
if (isset($model['account_id']) && intval($model['account_id']) < 0) {
$errors->add('account', 'No valid account_id present');
if (is_null($model['transaction_journal'])) {
$errors->add('transaction_journal', 'No valid transaction journal present');
}
if (isset($model['piggybank_id']) && intval($model['piggybank_id']) < 0) {
$errors->add('piggybank', 'No valid piggybank_id present');
}
if (!isset($model['transaction_journal_id']) && !isset($model['transaction_journal'])) {
$errors->add('transaction_journal', 'No TJ present');
}
if (isset($model['transaction_journal']) && !($model['transaction_journal'] instanceof \TransactionJournal)) {
$errors->add('transaction_journal', 'No valid transaction_journal present');
}
if (isset($model['transaction_journal_id']) && intval($model['transaction_journal_id']) < 0) {
$errors->add('account', 'No valid transaction_journal_id present');
}
if (isset($model['description']) && strlen($model['description']) > 255) {
$errors->add('account', 'Description too long');
}
if (!isset($model['amount'])) {
$errors->add('amount', 'No amount present.');
}
if (isset($model['amount']) && floatval($model['amount']) == 0) {
$errors->add('amount', 'Invalid amount.');
}
if (!$errors->has('account')) {
$successes->add('account', 'OK');
}
if (!$errors->has('')) {
$successes->add('piggybank', 'OK');
}
if (!$errors->has('transaction_journal')) {
$successes->add('transaction_journal', 'OK');
}
if (!$errors->has('amount')) {
$successes->add('amount', 'OK');
}
return ['errors' => $errors, 'warnings' => $warnings, 'successes' => $successes];
return $errors;
}
/**

View File

@ -62,111 +62,24 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
*/
public function store(array $data)
{
/** @var \FireflyIII\Database\TransactionType\TransactionType $typeRepository */
$typeRepository = \App::make('FireflyIII\Database\TransactionType\TransactionType');
/** @var \FireflyIII\Database\Account\Account $accountRepository */
$accountRepository = \App::make('FireflyIII\Database\Account\Account');
/** @var \FireflyIII\Database\TransactionCurrency\TransactionCurrency $currencyRepository */
$currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency\TransactionCurrency');
/** @var \FireflyIII\Database\Transaction\Transaction $transactionRepository */
$transactionRepository = \App::make('FireflyIII\Database\Transaction\Transaction');
$journalType = $typeRepository->findByWhat($data['what']);
$currency = $currencyRepository->findByCode($data['currency']);
$journal = new \TransactionJournal;
$journal->transactionType()->associate($journalType);
$journal->transactionCurrency()->associate($currency);
$journal->user()->associate($this->getUser());
$journal->description = $data['description'];
$journal->date = $data['date'];
$journal->completed = 0;
/*
* This must be enough to store the journal:
*/
if (!$journal->isValid()) {
\Log::error($journal->getErrors()->all());
throw new FireflyException('store() transaction journal failed, but it should not!');
}
$journalType = $this->getJournalType($data['what']);
$currency = $this->getJournalCurrency($data['currency']);
$journal = new \TransactionJournal(
['transaction_type_id' => $journalType->id, 'transaction_currency_id' => $currency->id, 'user_id' => $this->getUser()->id,
'description' => $data['description'], 'date' => $data['date'], 'completed' => 0]
);
$journal->save();
/*
* Still need to find the accounts related to the transactions.
* This depends on the type of transaction.
*/
switch ($data['what']) {
case 'withdrawal':
$data['from'] = $accountRepository->find($data['account_id']);
$data['to'] = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']);
break;
case 'opening':
break;
case 'deposit':
$data['to'] = $accountRepository->find($data['account_id']);
$data['from'] = $accountRepository->firstRevenueAccountOrCreate($data['revenue_account']);
break;
case 'transfer':
$data['from'] = $accountRepository->find($data['account_from_id']);
$data['to'] = $accountRepository->find($data['account_to_id']);
break;
list($fromAccount, $toAccount) = $this->storeAccounts($data);
default:
throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".');
break;
}
/*
* Then store both transactions.
*/
$first = ['account' => $data['from'], 'transaction_journal' => $journal, 'amount' => ($data['amount'] * -1),];
$validate = $transactionRepository->validate($first);
if ($validate['errors']->count() == 0) {
$transactionRepository->store($first);
} else {
throw new FireflyException($validate['errors']->first());
}
$second = ['account' => $data['to'], 'transaction_journal' => $journal, 'amount' => floatval($data['amount']),];
$validate = $transactionRepository->validate($second);
if ($validate['errors']->count() == 0) {
$transactionRepository->store($second);
} else {
throw new FireflyException($validate['errors']->first());
}
/*
* Store the budget.
*/
if (isset($data['budget_id']) && intval($data['budget_id']) > 0) {
/** @var \FireflyIII\Database\Budget\Budget $budgetRepository */
$budgetRepository = \App::make('FireflyIII\Database\Budget\Budget');
$budget = $budgetRepository->find(intval($data['budget_id']));
if ($budget) {
$journal->budgets()->save($budget);
}
}
if (isset($data['category']) && strlen($data['category']) > 0) {
/** @var \FireflyIII\Database\Category\Category $categoryRepository */
$categoryRepository = \App::make('FireflyIII\Database\Category\Category');
$category = $categoryRepository->firstOrCreate($data['category']);
if ($category) {
$journal->categories()->save($category);
}
}
$this->storeTransaction(['account' => $fromAccount, 'transaction_journal' => $journal, 'amount' => floatval($data['amount'] * -1)]);
$this->storeTransaction(['account' => $toAccount, 'transaction_journal' => $journal, 'amount' => floatval($data['amount'])]);
$this->storeBudget($data, $journal);
$this->storeCategory($data, $journal);
$journal->completed = 1;
$journal->save();
/*
* Trigger a search for a relevant recurring transaction.
*/
return $journal;
}
@ -254,6 +167,7 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
$model->components()->sync($components);
/*
* TODO move to transaction thing.
* Now we can update the transactions related to this journal.
*/
$amount = floatval($data['amount']);
@ -439,6 +353,123 @@ class TransactionJournal implements TransactionJournalInterface, CUD, CommonData
}
/**
* @param $type
*
* @return \AccountType|null
* @throws FireflyException
*/
public function getJournalType($type)
{
/** @var \FireflyIII\Database\TransactionType\TransactionType $typeRepository */
$typeRepository = \App::make('FireflyIII\Database\TransactionType\TransactionType');
return $typeRepository->findByWhat($type);
}
/**
* @param $currency
*
* @return null|\TransactionCurrency
*/
public function getJournalCurrency($currency)
{
/** @var \FireflyIII\Database\TransactionCurrency\TransactionCurrency $currencyRepository */
$currencyRepository = \App::make('FireflyIII\Database\TransactionCurrency\TransactionCurrency');
return $currencyRepository->findByCode($currency);
}
/**
* @param array $data
*
* @return array
* @throws FireflyException
*/
public function storeAccounts(array $data)
{
/** @var \FireflyIII\Database\Account\Account $accountRepository */
$accountRepository = \App::make('FireflyIII\Database\Account\Account');
$fromAccount = null;
$toAccount = null;
switch ($data['what']) {
case 'withdrawal':
$fromAccount = $accountRepository->find($data['account_id']);
$toAccount = $accountRepository->firstExpenseAccountOrCreate($data['expense_account']);
break;
case 'opening':
break;
case 'deposit':
$fromAccount = $accountRepository->firstRevenueAccountOrCreate($data['revenue_account']);
$toAccount = $accountRepository->find($data['account_id']);
break;
case 'transfer':
$fromAccount = $accountRepository->find($data['account_from_id']);
$toAccount = $accountRepository->find($data['account_to_id']);
break;
default:
throw new FireflyException('Cannot save transaction journal with accounts based on $what "' . $data['what'] . '".');
break;
}
return [$fromAccount, $toAccount];
}
/**
* @param array $data
*
* @return \Eloquent
* @throws FireflyException
*/
public function storeTransaction($data)
{
/** @var \FireflyIII\Database\Transaction\Transaction $repository */
$repository = \App::make('FireflyIII\Database\Transaction\Transaction');
$errors = $repository->validate($data);
if ($errors->count() > 0) {
\Log::error('Could not store transaction: ' . $errors->toJson());
throw new FireflyException('store() transaction failed, but it should not!');
}
return $repository->store($data);
}
/**
* @param array $data
* @param \TransactionJournal $journal
*/
public function storeBudget($data, \TransactionJournal $journal)
{
if (isset($data['budget_id']) && intval($data['budget_id']) > 0) {
/** @var \FireflyIII\Database\Budget\Budget $budgetRepository */
$budgetRepository = \App::make('FireflyIII\Database\Budget\Budget');
$budget = $budgetRepository->find(intval($data['budget_id']));
if ($budget) {
$journal->budgets()->save($budget);
}
}
}
/**
* @param array $data
* @param \TransactionJournal $journal
*/
public function storeCategory(array $data, \TransactionJournal $journal)
{
if (isset($data['category']) && strlen($data['category']) > 0) {
/** @var \FireflyIII\Database\Category\Category $categoryRepository */
$categoryRepository = \App::make('FireflyIII\Database\Category\Category');
$category = $categoryRepository->firstOrCreate($data['category']);
if ($category) {
$journal->categories()->save($category);
}
}
}
/**
* Returns an object with id $id.
*

View File

@ -71,10 +71,6 @@ class Piggybank
$event->piggybank()->associate($piggyBank);
$event->amount = floatval($relevantTransaction->amount * -1);
$event->date = new Carbon;
if (!$event->isValid()) {
var_dump($event->getErrors());
exit();
}
$event->save();
}
}
@ -200,7 +196,7 @@ class Piggybank
$events->listen('piggybank.update', 'FireflyIII\Event\Piggybank@updatePiggybank');
\App::before(
function ($request) {
function () {
$this->validateRepeatedExpenses();
}
);
@ -247,6 +243,7 @@ class Piggybank
$currentTarget = clone $target;
$currentStart = null;
while ($currentTarget < $today) {
/** @noinspection PhpInternalEntityUsedInspection */
$currentStart = \DateKit::subtractPeriod($currentTarget, $entry->rep_length, 0);
$currentTarget = \DateKit::addPeriod($currentTarget, $entry->rep_length, 0);
// create if not exists:
@ -287,6 +284,7 @@ class Piggybank
if ($journal->piggybankevents()->count() > 0) {
/** @noinspection PhpUnusedLocalVariableInspection */
$event = $journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->first();
$eventSum = floatval($journal->piggybankevents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->sum('amount'));

View File

@ -45,42 +45,49 @@ class FF3ServiceProvider extends ServiceProvider
{
// FORMAT:
#$this->app->bind('Interface', 'Class');
$this->registerFacades();
$this->registerInterfaces();
$this->registerAliases();
}
public function registerFacades()
{
$this->app->bind(
'reminders', function () {
return new Reminders;
}
return new Reminders;
}
);
$this->app->bind(
'filter', function () {
return new Filter;
}
return new Filter;
}
);
$this->app->bind(
'datekit', function () {
return new Date;
}
return new Date;
}
);
$this->app->bind(
'navigation', function () {
return new Navigation;
}
return new Navigation;
}
);
$this->app->bind(
'ffform', function () {
return new Form;
}
return new Form;
}
);
/*
* For models, various stuff:
*/
$this->app->bind(
'steam', function () {
return new Steam;
}
return new Steam;
}
);
}
public function registerInterfaces()
{
// preferences:
$this->app->bind('FireflyIII\Shared\Preferences\PreferencesInterface', 'FireflyIII\Shared\Preferences\Preferences');
@ -89,8 +96,10 @@ class FF3ServiceProvider extends ServiceProvider
// reports
$this->app->bind('FireflyIII\Report\ReportInterface', 'FireflyIII\Report\Report');
}
public function registerAliases()
{
// Shortcut so developers don't need to add an Alias in app/config/app.php
$this->app->booting(
function () {
@ -103,7 +112,6 @@ class FF3ServiceProvider extends ServiceProvider
$loader->alias('Steam', 'FireflyIII\Shared\Facade\Steam');
}
);
}
}

View File

@ -202,167 +202,4 @@ class Report implements ReportInterface
return $report;
}
/**
* @param \Account $account
* @param Carbon $month
*
* @return float
*/
public function getExpenseByMonth(\Account $account, Carbon $month)
{
if (isset($account->sharedExpense) && $account->sharedExpense === true) {
$shared = true;
} else {
if (isset($account->sharedExpense) && $account->sharedExpense === false) {
$shared = false;
} else {
$shared = ($account->getMeta('accountRole') == 'sharedExpense');
}
}
$start = clone $month;
$end = clone $month;
$start->startOfMonth();
$end->endOfMonth();
$sum = 0;
// get all journals.
$journals = \TransactionJournal::with(['transactionType', 'transactions'])->whereIn(
'id', function ($query) use ($account, $start, $end) {
$query->select('transaction_journal_id')
->from('transactions')
->where('account_id', $account->id);
}
)->before($end)->after($start)->get();
if ($shared) {
$expenses = $journals->filter(
function (\TransactionJournal $journal) use ($account) {
// any withdrawal is an expense:
if ($journal->transactionType->type == 'Withdrawal') {
return $journal;
}
// any transfer away from this account is an expense.
if ($journal->transactionType->type == 'Transfer') {
/** @var \Transaction $t */
foreach ($journal->transactions as $t) {
if ($t->account_id == $account->id && floatval($t->amount) < 0) {
return $journal;
}
}
}
return null;
}
);
} else {
$expenses = $journals->filter(
function (\TransactionJournal $journal) use ($account) {
// only withdrawals are expenses:
if ($journal->transactionType->type == 'Withdrawal') {
return $journal;
}
// transfers TO a shared account are also expenses.
if ($journal->transactionType->type == 'Transfer') {
/** @var \Transaction $t */
foreach ($journal->transactions() as $t) {
if ($t->account->getMeta('accountRole') == 'sharedExpense') {
echo '#' . $journal->id . ' is a shared expense!<br>';
return $journal;
}
}
}
return null;
}
);
}
/** @var \TransactionJournal $expense */
foreach ($expenses as $expense) {
$sum += $expense->getAmount();
}
return $sum;
}
/**
* @param \Account $account
* @param Carbon $month
*
* @return float
*/
public function getIncomeByMonth(\Account $account, Carbon $month)
{
if (isset($account->sharedExpense) && $account->sharedExpense === true) {
$shared = true;
} else {
if (isset($account->sharedExpense) && $account->sharedExpense === false) {
$shared = false;
} else {
$shared = ($account->getMeta('accountRole') == 'sharedExpense');
}
}
$start = clone $month;
$end = clone $month;
$start->startOfMonth();
$end->endOfMonth();
$sum = 0;
// get all journals.
$journals = \TransactionJournal::with(['transactionType', 'transactions'])->whereIn(
'id', function ($query) use ($account, $start, $end) {
$query->select('transaction_journal_id')
->from('transactions')
->where('account_id', $account->id);
}
)->before($end)->after($start)->get();
if ($shared) {
$incomes = $journals->filter(
function (\TransactionJournal $journal) use ($account) {
// any deposit is an income:
if ($journal->transactionType->type == 'Deposit') {
return $journal;
}
// any transfer TO this account is an income.
if ($journal->transactionType->type == 'Transfer') {
/** @var \Transaction $t */
foreach ($journal->transactions as $t) {
if ($t->account_id == $account->id && floatval($t->amount) > 0) {
return $journal;
}
}
}
return null;
}
);
} else {
$incomes = $journals->filter(
function (\TransactionJournal $journal) use ($account) {
// only deposits are incomes:
if ($journal->transactionType->type == 'Deposit') {
return $journal;
}
return null;
}
);
}
/** @var \TransactionJournal $expense */
foreach ($incomes as $income) {
$sum += $income->getAmount();
}
return $sum;
}
}

View File

@ -17,19 +17,14 @@ class Preferences implements PreferencesInterface
public function get($name, $default = null)
{
$pref = \Preference::where('user_id', \Auth::user()->id)->where('name', $name)->first();
if (is_null($default) && is_null($pref)) {
if (is_null($pref) && is_null($default)) {
// return NULL
return null;
}
if (!is_null($pref)) {
return $pref;
}
if (!is_null($default) && is_null($pref)) {
// create preference, return that:
return $this->set($name, $default);
}
return null;
return $this->set($name, $default);
}

View File

@ -9,6 +9,7 @@ use FireflyIII\Exception\FireflyException;
* Class Date
*
* @package FireflyIII\Shared\Toolkit
* @SuppressWarnings("ExcessiveClassComplexity")
*/
class Date
{
@ -16,6 +17,7 @@ class Date
* @param Carbon $theDate
* @param $repeatFreq
* @param $skip
* @SuppressWarnings("Cyclomatic")
*
* @return Carbon
* @throws FireflyException
@ -24,6 +26,7 @@ class Date
{
$date = clone $theDate;
$add = ($skip + 1);
switch ($repeatFreq) {
default:
throw new FireflyException('Cannot do addPeriod for $repeat_freq ' . $repeatFreq);
@ -60,6 +63,7 @@ class Date
/**
* @param Carbon $theCurrentEnd
* @param $repeatFreq
* @SuppressWarnings("Cyclomatic")
*
* @return mixed
* @throws FireflyException
@ -101,11 +105,14 @@ class Date
/**
* @param Carbon $theCurrentEnd
* @param $repeatFreq
* @param Carbon $maxDate
* @SuppressWarnings("Cyclomatic")
* @SuppressWarnings("MethodLength")
*
* @return mixed
* @throws FireflyException
*/
public function endOfX(Carbon $theCurrentEnd, $repeatFreq)
public function endOfX(Carbon $theCurrentEnd, $repeatFreq, Carbon $maxDate)
{
$currentEnd = clone $theCurrentEnd;
switch ($repeatFreq) {
@ -139,6 +146,9 @@ class Date
$currentEnd->endOfYear();
break;
}
if ($currentEnd > $maxDate) {
return clone $maxDate;
}
return $currentEnd;
}
@ -146,6 +156,7 @@ class Date
/**
* @param Carbon $date
* @param $repeatFrequency
* @SuppressWarnings("Cyclomatic")
*
* @return string
* @throws FireflyException
@ -180,6 +191,7 @@ class Date
/**
* @param Carbon $theDate
* @param $repeatFreq
* @SuppressWarnings("Cyclomatic")
*
* @return Carbon
* @throws FireflyException
@ -226,10 +238,10 @@ class Date
* @param Carbon $theDate
* @param $repeatFreq
* @param int $subtract
* @SuppressWarnings("Cyclomatic")
*
* @return Carbon
* @throws FireflyException
* @internal param Carbon $date
*/
public function subtractPeriod(Carbon $theDate, $repeatFreq, $subtract = 1)
{

View File

@ -17,41 +17,14 @@ class Filter
*/
public function setSessionDateRange()
{
/*
* Get the current range.
*/
$range = $this->setSessionRangeValue();
$start = \Session::has('start') ? \Session::get('start') : new Carbon;
/*
* Force start date to at the start of the $range.
* Ie. the start of the week, month, year. This also to protect against nefarious users
* who change their session data (I just wanted to use the word "nefarious").
*/
$start = $this->updateStartDate($range, $start);
/*
* Force end date to at the END of the $range. Always based on $start.
* Ie. the END of the week, month, year.
*/
$end = $this->updateEndDate($range, $start);
#\Log::debug('After update, session end is : ' . $end->format('Y-m-d'));
/*
* get the name of the month, depending on the range. Purely for astetics
*/
$range = $this->setSessionRangeValue();
$start = \Session::has('start') ? \Session::get('start') : new Carbon;
$start = $this->updateStartDate($range, $start);
$end = $this->updateEndDate($range, $start);
$period = $this->periodName($range, $start);
$prev = $this->previous($range, clone $start);
$next = $this->next($range, clone $start);
/*
* Get the date for the previous and next period.
* Ie. next week, next month, etc.
*/
$prev = $this->previous($range, clone $start);
$next = $this->next($range, clone $start);
/*
* Save everything in the session:
*/
\Session::put('start', $start);
\Session::put('end', $end);
\Session::put('range', $range);
@ -90,6 +63,7 @@ class Filter
/**
* @param $range
* @param Carbon $start
* @SuppressWarnings("Cyclomatic")
*
* @return Carbon
* @throws FireflyException
@ -215,6 +189,7 @@ class Filter
/**
* @param $range
* @param Carbon $date
* @SuppressWarnings("CyclomaticComplexity")
*
* @return Carbon
* @throws FireflyException

View File

@ -16,37 +16,33 @@ class Form
*
* @param Collection $set
* @param null $titleField
* @param bool $addEmpty
* @SuppressWarnings("CyclomaticComplexity")
*
* @return mixed
*/
public function makeSelectList(Collection $set, $titleField = null)
public function makeSelectList(Collection $set, $titleField = null, $addEmpty = false)
{
$selectList = [];
/** @var Model $entry */
if ($addEmpty) {
$selectList[0] = '(none)';
}
$fields = ['title', 'name', 'description'];
/** @var \Eloquent $entry */
foreach ($set as $entry) {
/** @noinspection PhpUndefinedFieldInspection */
$id = intval($entry->id);
$title = null;
if (is_null($titleField)) {
// try 'title' field.
if (isset($entry->title)) {
$title = $entry->title;
}
// try 'name' field
if (is_null($title)) {
$title = $entry->name;
}
$title = $titleField;
// try 'description' field
if (is_null($title)) {
$title = $entry->description;
foreach ($fields as $field) {
if (is_null($title) && isset($entry->$field)) {
$title = $entry->$field;
}
} else {
$title = $entry->$titleField;
}
$selectList[$id] = $title;
}
return $selectList;
}
}
}

View File

@ -64,57 +64,41 @@ class Reminders
public function updateReminders()
{
/*
* Reminder capable objects are (so far) only piggy banks.
*/
/** @var \FireflyIII\Database\PiggyBank\PiggyBank $repository */
$repository = \App::make('FireflyIII\Database\PiggyBank\PiggyBank');
/** @var \FireflyIII\Database\PiggyBank\RepeatedExpense $repeatedRepository */
$repeatedRepository = \App::make('FireflyIII\Database\PiggyBank\RepeatedExpense');
/** @var Collection $piggybanks */
$piggybanks = $repository->get()->merge($repeatedRepository->get());
/** @var Collection $set */
$set = \Piggybank::leftJoin('accounts', 'accounts.id', '=', 'piggybanks.account_id')
->where('accounts.user_id', \Auth::user()->id)
->whereNotNull('reminder')->get(['piggybanks.*']);
$set = $piggybanks->filter(
function (\Piggybank $piggybank) {
if (!is_null($piggybank->reminder)) {
return $piggybank;
}
return null;
}
);
$today = Carbon::now();
//$today = new Carbon('14-12-2014');
/** @var \Piggybank $piggybank */
foreach ($set as $piggybank) {
foreach ($set as $piggyBank) {
/*
* Try to find a reminder that is valid in the current [period]
* aka between [start of period] and [end of period] as denoted
* by the piggy's repeat_freq.
*/
/** @var \PiggybankRepetition $repetition */
$repetition = $piggybank->currentRelevantRep();
$start = \DateKit::startOfPeriod($today, $piggybank->reminder);
$repetition = $piggyBank->currentRelevantRep();
$start = \DateKit::startOfPeriod($today, $piggyBank->reminder);
if ($repetition->targetdate && $repetition->targetdate <= $today) {
// break when no longer relevant:
continue;
}
$end = \DateKit::endOfPeriod(clone $start, $piggybank->reminder);
$end = \DateKit::endOfPeriod(clone $start, $piggyBank->reminder);
// should have a reminder for this period:
/** @var Collection $reminders */
$reminders = $piggybank->reminders()->dateIs($start, $end)->get();
$reminders = $piggyBank->reminders()->dateIs($start, $end)->get();
if ($reminders->count() == 0) {
// create new!
$reminder = new \Reminder;
$reminder->startdate = $start;
$reminder->enddate = $end;
$reminder->active = 1;
$reminder->user()->associate($repository->getUser());
$reminder->remindersable_id= $piggybank->id;
$reminder->user()->associate(\Auth::getUser());
$reminder->remindersable_id = $piggyBank->id;
$reminder->remindersable_type = 'Piggybank';
$reminder->save();
}

View File

@ -58,4 +58,13 @@ class Steam
}
}
public function removeEmptyBudgetLimits()
{
$user = \Auth::user();
if ($user) {
\BudgetLimit::leftJoin('components', 'components.id', '=', 'budget_limits.component_id')->where('components.user_id', $user->id)
->where('budget_limits.amount', 0)->delete();
}
}
}

View File

@ -5,7 +5,9 @@
*/
class Budget extends Component
{
// @codingStandardsIgnoreStart
protected $isSubclass = true;
// @codingStandardsIgnoreEnd
/**
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough

View File

@ -18,6 +18,9 @@ class TransactionJournal extends Eloquent
'description' => 'required|between:1,255',
'date' => 'required|date',
'completed' => 'required|between:0,1'];
protected $fillable
= ['transaction_type_id', 'transaction_currency_id', 'user_id',
'description', 'date', 'completed'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany

View File

@ -127,4 +127,5 @@ App::down(
|
*/
/** @noinspection PhpIncludeInspection */
require app_path() . '/filters.php';

View File

@ -13,7 +13,9 @@ class TestCase extends Illuminate\Foundation\Testing\TestCase
*/
public function createApplication()
{
/** @noinspection PhpUnusedLocalVariableInspection */
$unitTesting = true;
/** @noinspection PhpUnusedLocalVariableInspection */
$testEnvironment = 'testing';
return require __DIR__ . '/../../bootstrap/start.php';

View File

@ -1,119 +0,0 @@
@extends('layouts.default')
@section('content')
{{ Breadcrumbs::renderIfExists(Route::getCurrentRoute()->getName(), $start) }}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<h3>Budgets</h3>
</div>
</div>
<div class="row">
@foreach($budgets as $budget)
<div class="col-lg-3 col-md-4 col-sm-6">
<div class="panel panel-default">
<div class="panel-heading">
{{{$budget->name}}}
</div>
<div class="panel-body">
@foreach($budget->repInfo as $repetition)
<p class="text-center">{{{$repetition['date']}}}</p>
<div class="progress progress-striped">
@if($repetition['overspent'])
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="{{$repetition['pct']}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$repetition['pct']}}%;min-width:15px;">
{{$repetition['pct_display']}}%
</div>
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="{{100-$repetition['pct']}}" aria-valuemin="0" aria-valuemax="100" style="width: {{100-$repetition['pct']}}%;">
</div>
@else
<div class="progress-bar" role="progressbar" aria-valuenow="{{$repetition['pct']}}" aria-valuemin="0" aria-valuemax="100" style="width: {{$repetition['pct']}}%;min-width:15px;">
{{$repetition['pct_display']}}%
</div>
@endif
</div>
<table class="table">
<tr>
<td style="width:50%">Budgeted</td>
<td>{{mf($repetition['budgeted'])}}</td>
</tr>
<tr>
<td>Spent</td>
<td>{{mf($repetition['spent'])}}</td>
</tr>
<tr>
<td>Left</td>
<td>{{mf($repetition['left'])}}</td>
</tr>
</table>
@endforeach
<!--
Progressbar, Spent, budgeted, left
</div>
-->
</div>
</div>
</div>
@endforeach
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<h3>Accounts</h3>
</div>
</div>
<div class="row">
@foreach($accounts as $account)
<div class="col-lg-4 col-md-6 col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">
{{{$account->name}}}
</div>
<div class="panel-body">
List of budgets with: expenses, left in budget
Balance at start of month.
Balance at end of month + left in all (relevant budgets)
</div>
<table class="table">
<?php $sum = 0;$sumBudgets = 0;?>
@foreach($account->budgetInfo as $budget)
<?php $sum += $budget['spent'];if($budget['budget_id'] != 0) {$sumBudgets += $budget['spent'];}?>
<tr>
<td>{{$budget['budget_name']}}</td>
<td>{{mf($budget['budgeted'])}}</td>
<td>{{mf($budget['spent'])}}</td>
<td>{{mf($budget['left'])}}</td>
</tr>
@endforeach
@if($sum != 0)
<tr>
<td><em>Sum</em></td>
<td></td>
<td>{{mf($sum)}}</td>
<td></td>
</tr>
@endif
@if($sum != 0)
<tr>
<td><em>Sum (budgets only)</em></td>
<td></td>
<td>{{mf($sumBudgets)}}</td>
<td></td>
</tr>
@endif
<tr>
<td>Balance</td>
<td></td>
<td>{{mf(Steam::balance($account, $end))}}</td>
<td></td>
</tr>
</table>
</div>
</div>
@endforeach
</div>
@stop
@section('scripts')
@stop

View File

@ -24,7 +24,7 @@
<div class="panel-body">
<ul>
@foreach($months as $month)
<li><a href="{{route('reports.budgets',[$month['year'],$month['month']])}}">{{$month['formatted']}}</a></li>
<li><a href="#{{$month['year']}}-{{$month['month']}}">{{$month['formatted']}}</a></li>
@endforeach
</ul>
</div>

View File

@ -28,6 +28,7 @@ require __DIR__ . '/../vendor/autoload.php';
*/
if (file_exists($compiled = __DIR__ . '/compiled.php')) {
/** @noinspection PhpIncludeInspection */
require $compiled;
}

View File

@ -2,25 +2,25 @@
if (!function_exists('mf')) {
/**
* @param $n
* @param $amount
* @param bool $coloured
*
* @return string
*/
function mf($n, $coloured = true)
function mf($amount, $coloured = true)
{
$n = floatval($n);
$n = round($n, 2);
$string = number_format($n, 2, ',', '.');
$amount = floatval($amount);
$amount = round($amount, 2);
$string = number_format($amount, 2, ',', '.');
if ($coloured === true && $n === 0.0) {
if ($coloured === true && $amount === 0.0) {
return '<span style="color:#999">&#8364; ' . $string . '</span>';
}
if ($coloured === true && $n > 0) {
if ($coloured === true && $amount > 0) {
return '<span class="text-success">&#8364; ' . $string . '</span>';
}
if ($coloured === true && $n < 0) {
if ($coloured === true && $amount < 0) {
return '<span class="text-danger">&#8364; ' . $string . '</span>';
}
@ -74,6 +74,7 @@ $app->bindInstallPaths(require __DIR__ . '/paths.php');
$framework = $app['path.base'] . '/vendor/laravel/framework/src';
/** @noinspection PhpIncludeInspection */
require $framework . '/Illuminate/Foundation/start.php';