Merge branch 'release/3.8.2'

This commit is contained in:
James Cole 2016-04-03 16:47:54 +02:00
commit a6936cbd02
251 changed files with 1949 additions and 722 deletions

View File

@ -5,6 +5,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
- No unreleased changes yet.
## [3.8.2] - 2016-04-03
### Added
- Small user administration at /admin.
- Informational popups are working in reports.
### Changed
- User activation emails are better
### Fixed
- Some bugs related to accounts and rules.
## [3.8.1] - 2016-03-29
### Added
- More translations
@ -15,21 +27,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- The pages related to rules have new URL's.
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- Spelling errors.
- Problems related to the "account repository".
- Some views showed empty (0.0) amounts.
### Security
- Initial release.
## [3.8.0] - 2016-03-20
### Added
- Two factor authentication, thanks to the excellent work of [zjean](https://github.com/zjean).

View File

@ -1,4 +1,4 @@
Copyright (C) 2016 Sander Dorigo
Copyright (C) 2016 thegrumpydictator@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -3,7 +3,7 @@ declare(strict_types = 1);
/**
* Kernel.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* ResendConfirmation.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* TransactionJournalStored.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* UserRegistration.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* AttachmentCollector.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BasicCollector.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* CollectorInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* UploadCollector.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ConfigurationFile.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* Entry.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BasicExporter.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* CsvExporter.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ExporterInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* Processor.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* AccountChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BillChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ChartJsBillChartGenerator.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BudgetChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* CategoryChartGeneratorInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* PiggyBankChartGenerator.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ReportChartGenerator.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* AttachUserRole.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* FireRulesForStore.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* FireRulesForUpdate.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RescanJournalAfterStore.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ScanForBillsAfterUpdate.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* SendRegistrationMail.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* UserConfirmation.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* UserEventListener.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,9 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Account;
use Log;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class AccountId
@ -19,22 +18,16 @@ class AccountId extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
/** @var Account $account */
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
} else {
/** @var Account $account */
$account = Auth::user()->accounts()->find($this->value);
if (!is_null($account)) {
Log::debug('Found ' . $account->accountType->type . ' named "******" with ID: ' . $this->value . ' (not mapped) ');
} else {
// new account to prevent TypeErrors.
$account = new Account;
}
$account = $repository->find($this->value);
}
return $account;

View File

@ -5,6 +5,7 @@ namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class AssetAccountIban
@ -19,60 +20,48 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface
*/
public function convert(): Account
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
return $account;
}
if (strlen($this->value) > 0) {
// find or create new account:
$account = $this->findAccount();
$set = $repository->getAccounts(['Default account', 'Asset account']);
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->iban == $this->value) {
if (is_null($account->id)) {
// create it if doesn't exist.
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
return $entry;
}
}
// create it if doesn't exist.
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
return $account;
}
return new Account;
}
/**
* @return Account
*/
protected function findAccount(): Account
{
$set = Auth::user()->accounts()->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->iban == $this->value) {
return $entry;
}
}
return new Account;
}
}

View File

@ -5,6 +5,7 @@ namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class AssetAccountName
@ -19,14 +20,19 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
return $account;
}
// find or create new account:
$set = Auth::user()->accounts()->accountTypeIn(['Asset account', 'Default account'])->get();
$set = $repository->getAccounts(['Default account', 'Asset account']);
/** @var Account $entry */
foreach ($set as $entry) {
if ($entry->name == $this->value) {
@ -35,8 +41,6 @@ class AssetAccountName extends BasicConverter implements ConverterInterface
}
// create it if doesnt exist.
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* AssetAccountNumber.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
@ -13,6 +14,7 @@ namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class AssetAccountNumber
@ -27,9 +29,12 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
return $account;
}
@ -37,53 +42,38 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface
$value = $this->value ?? '';
if (strlen($value) > 0) {
// find or create new account:
$account = $this->findAccount();
$set = $repository->getAccounts(['Default account', 'Asset account']);
/** @var Account $entry */
foreach ($set as $entry) {
$accountNumber = $entry->getMeta('accountNumber');
if ($accountNumber == $this->value) {
if (is_null($account->id)) {
// create it if doesn't exist.
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
return $entry;
}
}
$accountData = [
'name' => $this->value,
'accountType' => 'asset',
'virtualBalance' => 0,
'virtualBalanceCurrency' => 1, // hard coded.
'active' => true,
'user' => Auth::user()->id,
'iban' => null,
'accountNumber' => $this->value,
'accountRole' => null,
'openingBalance' => 0,
'openingBalanceDate' => new Carbon,
'openingBalanceCurrency' => 1, // hard coded.
];
$account = $repository->store($accountData);
return $account;
}
return null;
return null; // is this accepted?
}
/**
* @return Account
*/
protected function findAccount(): Account
{
$set = Auth::user()->accounts()->with(['accountmeta'])->accountTypeIn(['Default account', 'Asset account'])->get(['accounts.*']);
/** @var Account $entry */
foreach ($set as $entry) {
$accountNumber = $entry->getMeta('accountNumber');
if ($accountNumber == $this->value) {
return $entry;
}
}
return new Account;
}
}

View File

