mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-23 14:26:58 +00:00
Refactored accountRepository::getJournals > accountTasker > getJournals
This commit is contained in:
@@ -218,7 +218,7 @@ class AccountController extends Controller
|
||||
$page = intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$set = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
@@ -269,13 +269,13 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
* @param Account $account
|
||||
* @param string $date
|
||||
* @param AccountTaskerInterface $tasker
|
||||
* @param Account $account
|
||||
* @param string $date
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function showWithDate(ARI $repository, Account $account, string $date)
|
||||
public function showWithDate(AccountTaskerInterface $tasker, Account $account, string $date)
|
||||
{
|
||||
$carbon = new Carbon($date);
|
||||
$range = Preferences::get('viewRange', '1M')->data;
|
||||
@@ -286,7 +286,7 @@ class AccountController extends Controller
|
||||
$page = $page === 0 ? 1 : $page;
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$set = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
|
@@ -249,7 +249,7 @@ class BudgetController extends Controller
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$journals = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end);
|
||||
$journals = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end); // budget
|
||||
$count = $journals->count();
|
||||
$journals = $journals->slice($offset, $pageSize);
|
||||
$list = new LengthAwarePaginator($journals, $count, $pageSize);
|
||||
@@ -295,7 +295,7 @@ class BudgetController extends Controller
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end);
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end); // budget
|
||||
$count = $journals->count();
|
||||
$journals = $journals->slice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($journals, $count, $pageSize);
|
||||
@@ -334,7 +334,7 @@ class BudgetController extends Controller
|
||||
$page = intval(Input::get('page')) == 0 ? 1 : intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end);
|
||||
$journals = $repository->journalsInPeriod(new Collection([$budget]), new Collection, $start, $end); // budget
|
||||
$count = $journals->count();
|
||||
$journals = $journals->slice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($journals, $count, $pageSize);
|
||||
|
@@ -149,7 +149,7 @@ class CategoryController extends Controller
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->startOfMonth());
|
||||
$list = $repository->journalsInPeriodWithoutCategory(new Collection(), [], $start, $end);
|
||||
$list = $repository->journalsInPeriodWithoutCategory(new Collection(), [], $start, $end); // category
|
||||
$subTitle = trans(
|
||||
'firefly.without_category_between',
|
||||
['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)]
|
||||
@@ -176,7 +176,7 @@ class CategoryController extends Controller
|
||||
$page = intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end);
|
||||
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); // category
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$subTitle = $category->name;
|
||||
@@ -247,7 +247,7 @@ class CategoryController extends Controller
|
||||
$page = intval(Input::get('page'));
|
||||
$pageSize = Preferences::get('transactionPageSize', 50)->data;
|
||||
$offset = ($page - 1) * $pageSize;
|
||||
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end);
|
||||
$set = $repository->journalsInPeriod(new Collection([$category]), new Collection, [], $start, $end); // category
|
||||
$count = $set->count();
|
||||
$subSet = $set->splice($offset, $pageSize);
|
||||
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
|
||||
|
@@ -401,7 +401,7 @@ class BudgetController extends Controller
|
||||
*/
|
||||
private function spentInPeriodWithout(BudgetRepositoryInterface $repository, Carbon $start, Carbon $end):array
|
||||
{
|
||||
$list = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end);
|
||||
$list = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end); // budget
|
||||
$sum = '0';
|
||||
/** @var TransactionJournal $entry */
|
||||
foreach ($list as $entry) {
|
||||
|
@@ -19,6 +19,7 @@ use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Tag;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -26,7 +27,6 @@ use Log;
|
||||
use Preferences;
|
||||
use Route;
|
||||
use Session;
|
||||
use Steam;
|
||||
|
||||
|
||||
/**
|
||||
@@ -114,12 +114,13 @@ class HomeController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ARI $repository
|
||||
* @param AccountCrudInterface $crud
|
||||
* @param ARI $repository
|
||||
* @param AccountCrudInterface $crud
|
||||
* @param AccountTaskerInterface $tasker
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
|
||||
*/
|
||||
public function index(ARI $repository, AccountCrudInterface $crud)
|
||||
public function index(ARI $repository, AccountCrudInterface $crud, AccountTaskerInterface $tasker)
|
||||
{
|
||||
|
||||
$types = config('firefly.accountTypesByIdentifier.asset');
|
||||
@@ -139,12 +140,12 @@ class HomeController extends Controller
|
||||
/** @var Carbon $start */
|
||||
$start = session('start', Carbon::now()->startOfMonth());
|
||||
/** @var Carbon $end */
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
$showTour = Preferences::get('tour', true)->data;
|
||||
$accounts = $crud->getAccountsById($frontPage->data);
|
||||
$end = session('end', Carbon::now()->endOfMonth());
|
||||
$showTour = Preferences::get('tour', true)->data;
|
||||
$accounts = $crud->getAccountsById($frontPage->data);
|
||||
|
||||
foreach ($accounts as $account) {
|
||||
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$set = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$set = $set->splice(0, 10);
|
||||
|
||||
if (count($set) > 0) {
|
||||
@@ -153,7 +154,7 @@ class HomeController extends Controller
|
||||
}
|
||||
|
||||
return view(
|
||||
'index', compact('count', 'showTour', 'title','subTitle', 'mainTitleIcon', 'transactions')
|
||||
'index', compact('count', 'showTour', 'title', 'subTitle', 'mainTitleIcon', 'transactions')
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -19,9 +19,11 @@ use FireflyIII\Crud\Account\AccountCrudInterface;
|
||||
use FireflyIII\Exceptions\FireflyException;
|
||||
use FireflyIII\Helpers\Collection\BalanceLine;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use FireflyIII\Support\Binder\AccountList;
|
||||
@@ -185,22 +187,22 @@ class ReportController extends Controller
|
||||
*/
|
||||
private function expenseEntry(array $attributes): string
|
||||
{
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$crud = app(AccountCrudInterface::class);
|
||||
$account = $crud->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
|
||||
$journals = $repository->journalsInPeriod($attributes['accounts'], $types, $attributes['startDate'], $attributes['endDate']);
|
||||
/** @var AccountTaskerInterface $tasker */
|
||||
$tasker = app(AccountTaskerInterface::class);
|
||||
$crud = app(AccountCrudInterface::class);
|
||||
$account = $crud->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
|
||||
$journals = $tasker->getJournalsInPeriod($attributes['accounts'], $types, $attributes['startDate'], $attributes['endDate']);
|
||||
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
|
||||
|
||||
// filter for transfers and withdrawals TO the given $account
|
||||
$journals = $journals->filter(
|
||||
function (TransactionJournal $journal) use ($account) {
|
||||
$destinations = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
|
||||
if (in_array($account->id, $destinations)) {
|
||||
return true;
|
||||
}
|
||||
function (Transaction $transaction) use ($report) {
|
||||
// get the destinations:
|
||||
$destinations = TransactionJournal::destinationAccountList($transaction->transactionJournal)->pluck('id')->toArray();
|
||||
|
||||
return false;
|
||||
// do these intersect with the current list?
|
||||
return !empty(array_intersect($report, $destinations));
|
||||
}
|
||||
);
|
||||
|
||||
@@ -219,27 +221,23 @@ class ReportController extends Controller
|
||||
*/
|
||||
private function incomeEntry(array $attributes): string
|
||||
{
|
||||
/** @var AccountRepositoryInterface $repository */
|
||||
$repository = app(AccountRepositoryInterface::class);
|
||||
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
|
||||
$account = $crud->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::DEPOSIT, TransactionType::TRANSFER];
|
||||
$journals = $repository->journalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
|
||||
$destinations = $attributes['accounts']->pluck('id')->toArray();
|
||||
// filter for transfers and withdrawals FROM the given $account
|
||||
/** @var AccountTaskerInterface $tasker */
|
||||
$tasker = app(AccountTaskerInterface::class);
|
||||
/** @var AccountCrudInterface $crud */
|
||||
$crud = app(AccountCrudInterface::class);
|
||||
$account = $crud->find(intval($attributes['accountId']));
|
||||
$types = [TransactionType::DEPOSIT, TransactionType::TRANSFER];
|
||||
$journals = $tasker->getJournalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
|
||||
$report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report
|
||||
|
||||
// filter the set so the destinations outside of $attributes['accounts'] are not included.
|
||||
$journals = $journals->filter(
|
||||
function (TransactionJournal $journal) use ($account, $destinations) {
|
||||
$currentSources = TransactionJournal::sourceAccountList($journal)->pluck('id')->toArray();
|
||||
$currentDest = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
|
||||
if (
|
||||
!empty(array_intersect([$account->id], $currentSources))
|
||||
&& !empty(array_intersect($destinations, $currentDest))
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
function (Transaction $transaction) use ($report) {
|
||||
// get the destinations:
|
||||
$destinations = TransactionJournal::destinationAccountList($transaction->transactionJournal)->pluck('id')->toArray();
|
||||
|
||||
return false;
|
||||
// do these intersect with the current list?
|
||||
return !empty(array_intersect($report, $destinations));
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -21,8 +21,9 @@ use FireflyIII\Helpers\Report\BudgetReportHelperInterface;
|
||||
use FireflyIII\Helpers\Report\ReportHelperInterface;
|
||||
use FireflyIII\Models\Account;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
|
||||
use FireflyIII\Repositories\Account\AccountTaskerInterface;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
@@ -121,7 +122,7 @@ class ReportController extends Controller
|
||||
|
||||
switch ($reportType) {
|
||||
default:
|
||||
throw new FireflyException('Unfortunately, reports of the type "' . e($reportType) . '" are not yet available. ');
|
||||
throw new FireflyException('Unfortunately, reports of the type "' . e($reportType) . '" are not available at this time.');
|
||||
case 'default':
|
||||
|
||||
// more than one year date difference means year report.
|
||||
@@ -153,54 +154,36 @@ class ReportController extends Controller
|
||||
private function auditReport(Carbon $start, Carbon $end, Collection $accounts)
|
||||
{
|
||||
/** @var ARI $repos */
|
||||
$repos = app(ARI::class);
|
||||
$repos = app(ARI::class);
|
||||
/** @var AccountTaskerInterface $tasker */
|
||||
$tasker = app(AccountTaskerInterface::class);
|
||||
$auditData = [];
|
||||
$dayBefore = clone $start;
|
||||
$dayBefore->subDay();
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
|
||||
// balance the day before:
|
||||
$id = $account->id;
|
||||
$first = $repos->oldestJournalDate($account);
|
||||
$last = $repos->newestJournalDate($account);
|
||||
$exists = false;
|
||||
$journals = new Collection;
|
||||
$dayBeforeBalance = Steam::balance($account, $dayBefore);
|
||||
/*
|
||||
* Is there even activity on this account between the requested dates?
|
||||
*/
|
||||
if ($start->between($first, $last) || $end->between($first, $last)) {
|
||||
$exists = true;
|
||||
$journals = $repos->journalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$journals = $tasker->getJournalsInPeriod(new Collection([$account]), [], $start, $end);
|
||||
$journals = $journals->reverse();
|
||||
$startBalance = $dayBeforeBalance;
|
||||
|
||||
}
|
||||
/*
|
||||
* Reverse set, get balances.
|
||||
*/
|
||||
$journals = $journals->reverse();
|
||||
$startBalance = $dayBeforeBalance;
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($journals as $journal) {
|
||||
$journal->before = $startBalance;
|
||||
$transactionAmount = $journal->source_amount;
|
||||
|
||||
// get currently relevant transaction:
|
||||
$destinations = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
|
||||
if (in_array($account->id, $destinations)) {
|
||||
$transactionAmount = TransactionJournal::amountPositive($journal);
|
||||
}
|
||||
$newBalance = bcadd($startBalance, $transactionAmount);
|
||||
$journal->after = $newBalance;
|
||||
$startBalance = $newBalance;
|
||||
|
||||
/** @var Transaction $journal */
|
||||
foreach ($journals as $transaction) {
|
||||
$transaction->before = $startBalance;
|
||||
$transactionAmount = $transaction->transaction_amount;
|
||||
$newBalance = bcadd($startBalance, $transactionAmount);
|
||||
$transaction->after = $newBalance;
|
||||
$startBalance = $newBalance;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reverse set again.
|
||||
*/
|
||||
$auditData[$id]['journals'] = $journals->reverse();
|
||||
$auditData[$id]['exists'] = $exists;
|
||||
$auditData[$id]['exists'] = $journals->count() > 0;
|
||||
$auditData[$id]['end'] = $end->formatLocalized(strval(trans('config.month_and_day')));
|
||||
$auditData[$id]['endBalance'] = Steam::balance($account, $end);
|
||||
$auditData[$id]['dayBefore'] = $dayBefore->formatLocalized(strval(trans('config.month_and_day')));
|
||||
|
@@ -245,6 +245,7 @@ class TransactionController extends Controller
|
||||
$date = new Carbon($request->get('date'));
|
||||
if (count($ids) > 0) {
|
||||
$order = 0;
|
||||
$ids = array_unique($ids);
|
||||
foreach ($ids as $id) {
|
||||
$journal = $repository->find(intval($id));
|
||||
if ($journal && $journal->date->format('Y-m-d') == $date->format('Y-m-d')) {
|
||||
|
@@ -25,6 +25,7 @@ use FireflyIII\Support\Twig\Journal;
|
||||
use FireflyIII\Support\Twig\PiggyBank;
|
||||
use FireflyIII\Support\Twig\Rule;
|
||||
use FireflyIII\Support\Twig\Translation;
|
||||
use FireflyIII\Support\Twig\Transaction;
|
||||
use FireflyIII\Validation\FireflyValidator;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Twig;
|
||||
@@ -52,6 +53,7 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
Twig::addExtension(new Journal);
|
||||
Twig::addExtension(new Budget);
|
||||
Twig::addExtension(new Translation);
|
||||
Twig::addExtension(new Transaction);
|
||||
Twig::addExtension(new Rule);
|
||||
}
|
||||
|
||||
|
@@ -111,63 +111,6 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
return $transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): Collection
|
||||
{
|
||||
// first collect actual transaction journals (fairly easy)
|
||||
$query = $this->user->transactionJournals()->expanded()->sortCorrectly();
|
||||
|
||||
if ($end >= $start) {
|
||||
$query->before($end)->after($start);
|
||||
}
|
||||
|
||||
if (count($types) > 0) {
|
||||
$query->transactionTypes($types);
|
||||
}
|
||||
if ($accounts->count() > 0) {
|
||||
$accountIds = $accounts->pluck('id')->toArray();
|
||||
$query->leftJoin(
|
||||
'transactions as source', function (JoinClause $join) {
|
||||
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')->where('source.amount', '<', 0);
|
||||
}
|
||||
);
|
||||
$query->leftJoin(
|
||||
'transactions as destination', function (JoinClause $join) {
|
||||
$join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')->where('destination.amount', '>', 0);
|
||||
}
|
||||
);
|
||||
$query->where(
|
||||
// source.account_id in accountIds XOR destination.account_id in accountIds
|
||||
function (Builder $query) use ($accountIds) {
|
||||
$query->where(
|
||||
function (Builder $q1) use ($accountIds) {
|
||||
$q1->whereIn('source.account_id', $accountIds)
|
||||
->whereNotIn('destination.account_id', $accountIds);
|
||||
}
|
||||
)->orWhere(
|
||||
function (Builder $q2) use ($accountIds) {
|
||||
$q2->whereIn('destination.account_id', $accountIds)
|
||||
->whereNotIn('source.account_id', $accountIds);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// that should do it:
|
||||
$fields = TransactionJournal::queryFields();
|
||||
$complete = $query->get($fields);
|
||||
|
||||
return $complete;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Account $account
|
||||
|
@@ -60,16 +60,6 @@ interface AccountRepositoryInterface
|
||||
*/
|
||||
public function getFirstTransaction(TransactionJournal $journal, Account $account): Transaction;
|
||||
|
||||
/**
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function journalsInPeriod(Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Account $account
|
||||
|
@@ -190,6 +190,8 @@ class AccountTasker implements AccountTaskerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* It might be worth it to expand this query to include all account information required.
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param array $types
|
||||
* @param Carbon $start
|
||||
@@ -205,6 +207,8 @@ class AccountTasker implements AccountTaskerInterface
|
||||
->leftJoin('transaction_currencies', 'transaction_currencies.id', 'transaction_journals.transaction_currency_id')
|
||||
->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id')
|
||||
->leftJoin('bills', 'bills.id', 'transaction_journals.bill_id')
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin('account_types', 'accounts.account_type_id', 'account_types.id')
|
||||
->whereIn('transactions.account_id', $accountIds)
|
||||
->whereNull('transactions.deleted_at')
|
||||
->whereNull('transaction_journals.deleted_at')
|
||||
@@ -221,29 +225,35 @@ class AccountTasker implements AccountTaskerInterface
|
||||
|
||||
$set = $query->get(
|
||||
[
|
||||
'transaction_journals.id',
|
||||
'transaction_journals.id as journal_id',
|
||||
'transaction_journals.description',
|
||||
'transaction_journals.date',
|
||||
'transaction_journals.encrypted',
|
||||
'transaction_journals.transaction_currency_id',
|
||||
//'transaction_journals.transaction_currency_id',
|
||||
'transaction_currencies.code as transaction_currency_code',
|
||||
'transaction_currencies.symbol as transaction_currency_symbol',
|
||||
'transaction_journals.transaction_type_id',
|
||||
//'transaction_currencies.symbol as transaction_currency_symbol',
|
||||
'transaction_types.type as transaction_type_type',
|
||||
'transaction_journals.bill_id',
|
||||
'bills.name as bill_name',
|
||||
'transactions.id as transaction_id',
|
||||
'transactions.id as id',
|
||||
'transactions.amount as transaction_amount',
|
||||
'transactions.description as transaction_description',
|
||||
'transactions.account_id',
|
||||
'transactions.identifier',
|
||||
'transactions.transaction_journal_id',
|
||||
'accounts.name as account_name',
|
||||
'accounts.encrypted as account_encrypted',
|
||||
'account_types.type as account_type',
|
||||
|
||||
]
|
||||
);
|
||||
|
||||
// loop for decryption.
|
||||
$set->each(
|
||||
function (Transaction $transaction) {
|
||||
$transaction->date = new Carbon($transaction->date);
|
||||
$transaction->date = new Carbon($transaction->date);
|
||||
$transaction->description = intval($transaction->encrypted) === 1 ? Crypt::decrypt($transaction->description) : $transaction->description;
|
||||
$transaction->bill_name = !is_null($transaction->bill_name) ? Crypt::decrypt($transaction->bill_name) : '';
|
||||
$transaction->bill_name = !is_null($transaction->bill_name) ? Crypt::decrypt($transaction->bill_name) : '';
|
||||
}
|
||||
);
|
||||
|
||||
|
@@ -119,6 +119,41 @@ class Amount
|
||||
return $this->formatAnything($currency, strval($transaction->amount), $coloured);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will properly format the given number, in color or "black and white",
|
||||
* as a currency, given two things: the currency required and the currency code.
|
||||
*
|
||||
* @param string $code
|
||||
* @param string $amount
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formatWithCode(string $code, string $amount, bool $coloured = true): string
|
||||
{
|
||||
$locale = setlocale(LC_MONETARY, 0);
|
||||
$float = round($amount, 2);
|
||||
$formatter = new NumberFormatter($locale, NumberFormatter::CURRENCY);
|
||||
$result = $formatter->formatCurrency($float, $code);
|
||||
|
||||
if ($coloured === true) {
|
||||
|
||||
if ($amount > 0) {
|
||||
return '<span class="text-success" title="' . e($float) . '">' . $result . '</span>';
|
||||
} else {
|
||||
if ($amount < 0) {
|
||||
return '<span class="text-danger" title="' . e($float) . '">' . $result . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
return '<span style="color:#999" title="' . e($float) . '">' . $result . '</span>';
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
|
@@ -20,6 +20,7 @@ use FireflyIII\Models\Budget as ModelBudget;
|
||||
use FireflyIII\Models\Category;
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Twig_Extension;
|
||||
use Twig_SimpleFilter;
|
||||
@@ -164,7 +165,9 @@ class Journal extends Twig_Extension
|
||||
*/
|
||||
public function getFilters(): array
|
||||
{
|
||||
$filters = [$this->typeIcon()];
|
||||
$filters = [
|
||||
$this->typeIcon(),
|
||||
];
|
||||
|
||||
return $filters;
|
||||
}
|
||||
@@ -407,4 +410,5 @@ class Journal extends Twig_Extension
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
298
app/Support/Twig/Transaction.php
Normal file
298
app/Support/Twig/Transaction.php
Normal file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
/**
|
||||
* Transaction.php
|
||||
* Copyright (C) 2016 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This software may be modified and distributed under the terms of the
|
||||
* Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types = 1);
|
||||
|
||||
namespace FireflyIII\Support\Twig;
|
||||
|
||||
use Amount;
|
||||
use Crypt;
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Transaction as TransactionModel;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use Twig_Extension;
|
||||
use Twig_SimpleFilter;
|
||||
use Twig_SimpleFunction;
|
||||
|
||||
/**
|
||||
* Class Transaction
|
||||
*
|
||||
* @package FireflyIII\Support\Twig
|
||||
*/
|
||||
class Transaction extends Twig_Extension
|
||||
{
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function formatAmountWithCode(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'formatAmountWithCode', function (string $amount, string $code): string {
|
||||
|
||||
return Amount::formatWithCode($code, $amount, true);
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFilters(): array
|
||||
{
|
||||
$filters = [
|
||||
$this->typeIconTransaction(),
|
||||
];
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFunctions(): array
|
||||
{
|
||||
$functions = [
|
||||
$this->formatAmountWithCode(),
|
||||
$this->transactionSourceAccount(),
|
||||
$this->transactionDestinationAccount(),
|
||||
$this->optionalJournalAmount(),
|
||||
$this->transactionBudgets(),
|
||||
$this->transactionCategories(),
|
||||
$this->splitJournalIndicator(),
|
||||
];
|
||||
|
||||
return $functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the extension.
|
||||
*
|
||||
* @return string The extension name
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'transaction';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function optionalJournalAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'optionalJournalAmount', function (int $journalId, string $transactionAmount, string $code, string $type): string {
|
||||
|
||||
$amount = strval(
|
||||
TransactionModel
|
||||
::where('transaction_journal_id', $journalId)
|
||||
->whereNull('deleted_at')
|
||||
->where('amount', '<', 0)
|
||||
->sum('amount')
|
||||
);
|
||||
|
||||
if ($type === TransactionType::DEPOSIT || $type === TransactionType::TRANSFER) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
if (
|
||||
bccomp($amount, $transactionAmount) !== 0
|
||||
&& bccomp($amount, bcmul($transactionAmount, '-1')) !== 0
|
||||
) {
|
||||
// not equal?
|
||||
return ' (' . Amount::formatWithCode($code, $amount, true) . ')';
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
public function splitJournalIndicator(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'splitJournalIndicator', function (int $journalId) {
|
||||
$count = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count();
|
||||
if ($count > 2) {
|
||||
return '<i class="fa fa-fw fa-share-alt-square" aria-hidden="true"></i>';
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionBudgets(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionBudgets', function (TransactionModel $transaction): string {
|
||||
// see if the transaction has a budget:
|
||||
$budgets = $transaction->budgets()->get();
|
||||
if ($budgets->count() === 0) {
|
||||
$budgets = $transaction->transactionJournal()->first()->budgets()->get();
|
||||
}
|
||||
if ($budgets->count() > 0) {
|
||||
$str = [];
|
||||
foreach ($budgets as $budget) {
|
||||
$str[] = sprintf('<a href="%s" title="%s">%s</a>', route('budgets.show', $budget->id), $budget->name, $budget->name);
|
||||
}
|
||||
|
||||
return join(', ', $str);
|
||||
}
|
||||
|
||||
|
||||
return '';
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionCategories(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionCategories', function (TransactionModel $transaction): string {
|
||||
// see if the transaction has a category:
|
||||
$categories = $transaction->categories()->get();
|
||||
if ($categories->count() === 0) {
|
||||
$categories = $transaction->transactionJournal()->first()->categories()->get();
|
||||
}
|
||||
if ($categories->count() > 0) {
|
||||
$str = [];
|
||||
foreach ($categories as $category) {
|
||||
$str[] = sprintf('<a href="%s" title="%s">%s</a>', route('categories.show', $category->id), $category->name, $category->name);
|
||||
}
|
||||
|
||||
return join(', ', $str);
|
||||
}
|
||||
|
||||
return '';
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionDestinationAccount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionDestinationAccount', function (TransactionModel $transaction): string {
|
||||
|
||||
$name = intval($transaction->account_encrypted) === 1 ? Crypt::decrypt($transaction->account_name) : $transaction->account_name;
|
||||
$id = intval($transaction->account_id);
|
||||
$type = $transaction->account_type;
|
||||
// if the amount is positive, assume that the current account (the one in $transaction) is indeed the destination account.
|
||||
|
||||
if (bccomp($transaction->transaction_amount, '0') === -1) {
|
||||
// if the amount is negative, find the opposing account and use that one:
|
||||
$journalId = $transaction->journal_id;
|
||||
/** @var TransactionModel $other */
|
||||
$other = TransactionModel
|
||||
::where('transaction_journal_id', $journalId)->where('transactions.id', '!=', $transaction->id)
|
||||
->where('amount', '=', bcmul($transaction->transaction_amount, '-1'))->where('identifier', $transaction->identifier)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->first(['transactions.account_id', 'accounts.encrypted', 'accounts.name', 'account_types.type']);
|
||||
$name = intval($other->encrypted) === 1 ? Crypt::decrypt($other->name) : $other->name;
|
||||
$id = $other->account_id;
|
||||
$type = $other->type;
|
||||
}
|
||||
|
||||
if ($type === AccountType::CASH) {
|
||||
return '<span class="text-success">(cash)</span>';
|
||||
}
|
||||
|
||||
return '<a title="' . e($name) . '" href="' . route('accounts.show', $id) . '">' . e($name) . '</a>';
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionSourceAccount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionSourceAccount', function (TransactionModel $transaction): string {
|
||||
|
||||
$name = intval($transaction->account_encrypted) === 1 ? Crypt::decrypt($transaction->account_name) : $transaction->account_name;
|
||||
$id = intval($transaction->account_id);
|
||||
$type = $transaction->account_type;
|
||||
// if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account.
|
||||
|
||||
if (bccomp($transaction->transaction_amount, '0') === 1) {
|
||||
// if the amount is positive, find the opposing account and use that one:
|
||||
$journalId = $transaction->journal_id;
|
||||
/** @var TransactionModel $other */
|
||||
$other = TransactionModel
|
||||
::where('transaction_journal_id', $journalId)->where('transactions.id', '!=', $transaction->id)
|
||||
->where('amount', '=', bcmul($transaction->transaction_amount, '-1'))->where('identifier', $transaction->identifier)
|
||||
->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id')
|
||||
->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
|
||||
->first(['transactions.account_id', 'accounts.encrypted', 'accounts.name', 'account_types.type']);
|
||||
$name = intval($other->encrypted) === 1 ? Crypt::decrypt($other->name) : $other->name;
|
||||
$id = $other->account_id;
|
||||
$type = $other->type;
|
||||
}
|
||||
|
||||
if ($type === AccountType::CASH) {
|
||||
return '<span class="text-success">(cash)</span>';
|
||||
}
|
||||
|
||||
return '<a title="' . e($name) . '" href="' . route('accounts.show', $id) . '">' . e($name) . '</a>';
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's 5.
|
||||
*
|
||||
* @return Twig_SimpleFilter
|
||||
*/
|
||||
public function typeIconTransaction(): Twig_SimpleFilter
|
||||
{
|
||||
return new Twig_SimpleFilter(
|
||||
'typeIconTransaction', function (TransactionModel $transaction): string {
|
||||
|
||||
switch ($transaction->transaction_type_type) {
|
||||
case TransactionType::WITHDRAWAL:
|
||||
$txt = '<i class="fa fa-long-arrow-left fa-fw" title="' . trans('firefly.withdrawal') . '"></i>';
|
||||
break;
|
||||
case TransactionType::DEPOSIT:
|
||||
$txt = '<i class="fa fa-long-arrow-right fa-fw" title="' . trans('firefly.deposit') . '"></i>';
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
$txt = '<i class="fa fa-fw fa-exchange" title="' . trans('firefly.transfer') . '"></i>';
|
||||
break;
|
||||
case TransactionType::OPENING_BALANCE:
|
||||
$txt = '<i class="fa-fw fa fa-ban" title="' . trans('firefly.openingBalance') . '"></i>';
|
||||
break;
|
||||
default:
|
||||
$txt = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $txt;
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
}
|
@@ -37,7 +37,7 @@
|
||||
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% include 'list.journals' with {sorting:true, accountPerspective: account} %}
|
||||
{% include 'list.journals-tasker' with {sorting:true} %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -39,7 +39,7 @@
|
||||
<h3 class="box-title">{{ 'transactions'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
{% include 'list.journals' with {sorting:true} %}
|
||||
{% include 'list.journals-tasker' with {sorting:true} %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -79,7 +79,7 @@
|
||||
|
||||
</div>
|
||||
<div class="box-body no-padding">
|
||||
{% include 'list.journals-tiny' with {'transactions': data[0],'account': data[1]} %}
|
||||
{% include 'list.journals-tiny-tasker' with {'transactions': data[0],'account': data[1]} %}
|
||||
</div>
|
||||
<div class="box-footer clearfix">
|
||||
<a class="btn btn-sm btn-default btn-flat pull-right"
|
||||
|
134
resources/views/list/journals-tasker.twig
Normal file
134
resources/views/list/journals-tasker.twig
Normal file
@@ -0,0 +1,134 @@
|
||||
{{ journals.render|raw }}
|
||||
|
||||
<table class="table table-hover table-compressed {% if sorting %}sortable-table{% endif %}">
|
||||
<thead>
|
||||
<tr class="ignore">
|
||||
<th class="hidden-xs no_select_boxes" colspan="2"> </th>
|
||||
<th class="hidden-xs select_boxes" colspan="2" style="display: none;"><input name="select_all" class="select_all" type="checkbox"/></th>
|
||||
<th>{{ trans('list.description') }}</th>
|
||||
<th>{{ trans('list.amount') }}</th>
|
||||
<th class="hidden-sm hidden-xs">{{ trans('list.date') }}</th>
|
||||
<th class="hidden-xs">{{ trans('list.from') }}</th>
|
||||
<th class="hidden-xs">{{ trans('list.to') }}</th>
|
||||
<!-- Hide budgets? -->
|
||||
{% if not hideBudgets %}
|
||||
<th class="hidden-xs"><i class="fa fa-tasks fa-fw" title="{{ trans('list.budget') }}"></i></th>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hide categories? -->
|
||||
{% if not hideCategories %}
|
||||
<th class="hidden-xs"><i class="fa fa-bar-chart fa-fw" title="{{ trans('list.category') }}"></i></th>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hide bills? -->
|
||||
{% if not hideBills %}
|
||||
<th class="hidden-xs"><i class="fa fa-fw fa-rotate-right" title="{{ trans('list.bill') }}"></i></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<!-- to be fixed:
|
||||
SORTING
|
||||
ATTACHMENT COUNT
|
||||
SPLIT JOURNAL INDICATOR
|
||||
|
||||
-->
|
||||
<tbody>
|
||||
{% for transaction in journals %}
|
||||
<tr class="drag" data-date="{{ transaction.date.format('Y-m-d') }}" data-id="{{ transaction.journal_id }}">
|
||||
<td class="hidden-xs">
|
||||
<div class="select_single" style="display:none;">
|
||||
<input name="select_all_single[]" class="select_all_single" value="{{ transaction.journal_id }}" type="checkbox"/>
|
||||
</div>
|
||||
<div class="btn-group btn-group-xs edit_buttons">
|
||||
{% if sorting %}
|
||||
<a href="#" class="handle btn btn-default btn-xs"><i class="fa fa-fw fa-arrows-v"></i></a>
|
||||
{% endif %}
|
||||
<a href="{{ route('transactions.edit',transaction.journal_id) }}" class="btn btn-xs btn-default"><i class="fa fa-fw fa-pencil"></i></a>
|
||||
<a href="{{ route('transactions.delete',transaction.journal_id) }}" class="btn btn-xs btn-danger"><i class="fa fa-fw fa-trash-o"></i></a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|typeIconTransaction }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ route('transactions.show',transaction.journal_id) }}">
|
||||
|
||||
{% if transaction.transaction_description|length > 0 %}
|
||||
{{ transaction.transaction_description }} ({{ transaction.description }})
|
||||
{% else %}
|
||||
{{ transaction.description }}
|
||||
{% endif %}
|
||||
</a>
|
||||
{{ splitJournalIndicator(transaction.journal_id) }}
|
||||
</td>
|
||||
<td>
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatAmountWithCode(transaction.transaction_amount, transaction.transaction_currency_code) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount,
|
||||
transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
|
||||
|
||||
</td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transactionDestinationAccount(transaction) }}
|
||||
</td>
|
||||
|
||||
<!-- Do NOT hide the budget? -->
|
||||
{% if not hideBudgets %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionBudgets(transaction) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- Do NOT hide the category? -->
|
||||
{% if not hideCategories %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionCategories(transaction) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- Do NOT hide the bill? -->
|
||||
{% if not hideBills %}
|
||||
<td class="hidden-xs">
|
||||
{% if transaction.bill_id %}
|
||||
<a href="{{ route('bills.show',transaction.bill_id) }}">{{ transaction.bill_name }}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row mass_edit_all" style="display: none;">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
<div class="mass_button_options btn-group btn-group" style="display:none;">
|
||||
<a href="#" class="btn btn-default mass_edit"><i class="fa fa-fw fa-pencil"></i> <span>{{ 'edit_selected'|_ }}</span></a>
|
||||
<a href="#" class="btn btn-danger mass_delete"><i class="fa fa-fw fa-trash"></i> <span>{{ 'delete_selected'|_ }}</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||
|
||||
<div class="mass_buttons btn-group btn-group pull-right">
|
||||
<a href="#" class="btn btn-default mass_select"><i class="fa fa-fw fa-check-square-o"></i> {{ 'select_transactions'|_ }}</a>
|
||||
<a href="#" class="btn btn-default mass_stop_select" style="display:none;"><i class="fa faw-fw fa-square-o"
|
||||
aria-hidden="true"></i> {{ 'stop_selection'|_ }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
{{ journals.render|raw }}
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var edit_selected_txt = "{{ 'edit_selected'|_ }}";
|
||||
var delete_selected_txt = "{{ 'delete_selected'|_ }}";
|
||||
</script>
|
25
resources/views/list/journals-tiny-tasker.twig
Normal file
25
resources/views/list/journals-tiny-tasker.twig
Normal file
@@ -0,0 +1,25 @@
|
||||
<div class="list-group">
|
||||
{% for transaction in transactions %}
|
||||
<a class="list-group-item" title="{{ transaction.date.formatLocalized(trans('config.month_and_day')) }}"
|
||||
{% if transaction.transaction_type_type == 'Opening balance' %}
|
||||
href="#"
|
||||
{% else %}
|
||||
href="{{ route('transactions.show',transaction.journal_id) }}"
|
||||
{% endif %}
|
||||
>
|
||||
{{ transaction|typeIconTransaction }}
|
||||
{% if transaction.transaction_description|length > 0 %}
|
||||
{{ transaction.transaction_description }} ({{ transaction.description }})
|
||||
{% else %}
|
||||
{{ transaction.description }}
|
||||
{% endif %}
|
||||
<span class="pull-right small">
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatAmountWithCode(transaction.transaction_amount, transaction.transaction_currency_code) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount,
|
||||
transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
92
resources/views/popup/list/journals-tasker.twig
Normal file
92
resources/views/popup/list/journals-tasker.twig
Normal file
@@ -0,0 +1,92 @@
|
||||
<table class="table table-hover table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>{{ trans('list.description') }}</th>
|
||||
<th>{{ trans('list.amount') }}</th>
|
||||
<th class="hidden-sm hidden-xs">{{ trans('list.date') }}</th>
|
||||
{% if not hideSource %}
|
||||
<th class="hidden-xs">{{ trans('list.from') }}</th>
|
||||
{% endif %}
|
||||
{% if not hideDestination %}
|
||||
<th class="hidden-xs">{{ trans('list.to') }}</th>
|
||||
{% endif %}
|
||||
<!-- Hide budgets? -->
|
||||
{% if not hideBudget %}
|
||||
<th class="hidden-xs"><i class="fa fa-tasks fa-fw" title="{{ trans('list.budget') }}"></i></th>
|
||||
{% endif %}
|
||||
|
||||
<!-- Hide categories? -->
|
||||
{% if not hideCategory %}
|
||||
<th class="hidden-xs"><i class="fa fa-bar-chart fa-fw" title="{{ trans('list.category') }}"></i></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--
|
||||
Make sum:
|
||||
{% set sum = 0 %}
|
||||
-->
|
||||
{% for transaction in journals %}
|
||||
<!-- add to sum
|
||||
{% set sum = (sum + transaction.transaction_amount) %}
|
||||
-->
|
||||
<tr class="drag" data-date="{{ transaction.date.format('Y-m-d') }}" data-id="{{ transaction.journal_id }}">
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|typeIconTransaction }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ route('transactions.show',transaction.journal_id) }}">
|
||||
{% if transaction.transaction_description|length > 0 %}
|
||||
{{ transaction.transaction_description }} ({{ transaction.description }})
|
||||
{% else %}
|
||||
{{ transaction.description }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatAmountWithCode(transaction.transaction_amount, transaction.transaction_currency_code) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount,
|
||||
transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
</td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
{% if not hideSource %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if not hideDestination %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionDestinationAccount(transaction) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- Do NOT hide the budget? -->
|
||||
{% if not hideBudget %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionBudgets(transaction) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- Do NOT hide the category? -->
|
||||
{% if not hideCategory %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionCategories(transaction) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="2" style="text-align: right;"><em>{{ 'sum'|_ }}:</em></td>
|
||||
<td>{{ sum|formatAmount }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
{{ journals.render|raw }}
|
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% set hideDestination = true %}
|
||||
{% include 'popup/list/journals.twig' %}
|
||||
{% include 'popup/list/journals-tasker.twig' %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
{% set hideBudget = true %}
|
||||
{% set hideSource = true %}
|
||||
{% set accountPerspective = account %}
|
||||
{% include 'popup/list/journals.twig' %}
|
||||
{% include 'popup/list/journals-tasker.twig' %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'close'|_ }}</button>
|
||||
|
@@ -62,7 +62,7 @@
|
||||
balance: auditData[account.id].endBalance|formatAmount
|
||||
})|raw }}
|
||||
</p>
|
||||
{% include 'reports/partials/journals-audit.twig' with {'journals': auditData[account.id].journals,'account':account} %}
|
||||
{% include 'reports/partials/journals-audit-tasker.twig' with {'journals': auditData[account.id].journals,'account':account} %}
|
||||
<p style="padding:10px;">
|
||||
{{ trans('firefly.audit_end_balance',
|
||||
{
|
||||
|
160
resources/views/reports/partials/journals-audit-tasker.twig
Normal file
160
resources/views/reports/partials/journals-audit-tasker.twig
Normal file
@@ -0,0 +1,160 @@
|
||||
{{ journals.render|raw }}
|
||||
|
||||
<table class="table table-hover table-compressed">
|
||||
<thead>
|
||||
<tr class="ignore">
|
||||
<th class="hide-buttons"> </th>
|
||||
<th class="hide-icon"> </th>
|
||||
|
||||
<th class="hide-description">{{ trans('list.description') }}</th>
|
||||
<th class="hide-balance_before">{{ trans('list.balance_before') }}</th>
|
||||
<th class="hide-amount">{{ trans('list.amount') }}</th>
|
||||
<th class="hide-balance_after">{{ trans('list.balance_after') }}</th>
|
||||
|
||||
<th class="hide-date">{{ trans('list.date') }}</th>
|
||||
<th class="hide-book_date">{{ trans('list.book_date') }}</th>
|
||||
<th class="hide-process_date">{{ trans('list.process_date') }}</th>
|
||||
<th class="hide-interest_date">{{ trans('list.interest_date') }}</th>
|
||||
|
||||
<!-- new optional fields (3x) -->
|
||||
<th class="hide-interest_date">{{ trans('list.due_date') }}</th>
|
||||
<th class="hide-payment_date">{{ trans('list.payment_date') }}</th>
|
||||
<th class="hide-invoice_date">{{ trans('list.invoice_date') }}</th>
|
||||
|
||||
<th class="hide-from">{{ trans('list.from') }}</th>
|
||||
<th class="hide-to">{{ trans('list.to') }}</th>
|
||||
|
||||
<th class="hide-budget"><i class="fa fa-tasks fa-fw" title="{{ trans('list.budget') }}"></i></th>
|
||||
<th class="hide-category"><i class="fa fa-bar-chart fa-fw" title="{{ trans('list.category') }}"></i></th>
|
||||
<th class="hide-bill">{{ trans('list.bill') }}</th>
|
||||
|
||||
<!-- more optional fields (2x) -->
|
||||
<th class="hide-internal_reference">{{ trans('list.internal_reference') }}</th>
|
||||
<th class="hide-notes">{{ trans('list.notes') }}</th>
|
||||
|
||||
<th class="hide-create_date">{{ trans('list.create_date') }}</th>
|
||||
<th class="hide-update_date">{{ trans('list.update_date') }}</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for transaction in journals %}
|
||||
<tr data-date="{{ transaction.date.format('Y-m-d') }}" data-id="{{ journal.id }}">
|
||||
<td class="hide-buttons">
|
||||
<div class="btn-group btn-group-xs">
|
||||
<a href="{{ route('transactions.edit',transaction.journal_id) }}" class="btn btn-xs btn-default"><i class="fa fa-fw fa-pencil"></i></a>
|
||||
<a href="{{ route('transactions.delete',transaction.journal_id) }}" class="btn btn-xs btn-danger"><i class="fa fa-fw fa-trash-o"></i></a></div>
|
||||
</td>
|
||||
<td class="hide-icon">{{ transaction|typeIconTransaction }}</td>
|
||||
|
||||
<td class="hide-description">
|
||||
<a href="{{ route('transactions.show',transaction.journal_id) }}">
|
||||
{% if transaction.transaction_description|length > 0 %}
|
||||
{{ transaction.transaction_description }} ({{ transaction.description }})
|
||||
{% else %}
|
||||
{{ transaction.description }}
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
<td class="hide-balance_before">{{ transaction.before|formatAmount }}</td>
|
||||
<td class="hide-amount">
|
||||
<!-- format amount of transaction -->
|
||||
{{ formatAmountWithCode(transaction.transaction_amount, transaction.transaction_currency_code) }}
|
||||
<!-- and then amount of journal itself. -->
|
||||
{{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount,
|
||||
transaction.transaction_currency_code, transaction.transaction_type_type) }}
|
||||
</td>
|
||||
<td class="hide-balance_after">{{ transaction.after|formatAmount }}</td>
|
||||
|
||||
<td class="hide-date">{{ transaction.date.formatLocalized(monthAndDayFormat) }}</td>
|
||||
<td class="hide-book_date">
|
||||
{% if transaction.transactionJournal.hasMeta('book_date') %}
|
||||
{{ transaction.transactionJournal.getMeta('book_date').formatLocalized(monthAndDayFormat) }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="hide-process_date">
|
||||
{% if transaction.transactionJournal.hasMeta('process_date') %}
|
||||
{{ transaction.transactionJournal.getMeta('process_date').formatLocalized(monthAndDayFormat) }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
<td class="hide-interest_date">
|
||||
{% if transaction.transactionJournal.hasMeta('interest_date') %}
|
||||
{{ transaction.transactionJournal.getMeta('interest_date').formatLocalized(monthAndDayFormat) }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
|
||||
<!-- new optional fields (3x) -->
|
||||
<td class="hide-due_date">
|
||||
{% if transaction.transactionJournal.hasMeta('due_date') %}
|
||||
{{ transaction.transactionJournal.getMeta('due_date').formatLocalized(monthAndDayFormat) }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
<td class="hide-payment_date">
|
||||
{% if transaction.transactionJournal.hasMeta('payment_date') %}
|
||||
{{ transaction.transactionJournal.getMeta('payment_date').formatLocalized(monthAndDayFormat) }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
<td class="hide-invoice_date">
|
||||
{% if transaction.transactionJournal.hasMeta('invoice_date') %}
|
||||
{{ transaction.transactionJournal.getMeta('invoice_date').formatLocalized(monthAndDayFormat) }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="hide-from">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
</td>
|
||||
<td class="hide-to">
|
||||
{{ transactionDestinationAccount(transaction) }}
|
||||
</td>
|
||||
|
||||
<td class="hide-budget">
|
||||
{{ transactionBudgets(transaction) }}
|
||||
</td>
|
||||
<td class="hide-category">
|
||||
{{ transactionCategories(transaction) }}
|
||||
</td>
|
||||
{% if transaction.bill_id %}
|
||||
<td class="hide-bill">
|
||||
<i class="fa fa-fw fa-rotate-right" title="{{ trans('list.bill') }}"></i> 
|
||||
<a href="{{ route('bills.show',transaction.bill_id) }}">{{ transaction.bill_name }}</a>
|
||||
</td>
|
||||
{% else %}
|
||||
<td class="hide-bill"> </td>
|
||||
{% endif %}
|
||||
|
||||
<!-- new optional fields (2x) -->
|
||||
<td class="hide-internal_reference">
|
||||
|
||||
{% if transaction.transactionJournal.hasMeta('internal_reference') %}
|
||||
{{ transaction.transactionJournal.getMeta('internal_reference') }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
<td class="hide-notes">
|
||||
|
||||
{% if transaction.transactionJournal.hasMeta('notes') %}
|
||||
{{ transaction.transactionJournal.getMeta('notes')|nl2br }}
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
|
||||
<td class="hide-create_date">
|
||||
{{ transaction.transactionJournal.created_at.formatLocalized(dateTimeFormat) }}
|
||||
</td>
|
||||
|
||||
<td class="hide-update_date">
|
||||
{{ transaction.transactionJournal.updated_at.formatLocalized(dateTimeFormat) }}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ journals.render|raw }}
|
Reference in New Issue
Block a user