diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php index f4fa3d2e6e..032cc8d708 100644 --- a/app/Helpers/Collector/JournalCollector.php +++ b/app/Helpers/Collector/JournalCollector.php @@ -25,11 +25,13 @@ namespace FireflyIII\Helpers\Collector; use Carbon\Carbon; use DB; use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Filter\CountAttachmentsFilter; use FireflyIII\Helpers\Filter\FilterInterface; use FireflyIII\Helpers\Filter\InternalTransferFilter; use FireflyIII\Helpers\Filter\NegativeAmountFilter; use FireflyIII\Helpers\Filter\OpposingAccountFilter; use FireflyIII\Helpers\Filter\PositiveAmountFilter; +use FireflyIII\Helpers\Filter\SplitIndicatorFilter; use FireflyIII\Helpers\Filter\TransferFilter; use FireflyIII\Models\AccountType; use FireflyIII\Models\Budget; @@ -760,6 +762,8 @@ class JournalCollector implements JournalCollectorInterface TransferFilter::class => new TransferFilter, PositiveAmountFilter::class => new PositiveAmountFilter, NegativeAmountFilter::class => new NegativeAmountFilter, + SplitIndicatorFilter::class => new SplitIndicatorFilter, + CountAttachmentsFilter::class => new CountAttachmentsFilter, ]; Log::debug(sprintf('Will run %d filters on the set.', count($this->filters))); foreach ($this->filters as $enabled) { diff --git a/app/Helpers/Filter/CountAttachmentsFilter.php b/app/Helpers/Filter/CountAttachmentsFilter.php new file mode 100644 index 0000000000..9ca0e79438 --- /dev/null +++ b/app/Helpers/Filter/CountAttachmentsFilter.php @@ -0,0 +1,67 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Helpers\Filter; + + +use DB; +use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionJournal; +use Illuminate\Support\Collection; + +/** + * Class CountAttachmentsFilter + */ +class CountAttachmentsFilter implements FilterInterface +{ + + /** + * @param Collection $set + * + * @return Collection + */ + public function filter(Collection $set): Collection + { + // grab journal ID's: + $ids = $set->pluck('journal_id')->toArray(); + + $result = DB::table('attachments') + ->whereNull('deleted_at') + ->whereIn('attachable_id', $ids) + ->where('attachable_type', TransactionJournal::class) + ->groupBy('attachable_id')->get(['attachable_id', DB::raw('COUNT(*) as number')]); + $counter = []; + foreach ($result as $row) { + $counter[$row->attachable_id] = $row->number; + } + $set->each( + function (Transaction $transaction) use ($counter) { + $id = (int)$transaction->journal_id; + $count = $counter[$id] ?? 0; + $transaction->attachmentCount = $count; + } + ); + + return $set; + } +} \ No newline at end of file diff --git a/app/Helpers/Filter/SplitIndicatorFilter.php b/app/Helpers/Filter/SplitIndicatorFilter.php new file mode 100644 index 0000000000..73116232e1 --- /dev/null +++ b/app/Helpers/Filter/SplitIndicatorFilter.php @@ -0,0 +1,67 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Helpers\Filter; + + +use DB; +use FireflyIII\Models\Transaction; +use Illuminate\Support\Collection; + +/** + * Class SplitIndicatorFilter + */ +class SplitIndicatorFilter implements FilterInterface +{ + + /** + * @param Collection $set + * + * @return Collection + */ + public function filter(Collection $set): Collection + { + // grab journal ID's: + $ids = $set->pluck('journal_id')->toArray(); + + $result = DB::table('transactions') + ->whereNull('deleted_at')->whereIn('transaction_journal_id', $ids) + ->groupBy('transaction_journal_id')->get(['transaction_journal_id', DB::raw('COUNT(*) as number')]); + $counter = []; + foreach ($result as $row) { + $counter[$row->transaction_journal_id] = $row->number; + } + $set->each( + function (Transaction $transaction) use ($counter) { + $id = (int)$transaction->journal_id; + $count = $counter[$id] ?? 0; + $transaction->is_split = false; + if ($count > 2) { + $transaction->is_split = true; + } + } + ); + + return $set; + } +} \ No newline at end of file diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 113062dc37..b59de1fcbf 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -435,33 +435,34 @@ class AccountController extends Controller if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } + /** @var array $dates */ $dates = app('navigation')->blockPeriods($start, $end, $range); $entries = new Collection; // loop dates - foreach ($dates as $date) { + foreach ($dates as $currentDate) { // try a collector for income: /** @var JournalCollectorInterface $collector */ $collector = app(JournalCollectorInterface::class); - $collector->setAccounts(new Collection([$account]))->setRange($date['start'], $date['end'])->setTypes([TransactionType::DEPOSIT]) + $collector->setAccounts(new Collection([$account]))->setRange($currentDate['start'], $currentDate['end'])->setTypes([TransactionType::DEPOSIT]) ->withOpposingAccount(); - $earned = strval($collector->getJournals()->sum('transaction_amount')); + $earned = (string)$collector->getJournals()->sum('transaction_amount'); // try a collector for expenses: /** @var JournalCollectorInterface $collector */ $collector = app(JournalCollectorInterface::class); - $collector->setAccounts(new Collection([$account]))->setRange($date['start'], $date['end'])->setTypes([TransactionType::WITHDRAWAL]) + $collector->setAccounts(new Collection([$account]))->setRange($currentDate['start'], $currentDate['end'])->setTypes([TransactionType::WITHDRAWAL]) ->withOpposingAccount(); - $spent = strval($collector->getJournals()->sum('transaction_amount')); + $spent = (string)$collector->getJournals()->sum('transaction_amount'); - $dateName = app('navigation')->periodShow($date['start'], $date['period']); + $dateName = app('navigation')->periodShow($currentDate['start'], $currentDate['period']); $entries->push( [ 'name' => $dateName, 'spent' => $spent, 'earned' => $earned, - 'start' => $date['start']->format('Y-m-d'), - 'end' => $date['end']->format('Y-m-d'), + 'start' => $currentDate['start']->format('Y-m-d'), + 'end' => $currentDate['end']->format('Y-m-d'), ] ); } diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 2212ead0df..668cb64f1e 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -447,20 +447,20 @@ class CategoryController extends Controller if ($cache->has()) { return $cache->get(); // @codeCoverageIgnore } - + /** @var array $dates */ $dates = app('navigation')->blockPeriods($start, $end, $range); $entries = new Collection; - foreach ($dates as $date) { - $spent = $this->repository->spentInPeriod(new Collection([$category]), $accounts, $date['start'], $date['end']); - $earned = $this->repository->earnedInPeriod(new Collection([$category]), $accounts, $date['start'], $date['end']); - $dateStr = $date['end']->format('Y-m-d'); - $dateName = app('navigation')->periodShow($date['end'], $date['period']); + foreach ($dates as $currentDate) { + $spent = $this->repository->spentInPeriod(new Collection([$category]), $accounts, $currentDate['start'], $currentDate['end']); + $earned = $this->repository->earnedInPeriod(new Collection([$category]), $accounts, $currentDate['start'], $currentDate['end']); + $dateStr = $currentDate['end']->format('Y-m-d'); + $dateName = app('navigation')->periodShow($currentDate['end'], $currentDate['period']); // amount transferred /** @var JournalCollectorInterface $collector */ $collector = app(JournalCollectorInterface::class); - $collector->setAllAssetAccounts()->setRange($date['start'], $date['end'])->setCategory($category) + $collector->setAllAssetAccounts()->setRange($currentDate['start'], $currentDate['end'])->setCategory($category) ->withOpposingAccount()->setTypes([TransactionType::TRANSFER]); $collector->removeFilter(InternalTransferFilter::class); $transferred = Steam::positive($collector->getJournals()->sum('transaction_amount')); @@ -473,7 +473,7 @@ class CategoryController extends Controller 'earned' => $earned, 'sum' => bcadd($earned, $spent), 'transferred' => $transferred, - 'date' => clone $date['end'], + 'date' => clone $currentDate['end'], ] ); } diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 2b7178c678..d1727bb020 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -25,13 +25,14 @@ namespace FireflyIII\Http\Controllers; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\JournalCollectorInterface; +use FireflyIII\Helpers\Filter\CountAttachmentsFilter; use FireflyIII\Helpers\Filter\InternalTransferFilter; +use FireflyIII\Helpers\Filter\SplitIndicatorFilter; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; -use FireflyIII\Support\CacheProperties; use FireflyIII\Transformers\TransactionTransformer; use Illuminate\Http\Request; use Illuminate\Support\Collection; @@ -45,6 +46,9 @@ use View; */ class TransactionController extends Controller { + /** @var JournalRepositoryInterface */ + private $repository; + /** * TransactionController constructor. */ @@ -56,6 +60,7 @@ class TransactionController extends Controller function ($request, $next) { app('view')->share('title', trans('firefly.transactions')); app('view')->share('mainTitleIcon', 'fa-repeat'); + $this->repository = app(JournalRepositoryInterface::class); return $next($request); } @@ -63,96 +68,141 @@ class TransactionController extends Controller } /** - * @param Request $request - * @param JournalRepositoryInterface $repository - * @param string $what - * @param string $moment + * Index for a range of transactions. + * + * @param Request $request + * @param string $what + * @param Carbon $start + * @param Carbon $end * * @return View * */ - public function index(Request $request, JournalRepositoryInterface $repository, string $what, string $moment = '') + public function index(Request $request, string $what, Carbon $start = null, Carbon $end = null) { - // default values: $subTitleIcon = config('firefly.transactionIconsByWhat.' . $what); $types = config('firefly.transactionTypesByWhat.' . $what); - $page = intval($request->get('page')); - $pageSize = intval(Preferences::get('listPageSize', 50)->data); - $range = Preferences::get('viewRange', '1M')->data; - $start = null; - $end = null; - $periods = new Collection; + $page = (int)$request->get('page'); + $pageSize = (int)Preferences::get('listPageSize', 50)->data; $path = route('transactions.index', [$what]); - - // prep for "all" view. - if ('all' === $moment) { - $subTitle = trans('firefly.all_' . $what); - $first = $repository->first(); - $start = $first->date ?? new Carbon; - $end = new Carbon; - $path = route('transactions.index', [$what, 'all']); + if (null === $start) { + $start = session('start'); + $end = session('end'); + } + if (null === $end) { + $end = session('end'); } - // prep for "specific date" view. - if (strlen($moment) > 0 && 'all' !== $moment) { - $start = new Carbon($moment); - $end = app('navigation')->endOfPeriod($start, $range); - $path = route('transactions.index', [$what, $moment]); - $subTitle = trans( - 'firefly.title_' . $what . '_between', - ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] - ); - $periods = $this->getPeriodOverview($what); - } - - // prep for current period - if (0 === strlen($moment)) { - $start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range)); - $end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range)); - $periods = $this->getPeriodOverview($what); - $subTitle = trans( - 'firefly.title_' . $what . '_between', - ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] - ); + if ($end < $start) { + list($start, $end) = [$end, $start]; } + $startStr = $start->formatLocalized($this->monthAndDayFormat); + $endStr = $end->formatLocalized($this->monthAndDayFormat); + $subTitle = trans('firefly.title_' . $what . '_between', ['start' => $startStr, 'end' => $endStr]); + $periods = $this->getPeriodOverview($what, $end); /** @var JournalCollectorInterface $collector */ $collector = app(JournalCollectorInterface::class); - $collector->setAllAssetAccounts()->setRange($start, $end)->setTypes($types)->setLimit($pageSize)->setPage($page)->withOpposingAccount(); + $collector->setAllAssetAccounts()->setRange($start, $end) + ->setTypes($types)->setLimit($pageSize)->setPage($page)->withOpposingAccount() + ->withBudgetInformation()->withCategoryInformation(); $collector->removeFilter(InternalTransferFilter::class); + $collector->addFilter(SplitIndicatorFilter::class); + $collector->addFilter(CountAttachmentsFilter::class); $transactions = $collector->getPaginatedJournals(); $transactions->setPath($path); - return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'transactions', 'periods', 'start', 'end', 'moment')); + return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'transactions', 'periods', 'start', 'end')); + + + // + + + // // prep for "all" view. + // if ('all' === $moment) { + // $subTitle = trans('firefly.all_' . $what); + // $first = $this->repository->first(); + // $start = $first->date ?? new Carbon; + // $end = new Carbon; + // $path = route('transactions.index', [$what, 'all']); + // } + // + // // prep for "specific date" view. + // if (strlen($moment) > 0 && 'all' !== $moment) { + // $start = new Carbon($moment); + // $end = app('navigation')->endOfPeriod($start, $range); + // $path = route('transactions.index', [$what, $moment]); + // + // } + + // // prep for current period + // if (0 === strlen($moment)) { + // $start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range)); + // $end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range)); + // $subTitle = trans( + // 'firefly.title_' . $what . '_between', + // ['start' => $start->formatLocalized($this->monthAndDayFormat), 'end' => $end->formatLocalized($this->monthAndDayFormat)] + // ); + // } } /** - * @param Request $request - * @param JournalRepositoryInterface $repository + * @param Request $request + * @param string $what + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function indexAll(Request $request, string $what) + { + $subTitleIcon = config('firefly.transactionIconsByWhat.' . $what); + $types = config('firefly.transactionTypesByWhat.' . $what); + $page = (int)$request->get('page'); + $pageSize = (int)Preferences::get('listPageSize', 50)->data; + $path = route('transactions.index.all', [$what]); + $first = $this->repository->first(); + $start = $first->date ?? new Carbon; + $end = new Carbon; + $subTitle = trans('firefly.all_' . $what); + + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setAllAssetAccounts()->setRange($start, $end) + ->setTypes($types)->setLimit($pageSize)->setPage($page)->withOpposingAccount() + ->withBudgetInformation()->withCategoryInformation(); + $collector->removeFilter(InternalTransferFilter::class); + $collector->addFilter(SplitIndicatorFilter::class); + $collector->addFilter(CountAttachmentsFilter::class); + $transactions = $collector->getPaginatedJournals(); + $transactions->setPath($path); + + return view('transactions.index', compact('subTitle', 'what', 'subTitleIcon', 'transactions', 'start', 'end')); + } + + /** + * @param Request $request * * @return \Illuminate\Http\JsonResponse */ - public function reconcile(Request $request, JournalRepositoryInterface $repository) + public function reconcile(Request $request) { $transactionIds = $request->get('transactions'); foreach ($transactionIds as $transactionId) { - $transactionId = intval($transactionId); - $transaction = $repository->findTransaction($transactionId); + $transactionId = (int)$transactionId; + $transaction = $this->repository->findTransaction($transactionId); Log::debug(sprintf('Transaction ID is %d', $transaction->id)); - $repository->reconcile($transaction); + $this->repository->reconcile($transaction); } return response()->json(['ok' => 'reconciled']); } /** - * @param Request $request - * @param JournalRepositoryInterface $repository + * @param Request $request * * @return \Illuminate\Http\JsonResponse */ - public function reorder(Request $request, JournalRepositoryInterface $repository) + public function reorder(Request $request) { $ids = $request->get('items'); $date = new Carbon($request->get('date')); @@ -160,9 +210,9 @@ class TransactionController extends Controller $order = 0; $ids = array_unique($ids); foreach ($ids as $id) { - $journal = $repository->find(intval($id)); + $journal = $this->repository->find((int)$id); if ($journal && $journal->date->isSameDay($date)) { - $repository->setOrder($journal, $order); + $this->repository->setOrder($journal, $order); ++$order; } } @@ -174,13 +224,12 @@ class TransactionController extends Controller /** * @param TransactionJournal $journal - * @param JournalRepositoryInterface $repository * @param LinkTypeRepositoryInterface $linkTypeRepository * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View * @throws FireflyException */ - public function show(TransactionJournal $journal, JournalRepositoryInterface $repository, LinkTypeRepositoryInterface $linkTypeRepository) + public function show(TransactionJournal $journal, LinkTypeRepositoryInterface $linkTypeRepository) { if ($this->isOpeningBalance($journal)) { return $this->redirectToAccount($journal); @@ -206,7 +255,7 @@ class TransactionController extends Controller $transactions[] = $transformer->transform($transaction); } - $events = $repository->getPiggyBankEvents($journal); + $events = $this->repository->getPiggyBankEvents($journal); $what = strtolower($transactionType); $subTitle = trans('firefly.' . $what) . ' "' . $journal->description . '"'; @@ -218,61 +267,44 @@ class TransactionController extends Controller * * @return Collection */ - private function getPeriodOverview(string $what): Collection + private function getPeriodOverview(string $what, Carbon $date): Collection { - $repository = app(JournalRepositoryInterface::class); - $first = $repository->first(); - $start = $first->date ?? new Carbon; - $range = Preferences::get('viewRange', '1M')->data; - $start = app('navigation')->startOfPeriod($start, $range); - $end = app('navigation')->endOfX(new Carbon, $range, null); - $entries = new Collection; - $types = config('firefly.transactionTypesByWhat.' . $what); - - // properties for cache - $cache = new CacheProperties; - $cache->addProperty($start); - $cache->addProperty($end); - $cache->addProperty($what); - $cache->addProperty('transaction-list-entries'); - - if ($cache->has()) { - return $cache->get(); // @codeCoverageIgnore + $range = Preferences::get('viewRange', '1M')->data; + $first = $this->repository->first(); + $start = (new Carbon)->subYear(); + $types = config('firefly.transactionTypesByWhat.' . $what); + $entries = new Collection; + if (null !== $first) { + $start = $first->date; } + if ($date < $start) { + list($start, $date) = [$date, $start]; // @codeCoverageIgnore + } + /** @var array $dates */ + $dates = app('navigation')->blockPeriods($start, $date, $range); - Log::debug(sprintf('Going to get period expenses and incomes between %s and %s.', $start->format('Y-m-d'), $end->format('Y-m-d'))); - while ($end >= $start) { - Log::debug('Loop start!'); - $end = app('navigation')->startOfPeriod($end, $range); - $currentEnd = app('navigation')->endOfPeriod($end, $range); - - // count journals without budget in this period: + foreach ($dates as $currentDate) { /** @var JournalCollectorInterface $collector */ $collector = app(JournalCollectorInterface::class); - $collector->setAllAssetAccounts()->setRange($end, $currentEnd)->withOpposingAccount()->setTypes($types); + $collector->setAllAssetAccounts()->setRange($currentDate['start'], $currentDate['end'])->withOpposingAccount()->setTypes($types); $collector->removeFilter(InternalTransferFilter::class); $journals = $collector->getJournals(); - $sum = $journals->sum('transaction_amount'); - // count per currency: - $sums = $this->sumPerCurrency($journals); - $dateStr = $end->format('Y-m-d'); - $dateName = app('navigation')->periodShow($end, $range); - $array = [ - 'string' => $dateStr, - 'name' => $dateName, - 'sum' => $sum, - 'sums' => $sums, - 'date' => clone $end, - ]; - Log::debug(sprintf('What is %s', $what)); if ($journals->count() > 0) { - $entries->push($array); // @codeCoverageIgnore + $sums = $this->sumPerCurrency($journals); + $dateName = app('navigation')->periodShow($currentDate['start'], $currentDate['period']); + $sum = $journals->sum('transaction_amount'); + $entries->push( + [ + 'name' => $dateName, + 'sums' => $sums, + 'sum' => $sum, + 'start' => $currentDate['start']->format('Y-m-d'), + 'end' => $currentDate['end']->format('Y-m-d'), + ] + ); } - $end = app('navigation')->subtractPeriod($end, $range, 1); } - Log::debug('End of loop'); - $cache->store($entries); return $entries; } @@ -287,7 +319,7 @@ class TransactionController extends Controller $return = []; /** @var Transaction $transaction */ foreach ($collection as $transaction) { - $currencyId = intval($transaction->transaction_currency_id); + $currencyId = (int)$transaction->transaction_currency_id; // save currency information: if (!isset($return[$currencyId])) { diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php index f965a5c8e9..027300de00 100644 --- a/app/Models/Transaction.php +++ b/app/Models/Transaction.php @@ -68,6 +68,8 @@ use Watson\Validating\ValidatingTrait; * @property int $transaction_currency_dp * @property string $transaction_currency_code * @property string $description + * @property bool $is_split + * @property int $attachmentCount */ class Transaction extends Model { diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 6970b7b4b1..7fafc5d844 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -103,8 +103,8 @@ class EventServiceProvider extends ServiceProvider function (PiggyBank $piggyBank) { $repetition = new PiggyBankRepetition; $repetition->piggyBank()->associate($piggyBank); - $repetition->startdate = null === $piggyBank->startdate ? null : $piggyBank->startdate; - $repetition->targetdate = null === $piggyBank->targetdate ? null : $piggyBank->targetdate; + $repetition->startdate = $piggyBank->startdate; + $repetition->targetdate = $piggyBank->targetdate; $repetition->currentamount = 0; $repetition->save(); } diff --git a/app/Support/Twig/Extension/Transaction.php b/app/Support/Twig/Extension/Transaction.php index 9e8c7bb071..042f28fb39 100644 --- a/app/Support/Twig/Extension/Transaction.php +++ b/app/Support/Twig/Extension/Transaction.php @@ -120,44 +120,40 @@ class Transaction extends Twig_Extension } /** + * * @param TransactionModel $transaction * * @return string */ public function budgets(TransactionModel $transaction): string { + $txt = ''; // journal has a budget: - if (isset($transaction->transaction_journal_budget_id)) { + if (null !== $transaction->transaction_journal_budget_id) { $name = app('steam')->tryDecrypt($transaction->transaction_journal_budget_name); $txt = sprintf('%s', route('budgets.show', [$transaction->transaction_journal_budget_id]), $name, $name); - - return $txt; } // transaction has a budget - if (isset($transaction->transaction_budget_id)) { + if (null !== $transaction->transaction_budget_id && $txt === '') { $name = app('steam')->tryDecrypt($transaction->transaction_budget_name); $txt = sprintf('%s', route('budgets.show', [$transaction->transaction_budget_id]), $name, $name); - - return $txt; } - // see if the transaction has a budget: - $budgets = $transaction->budgets()->get(); - if (0 === $budgets->count()) { - $budgets = $transaction->transactionJournal()->first()->budgets()->get(); - } - if ($budgets->count() > 0) { - $str = []; - foreach ($budgets as $budget) { - $str[] = sprintf('%s', route('budgets.show', [$budget->id]), $budget->name, $budget->name); + if ($txt === '') { + // see if the transaction has a budget: + $budgets = $transaction->budgets()->get(); + if (0 === $budgets->count()) { + $budgets = $transaction->transactionJournal()->first()->budgets()->get(); + } + if ($budgets->count() > 0) { + $str = []; + foreach ($budgets as $budget) { + $str[] = sprintf('%s', route('budgets.show', [$budget->id]), $budget->name, $budget->name); + } + $txt = implode(', ', $str); } - - $txt = join(', ', $str); - - return $txt; } - $txt = ''; return $txt; } @@ -169,40 +165,35 @@ class Transaction extends Twig_Extension */ public function categories(TransactionModel $transaction): string { + $txt = ''; // journal has a category: - if (isset($transaction->transaction_journal_category_id)) { + if (null !== $transaction->transaction_journal_category_id) { $name = app('steam')->tryDecrypt($transaction->transaction_journal_category_name); $txt = sprintf('%s', route('categories.show', [$transaction->transaction_journal_category_id]), $name, $name); - - return $txt; } // transaction has a category: - if (isset($transaction->transaction_category_id)) { + if (null !== $transaction->transaction_category_id && $txt === '') { $name = app('steam')->tryDecrypt($transaction->transaction_category_name); $txt = sprintf('%s', route('categories.show', [$transaction->transaction_category_id]), $name, $name); - - return $txt; } - // see if the transaction has a category: - $categories = $transaction->categories()->get(); - if (0 === $categories->count()) { - $categories = $transaction->transactionJournal()->first()->categories()->get(); - } - if ($categories->count() > 0) { - $str = []; - foreach ($categories as $category) { - $str[] = sprintf('%s', route('categories.show', [$category->id]), $category->name, $category->name); + if ($txt === '') { + // see if the transaction has a category: + $categories = $transaction->categories()->get(); + if (0 === $categories->count()) { + $categories = $transaction->transactionJournal()->first()->categories()->get(); } + if ($categories->count() > 0) { + $str = []; + foreach ($categories as $category) { + $str[] = sprintf('%s', route('categories.show', [$category->id]), $category->name, $category->name); + } - $txt = join(', ', $str); - - return $txt; + $txt = implode(', ', $str); + } } - $txt = ''; - return $txt; } @@ -286,18 +277,25 @@ class Transaction extends Twig_Extension */ public function hasAttachments(TransactionModel $transaction): string { - $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('', Lang::choice('firefly.nr_of_attachments', $count, ['count' => $count])); - - return $res; - } - $res = ''; + if (is_int($transaction->attachmentCount) && $transaction->attachmentCount > 0) { + $res = sprintf( + '', Lang::choice( + 'firefly.nr_of_attachments', + $transaction->attachmentCount, ['count' => $transaction->attachmentCount] + ) + ); + } + if ($transaction->attachmentCount === null) { + $journalId = (int)$transaction->journal_id; + $count = Attachment::whereNull('deleted_at') + ->where('attachable_type', 'FireflyIII\Models\TransactionJournal') + ->where('attachable_id', $journalId) + ->count(); + if ($count > 0) { + $res = sprintf('', Lang::choice('firefly.nr_of_attachments', $count, ['count' => $count])); + } + } return $res; } @@ -341,7 +339,7 @@ class Transaction extends Twig_Extension public function isReconciled(TransactionModel $transaction): string { $icon = ''; - if (1 === intval($transaction->reconciled)) { + if (1 === (int)$transaction->reconciled) { $icon = ''; } @@ -349,21 +347,26 @@ class Transaction extends Twig_Extension } /** + * Returns an icon when the transaction is a split transaction. + * * @param TransactionModel $transaction * * @return string */ public function isSplit(TransactionModel $transaction): string { - $journalId = intval($transaction->journal_id); - $count = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count(); - if ($count > 2) { - $res = ''; - - return $res; + $res = ''; + if ($transaction->is_split === true) { + $res = '!!!'; } - $res = ''; + if ($transaction->is_split === null) { + $journalId = (int)$transaction->journal_id; + $count = TransactionModel::where('transaction_journal_id', $journalId)->whereNull('deleted_at')->count(); + if ($count > 2) { + $res = ''; + } + } return $res; } diff --git a/resources/views/partials/transaction-row.twig b/resources/views/partials/transaction-row.twig index 2b54a0bad0..9f392268ee 100644 --- a/resources/views/partials/transaction-row.twig +++ b/resources/views/partials/transaction-row.twig @@ -35,34 +35,31 @@ +
- {{ 'show_all_no_filter'|_ }} + {{ 'show_all_no_filter'|_ }}
{% else %}@@ -56,10 +56,9 @@ {% for period in periods %} {% if period.sum != 0 %} - -