mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Code cleanup.
This commit is contained in:
parent
8e6ca0dd05
commit
900dea2c66
@ -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...');
|
||||
|
@ -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();
|
||||
|
@ -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]);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -27,6 +27,7 @@ class ProfileController extends BaseController
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\View\View
|
||||
* @SuppressWarnings("CyclomaticComplexity")
|
||||
*/
|
||||
public function postChangePassword()
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -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'));
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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`'));
|
||||
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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'));
|
||||
|
||||
|
@ -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');
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,7 +5,9 @@
|
||||
*/
|
||||
class Budget extends Component
|
||||
{
|
||||
// @codingStandardsIgnoreStart
|
||||
protected $isSubclass = true;
|
||||
// @codingStandardsIgnoreEnd
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
|
||||
|
@ -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
|
||||
|
@ -127,4 +127,5 @@ App::down(
|
||||
|
|
||||
*/
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require app_path() . '/filters.php';
|
||||
|
@ -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';
|
||||
|
@ -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
|
@ -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>
|
||||
|
@ -28,6 +28,7 @@ require __DIR__ . '/../vendor/autoload.php';
|
||||
*/
|
||||
|
||||
if (file_exists($compiled = __DIR__ . '/compiled.php')) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require $compiled;
|
||||
}
|
||||
|
||||
|
@ -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">€ ' . $string . '</span>';
|
||||
}
|
||||
if ($coloured === true && $n > 0) {
|
||||
if ($coloured === true && $amount > 0) {
|
||||
return '<span class="text-success">€ ' . $string . '</span>';
|
||||
}
|
||||
if ($coloured === true && $n < 0) {
|
||||
if ($coloured === true && $amount < 0) {
|
||||
return '<span class="text-danger">€ ' . $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';
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user