mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Various cleanup in transaction and journal display code.
This commit is contained in:
parent
b4dc70244a
commit
bb46d034cd
@ -73,6 +73,7 @@ class JournalCollector implements JournalCollectorInterface
|
||||
'transaction_journals.encrypted',
|
||||
'transaction_types.type as transaction_type_type',
|
||||
'transaction_journals.bill_id',
|
||||
'transaction_journals.updated_at',
|
||||
'bills.name as bill_name',
|
||||
'bills.name_encrypted as bill_name_encrypted',
|
||||
|
||||
|
@ -125,11 +125,11 @@ class TransactionController extends Controller
|
||||
$collector = app(JournalCollectorInterface::class);
|
||||
$collector->setAllAssetAccounts()->setRange($start, $end)->setTypes($types)->setLimit($pageSize)->setPage($page)->withOpposingAccount();
|
||||
$collector->removeFilter(InternalTransferFilter::class);
|
||||
$journals = $collector->getPaginatedJournals();
|
||||
$journals->setPath($path);
|
||||
$transactions = $collector->getPaginatedJournals();
|
||||
$transactions->setPath($path);
|
||||
|
||||
|
||||
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'journals', 'periods', 'start', 'end', 'moment'));
|
||||
return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'transactions', 'periods', 'start', 'end', 'moment'));
|
||||
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,8 @@ use FireflyIII\Support\Steam;
|
||||
use FireflyIII\Support\Twig\AmountFormat;
|
||||
use FireflyIII\Support\Twig\General;
|
||||
use FireflyIII\Support\Twig\Journal;
|
||||
use FireflyIII\Support\Twig\Loader\TransactionJournalLoader;
|
||||
use FireflyIII\Support\Twig\Loader\TransactionLoader;
|
||||
use FireflyIII\Support\Twig\PiggyBank;
|
||||
use FireflyIII\Support\Twig\Rule;
|
||||
use FireflyIII\Support\Twig\Transaction;
|
||||
@ -83,6 +85,8 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
);
|
||||
$config = app('config');
|
||||
Twig::addExtension(new Functions($config));
|
||||
Twig::addRuntimeLoader(new TransactionLoader);
|
||||
Twig::addRuntimeLoader(new TransactionJournalLoader);
|
||||
Twig::addExtension(new PiggyBank);
|
||||
Twig::addExtension(new General);
|
||||
Twig::addExtension(new Journal);
|
||||
|
@ -124,6 +124,7 @@ class JournalTasker implements JournalTaskerInterface
|
||||
);
|
||||
|
||||
$transactions = [];
|
||||
$transactionType = $journal->transactionType->type;
|
||||
|
||||
/** @var Transaction $entry */
|
||||
foreach ($set as $entry) {
|
||||
@ -132,6 +133,8 @@ class JournalTasker implements JournalTaskerInterface
|
||||
$budget = $entry->budgets->first();
|
||||
$category = $entry->categories->first();
|
||||
$transaction = [
|
||||
'journal_type' => $transactionType,
|
||||
'updated_at' => $journal->updated_at,
|
||||
'source_id' => $entry->id,
|
||||
'source_amount' => $entry->amount,
|
||||
'foreign_source_amount' => $entry->foreign_amount,
|
||||
|
@ -267,140 +267,4 @@ class Amount
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function journalAmount(TransactionJournal $journal, bool $coloured = true): string
|
||||
{
|
||||
$amounts = [];
|
||||
$transactions = $journal->transactions()->where('amount', '>', 0)->get();
|
||||
/** @var TransactionModel $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
// model some fields to fit "transactionAmount()":
|
||||
$transaction->transaction_amount = $transaction->amount;
|
||||
$transaction->transaction_foreign_amount = $transaction->foreign_amount;
|
||||
$transaction->transaction_type_type = $journal->transactionType->type;
|
||||
$transaction->transaction_currency_symbol = $transaction->transactionCurrency->symbol;
|
||||
$transaction->transaction_currency_dp = $transaction->transactionCurrency->decimal_places;
|
||||
if (!is_null($transaction->foreign_currency_id)) {
|
||||
$transaction->foreign_currency_symbol = $transaction->foreignCurrency->symbol;
|
||||
$transaction->foreign_currency_dp = $transaction->foreignCurrency->decimal_places;
|
||||
}
|
||||
|
||||
$amounts[] = $this->transactionAmount($transaction, $coloured);
|
||||
}
|
||||
|
||||
return join(' / ', $amounts);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionJournal $journal
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function journalTotalAmount(TransactionJournal $journal, bool $coloured = true): string
|
||||
{
|
||||
$transactions = $journal->transactions()->where('amount', '>', 0)->get();
|
||||
$totals = [];
|
||||
$type = $journal->transactionType->type;
|
||||
/** @var TransactionModel $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
// model some fields to fit "transactionAmount()":
|
||||
$currencyId = $transaction->transaction_currency_id;
|
||||
|
||||
if (!isset($totals[$currencyId])) {
|
||||
$totals[$currencyId] = [
|
||||
'amount' => '0',
|
||||
'symbol' => $transaction->transactionCurrency->symbol,
|
||||
'dp' => $transaction->transactionCurrency->decimal_places,
|
||||
];
|
||||
}
|
||||
$totals[$currencyId]['amount'] = bcadd($transaction->amount, $totals[$currencyId]['amount']);
|
||||
|
||||
if (!is_null($transaction->foreign_currency_id)) {
|
||||
$foreignId = $transaction->foreign_currency_id;
|
||||
if (!isset($totals[$foreignId])) {
|
||||
$totals[$foreignId] = [
|
||||
'amount' => '0',
|
||||
'symbol' => $transaction->foreignCurrency->symbol,
|
||||
'dp' => $transaction->foreignCurrency->decimal_places,
|
||||
];
|
||||
}
|
||||
$totals[$foreignId]['amount'] = bcadd($transaction->foreign_amount, $totals[$foreignId]['amount']);
|
||||
}
|
||||
}
|
||||
$array = [];
|
||||
foreach ($totals as $total) {
|
||||
$currency = new TransactionCurrency;
|
||||
$currency->symbol = $total['symbol'];
|
||||
$currency->decimal_places = $total['dp'];
|
||||
if ($type === TransactionType::WITHDRAWAL) {
|
||||
$total['amount'] = bcmul($total['amount'], '-1');
|
||||
}
|
||||
$array[] = $this->formatAnything($currency, $total['amount']);
|
||||
}
|
||||
|
||||
return join(' / ', $array);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This formats a transaction, IF that transaction has been "collected" using the JournalCollector.
|
||||
*
|
||||
* @param TransactionModel $transaction
|
||||
* @param bool $coloured
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function transactionAmount(TransactionModel $transaction, bool $coloured = true): string
|
||||
{
|
||||
$amount = bcmul(app('steam')->positive(strval($transaction->transaction_amount)), '-1');
|
||||
|
||||
$format = '%s';
|
||||
|
||||
if ($transaction->transaction_type_type === TransactionType::DEPOSIT) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
if ($transaction->transaction_type_type === TransactionType::TRANSFER) {
|
||||
$amount = app('steam')->positive($amount);
|
||||
$coloured = false;
|
||||
$format = '<span class="text-info">%s</span>';
|
||||
}
|
||||
if ($transaction->transaction_type_type === TransactionType::OPENING_BALANCE) {
|
||||
$amount = strval($transaction->transaction_amount);
|
||||
}
|
||||
|
||||
$currency = new TransactionCurrency;
|
||||
$currency->symbol = $transaction->transaction_currency_symbol;
|
||||
$currency->decimal_places = $transaction->transaction_currency_dp;
|
||||
$str = sprintf($format, $this->formatAnything($currency, $amount, $coloured));
|
||||
|
||||
|
||||
if (!is_null($transaction->transaction_foreign_amount)) {
|
||||
$amount = bcmul(app('steam')->positive(strval($transaction->transaction_foreign_amount)), '-1');
|
||||
if ($transaction->transaction_type_type === TransactionType::DEPOSIT) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
|
||||
if ($transaction->transaction_type_type === TransactionType::TRANSFER) {
|
||||
$amount = app('steam')->positive($amount);
|
||||
$coloured = false;
|
||||
$format = '<span class="text-info">%s</span>';
|
||||
}
|
||||
|
||||
$currency = new TransactionCurrency;
|
||||
$currency->symbol = $transaction->foreign_currency_symbol;
|
||||
$currency->decimal_places = $transaction->foreign_currency_dp;
|
||||
$str .= ' (' . sprintf($format, $this->formatAnything($currency, $amount, $coloured)) . ')';
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class CacheProperties
|
||||
{
|
||||
|
||||
/** @var string */
|
||||
protected $md5 = '';
|
||||
protected $hash = '';
|
||||
/** @var Collection */
|
||||
protected $properties;
|
||||
|
||||
@ -66,15 +66,15 @@ class CacheProperties
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
return Cache::get($this->md5);
|
||||
return Cache::get($this->hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMd5(): string
|
||||
public function getHash(): string
|
||||
{
|
||||
return $this->md5;
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,9 +85,9 @@ class CacheProperties
|
||||
if (getenv('APP_ENV') === 'testing') {
|
||||
return false;
|
||||
}
|
||||
$this->md5();
|
||||
$this->hash();
|
||||
|
||||
return Cache::has($this->md5);
|
||||
return Cache::has($this->hash);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,18 +95,18 @@ class CacheProperties
|
||||
*/
|
||||
public function store($data)
|
||||
{
|
||||
Cache::forever($this->md5, $data);
|
||||
Cache::forever($this->hash, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function md5()
|
||||
private function hash()
|
||||
{
|
||||
$this->md5 = '';
|
||||
$content = '';
|
||||
foreach ($this->properties as $property) {
|
||||
$this->md5 .= json_encode($property);
|
||||
$content .= json_encode($property);
|
||||
}
|
||||
$this->md5 = md5($this->md5);
|
||||
$this->hash = substr(sha1($content), 0, 16);
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ class ExpandedForm
|
||||
$options['step'] = 'any';
|
||||
unset($options['placeholder']);
|
||||
|
||||
$html = view('form.number', compact( 'classes', 'name', 'label', 'value', 'options'))->render();
|
||||
$html = view('form.number', compact('classes', 'name', 'label', 'value', 'options'))->render();
|
||||
|
||||
return $html;
|
||||
}
|
||||
@ -586,7 +586,7 @@ class ExpandedForm
|
||||
$value = $this->fillFieldValue($name, $value);
|
||||
$options['step'] = 'any';
|
||||
$defaultCurrency = isset($options['currency']) ? $options['currency'] : Amt::getDefaultCurrency();
|
||||
$currencies = Amt::getAllCurrencies();
|
||||
$currencies = app('amount')->getAllCurrencies();
|
||||
unset($options['currency']);
|
||||
unset($options['placeholder']);
|
||||
|
||||
|
47
app/Support/SingleCacheProperties.php
Normal file
47
app/Support/SingleCacheProperties.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* SingleCacheProperties.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support;
|
||||
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CacheProperties
|
||||
*
|
||||
* @package FireflyIII\Support
|
||||
*/
|
||||
class SingleCacheProperties extends CacheProperties
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->properties = new Collection;
|
||||
if (auth()->check()) {
|
||||
$this->addProperty(auth()->user()->id);
|
||||
}
|
||||
}
|
||||
}
|
@ -59,9 +59,6 @@ class AmountFormat extends Twig_Extension
|
||||
return [
|
||||
$this->formatAmountByAccount(),
|
||||
$this->formatAmountBySymbol(),
|
||||
$this->transactionAmount(),
|
||||
$this->journalAmount(),
|
||||
$this->journalTotalAmount(),
|
||||
$this->formatDestinationAfter(),
|
||||
$this->formatDestinationBefore(),
|
||||
$this->formatSourceAfter(),
|
||||
@ -274,43 +271,4 @@ class AmountFormat extends Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function journalAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'journalAmount', function (TransactionJournal $journal): string {
|
||||
|
||||
return app('amount')->journalAmount($journal, true);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function journalTotalAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'journalTotalAmount', function (TransactionJournal $journal): string {
|
||||
|
||||
return app('amount')->journalTotalAmount($journal, true);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
protected function transactionAmount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionAmount', function (TransactionModel $transaction): string {
|
||||
|
||||
return app('amount')->transactionAmount($transaction, true);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
487
app/Support/Twig/Extension/Transaction.php
Normal file
487
app/Support/Twig/Extension/Transaction.php
Normal file
@ -0,0 +1,487 @@
|
||||
<?php
|
||||
/**
|
||||
* Transaction.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig\Extension;
|
||||
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Transaction as TransactionModel;
|
||||
use FireflyIII\Models\TransactionCurrency;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\SingleCacheProperties;
|
||||
use Lang;
|
||||
use Twig_Extension;
|
||||
|
||||
/**
|
||||
* Class Transaction
|
||||
*
|
||||
* @package FireflyIII\Support\Twig\Extension
|
||||
*/
|
||||
class Transaction extends Twig_Extension
|
||||
{
|
||||
/**
|
||||
* Can show the amount of a transaction, if that transaction has been collected by the journal collector.
|
||||
*
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function amount(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('transaction-amount');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
$amount = bcmul(app('steam')->positive(strval($transaction->transaction_amount)), '-1');
|
||||
$format = '%s';
|
||||
$coloured = true;
|
||||
|
||||
if ($transaction->transaction_type_type === TransactionType::DEPOSIT) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
if ($transaction->transaction_type_type === TransactionType::TRANSFER) {
|
||||
$amount = app('steam')->positive($amount);
|
||||
$coloured = false;
|
||||
$format = '<span class="text-info">%s</span>';
|
||||
}
|
||||
if ($transaction->transaction_type_type === TransactionType::OPENING_BALANCE) {
|
||||
$amount = strval($transaction->transaction_amount);
|
||||
}
|
||||
|
||||
$currency = new TransactionCurrency;
|
||||
$currency->symbol = $transaction->transaction_currency_symbol;
|
||||
$currency->decimal_places = $transaction->transaction_currency_dp;
|
||||
$str = sprintf($format, app('amount')->formatAnything($currency, $amount, $coloured));
|
||||
|
||||
|
||||
if (!is_null($transaction->transaction_foreign_amount)) {
|
||||
$amount = bcmul(app('steam')->positive(strval($transaction->transaction_foreign_amount)), '-1');
|
||||
if ($transaction->transaction_type_type === TransactionType::DEPOSIT) {
|
||||
$amount = bcmul($amount, '-1');
|
||||
}
|
||||
|
||||
|
||||
if ($transaction->transaction_type_type === TransactionType::TRANSFER) {
|
||||
$amount = app('steam')->positive($amount);
|
||||
$coloured = false;
|
||||
$format = '<span class="text-info">%s</span>';
|
||||
}
|
||||
|
||||
$currency = new TransactionCurrency;
|
||||
$currency->symbol = $transaction->foreign_currency_symbol;
|
||||
$currency->decimal_places = $transaction->foreign_currency_dp;
|
||||
$str .= ' (' . sprintf($format, app('amount')->formatAnything($currency, $amount, $coloured)) . ')';
|
||||
}
|
||||
$cache->store($str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function amountArray(array $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('transaction-array-amount');
|
||||
$cache->addProperty($transaction['source_id']);
|
||||
$cache->addProperty($transaction['destination_id']);
|
||||
$cache->addProperty($transaction['updated_at']);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
// first display amount:
|
||||
$amount = $transaction['journal_type'] === TransactionType::WITHDRAWAL ? $transaction['source_amount']
|
||||
: $transaction['destination_amount'];
|
||||
$fakeCurrency = new TransactionCurrency;
|
||||
$fakeCurrency->decimal_places = $transaction['transaction_currency_dp'];
|
||||
$fakeCurrency->symbol = $transaction['transaction_currency_symbol'];
|
||||
$string = app('amount')->formatAnything($fakeCurrency, $amount, true);
|
||||
|
||||
// then display (if present) the foreign amount:
|
||||
if(!is_null($transaction['foreign_source_amount'])) {
|
||||
$amount = $transaction['journal_type'] === TransactionType::WITHDRAWAL ? $transaction['foreign_source_amount']
|
||||
: $transaction['foreign_destination_amount'];
|
||||
$fakeCurrency = new TransactionCurrency;
|
||||
$fakeCurrency->decimal_places = $transaction['foreign_currency_dp'];
|
||||
$fakeCurrency->symbol = $transaction['foreign_currency_symbol'];
|
||||
$string .= ' ('.app('amount')->formatAnything($fakeCurrency, $amount, true).')';
|
||||
}
|
||||
$cache->store($string);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function budgets(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('transaction-budgets');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
// journal has a budget:
|
||||
if (isset($transaction->transaction_journal_budget_id)) {
|
||||
$name = app('steam')->tryDecrypt($transaction->transaction_journal_budget_name);
|
||||
$txt = sprintf('<a href="%s" title="%s">%s</a>', route('budgets.show', [$transaction->transaction_journal_budget_id]), $name, $name);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
// transaction has a budget
|
||||
if (isset($transaction->transaction_budget_id)) {
|
||||
$name = app('steam')->tryDecrypt($transaction->transaction_budget_name);
|
||||
$txt = sprintf('<a href="%s" title="%s">%s</a>', route('budgets.show', [$transaction->transaction_budget_id]), $name, $name);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
$txt = join(', ', $str);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
$txt = '';
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function categories(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('transaction-categories');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
// journal has a category:
|
||||
if (isset($transaction->transaction_journal_category_id)) {
|
||||
$name = app('steam')->tryDecrypt($transaction->transaction_journal_category_name);
|
||||
$txt = sprintf('<a href="%s" title="%s">%s</a>', route('categories.show', [$transaction->transaction_journal_category_id]), $name, $name);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
// transaction has a category:
|
||||
if (isset($transaction->transaction_category_id)) {
|
||||
$name = app('steam')->tryDecrypt($transaction->transaction_category_name);
|
||||
$txt = sprintf('<a href="%s" title="%s">%s</a>', route('categories.show', [$transaction->transaction_category_id]), $name, $name);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
$txt = join(', ', $str);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
$txt = '';
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function description(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('description');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$description = $transaction->description;
|
||||
if (strlen(strval($transaction->transaction_description)) > 0) {
|
||||
$description = $transaction->transaction_description . '(' . $transaction->description . ')';
|
||||
}
|
||||
|
||||
$cache->store($description);
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function destinationAccount(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('transaction-destination');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
$name = app('steam')->tryDecrypt($transaction->account_name);
|
||||
$transactionId = intval($transaction->account_id);
|
||||
$type = $transaction->account_type;
|
||||
|
||||
// name is present in object, use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === -1 && !is_null($transaction->opposing_account_id)) {
|
||||
$name = $transaction->opposing_account_name;
|
||||
$transactionId = intval($transaction->opposing_account_id);
|
||||
$type = $transaction->opposing_account_type;
|
||||
}
|
||||
|
||||
// Find the opposing account and use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === -1 && is_null($transaction->opposing_account_id)) {
|
||||
// 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 = app('steam')->tryDecrypt($other->name);
|
||||
$transactionId = $other->account_id;
|
||||
$type = $other->type;
|
||||
}
|
||||
|
||||
if ($type === AccountType::CASH) {
|
||||
$txt = '<span class="text-success">(' . trans('firefly.cash') . ')</span>';
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
$txt = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$transactionId]));
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function hasAttachments(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('attachments');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$journalId = intval($transaction->journal_id);
|
||||
$count = Attachment::whereNull('deleted_at')
|
||||
->where('attachable_type', 'FireflyIII\Models\TransactionJournal')
|
||||
->where('attachable_id', $journalId)
|
||||
->count();
|
||||
if ($count > 0) {
|
||||
$res = sprintf('<i class="fa fa-paperclip" title="%s"></i>', Lang::choice('firefly.nr_of_attachments', $count, ['count' => $count]));
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
$res = '';
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function icon(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('icon');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
switch ($transaction->transaction_type_type) {
|
||||
case TransactionType::WITHDRAWAL:
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-left fa-fw" title="%s"></i>', trans('firefly.withdrawal'));
|
||||
break;
|
||||
case TransactionType::DEPOSIT:
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-right fa-fw" title="%s"></i>', trans('firefly.deposit'));
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
$txt = sprintf('<i class="fa fa-fw fa-exchange" title="%s"></i>', trans('firefly.transfer'));
|
||||
break;
|
||||
case TransactionType::OPENING_BALANCE:
|
||||
$txt = sprintf('<i class="fa-fw fa fa-star-o" title="%s"></i>', trans('firefly.openingBalance'));
|
||||
break;
|
||||
default:
|
||||
$txt = '';
|
||||
break;
|
||||
}
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function isSplit(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('split');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$journalId = intval($transaction->journal_id);
|
||||
$count = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count();
|
||||
if ($count > 2) {
|
||||
$res = '<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>';
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
$res = '';
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sourceAccount(TransactionModel $transaction): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('transaction-source');
|
||||
$cache->addProperty($transaction->id);
|
||||
$cache->addProperty($transaction->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
// if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account.
|
||||
$name = app('steam')->tryDecrypt($transaction->account_name);
|
||||
$transactionId = intval($transaction->account_id);
|
||||
$type = $transaction->account_type;
|
||||
|
||||
// name is present in object, use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === 1 && !is_null($transaction->opposing_account_id)) {
|
||||
$name = $transaction->opposing_account_name;
|
||||
$transactionId = intval($transaction->opposing_account_id);
|
||||
$type = $transaction->opposing_account_type;
|
||||
}
|
||||
// Find the opposing account and use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === 1 && is_null($transaction->opposing_account_id)) {
|
||||
$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 = app('steam')->tryDecrypt(intval($other->encrypted), $other->name);
|
||||
$transactionId = $other->account_id;
|
||||
$type = $other->type;
|
||||
}
|
||||
|
||||
if ($type === AccountType::CASH) {
|
||||
$txt = '<span class="text-success">(' . trans('firefly.cash') . ')</span>';
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
$txt = sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$transactionId]));
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
}
|
||||
}
|
92
app/Support/Twig/Extension/TransactionJournal.php
Normal file
92
app/Support/Twig/Extension/TransactionJournal.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionJournal.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig\Extension;
|
||||
|
||||
use FireflyIII\Models\Transaction;
|
||||
use FireflyIII\Models\TransactionJournal as JournalModel;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\SingleCacheProperties;
|
||||
use Twig_Extension;
|
||||
|
||||
class TransactionJournal extends Twig_Extension
|
||||
{
|
||||
|
||||
/**
|
||||
* @param JournalModel $journal
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function totalAmount(JournalModel $journal): string
|
||||
{
|
||||
$cache = new SingleCacheProperties;
|
||||
$cache->addProperty('total-amount');
|
||||
$cache->addProperty($journal->id);
|
||||
$cache->addProperty($journal->updated_at);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
|
||||
$transactions = $journal->transactions()->where('amount', '>', 0)->get();
|
||||
$totals = [];
|
||||
$type = $journal->transactionType->type;
|
||||
/** @var Transaction $transaction */
|
||||
foreach ($transactions as $transaction) {
|
||||
$currencyId = $transaction->transaction_currency_id;
|
||||
$currency = $transaction->transactionCurrency;
|
||||
|
||||
if (!isset($totals[$currencyId])) {
|
||||
$totals[$currencyId] = [
|
||||
'amount' => '0',
|
||||
'currency' => $currency,
|
||||
];
|
||||
}
|
||||
$totals[$currencyId]['amount'] = bcadd($transaction->amount, $totals[$currencyId]['amount']);
|
||||
|
||||
if (!is_null($transaction->foreign_currency_id)) {
|
||||
$foreignId = $transaction->foreign_currency_id;
|
||||
$foreign = $transaction->foreignCurrency;
|
||||
if (!isset($totals[$foreignId])) {
|
||||
$totals[$foreignId] = [
|
||||
'amount' => '0',
|
||||
'currency' => $foreign,
|
||||
];
|
||||
}
|
||||
$totals[$foreignId]['amount'] = bcadd($transaction->foreign_amount, $totals[$foreignId]['amount']);
|
||||
}
|
||||
}
|
||||
$array = [];
|
||||
foreach ($totals as $total) {
|
||||
if ($type === TransactionType::WITHDRAWAL) {
|
||||
$total['amount'] = bcmul($total['amount'], '-1');
|
||||
}
|
||||
$array[] = app('amount')->formatAnything($total['currency'], $total['amount']);
|
||||
}
|
||||
$txt = join(' / ', $array);
|
||||
$cache->store($txt);
|
||||
|
||||
return $txt;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -32,7 +32,7 @@ use FireflyIII\Support\CacheProperties;
|
||||
use Twig_Extension;
|
||||
use Twig_SimpleFilter;
|
||||
use Twig_SimpleFunction;
|
||||
|
||||
use FireflyIII\Support\Twig\Extension\TransactionJournal as TransactionJournalExtension;
|
||||
/**
|
||||
* Class Journal
|
||||
*
|
||||
@ -83,6 +83,7 @@ class Journal extends Twig_Extension
|
||||
{
|
||||
$filters = [
|
||||
$this->typeIcon(),
|
||||
new Twig_SimpleFilter('journalTotalAmount', [TransactionJournalExtension::class, 'totalAmount'], ['is_safe' => ['html']]),
|
||||
];
|
||||
|
||||
return $filters;
|
||||
|
57
app/Support/Twig/Loader/TransactionJournalLoader.php
Normal file
57
app/Support/Twig/Loader/TransactionJournalLoader.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionJournalLoader.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig\Loader;
|
||||
|
||||
|
||||
use FireflyIII\Support\Twig\Extension\TransactionJournal;
|
||||
use Twig_RuntimeLoaderInterface;
|
||||
|
||||
/**
|
||||
* Class TransactionJournalLoader
|
||||
*
|
||||
* @package FireflyIII\Support\Twig\Extension
|
||||
*/
|
||||
class TransactionJournalLoader implements Twig_RuntimeLoaderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Creates the runtime implementation of a Twig element (filter/function/test).
|
||||
*
|
||||
* @param string $class A runtime class
|
||||
*
|
||||
* @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class
|
||||
*/
|
||||
public function load($class)
|
||||
{
|
||||
// implement the logic to create an instance of $class
|
||||
// and inject its dependencies
|
||||
// most of the time, it means using your dependency injection container
|
||||
|
||||
if (TransactionJournal::class === $class) {
|
||||
return app(TransactionJournal::class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
57
app/Support/Twig/Loader/TransactionLoader.php
Normal file
57
app/Support/Twig/Loader/TransactionLoader.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* TransactionLoader.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
*
|
||||
* This file is part of Firefly III.
|
||||
*
|
||||
* Firefly III is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Firefly III is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig\Loader;
|
||||
|
||||
|
||||
use FireflyIII\Support\Twig\Extension\Transaction;
|
||||
use Twig_RuntimeLoaderInterface;
|
||||
|
||||
/**
|
||||
* Class TransactionLoader
|
||||
*
|
||||
* @package FireflyIII\Support\Twig\Extension
|
||||
*/
|
||||
class TransactionLoader implements Twig_RuntimeLoaderInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Creates the runtime implementation of a Twig element (filter/function/test).
|
||||
*
|
||||
* @param string $class A runtime class
|
||||
*
|
||||
* @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class
|
||||
*/
|
||||
public function load($class)
|
||||
{
|
||||
// implement the logic to create an instance of $class
|
||||
// and inject its dependencies
|
||||
// most of the time, it means using your dependency injection container
|
||||
|
||||
if (Transaction::class === $class) {
|
||||
return app(Transaction::class);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -23,12 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Twig;
|
||||
|
||||
use FireflyIII\Models\AccountType;
|
||||
use FireflyIII\Models\Attachment;
|
||||
use FireflyIII\Models\Transaction as TransactionModel;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Support\CacheProperties;
|
||||
use Lang;
|
||||
use FireflyIII\Support\Twig\Extension\Transaction as TransactionExtension;
|
||||
use Steam;
|
||||
use Twig_Extension;
|
||||
use Twig_SimpleFilter;
|
||||
@ -41,48 +37,22 @@ use Twig_SimpleFunction;
|
||||
*/
|
||||
class Transaction extends Twig_Extension
|
||||
{
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function attachmentIndicator(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'attachmentIndicator', function (int $journalId) {
|
||||
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('attachments_journal');
|
||||
$cache->addProperty($journalId);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$count = Attachment::whereNull('deleted_at')
|
||||
->where('attachable_type', 'FireflyIII\Models\TransactionJournal')
|
||||
->where('attachable_id', $journalId)
|
||||
->count();
|
||||
if ($count > 0) {
|
||||
$res = sprintf('<i class="fa fa-paperclip" title="%s"></i>', Lang::choice('firefly.nr_of_attachments', $count, ['count' => $count]));
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
$res = '';
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getFilters(): array
|
||||
{
|
||||
$filters = [
|
||||
$this->typeIconTransaction(),
|
||||
new Twig_SimpleFilter('transactionIcon', [TransactionExtension::class, 'icon'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionDescription', [TransactionExtension::class, 'description']),
|
||||
new Twig_SimpleFilter('transactionIsSplit', [TransactionExtension::class, 'isSplit'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionHasAtt', [TransactionExtension::class, 'hasAttachments'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionAmount', [TransactionExtension::class, 'amount'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionArrayAmount', [TransactionExtension::class, 'amountArray'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionBudgets', [TransactionExtension::class, 'budgets'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionCategories', [TransactionExtension::class, 'categories'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionSourceAccount', [TransactionExtension::class, 'sourceAccount'], ['is_safe' => ['html']]),
|
||||
new Twig_SimpleFilter('transactionDestinationAccount', [TransactionExtension::class, 'destinationAccount'], ['is_safe' => ['html']]),
|
||||
];
|
||||
|
||||
return $filters;
|
||||
@ -94,14 +64,8 @@ class Transaction extends Twig_Extension
|
||||
public function getFunctions(): array
|
||||
{
|
||||
$functions = [
|
||||
$this->transactionSourceAccount(),
|
||||
$this->transactionDestinationAccount(),
|
||||
$this->transactionBudgets(),
|
||||
$this->transactionIdBudgets(),
|
||||
$this->transactionCategories(),
|
||||
$this->transactionIdCategories(),
|
||||
$this->splitJournalIndicator(),
|
||||
$this->attachmentIndicator(),
|
||||
];
|
||||
|
||||
return $functions;
|
||||
@ -117,107 +81,6 @@ class Transaction extends Twig_Extension
|
||||
return 'transaction';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function splitJournalIndicator(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'splitJournalIndicator', function (int $journalId) {
|
||||
|
||||
$cache = new CacheProperties;
|
||||
$cache->addProperty('is_split_journal');
|
||||
$cache->addProperty($journalId);
|
||||
if ($cache->has()) {
|
||||
return $cache->get();
|
||||
}
|
||||
$count = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count();
|
||||
if ($count > 2) {
|
||||
$res = '<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>';
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
$res = '';
|
||||
$cache->store($res);
|
||||
|
||||
return $res;
|
||||
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionBudgets(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionBudgets', function (TransactionModel $transaction): string {
|
||||
return $this->getTransactionBudgets($transaction);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionCategories(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionCategories', function (TransactionModel $transaction): string {
|
||||
return $this->getTransactionCategories($transaction);
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionDestinationAccount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionDestinationAccount', function (TransactionModel $transaction): string {
|
||||
|
||||
$name = Steam::decrypt(intval($transaction->account_encrypted), $transaction->account_name);
|
||||
$transactionId = intval($transaction->account_id);
|
||||
$type = $transaction->account_type;
|
||||
|
||||
// name is present in object, use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === -1 && !is_null($transaction->opposing_account_id)) {
|
||||
$name = $transaction->opposing_account_name;
|
||||
$transactionId = intval($transaction->opposing_account_id);
|
||||
$type = $transaction->opposing_account_type;
|
||||
}
|
||||
|
||||
// Find the opposing account and use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === -1 && is_null($transaction->opposing_account_id)) {
|
||||
// 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 = Steam::decrypt(intval($other->encrypted), $other->name);
|
||||
$transactionId = $other->account_id;
|
||||
$type = $other->type;
|
||||
}
|
||||
|
||||
if ($type === AccountType::CASH) {
|
||||
return '<span class="text-success">(cash)</span>';
|
||||
}
|
||||
|
||||
return sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$transactionId]));
|
||||
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
@ -247,84 +110,6 @@ class Transaction extends Twig_Extension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Twig_SimpleFunction
|
||||
*/
|
||||
public function transactionSourceAccount(): Twig_SimpleFunction
|
||||
{
|
||||
return new Twig_SimpleFunction(
|
||||
'transactionSourceAccount', function (TransactionModel $transaction): string {
|
||||
|
||||
// if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account.
|
||||
$name = Steam::decrypt(intval($transaction->account_encrypted), $transaction->account_name);
|
||||
$transactionId = intval($transaction->account_id);
|
||||
$type = $transaction->account_type;
|
||||
|
||||
// name is present in object, use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === 1 && !is_null($transaction->opposing_account_id)) {
|
||||
$name = $transaction->opposing_account_name;
|
||||
$transactionId = intval($transaction->opposing_account_id);
|
||||
$type = $transaction->opposing_account_type;
|
||||
}
|
||||
// Find the opposing account and use that one:
|
||||
if (bccomp($transaction->transaction_amount, '0') === 1 && is_null($transaction->opposing_account_id)) {
|
||||
$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 = Steam::decrypt(intval($other->encrypted), $other->name);
|
||||
$transactionId = $other->account_id;
|
||||
$type = $other->type;
|
||||
}
|
||||
|
||||
if ($type === AccountType::CASH) {
|
||||
return '<span class="text-success">(cash)</span>';
|
||||
}
|
||||
|
||||
return sprintf('<a title="%1$s" href="%2$s">%1$s</a>', e($name), route('accounts.show', [$transactionId]));
|
||||
|
||||
}, ['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 = sprintf('<i class="fa fa-long-arrow-left fa-fw" title="%s"></i>', trans('firefly.withdrawal'));
|
||||
break;
|
||||
case TransactionType::DEPOSIT:
|
||||
$txt = sprintf('<i class="fa fa-long-arrow-right fa-fw" title="%s"></i>', trans('firefly.deposit'));
|
||||
break;
|
||||
case TransactionType::TRANSFER:
|
||||
$txt = sprintf('<i class="fa fa-fw fa-exchange" title="%s"></i>', trans('firefly.transfer'));
|
||||
break;
|
||||
case TransactionType::OPENING_BALANCE:
|
||||
$txt = sprintf('<i class="fa-fw fa fa-star-o" title="%s"></i>', trans('firefly.openingBalance'));
|
||||
break;
|
||||
default:
|
||||
$txt = '';
|
||||
break;
|
||||
}
|
||||
|
||||
return $txt;
|
||||
}, ['is_safe' => ['html']]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TransactionModel $transaction
|
||||
*
|
||||
|
@ -34,13 +34,14 @@
|
||||
<td data-value="{{ link.source.description }}">
|
||||
<a href="{{ route('transactions.show', [link.source_id]) }}">{{ link.source.description }}</a>
|
||||
</td>
|
||||
<td>{{ journalAmount(link.source) }}</td>
|
||||
<td>{{ link.source|journalTotalAmount }}</td>
|
||||
<td>{{ linkType.outward }}</td>
|
||||
<td data-value="{{ link.destination.description }}">
|
||||
<a href="{{ route('transactions.show', [link.destination_id]) }}">{{ link.destination.description }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ journalAmount(link.destination) }}
|
||||
{{ link.destination|journalTotalAmount }}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -7,14 +7,10 @@
|
||||
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 %}
|
||||
{{ transaction|transactionIcon }}
|
||||
{{ transaction|transactionDescription }}
|
||||
<span class="pull-right small">
|
||||
{{ transactionAmount(transaction) }}
|
||||
{{ transaction|transactionAmount }}
|
||||
</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
@ -27,80 +27,8 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for transaction in journals %}
|
||||
<tr class="drag" data-date="{{ transaction.date.format('Y-m-d') }}" data-id="{{ transaction.journal_id }}">
|
||||
{# input buttons #}
|
||||
<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 edit_tr_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>
|
||||
|
||||
{# icon #}
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|typeIconTransaction }}
|
||||
</td>
|
||||
|
||||
{# description #}
|
||||
<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>
|
||||
{# is a split journal #}
|
||||
{{ splitJournalIndicator(transaction.journal_id) }}
|
||||
|
||||
{# count attachments #}
|
||||
{{ attachmentIndicator(transaction.journal_id) }}
|
||||
</td>
|
||||
<td style="text-align: right;">
|
||||
<span style="margin-right:5px;">
|
||||
{{ transactionAmount(transaction) }}
|
||||
</span>
|
||||
|
||||
</td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm hidden-md">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm hidden-md">
|
||||
{{ 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>
|
||||
{% for transaction in transactions %}
|
||||
{% include 'partials.transaction-row' %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
65
resources/views/partials/transaction-row.twig
Normal file
65
resources/views/partials/transaction-row.twig
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
<tr class="drag" data-date="{{ transaction.date.format('Y-m-d') }}" data-id="{{ transaction.journal_id }}">
|
||||
{# input buttons #}
|
||||
<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 edit_tr_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>
|
||||
|
||||
{# icon #}
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|transactionIcon }}
|
||||
</td>
|
||||
|
||||
{# description #}
|
||||
<td>
|
||||
<a href="{{ route('transactions.show',transaction.journal_id) }}">
|
||||
{{ transaction|transactionDescription }}
|
||||
</a>
|
||||
{# is a split journal #}
|
||||
{{ transaction|transactionIsSplit }}
|
||||
{# count attachments #}
|
||||
{{ transaction|transactionHasAtt }}
|
||||
</td>
|
||||
<td style="text-align: right;"><span style="margin-right:5px;">{{ transaction|transactionAmount }}</span></td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm hidden-md">
|
||||
{# all source accounts #}
|
||||
{{ transaction|transactionSourceAccount }}
|
||||
</td>
|
||||
<td class="hidden-xs hidden-sm hidden-md">
|
||||
{# all destination accounts #}
|
||||
{{ transaction|transactionDestinationAccount }}
|
||||
</td>
|
||||
|
||||
{# Do NOT hide the budget? #}
|
||||
{% if not hideBudgets %}
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|transactionBudgets }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
{# Do NOT hide the category? #}
|
||||
{% if not hideCategories %}
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|transactionCategories }}
|
||||
</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>
|
@ -11,68 +11,61 @@
|
||||
{% if not hideDestination %}
|
||||
<th class="hidden-xs">{{ trans('list.to') }}</th>
|
||||
{% endif %}
|
||||
<!-- Hide budgets? -->
|
||||
{# 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? -->
|
||||
{# 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:
|
||||
{# 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 }}
|
||||
{{ transaction|transactionIcon }}
|
||||
</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 %}
|
||||
{{ transaction|transactionDescription }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{# TODO replace with new format code #}
|
||||
{{ transactionAmount(transaction) }}
|
||||
{{ transaction|transactionAmount }}
|
||||
</td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
{% if not hideSource %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
{{ transaction|transactionSourceAccount }}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if not hideDestination %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionDestinationAccount(transaction) }}
|
||||
{{ transaction|transactionDestinationAccount }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- Do NOT hide the budget? -->
|
||||
{# Do NOT hide the budget? #}
|
||||
{% if not hideBudget %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionBudgets(transaction) }}
|
||||
{{ transaction|transactionBudgets }}
|
||||
</td>
|
||||
{% endif %}
|
||||
|
||||
<!-- Do NOT hide the category? -->
|
||||
{# Do NOT hide the category? #}
|
||||
{% if not hideCategory %}
|
||||
<td class="hidden-xs">
|
||||
{{ transactionCategories(transaction) }}
|
||||
{{ transaction|transactionCategories }}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
@ -46,7 +46,7 @@
|
||||
<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-icon">{{ transaction|transactionIcon }}</td>
|
||||
|
||||
<td class="hide-description">
|
||||
<a href="{{ route('transactions.show',transaction.journal_id) }}">
|
||||
@ -59,7 +59,7 @@
|
||||
</td>
|
||||
<td class="hide-balance_before" style="text-align: right;">{{ formatAmountByCurrency(transaction.currency, transaction.before) }}</td>
|
||||
<td class="hide-amount" style="text-align: right;">
|
||||
{{ transactionAmount(transaction) }}
|
||||
{{ transaction|transactionAmount }}
|
||||
</td>
|
||||
<td class="hide-balance_after" style="text-align: right;">{{ formatAmountByCurrency(transaction.currency, transaction.after) }}</td>
|
||||
|
||||
@ -104,17 +104,17 @@
|
||||
|
||||
|
||||
<td class="hide-from">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
{{ transaction|transactionSourceAccount }}
|
||||
</td>
|
||||
<td class="hide-to">
|
||||
{{ transactionDestinationAccount(transaction) }}
|
||||
{{ transaction|transactionDestinationAccount }}
|
||||
</td>
|
||||
|
||||
<td class="hide-budget">
|
||||
{{ transactionBudgets(transaction) }}
|
||||
{{ transaction|transactionBudgets }}
|
||||
</td>
|
||||
<td class="hide-category">
|
||||
{{ transactionCategories(transaction) }}
|
||||
{{ transaction|transactionCategories }}
|
||||
</td>
|
||||
{% if transaction.bill_id %}
|
||||
<td class="hide-bill">
|
||||
|
@ -28,7 +28,7 @@
|
||||
class="fa fa-fw fa-trash-o"></i></a></div>
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transaction|typeIconTransaction }}
|
||||
{{ transaction|transactionIcon }}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{ route('transactions.show',transaction.journal_id) }}">
|
||||
@ -39,7 +39,7 @@
|
||||
{{ transaction.description }}
|
||||
{% endif %}
|
||||
</a>
|
||||
{{ splitJournalIndicator(transaction.journal_id) }}
|
||||
{{ transaction|transactionIsSplit }}
|
||||
|
||||
{% if transaction.transactionJournal.attachments|length > 0 %}
|
||||
<i class="fa fa-paperclip"
|
||||
@ -48,23 +48,23 @@
|
||||
</td>
|
||||
<td style="text-align: right;">
|
||||
<span style="margin-right:5px;">
|
||||
{{ transactionAmount(transaction) }}
|
||||
{{ transaction|transactionAmount }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="hidden-sm hidden-xs">
|
||||
{{ transaction.date.formatLocalized(monthAndDayFormat) }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transactionSourceAccount(transaction) }}
|
||||
{{ transaction|transactionSourceAccount }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transactionDestinationAccount(transaction) }}
|
||||
{{ transaction|transactionDestinationAccount }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transactionBudgets(transaction) }}
|
||||
{{ transaction|transactionBudgets }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{{ transactionCategories(transaction) }}
|
||||
{{ transaction|transactionCategories }}
|
||||
</td>
|
||||
<td class="hidden-xs">
|
||||
{% if transaction.bill_id %}
|
||||
|
@ -43,7 +43,8 @@
|
||||
<a href="{{ route('transactions.show',journal.id) }}" title="{{ journal.description }}">{{ journal.description }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ journalAmount(journal) }}
|
||||
{{ journal|journalTotalAmount }}
|
||||
|
||||
</td>
|
||||
<td>
|
||||
{{ journal.date.formatLocalized(monthAndDayFormat) }}
|
||||
|
@ -88,11 +88,13 @@
|
||||
<tr>
|
||||
<td>{{ 'total_amount'|_ }}</td>
|
||||
<td>
|
||||
{{ journalAmount(journal) }}
|
||||
{{ journal|journalTotalAmount }}
|
||||
|
||||
{# if more transactions, list each one: #}
|
||||
{% if transactions|length > 1 %}
|
||||
({{ journalTotalAmount(journal) }})
|
||||
({% for transaction in transactions %}{{ transaction|transactionArrayAmount }}{% if loop.index != loop.length %}, {% endif %}{% endfor %})
|
||||
{% endif %}
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -336,12 +338,12 @@
|
||||
<a href="{{ route('transactions.show',link.destination.id) }}">
|
||||
#{{ link.destination.id }}: {{ link.destination.description }}
|
||||
</a>
|
||||
({{ journalAmount(link.destination) }})
|
||||
({{ link.destination|journalTotalAmount }})
|
||||
{% else %}
|
||||
{{ journalLinkTranslation('inward', link.linkType.inward) }}
|
||||
<a href="{{ route('transactions.show',link.source.id) }}">
|
||||
#{{ link.source.id }}: {{ link.source.description }}</a>
|
||||
({{ journalAmount(link.source) }})
|
||||
({{ link.source|journalTotalAmount }})
|
||||
{% endif %}
|
||||
{% if link.comment != "" %}
|
||||
<br/><em>{{ link.comment }}</em>
|
||||
|
Loading…
Reference in New Issue
Block a user