@ -2,8 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
/**
* Class BillId
@ -18,11 +18,14 @@ class BillId extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var BillRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]);
$bill = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$bill = Auth::user()->bills()->find($this->value);
$bill = $repository->find($this->value);
}
return $bill;

View File

@ -2,8 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
/**
* Class BillName
@ -18,13 +18,15 @@ class BillName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var BillRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Bill\BillRepositoryInterface');
$bill = null;
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$bill = Auth::user()->bills()->find($this->mapped[$this->index][$this->value]);
$bill = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$bills = Auth::user()->bills()->get();
$bills = $repository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
if ($bill->name == $this->value) {

View File

@ -2,8 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
/**
* Class BudgetId
@ -18,11 +18,15 @@ class BudgetId extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var BudgetRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]);
$budget = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$budget = Auth::user()->budgets()->find($this->value);
$budget = $repository->find($this->value);
}
return $budget;

View File

@ -4,6 +4,7 @@ namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
/**
* Class BudgetName
@ -18,12 +19,14 @@ class BudgetName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var BudgetRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$budget = Auth::user()->budgets()->find($this->mapped[$this->index][$this->value]); // see issue #180
$budget = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
$budget = $repository->store(['name' => $this->value, 'user' => Auth::user()->id]);
}
return $budget;

View File

@ -2,8 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface;
/**
* Class CategoryId
@ -18,11 +18,14 @@ class CategoryId extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var SingleCategoryRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
$category = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$category = Auth::user()->categories()->find($this->value);
$category = $repository->find($this->value);
}
return $category;

View File

@ -4,6 +4,7 @@ namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface;
/**
* Class CategoryName
@ -18,16 +19,20 @@ class CategoryName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var SingleCategoryRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface');
// is mapped? Then it's easy!
if (isset($this->mapped[$this->index][$this->value])) {
$category = Auth::user()->categories()->find($this->mapped[$this->index][$this->value]);
$category = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$category = Category::firstOrCreateEncrypted( // See issue #180
[
'name' => $this->value,
'user_id' => Auth::user()->id,
]
);
$data = [
'name' => $this->value,
'user' => Auth::user()->id,
];
$category = $repository->store($data);
}
return $category;

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
/**
* Class CurrencyCode
@ -17,10 +18,14 @@ class CurrencyCode extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = TransactionCurrency::whereCode($this->value)->first();
$currency = $repository->findByCode($this->value);
}
return $currency;

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
/**
* Class CurrencyId
@ -17,10 +18,13 @@ class CurrencyId extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = TransactionCurrency::find($this->value);
$currency = $repository->find($this->value);
}
return $currency;

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
/**
* Class CurrencyName
@ -17,10 +18,14 @@ class CurrencyName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = TransactionCurrency::whereName($this->value)->first();
$currency = $repository->findByName($this->value);
}
return $currency;

View File

@ -3,6 +3,7 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
/**
* Class CurrencySymbol
@ -17,10 +18,13 @@ class CurrencySymbol extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$currency = TransactionCurrency::find($this->mapped[$this->index][$this->value]);
$currency = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$currency = TransactionCurrency::whereSymbol($this->value)->first();
$currency = $repository->findBySymbol($this->value);
}
return $currency;

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* INGDebetCredit.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,9 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Account;
use Log;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class OpposingAccountIban
@ -21,15 +20,23 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
return $account;
} else {
if (strlen($this->value) > 0) {
$account = $this->findAccount();
if (!is_null($account)) {
return $account;
$set = $repository->getAccounts([]);
/** @var Account $account */
foreach ($set as $account) {
if ($account->iban == $this->value) {
return $account;
}
}
}
@ -37,21 +44,4 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface
}
}
/**
* @return Account|null
*/
protected function findAccount()
{
$set = Auth::user()->accounts()->get();
/** @var Account $account */
foreach ($set as $account) {
if ($account->iban == $this->value) {
Log::debug('OpposingAccountIban::convert found an Account (#' . $account->id . ': ******) with IBAN ******');
return $account;
}
}
return null;
}
}

View File

@ -2,8 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class OpposingAccountId
@ -19,11 +19,14 @@ class OpposingAccountId extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
} else {
$account = Auth::user()->accounts()->find($this->value);
$account = $repository->find($this->value);
}
return $account;

View File

