diff --git a/app/JsonApi/V3/Accounts/AccountRepository.php b/app/JsonApi/V3/Accounts/AccountRepository.php new file mode 100644 index 0000000000..abe23dbb87 --- /dev/null +++ b/app/JsonApi/V3/Accounts/AccountRepository.php @@ -0,0 +1,60 @@ +withUserGroup($this->userGroup) + ->withServer($this->server) + ->withSchema($this->schema); + } + +} diff --git a/app/JsonApi/V3/Accounts/AccountResource.php b/app/JsonApi/V3/Accounts/AccountResource.php index a289f9a39a..51cd94db43 100644 --- a/app/JsonApi/V3/Accounts/AccountResource.php +++ b/app/JsonApi/V3/Accounts/AccountResource.php @@ -4,6 +4,7 @@ namespace FireflyIII\JsonApi\V3\Accounts; use FireflyIII\Models\Account; use Illuminate\Http\Request; +use Illuminate\Support\Collection; use LaravelJsonApi\Core\Resources\JsonApiResource; /** @@ -22,14 +23,102 @@ class AccountResource extends JsonApiResource public function attributes($request): iterable { return [ - 'created_at' => $this->resource->created_at, - 'updated_at' => $this->resource->updated_at, - 'name' => $this->resource->name, - 'account_type' => $this->resource->accountType->type, - 'virtual_balance' => $this->resource->virtual_balance, - 'iban' => $this->resource->iban, - 'active' => $this->resource->active, - 'order' => $this->resource->order, + 'created_at' => $this->resource->created_at, + 'updated_at' => $this->resource->updated_at, + 'name' => $this->resource->name, + 'iban' => '' === $this->resource->iban ? null : $this->resource->iban, + 'active' => $this->resource->active, + 'last_activity' => $this->resource->last_activity, + 'type' => $this->resource->type, + 'account_role' => $this->resource->account_role, + + + + + + + // 'virtual_balance' => $this->resource->virtual_balance, + // 'native_balance' => $this->resource->native_balance, + //'user' => $this->resource->user_array, +// 'balances' => [] +// + // currency +// 'currency_id' => $this->resource->currency_id, +// 'currency_code' => $this->resource->currency_code, +// 'currency_symbol' => $this->resource->currency_symbol, +// 'currency_decimal_places' => $this->resource->currency_decimal_places, + + // balance (in currency, on date) +// 'current_balance' => $this->resource->current_balance, + + + // 'current_balance' => app('steam')->bcround(app('steam')->balance($account, $date), $decimalPlaces), + // 'current_balance_date' => $date->toAtomString(), + // 'notes' => $this->repository->getNoteText($account), + // 'monthly_payment_date' => $monthlyPaymentDate, + // 'credit_card_type' => $creditCardType, + // 'account_number' => $this->repository->getMetaValue($account, 'account_number'), + // 'bic' => $this->repository->getMetaValue($account, 'BIC'), + // 'opening_balance' => $openingBalance, + // 'opening_balance_date' => $openingBalanceDate, + // 'liability_type' => $liabilityType, + // 'liability_direction' => $liabilityDirection, + // 'interest' => $interest, + // 'interest_period' => $interestPeriod, + // 'current_debt' => $this->repository->getMetaValue($account, 'current_debt'), + // 'include_net_worth' => $includeNetWorth, + // 'longitude' => $longitude, + // 'latitude' => $latitude, + // 'zoom_level' => $zoomLevel, + + // 'order' => $order, + + // 'currency_id' => (string) $currency->id, + // 'currency_code' => $currency->code, + // 'currency_symbol' => $currency->symbol, + // 'currency_decimal_places' => $currency->decimal_places, + // + // 'native_currency_id' => (string) $this->default->id, + // 'native_currency_code' => $this->default->code, + // 'native_currency_symbol' => $this->default->symbol, + // 'native_currency_decimal_places' => $this->default->decimal_places, + // + // // balance: + // 'current_balance' => $balance, + // 'native_current_balance' => $nativeBalance, + // 'current_balance_date' => $this->getDate()->endOfDay()->toAtomString(), + // + // // balance difference + // 'balance_difference' => $balanceDiff, + // 'native_balance_difference' => $nativeBalanceDiff, + // 'balance_difference_start' => $diffStart, + // 'balance_difference_end' => $diffEnd, + // + // // more meta + // 'last_activity' => array_key_exists($id, $this->lastActivity) ? $this->lastActivity[$id]->toAtomString() : null, + // + // // liability stuff + // 'liability_type' => $liabilityType, + // 'liability_direction' => $liabilityDirection, + // 'interest' => $interest, + // 'interest_period' => $interestPeriod, + // 'current_debt' => $currentDebt, + // + // // object group + // 'object_group_id' => null !== $objectGroupId ? (string) $objectGroupId : null, + // 'object_group_order' => $objectGroupOrder, + // 'object_group_title' => $objectGroupTitle, + // 'notes' => $this->repository->getNoteText($account), + // 'monthly_payment_date' => $monthlyPaymentDate, + // 'credit_card_type' => $creditCardType, + // 'bic' => $this->repository->getMetaValue($account, 'BIC'), + // 'virtual_balance' => number_format((float) $account->virtual_balance, $decimalPlaces, '.', ''), + // 'opening_balance' => $openingBalance, + // 'opening_balance_date' => $openingBalanceDate, + // 'include_net_worth' => $includeNetWorth, + // 'longitude' => $longitude, + // 'latitude' => $latitude, + // 'zoom_level' => $zoomLevel, ]; } @@ -43,7 +132,8 @@ class AccountResource extends JsonApiResource public function relationships($request): iterable { return [ - 'user' => $this->relation('user') + $this->relation('user')->withData($this->resource->user), + $this->relation('balances')->withData($this->resource->balances), ]; } diff --git a/app/JsonApi/V3/Accounts/Capabilities/AccountQuery.php b/app/JsonApi/V3/Accounts/Capabilities/AccountQuery.php new file mode 100644 index 0000000000..ea46fce8f1 --- /dev/null +++ b/app/JsonApi/V3/Accounts/Capabilities/AccountQuery.php @@ -0,0 +1,81 @@ +queryParameters->filter(); + $sort = $this->queryParameters->sortFields(); + $pagination = $this->filtersPagination($this->queryParameters->page()); + $needsAll = $this->validateParams('account', $sort); + $query = $this->userGroup->accounts(); + + if (!$needsAll) { + $query = $this->addPagination($query, $pagination); + } + $query = $this->addSortParams($query, $sort); + $query = $this->addFilterParams('account', $query, $filters); + + $collection = $query->get(['accounts.*']); + + // enrich data + $enrichment = new AccountEnrichment(); + $collection = $enrichment->enrich($collection); + + + // add filters after the query + + // add sort after the query + $collection = $this->sortCollection($collection, $sort); + + + return $collection; + +// var_dump($filters->value('name')); +// exit; + } +} diff --git a/app/JsonApi/V3/Server.php b/app/JsonApi/V3/Server.php index 78a5beec6a..b94c51d0cd 100644 --- a/app/JsonApi/V3/Server.php +++ b/app/JsonApi/V3/Server.php @@ -3,6 +3,7 @@ namespace FireflyIII\JsonApi\V3; use FireflyIII\JsonApi\V3\Accounts\AccountSchema; +use FireflyIII\JsonApi\V3\Balances\BalanceSchema; use FireflyIII\JsonApi\V3\Users\UserSchema; use LaravelJsonApi\Core\Server\Server as BaseServer; @@ -36,6 +37,7 @@ class Server extends BaseServer return [ AccountSchema::class, UserSchema::class, + BalanceSchema::class, ]; } diff --git a/app/JsonApi/V3/Users/UserSchema.php b/app/JsonApi/V3/Users/UserSchema.php index ef56aa5284..ccc307b9d4 100644 --- a/app/JsonApi/V3/Users/UserSchema.php +++ b/app/JsonApi/V3/Users/UserSchema.php @@ -7,6 +7,7 @@ use LaravelJsonApi\Eloquent\Contracts\Paginator; use LaravelJsonApi\Eloquent\Fields\DateTime; use LaravelJsonApi\Eloquent\Fields\ID; use LaravelJsonApi\Eloquent\Fields\Relations\HasMany; +use LaravelJsonApi\Eloquent\Fields\Str; use LaravelJsonApi\Eloquent\Filters\WhereIdIn; use LaravelJsonApi\Eloquent\Pagination\PagePagination; use LaravelJsonApi\Eloquent\Schema; @@ -31,8 +32,9 @@ class UserSchema extends Schema return [ ID::make(), DateTime::make('created_at')->sortable()->readOnly(), - DateTime::make('created_at')->sortable()->readOnly(), - //HasMany::make('accounts'), + DateTime::make('updated_at')->sortable()->readOnly(), + Str::make('email'), + HasMany::make('accounts'), ]; } diff --git a/app/Policies/AccountPolicy.php b/app/Policies/AccountPolicy.php index d0394bfce6..3f7b05fa2f 100644 --- a/app/Policies/AccountPolicy.php +++ b/app/Policies/AccountPolicy.php @@ -53,4 +53,19 @@ class AccountPolicy return true; return auth()->check(); } + + /** + * Everybody can do this, but selection should limit to user. + * + * @return true + */ + public function viewUser(User $user, Account $account): bool + { + return $this->view($user, $account); + } + + public function viewBalances(User $user, Account $account): bool + { + return $this->view($user, $account); + } } diff --git a/app/Policies/BalancePolicy.php b/app/Policies/BalancePolicy.php new file mode 100644 index 0000000000..3571a0e870 --- /dev/null +++ b/app/Policies/BalancePolicy.php @@ -0,0 +1,53 @@ +check() && $user->id === $account->user_id; + } + + /** + * Everybody can do this, but selection should limit to user. + * + * @return true + */ + public function viewAny(): bool + { + return auth()->check(); + } +} diff --git a/app/Support/JsonApi/Enrichments/AccountEnrichment.php b/app/Support/JsonApi/Enrichments/AccountEnrichment.php index f827d9f528..cfc4fd0b97 100644 --- a/app/Support/JsonApi/Enrichments/AccountEnrichment.php +++ b/app/Support/JsonApi/Enrichments/AccountEnrichment.php @@ -51,6 +51,11 @@ class AccountEnrichment implements EnrichmentInterface $this->collection->transform(function (Account $account) { $account->user_array = ['id' => 1,'bla bla' => 'bla']; + $account->balances = collect([ + ['balance_id' => 1,'balance' => 5], + ['balance_id' => 2,'balance' => 5], + ['balance_id' => 3,'balance' => 5], + ]); return $account; }); diff --git a/routes/api.php b/routes/api.php index 151f63eb4c..1cdb0c9f96 100644 --- a/routes/api.php +++ b/routes/api.php @@ -23,14 +23,18 @@ declare(strict_types=1); use LaravelJsonApi\Laravel\Facades\JsonApiRoute; -use LaravelJsonApi\Laravel\Routing\ResourceRegistrar; use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController; +use LaravelJsonApi\Laravel\Routing\Relationships; +use LaravelJsonApi\Laravel\Routing\ResourceRegistrar; JsonApiRoute::server('v3') ->prefix('v3') ->resources(function (ResourceRegistrar $server) { - $server->resource('accounts', JsonApiController::class); + $server->resource('accounts', JsonApiController::class)->readOnly()->relationships(function (Relationships $relations) { + $relations->hasOne('user')->readOnly(); + $relations->hasMany('balances')->readOnly(); + }); $server->resource('users', JsonApiController::class); });