diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php index 3ab23248d0..5355126e68 100644 --- a/app/Api/V1/Controllers/AccountController.php +++ b/app/Api/V1/Controllers/AccountController.php @@ -94,22 +94,32 @@ class AccountController extends Controller */ public function index(Request $request) { + // create some objects: + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + + // read type from URI + $type = $request->get('type') ?? 'all'; + $this->parameters->set('type', $type); + + // types to get, page size: $types = $this->mapTypes($this->parameters->get('type')); $pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); + + // get list of accounts. Count it and split it. $collection = $this->repository->getAccountsByType($types); $count = $collection->count(); $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); // make paginator: $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); - $manager = new Manager(); - $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; - $manager->setSerializer(new JsonApiSerializer($baseUrl)); + // present to user. + $manager->setSerializer(new JsonApiSerializer($baseUrl)); $resource = new FractalCollection($accounts, new AccountTransformer($this->parameters), 'accounts'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - return response()->json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } /** @@ -120,14 +130,17 @@ class AccountController extends Controller */ public function show(Request $request, Account $account) { - $manager = new Manager(); - //$manager->parseIncludes(['attachments', 'journals', 'user']); + + // add include parameter: + $include = $request->get('include') ?? ''; + $manager->parseIncludes($include); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $manager->setSerializer(new JsonApiSerializer($baseUrl)); $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); - return response()->json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } /** @@ -150,7 +163,7 @@ class AccountController extends Controller $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); - return response()->json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } @@ -177,7 +190,7 @@ class AccountController extends Controller $resource = new Item($account, new AccountTransformer($this->parameters), 'accounts'); - return response()->json($manager->createData($resource)->toArray()); + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); } /** diff --git a/app/Api/V1/Controllers/BillController.php b/app/Api/V1/Controllers/BillController.php index c383b31c2e..767d5ead1f 100644 --- a/app/Api/V1/Controllers/BillController.php +++ b/app/Api/V1/Controllers/BillController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\BillRequest; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Bill; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Transformers\BillTransformer; @@ -110,7 +111,10 @@ class BillController extends Controller public function show(Request $request, Bill $bill) { $manager = new Manager(); - $manager->parseIncludes(['attachments', 'journals', 'user']); + // add include parameter: + $include = $request->get('include') ?? ''; + $manager->parseIncludes($include); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; $manager->setSerializer(new JsonApiSerializer($baseUrl)); diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php index 240735d3b5..c5bd32e287 100644 --- a/app/Api/V1/Controllers/Controller.php +++ b/app/Api/V1/Controllers/Controller.php @@ -88,9 +88,6 @@ class Controller extends BaseController $bag->set($field, $obj); } - $type = request()->get('type') ?? 'all'; - $bag->set('type', $type); - return $bag; } diff --git a/app/Api/V1/Controllers/TransactionController.php b/app/Api/V1/Controllers/TransactionController.php new file mode 100644 index 0000000000..14ff90b93a --- /dev/null +++ b/app/Api/V1/Controllers/TransactionController.php @@ -0,0 +1,154 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use Illuminate\Http\Request; +use Illuminate\Support\Collection; +use Preferences; + + +/** + * Class TransactionController + */ +class TransactionController extends Controller +{ + + /** @var JournalRepositoryInterface */ + private $repository; + /** + * TransactionController constructor. + * + * @throws \FireflyIII\Exceptions\FireflyException + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + /** @var JournalRepositoryInterface repository */ + $this->repository = app(JournalRepositoryInterface::class); + $this->repository->setUser(auth()->user()); + + return $next($request); + } + ); + } + + /** + * Remove the specified resource from storage. + * + * @param \FireflyIII\Models\TransactionJournal $journal + * + * @return \Illuminate\Http\Response + */ + public function delete(TransactionJournal $journal) + { + $this->repository->destroy($journal); + + return response()->json([], 204); + } + + /** + * Display a listing of the resource. + * + * @param Request $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function index(Request $request) + { + $pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); + $paginator = $this->repository->getPaginator($pageSize); + /** @var Collection $bills */ + $bills = $paginator->getCollection(); + + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new FractalCollection($bills, new BillTransformer($this->parameters), 'bills'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray()); + } + + + /** + * @param Request $request + * @param Bill $bill + * + * @return \Illuminate\Http\JsonResponse + */ + public function show(Request $request, Bill $bill) + { + $manager = new Manager(); + $manager->parseIncludes(['attachments', 'journals', 'user']); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); + + return response()->json($manager->createData($resource)->toArray()); + } + + /** + * @param BillRequest $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function store(BillRequest $request) + { + $bill = $this->repository->store($request->getAll()); + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); + + return response()->json($manager->createData($resource)->toArray()); + + } + + + /** + * @param BillRequest $request + * @param Bill $bill + * + * @return \Illuminate\Http\JsonResponse + */ + public function update(BillRequest $request, Bill $bill) + { + $data = $request->getAll(); + $bill = $this->repository->update($bill, $data); + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new Item($bill, new BillTransformer($this->parameters), 'bills'); + + return response()->json($manager->createData($resource)->toArray()); + + } +} \ No newline at end of file diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php index c731ff0b2a..fdade64998 100644 --- a/app/Helpers/Collector/JournalCollector.php +++ b/app/Helpers/Collector/JournalCollector.php @@ -69,6 +69,8 @@ class JournalCollector implements JournalCollectorInterface 'transaction_journals.description', 'transaction_journals.date', 'transaction_journals.encrypted', + 'transaction_journals.created_at', + 'transaction_journals.updated_at', 'transaction_types.type as transaction_type_type', 'transaction_journals.bill_id', 'transaction_journals.updated_at', diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php index 780f92b5c7..49b7fbb3a9 100644 --- a/app/Transformers/AccountTransformer.php +++ b/app/Transformers/AccountTransformer.php @@ -25,10 +25,12 @@ namespace FireflyIII\Transformers; use Carbon\Carbon; +use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; use FireflyIII\Models\Note; use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Models\TransactionJournal; +use Illuminate\Support\Collection; use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Item; use League\Fractal\TransformerAbstract; @@ -44,7 +46,7 @@ class AccountTransformer extends TransformerAbstract * * @var array */ - protected $availableIncludes = ['journals', 'piggy_banks', 'user']; + protected $availableIncludes = ['transactions', 'piggy_banks', 'user']; /** * List of resources to automatically include * @@ -69,20 +71,26 @@ class AccountTransformer extends TransformerAbstract * * @return FractalCollection */ - public function includeJournals(Account $account): FractalCollection + public function includeTransactions(Account $account): FractalCollection { - $ids = $account->transactions()->get(['transactions.transaction_journal_id'])->pluck('transaction_journal_id')->toArray(); - $query = TransactionJournal::whereIn('id', $ids); - if (!is_null($this->parameters->get('end'))) { - $query->where('date', '<=', $this->parameters->get('end')->format('Y-m-d 00:00:00')); - } - if (!is_null($this->parameters->get('start'))) { - $query->where('date', '>=', $this->parameters->get('start')->format('Y-m-d 00:00:00')); - } + $pageSize = intval(app('preferences')->getForUser($account->user, 'listPageSize', 50)->data); - $journals = $query->get(['transaction_journals.*']); + // journals always use collector and limited using URL parameters. + $collector = new JournalCollector; + $collector->setUser($account->user); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + if ($account->accountType->type === AccountType::ASSET) { + $collector->setAccounts(new Collection([$account])); + } else { + $collector->setOpposingAccounts(new Collection([$account])); + } + if (!is_null($this->parameters->get('start')) && !is_null($this->parameters->get('end'))) { + $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); + } + $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); + $journals = $collector->getJournals(); - return $this->collection($journals, new TransactionJournalTransformer($this->parameters), 'journals'); + return $this->collection($journals, new TransactionTransformer($this->parameters), 'transactions'); } /** diff --git a/app/Transformers/BillTransformer.php b/app/Transformers/BillTransformer.php index b452655019..cdce182e43 100644 --- a/app/Transformers/BillTransformer.php +++ b/app/Transformers/BillTransformer.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Transformers; use Carbon\Carbon; +use FireflyIII\Helpers\Collector\JournalCollector; use FireflyIII\Models\Bill; use FireflyIII\Models\Note; use FireflyIII\Repositories\Bill\BillRepositoryInterface; @@ -43,7 +44,7 @@ class BillTransformer extends TransformerAbstract * * @var array */ - protected $availableIncludes = ['attachments', 'journals', 'user']; + protected $availableIncludes = ['attachments', 'transactions', 'user']; /** * List of resources to automatically include * @@ -81,18 +82,23 @@ class BillTransformer extends TransformerAbstract * * @return FractalCollection */ - public function includeJournals(Bill $bill): FractalCollection + public function includeTransactions(Bill $bill): FractalCollection { - $query = $bill->transactionJournals(); - if (!is_null($this->parameters->get('end'))) { - $query->where('date', '<=', $this->parameters->get('end')->format('Y-m-d 00:00:00')); - } - if (!is_null($this->parameters->get('start'))) { - $query->where('date', '>=', $this->parameters->get('start')->format('Y-m-d 00:00:00')); - } - $journals = $query->get(); + $pageSize = intval(app('preferences')->getForUser($bill->user, 'listPageSize', 50)->data); - return $this->collection($journals, new TransactionJournalTransformer($this->parameters), 'journals'); + // journals always use collector and limited using URL parameters. + $collector = new JournalCollector; + $collector->setUser($bill->user); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + $collector->setAllAssetAccounts(); + $collector->setBills(new Collection([$bill])); + if (!is_null($this->parameters->get('start')) && !is_null($this->parameters->get('end'))) { + $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); + } + $collector->setLimit($pageSize)->setPage($this->parameters->get('page')); + $journals = $collector->getJournals(); + + return $this->collection($journals, new TransactionTransformer($this->parameters), 'transactions'); } /** diff --git a/app/Transformers/BudgetTransformer.php b/app/Transformers/BudgetTransformer.php index d02a1f6d20..fb3cf05b4e 100644 --- a/app/Transformers/BudgetTransformer.php +++ b/app/Transformers/BudgetTransformer.php @@ -38,7 +38,7 @@ class BudgetTransformer extends TransformerAbstract * * @var array */ - protected $availableIncludes = ['user']; + protected $availableIncludes = ['user', 'transactions']; /** * List of resources to automatically include * diff --git a/app/Transformers/CategoryTransformer.php b/app/Transformers/CategoryTransformer.php index eebb924024..3d78fbfaf0 100644 --- a/app/Transformers/CategoryTransformer.php +++ b/app/Transformers/CategoryTransformer.php @@ -38,7 +38,7 @@ class CategoryTransformer extends TransformerAbstract * * @var array */ - protected $availableIncludes = ['user']; + protected $availableIncludes = ['user','transactions']; /** * List of resources to automatically include * diff --git a/app/Transformers/TransactionJournalTransformer.php b/app/Transformers/TransactionJournalTransformer.php deleted file mode 100644 index a29a377f3a..0000000000 --- a/app/Transformers/TransactionJournalTransformer.php +++ /dev/null @@ -1,212 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Transformers; - - -use FireflyIII\Models\Note; -use FireflyIII\Models\TransactionJournal; -use League\Fractal\Resource\Collection as FractalCollection; -use League\Fractal\Resource\Item; -use League\Fractal\TransformerAbstract; -use Symfony\Component\HttpFoundation\ParameterBag; - -/** - * Class TransactionJournalTransformer - */ -class TransactionJournalTransformer extends TransformerAbstract -{ - - /** - * List of resources possible to include - * - * @var array - */ - protected $availableIncludes = ['attachments', 'transactions', 'user', 'tags', 'budget', 'category', 'bill', 'journal_meta', 'piggy_bank_events']; - /** - * List of resources to automatically include - * - * @var array - */ - protected $defaultIncludes = ['attachments', 'transactions', 'user', 'tags', 'budget', 'category', 'bill', 'journal_meta', 'piggy_bank_events']; - - /** @var ParameterBag */ - protected $parameters; - - /** - * BillTransformer constructor. - * - * @param ParameterBag $parameters - */ - public function __construct(ParameterBag $parameters) - { - $this->parameters = $parameters; - } - - /** - * @param TransactionJournal $journal - * - * @return FractalCollection - */ - public function includeAttachments(TransactionJournal $journal): FractalCollection - { - return $this->collection($journal->attachments, new AttachmentTransformer($this->parameters), 'attachments'); - } - - /** - * @param TransactionJournal $journal - * - * @return Item|null - */ - public function includeBill(TransactionJournal $journal): ?Item - { - $bill = $journal->bill()->first(); - if (!is_null($bill)) { - return $this->item($bill, new BillTransformer($this->parameters), 'bills'); - } - - return null; - } - - /** - * @param TransactionJournal $journal - * - * @return Item|null - */ - public function includeBudget(TransactionJournal $journal): ?Item - { - $budget = $journal->budgets()->first(); - if (!is_null($budget)) { - return $this->item($budget, new BudgetTransformer($this->parameters), 'budgets'); - } - - return null; - } - - /** - * @param TransactionJournal $journal - * - * @return Item|null - */ - public function includeCategory(TransactionJournal $journal): ?Item - { - $category = $journal->categories()->first(); - if (!is_null($category)) { - return $this->item($category, new CategoryTransformer($this->parameters), 'categories'); - } - - return null; - } - - /** - * @param TransactionJournal $journal - * - * @return FractalCollection - */ - public function includeJournalMeta(TransactionJournal $journal): FractalCollection - { - $meta = $journal->transactionJournalMeta()->get(); - - return $this->collection($meta, new JournalMetaTransformer($this->parameters), 'journal_meta'); - } - - /** - * @param TransactionJournal $journal - * - * @return FractalCollection - */ - public function includePiggyBankEvents(TransactionJournal $journal): FractalCollection - { - $events = $journal->piggyBankEvents()->get(); - - return $this->collection($events, new PiggyBankEventTransformer($this->parameters), 'piggy_bank_events'); - } - - /** - * @param TransactionJournal $journal - * - * @return FractalCollection - */ - public function includeTags(TransactionJournal $journal): FractalCollection - { - $set = $journal->tags; - - return $this->collection($set, new TagTransformer($this->parameters), 'tag'); - } - - /** - * @param TransactionJournal $journal - * - * @return FractalCollection - */ - public function includeTransactions(TransactionJournal $journal): FractalCollection - { - $set = $journal->transactions()->where('amount', '<', 0)->get(['transactions.*']); - - return $this->collection($set, new TransactionTransformer($this->parameters), 'transactions'); - } - - /** - * @param TransactionJournal $journal - * - * @return \League\Fractal\Resource\Item - */ - public function includeUser(TransactionJournal $journal): Item - { - return $this->item($journal->user, new UserTransformer($this->parameters), 'users'); - } - - /** - * @param TransactionJournal $journal - * - * @return array - */ - public function transform(TransactionJournal $journal): array - { - $data = [ - 'id' => (int)$journal->id, - 'updated_at' => $journal->updated_at->toAtomString(), - 'created_at' => $journal->created_at->toAtomString(), - 'type' => $journal->transactionType->type, - 'description' => $journal->description, - 'date' => $journal->date->format('Y-m-d'), - 'order' => $journal->order, - 'completed' => $journal->completed, - 'notes' => null, - 'links' => [ - [ - 'rel' => 'self', - 'uri' => '/journals/' . $journal->id, - ], - ], - ]; - /** @var Note $note */ - $note = $journal->notes()->first(); - if (!is_null($note)) { - $data['notes'] = $note->text; - } - - return $data; - } - -} \ No newline at end of file diff --git a/app/Transformers/TransactionTransformer.php b/app/Transformers/TransactionTransformer.php index 126e048935..7cc92d00cb 100644 --- a/app/Transformers/TransactionTransformer.php +++ b/app/Transformers/TransactionTransformer.php @@ -24,7 +24,11 @@ declare(strict_types=1); namespace FireflyIII\Transformers; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionType; +use League\Fractal\Resource\Collection as FractalCollection; +use League\Fractal\Resource\Item; use League\Fractal\TransformerAbstract; use Symfony\Component\HttpFoundation\ParameterBag; @@ -33,6 +37,19 @@ use Symfony\Component\HttpFoundation\ParameterBag; */ class TransactionTransformer extends TransformerAbstract { + /** + * List of resources possible to include + * + * @var array + */ + protected $availableIncludes = ['attachments', 'user', 'tags', 'journal_meta', 'piggy_bank_events']; + /** + * List of resources to automatically include + * + * @var array + */ + protected $defaultIncludes = []; + /** @var ParameterBag */ protected $parameters; @@ -46,34 +63,100 @@ class TransactionTransformer extends TransformerAbstract $this->parameters = $parameters; } + /** + * @param Transaction $transaction + * + * @return FractalCollection + */ + public function includeAttachments(Transaction $transaction): FractalCollection + { + return $this->collection($transaction->transactionJournal->attachments, new AttachmentTransformer($this->parameters), 'attachments'); + } + + /** + * @param Transaction $transaction + * + * @return FractalCollection + */ + public function includeJournalMeta(Transaction $transaction): FractalCollection + { + $meta = $transaction->transactionJournal->transactionJournalMeta()->get(); + + return $this->collection($meta, new JournalMetaTransformer($this->parameters), 'journal_meta'); + } + + /** + * @param Transaction $transaction + * + * @return FractalCollection + */ + public function includePiggyBankEvents(Transaction $transaction): FractalCollection + { + $events = $transaction->transactionJournal->piggyBankEvents()->get(); + + return $this->collection($events, new PiggyBankEventTransformer($this->parameters), 'piggy_bank_events'); + } + + /** + * @param Transaction $transaction + * + * @return FractalCollection + */ + public function includeTags(Transaction $transaction): FractalCollection + { + $set = $transaction->transactionJournal->tags; + + return $this->collection($set, new TagTransformer($this->parameters), 'tags'); + } + + /** + * @param Transaction $transaction + * + * @return \League\Fractal\Resource\Item + */ + public function includeUser(Transaction $transaction): Item + { + return $this->item($transaction->transactionJournal->user, new UserTransformer($this->parameters), 'users'); + } + + /** * @param Transaction $transaction * * @return array + * @throws FireflyException */ public function transform(Transaction $transaction): array { - $opposing = Transaction - ::where('transaction_journal_id', $transaction->transaction_journal_id) - ->where('identifier', $transaction->identifier) - ->where('amount', $transaction->amount * -1) - ->whereNull('deleted_at') - ->first(['transactions.*']); - $data = [ - 'id' => (int)$transaction->id, - 'updated_at' => $transaction->updated_at->toAtomString(), - 'created_at' => $transaction->created_at->toAtomString(), - 'source_id' => (int)$transaction->account_id, - 'destination_id' => $opposing->account_id, - 'description' => $transaction->description, - 'currency_id' => (int)$transaction->transaction_currency_id, - 'amount' => (float)$transaction->amount, - 'foreign_currency_id' => is_null($transaction->foreign_currency_id) ? null : (int)$transaction->foreign_currency_id, - 'foreign_amount' => is_null($transaction->foreign_amount) ? null : (float)$transaction->foreign_amount, - 'identifier' => (int)$transaction->identifier, - - 'links' => [ + 'id' => (int)$transaction->id, + 'updated_at' => $transaction->updated_at->toAtomString(), + 'created_at' => $transaction->created_at->toAtomString(), + 'description' => $transaction->description, + 'date' => $transaction->date->format('Y-m-d'), + 'type' => $transaction->transaction_type_type, + 'identifier' => $transaction->identifier, + 'journal_id' => (int)$transaction->journal_id, + 'reconciled' => (bool)$transaction->reconciled, + 'amount' => round($transaction->transaction_amount, $transaction->transaction_currency_dp), + 'currency_id' => $transaction->transaction_currency_id, + 'currency_code' => $transaction->transaction_currency_code, + 'currency_dp' => $transaction->transaction_currency_dp, + 'foreign_amount' => null, + 'foreign_currency_id' => $transaction->foreign_currency_id, + 'foreign_currency_code' => $transaction->foreign_currency_code, + 'foreign_currency_dp' => $transaction->foreign_currency_dp, + 'bill_id' => $transaction->bill_id, + 'bill_name' => $transaction->bill_name, + 'category_id' => is_null($transaction->transaction_category_id) ? $transaction->transaction_journal_category_id + : $transaction->transaction_category_id, + 'category_name' => is_null($transaction->transaction_category_name) ? $transaction->transaction_journal_category_name + : $transaction->transaction_category_name, + 'budget_id' => is_null($transaction->transaction_budget_id) ? $transaction->transaction_journal_budget_id + : $transaction->transaction_budget_id, + 'budget_name' => is_null($transaction->transaction_budget_name) ? $transaction->transaction_journal_budget_name + : $transaction->transaction_budget_name, + 'links' => [ [ 'rel' => 'self', 'uri' => '/transactions/' . $transaction->id, @@ -81,7 +164,66 @@ class TransactionTransformer extends TransformerAbstract ], ]; + // expand foreign amount: + if (!is_null($transaction->transaction_foreign_amount)) { + $data['foreign_amount'] = round($transaction->transaction_foreign_amount, $transaction->foreign_currency_dp); + } + + // switch on type for consistency + switch (true) { + case TransactionType::WITHDRAWAL === $transaction->transaction_type_type: + $data['source_id'] = $transaction->account_id; + $data['source_name'] = $transaction->account_name; + $data['source_iban'] = $transaction->account_iban; + $data['source_type'] = $transaction->account_type; + $data['destination_id'] = $transaction->opposing_account_id; + $data['destination_name'] = $transaction->opposing_account_name; + $data['destination_iban'] = $transaction->opposing_account_iban; + $data['destination_type'] = $transaction->opposing_account_type; + break; + case TransactionType::DEPOSIT === $transaction->transaction_type_type: + $data['source_id'] = $transaction->opposing_account_id; + $data['source_name'] = $transaction->opposing_account_name; + $data['source_iban'] = $transaction->opposing_account_iban; + $data['source_type'] = $transaction->opposing_account_type; + $data['destination_id'] = $transaction->account_id; + $data['destination_name'] = $transaction->account_name; + $data['destination_iban'] = $transaction->account_iban; + $data['destination_type'] = $transaction->account_type; + break; + case TransactionType::TRANSFER === $transaction->transaction_type_type && bccomp($transaction->transaction_amount, '0') > 0: + $data['source_id'] = $transaction->opposing_account_id; + $data['source_name'] = $transaction->opposing_account_name; + $data['source_iban'] = $transaction->opposing_account_iban; + $data['source_type'] = $transaction->opposing_account_type; + $data['destination_id'] = $transaction->account_id; + $data['destination_name'] = $transaction->account_name; + $data['destination_iban'] = $transaction->account_iban; + $data['destination_type'] = $transaction->account_type; + break; + case TransactionType::TRANSFER === $transaction->transaction_type_type && bccomp($transaction->transaction_amount, '0') < 0: + $data['source_id'] = $transaction->account_id; + $data['source_name'] = $transaction->account_name; + $data['source_iban'] = $transaction->account_iban; + $data['source_type'] = $transaction->account_type; + $data['destination_id'] = $transaction->opposing_account_id; + $data['destination_name'] = $transaction->opposing_account_name; + $data['destination_iban'] = $transaction->opposing_account_iban; + $data['destination_type'] = $transaction->opposing_account_type; + $data['amount'] = $data['amount'] * -1; + $data['foreign_amount'] = is_null($data['foreign_amount']) ? null : $data['foreign_amount'] * -1; + break; + default: + throw new FireflyException(sprintf('Cannot handle % s!', $transaction->transaction_type_type)); + + } + + // expand description. + if (strlen(strval($transaction->transaction_description)) > 0) { + $data['description'] = $transaction->transaction_description . ' (' . $transaction->description . ')'; + } + + return $data; } - } \ No newline at end of file