From 8b868b426af6ea4b4fa46b8b5947d42582dcac02 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 11 Feb 2018 08:08:08 +0100 Subject: [PATCH] First API routes for accounts. --- app/Api/V1/Controllers/AccountController.php | 216 +++++++++++++++++++ app/Transformers/AccountTransformer.php | 87 ++++++++ routes/api.php | 17 +- 3 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 app/Api/V1/Controllers/AccountController.php create mode 100644 app/Transformers/AccountTransformer.php diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/AccountController.php new file mode 100644 index 0000000000..00ec2b894f --- /dev/null +++ b/app/Api/V1/Controllers/AccountController.php @@ -0,0 +1,216 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers; + +use FireflyIII\Models\Account; +use FireflyIII\Models\AccountType; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Transformers\AccountTransformer; +use Illuminate\Http\Request; +use Illuminate\Pagination\LengthAwarePaginator; +use League\Fractal\Manager; +use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use League\Fractal\Resource\Collection as FractalCollection; +use League\Fractal\Resource\Item; +use League\Fractal\Serializer\JsonApiSerializer; +use Preferences; +use Response; + +/** + * Class AccountController + */ +class AccountController extends Controller +{ + + /** @var AccountRepositoryInterface */ + private $repository; + + /** + * AccountController constructor. + * + * @throws \FireflyIII\Exceptions\FireflyException + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + /** @var AccountRepositoryInterface repository */ + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser(auth()->user()); + + return $next($request); + } + ); + } + + /** + * Remove the specified resource from storage. + * + * @param \FireflyIII\Models\Account $account + * + * @return \Illuminate\Http\Response + */ + public function delete(Account $account) + { + $this->repository->destroy($account, new Account); + + return response()->json([], 204); + } + + /** + * Display a listing of the resource. + * + * @param Request $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function index(Request $request) + { + $type = $request->get('type') ?? 'all'; + $types = $this->mapTypes($type); + $pageSize = intval(Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data); + $page = 0 === intval($request->get('page')) ? 1 : intval($request->get('page')); + $collection = $this->repository->getAccountsByType($types); + $count = $collection->count(); + $accounts = $collection->slice(($page - 1) * $pageSize, $pageSize); + + // make paginator: + $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $page); + + $manager = new Manager(); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + + $resource = new FractalCollection($accounts, new AccountTransformer, 'accounts'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return Response::json($manager->createData($resource)->toArray()); + } + + /** + * @param Request $request + * @param Account $account + * + * @return \Illuminate\Http\JsonResponse + */ + public function show(Request $request, Account $account) + { + + $manager = new Manager(); + $manager->parseIncludes(['attachments', 'journals', 'user']); + $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; + $manager->setSerializer(new JsonApiSerializer($baseUrl)); + $resource = new Item($account, new AccountTransformer, 'accounts'); + + return Response::json($manager->createData($resource)->toArray()); + } + + /** + * @param AccountRequest $request + * + * @return \Illuminate\Http\JsonResponse + */ + public function store(AccountRequest $request) + { + + } + + /** + * @param AccountRequest $request + * @param Account $account + * + * @return \Illuminate\Http\JsonResponse + */ + public function update(AccountRequest $request, Account $account) + { + + + } + + /** + * @param string $type + * + * @return array + */ + private function mapTypes(string $type): array + { + $types = [ + 'all' => [ + AccountType::DEFAULT, + AccountType::CASH, + AccountType::ASSET, + AccountType::EXPENSE, + AccountType::REVENUE, + AccountType::INITIAL_BALANCE, + AccountType::BENEFICIARY, + AccountType::IMPORT, + AccountType::RECONCILIATION, + AccountType::LOAN, + ], + 'asset' => [ + AccountType::DEFAULT, + AccountType::ASSET, + ], + 'cash' => [ + AccountType::CASH, + ], + 'expense' => [ + AccountType::EXPENSE, + AccountType::BENEFICIARY, + ], + 'revenue' => [ + AccountType::REVENUE, + ], + 'special' => [ + AccountType::CASH, + AccountType::INITIAL_BALANCE, + AccountType::IMPORT, + AccountType::RECONCILIATION, + AccountType::LOAN, + ], + 'hidden' => [ + AccountType::INITIAL_BALANCE, + AccountType::IMPORT, + AccountType::RECONCILIATION, + AccountType::LOAN, + ], + AccountType::DEFAULT => [AccountType::DEFAULT], + AccountType::CASH => [AccountType::CASH], + AccountType::ASSET => [AccountType::ASSET], + AccountType::EXPENSE => [AccountType::EXPENSE], + AccountType::REVENUE => [AccountType::REVENUE], + AccountType::INITIAL_BALANCE => [AccountType::INITIAL_BALANCE], + AccountType::BENEFICIARY => [AccountType::BENEFICIARY], + AccountType::IMPORT => [AccountType::IMPORT], + AccountType::RECONCILIATION => [AccountType::RECONCILIATION], + AccountType::LOAN => [AccountType::LOAN], + ]; + if (isset($types[$type])) { + return $types[$type]; + } + + return $types['all']; + } +} \ No newline at end of file diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php new file mode 100644 index 0000000000..3bb736c0fb --- /dev/null +++ b/app/Transformers/AccountTransformer.php @@ -0,0 +1,87 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Transformers; + + +use FireflyIII\Models\Account; +use FireflyIII\Models\Note; +use FireflyIII\Models\TransactionCurrency; +use League\Fractal\TransformerAbstract; + +/** + * Class AccountTransformer + */ +class AccountTransformer extends TransformerAbstract +{ + /** + * @param Account $account + * + * @return array + */ + public function transform(Account $account): array + { + $role = $account->getMeta('accountRole'); + if (strlen($role) === 0) { + $role = null; + } + $currencyId = (int)$account->getMeta('currency_id'); + $currencyCode = null; + if ($currencyId > 0) { + $currency = TransactionCurrency::find($currencyId); + $currencyCode = $currency->code; + } + + if ($currencyId === 0) { + $currencyId = null; + } + + + $data = [ + 'id' => (int)$account->id, + 'updated_at' => $account->updated_at->toAtomString(), + 'created_at' => $account->created_at->toAtomString(), + 'name' => $account->name, + 'active' => intval($account->active) === 1, + 'type' => $account->accountType->type, + 'currency_id' => $currencyId, + 'currency_code' => $currencyCode, + 'notes' => null, + 'role' => $role, + 'links' => [ + [ + 'rel' => 'self', + 'uri' => '/accounts/' . $account->id, + ], + ], + ]; + /** @var Note $note */ + $note = $account->notes()->first(); + if (!is_null($note)) { + $data['notes'] = $note->text; + } + + return $data; + } + +} \ No newline at end of file diff --git a/routes/api.php b/routes/api.php index e3e7ef16f2..f905786357 100644 --- a/routes/api.php +++ b/routes/api.php @@ -20,7 +20,21 @@ */ Route::group( - ['middleware' => ['auth:api','bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'bills', 'as' => 'api.v1.bills.'], function () { + ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'accounts', 'as' => 'api.v1.accounts.'], + function () { + + // Accounts API routes: + Route::get('', ['uses' => 'AccountController@index', 'as' => 'index']); + Route::post('', ['uses' => 'AccountController@store', 'as' => 'store']); + Route::get('{account}', ['uses' => 'AccountController@show', 'as' => 'show']); + Route::put('{account}', ['uses' => 'AccountController@update', 'as' => 'update']); + Route::delete('{account}', ['uses' => 'AccountController@delete', 'as' => 'delete']); + } +); + + +Route::group( + ['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'bills', 'as' => 'api.v1.bills.'], function () { // Bills API routes: Route::get('', ['uses' => 'BillController@index', 'as' => 'index']); @@ -30,3 +44,4 @@ Route::group( Route::delete('{bill}', ['uses' => 'BillController@delete', 'as' => 'delete']); } ); +