Budgets and budget limits end point.

This commit is contained in:
James Cole
2018-12-09 08:45:53 +01:00
parent b0e1c85c55
commit 108d43f967
7 changed files with 261 additions and 47 deletions

View File

@@ -23,11 +23,19 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Api\V1\Requests\BudgetRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\Budget;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\Transformers\BudgetTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -45,6 +53,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
*/
class BudgetController extends Controller
{
use TransactionFilter;
/** @var BudgetRepositoryInterface The budget repository */
private $repository;
@@ -68,6 +77,33 @@ class BudgetController extends Controller
);
}
/**
* Display a listing of the resource.
*
* @param Request $request
* @param Budget $budget
*
* @return JsonResponse
*/
public function budgetLimits(Request $request, Budget $budget): JsonResponse
{
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
$this->parameters->set('budget_id', $budget->id);
$collection = $this->repository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.budgets.budget_limits', [$budget->id]) . $this->buildParams());
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new FractalCollection($budgetLimits, new BudgetLimitTransformer($this->parameters), 'budget_limits');
$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.
*
@@ -115,7 +151,6 @@ class BudgetController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show a budget.
*
@@ -158,6 +193,76 @@ class BudgetController extends Controller
throw new FireflyException('Could not store new budget.'); // @codeCoverageIgnore
}
/**
* Store a newly created resource in storage.
*
* @param BudgetLimitRequest $request
* @param Budget $budget
*
* @return JsonResponse
*/
public function storeBudgetLimit(BudgetLimitRequest $request, Budget $budget): JsonResponse
{
$data = $request->getAll();
$data['budget'] = $budget;
$budgetLimit = $this->repository->storeBudgetLimit($data);
$manager = new Manager;
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show all transactions.
*
* @param Request $request
*
* @param Budget $budget
*
* @return JsonResponse
*/
public function transactions(Request $request, Budget $budget): 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->setBudget($budget);
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.budgets.transactions', [$budget->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 budget.

View File

@@ -26,9 +26,15 @@ namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BudgetLimitRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\TransactionCollectorInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\Transformers\TransactionTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
@@ -48,6 +54,7 @@ use League\Fractal\Serializer\JsonApiSerializer;
*/
class BudgetLimitController extends Controller
{
use TransactionFilter;
/** @var BudgetRepositoryInterface The budget repository */
private $repository;
@@ -163,6 +170,52 @@ class BudgetLimitController extends Controller
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* Show all transactions.
*
* @param Request $request
* @param BudgetLimit $budgetLimit
*
* @return JsonResponse
*/
public function transactions(Request $request, BudgetLimit $budgetLimit): 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->setBudget($budgetLimit->budget);
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
if (\in_array(TransactionType::TRANSFER, $types, true)) {
$collector->removeFilter(InternalTransferFilter::class);
}
$collector->setLimit($pageSize)->setPage($this->parameters->get('page'));
$collector->setTypes($types);
$paginator = $collector->getPaginatedTransactions();
$paginator->setPath(route('api.v1.budget_limits.transactions', [$budgetLimit->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 the specified resource in storage.
*

View File

@@ -48,10 +48,12 @@ class BudgetLimitRequest extends Request
public function getAll(): array
{
return [
'budget_id' => $this->integer('budget_id'),
'start_date' => $this->date('start_date'),
'end_date' => $this->date('end_date'),
'amount' => $this->string('amount'),
'budget_id' => $this->integer('budget_id'),
'start' => $this->date('start'),
'end' => $this->date('end'),
'amount' => $this->string('amount'),
'currency_id' => $this->integer('currency_id'),
'currency_code' => $this->string('currency_code'),
];
}
@@ -63,10 +65,12 @@ class BudgetLimitRequest extends Request
public function rules(): array
{
$rules = [
'budget_id' => 'required|exists:budgets,id|belongsToUser:budgets,id',
'start_date' => 'required|before:end_date|date',
'end_date' => 'required|after:start_date|date',
'amount' => 'required|more:0',
'budget_id' => 'required|exists:budgets,id|belongsToUser:budgets,id',
'start' => 'required|before:end|date',
'end' => 'required|after:start|date',
'amount' => 'required|more:0',
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code',
];
switch ($this->method()) {
default:
@@ -76,6 +80,12 @@ class BudgetLimitRequest extends Request
$rules['budget_id'] = 'required|exists:budgets,id|belongsToUser:budgets,id';
break;
}
// if request has a budget already, drop the rule.
$budget = $this->route()->parameter('budget');
if (null !== $budget) {
unset($rules['budget_id']);
}
return $rules;
}