diff --git a/app/Console/Commands/Upgrade/RenameAccountMeta.php b/app/Console/Commands/Upgrade/RenameAccountMeta.php
index a68f0cfcdb..1a184daeee 100644
--- a/app/Console/Commands/Upgrade/RenameAccountMeta.php
+++ b/app/Console/Commands/Upgrade/RenameAccountMeta.php
@@ -51,11 +51,13 @@ class RenameAccountMeta extends Command
public function handle(): int
{
$start = microtime(true);
+ // @codeCoverageIgnoreStart
if ($this->isExecuted() && true !== $this->option('force')) {
$this->warn('This command has already been executed.');
return 0;
}
+ // @codeCoverageIgnoreEnd
$array = [
'accountRole' => 'account_role',
'ccType' => 'cc_type',
diff --git a/app/Factory/AccountFactory.php b/app/Factory/AccountFactory.php
index e9fdcc5b9b..0c35036f02 100644
--- a/app/Factory/AccountFactory.php
+++ b/app/Factory/AccountFactory.php
@@ -27,7 +27,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\AccountServiceTrait;
use FireflyIII\User;
@@ -40,12 +39,13 @@ use Log;
*/
class AccountFactory
{
+ use AccountServiceTrait;
+
/** @var AccountRepositoryInterface */
protected $accountRepository;
/** @var User */
private $user;
- use AccountServiceTrait;
/** @var array */
private $canHaveVirtual;
@@ -223,27 +223,5 @@ class AccountFactory
}
- /**
- * @param int $currencyId
- * @param string $currencyCode
- * @return TransactionCurrency
- */
- protected function getCurrency(int $currencyId, string $currencyCode): TransactionCurrency
- {
- // find currency, or use default currency instead.
- /** @var TransactionCurrencyFactory $factory */
- $factory = app(TransactionCurrencyFactory::class);
- /** @var TransactionCurrency $currency */
- $currency = $factory->find($currencyId, $currencyCode);
-
- if (null === $currency) {
- // use default currency:
- $currency = app('amount')->getDefaultCurrencyByUser($this->user);
- }
- $currency->enabled = true;
- $currency->save();
-
- return $currency;
- }
}
diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php
index a123efe411..596385404a 100644
--- a/app/Helpers/Collector/GroupCollector.php
+++ b/app/Helpers/Collector/GroupCollector.php
@@ -121,6 +121,7 @@ class GroupCollector implements GroupCollectorInterface
'source.foreign_amount as foreign_amount',
'source.foreign_currency_id as foreign_currency_id',
'foreign_currency.code as foreign_currency_code',
+ 'foreign_currency.name as foreign_currency_name',
'foreign_currency.symbol as foreign_currency_symbol',
'foreign_currency.decimal_places as foreign_currency_decimal_places',
@@ -590,6 +591,7 @@ class GroupCollector implements GroupCollectorInterface
/**
* Return the sum of all journals.
+ * TODO ignores the currency.
*
* @return string
*/
diff --git a/app/Http/Controllers/Account/CreateController.php b/app/Http/Controllers/Account/CreateController.php
index 242e96d69f..37c1cf9f1f 100644
--- a/app/Http/Controllers/Account/CreateController.php
+++ b/app/Http/Controllers/Account/CreateController.php
@@ -28,6 +28,7 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\AccountFormRequest;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
+use FireflyIII\Support\Http\Controllers\ModelInformation;
use Illuminate\Http\Request;
use Log;
@@ -37,11 +38,13 @@ use Log;
*/
class CreateController extends Controller
{
+ use ModelInformation;
/** @var AccountRepositoryInterface The account repository */
private $repository;
/**
* CreateController constructor.
+ * @codeCoverageIgnore
*/
public function __construct()
{
@@ -122,11 +125,9 @@ class CreateController extends Controller
// update preferences if necessary:
$frontPage = app('preferences')->get('frontPageAccounts', [])->data;
- if (AccountType::ASSET === $account->accountType->type && count($frontPage) > 0) {
- // @codeCoverageIgnoreStart
+ if (AccountType::ASSET === $account->accountType->type) {
$frontPage[] = $account->id;
app('preferences')->set('frontPageAccounts', $frontPage);
- // @codeCoverageIgnoreEnd
}
// redirect to previous URL.
$redirect = redirect($this->getPreviousUri('accounts.create.uri'));
@@ -140,40 +141,6 @@ class CreateController extends Controller
return $redirect;
}
- /**
- * @codeCoverageIgnore
- * @return array
- */
- protected function getRoles(): array
- {
- $roles = [];
- foreach (config('firefly.accountRoles') as $role) {
- $roles[$role] = (string)trans(sprintf('firefly.account_role_%s', $role));
- }
- return $roles;
- }
-
- /**
- * @codeCoverageIgnore
- * @return array
- */
- protected function getLiabilityTypes(): array
- {
-
- // types of liability:
- $debt = $this->repository->getAccountTypeByType(AccountType::DEBT);
- $loan = $this->repository->getAccountTypeByType(AccountType::LOAN);
- $mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE);
- /** @noinspection NullPointerExceptionInspection */
- $liabilityTypes = [
- $debt->id => (string)trans(sprintf('firefly.account_type_%s', AccountType::DEBT)),
- $loan->id => (string)trans(sprintf('firefly.account_type_%s', AccountType::LOAN)),
- $mortgage->id => (string)trans(sprintf('firefly.account_type_%s', AccountType::MORTGAGE)),
- ];
- asort($liabilityTypes);
-
- return $liabilityTypes;
- }
}
diff --git a/app/Http/Controllers/Account/DeleteController.php b/app/Http/Controllers/Account/DeleteController.php
index 3ec08fe917..c997c4814e 100644
--- a/app/Http/Controllers/Account/DeleteController.php
+++ b/app/Http/Controllers/Account/DeleteController.php
@@ -39,6 +39,7 @@ class DeleteController extends Controller
/**
* DeleteController constructor.
+ * @codeCoverageIgnore
*/
public function __construct()
{
@@ -66,16 +67,16 @@ class DeleteController extends Controller
*/
public function delete(Account $account)
{
- $typeName = config('firefly.shortNamesByFullName.' . $account->accountType->type);
- $subTitle = (string)trans('firefly.delete_' . $typeName . '_account', ['name' => $account->name]);
+ $typeName = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
+ $subTitle = (string)trans(sprintf('firefly.delete_%s_account', $typeName), ['name' => $account->name]);
$accountList = app('expandedform')->makeSelectListWithEmpty($this->repository->getAccountsByType([$account->accountType->type]));
- $what = $typeName;
+ $objectType = $typeName;
unset($accountList[$account->id]);
// put previous url in session
$this->rememberPreviousUri('accounts.delete.uri');
- return view('accounts.delete', compact('account', 'subTitle', 'accountList', 'what'));
+ return view('accounts.delete', compact('account', 'subTitle', 'accountList', 'objectType'));
}
/**
@@ -89,13 +90,13 @@ class DeleteController extends Controller
public function destroy(Request $request, Account $account)
{
$type = $account->accountType->type;
- $typeName = config('firefly.shortNamesByFullName.' . $type);
+ $typeName = config(sprintf('firefly.shortNamesByFullName.%s', $type));
$name = $account->name;
$moveTo = $this->repository->findNull((int)$request->get('move_account_before_delete'));
$this->repository->destroy($account, $moveTo);
- $request->session()->flash('success', (string)trans('firefly.' . $typeName . '_deleted', ['name' => $name]));
+ $request->session()->flash('success', (string)trans(sprintf('firefly.%s_deleted', $typeName), ['name' => $name]));
app('preferences')->mark();
return redirect($this->getPreviousUri('accounts.delete.uri'));
diff --git a/app/Http/Controllers/Account/EditController.php b/app/Http/Controllers/Account/EditController.php
index d2927ab977..8b6b73321e 100644
--- a/app/Http/Controllers/Account/EditController.php
+++ b/app/Http/Controllers/Account/EditController.php
@@ -27,9 +27,9 @@ namespace FireflyIII\Http\Controllers\Account;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\AccountFormRequest;
use FireflyIII\Models\Account;
-use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Support\Http\Controllers\ModelInformation;
use Illuminate\Http\Request;
/**
@@ -38,6 +38,7 @@ use Illuminate\Http\Request;
*/
class EditController extends Controller
{
+ use ModelInformation;
/** @var CurrencyRepositoryInterface The currency repository */
private $currencyRepos;
/** @var AccountRepositoryInterface The account repository */
@@ -78,24 +79,11 @@ class EditController extends Controller
*/
public function edit(Request $request, Account $account, AccountRepositoryInterface $repository)
{
- $what = config('firefly.shortNamesByFullName')[$account->accountType->type];
- $subTitle = (string)trans('firefly.edit_' . $what . '_account', ['name' => $account->name]);
- $subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
- $roles = [];
- foreach (config('firefly.accountRoles') as $role) {
- $roles[$role] = (string)trans('firefly.account_role_' . $role);
- }
-
- // types of liability:
- $debt = $this->repository->getAccountTypeByType(AccountType::DEBT);
- $loan = $this->repository->getAccountTypeByType(AccountType::LOAN);
- $mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE);
- $liabilityTypes = [
- $debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT),
- $loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN),
- $mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE),
- ];
- asort($liabilityTypes);
+ $objectType = config('firefly.shortNamesByFullName')[$account->accountType->type];
+ $subTitle = (string)trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
+ $roles = $this->getRoles();
+ $liabilityTypes = $this->getLiabilityTypes();
// interest calculation periods:
$interestPeriods = [
@@ -146,7 +134,7 @@ class EditController extends Controller
$request->session()->flash('preFilled', $preFilled);
return view(
- 'accounts.edit', compact('account', 'currency', 'subTitle', 'subTitleIcon', 'what', 'roles', 'preFilled', 'liabilityTypes', 'interestPeriods')
+ 'accounts.edit', compact('account', 'currency', 'subTitle', 'subTitleIcon', 'objectType', 'roles', 'preFilled', 'liabilityTypes', 'interestPeriods')
);
}
diff --git a/app/Http/Controllers/Account/IndexController.php b/app/Http/Controllers/Account/IndexController.php
index 1e49e808e0..36f0b0e8b3 100644
--- a/app/Http/Controllers/Account/IndexController.php
+++ b/app/Http/Controllers/Account/IndexController.php
@@ -43,6 +43,7 @@ class IndexController extends Controller
/**
* IndexController constructor.
+ * @codeCoverageIgnore
*/
public function __construct()
{
@@ -65,16 +66,16 @@ class IndexController extends Controller
* Show list of accounts.
*
* @param Request $request
- * @param string $what
+ * @param string $objectType
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
- public function index(Request $request, string $what)
+ public function index(Request $request, string $objectType)
{
- $what = $what ?? 'asset';
- $subTitle = (string)trans('firefly.' . $what . '_accounts');
- $subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
- $types = config('firefly.accountTypesByIdentifier.' . $what);
+ $objectType = $objectType ?? 'asset';
+ $subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType));
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
+ $types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
$collection = $this->repository->getAccountsByType($types);
$total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
@@ -99,16 +100,16 @@ class IndexController extends Controller
$account->endBalance = $this->isInArray($endBalances, $account->id);
$account->difference = bcsub($account->endBalance, $account->startBalance);
$account->interest = round($this->repository->getMetaValue($account, 'interest'), 6);
- $account->interestPeriod = (string)trans('firefly.interest_calc_' . $this->repository->getMetaValue($account, 'interest_period'));
- $account->accountTypeString = (string)trans('firefly.account_type_' . $account->accountType->type);
+ $account->interestPeriod = (string)trans(sprintf('firefly.interest_calc_%s', $this->repository->getMetaValue($account, 'interest_period')));
+ $account->accountTypeString = (string)trans(sprintf('firefly.account_type_%s', $account->accountType->type));
}
);
// make paginator:
$accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
- $accounts->setPath(route('accounts.index', [$what]));
+ $accounts->setPath(route('accounts.index', [$objectType]));
- return view('accounts.index', compact('what', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
+ return view('accounts.index', compact('objectType', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
}
diff --git a/app/Http/Requests/AccountFormRequest.php b/app/Http/Requests/AccountFormRequest.php
index 95fe5c0992..6f40068d08 100644
--- a/app/Http/Requests/AccountFormRequest.php
+++ b/app/Http/Requests/AccountFormRequest.php
@@ -111,8 +111,7 @@ class AccountFormRequest extends Request
'interest_period' => 'in:daily,monthly,yearly',
];
- // TODO verify if this will work.
- if ('liabilities' === $this->get('what')) {
+ if ('liabilities' === $this->get('objectType')) {
$rules['opening_balance'] = ['numeric', 'required'];
$rules['opening_balance_date'] = 'date|required';
}
diff --git a/app/Services/Internal/Support/AccountServiceTrait.php b/app/Services/Internal/Support/AccountServiceTrait.php
index 0e20dfda60..65b0c64338 100644
--- a/app/Services/Internal/Support/AccountServiceTrait.php
+++ b/app/Services/Internal/Support/AccountServiceTrait.php
@@ -26,11 +26,15 @@ namespace FireflyIII\Services\Internal\Support;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountMetaFactory;
+use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Factory\TransactionGroupFactory;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Note;
+use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
+use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
use Log;
@@ -75,6 +79,32 @@ trait AccountServiceTrait
return $iban;
}
+ /**
+ * Update meta data for account. Depends on type which fields are valid.
+ *
+ * TODO this method treats expense accounts and liabilities the same way (tries to save interest)
+ *
+ * @param Account $account
+ * @param array $data
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ */
+ public function updateMetaData(Account $account, array $data): void
+ {
+ $fields = $this->validFields;
+
+ if ($account->accountType->type === AccountType::ASSET) {
+ $fields = $this->validAssetFields;
+ }
+ if ($account->accountType->type === AccountType::ASSET && 'ccAsset' === $data['account_role']) {
+ $fields = $this->validCCFields;
+ }
+ /** @var AccountMetaFactory $factory */
+ $factory = app(AccountMetaFactory::class);
+ foreach ($fields as $field) {
+ $factory->crud($account, $field, (string)($data[$field] ?? ''));
+ }
+ }
+
// /**
// * @param User $user
// * @param string $name
@@ -126,29 +156,34 @@ trait AccountServiceTrait
// }
/**
- * Update meta data for account. Depends on type which fields are valid.
- *
- * TODO this method treats expense accounts and liabilities the same way (tries to save interest)
- *
* @param Account $account
- * @param array $data
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @param string $note
+ *
+ * @return bool
*/
- public function updateMetaData(Account $account, array $data): void
+ public function updateNote(Account $account, string $note): bool
{
- $fields = $this->validFields;
+ if ('' === $note) {
+ $dbNote = $account->notes()->first();
+ if (null !== $dbNote) {
+ try {
+ $dbNote->delete();
+ } catch (Exception $e) {
+ Log::debug($e->getMessage());
+ }
+ }
- if ($account->accountType->type === AccountType::ASSET) {
- $fields = $this->validAssetFields;
+ return true;
}
- if ($account->accountType->type === AccountType::ASSET && 'ccAsset' === $data['account_role']) {
- $fields = $this->validCCFields;
- }
- /** @var AccountMetaFactory $factory */
- $factory = app(AccountMetaFactory::class);
- foreach ($fields as $field) {
- $factory->crud($account, $field, (string)($data[$field] ?? ''));
+ $dbNote = $account->notes()->first();
+ if (null === $dbNote) {
+ $dbNote = new Note;
+ $dbNote->noteable()->associate($account);
}
+ $dbNote->text = trim($note);
+ $dbNote->save();
+
+ return true;
}
// /**
@@ -262,37 +297,6 @@ trait AccountServiceTrait
// return $journal;
// }
- /**
- * @param Account $account
- * @param string $note
- *
- * @return bool
- */
- public function updateNote(Account $account, string $note): bool
- {
- if ('' === $note) {
- $dbNote = $account->notes()->first();
- if (null !== $dbNote) {
- try {
- $dbNote->delete();
- } catch (Exception $e) {
- Log::debug($e->getMessage());
- }
- }
-
- return true;
- }
- $dbNote = $account->notes()->first();
- if (null === $dbNote) {
- $dbNote = new Note;
- $dbNote->noteable()->associate($account);
- }
- $dbNote->text = trim($note);
- $dbNote->save();
-
- return true;
- }
-
/**
* Verify if array contains valid data to possibly store or update the opening balance.
*
@@ -313,6 +317,29 @@ trait AccountServiceTrait
return false;
}
+ /**
+ * @param int $currencyId
+ * @param string $currencyCode
+ * @return TransactionCurrency
+ */
+ protected function getCurrency(int $currencyId, string $currencyCode): TransactionCurrency
+ {
+ // find currency, or use default currency instead.
+ /** @var TransactionCurrencyFactory $factory */
+ $factory = app(TransactionCurrencyFactory::class);
+ /** @var TransactionCurrency $currency */
+ $currency = $factory->find($currencyId, $currencyCode);
+
+ if (null === $currency) {
+ // use default currency:
+ $currency = app('amount')->getDefaultCurrencyByUser($this->user);
+ }
+ $currency->enabled = true;
+ $currency->save();
+
+ return $currency;
+ }
+
// /**
// * @param Account $account
// * @param TransactionJournal $journal
@@ -446,6 +473,7 @@ trait AccountServiceTrait
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
}
+
// @codeCoverageIgnoreEnd
return $group;
@@ -462,12 +490,46 @@ trait AccountServiceTrait
*/
protected function updateOBGroup(Account $account, array $data): ?TransactionGroup
{
- if (null === $this->getOBGroup($account)) {
+ $obGroup = $this->getOBGroup($account);
+ if (null === $obGroup) {
return $this->createOBGroup($account, $data);
}
+ /** @var TransactionJournal $journal */
+ $journal = $obGroup->transactionJournals()->first();
+ $journal->date = $data['opening_balance_date'] ?? $journal->date;
+ $journal->transaction_currency_id = $data['currency_id'];
- // edit in this method
- die('cannot handle edit');
+ /** @var Transaction $obTransaction */
+ $obTransaction = $journal->transactions()->where('account_id', '!=', $account->id)->first();
+ /** @var Transaction $accountTransaction */
+ $accountTransaction = $journal->transactions()->where('account_id', $account->id)->first();
+
+ // if amount is negative:
+ if (1 === bccomp('0', $data['opening_balance'])) {
+ // account transaction loses money:
+ $accountTransaction->amount = app('steam')->negative($data['opening_balance']);
+ $accountTransaction->transaction_currency_id = $data['currency_id'];
+
+ // OB account transaction gains money
+ $obTransaction->amount = app('steam')->positive($data['opening_balance']);
+ $obTransaction->transaction_currency_id = $data['currency_id'];
+ }
+ if (-1 === bccomp('0', $data['opening_balance'])) {
+ // account gains money:
+ $accountTransaction->amount = app('steam')->positive($data['opening_balance']);
+ $accountTransaction->transaction_currency_id = $data['currency_id'];
+
+ // OB account loses money:
+ $obTransaction->amount = app('steam')->negative($data['opening_balance']);
+ $obTransaction->transaction_currency_id = $data['currency_id'];
+ }
+ // save both
+ $accountTransaction->save();
+ $obTransaction->save();
+ $journal->save();
+ $obGroup->refresh();
+
+ return $obGroup;
}
/**
diff --git a/app/Services/Internal/Update/AccountUpdateService.php b/app/Services/Internal/Update/AccountUpdateService.php
index f614f5fd52..a593b1457d 100644
--- a/app/Services/Internal/Update/AccountUpdateService.php
+++ b/app/Services/Internal/Update/AccountUpdateService.php
@@ -25,7 +25,9 @@ namespace FireflyIII\Services\Internal\Update;
use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Models\Account;
+use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\AccountServiceTrait;
use Log;
@@ -36,6 +38,11 @@ class AccountUpdateService
{
use AccountServiceTrait;
+ /** @var array */
+ private $canHaveVirtual;
+ /** @var AccountRepositoryInterface */
+ protected $accountRepository;
+
/**
* Constructor.
*/
@@ -44,6 +51,9 @@ class AccountUpdateService
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this)));
}
+ // TODO move to configuration.
+ $this->canHaveVirtual = [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
+ $this->accountRepository = app(AccountRepositoryInterface::class);
}
/**
@@ -53,12 +63,11 @@ class AccountUpdateService
* @param array $data
*
* @return Account
- * @throws \FireflyIII\Exceptions\FireflyException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function update(Account $account, array $data): Account
{
+ $this->accountRepository->setUser($account->user);
+
// update the account itself:
$account->name = $data['name'];
$account->active = $data['active'];
@@ -69,32 +78,26 @@ class AccountUpdateService
if (isset($data['currency_id']) && 0 === $data['currency_id']) {
unset($data['currency_id']);
}
- // find currency, or use default currency instead.
- /** @var TransactionCurrencyFactory $factory */
- $factory = app(TransactionCurrencyFactory::class);
- /** @var TransactionCurrency $currency */
- $currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null);
- if (null === $currency) {
- // use default currency:
- $currency = app('amount')->getDefaultCurrencyByUser($account->user);
- }
- $currency->enabled = true;
- $currency->save();
+ // find currency, or use default currency instead.
+ $currency = $this->getCurrency((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null));
+ unset($data['currency_code']);
$data['currency_id'] = $currency->id;
+
// update all meta data:
$this->updateMetaData($account, $data);
// has valid initial balance (IB) data?
- if ($this->validOBData($data)) {
- // then do update!
- $this->updateIB($account, $data);
- }
-
- // if not, delete it when exist.
- if (!$this->validOBData($data)) {
- $this->deleteIB($account);
+ $type = $account->accountType;
+ // if it can have a virtual balance, it can also have an opening balance.
+ if (in_array($type->type, $this->canHaveVirtual, true)) {
+ if ($this->validOBData($data)) {
+ $this->updateOBGroup($account, $data);
+ }
+ if (!$this->validOBData($data)) {
+ $this->deleteOBGroup($account);
+ }
}
// update note:
diff --git a/resources/views/v1/accounts/edit.twig b/resources/views/v1/accounts/edit.twig
index 1d2da47fd7..97f24244eb 100644
--- a/resources/views/v1/accounts/edit.twig
+++ b/resources/views/v1/accounts/edit.twig
@@ -8,7 +8,7 @@
{{ Form.model(account, {'class' : 'form-horizontal','id' : 'update','url' : route('accounts.update',account.id) } ) }}
-
+
@@ -18,11 +18,11 @@
{{ ExpandedForm.text('name') }}
- {% if account.accountType.type == 'Default account' or account.accountType.type == 'Asset account' or what == 'liabilities' %}
+ {% if account.accountType.type == 'Default account' or account.accountType.type == 'Asset account' or objectType == 'liabilities' %}
{{ ExpandedForm.currencyList('currency_id', null, {helpText:'account_default_currency'|_}) }}
{% endif %}
- {% if what == 'liabilities' %}
+ {% if objectType == 'liabilities' %}
{{ ExpandedForm.select('liability_type_id', liabilityTypes) }}
{{ ExpandedForm.amountNoCurrency('opening_balance', null, {label:'debt_start_amount'|_, helpText: 'debt_start_amount_help'|_}) }}
{{ ExpandedForm.date('opening_balance_date', null, {label:'debt_start_date'|_}) }}
@@ -90,7 +90,7 @@
diff --git a/resources/views/v1/accounts/index.twig b/resources/views/v1/accounts/index.twig
index 38e9c30618..2a133a2553 100644
--- a/resources/views/v1/accounts/index.twig
+++ b/resources/views/v1/accounts/index.twig
@@ -1,14 +1,14 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
- {{ Breadcrumbs.render(Route.getCurrentRoute.getName, what) }}
+ {{ Breadcrumbs.render(Route.getCurrentRoute.getName, objectType) }}
{% endblock %}
{% block content %}
{% if accounts.count > 0 %}
-
{% endif %}
{% if accounts.count == 0 and page == 1 %}
- {% include 'partials.empty' with {what: what, type: 'accounts',route: route('accounts.create', [what])} %}
+ {% include 'partials.empty' with {objectType: objectType, type: 'accounts',route: route('accounts.create', [objectType])} %}
{% endif %}
{% endblock %}
@@ -52,7 +52,7 @@
{% block scripts %}
{% endblock %}
diff --git a/resources/views/v1/list/accounts.twig b/resources/views/v1/list/accounts.twig
index c7b0b7a4a2..f1c5c3a814 100644
--- a/resources/views/v1/list/accounts.twig
+++ b/resources/views/v1/list/accounts.twig
@@ -6,10 +6,10 @@
{{ trans('list.name') }}
- {% if what == 'asset' %}
+ {% if objectType == 'asset' %}
{{ trans('list.role') }}
{% endif %}
- {% if what == 'liabilities' %}
+ {% if objectType == 'liabilities' %}
{{ trans('list.liability_type') }}
{{ trans('list.interest') }} ({{ trans('list.interest_period') }})
{% endif %}
@@ -17,7 +17,7 @@
{{ trans('list.currentBalance') }}
{{ trans('list.active') }}
{# hide last activity to make room for other stuff #}
- {% if what != 'liabilities' %}
+ {% if objectType != 'liabilities' %}
{{ trans('list.lastActivity') }}
{% endif %}
{{ account.name }}
- {% if what == "asset" %}
+ {% if objectType == "asset" %}
{% for entry in account.accountmeta %}
{% if entry.name == 'account_role' %}
@@ -47,7 +47,7 @@
{% endfor %}
{% endif %}
- {% if what == 'liabilities' %}
+ {% if objectType == 'liabilities' %}
{{ account.accountTypeString }}
{{ account.interest }}% ({{ account.interestPeriod|lower }})
@@ -67,7 +67,7 @@
{% endif %}
{# hide last activity to make room for other stuff #}
- {% if what != 'liabilities' %}
+ {% if objectType != 'liabilities' %}
{% if account.lastActivityDate %}
{{ account.lastActivityDate.formatLocalized(monthAndDayFormat) }}
diff --git a/tests/Feature/Controllers/Account/CreateControllerTest.php b/tests/Feature/Controllers/Account/CreateControllerTest.php
index c2f4ccbebc..7081d3604c 100644
--- a/tests/Feature/Controllers/Account/CreateControllerTest.php
+++ b/tests/Feature/Controllers/Account/CreateControllerTest.php
@@ -24,8 +24,9 @@ declare(strict_types=1);
namespace Tests\Feature\Controllers\Account;
-use FireflyIII\Models\Account;
+use Amount;
use FireflyIII\Models\AccountType;
+use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
@@ -39,7 +40,10 @@ use Tests\TestCase;
/**
*
- * Class CreateControllerTest
+ * Class CreateControllerTest.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class CreateControllerTest extends TestCase
{
@@ -63,12 +67,24 @@ class CreateControllerTest extends TestCase
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$repository = $this->mock(CurrencyRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
+ $euro = $this->getEuro();
$repository->shouldReceive('get')->andReturn(new Collection);
+
+ // used for session range.
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
+ // mock default calls to Preferences:
+ $this->mockDefaultPreferences();
+ $this->mockIntroPreference('shown_demo_accounts_create_asset');
+
+ // mock default calls to Configuration:
+ $this->mockDefaultConfiguration();
+
// get all types:
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
@@ -91,23 +107,40 @@ class CreateControllerTest extends TestCase
// mock stuff
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
-
- $repository->shouldReceive('store')->once()->andReturn(factory(Account::class)->make());
+ $asset = $this->getRandomAsset();
+ $euro = $this->getEuro();
+ $repository->shouldReceive('store')->once()->andReturn($asset);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
- // change the preference:
- Preferences::setForUser($this->user(), 'frontPageAccounts', [1]);
+ // mock default calls to Configuration:
+ $this->mockDefaultConfiguration();
- $this->session(['accounts.create.uri' => 'http://localhost']);
+ // change the preference:
+ $emptyPref = new Preference;
+ $emptyPref->data = [];
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['frontPageAccounts', []])->andReturn($emptyPref);
+ Preferences::shouldReceive('set')->atLeast()->once()->withArgs(['frontPageAccounts', [$asset->id]]);
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
+
+ Preferences::shouldReceive('mark')->atLeast()->once()->withNoArgs();
+
+ // mock default calls to Preferences:
+ $this->mockDefaultPreferences();
+
+
+
+ $this->session(['accounts.create.uri' => 'http://localhost/x']);
$this->be($this->user());
$data = [
- 'name' => 'new account ' . $this->randomInt(),
- 'what' => 'asset',
+ 'name' => 'new account ' . $this->randomInt(),
+ 'objectType' => 'asset',
];
$response = $this->post(route('accounts.store', ['asset']), $data);
$response->assertStatus(302);
$response->assertSessionHas('success');
+ $response->assertRedirect('http://localhost/x');
}
/**
@@ -120,21 +153,44 @@ class CreateControllerTest extends TestCase
// mock stuff
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
+ $asset = $this->getRandomAsset();
+ $euro = $this->getEuro();
- $repository->shouldReceive('store')->once()->andReturn(factory(Account::class)->make());
+ $repository->shouldReceive('store')->once()->andReturn($asset);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+ // change the preference:
+ $emptyPref = new Preference;
+ $emptyPref->data = [];
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['frontPageAccounts', []])->andReturn($emptyPref);
+ Preferences::shouldReceive('set')->atLeast()->once()->withArgs(['frontPageAccounts', [$asset->id]]);
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
+
+ // mock default calls to Preferences:
+ $this->mockDefaultPreferences();
+ //$this->mockIntroPreference('shown_demo_accounts_create_asset');
+
+ // mock default calls to Configuration:
+ $this->mockDefaultConfiguration();
+
+
+
+ Preferences::shouldReceive('mark')->atLeast()->once()->withNoArgs();
+
$this->session(['accounts.create.uri' => 'http://localhost']);
$this->be($this->user());
$data = [
'name' => 'new account ' . $this->randomInt(),
- 'what' => 'asset',
+ 'objectType' => 'asset',
'create_another' => 1,
];
+
$response = $this->post(route('accounts.store', ['asset']), $data);
$response->assertStatus(302);
$response->assertSessionHas('success');
+ $response->assertRedirect('http://localhost/accounts/create/asset');
}
/**
@@ -147,21 +203,36 @@ class CreateControllerTest extends TestCase
// mock stuff
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
-
- $repository->shouldReceive('store')->once()->andReturn(factory(Account::class)->make());
+ $liability = $this->getRandomLoan();
+ $loan = AccountType::where('type', AccountType::LOAN)->first();
+ $euro = $this->getEuro();
+ $repository->shouldReceive('store')->once()->andReturn($liability);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
// change the preference:
- Preferences::setForUser($this->user(), 'frontPageAccounts', [1]);
+ $emptyPref = new Preference;
+ $emptyPref->data = [];
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['frontPageAccounts', []])->andReturn($emptyPref);
+
+ // mock default calls to Preferences:
+ $this->mockDefaultPreferences();
+ //$this->mockIntroPreference('shown_demo_accounts_create_asset');
+
+ // mock default calls to Configuration:
+ $this->mockDefaultConfiguration();
+
+ Preferences::shouldReceive('mark')->atLeast()->once()->withNoArgs();
$this->session(['accounts.create.uri' => 'http://localhost']);
$this->be($this->user());
$data = [
- 'name' => 'new liability account ' . $this->randomInt(),
- 'what' => 'liabilities',
- 'liability_type_id' => AccountType::where('type', AccountType::LOAN)->first()->id,
- 'openingBalance' => '100',
- 'openingBalanceDate' => '2018-01-01',
+ 'name' => 'new liability account ' . $this->randomInt(),
+ 'objectType' => 'liabilities',
+ 'liability_type_id' => $loan->id,
+ 'opening_balance' => '-100',
+ 'opening_balance_date' => '2018-01-01',
];
$response = $this->post(route('accounts.store', ['liabilities']), $data);
diff --git a/tests/Feature/Controllers/Account/DeleteControllerTest.php b/tests/Feature/Controllers/Account/DeleteControllerTest.php
index a2e4dec6bb..c306f3693f 100644
--- a/tests/Feature/Controllers/Account/DeleteControllerTest.php
+++ b/tests/Feature/Controllers/Account/DeleteControllerTest.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace Tests\Feature\Controllers\Account;
+use Amount;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
@@ -33,10 +34,15 @@ use Illuminate\Support\Collection;
use Log;
use Mockery;
use Tests\TestCase;
+use Preferences;
+
/**
*
* Class DeleteControllerTest
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class DeleteControllerTest extends TestCase
{
@@ -59,15 +65,25 @@ class DeleteControllerTest extends TestCase
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
+ $asset = $this->getRandomAsset();
$repository->shouldReceive('getAccountsByType')->withArgs([[AccountType::ASSET]])->andReturn(new Collection);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
+ // mock Amount
+ $euro = $this->getEuro();
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
$this->be($this->user());
- $account = $this->user()->accounts()->where('account_type_id', 3)->whereNull('deleted_at')->first();
- $response = $this->get(route('accounts.delete', [$account->id]));
+ $response = $this->get(route('accounts.delete', [$asset->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('');
@@ -82,15 +98,27 @@ class DeleteControllerTest extends TestCase
// mock stuff
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$repository = $this->mock(AccountRepositoryInterface::class);
+ $asset = $this->getRandomAsset();
+ $euro = $this->getEuro();
$repository->shouldReceive('findNull')->withArgs([0])->once()->andReturn(null);
$repository->shouldReceive('destroy')->andReturn(true);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
+ Preferences::shouldReceive('mark')->atLeast()->once();
+
+ // mock Amount
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
$this->session(['accounts.delete.uri' => 'http://localhost/accounts/show/1']);
- $account = $this->user()->accounts()->where('account_type_id', 3)->whereNull('deleted_at')->first();
$this->be($this->user());
- $response = $this->post(route('accounts.destroy', [$account->id]));
+ $response = $this->post(route('accounts.destroy', [$asset->id]));
$response->assertStatus(302);
$response->assertSessionHas('success');
}
diff --git a/tests/Feature/Controllers/Account/EditControllerTest.php b/tests/Feature/Controllers/Account/EditControllerTest.php
index 9282b583ec..3de317bf0e 100644
--- a/tests/Feature/Controllers/Account/EditControllerTest.php
+++ b/tests/Feature/Controllers/Account/EditControllerTest.php
@@ -35,11 +35,15 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Support\Collection;
use Log;
use Mockery;
+use Preferences;
use Tests\TestCase;
/**
*
* Class EditControllerTest
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class EditControllerTest extends TestCase
{
@@ -54,6 +58,7 @@ class EditControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Account\EditController
+ * @covers \FireflyIII\Http\Requests\AccountFormRequest
*/
public function testEdit(): void
{
@@ -61,36 +66,47 @@ class EditControllerTest extends TestCase
$repository = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
+ $asset = $this->getRandomAsset();
+ $euro = $this->getEuro();
- $repository->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::find(1))->atLeast()->once();
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
+ // mock preferences:
+ $this->mockDefaultPreferences();
+
+ $repository->shouldReceive('findNull')->withArgs([1])->andReturn($euro)->atLeast()->once();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
- $repository->shouldReceive('get')->andReturn(new Collection);
+ $repository->shouldReceive('get')->andReturn(new Collection)->atLeast()->once();
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$accountRepos->shouldReceive('getNoteText')->andReturn('Some text')->once();
- $accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull();
- $accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull();
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('123');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccType'])->andReturn('');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccMonthlyPaymentDate'])->andReturn('');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
+ $accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull()->atLeast()->once();
+ $accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull()->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_number'])->andReturn('123')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_role'])->andReturn('defaultAsset')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_type'])->andReturn('')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_monthly_payment_date'])->andReturn('')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1')->atLeast()->once();
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly')->atLeast()->once();
// get all types:
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
+ // mock calls to Preferences:
+ //$this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
$this->be($this->user());
- $account = $this->user()->accounts()->where('account_type_id', 3)->whereNull('deleted_at')->first();
- $response = $this->get(route('accounts.edit', [$account->id]));
+ $response = $this->get(route('accounts.edit', [$asset->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('');
@@ -99,6 +115,7 @@ class EditControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Account\EditController
+ * @covers \FireflyIII\Http\Requests\AccountFormRequest
*/
public function testEditLiability(): void
{
@@ -106,22 +123,23 @@ class EditControllerTest extends TestCase
$repository = $this->mock(CurrencyRepositoryInterface::class);
$accountRepos = $this->mock(AccountRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
-
+ $euro = $this->getEuro();
+ $loan = $this->getRandomLoan();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
- $repository->shouldReceive('findNull')->once()->andReturn(TransactionCurrency::find(1));
+ $repository->shouldReceive('findNull')->once()->andReturn($euro);
$repository->shouldReceive('get')->andReturn(new Collection);
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
$accountRepos->shouldReceive('getNoteText')->andReturn('Some text')->once();
$accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull();
$accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('123');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccType'])->andReturn('');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_number'])->andReturn('123');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_role'])->andReturn('defaultAsset');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_type'])->andReturn('');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccMonthlyPaymentDate'])->andReturn('');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_monthly_payment_date'])->andReturn('');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
@@ -131,10 +149,19 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
+ // mock Amount
+ $euro = $this->getEuro();
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
$this->be($this->user());
- $account = $this->user()->accounts()->where('account_type_id', 12)->whereNull('deleted_at')->first();
- $response = $this->get(route('accounts.edit', [$account->id]));
+ $response = $this->get(route('accounts.edit', [$loan->id]));
$response->assertStatus(200);
// has bread crumb
$response->assertSee('');
@@ -143,6 +170,7 @@ class EditControllerTest extends TestCase
/**
* @covers \FireflyIII\Http\Controllers\Account\EditController
+ * @covers \FireflyIII\Http\Requests\AccountFormRequest
*/
public function testEditNull(): void
{
@@ -163,15 +191,21 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getOpeningBalanceAmount')->andReturnNull();
$accountRepos->shouldReceive('getOpeningBalanceDate')->andReturnNull();
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('123');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountRole'])->andReturn('defaultAsset');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccType'])->andReturn('');
- $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'ccMonthlyPaymentDate'])->andReturn('');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_number'])->andReturn('123');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_role'])->andReturn('defaultAsset');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_type'])->andReturn('');
+ $accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'cc_monthly_payment_date'])->andReturn('');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'include_net_worth'])->andReturn('1');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'BIC'])->andReturn('BIC');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
$accountRepos->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
// get all types:
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
@@ -195,13 +229,18 @@ class EditControllerTest extends TestCase
public function testUpdate(): void
{
// mock stuff
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $repository = $this->mock(AccountRepositoryInterface::class);
- $currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
+ $journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $repository = $this->mock(AccountRepositoryInterface::class);
+ $this->mock(CurrencyRepositoryInterface::class);
$repository->shouldReceive('update')->once();
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
+
+ $euro = $this->getEuro();
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+ Preferences::shouldReceive('mark')->atLeast()->once();
+
$this->session(['accounts.edit.uri' => 'http://localhost/javascript/account']);
$this->be($this->user());
$data = [
@@ -210,6 +249,12 @@ class EditControllerTest extends TestCase
'what' => 'asset',
];
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
$response = $this->post(route('accounts.update', [1]), $data);
$response->assertStatus(302);
$response->assertSessionHas('success');
@@ -223,9 +268,9 @@ class EditControllerTest extends TestCase
public function testUpdateAgain(): void
{
// mock stuff
- $journalRepos = $this->mock(JournalRepositoryInterface::class);
- $repository = $this->mock(AccountRepositoryInterface::class);
- $currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
+ $journalRepos = $this->mock(JournalRepositoryInterface::class);
+ $repository = $this->mock(AccountRepositoryInterface::class);
+ $this->mock(CurrencyRepositoryInterface::class);
$repository->shouldReceive('update')->once();
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
@@ -238,6 +283,16 @@ class EditControllerTest extends TestCase
'return_to_edit' => '1',
];
+ $euro = $this->getEuro();
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+ Preferences::shouldReceive('mark')->atLeast()->once();
+
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
$response = $this->post(route('accounts.update', [1]), $data);
$response->assertStatus(302);
$response->assertSessionHas('success');
diff --git a/tests/Feature/Controllers/Account/IndexControllerTest.php b/tests/Feature/Controllers/Account/IndexControllerTest.php
index a94f0a4244..f2192d6453 100644
--- a/tests/Feature/Controllers/Account/IndexControllerTest.php
+++ b/tests/Feature/Controllers/Account/IndexControllerTest.php
@@ -22,8 +22,8 @@ declare(strict_types=1);
namespace Tests\Feature\Controllers\Account;
-use FireflyIII\Models\Account;
-use FireflyIII\Models\TransactionCurrency;
+use Amount;
+use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
@@ -32,13 +32,14 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Support\Collection;
use Log;
use Mockery;
+use Preferences;
use Steam;
use Tests\TestCase;
+
/**
* Class IndexControllerTest
*
- * @SuppressWarnings(PHPMD.TooManyPublicMethods)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
@@ -64,26 +65,40 @@ class IndexControllerTest extends TestCase
public function testIndex(string $range): void
{
// mock stuff
- $account = factory(Account::class)->make();
+ $account = $this->getRandomAsset();
$repository = $this->mock(AccountRepositoryInterface::class);
$journalRepos = $this->mock(JournalRepositoryInterface::class);
$currencyRepos = $this->mock(CurrencyRepositoryInterface::class);
$userRepos = $this->mock(UserRepositoryInterface::class);
-
+ $euro = $this->getEuro();
// mock hasRole for user repository:
$userRepos->shouldReceive('hasRole')->withArgs([Mockery::any(), 'owner'])->andReturn(true)->atLeast()->once();
$repository->shouldReceive('getAccountsByType')->andReturn(new Collection([$account]));
$repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'currency_id'])->andReturn('1');
$journalRepos->shouldReceive('firstNull')->once()->andReturn(new TransactionJournal);
- $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn(TransactionCurrency::find(1));
+ $currencyRepos->shouldReceive('findNull')->withArgs([1])->andReturn($euro);
Steam::shouldReceive('balancesByAccounts')->andReturn([$account->id => '100']);
Steam::shouldReceive('getLastActivities')->andReturn([]);
+
+ // mock calls to Preferences:
+ $this->mockDefaultPreferences();
+
+ // mock calls to Configuration:
+ $this->mockDefaultConfiguration();
+
+ // list size
+ $pref = new Preference;
+ $pref->data = 50;
+ Preferences::shouldReceive('get')->withArgs(['listPageSize', 50])->atLeast()->once()->andReturn($pref);
+
+ Amount::shouldReceive('formatAnything')->andReturn('123');
+ Amount::shouldReceive('getDefaultCurrency')->atLeast()->once()->andReturn($euro);
+
$repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest'])->andReturn('1');
$repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'interest_period'])->andReturn('monthly');
-
- $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'accountNumber'])->andReturn('123');
+ $repository->shouldReceive('getMetaValue')->withArgs([Mockery::any(), 'account_number'])->andReturn('123');
$this->be($this->user());
$this->changeDateRange($this->user(), $range);
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 0891a8db9e..2399c348ba 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -27,11 +27,13 @@ use Carbon\Carbon;
use Closure;
use DB;
use Exception;
+use FireflyConfig;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Budget;
+use FireflyIII\Models\Configuration;
use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
@@ -42,6 +44,7 @@ use FireflyIII\User;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Log;
use Mockery;
+use Preferences;
use RuntimeException;
/**
@@ -51,6 +54,56 @@ use RuntimeException;
*/
abstract class TestCase extends BaseTestCase
{
+ /**
+ * Mock the Preferences call that checks if the user has seen the introduction popups already.
+ *
+ * @param string $key
+ */
+ public function mockIntroPreference(string $key): void
+ {
+ $true = new Preference;
+ $true->data = true;
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs([$key, false])->andReturn($true);
+ }
+
+ /**
+ * Mock the call that checks for the users last activity (for caching).
+ */
+ public function mockLastActivity(): void
+ {
+ Preferences::shouldReceive('lastActivity')->withNoArgs()->atLeast()->once()->andReturn('md512345');
+ }
+
+ public function mockDefaultConfiguration(): void
+ {
+
+ $falseConfig = new Configuration;
+ $falseConfig->data = false;
+
+ FireflyConfig::shouldReceive('get')->withArgs(['is_demo_site', false])->once()->andReturn($falseConfig);
+ }
+
+ /**
+ * Mock default preferences.
+ */
+ public function mockDefaultPreferences(): void
+ {
+ $false = new Preference;
+ $false->data = false;
+ $view = new Preference;
+ $view->data = '1M';
+ $lang = new Preference;
+ $lang->data = 'en_US';
+ $list = new Preference;
+ $list->data = 50;
+
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['twoFactorAuthEnabled', false])->andReturn($false);
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['twoFactorAuthSecret'])->andReturnNull();
+ Preferences::shouldReceive('get')->withArgs(['viewRange', Mockery::any()])->andReturn($view);
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['language', 'en_US'])->andReturn($lang);
+ Preferences::shouldReceive('get')->atLeast()->once()->withArgs(['list-length', 10])->andReturn($list);
+ }
+
/**
* @return int
*/