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 %}
{% if what == 'asset' %}{% if objectType == 'asset' %}{% 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('