Complete accounts and bills end point.

This commit is contained in:
James Cole 2018-12-09 13:09:43 +01:00
parent 108d43f967
commit 97f6e68164
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
7 changed files with 299 additions and 25 deletions

View File

@ -24,16 +24,23 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\AccountRequest;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\PiggyBankTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
@ -47,7 +54,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
*/
class AccountController extends Controller
{
use AccountFilter;
use AccountFilter, TransactionFilter;
/** @var CurrencyRepositoryInterface The currency repository */
private $currencyRepository;
/** @var AccountRepositoryInterface The account repository */
@ -127,6 +134,41 @@ class AccountController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List all of them.
*
* @param Request $request
* @param Account $account
*
* @return JsonResponse]
*/
public function piggyBanks(Request $request, Account $account): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getPiggyBanks($account);
$count = $collection->count();
$piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.accounts.piggy_banks', [$account->id]) . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($piggyBanks, new PiggyBankTransformer($this->parameters), 'piggy_banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show single instance.
*
@ -170,6 +212,58 @@ class AccountController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show all transactions.
*
* @param Request $request
* @param Account $account
*
* @return JsonResponse
*/
public function transactions(Request $request, Account $account): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
$types = $this->mapTransactionTypes($this->parameters->get('type'));
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
/** @var User $admin */
$admin = auth()->user();
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class);
$collector->setUser($admin);
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
if ($this->repository->isAsset($account)) {
$collector->setAccounts(new Collection([$account]));
}
if (!$this->repository->isAsset($account)) {
$collector->setOpposingAccounts(new Collection([$account]));
}
if (\in_array(TransactionType::TRANSFER, $types, true)) {
$collector->removeFilter(InternalTransferFilter::class);
}
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
}
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.accounts.transactions', [$account->id]) . $this->buildParams());
$transactions = $paginator->getCollection();
$repository = app(JournalRepositoryInterface::class);
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters, $repository), 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update account.
*

View File

@ -26,12 +26,19 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BillRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\Transformers\BillTransformer;
use FireflyIII\Transformers\RuleTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
@ -44,6 +51,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
*/
class BillController extends Controller
{
use TransactionFilter;
/** @var BillRepositoryInterface The bill repository */
private $repository;
@ -67,6 +75,38 @@ class BillController extends Controller
);
}
/**
* Display a listing of the resource.
*
* @param Request $request
* @param Bill $bill
*
* @return JsonResponse
*/
public function attachments(Request $request, Bill $bill): JsonResponse
{
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->getAttachments($bill);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.bills.attachments', [$bill->id]) . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($attachments, new AttachmentTransformer($this->parameters), 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Remove the specified resource from storage.
*
@ -105,6 +145,40 @@ class BillController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* List all of them.
*
* @param Request $request
* @param Bill $bill
*
* @return JsonResponse
*/
public function rules(Request $request, Bill $bill): JsonResponse
{
// create some objects:
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
// types to get, page size:
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
// get list of budgets. Count it and split it.
$collection = $this->repository->getRulesForBill($bill);
$count = $collection->count();
$rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
$paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.bills.rules', [$bill->id]) . $this->buildParams());
// present to user.
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($rules, new RuleTransformer($this->parameters), 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show the specified bill.
@ -149,6 +223,49 @@ class BillController extends Controller
}
/**
* Show all transactions.
*
* @param Request $request
*
* @param Bill $bill
*
* @return JsonResponse
*/
public function transactions(Request $request, Bill $bill): JsonResponse
{
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
$types = $this->mapTransactionTypes($this->parameters->get('type'));
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
/** @var User $admin */
$admin = auth()->user();
/** @var TransactionCollectorInterface $collector */
$collector = app(TransactionCollectorInterface::class);
$collector->setUser($admin);
$collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation();
$collector->setAllAssetAccounts();
$collector->setBills(new Collection([$bill]));
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
}
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams());
$transactions = $paginator->getCollection();
$repository = app(JournalRepositoryInterface::class);
$resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters, $repository), 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Update a bill.

View File

