Refactoring.

This commit is contained in:
James Cole
2016-05-13 15:53:39 +02:00
parent 36bc483edb
commit 20e1e50032
31 changed files with 526 additions and 392 deletions

View File

@@ -50,7 +50,7 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
private function searchOrCreate(AccountRepositoryInterface $repository) private function searchOrCreate(AccountRepositoryInterface $repository)
{ {
// find or create new account: // find or create new account:
$set = $repository->getAccounts(['Default account', 'Asset account']); $set = $repository->getAccountsByType(['Default account', 'Asset account']);
/** @var Account $entry */ /** @var Account $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
if ($entry->iban == $this->value) { if ($entry->iban == $this->value) {

View File

@@ -28,7 +28,7 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
return $account; return $account;
} }
$set = $repository->getAccounts(['Default account', 'Asset account']); $set = $repository->getAccountsByType(['Default account', 'Asset account']);
/** @var Account $entry */ /** @var Account $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
if ($entry->name == $this->value) { if ($entry->name == $this->value) {

View File

@@ -42,7 +42,7 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
$value = $this->value ?? ''; $value = $this->value ?? '';
if (strlen($value) > 0) { if (strlen($value) > 0) {
// find or create new account: // find or create new account:
$set = $repository->getAccounts(['Default account', 'Asset account']); $set = $repository->getAccountsByType(['Default account', 'Asset account']);
/** @var Account $entry */ /** @var Account $entry */
foreach ($set as $entry) { foreach ($set as $entry) {
$accountNumber = $entry->getMeta('accountNumber'); $accountNumber = $entry->getMeta('accountNumber');

View File

@@ -41,7 +41,7 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface
{ {
if (strlen($this->value) > 0) { if (strlen($this->value) > 0) {
$set = $repository->getAccounts([]); $set = $repository->getAccountsByType([]);
/** @var Account $account */ /** @var Account $account */
foreach ($set as $account) { foreach ($set as $account) {
if ($account->iban == $this->value) { if ($account->iban == $this->value) {

View File

@@ -6,8 +6,11 @@ use ExpandedForm;
use FireflyIII\Http\Requests\AccountFormRequest; use FireflyIII\Http\Requests\AccountFormRequest;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
use FireflyIII\Support\CacheProperties;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Input; use Input;
use Navigation;
use Preferences; use Preferences;
use Session; use Session;
use Steam; use Steam;
@@ -66,7 +69,7 @@ class AccountController extends Controller
{ {
$typeName = config('firefly.shortNamesByFullName.' . $account->accountType->type); $typeName = config('firefly.shortNamesByFullName.' . $account->accountType->type);
$subTitle = trans('firefly.delete_' . $typeName . '_account', ['name' => $account->name]); $subTitle = trans('firefly.delete_' . $typeName . '_account', ['name' => $account->name]);
$accountList = ExpandedForm::makeSelectListWithEmpty($repository->getAccounts([$account->accountType->type])); $accountList = ExpandedForm::makeSelectListWithEmpty($repository->getAccountsByType([$account->accountType->type]));
unset($accountList[$account->id]); unset($accountList[$account->id]);
// put previous url in session // put previous url in session
@@ -157,7 +160,7 @@ class AccountController extends Controller
$subTitle = trans('firefly.' . $what . '_accounts'); $subTitle = trans('firefly.' . $what . '_accounts');
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what); $subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$types = config('firefly.accountTypesByIdentifier.' . $what); $types = config('firefly.accountTypesByIdentifier.' . $what);
$accounts = $repository->getAccounts($types); $accounts = $repository->getAccountsByType($types);
/** @var Carbon $start */ /** @var Carbon $start */
$start = clone session('start', Carbon::now()->startOfMonth()); $start = clone session('start', Carbon::now()->startOfMonth());
/** @var Carbon $end */ /** @var Carbon $end */
@@ -180,6 +183,32 @@ class AccountController extends Controller
return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts')); return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'accounts'));
} }
/**
* @param ARI $repository
* @param Account $account
* @param string $date
*
* @return View
*/
public function showWithDate(ARI $repository, Account $account, string $date)
{
$carbon = new Carbon($date);
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($carbon, $range);
$end = Navigation::endOfPeriod($carbon, $range);
$subTitle = $account->name;
$page = intval(Input::get('page'));
$pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$journals->setPath('categories/show/' . $account->id . '/' . $date);
return view('accounts.show_with_date', compact('category', 'journals', 'subTitle', 'carbon'));
}
/** /**
* @param ARI $repository * @param ARI $repository
* @param Account $account * @param Account $account
@@ -188,16 +217,59 @@ class AccountController extends Controller
*/ */
public function show(ARI $repository, Account $account) public function show(ARI $repository, Account $account)
{ {
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page')); // show journals from current period only:
$pageSize = Preferences::get('transactionPageSize', 50)->data; $range = Preferences::get('viewRange', '1M')->data;
$subTitleIcon = config('firefly.subTitlesByIdentifier.' . $account->accountType->type); $start = session('start', Navigation::startOfPeriod(new Carbon, $range));
$what = config('firefly.shortNamesByFullName.' . $account->accountType->type); $end = session('end', Navigation::endOfPeriod(new Carbon, $range));
$journals = $repository->getJournals($account, $page, $pageSize); $page = intval(Input::get('page'));
$subTitle = trans('firefly.details_for_' . $what, ['name' => $account->name]); $pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$journals->setPath('accounts/show/' . $account->id); $journals->setPath('accounts/show/' . $account->id);
// grouped other months thing:
// oldest transaction in account:
$start = $repository->firstUseDate($account);
if ($start->year == 1900) {
$start = new Carbon;
}
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range);
$end = Navigation::endOfX(new Carbon, $range);
$entries = new Collection;
return view('accounts.show', compact('account', 'what', 'subTitleIcon', 'journals', 'subTitle')); // chart properties for cache:
$cache = new CacheProperties;
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('account-show');
$cache->addProperty($account->id);
if ($cache->has()) {
//$entries = $cache->get();
//return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
}
$accountCollection = new Collection([$account]);
while ($end >= $start) {
$end = Navigation::startOfPeriod($end, $range);
$currentEnd = Navigation::endOfPeriod($end, $range);
$spent = $repository->spentInPeriod($accountCollection, $end, $currentEnd);
$earned = $repository->earnedInPeriod($accountCollection, $end, $currentEnd);
$dateStr = $end->format('Y-m-d');
$dateName = Navigation::periodShow($end, $range);
$entries->push([$dateStr, $dateName, $spent, $earned]);
$end = Navigation::subtractPeriod($end, $range, 1);
}
$cache->store($entries);
return view('accounts.show', compact('account', 'what', 'entries', 'subTitleIcon', 'journals', 'subTitle'));
} }
/** /**

View File

@@ -174,7 +174,7 @@ class BudgetController extends Controller
$period = Navigation::periodShow($start, $range); $period = Navigation::periodShow($start, $range);
$periodStart = $start->formatLocalized($this->monthAndDayFormat); $periodStart = $start->formatLocalized($this->monthAndDayFormat);
$periodEnd = $end->formatLocalized($this->monthAndDayFormat); $periodEnd = $end->formatLocalized($this->monthAndDayFormat);
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']); $accounts = $accountRepository->getAccountsByType(['Default account', 'Asset account', 'Cash account']);
$startAsString = $start->format('Y-m-d'); $startAsString = $start->format('Y-m-d');
$endAsString = $end->format('Y-m-d'); $endAsString = $end->format('Y-m-d');

View File

@@ -3,7 +3,6 @@
use Auth; use Auth;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Http\Requests\CategoryFormRequest; use FireflyIII\Http\Requests\CategoryFormRequest;
use FireflyIII\Models\Account;
use FireflyIII\Models\Category; use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI; use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
@@ -153,16 +152,25 @@ class CategoryController extends Controller
*/ */
public function show(CRI $repository, Category $category) public function show(CRI $repository, Category $category)
{ {
/** @var Carbon $carbon */
$range = Preferences::get('viewRange', '1M')->data;
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
$hideCategory = true; // used in list. $hideCategory = true; // used in list.
$pageSize = Preferences::get('transactionPageSize', 50)->data;
$page = intval(Input::get('page')); $page = intval(Input::get('page'));
$journals = $repository->getJournals($category, $page, $pageSize); $pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end);
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$journals->setPath('categories/show/' . $category->id); $journals->setPath('categories/show/' . $category->id);
// list of ranges for list of periods:
// oldest transaction in category: // oldest transaction in category:
$start = $repository->firstUseDate($category, new Collection); $start = $repository->firstUseDate($category, new Collection);
if ($start->year == 1900) {
$start = new Carbon;
}
$range = Preferences::get('viewRange', '1M')->data; $range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range); $start = Navigation::startOfPeriod($start, $range);
$end = Navigation::endOfX(new Carbon, $range); $end = Navigation::endOfX(new Carbon, $range);
@@ -177,8 +185,9 @@ class CategoryController extends Controller
if ($cache->has()) { if ($cache->has()) {
//$entries = $cache->get(); $entries = $cache->get();
//return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
return view('categories.show', compact('category', 'journals', 'entries', 'hideCategory', 'subTitle'));
} }
@@ -223,7 +232,7 @@ class CategoryController extends Controller
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); $set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end);
$count = $set->count(); $count = $set->count();
$subSet = $set->splice($offset, $pageSize); $subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page); $journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$journals->setPath('categories/show/' . $category->id . '/' . $date); $journals->setPath('categories/show/' . $category->id . '/' . $date);
return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon')); return view('categories.show_with_date', compact('category', 'journals', 'hideCategory', 'subTitle', 'carbon'));

View File

@@ -8,10 +8,7 @@ use FireflyIII\Generator\Chart\Account\AccountChartGeneratorInterface;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Preferences;
use Response;
/** checked /** checked
* Class AccountController * Class AccountController
@@ -34,39 +31,6 @@ class AccountController extends Controller
$this->generator = app(AccountChartGeneratorInterface::class); $this->generator = app(AccountChartGeneratorInterface::class);
} }
/**
* Shows the balances for a given set of dates and accounts.
*
* @param $reportType
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return \Illuminate\Http\JsonResponse
*/
public function report(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
{
// chart properties for cache:
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('all');
$cache->addProperty('accounts');
$cache->addProperty('default');
$cache->addProperty($reportType);
$cache->addProperty($accounts);
if ($cache->has()) {
return Response::json($cache->get());
}
// make chart:
$data = $this->generator->frontpage($accounts, $start, $end);
$cache->store($data);
return Response::json($data);
}
/** /**
* Shows the balances for all the user's expense accounts. * Shows the balances for all the user's expense accounts.
* *
@@ -76,6 +40,7 @@ class AccountController extends Controller
*/ */
public function expenseAccounts(ARI $repository) public function expenseAccounts(ARI $repository)
{ {
/*
$start = clone session('start', Carbon::now()->startOfMonth()); $start = clone session('start', Carbon::now()->startOfMonth());
$end = clone session('end', Carbon::now()->endOfMonth()); $end = clone session('end', Carbon::now()->endOfMonth());
$accounts = $repository->getAccounts(['Expense account', 'Beneficiary account']); $accounts = $repository->getAccounts(['Expense account', 'Beneficiary account']);
@@ -94,7 +59,7 @@ class AccountController extends Controller
$cache->store($data); $cache->store($data);
return Response::json($data); return Response::json($data);
*/
} }
/** /**
@@ -106,6 +71,7 @@ class AccountController extends Controller
*/ */
public function frontpage(ARI $repository) public function frontpage(ARI $repository)
{ {
/*
$frontPage = Preferences::get('frontPageAccounts', []); $frontPage = Preferences::get('frontPageAccounts', []);
$start = clone session('start', Carbon::now()->startOfMonth()); $start = clone session('start', Carbon::now()->startOfMonth());
$end = clone session('end', Carbon::now()->endOfMonth()); $end = clone session('end', Carbon::now()->endOfMonth());
@@ -125,7 +91,41 @@ class AccountController extends Controller
$cache->store($data); $cache->store($data);
return Response::json($data); return Response::json($data);
*/
}
/**
* Shows the balances for a given set of dates and accounts.
*
* @param $reportType
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return \Illuminate\Http\JsonResponse
*/
public function report(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
{
/*
// chart properties for cache:
$cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('all');
$cache->addProperty('accounts');
$cache->addProperty('default');
$cache->addProperty($reportType);
$cache->addProperty($accounts);
if ($cache->has()) {
return Response::json($cache->get());
}
// make chart:
$data = $this->generator->frontpage($accounts, $start, $end);
$cache->store($data);
return Response::json($data);
*/
} }
/** /**
@@ -137,7 +137,7 @@ class AccountController extends Controller
*/ */
public function single(Account $account) public function single(Account $account)
{ {
/*
$start = clone session('start', Carbon::now()->startOfMonth()); $start = clone session('start', Carbon::now()->startOfMonth());
$end = clone session('end', Carbon::now()->endOfMonth()); $end = clone session('end', Carbon::now()->endOfMonth());
@@ -157,5 +157,6 @@ class AccountController extends Controller
$cache->store($data); $cache->store($data);
return Response::json($data); return Response::json($data);
*/
} }
} }

View File

@@ -42,26 +42,11 @@ class BillController extends Controller
*/ */
public function frontpage(BillRepositoryInterface $repository) public function frontpage(BillRepositoryInterface $repository)
{ {
$start = session('start', Carbon::now()->startOfMonth()); $start = session('start', Carbon::now()->startOfMonth());
$end = session('end', Carbon::now()->endOfMonth()); $end = session('end', Carbon::now()->endOfMonth());
$paid = $repository->getBillsPaidInRange($start, $end); // will be a negative amount. $paid = $repository->getBillsPaidInRange($start, $end); // will be a negative amount.
$unpaid = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount. $unpaid = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount.
$creditCardDue = $repository->getCreditCardBill($start, $end); $data = $this->generator->frontpage($paid, $unpaid);
if ($creditCardDue < 0) {
// expenses are negative (bill not yet paid),
$creditCardDue = bcmul($creditCardDue, '-1');
$unpaid = bcadd($unpaid, $creditCardDue);
}
// if $creditCardDue more than zero, the bill has been paid: (transfer = positive).
// amount must be negative to be added to $paid:
if ($creditCardDue >= 0) {
$paid = bcadd($paid, $creditCardDue);
}
// build chart:
$data = $this->generator->frontpage($paid, $unpaid);
return Response::json($data); return Response::json($data);
} }

View File

@@ -110,7 +110,7 @@ class BudgetController extends Controller
$cache->addProperty($repetition->id); $cache->addProperty($repetition->id);
if ($cache->has()) { if ($cache->has()) {
// return Response::json($cache->get()); return Response::json($cache->get());
} }
$entries = new Collection; $entries = new Collection;
@@ -150,7 +150,7 @@ class BudgetController extends Controller
$cache->addProperty('budget'); $cache->addProperty('budget');
$cache->addProperty('all'); $cache->addProperty('all');
if ($cache->has()) { if ($cache->has()) {
//return Response::json($cache->get()); return Response::json($cache->get());
} }
$budgets = $repository->getActiveBudgets(); $budgets = $repository->getActiveBudgets();
$repetitions = $repository->getAllBudgetLimitRepetitions($start, $end); $repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
@@ -203,8 +203,6 @@ class BudgetController extends Controller
$data = $this->generator->frontpage($allEntries); $data = $this->generator->frontpage($allEntries);
$cache->store($data); $cache->store($data);
return ' ' . json_encode($data);
return Response::json($data); return Response::json($data);
} }
@@ -230,7 +228,7 @@ class BudgetController extends Controller
$cache->addProperty('multiYearBudget'); $cache->addProperty('multiYearBudget');
if ($cache->has()) { if ($cache->has()) {
//return Response::json($cache->get()); return Response::json($cache->get());
} }
$budgetIds = $budgets->pluck('id')->toArray(); $budgetIds = $budgets->pluck('id')->toArray();
$repetitions = $repository->getAllBudgetLimitRepetitions($start, $end); $repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
@@ -300,7 +298,7 @@ class BudgetController extends Controller
$cache->addProperty('budget'); $cache->addProperty('budget');
$cache->addProperty('period'); $cache->addProperty('period');
if ($cache->has()) { if ($cache->has()) {
//return Response::json($cache->get()); return Response::json($cache->get());
} }
// loop over period, add by users range: // loop over period, add by users range:
$current = clone $start; $current = clone $start;

View File

@@ -64,7 +64,7 @@ class CategoryController extends Controller
$cache->addProperty('all'); $cache->addProperty('all');
$cache->addProperty('categories'); $cache->addProperty('categories');
if ($cache->has()) { if ($cache->has()) {
//return Response::json($cache->get()); return Response::json($cache->get());
} }
while ($start <= $end) { while ($start <= $end) {
@@ -119,7 +119,7 @@ class CategoryController extends Controller
$cache->addProperty('category'); $cache->addProperty('category');
$cache->addProperty('frontpage'); $cache->addProperty('frontpage');
if ($cache->has()) { if ($cache->has()) {
//return Response::json($cache->get()); return Response::json($cache->get());
} }
$categories = $repository->getCategories(); $categories = $repository->getCategories();
$set = new Collection; $set = new Collection;
@@ -169,7 +169,7 @@ class CategoryController extends Controller
$cache->addProperty('multiYearCategory'); $cache->addProperty('multiYearCategory');
if ($cache->has()) { if ($cache->has()) {
//return Response::json($cache->get()); return Response::json($cache->get());
} }
$entries = new Collection; $entries = new Collection;
@@ -237,7 +237,7 @@ class CategoryController extends Controller
$cache->addProperty('category'); $cache->addProperty('category');
$cache->addProperty('period'); $cache->addProperty('period');
if ($cache->has()) { if ($cache->has()) {
// return Response::json($cache->get()); return Response::json($cache->get());
} }
/** @var CRI $repository */ /** @var CRI $repository */

View File

@@ -190,7 +190,7 @@ class CsvController extends Controller
]; ];
// get a list of asset accounts: // get a list of asset accounts:
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Asset account', 'Default account'])); $accounts = ExpandedForm::makeSelectList($repository->getAccountsByType(['Asset account', 'Default account']));
// can actually upload? // can actually upload?
$uploadPossible = is_writable(storage_path('upload')); $uploadPossible = is_writable(storage_path('upload'));

View File

@@ -102,7 +102,7 @@ class ExportController extends Controller
$jobs->cleanup(); $jobs->cleanup();
// does the user have shared accounts? // does the user have shared accounts?
$accounts = $repository->getAccounts(['Default account', 'Asset account']); $accounts = $repository->getAccountsByType(['Default account', 'Asset account']);
$accountList = ExpandedForm::makeSelectList($accounts); $accountList = ExpandedForm::makeSelectList($accounts);
$checked = array_keys($accountList); $checked = array_keys($accountList);
$formats = array_keys(config('firefly.export_formats')); $formats = array_keys(config('firefly.export_formats'));

View File

@@ -7,6 +7,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Tag; use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Support\Collection;
use Input; use Input;
use Preferences; use Preferences;
use Route; use Route;
@@ -116,7 +117,7 @@ class HomeController extends Controller
/** @var Carbon $end */ /** @var Carbon $end */
$end = session('end', Carbon::now()->endOfMonth()); $end = session('end', Carbon::now()->endOfMonth());
$showTour = Preferences::get('tour', true)->data; $showTour = Preferences::get('tour', true)->data;
$accounts = $repository->getFrontpageAccounts($frontPage); $accounts = $repository->getAccountsById($frontPage->data);
$savings = $repository->getSavingsAccounts(); $savings = $repository->getSavingsAccounts();
$piggyBankAccounts = $repository->getPiggyBankAccounts(); $piggyBankAccounts = $repository->getPiggyBankAccounts();
@@ -133,7 +134,8 @@ class HomeController extends Controller
} }
foreach ($accounts as $account) { foreach ($accounts as $account) {
$set = $repository->getFrontpageTransactions($account, $start, $end); $set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
$set = $set->splice(0, 10);
if (count($set) > 0) { if (count($set) > 0) {
$transactions[] = [$set, $account]; $transactions[] = [$set, $account];
@@ -153,10 +155,10 @@ class HomeController extends Controller
{ {
// these routes are not relevant for the help pages: // these routes are not relevant for the help pages:
$ignore = [ $ignore = [
// 'logout', 'register', 'bills.rescan', 'attachments.download', 'attachments.preview', // 'logout', 'register', 'bills.rescan', 'attachments.download', 'attachments.preview',
// 'budgets.income', 'csv.download-config', 'currency.default', 'export.status', 'export.download', // 'budgets.income', 'csv.download-config', 'currency.default', 'export.status', 'export.download',
// 'json.', 'help.', 'piggy-banks.addMoney', 'piggy-banks.removeMoney', 'rules.rule.up', 'rules.rule.down', // 'json.', 'help.', 'piggy-banks.addMoney', 'piggy-banks.removeMoney', 'rules.rule.up', 'rules.rule.down',
// 'rules.rule-group.up', 'rules.rule-group.down', 'debugbar', // 'rules.rule-group.up', 'rules.rule-group.down', 'debugbar',
]; ];
$routes = Route::getRoutes(); $routes = Route::getRoutes();
/** @var \Illuminate\Routing\Route $route */ /** @var \Illuminate\Routing\Route $route */

View File

@@ -60,11 +60,7 @@ class JsonController extends Controller
* Since both this method and the chart use the exact same data, we can suffice * Since both this method and the chart use the exact same data, we can suffice
* with calling the one method in the bill repository that will get this amount. * with calling the one method in the bill repository that will get this amount.
*/ */
$amount = $repository->getBillsPaidInRange($start, $end); // will be a negative amount. $amount = $repository->getBillsPaidInRange($start, $end); // will be a negative amount.
$creditCardDue = $repository->getCreditCardBill($start, $end);
if ($creditCardDue >= 0) {
$amount = bcadd($amount, $creditCardDue);
}
$amount = bcmul($amount, '-1'); $amount = bcmul($amount, '-1');
$data = ['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]; $data = ['box' => 'bills-paid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
@@ -79,18 +75,10 @@ class JsonController extends Controller
*/ */
public function boxBillsUnpaid(BillRepositoryInterface $repository) public function boxBillsUnpaid(BillRepositoryInterface $repository)
{ {
$start = session('start', Carbon::now()->startOfMonth()); $start = session('start', Carbon::now()->startOfMonth());
$end = session('end', Carbon::now()->endOfMonth()); $end = session('end', Carbon::now()->endOfMonth());
$amount = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount. $amount = $repository->getBillsUnpaidInRange($start, $end); // will be a positive amount.
$creditCardDue = $repository->getCreditCardBill($start, $end); $data = ['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
if ($creditCardDue < 0) {
// expenses are negative (bill not yet paid),
$creditCardDue = bcmul($creditCardDue, '-1');
$amount = bcadd($amount, $creditCardDue);
}
$data = ['box' => 'bills-unpaid', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
return Response::json($data); return Response::json($data);
} }
@@ -115,7 +103,7 @@ class JsonController extends Controller
if ($cache->has()) { if ($cache->has()) {
return Response::json($cache->get()); return Response::json($cache->get());
} }
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']); $accounts = $accountRepository->getAccountsByType(['Default account', 'Asset account', 'Cash account']);
$amount = $reportQuery->income($accounts, $start, $end)->sum('journalAmount'); $amount = $reportQuery->income($accounts, $start, $end)->sum('journalAmount');
$data = ['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount]; $data = ['box' => 'in', 'amount' => Amount::format($amount, false), 'amount_raw' => $amount];
@@ -136,7 +124,7 @@ class JsonController extends Controller
$start = session('start', Carbon::now()->startOfMonth()); $start = session('start', Carbon::now()->startOfMonth());
$end = session('end', Carbon::now()->endOfMonth()); $end = session('end', Carbon::now()->endOfMonth());
$accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']); $accounts = $accountRepository->getAccountsByType(['Default account', 'Asset account', 'Cash account']);
// works for json too! // works for json too!
$cache = new CacheProperties; $cache = new CacheProperties;
@@ -192,7 +180,7 @@ class JsonController extends Controller
*/ */
public function expenseAccounts(ARI $accountRepository) public function expenseAccounts(ARI $accountRepository)
{ {
$list = $accountRepository->getAccounts(['Expense account', 'Beneficiary account']); $list = $accountRepository->getAccountsByType(['Expense account', 'Beneficiary account']);
$return = []; $return = [];
foreach ($list as $entry) { foreach ($list as $entry) {
$return[] = $entry->name; $return[] = $entry->name;
@@ -209,7 +197,7 @@ class JsonController extends Controller
*/ */
public function revenueAccounts(ARI $accountRepository) public function revenueAccounts(ARI $accountRepository)
{ {
$list = $accountRepository->getAccounts(['Revenue account']); $list = $accountRepository->getAccountsByType(['Revenue account']);
$return = []; $return = [];
foreach ($list as $entry) { foreach ($list as $entry) {
$return[] = $entry->name; $return[] = $entry->name;

View File

@@ -65,7 +65,7 @@ class PiggyBankController extends Controller
{ {
$periods = config('firefly.piggy_bank_periods'); $periods = config('firefly.piggy_bank_periods');
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); $accounts = ExpandedForm::makeSelectList($repository->getAccountsByType(['Default account', 'Asset account']));
$subTitle = trans('firefly.new_piggy_bank'); $subTitle = trans('firefly.new_piggy_bank');
$subTitleIcon = 'fa-plus'; $subTitleIcon = 'fa-plus';
@@ -124,7 +124,7 @@ class PiggyBankController extends Controller
{ {
$periods = config('firefly.piggy_bank_periods'); $periods = config('firefly.piggy_bank_periods');
$accounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); $accounts = ExpandedForm::makeSelectList($repository->getAccountsByType(['Default account', 'Asset account']));
$subTitle = trans('firefly.update_piggy_title', ['name' => $piggyBank->name]); $subTitle = trans('firefly.update_piggy_title', ['name' => $piggyBank->name]);
$subTitleIcon = 'fa-pencil'; $subTitleIcon = 'fa-pencil';
$targetDate = null; $targetDate = null;

View File

@@ -16,6 +16,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collection\BalanceLine; use FireflyIII\Helpers\Collection\BalanceLine;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
@@ -182,7 +183,8 @@ class ReportController extends Controller
/** @var AccountRepositoryInterface $repository */ /** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class); $repository = app(AccountRepositoryInterface::class);
$account = $repository->find(intval($attributes['accountId'])); $account = $repository->find(intval($attributes['accountId']));
$journals = $repository->getExpensesByDestination($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']); $types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
$journals = $repository->journalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
$view = view('popup.report.expense-entry', compact('journals', 'account'))->render(); $view = view('popup.report.expense-entry', compact('journals', 'account'))->render();
return $view; return $view;
@@ -201,10 +203,10 @@ class ReportController extends Controller
/** @var AccountRepositoryInterface $repository */ /** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class); $repository = app(AccountRepositoryInterface::class);
$account = $repository->find(intval($attributes['accountId'])); $account = $repository->find(intval($attributes['accountId']));
$journals = $repository->getIncomeByDestination($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']); $types = [TransactionType::DEPOSIT, TransactionType::TRANSFER];
$journals = $repository->journalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
$view = view('popup.report.income-entry', compact('journals', 'account'))->render(); $view = view('popup.report.income-entry', compact('journals', 'account'))->render();
return $view; return $view;
} }

View File

@@ -63,7 +63,7 @@ class PreferencesController extends Controller
*/ */
public function index(ARI $repository) public function index(ARI $repository)
{ {
$accounts = $repository->getAccounts(['Default account', 'Asset account']); $accounts = $repository->getAccountsByType(['Default account', 'Asset account']);
$viewRangePref = Preferences::get('viewRange', '1M'); $viewRangePref = Preferences::get('viewRange', '1M');
$viewRange = $viewRangePref->data; $viewRange = $viewRangePref->data;
$frontPageAccounts = Preferences::get('frontPageAccounts', []); $frontPageAccounts = Preferences::get('frontPageAccounts', []);

View File

@@ -69,7 +69,7 @@ class ReportController extends Controller
$customFiscalYear = Preferences::get('customFiscalYear', 0)->data; $customFiscalYear = Preferences::get('customFiscalYear', 0)->data;
// does the user have shared accounts? // does the user have shared accounts?
$accounts = $repository->getAccounts(['Default account', 'Asset account']); $accounts = $repository->getAccountsByType(['Default account', 'Asset account']);
// get id's for quick links: // get id's for quick links:
$accountIds = []; $accountIds = [];
/** @var Account $account */ /** @var Account $account */

View File

@@ -178,7 +178,7 @@ class RuleGroupController extends Controller
public function selectTransactions(AccountRepositoryInterface $repository, RuleGroup $ruleGroup) public function selectTransactions(AccountRepositoryInterface $repository, RuleGroup $ruleGroup)
{ {
// does the user have shared accounts? // does the user have shared accounts?
$accounts = $repository->getAccounts(['Default account', 'Asset account']); $accounts = $repository->getAccountsByType(['Default account', 'Asset account']);
$accountList = ExpandedForm::makeSelectList($accounts); $accountList = ExpandedForm::makeSelectList($accounts);
$checkedAccounts = array_keys($accountList); $checkedAccounts = array_keys($accountList);
$first = session('first')->format('Y-m-d'); $first = session('first')->format('Y-m-d');

View File

@@ -71,7 +71,7 @@ class SplitController extends Controller
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size'))); $uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
$currencies = ExpandedForm::makeSelectList($currencyRepository->get()); $currencies = ExpandedForm::makeSelectList($currencyRepository->get());
$assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccounts(['Default account', 'Asset account'])); $assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccountsByType(['Default account', 'Asset account']));
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets()); $budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$preFilled = $this->arrayFromJournal($request, $journal); $preFilled = $this->arrayFromJournal($request, $journal);
@@ -116,7 +116,7 @@ class SplitController extends Controller
$budgetRepository = app(BudgetRepositoryInterface::class); $budgetRepository = app(BudgetRepositoryInterface::class);
$currencies = ExpandedForm::makeSelectList($currencyRepository->get()); $currencies = ExpandedForm::makeSelectList($currencyRepository->get());
$assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccounts(['Default account', 'Asset account'])); $assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccountsByType(['Default account', 'Asset account']));
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets()); $budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
return view('split.journals.from-store', compact('currencies', 'assetAccounts', 'budgets', 'preFilled')); return view('split.journals.from-store', compact('currencies', 'assetAccounts', 'budgets', 'preFilled'));

View File

@@ -72,7 +72,7 @@ class TransactionController extends Controller
$what = strtolower($what); $what = strtolower($what);
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size'))); $uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
$assetAccounts = ExpandedForm::makeSelectList($repository->getAccounts(['Default account', 'Asset account'])); $assetAccounts = ExpandedForm::makeSelectList($repository->getAccountsByType(['Default account', 'Asset account']));
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets()); $budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBanks = $piggyRepository->getPiggyBanks(); $piggyBanks = $piggyRepository->getPiggyBanks();
/** @var PiggyBank $piggy */ /** @var PiggyBank $piggy */
@@ -159,7 +159,7 @@ class TransactionController extends Controller
/** @var PiggyBankRepositoryInterface $piggyRepository */ /** @var PiggyBankRepositoryInterface $piggyRepository */
$piggyRepository = app(PiggyBankRepositoryInterface::class); $piggyRepository = app(PiggyBankRepositoryInterface::class);
$assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccounts(['Default account', 'Asset account'])); $assetAccounts = ExpandedForm::makeSelectList($accountRepository->getAccountsByType(['Default account', 'Asset account']));
$budgetList = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets()); $budgetList = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBankList = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanks()); $piggyBankList = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanks());
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize')); $maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
@@ -296,7 +296,7 @@ class TransactionController extends Controller
$subTitle = trans('firefly.mass_edit_journals'); $subTitle = trans('firefly.mass_edit_journals');
/** @var ARI $accountRepository */ /** @var ARI $accountRepository */
$accountRepository = app(ARI::class); $accountRepository = app(ARI::class);
$accountList = ExpandedForm::makeSelectList($accountRepository->getAccounts(['Default account', 'Asset account'])); $accountList = ExpandedForm::makeSelectList($accountRepository->getAccountsByType(['Default account', 'Asset account']));
// put previous url in session // put previous url in session
Session::put('transactions.mass-edit.url', URL::previous()); Session::put('transactions.mass-edit.url', URL::previous());

View File

@@ -83,7 +83,9 @@ Route::group(
Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense'); Route::get('/accounts/create/{what}', ['uses' => 'AccountController@create', 'as' => 'accounts.create'])->where('what', 'revenue|asset|expense');
Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']); Route::get('/accounts/edit/{account}', ['uses' => 'AccountController@edit', 'as' => 'accounts.edit']);
Route::get('/accounts/delete/{account}', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']); Route::get('/accounts/delete/{account}', ['uses' => 'AccountController@delete', 'as' => 'accounts.delete']);
Route::get('/accounts/show/{account}/{view?}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']); Route::get('/accounts/show/{account}', ['uses' => 'AccountController@show', 'as' => 'accounts.show']);
Route::get('/accounts/show/{account}/{date}', ['uses' => 'AccountController@showWithDate', 'as' => 'accounts.show.date']);
Route::post('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']); Route::post('/accounts/store', ['uses' => 'AccountController@store', 'as' => 'accounts.store']);
Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']); Route::post('/accounts/update/{account}', ['uses' => 'AccountController@update', 'as' => 'accounts.update']);

View File

@@ -21,6 +21,15 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
*/ */
class AccountType extends Model class AccountType extends Model
{ {
const DEFAULT = 'Default account';
const CASH = 'Cash account';
const ASSET = 'Asset account';
const EXPENSE = 'Expense account';
const REVENUE = 'Revenue account';
const INITIAL_BALANCE = 'Initial balance account';
const BENEFICIARY = 'Beneficiary account';
const IMPORT = 'Import account';
protected $dates = ['created_at', 'updated_at']; protected $dates = ['created_at', 'updated_at'];

View File

@@ -8,7 +8,6 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Preference;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
@@ -77,6 +76,23 @@ class AccountRepository implements AccountRepositoryInterface
return true; return true;
} }
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function earnedInPeriod(Collection $accounts, Carbon $start, Carbon $end): string
{
Log::debug('earnedinperiod');
$types = [TransactionType::DEPOSIT, TransactionType::TRANSFER];
$sum = bcmul($this->sumInPeriod($accounts, $types, $start, $end), '-1');
return $sum;
}
/** /**
* @param $accountId * @param $accountId
* *
@@ -92,6 +108,29 @@ class AccountRepository implements AccountRepositoryInterface
return $account; return $account;
} }
/**
* @param Account $account
*
* @return Carbon
*/
public function firstUseDate(Account $account): Carbon
{
$first = new Carbon('1900-01-01');
/** @var Transaction $first */
$date = $account->transactions()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->orderBy('transaction_journals.date', 'ASC')
->orderBy('transaction_journals.order', 'DESC')
->orderBy('transaction_journals.id', 'ASC')
->first(['transaction_journals.date']);
if (!is_null($date)) {
$first = new Carbon($date->date);
}
return $first;
}
/** /**
* Gets all the accounts by ID, for a given set. * Gets all the accounts by ID, for a given set.
* *
@@ -105,11 +144,11 @@ class AccountRepository implements AccountRepositoryInterface
} }
/** /**
* @param array $types * @param array $accountIds
* *
* @return Collection * @return Collection
*/ */
public function getAccounts(array $types): Collection public function getAccountsById(array $accountIds): Collection
{ {
/** @var Collection $result */ /** @var Collection $result */
$query = $this->user->accounts()->with( $query = $this->user->accounts()->with(
@@ -117,9 +156,11 @@ class AccountRepository implements AccountRepositoryInterface
$query->where('name', 'accountRole'); $query->where('name', 'accountRole');
}] }]
); );
if (count($types) > 0) {
$query->accountTypeIn($types); if (count($accountIds) > 0) {
$query->whereIn('accounts.id', $accountIds);
} }
$result = $query->get(['accounts.*']); $result = $query->get(['accounts.*']);
$result = $result->sortBy( $result = $result->sortBy(
@@ -132,72 +173,31 @@ class AccountRepository implements AccountRepositoryInterface
} }
/** /**
* This method returns the users credit cards, along with some basic information about the * @param array $types
* balance they have on their CC. To be used in the JSON boxes on the front page that say
* how many bills there are still left to pay. The balance will be saved in field "balance".
*
* To get the balance, the field "date" is necessary.
*
* @param Carbon $date
* *
* @return Collection * @return Collection
*/ */
public function getCreditCards(Carbon $date): Collection public function getAccountsByType(array $types): Collection
{ {
$set = $this->user->accounts() /** @var Collection $result */
->hasMetaValue('accountRole', 'ccAsset') $query = $this->user->accounts()->with(
->hasMetaValue('ccType', 'monthlyFull') ['accountmeta' => function (HasMany $query) {
->leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') $query->where('name', 'accountRole');
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') }]
->whereNull('transactions.deleted_at') );
->where('transaction_journals.date', '<=', $date->format('Y-m-d')) if (count($types) > 0) {
->groupBy('accounts.id') $query->accountTypeIn($types);
->get( }
[
'accounts.*',
'ccType.data as ccType',
'accountRole.data as accountRole',
DB::Raw('SUM(`transactions`.`amount`) AS `balance`'),
]
);
return $set; $result = $query->get(['accounts.*']);
}
/** $result = $result->sortBy(
* Returns a list of transactions TO the $account, not including transfers function (Account $account) {
* and/or expenses in the $accounts list. return strtolower($account->name);
* }
* @param Account $account );
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpensesByDestination(Account $account, Collection $accounts, Carbon $start, Carbon $end): Collection
{
$ids = $accounts->pluck('id')->toArray();
$journals = $this->user->transactionjournals()
->expanded()
->sortCorrectly()
->before($end)
->leftJoin(
'transactions as dest', function (JoinClause $join) {
$join->on('dest.transaction_journal_id', '=', 'transaction_journals.id')->where('dest.amount', '>', 0);
}
)
->leftJoin(
'transactions as source', function (JoinClause $join) {
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', 0);
}
)
->where('dest.account_id', $account->id)
->whereIn('source.account_id', $ids)
->after($start)
->get(TransactionJournal::queryFields());
return $journals; return $result;
} }
/** /**
@@ -216,80 +216,6 @@ class AccountRepository implements AccountRepositoryInterface
return $transaction; return $transaction;
} }
/**
* @param Preference $preference
*
* @return Collection
*/
public function getFrontpageAccounts(Preference $preference): Collection
{
$query = $this->user->accounts()->accountTypeIn(['Default account', 'Asset account']);
if (count($preference->data) > 0) {
$query->whereIn('accounts.id', $preference->data);
}
$result = $query->get(['accounts.*']);
return $result;
}
/**
*
* @param Account $account
* @param Carbon $start
* @param Carbon $end
*
* @return mixed
*/
public function getFrontpageTransactions(Account $account, Carbon $start, Carbon $end): Collection
{
$query = $this->user
->transactionjournals()
->expanded()
->sortCorrectly()
->before($end)
->after($start)
->take(10);
// expand query:
$query->leftJoin(
'transactions as source', function (JoinClause $join) {
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id');
}
)->where('source.account_id', $account->id);
$query->take(10);
$set = $query->get(TransactionJournal::queryFields());
return $set;
}
/**
* Returns a list of transactions TO the given (asset) $account, but none from the
* given list of accounts
*
* @param Account $account
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getIncomeByDestination(Account $account, Collection $accounts, Carbon $start, Carbon $end): Collection
{
$ids = $accounts->pluck('id')->toArray();
$journals = $this->user->transactionjournals()
->expanded()
->sortCorrectly()
->before($end)
->where('source_account.id', $account->id)
->whereIn('destination_account.id', $ids)
->after($start)
->get(TransactionJournal::queryFields());
return $journals;
}
/** /**
* @param Account $account * @param Account $account
* @param int $page * @param int $page
@@ -435,7 +361,38 @@ class AccountRepository implements AccountRepositoryInterface
} }
/** /**
* * @param Collection $accounts
* @param array $types
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function journalsInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): Collection
{
// first collect actual transaction journals (fairly easy)
$query = $this->user->transactionjournals()->expanded()->sortCorrectly();
if ($end >= $start) {
$query->before($end)->after($start);
}
if (count($types) > 0) {
$query->transactionTypes($types);
}
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
$query->whereIn('t.account_id', $accountIds);
}
// that should do it:
$complete = $query->get(TransactionJournal::queryFields());
return $complete;
}
/**
*
* @param Account $account * @param Account $account
* @param Carbon $date * @param Carbon $date
* *
@@ -524,6 +481,22 @@ class AccountRepository implements AccountRepositoryInterface
return $journal; return $journal;
} }
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriod(Collection $accounts, Carbon $start, Carbon $end): string
{
Log::debug('spentinperiod');
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
$sum = $this->sumInPeriod($accounts, $types, $start, $end);
return $sum;
}
/** /**
* @param array $data * @param array $data
* *
@@ -788,4 +761,64 @@ class AccountRepository implements AccountRepositoryInterface
} }
} }
/**
* @param Collection $accounts
* @param array $types
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
private function sumInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): string
{
// first collect incoming transaction journals (where the $accounts receive the money).
$query = $this->user
->transactionjournals()
->distinct()
->transactionTypes($types)
->leftJoin(
'transactions as t', function (JoinClause $join) {
$join->on('t.transaction_journal_id', '=', 'transaction_journals.id')->where('amount', '>', 0);
}
);
if ($end >= $start) {
$query->before($end)->after($start);
}
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$query->whereIn('t.account_id', $accountIds);
}
// that should do it:
$first = strval($query->sum('t.amount'));
// the the other way around:
$query = $this->user
->transactionjournals()
->distinct()
->transactionTypes($types)
->leftJoin(
'transactions as t', function (JoinClause $join) {
$join->on('t.transaction_journal_id', '=', 'transaction_journals.id')->where('amount', '<', 0);
}
);
if ($end >= $start) {
$query->before($end)->after($start);
}
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$query->whereIn('t.account_id', $accountIds);
}
// that should do it:
$second = strval($query->sum('t.amount'));
$sum = bcadd($first, $second);
Log::debug('SumInPeriodData ', ['accounts' => $accountIds, 'first' => $first, 'second' => $second, 'sum' => $sum]);
return $sum;
}
} }

View File

@@ -6,7 +6,6 @@ namespace FireflyIII\Repositories\Account;
use Carbon\Carbon; use Carbon\Carbon;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\Preference;
use FireflyIII\Models\Transaction; use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Pagination\LengthAwarePaginator;
@@ -35,6 +34,15 @@ interface AccountRepositoryInterface
*/ */
public function destroy(Account $account, Account $moveTo): bool; public function destroy(Account $account, Account $moveTo): bool;
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function earnedInPeriod(Collection $accounts, Carbon $start, Carbon $end): string;
/** /**
* @param int $accountId * @param int $accountId
* *
@@ -42,6 +50,13 @@ interface AccountRepositoryInterface
*/ */
public function find(int $accountId): Account; public function find(int $accountId): Account;
/**
* @param Account $account
*
* @return Carbon
*/
public function firstUseDate(Account $account): Carbon;
/** /**
* Gets all the accounts by ID, for a given set. * Gets all the accounts by ID, for a given set.
* *
@@ -51,38 +66,19 @@ interface AccountRepositoryInterface
*/ */
public function get(array $ids): Collection; public function get(array $ids): Collection;
/**
* @param array $accountIds
*
* @return Collection
*/
public function getAccountsById(array $accountIds): Collection;
/** /**
* @param array $types * @param array $types
* *
* @return Collection * @return Collection
*/ */
public function getAccounts(array $types): Collection; public function getAccountsByType(array $types): Collection;
/**
* This method returns the users credit cards, along with some basic information about the
* balance they have on their CC. To be used in the JSON boxes on the front page that say
* how many bills there are still left to pay. The balance will be saved in field "balance".
*
* To get the balance, the field "date" is necessary.
*
* @param Carbon $date
*
* @return Collection
*/
public function getCreditCards(Carbon $date): Collection;
/**
* Returns a list of transactions TO the given (expense) $account, all from the
* given list of accounts
*
* @param Account $account
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpensesByDestination(Account $account, Collection $accounts, Carbon $start, Carbon $end): Collection;
/** /**
* @param TransactionJournal $journal * @param TransactionJournal $journal
@@ -93,35 +89,10 @@ interface AccountRepositoryInterface
public function getFirstTransaction(TransactionJournal $journal, Account $account): Transaction; public function getFirstTransaction(TransactionJournal $journal, Account $account): Transaction;
/** /**
* @param Preference $preference * @deprecated
* *
* @return Collection * SEE OTHER GETJOURNALS METHODS.
*/
public function getFrontpageAccounts(Preference $preference): Collection;
/**
* @param Account $account
* @param Carbon $start
* @param Carbon $end
* *
* @return Collection
*/
public function getFrontpageTransactions(Account $account, Carbon $start, Carbon $end): Collection;
/**
* Returns a list of transactions TO the given (asset) $account, but none from the
* given list of accounts
*
* @param Account $account
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getIncomeByDestination(Account $account, Collection $accounts, Carbon $start, Carbon $end): Collection;
/**
* @param Account $account * @param Account $account
* @param int $page * @param int $page
* @param int $pageSize * @param int $pageSize
@@ -131,6 +102,10 @@ interface AccountRepositoryInterface
public function getJournals(Account $account, int $page, int $pageSize = 50): LengthAwarePaginator; public function getJournals(Account $account, int $page, int $pageSize = 50): LengthAwarePaginator;
/** /**
* @deprecated
*
* SEE OTHER GETJOURNALS METHODS.
*
* @param Account $account * @param Account $account
* @param Carbon $start * @param Carbon $start
* @param Carbon $end * @param Carbon $end
@@ -140,6 +115,8 @@ interface AccountRepositoryInterface
public function getJournalsInRange(Account $account, Carbon $start, Carbon $end): Collection; public function getJournalsInRange(Account $account, Carbon $start, Carbon $end): Collection;
/** /**
* @deprecated
*
* Get the accounts of a user that have piggy banks connected to them. * Get the accounts of a user that have piggy banks connected to them.
* *
* @return Collection * @return Collection
@@ -147,6 +124,8 @@ interface AccountRepositoryInterface
public function getPiggyBankAccounts(): Collection; public function getPiggyBankAccounts(): Collection;
/** /**
* @deprecated
*
* Get savings accounts and the balance difference in the period. * Get savings accounts and the balance difference in the period.
* *
* @return Collection * @return Collection
@@ -154,6 +133,18 @@ interface AccountRepositoryInterface
public function getSavingsAccounts() : Collection; public function getSavingsAccounts() : Collection;
/** /**
* @param Collection $accounts
* @param array $types
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function journalsInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
/**
* @deprecated
*
* @param Account $account * @param Account $account
* @param Carbon $date * @param Carbon $date
* *
@@ -180,12 +171,23 @@ interface AccountRepositoryInterface
public function oldestJournalDate(Account $account): Carbon; public function oldestJournalDate(Account $account): Carbon;
/** /**
*
*
* @param Account $account * @param Account $account
* *
* @return TransactionJournal * @return TransactionJournal
*/ */
public function openingBalanceTransaction(Account $account) : TransactionJournal; public function openingBalanceTransaction(Account $account) : TransactionJournal;
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriod(Collection $accounts, Carbon $start, Carbon $end): string;
/** /**
* @param array $data * @param array $data
* *
@@ -203,6 +205,8 @@ interface AccountRepositoryInterface
public function storeMeta(Account $account, string $name, $value): AccountMeta; public function storeMeta(Account $account, string $name, $value): AccountMeta;
/** /**
* @deprecated
*
* @return string * @return string
*/ */
public function sumOfEverything() : string; public function sumOfEverything() : string;

View File

@@ -250,55 +250,6 @@ class BillRepository implements BillRepositoryInterface
return $amount; return $amount;
} }
/**
* This method will tell you if you still have a CC bill to pay. Amount will be positive if the amount
* has been paid, otherwise it will be negative.
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getCreditCardBill(Carbon $start, Carbon $end): string
{
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$amount = '0';
$creditCards = $accountRepository->getCreditCards($end); // Find credit card accounts and possibly unpaid credit card bills.
/** @var Account $creditCard */
foreach ($creditCards as $creditCard) {
if ($creditCard->balance == 0) {
// find a transfer TO the credit card which should account for anything paid. If not, the CC is not yet used.
$set = TransactionJournal::whereIn(
'transaction_journals.id', function (Builder $q) use ($creditCard, $start, $end) {
$q->select('transaction_journals.id')
->from('transactions')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->where('transactions.account_id', $creditCard->id)
->where('transactions.amount', '>', 0)// this makes the filter unnecessary.
->where('transaction_journals.user_id', $this->user->id)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->where('transaction_types.type', TransactionType::TRANSFER);
}
)->leftJoin(
'transactions', function (JoinClause $join) {
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
)->first([DB::raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$sumAmount = $set->sum_amount ?? '0';
$amount = bcadd($amount, $sumAmount);
} else {
$amount = bcadd($amount, $creditCard->balance);
}
}
return $amount;
}
/** /**
* This method also returns the amount of the journal in "journalAmount" * This method also returns the amount of the journal in "journalAmount"
* for easy access. * for easy access.

View File

@@ -84,17 +84,6 @@ interface BillRepositoryInterface
*/ */
public function getBillsUnpaidInRange(Carbon $start, Carbon $end): string; public function getBillsUnpaidInRange(Carbon $start, Carbon $end): string;
/**
* This method will tell you if you still have a CC bill to pay. Amount will be negative if the amount
* has been paid
*
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function getCreditCardBill(Carbon $start, Carbon $end): string;
/** /**
* @param Bill $bill * @param Bill $bill
* *

View File

@@ -108,9 +108,7 @@ class Navigation
$currentEnd->$function(); $currentEnd->$function();
} }
if (in_array($repeatFreq, $subDay)) { if (in_array($repeatFreq, $subDay)) {
Log::debug('Before subday: ' . $currentEnd->format('Y-m-d'));
$currentEnd->subDay(); $currentEnd->subDay();
Log::debug('After subday: ' . $currentEnd->format('Y-m-d'));
} }
return $currentEnd; return $currentEnd;

View File

@@ -6,7 +6,7 @@
{% block content %} {% block content %}
<div class="row"> <div class="row">
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-12 col-md-10 col-sm-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ account.name }}</h3> <h3 class="box-title">{{ account.name }}</h3>
@@ -32,7 +32,7 @@
<div class="row"> <div class="row">
<div class="col-lg-12 col-md-12 col-sm-12"> <div class="col-lg-8 col-md-8 col-sm-12">
<div class="box"> <div class="box">
<div class="box-header with-border"> <div class="box-header with-border">
<h3 class="box-title">{{ 'transactions'|_ }}</h3> <h3 class="box-title">{{ 'transactions'|_ }}</h3>
@@ -42,6 +42,35 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-4 col-sm-12 col-xs-12">
{% for entry in entries %}
{% if entry[2] != 0 or entry[3] != 0 %}
<div class="box">
<div class="box-header with-border">
<h3 class="box-title"><a href="{{ route('accounts.show.date',[account.id,entry[0]]) }}">{{ entry[1] }}</a>
</h3>
</div>
<div class="box-body no-padding">
<table class="table table-hover">
{% if entry[2] != 0 %}
<tr>
<td colspan="33%">{{ 'spent'|_ }}</td>
<td colspan="67%">{{ entry[2]|formatAmount }}</td>
</tr>
{% endif %}
{% if entry[3] != 0 %}
<tr>
<td colspan="33%">{{ 'earned'|_ }}</td>
<td colspan="67%">{{ entry[3]|formatAmount }}</td>
</tr>
{% endif %}
</table>
</div>
</div>
{% endif %}
{% endfor %}
</div>
</div> </div>

View File

@@ -0,0 +1,62 @@
{% extends "./layout/default.twig" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, account) }}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'overview'|_ }} (period)</h3>
<!-- ACTIONS MENU -->
<div class="box-tools pull-right">
<button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
<div class="btn-group">
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
<ul class="dropdown-menu" role="menu">
<li><a href="{{ route('accounts.edit', account.id) }}"><i class="fa fa-pencil fa-fw"></i> {{ 'edit'|_ }}</a></li>
<li><a href="{{ route('accounts.delete', account.id) }}"><i class="fa fa-trash fa-fw"></i> {{ 'delete'|_ }}</a></li>
</ul>
</div>
</div>
</div>
<div class="box-body">
<canvas id="period-specific-period-account" style="width:100%;height:350px;" height="350"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="box">
<div class="box-header with-border">
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
</div>
<div class="box-body">
{% include 'list.journals' with {sorting:true} %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
var accountID = {{ account.id }};
</script>
<script type="text/javascript" src="js/lib/Chart.bundle.min.js"></script>
<script type="text/javascript" src="js/ff/charts.js"></script>
<script src="js/lib/jquery-ui.min.js" type="text/javascript"></script>
<script src="js/lib/jquery.color-2.1.2.min.js" type="text/javascript"></script>
<script src="js/ff/accounts/show.js" type="text/javascript"></script>
<script type="text/javascript" src="js/ff/transactions/list.js"></script>
{% endblock %}