mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-06 12:45:30 +00:00
Some basic code for liability accounts.
This commit is contained in:
@@ -91,6 +91,11 @@ class ShowController extends Controller
|
|||||||
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
|
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
|
||||||
return $this->redirectToOriginalAccount($account);
|
return $this->redirectToOriginalAccount($account);
|
||||||
}
|
}
|
||||||
|
// a basic thing to determin if this account is a liability:
|
||||||
|
if ($this->repository->isLiability($account)) {
|
||||||
|
return redirect(route('accounts.show.all', [$account->id]));
|
||||||
|
}
|
||||||
|
|
||||||
/** @var Carbon $start */
|
/** @var Carbon $start */
|
||||||
$start = $start ?? session('start');
|
$start = $start ?? session('start');
|
||||||
/** @var Carbon $end */
|
/** @var Carbon $end */
|
||||||
@@ -122,9 +127,13 @@ class ShowController extends Controller
|
|||||||
$transactions->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
|
$transactions->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
|
||||||
$showAll = false;
|
$showAll = false;
|
||||||
|
|
||||||
|
|
||||||
return view(
|
return view(
|
||||||
'accounts.show',
|
'accounts.show',
|
||||||
compact('account', 'showAll', 'what', 'currency', 'today', 'periods', 'subTitleIcon', 'transactions', 'subTitle', 'start', 'end', 'chartUri')
|
compact(
|
||||||
|
'account', 'showAll', 'what', 'currency', 'today', 'periods', 'subTitleIcon', 'transactions', 'subTitle', 'start', 'end',
|
||||||
|
'chartUri'
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,6 +153,7 @@ class ShowController extends Controller
|
|||||||
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
|
if (AccountType::INITIAL_BALANCE === $account->accountType->type) {
|
||||||
return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore
|
return $this->redirectToOriginalAccount($account); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
$isLiability = $this->repository->isLiability($account);
|
||||||
$end = new Carbon;
|
$end = new Carbon;
|
||||||
$today = new Carbon;
|
$today = new Carbon;
|
||||||
$start = $this->repository->oldestJournalDate($account) ?? Carbon::now()->startOfMonth();
|
$start = $this->repository->oldestJournalDate($account) ?? Carbon::now()->startOfMonth();
|
||||||
@@ -167,7 +177,7 @@ class ShowController extends Controller
|
|||||||
|
|
||||||
return view(
|
return view(
|
||||||
'accounts.show',
|
'accounts.show',
|
||||||
compact('account', 'showAll', 'currency', 'today', 'chartUri', 'periods', 'subTitleIcon', 'transactions', 'subTitle', 'start', 'end')
|
compact('account', 'showAll','isLiability', 'currency', 'today', 'chartUri', 'periods', 'subTitleIcon', 'transactions', 'subTitle', 'start', 'end')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -270,6 +270,30 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $factory->findOrCreate('Cash account', $type->type);
|
return $factory->findOrCreate('Cash account', $type->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $account
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getInterestPerDay(Account $account): string
|
||||||
|
{
|
||||||
|
$interest = $this->getMetaValue($account, 'interest');
|
||||||
|
$interestPeriod = $this->getMetaValue($account, 'interest_period');
|
||||||
|
Log::debug(sprintf('Start with interest of %s percent', $interest));
|
||||||
|
|
||||||
|
// calculate
|
||||||
|
if ('monthly' === $interestPeriod) {
|
||||||
|
$interest = bcdiv(bcmul($interest, '12'), '365'); // per year
|
||||||
|
Log::debug(sprintf('Interest is now (monthly to daily) %s percent', $interest));
|
||||||
|
}
|
||||||
|
if ('yearly' === $interestPeriod) {
|
||||||
|
$interest = bcdiv($interest, '365'); // per year
|
||||||
|
Log::debug(sprintf('Interest is now (yearly to daily) %s percent', $interest));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $interest;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return meta value for account. Null if not found.
|
* Return meta value for account. Null if not found.
|
||||||
*
|
*
|
||||||
@@ -382,6 +406,57 @@ class AccountRepository implements AccountRepositoryInterface
|
|||||||
return $account;
|
return $account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Account $account
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isLiability(Account $account): bool
|
||||||
|
{
|
||||||
|
return \in_array($account->accountType->type, [AccountType::CREDITCARD, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date of the very last transaction in this account.
|
||||||
|
*
|
||||||
|
* @param Account $account
|
||||||
|
*
|
||||||
|
* @return TransactionJournal|null
|
||||||
|
*/
|
||||||
|
public function latestJournal(Account $account): ?TransactionJournal
|
||||||
|
{
|
||||||
|
$first = $account->transactions()
|
||||||
|
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
|
||||||
|
->orderBy('transaction_journals.date', 'DESC')
|
||||||
|
->orderBy('transaction_journals.order', 'ASC')
|
||||||
|
->where('transaction_journals.user_id', $this->user->id)
|
||||||
|
->orderBy('transaction_journals.id', 'DESC')
|
||||||
|
->first(['transaction_journals.id']);
|
||||||
|
if (null !== $first) {
|
||||||
|
return TransactionJournal::find((int)$first->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date of the very last transaction in this account.
|
||||||
|
*
|
||||||
|
* @param Account $account
|
||||||
|
*
|
||||||
|
* @return Carbon|null
|
||||||
|
*/
|
||||||
|
public function latestJournalDate(Account $account): ?Carbon
|
||||||
|
{
|
||||||
|
$result = null;
|
||||||
|
$journal = $this->latestJournal($account);
|
||||||
|
if (null !== $journal) {
|
||||||
|
$result = $journal->date;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the date of the very first transaction in this account.
|
* Returns the date of the very first transaction in this account.
|
||||||
*
|
*
|
||||||
|
@@ -123,6 +123,13 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getCashAccount(): Account;
|
public function getCashAccount(): Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $account
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getInterestPerDay(Account $account): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return meta value for account. Null if not found.
|
* Return meta value for account. Null if not found.
|
||||||
*
|
*
|
||||||
@@ -151,7 +158,6 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getOpeningBalanceAmount(Account $account): ?string;
|
public function getOpeningBalanceAmount(Account $account): ?string;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return date of opening balance as string or null.
|
* Return date of opening balance as string or null.
|
||||||
*
|
*
|
||||||
@@ -170,6 +176,31 @@ interface AccountRepositoryInterface
|
|||||||
*/
|
*/
|
||||||
public function getReconciliation(Account $account): ?Account;
|
public function getReconciliation(Account $account): ?Account;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Account $account
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isLiability(Account $account): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date of the very first transaction in this account.
|
||||||
|
*
|
||||||
|
* @param Account $account
|
||||||
|
*
|
||||||
|
* @return TransactionJournal|null
|
||||||
|
*/
|
||||||
|
public function latestJournal(Account $account): ?TransactionJournal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the date of the very last transaction in this account.
|
||||||
|
*
|
||||||
|
* @param Account $account
|
||||||
|
*
|
||||||
|
* @return Carbon|null
|
||||||
|
*/
|
||||||
|
public function latestJournalDate(Account $account): ?Carbon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the date of the very first transaction in this account.
|
* Returns the date of the very first transaction in this account.
|
||||||
*
|
*
|
||||||
|
@@ -902,7 +902,7 @@ return [
|
|||||||
'errors' => 'Errors',
|
'errors' => 'Errors',
|
||||||
'debt_start_date' => 'Start date of debt',
|
'debt_start_date' => 'Start date of debt',
|
||||||
'debt_start_amount' => 'Start amount of debt',
|
'debt_start_amount' => 'Start amount of debt',
|
||||||
'debt_start_amount_help' => 'Please enter a positive amount. You may also enter the current amount, if the original amount was way-back-when.',
|
'debt_start_amount_help' => 'Please enter the original amount of this liability as a positive number. You may also enter the current amount. Make sure to edit the date below to match.',
|
||||||
'store_new_liabilities_account' => 'Store new liability',
|
'store_new_liabilities_account' => 'Store new liability',
|
||||||
'edit_liabilities_account' => 'Edit liability ":name"',
|
'edit_liabilities_account' => 'Edit liability ":name"',
|
||||||
|
|
||||||
|
@@ -6,30 +6,51 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">
|
<h3 class="box-title">
|
||||||
{{ trans('firefly.chart_account_in_period', {name: account.name, start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat) }) }}
|
{{ trans('firefly.chart_account_in_period', {name: account.name, start: start.formatLocalized(monthAndDayFormat), end: end.formatLocalized(monthAndDayFormat) }) }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="box-tools pull-right">
|
<div class="box-tools pull-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
|
<button class="btn btn-box-tool dropdown-toggle" data-toggle="dropdown"><i class="fa fa-ellipsis-v"></i></button>
|
||||||
<ul class="dropdown-menu" role="menu">
|
<ul class="dropdown-menu" role="menu">
|
||||||
<li><a href="{{ route('accounts.edit', account.id) }}"><i class="fa fa-pencil fa-fw"></i> {{ 'edit'|_ }}</a></li>
|
<li><a href="{{ route('accounts.edit', account.id) }}"><i class="fa fa-pencil fa-fw"></i> {{ 'edit'|_ }}</a></li>
|
||||||
<li><a href="{{ route('accounts.delete', account.id) }}"><i class="fa fa-trash fa-fw"></i> {{ 'delete'|_ }}</a></li>
|
<li><a href="{{ route('accounts.delete', account.id) }}"><i class="fa fa-trash fa-fw"></i> {{ 'delete'|_ }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<div>
|
||||||
<canvas id="overview-chart" style="width:100%;height:400px;" height="400" width="100%"></canvas>
|
<canvas id="overview-chart" style="width:100%;height:400px;" height="400" width="100%"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
<p>
|
||||||
|
{% if isLiability %}
|
||||||
|
<em>This chart pre-calculates rent starting from the last transaction you've entered. It's just an estimation.</em>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if not showAll and isLiability %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">pay-off by date</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
Content
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if not showAll %}
|
{% endif %}
|
||||||
|
{% if not showAll and not isLiability %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
|
Reference in New Issue
Block a user