diff --git a/app/Http/Controllers/Account/EditController.php b/app/Http/Controllers/Account/EditController.php index 3bab623ed8..0201d5659c 100644 --- a/app/Http/Controllers/Account/EditController.php +++ b/app/Http/Controllers/Account/EditController.php @@ -27,6 +27,7 @@ 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 Illuminate\Http\Request; @@ -85,6 +86,26 @@ class EditController extends Controller $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); + $creditCard = $this->repository->getAccountTypeByType(AccountType::CREDITCARD); + $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), + $creditCard->id => (string)trans('firefly.account_type_' . AccountType::CREDITCARD), + ]; + asort($liabilityTypes); + + // interest calculation periods: + $interestPeriods = [ + 'daily' => (string)trans('firefly.interest_calc_daily'), + 'monthly' => (string)trans('firefly.interest_calc_monthly'), + 'yearly' => (string)trans('firefly.interest_calc_yearly'), + ]; + // put previous url in session if not redirect from store (not "return_to_edit"). if (true !== session('accounts.edit.fromUpdate')) { $this->rememberPreviousUri('accounts.edit.uri'); @@ -108,16 +129,24 @@ class EditController extends Controller 'ccMonthlyPaymentDate' => $repository->getMetaValue($account, 'ccMonthlyPaymentDate'), 'BIC' => $repository->getMetaValue($account, 'BIC'), 'openingBalanceDate' => $openingBalanceDate, + 'liability_type_id' => $account->account_type_id, 'openingBalance' => $openingBalanceAmount, 'virtualBalance' => $account->virtual_balance, 'currency_id' => $currency->id, + 'interest' => $repository->getMetaValue($account, 'interest'), + 'interest_period' => $repository->getMetaValue($account, 'interest_period'), 'notes' => $this->repository->getNoteText($account), 'active' => $hasOldInput ? (bool)$request->old('active') : $account->active, ]; + if ('liabilities' === $what) { + $preFilled['openingBalance'] = bcmul($preFilled['openingBalance'], '-1'); + } $request->session()->flash('preFilled', $preFilled); - return view('accounts.edit', compact('account', 'currency', 'subTitle', 'subTitleIcon', 'what', 'roles', 'preFilled')); + return view( + 'accounts.edit', compact('account', 'currency', 'subTitle', 'subTitleIcon', 'what', 'roles', 'preFilled', 'liabilityTypes', 'interestPeriods') + ); } diff --git a/app/Http/Controllers/Account/IndexController.php b/app/Http/Controllers/Account/IndexController.php index 533c7e2e9b..98da7143e4 100644 --- a/app/Http/Controllers/Account/IndexController.php +++ b/app/Http/Controllers/Account/IndexController.php @@ -101,10 +101,13 @@ class IndexController extends Controller $accounts->each( function (Account $account) use ($activities, $startBalances, $endBalances) { - $account->lastActivityDate = $this->isInArray($activities, $account->id); - $account->startBalance = $this->isInArray($startBalances, $account->id); - $account->endBalance = $this->isInArray($endBalances, $account->id); - $account->difference = bcsub($account->endBalance, $account->startBalance); + $account->lastActivityDate = $this->isInArray($activities, $account->id); + $account->startBalance = $this->isInArray($startBalances, $account->id); + $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); } ); diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php index 5e3e12f362..efc6dfb0b5 100644 --- a/app/Http/Controllers/BillController.php +++ b/app/Http/Controllers/BillController.php @@ -276,10 +276,10 @@ class BillController extends Controller public function show(Request $request, Bill $bill) { // add info about rules: - $rules = $this->billRepository->getRulesForBill($bill); - $subTitle = $bill->name; + $rules = $this->billRepository->getRulesForBill($bill); + $subTitle = $bill->name; /** @var Carbon $start */ - $start = session('start'); + $start = session('start'); /** @var Carbon $end */ $end = session('end'); $year = $start->year; @@ -342,30 +342,7 @@ class BillController extends Controller $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore } - // do return to original bill form? - $return = 'false'; - if (1 === (int)$request->get('create_another')) { - $return = 'true'; - } - - $group = null; - // find first rule group, or create one: - $count = $this->ruleGroupRepos->count(); - if (0 === $count) { - $data = [ - 'title' => (string)trans('firefly.rulegroup_for_bills_title'), - 'description' => (string)trans('firefly.rulegroup_for_bills_description'), - ]; - $group = $this->ruleGroupRepos->store($data); - } - if ($count > 0) { - $group = $this->ruleGroupRepos->getActiveGroups($bill->user)->first(); - } - - // redirect to page that will create a new rule. - $params = http_build_query(['fromBill' => $bill->id, 'return' => $return]); - - return redirect(route('rules.create', [$group->id]) . '?' . $params); + return redirect(route('rules.create-from-bill', [$bill->id])); } /** diff --git a/app/Http/Controllers/Rule/CreateController.php b/app/Http/Controllers/Rule/CreateController.php index 622440301d..e475de3551 100644 --- a/app/Http/Controllers/Rule/CreateController.php +++ b/app/Http/Controllers/Rule/CreateController.php @@ -70,8 +70,6 @@ class CreateController extends Controller /** * Create a new rule. It will be stored under the given $ruleGroup. * - * TODO reinstate bill specific code. - * * @param Request $request * @param RuleGroup $ruleGroup * @@ -119,6 +117,55 @@ class CreateController extends Controller ); } + /** + * Create a new rule. It will be stored under the given $ruleGroup. + * + * @param Request $request + * @param Bill $bill + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + public function createFromBill(Request $request, Bill $bill) + { + $request->session()->flash('info', (string)trans('firefly.instructions_rule_from_bill', ['name' => $bill->name])); + + $this->createDefaultRuleGroup(); + $this->createDefaultRule(); + $preFilled = [ + 'strict' => true, + 'title' => (string)trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]), + 'description' => (string)trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]), + ]; + + // make triggers and actions from the bill itself. + + // get triggers and actions for bill: + $oldTriggers = $this->getTriggersForBill($bill); + $oldActions = $this->getActionsForBill($bill); + + $triggerCount = \count($oldTriggers); + $actionCount = \count($oldActions); + $subTitleIcon = 'fa-clone'; + + // title depends on whether or not there is a rule group: + $subTitle = (string)trans('firefly.make_new_rule_no_group'); + + // flash old data + $request->session()->flash('preFilled', $preFilled); + + // put previous url in session if not redirect from store (not "create another"). + if (true !== session('rules.create.fromStore')) { + $this->rememberPreviousUri('rules.create.uri'); + } + session()->forget('rules.create.fromStore'); + + return view( + 'rules.rule.create', compact('subTitleIcon', 'oldTriggers', 'preFilled', 'oldActions', 'triggerCount', 'actionCount', 'subTitle') + ); + } + /** * Store the new rule. * diff --git a/app/Models/Account.php b/app/Models/Account.php index b4d40cc1af..c4a25daf2f 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -53,8 +53,11 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property Carbon lastActivityDate * @property Collection accountMeta * @property bool encrypted - * @property int account_type_id - * @property Collection piggyBanks + * @property int account_type_id + * @property Collection piggyBanks + * @property string $interest + * @property string $interestPeriod + * @property string accountTypeString * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index 29616566f1..8489a62a80 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -299,10 +299,10 @@ class AccountRepository implements AccountRepositoryInterface public function getNoteText(Account $account): ?string { $note = $account->notes()->first(); + if (null === $note) { return null; } - return $note->text; } diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php index 51609ca6c1..08709f9661 100644 --- a/app/Support/ExpandedForm.php +++ b/app/Support/ExpandedForm.php @@ -41,7 +41,6 @@ use Illuminate\Support\HtmlString; use Illuminate\Support\MessageBag; use Log; use RuntimeException; -use Session; use Throwable; /** @@ -246,7 +245,7 @@ class ExpandedForm $value = $value ?? 1; $options['checked'] = true === $checked; - if (Session::has('preFilled')) { + if (app('session')->has('preFilled')) { $preFilled = session('preFilled'); $options['checked'] = $preFilled[$name] ?? $options['checked']; } @@ -528,34 +527,6 @@ class ExpandedForm return $html; } - /** - * Function to render a percentage. - * - * @param string $name - * @param mixed $value - * @param array $options - * - * @return string - * - */ - public function percentage(string $name, $value = null, array $options = null): string - { - $label = $this->label($name, $options); - $options = $this->expandOptionArray($name, $label, $options); - $classes = $this->getHolderClasses($name); - $value = $this->fillFieldValue($name, $value); - $options['step'] = 'any'; - unset($options['placeholder']); - try { - $html = view('form.percentage', compact('classes', 'name', 'label', 'value', 'options'))->render(); - } catch (Throwable $e) { - Log::debug(sprintf('Could not render percentage(): %s', $e->getMessage())); - $html = 'Could not render percentage.'; - } - - return $html; - } - /** * @param string $type * @param string $name @@ -598,6 +569,34 @@ class ExpandedForm return $html; } + /** + * Function to render a percentage. + * + * @param string $name + * @param mixed $value + * @param array $options + * + * @return string + * + */ + public function percentage(string $name, $value = null, array $options = null): string + { + $label = $this->label($name, $options); + $options = $this->expandOptionArray($name, $label, $options); + $classes = $this->getHolderClasses($name); + $value = $this->fillFieldValue($name, $value); + $options['step'] = 'any'; + unset($options['placeholder']); + try { + $html = view('form.percentage', compact('classes', 'name', 'label', 'value', 'options'))->render(); + } catch (Throwable $e) { + Log::debug(sprintf('Could not render percentage(): %s', $e->getMessage())); + $html = 'Could not render percentage.'; + } + + return $html; + } + /** * @param string $name * @param mixed $value @@ -784,12 +783,16 @@ class ExpandedForm */ public function textarea(string $name, $value = null, array $options = null): string { - $value = $value ?? ''; $label = $this->label($name, $options); $options = $this->expandOptionArray($name, $label, $options); $classes = $this->getHolderClasses($name); $value = $this->fillFieldValue($name, $value); $options['rows'] = 4; + + if (null === $value) { + $value = ''; + } + try { $html = view('form.textarea', compact('classes', 'name', 'label', 'value', 'options'))->render(); } catch (Throwable $e) { @@ -880,12 +883,13 @@ class ExpandedForm * @return mixed * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function fillFieldValue(string $name, $value) + protected function fillFieldValue(string $name, $value = null) { - if (Session::has('preFilled')) { + if (app('session')->has('preFilled')) { $preFilled = session('preFilled'); $value = isset($preFilled[$name]) && null === $value ? $preFilled[$name] : $value; } + try { if (null !== request()->old($name)) { $value = request()->old($name); @@ -894,6 +898,7 @@ class ExpandedForm // don't care about session errors. Log::debug(sprintf('Run time: %s', $e->getMessage())); } + if ($value instanceof Carbon) { $value = $value->format('Y-m-d'); } diff --git a/app/Support/Http/Controllers/RuleManagement.php b/app/Support/Http/Controllers/RuleManagement.php index 60d9b0bcb9..2dd2415f6c 100644 --- a/app/Support/Http/Controllers/RuleManagement.php +++ b/app/Support/Http/Controllers/RuleManagement.php @@ -47,36 +47,36 @@ trait RuleManagement if (0 === $ruleRepository->count()) { $data = [ 'rule_group_id' => $ruleRepository->getFirstRuleGroup()->id, - 'stop-processing' => 0, + 'stop_processing' => 0, 'title' => (string)trans('firefly.default_rule_name'), 'description' => (string)trans('firefly.default_rule_description'), 'trigger' => 'store-journal', 'strict' => true, - 'rule-triggers' => [ + 'rule_triggers' => [ [ 'name' => 'description_is', 'value' => (string)trans('firefly.default_rule_trigger_description'), - 'stop-processing' => false, + 'stop_processing' => false, ], [ 'name' => 'from_account_is', 'value' => (string)trans('firefly.default_rule_trigger_from_account'), - 'stop-processing' => false, + 'stop_processing' => false, ], ], - 'rule-actions' => [ + 'rule_actions' => [ [ 'name' => 'prepend_description', 'value' => (string)trans('firefly.default_rule_action_prepend'), - 'stop-processing' => false, + 'stop_processing' => false, ], [ 'name' => 'set_category', 'value' => (string)trans('firefly.default_rule_action_set_category'), - 'stop-processing' => false, + 'stop_processing' => false, ], ], ]; diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 7d8698b072..cd7e7b10e5 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -271,6 +271,7 @@ return [ 'save_rules_by_moving' => 'Save these rule(s) by moving them to another rule group:', 'make_new_rule' => 'Make a new rule in rule group ":title"', 'make_new_rule_no_group' => 'Make a new rule', + 'instructions_rule_from_bill' => 'In order to match transactions to your new bill ":name", Firefly III can create a rule that will automatically be checked against any transactions you store. Please verify the details below and store the rule to have Firefly III automatically match transactions to your new bill.', 'rule_is_strict' => 'strict rule', 'rule_is_not_strict' => 'non-strict rule', 'rule_help_stop_processing' => 'When you check this box, later rules in this group will not be executed.', @@ -694,6 +695,7 @@ return [ 'expense_deleted' => 'Successfully deleted expense account ":name"', 'revenue_deleted' => 'Successfully deleted revenue account ":name"', 'update_asset_account' => 'Update asset account', + 'update_liabilities_account' => 'Update liability', 'update_expense_account' => 'Update expense account', 'update_revenue_account' => 'Update revenue account', 'make_new_asset_account' => 'Create a new asset account', @@ -899,6 +901,7 @@ return [ 'debt_start_amount' => 'Start amount of debt', 'debt_start_amount_help' => 'Please enter a positive amount. Feel free to enter the current amount and date.', 'store_new_liabilities_account' => 'Store new liability', + 'edit_liabilities_account' => 'Edit liability ":name"', // reports: 'report_default' => 'Default financial report between :start and :end', diff --git a/resources/lang/en_US/list.php b/resources/lang/en_US/list.php index bc36c21a41..4a50b795c8 100644 --- a/resources/lang/en_US/list.php +++ b/resources/lang/en_US/list.php @@ -130,4 +130,7 @@ return [ 'transaction_s' => 'Transaction(s)', 'field' => 'Field', 'value' => 'Value', + 'interest' => 'Interest', + 'interest_period' => 'interest period', + 'liability_type' => 'Type of liability', ]; diff --git a/resources/views/accounts/create.twig b/resources/views/accounts/create.twig index dc32ab6e77..7b8dc44121 100644 --- a/resources/views/accounts/create.twig +++ b/resources/views/accounts/create.twig @@ -17,7 +17,7 @@