@ -2,8 +2,8 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
/**
* Class OpposingAccountName
@ -20,8 +20,11 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
if (isset($this->mapped[$this->index][$this->value])) {
$account = Auth::user()->accounts()->find($this->mapped[$this->index][$this->value]);
$account = $repository->find($this->mapped[$this->index][$this->value]);
return $account;
} else {

View File

@ -2,8 +2,7 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Support\Collection;
/**
@ -19,17 +18,22 @@ class TagsComma extends BasicConverter implements ConverterInterface
*/
public function convert()
{
$tags = new Collection;
/** @var TagRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface');
$tags = new Collection;
$strings = explode(',', $this->value);
foreach ($strings as $string) {
$tag = Tag::firstOrCreateEncrypted( // See issue #180
[
'tag' => $string,
'tagMode' => 'nothing',
'user_id' => Auth::user()->id,
]
);
$data = [
'tag' => $string,
'date' => null,
'description' => null,
'latitude' => null,
'longitude' => null,
'zoomLevel' => null,
'tagMode' => 'nothing',
];
$tag = $repository->store($data); // should validate first?
$tags->push($tag);
}
$tags = $tags->merge($this->data['tags']);

View File

@ -2,8 +2,7 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Csv\Converter;
use Auth;
use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Support\Collection;
/**
@ -19,17 +18,23 @@ class TagsSpace extends BasicConverter implements ConverterInterface
*/
public function convert()
{
/** @var TagRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Tag\TagRepositoryInterface');
$tags = new Collection;
$strings = explode(' ', $this->value);
foreach ($strings as $string) {
$tag = Tag::firstOrCreateEncrypted( // See issue #180
[
'tag' => $string,
'tagMode' => 'nothing',
'user_id' => Auth::user()->id,
]
);
$data = [
'tag' => $string,
'date' => null,
'description' => null,
'latitude' => null,
'longitude' => null,
'zoomLevel' => null,
'tagMode' => 'nothing',
];
$tag = $repository->store($data); // should validate first?
$tags->push($tag);
}
$tags = $tags->merge($this->data['tags']);

View File

@ -120,6 +120,8 @@ class Importer
Log::error('Caught error at row #' . $index . ': ' . $result);
$this->errors[$index] = $result;
} else {
$this->imported++;
$this->journals->push($result);
}

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* Specifix.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* AccountReportHelper.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* AccountReportHelperInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BalanceReportHelper.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BalanceReportHelperInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BudgetReportHelper.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* BudgetReportHelperInterface.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -15,6 +15,8 @@ use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
/**
@ -230,27 +232,36 @@ class ReportHelper implements ReportHelperInterface
{
$ids = $accounts->pluck('id')->toArray();
$set = Tag::
distinct()
->leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
->leftJoin('transaction_journals', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin(
'transactions AS source', function (JoinClause $join) {
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', '0');
}
)
->leftJoin(
'transactions AS destination', function (JoinClause $join) {
$join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')->where('destination.amount', '>', '0');
}
)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereIn('transactions.account_id', $ids)->get(
['tags.id', 'tags.tag', 'transaction_journals.id as journal_id', 'transactions.amount']
);
->where(
function (Builder $q) use ($ids) {
$q->whereIn('source.account_id', $ids)
->whereIn('destination.account_id', $ids, 'xor');
}
)
->get(['tags.id', 'tags.tag', 'transaction_journals.id as journal_id', 'destination.amount']);
$collection = [];
if ($set->count() === 0) {
return $collection;
}
/** @var Tag $entry */
foreach ($set as $entry) {
// less than zero? multiply to be above zero.
$amount = $entry->amount;
if (bccomp($amount, '0', 2) === -1) {
$amount = bcmul($amount, '-1');
}
$id = intval($entry->id);
$id = intval($entry->id);
if (!isset($collection[$id])) {
$collection[$id] = [
'id' => $id,

View File

@ -42,6 +42,7 @@ class AccountController extends Controller
$subTitleIcon = Config::get('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account');
Session::flash('preFilled', []);
// put previous url in session if not redirect from store (not "create another").
if (session('accounts.create.fromStore') !== true) {

View File

@ -0,0 +1,33 @@
<?php
/**
* HomeController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
/**
* Class HomeController
*
* @package FireflyIII\Http\Controllers\Admin
*/
class HomeController extends Controller
{
/**
* @return mixed
*/
public function index()
{
$title = strval(trans('firefly.administration'));
$mainTitleIcon = 'fa-hand-spock-o';
return view('admin.index', compact('title', 'mainTitleIcon'));
}
}

View File

@ -0,0 +1,70 @@
<?php
/**
* UserController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Preferences;
/**
* Class UserController
*
* @package FireflyIII\Http\Controllers\Admin
*/
class UserController extends Controller
{
/**
* @param UserRepositoryInterface $repository
*/
public function index(UserRepositoryInterface $repository)
{
$title = strval(trans('firefly.administration'));
$mainTitleIcon = 'fa-hand-spock-o';
$subTitle = strval(trans('firefly.user_administration'));
$subTitleIcon = 'fa-users';
$confirmAccount = env('MUST_CONFIRM_ACCOUNT', false);
// list all users:
$users = $repository->all();
// add meta stuff.
$users->each(
function (User $user) use ($confirmAccount) {
// is user activated?
$isConfirmed = Preferences::getForUser($user, 'user_confirmed', false)->data;
if ($isConfirmed === false && $confirmAccount === true) {
$user->activated = false;
} else {
$user->activated = true;
}
// is user admin?
$user->isAdmin = $user->hasRole('owner');
// user has 2FA enabled?
$is2faEnabled = Preferences::getForUser($user, 'twoFactorAuthEnabled', false)->data;
$has2faSecret = !is_null(Preferences::getForUser($user, 'twoFactorAuthSecret'));
if ($is2faEnabled && $has2faSecret) {
$user->has2FA = true;
} else {
$user->has2FA = false;
}
}
);
return view('admin.users.index', compact('title', 'mainTitleIcon', 'subTitle', 'subTitleIcon', 'users'));
}
}

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* ConfirmationController.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* TwoFactorController.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
@ -36,13 +37,14 @@ class TwoFactorController extends Controller
// to make sure the validator in the next step gets the secret, we push it in session
$secret = Preferences::get('twoFactorAuthSecret', '')->data;
$title = strval(trans('firefly.two_factor_title'));
if (strlen($secret) === 0) {
throw new FireflyException('Your two factor authentication secret is empty, which it cannot be at this point. Please check the log files.');
}
Session::flash('two-factor-secret', $secret);
return view('auth.two-factor', compact('user'));
return view('auth.two-factor', compact('user', 'title'));
}
/**
@ -53,6 +55,7 @@ class TwoFactorController extends Controller
{
$user = Auth::user();
$siteOwner = env('SITE_OWNER', '');
$title = strval(trans('firefly.two_factor_forgot_title'));
Log::info(
'To reset the two factor authentication for user #' . $user->id .
@ -60,7 +63,7 @@ class TwoFactorController extends Controller
' "twoFactorAuthSecret" for user_id ' . $user->id . '. That will take care of it.'
);
return view('auth.lost-two-factor', compact('user', 'siteOwner'));
return view('auth.lost-two-factor', compact('user', 'siteOwner', 'title'));
}
/**

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ExportController.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -0,0 +1,234 @@
<?php
declare(strict_types = 1);
/**
* ReportController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Http\Controllers\Popup;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collection\BalanceLine;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface;
use FireflyIII\Support\Binder\AccountList;
use Illuminate\Http\Request;
use InvalidArgumentException;
use Response;
use View;
/**
* Class ReportController
*
* @package FireflyIII\Http\Controllers\Popup
*/
class ReportController extends Controller
{
/**
* @param Request $request
*
* @throws FireflyException
*/
public function info(Request $request)
{
$attributes = $request->get('attributes');
$attributes = $this->parseAttributes($attributes);
View::share('start', $attributes['startDate']);
View::share('end', $attributes['endDate']);
switch ($attributes['location']) {
default:
throw new FireflyException('Firefly cannot handle "' . e($attributes['location']) . '" ');
case 'budget-spent-amount':
$html = $this->budgetSpentAmount($attributes);
break;
case 'expense-entry':
$html = $this->expenseEntry($attributes);
break;
case 'income-entry':
$html = $this->incomeEntry($attributes);
break;
case 'category-entry':
$html = $this->categoryEntry($attributes);
break;
case 'balance-amount':
$html = $this->balanceAmount($attributes);
break;
}
return Response::json(['html' => $html]);
}
/**
* @param $attributes
*
* @return string
* @throws FireflyException
*/
private function balanceAmount(array $attributes): string
{
$role = intval($attributes['role']);
/** @var BudgetRepositoryInterface $budgetRepository */
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$budget = $budgetRepository->find(intval($attributes['budgetId']));
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$account = $accountRepository->find(intval($attributes['accountId']));
switch (true) {
case ($role === BalanceLine::ROLE_DEFAULTROLE && !is_null($budget->id)):
$journals = $budgetRepository->expensesSplit($budget, $account, $attributes['startDate'], $attributes['endDate']);
break;
case ($role === BalanceLine::ROLE_DEFAULTROLE && is_null($budget->id)):
$budget->name = strval(trans('firefly.no_budget'));
$journals = $budgetRepository->getAllWithoutBudget($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
break;
case ($role === BalanceLine::ROLE_DIFFROLE):
// journals no budget, not corrected by a tag.
$journals = $budgetRepository->getAllWithoutBudget($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
$budget->name = strval(trans('firefly.leftUnbalanced'));
$journals = $journals->filter(
function (TransactionJournal $journal) {
$tags = $journal->tags()->where('tagMode', 'balancingAct')->count();
if ($tags === 0) {
return $journal;
}
}
);
break;
case ($role === BalanceLine::ROLE_TAGROLE):
throw new FireflyException('Firefly cannot handle this type of info-button (BalanceLine::TagRole)');
}
$view = view('popup.report.balance-amount', compact('journals', 'budget', 'account'))->render();
return $view;
}
/**
* Returns all expenses inside the given budget for the given accounts.
*
* @param array $attributes
*
* @return string
* @throws FireflyException
*/
private function budgetSpentAmount(array $attributes): string
{
// need to find the budget
// then search for expenses in the given period
// list them in some table format.
/** @var BudgetRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$budget = $repository->find(intval($attributes['budgetId']));
if (is_null($budget->id)) {
$journals = $repository->getWithoutBudgetForAccounts($attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
} else {
// get all expenses in budget in period:
$journals = $repository->getExpenses($budget, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
}
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
return $view;
}
/**
* Returns all expenses in category in range.
*
* @param $attributes
*
* @return string
* @throws FireflyException
*/
private function categoryEntry(array $attributes): string
{
/** @var SingleCategoryRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface');
$category = $repository->find(intval($attributes['categoryId']));
$journals = $repository->getJournalsForAccountsInRange($category, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
return $view;
}
/**
* Returns all the expenses that went to the given expense account.
*
* @param $attributes
*
* @return string
* @throws FireflyException
*/
private function expenseEntry(array $attributes): string
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$account = $repository->find(intval($attributes['accountId']));
$journals = $repository->getExpensesByDestination($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
$view = view('popup.report.expense-entry', compact('journals', 'account'))->render();
return $view;
}
/**
* Returns all the incomes that went to the given asset account.
*
* @param $attributes
*
* @return string
* @throws FireflyException
*/
private function incomeEntry(array $attributes): string
{
/** @var AccountRepositoryInterface $repository */
$repository = app('FireflyIII\Repositories\Account\AccountRepositoryInterface');
$account = $repository->find(intval($attributes['accountId']));
$journals = $repository->getIncomeByDestination($account, $attributes['accounts'], $attributes['startDate'], $attributes['endDate']);
$view = view('popup.report.income-entry', compact('journals', 'account'))->render();
return $view;
}
/**
* @param array $attributes
*
* @return array
* @throws FireflyException
*/
private function parseAttributes(array $attributes): array
{
$attributes['location'] = $attributes['location'] ?? '';
$attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', '');
try {
$attributes['startDate'] = Carbon::createFromFormat('Ymd', $attributes['startDate']);
} catch (InvalidArgumentException $e) {
throw new FireflyException('Could not parse start date "' . e($attributes['startDate']) . '".');
}
try {
$attributes['endDate'] = Carbon::createFromFormat('Ymd', $attributes['endDate']);
} catch (InvalidArgumentException $e) {
throw new FireflyException('Could not parse start date "' . e($attributes['endDate']) . '".');
}
return $attributes;
}
}

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RuleController.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -7,6 +7,7 @@ use FireflyIII\Http\Middleware\Authenticate;
use FireflyIII\Http\Middleware\AuthenticateTwoFactor;
use FireflyIII\Http\Middleware\Binder;
use FireflyIII\Http\Middleware\EncryptCookies;
use FireflyIII\Http\Middleware\IsAdmin;
use FireflyIII\Http\Middleware\IsConfirmed;
use FireflyIII\Http\Middleware\IsNotConfirmed;
use FireflyIII\Http\Middleware\Range;
@ -121,6 +122,25 @@ class Kernel extends HttpKernel
Range::class,
Binder::class,
],
// MUST be logged in
// MUST have 2fa
// MUST be confirmed.
// MUST have owner role
// (this group includes the other Firefly middleware)
'admin' => [
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
Authenticate::class,
AuthenticateTwoFactor::class,
IsConfirmed::class,
IsAdmin::class,
Range::class,
Binder::class,
],
'api' => [
'throttle:60,1',

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* AuthenticateTwoFactor.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -0,0 +1,63 @@
<?php
/**
* IsAdmin.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
/**
* IsConfirmed.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Middleware;
use Closure;
use FireflyIII\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Class IsAdmin
*
* @package FireflyIII\Http\Middleware
*/
class IsAdmin
{
/**
* Handle an incoming request. User account must be confirmed for this routine to let
* the user pass.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
*
* @return mixed
*/
public function handle(Request $request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
} else {
/** @var User $user */
$user = Auth::user();
if (!$user->hasRole('owner')) {
return redirect(route('home'));
}
}
return $next($request);
}
}

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* IsConfirmed.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* IsNotConfirmed.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* RedirectIfTwoFactorAuthenticated.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ExportFormRequest.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RuleFormRequest.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RuleGroupFormRequest.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* TestRuleFormRequest.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
@ -10,7 +11,7 @@
declare(strict_types = 1);
/**
* TestRuleFormRequest.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -28,9 +28,8 @@ Route::group(
);
/**
* For other routes, it is only relevant that the user is authenticated.
* For some other routes, it is only relevant that the user is authenticated.
*/
Route::group(
['middleware' => 'user-simple-auth'], function () {
Route::get('/error', 'HomeController@displayError');
@ -378,6 +377,28 @@ Route::group(
Route::post('/transaction/destroy/{tj}', ['uses' => 'TransactionController@destroy', 'as' => 'transactions.destroy']);
Route::post('/transaction/reorder', ['uses' => 'TransactionController@reorder', 'as' => 'transactions.reorder']);
/**
* POPUP Controllers
*/
/**
* Report popup
*/
Route::get('/popup/report', ['uses' => 'Popup\ReportController@info', 'as' => 'popup.report']);
}
);
/**
* For the admin routes, the user must be logged in and have the role of 'owner'
*/
Route::group(
['middleware' => 'admin'], function () {
// admin home
Route::get('/admin', ['uses' => 'Admin\HomeController@index', 'as' => 'admin.index']);
// user manager
Route::get('/admin/users', ['uses' => 'Admin\UserController@index', 'as' => 'admin.users']);
}
);

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ExportJob.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* Rule.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RuleAction.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RuleGroup.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* RuleTrigger.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -92,6 +92,22 @@ class Tag extends Model
throw new NotFoundHttpException;
}
/**
* @param Tag $tag
*
* @return string
*/
public static function tagSum(Tag $tag): string
{
$sum = '0';
/** @var TransactionJournal $journal */
foreach ($tag->transactionjournals as $journal) {
bcadd($sum, TransactionJournal::amount($journal));
}
return $sum;
}
/**
* @codeCoverageIgnore
*

View File

@ -382,7 +382,8 @@ class TransactionJournal extends TransactionJournalSupport
// join destination account
$query->leftJoin('accounts as source_account', 'source_account.id', '=', 'source.account_id');
// join destination account type
$query->leftJoin('account_types as source_acct_type', 'source_account.account_type_id', '=', 'source_acct_type.id');
$query->leftJoin('account_types as source_acct_type', 'source_account.account_type_id', '=', 'source_acct_type.id')
->orderBy('transaction_journals.date', 'DESC')->orderBy('transaction_journals.order', 'ASC')->orderBy('transaction_journals.id', 'DESC');
$query->with(['categories', 'budgets', 'attachments', 'bill']);

View File

@ -1,7 +1,8 @@
<?php
declare(strict_types = 1);
/**
* TransactionJournalMeta.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

View File

@ -45,5 +45,21 @@ class CategoryServiceProvider extends ServiceProvider
return app('FireflyIII\Repositories\Category\CategoryRepository', $arguments);
}
);
$this->app->bind(
'FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface',
function (Application $app, array $arguments) {
if (!isset($arguments[0]) && Auth::check()) {
return app('FireflyIII\Repositories\Category\SingleCategoryRepository', [Auth::user()]);
} else {
if (!isset($arguments[0]) && !Auth::check()) {
throw new FireflyException('There is no user present.');
}
}
return app('FireflyIII\Repositories\Category\SingleCategoryRepository', $arguments);
}
);
}
}

View File

@ -82,7 +82,7 @@ class FireflyServiceProvider extends ServiceProvider
}
);
$this->app->bind('FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface', 'FireflyIII\Repositories\Category\SingleCategoryRepository');
$this->app->bind('FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', 'FireflyIII\Repositories\Currency\CurrencyRepository');
$this->app->bind('FireflyIII\Support\Search\SearchInterface', 'FireflyIII\Support\Search\Search');
$this->app->bind('FireflyIII\Repositories\User\UserRepositoryInterface', 'FireflyIII\Repositories\User\UserRepository');

View File

@ -33,6 +33,8 @@ class AccountRepository implements AccountRepositoryInterface
/** @var User */
private $user;
/** @var array */
private $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber'];
/**
* AttachmentRepository constructor.
@ -75,15 +77,18 @@ class AccountRepository implements AccountRepositoryInterface
}
/**
* @deprecated
*
* @param $accountId
*
* @return Account
*/
public function find(int $accountId): Account
{
return $this->user->accounts()->findOrNew($accountId);
$account = $this->user->accounts()->find($accountId);
if (is_null($account)) {
$account = new Account;
}
return $account;
}
/**
@ -106,11 +111,15 @@ class AccountRepository implements AccountRepositoryInterface
public function getAccounts(array $types): Collection
{
/** @var Collection $result */
$result = $this->user->accounts()->with(
$query = $this->user->accounts()->with(
['accountmeta' => function (HasMany $query) {
$query->where('name', 'accountRole');
}]
)->accountTypeIn($types)->get(['accounts.*']);
);
if (count($types) > 0) {
$query->accountTypeIn($types);
}
$result = $query->get(['accounts.*']);
$result = $result->sortBy(
function (Account $account) {
@ -154,6 +163,31 @@ class AccountRepository implements AccountRepositoryInterface
return $set;
}
/**
* Returns a list of transactions TO the $account, not including transfers
* and/or expenses in the $accounts list.
*
* @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)
{
$ids = $accounts->pluck('id')->toArray();
$journals = $this->user->transactionjournals()
->expanded()
->before($end)
->where('destination_account.id', $account->id)
->whereIn('source_account.id', $ids)
->after($start)
->get(TransactionJournal::QUERYFIELDS);
return $journals;
}
/**
* @param TransactionJournal $journal
* @param Account $account
@ -448,7 +482,7 @@ class AccountRepository implements AccountRepositoryInterface
$this->updateMetadata($account, $data);
$openingBalance = $this->openingBalanceTransaction($account);
if ($data['openingBalance'] != 0) {
if ($openingBalance) {
if (!is_null($openingBalance->id)) {
$this->updateInitialBalance($account, $openingBalance, $data);
} else {
$type = $data['openingBalance'] < 0 ? 'expense' : 'revenue';
@ -570,8 +604,7 @@ class AccountRepository implements AccountRepositoryInterface
*/
protected function storeMetadata(Account $account, array $data)
{
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
foreach ($validFields as $field) {
foreach ($this->validFields as $field) {
if (isset($data[$field])) {
$metaData = new AccountMeta(
[
@ -621,9 +654,7 @@ class AccountRepository implements AccountRepositoryInterface
*/
protected function updateMetadata(Account $account, array $data)
{
$validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType'];
foreach ($validFields as $field) {
foreach ($this->validFields as $field) {
$entry = $account->accountMeta()->where('name', $field)->first();
if (isset($data[$field])) {
@ -645,4 +676,29 @@ class AccountRepository implements AccountRepositoryInterface
}
}
/**
* 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)
{
$ids = $accounts->pluck('id')->toArray();
$journals = $this->user->transactionjournals()
->expanded()
->before($end)
->where('source_account.id', $account->id)
->whereIn('destination_account.id', $ids)
->after($start)
->get(TransactionJournal::QUERYFIELDS);
return $journals;
}
}

View File

@ -71,6 +71,19 @@ interface AccountRepositoryInterface
*/
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);
/**
* @param TransactionJournal $journal
* @param Account $account
@ -95,6 +108,19 @@ interface AccountRepositoryInterface
*/
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);
/**
* @param Account $account
* @param $page

View File

@ -49,6 +49,23 @@ class BillRepository implements BillRepositoryInterface
return true;
}
/**
* Find a bill by ID.
*
* @param int $billId
*
* @return Bill
*/
public function find(int $billId) : Bill
{
$bill = $this->user->bills()->find($billId);
if (is_null($bill)) {
$bill = new Bill;
}
return $bill;
}
/**
* @return Collection
*/
@ -252,7 +269,7 @@ class BillRepository implements BillRepositoryInterface
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(
$set = TransactionJournal::whereIn(
'transaction_journals.id', function (Builder $q) use ($creditCard, $start, $end) {
$q->select('transaction_journals.id')
->from('transactions')
@ -270,8 +287,8 @@ class BillRepository implements BillRepositoryInterface
$join->on('transactions.transaction_journal_id', '=', 'transaction_journals.id')->where('transactions.amount', '>', 0);
}
)->first([DB::raw('SUM(`transactions`.`amount`) as `sum_amount`')]);
$amount = bcadd($amount, $set->sum_amount);
$sumAmount = $set->sum_amount ?? '0';
$amount = bcadd($amount, $sumAmount);
} else {
$amount = bcadd($amount, $creditCard->balance);
}

View File

@ -23,6 +23,15 @@ interface BillRepositoryInterface
*/
public function destroy(Bill $bill): bool;
/**
* Find a bill by ID.
*
* @param int $billId
*
* @return Bill
*/
public function find(int $billId) : Bill;
/**
* @return Collection
*/

View File

@ -5,6 +5,7 @@ namespace FireflyIII\Repositories\Budget;
use Carbon\Carbon;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\LimitRepetition;
@ -74,6 +75,40 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
return true;
}
/**
* @param Budget $budget
* @param Account $account
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function expensesSplit(Budget $budget, Account $account, Carbon $start, Carbon $end): Collection
{
return $budget->transactionjournals()->expanded()
->before($end)
->after($start)
->where('source_account.id', $account->id)
->get(TransactionJournal::QUERYFIELDS);
}
/**
* Find a budget.
*
* @param int $budgetId
*
* @return Budget
*/
public function find(int $budgetId): Budget
{
$budget = $this->user->budgets()->find($budgetId);
if (is_null($budget)) {
$budget = new Budget;
}
return $budget;
}
/**
* @param Budget $budget
*
@ -124,6 +159,30 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
->get(['limit_repetitions.*', 'budget_limits.budget_id']);
}
/**
* @param Account $account
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return Collection
*/
public function getAllWithoutBudget(Account $account, Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
return $this->user
->transactionjournals()
->expanded()
->where('source_account.id', $account->id)
->whereNotIn('destination_account.id', $ids)
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('budget_transaction_journal.id')
->before($end)
->after($start)
->get(TransactionJournal::QUERYFIELDS);
}
/**
* Get the budgeted amounts for each budgets in each year.
*
@ -355,6 +414,30 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
return $data;
}
/**
* Returns all expenses for the given budget and the given accounts, in the given period.
*
* @param Budget $budget
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpenses(Budget $budget, Collection $accounts, Carbon $start, Carbon $end):Collection
{
$ids = $accounts->pluck('id')->toArray();
$set = $budget->transactionjournals()
->before($end)
->after($start)
->expanded()
->where('transaction_types.type', TransactionType::WITHDRAWAL)
->whereIn('source_account.id', $ids)
->get(TransactionJournal::QUERYFIELDS);
return $set;
}
/**
* Returns the expenses for this budget grouped per day, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
@ -460,15 +543,36 @@ class BudgetRepository extends ComponentRepository implements BudgetRepositoryIn
{
return $this->user
->transactionjournals()
->transactionTypes([TransactionType::WITHDRAWAL])
->expanded()
->where('transaction_types.type', TransactionType::WITHDRAWAL)
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('budget_transaction_journal.id')
->before($end)
->after($start)
->orderBy('transaction_journals.date', 'DESC')
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->get(['transaction_journals.*']);
->get(TransactionJournal::QUERYFIELDS);
}
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getWithoutBudgetForAccounts(Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
return $this->user
->transactionjournals()
->expanded()
->whereIn('source_account.id', $ids)
->where('transaction_types.type', TransactionType::WITHDRAWAL)
->leftJoin('budget_transaction_journal', 'budget_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->whereNull('budget_transaction_journal.id')
->before($end)
->after($start)
->get(TransactionJournal::QUERYFIELDS);
}
/**

View File

@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\Budget;
use Carbon\Carbon;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\LimitRepetition;
use Illuminate\Pagination\LengthAwarePaginator;
@ -17,7 +18,6 @@ use Illuminate\Support\Collection;
interface BudgetRepositoryInterface
{
/**
*
* Same as ::spentInPeriod but corrects journals for a set of accounts
@ -43,6 +43,25 @@ interface BudgetRepositoryInterface
*/
public function destroy(Budget $budget);
/**
* @param Budget $budget
* @param Account $account
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function expensesSplit(Budget $budget, Account $account, Carbon $start, Carbon $end): Collection;
/**
* Find a budget.
*
* @param int $budgetId
*
* @return Budget
*/
public function find(int $budgetId): Budget;
/**
* @param Budget $budget
*
@ -63,6 +82,16 @@ interface BudgetRepositoryInterface
*/
public function getAllBudgetLimitRepetitions(Carbon $start, Carbon $end);
/**
* @param Account $account
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getAllWithoutBudget(Account $account, Collection $accounts, Carbon $start, Carbon $end);
/**
* Get the budgeted amounts for each budgets in each year.
*
@ -124,6 +153,18 @@ interface BudgetRepositoryInterface
*/
public function getCurrentRepetition(Budget $budget, Carbon $start, Carbon $end);
/**
* Returns all expenses for the given budget and the given accounts, in the given period.
*
* @param Budget $budget
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getExpenses(Budget $budget, Collection $accounts, Carbon $start, Carbon $end):Collection;
/**
* Returns the expenses for this budget grouped per day, with the date
* in "date" (a string, not a Carbon) and the amount in "dailyAmount".
@ -167,6 +208,15 @@ interface BudgetRepositoryInterface
*/
public function getWithoutBudget(Carbon $start, Carbon $end);
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getWithoutBudgetForAccounts(Collection $accounts, Carbon $start, Carbon $end);
/**
* @param Collection $accounts
* @param Carbon $start

View File

@ -9,6 +9,7 @@ use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Shared\ComponentRepository;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
@ -18,6 +19,19 @@ use Illuminate\Support\Collection;
*/
class SingleCategoryRepository extends ComponentRepository implements SingleCategoryRepositoryInterface
{
/** @var User */
private $user;
/**
* BillRepository constructor.
*
* @param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* @param Category $category
*
@ -87,6 +101,23 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
return $return;
}
/**
* Find a category
*
* @param int $categoryId
*
* @return Category
*/
public function find(int $categoryId) : Category
{
$category = $this->user->categories()->find($categoryId);
if (is_null($category)) {
$category = new Category;
}
return $category;
}
/**
* @param Category $category
*
@ -122,6 +153,28 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
}
/**
* @param Category $category
* @param Collection $accounts
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getJournalsForAccountsInRange(Category $category, Collection $accounts, Carbon $start, Carbon $end)
{
$ids = $accounts->pluck('id')->toArray();
return $category->transactionjournals()
->after($start)
->before($end)
->expanded()
->whereIn('source_account.id', $ids)
->whereNotIn('destination_account.id', $ids)
->get(TransactionJournal::QUERYFIELDS);
}
/**
* @param Category $category
* @param int $page
@ -140,13 +193,9 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
->expanded()
->take(50)
->offset($offset)
->orderBy('transaction_journals.date', 'DESC')
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->get(TransactionJournal::QUERYFIELDS);
}
/**
* @param Category $category
*
@ -206,7 +255,7 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
*/
public function store(array $data)
{
$newCategory = new Category(
$newCategory = Category::firstOrCreateEncrypted(
[
'user_id' => $data['user'],
'name' => $data['name'],
@ -231,6 +280,4 @@ class SingleCategoryRepository extends ComponentRepository implements SingleCate
return $category;
}
}

View File

@ -14,6 +14,7 @@ use Illuminate\Support\Collection;
*/
interface SingleCategoryRepositoryInterface
{
/**
* @param Category $category
*
@ -54,6 +55,14 @@ interface SingleCategoryRepositoryInterface
*/
public function earnedPerDay(Category $category, Carbon $start, Carbon $end);
/**
* Find a category
*
* @param int $categoryId
*
* @return Category
*/
public function find(int $categoryId) : Category;
/**
* @param Category $category
@ -70,6 +79,16 @@ interface SingleCategoryRepositoryInterface
*/
public function getJournals(Category $category, $page);
/**
* @param Category $category
* @param Collection $accounts
*
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
public function getJournalsForAccountsInRange(Category $category, Collection $accounts, Carbon $start, Carbon $end);
/**
* @param Category $category

View File

@ -26,6 +26,75 @@ class CurrencyRepository implements CurrencyRepositoryInterface
return $currency->transactionJournals()->count();
}
/**
* Find by ID
*
* @param int $currencyId
*
* @return TransactionCurrency
*/
public function find(int $currencyId) : TransactionCurrency
{
$currency = TransactionCurrency::find($currencyId);
if (is_null($currency)) {
$currency = new TransactionCurrency;
}
return $currency;
}
/**
* Find by currency code
*
* @param string $currencyCode
*
* @return TransactionCurrency
*/
public function findByCode(string $currencyCode) : TransactionCurrency
{
$currency = TransactionCurrency::whereCode($currencyCode)->first();
if (is_null($currency)) {
$currency = new TransactionCurrency;
}
return $currency;
}
/**
* Find by currency name
*
* @param string $currencyName
*
* @return TransactionCurrency
*/
public function findByName(string $currencyName) : TransactionCurrency
{
$preferred = TransactionCurrency::whereName($currencyName)->first();
if (is_null($preferred)) {
$preferred = new TransactionCurrency;
}
return $preferred;
}
/**
* Find by currency symbol
*
* @param string $currencySymbol
*
* @return TransactionCurrency
*/
public function findBySymbol(string $currencySymbol) : TransactionCurrency
{
$currency = TransactionCurrency::whereSymbol($currencySymbol)->first();
if (is_null($currency)) {
$currency = new TransactionCurrency;
}
return $currency;
}
/**
* @return Collection
*/

View File

@ -15,7 +15,6 @@ use Illuminate\Support\Collection;
*/
interface CurrencyRepositoryInterface
{
/**
* @param TransactionCurrency $currency
*
@ -23,6 +22,42 @@ interface CurrencyRepositoryInterface
*/
public function countJournals(TransactionCurrency $currency);
/**
* Find by ID
*
* @param int $currencyId
*
* @return TransactionCurrency
*/
public function find(int $currencyId) : TransactionCurrency;
/**
* Find by currency code
*
* @param string $currencyCode
*
* @return TransactionCurrency
*/
public function findByCode(string $currencyCode) : TransactionCurrency;
/**
* Find by currency name
*
* @param string $currencyName
*
* @return TransactionCurrency
*/
public function findByName(string $currencyName) : TransactionCurrency;
/**
* Find by currency symbol
*
* @param string $currencySymbol
*
* @return TransactionCurrency
*/
public function findBySymbol(string $currencySymbol) : TransactionCurrency;
/**
* @return Collection
*/

View File

@ -2,7 +2,7 @@
declare(strict_types = 1);
/**
* ExportJobRepository.php
* Copyright (C) 2016 Sander Dorigo
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.

Some files were not shown because too many files have changed in this diff Show More