. */ declare(strict_types=1); namespace FireflyIII\Http\Controllers\Transaction; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; use FireflyIII\Transformers\TransactionGroupTransformer; use Illuminate\Contracts\View\Factory; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Str; use Illuminate\View\View; use Symfony\Component\HttpFoundation\ParameterBag; /** * Class ShowController */ class ShowController extends Controller { /** @var TransactionGroupRepositoryInterface */ private $repository; /** * ShowController constructor. */ public function __construct() { parent::__construct(); // some useful repositories: $this->middleware( function ($request, $next) { $this->repository = app(TransactionGroupRepositoryInterface::class); app('view')->share('title', (string) trans('firefly.transactions')); app('view')->share('mainTitleIcon', 'fa-exchange'); return $next($request); } ); } /** * @param TransactionGroup $transactionGroup * * @return JsonResponse */ public function debugShow(TransactionGroup $transactionGroup) { return response()->json($this->repository->expandGroup($transactionGroup)); } /** * @param TransactionGroup $transactionGroup * * @throws FireflyException * @return Factory|View */ public function show(Request $request, TransactionGroup $transactionGroup) { /** @var TransactionJournal $first */ $first = $transactionGroup->transactionJournals()->first(['transaction_journals.*']); $splits = $transactionGroup->transactionJournals()->count(); if (null === $first) { throw new FireflyException('This transaction is broken :(.'); } $type = (string) trans(sprintf('firefly.%s', $first->transactionType->type)); $title = 1 === $splits ? $first->description : $transactionGroup->title; $subTitle = sprintf('%s: "%s"', $type, $title); /** @var TransactionGroupTransformer $transformer */ $transformer = app(TransactionGroupTransformer::class); $transformer->setParameters(new ParameterBag); $groupArray = $transformer->transformObject($transactionGroup); // do some calculations: $amounts = $this->getAmounts($groupArray); $accounts = $this->getAccounts($groupArray); // make sure notes are escaped but not double escaped. foreach ($groupArray['transactions'] as $index => $transaction) { $search = ['&', '>', '<']; if (!Str::contains($transaction['notes'], $search)) { $groupArray['transactions'][$index]['notes'] = e($transaction['notes']); } $groupArray['transactions'][$index]['tags'] = $this->repository->getTagObjects($groupArray['transactions'][$index]['transaction_journal_id']); } $events = $this->repository->getPiggyEvents($transactionGroup); $attachments = $this->repository->getAttachments($transactionGroup); $links = $this->repository->getLinks($transactionGroup); return view( 'transactions.show', compact( 'transactionGroup', 'amounts', 'first', 'type', 'subTitle', 'splits', 'groupArray', 'events', 'attachments', 'links', 'accounts', ) ); } /** * @param array $group * * @return array */ private function getAmounts(array $group): array { $amounts = []; foreach ($group['transactions'] as $transaction) { $symbol = $transaction['currency_symbol']; if (!isset($amounts[$symbol])) { $amounts[$symbol] = [ 'amount' => '0', 'symbol' => $symbol, 'decimal_places' => $transaction['currency_decimal_places'], ]; } $amounts[$symbol]['amount'] = bcadd($amounts[$symbol]['amount'], $transaction['amount']); if (null !== $transaction['foreign_amount']) { // same for foreign currency: $foreignSymbol = $transaction['foreign_currency_symbol']; if (!isset($amounts[$foreignSymbol])) { $amounts[$foreignSymbol] = [ 'amount' => '0', 'symbol' => $foreignSymbol, 'decimal_places' => $transaction['foreign_currency_decimal_places'], ]; } $amounts[$foreignSymbol]['amount'] = bcadd($amounts[$foreignSymbol]['amount'], $transaction['foreign_amount']); } } return $amounts; } /** * @param array $group * * @return array */ private function getAccounts(array $group): array { $accounts = []; foreach ($group['transactions'] as $index => $transaction) { $accounts['source'][] = [ 'type' => $transaction['source_type'], 'id' => $transaction['source_id'], 'name' => $transaction['source_name'], 'iban' => $transaction['source_iban'] ]; $accounts['destination'][] = [ 'type' => $transaction['destination_type'], 'id' => $transaction['destination_id'], 'name' => $transaction['destination_name'], 'iban' => $transaction['destination_iban'] ]; } $accounts['source'] = array_unique($accounts['source'], SORT_REGULAR); $accounts['destination'] = array_unique($accounts['destination'], SORT_REGULAR); return $accounts; } }