@ -386,6 +386,16 @@ class AccountRepository implements AccountRepositoryInterface
return $journal->date->format('Y-m-d');
}
/**
* @param Account $account
*
* @return Collection
*/
public function getPiggyBanks(Account $account): Collection
{
return $account->piggyBanks()->get();
}
/**
* @param Account $account
*
@ -416,6 +426,18 @@ class AccountRepository implements AccountRepositoryInterface
return $account;
}
/**
* @param Account $account
*
* @return bool
*/
public function isAsset(Account $account): bool
{
$type = $account->accountType->type;
return AccountType::ASSET === $type || AccountType::DEFAULT === $type;
}
/**
* @param Account $account
*

View File

@ -35,7 +35,6 @@ use Illuminate\Support\Collection;
*/
interface AccountRepositoryInterface
{
/**
* Moved here from account CRUD.
*
@ -167,6 +166,13 @@ interface AccountRepositoryInterface
*/
public function getOpeningBalanceDate(Account $account): ?string;
/**
* @param Account $account
*
* @return Collection
*/
public function getPiggyBanks(Account $account): Collection;
/**
* Find or create the opposing reconciliation account.
*
@ -176,6 +182,13 @@ interface AccountRepositoryInterface
*/
public function getReconciliation(Account $account): ?Account;
/**
* @param Account $account
*
* @return bool
*/
public function isAsset(Account $account): bool;
/**
* @param Account $account
*

View File

@ -121,6 +121,18 @@ class BillRepository implements BillRepositoryInterface
return $set;
}
/**
* Get all attachments.
*
* @param Bill $bill
*
* @return Collection
*/
public function getAttachments(Bill $bill): Collection
{
return $bill->attachments()->get();
}
/**
* @return Collection
*/
@ -148,7 +160,8 @@ class BillRepository implements BillRepositoryInterface
public function getBillsForAccounts(Collection $accounts): Collection
{
$fields = ['bills.id', 'bills.created_at', 'bills.updated_at', 'bills.deleted_at', 'bills.user_id', 'bills.name', 'bills.match', 'bills.amount_min',
'bills.amount_max', 'bills.date','bills.transaction_currency_id', 'bills.repeat_freq', 'bills.skip', 'bills.automatch', 'bills.active', 'bills.name_encrypted',
'bills.amount_max', 'bills.date', 'bills.transaction_currency_id', 'bills.repeat_freq', 'bills.skip', 'bills.automatch', 'bills.active',
'bills.name_encrypted',
'bills.match_encrypted',];
$ids = $accounts->pluck('id')->toArray();
$set = $this->user->bills()
@ -381,9 +394,11 @@ class BillRepository implements BillRepositoryInterface
*/
public function getPaidDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
$dates = $bill->transactionJournals()->before($end)->after($start)->get([
'transaction_journals.id','transaction_journals.date'
])->pluck('date', 'id');
$dates = $bill->transactionJournals()->before($end)->after($start)->get(
[
'transaction_journals.id', 'transaction_journals.date',
]
)->pluck('date', 'id');
return $dates;
}

View File

@ -64,6 +64,15 @@ interface BillRepositoryInterface
*/
public function getActiveBills(): Collection;
/**
* Get all attachments.
*
* @param Bill $bill
*
* @return Collection
*/
public function getAttachments(Bill $bill): Collection;
/**
* @return Collection
*/

View File

@ -40,6 +40,10 @@ Route::group(
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::get('{account}/piggy_banks', ['uses' => 'AccountController@piggyBanks', 'as' => 'piggy_banks']);
Route::get('{account}/transactions', ['uses' => 'AccountController@transactions', 'as' => 'transactions']);
}
);
@ -72,6 +76,22 @@ Route::group(
}
);
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']);
Route::post('', ['uses' => 'BillController@store', 'as' => 'store']);
Route::get('{bill}', ['uses' => 'BillController@show', 'as' => 'show']);
Route::put('{bill}', ['uses' => 'BillController@update', 'as' => 'update']);
Route::delete('{bill}', ['uses' => 'BillController@delete', 'as' => 'delete']);
Route::get('{bill}/attachments', ['uses' => 'BillController@attachments', 'as' => 'attachments']);
Route::get('{bill}/rules', ['uses' => 'BillController@rules', 'as' => 'rules']);
Route::get('{bill}/transactions', ['uses' => 'BillController@transactions', 'as' => 'transactions']);
}
);
Route::group(
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'budgets/limits', 'as' => 'api.v1.budget_limits.'],
@ -103,22 +123,6 @@ Route::group(
}
);
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']);
Route::post('', ['uses' => 'BillController@store', 'as' => 'store']);
Route::get('{bill}', ['uses' => 'BillController@show', 'as' => 'show']);
Route::put('{bill}', ['uses' => 'BillController@update', 'as' => 'update']);
Route::delete('{bill}', ['uses' => 'BillController@delete', 'as' => 'delete']);
}
);
Route::group(
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'categories', 'as' => 'api.v1.categories.'],
function () {
@ -177,7 +181,8 @@ Route::group(
);
Route::group(
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'transaction_links', 'as' => 'api.v1.transaction_links.'],
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'transaction_links',
'as' => 'api.v1.transaction_links.'],
function () {
// Transaction Links API routes:
@ -301,7 +306,6 @@ Route::group(
);
Route::group(
['middleware' => ['auth:api', 'bindings'], 'namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'transactions', 'as' => 'api.v1.transactions.'],
function () {