PHPackages                             whilesmart/eloquent-holdings - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. whilesmart/eloquent-holdings

ActiveLibrary[Database &amp; ORM](/categories/database)

whilesmart/eloquent-holdings
============================

Polymorphic holdings register (crypto, stocks, property, any asset) for Laravel: track quantity and value, with pluggable live pricing.

1.0.0(today)019↑2584.2%MITPHPPHP ^8.2

Since Jun 27Pushed todayCompare

[ Source](https://github.com/whilesmartphp/eloquent-holdings)[ Packagist](https://packagist.org/packages/whilesmart/eloquent-holdings)[ RSS](/packages/whilesmart-eloquent-holdings/feed)WikiDiscussions dev Synced today

READMEChangelog (1)Dependencies (5)Versions (4)Used By (0)

whilesmart/eloquent-holdings
============================

[](#whilesmarteloquent-holdings)

A polymorphic holdings register for Laravel: one model for anything you own and want to value, whether crypto, stocks, property, or collectibles. Each holding is scoped to an owner (a workspace, organization, user) through [`whilesmart/eloquent-owner-access`](https://github.com/whilesmartphp/eloquent-owner-access), carries a quantity and a unit price, and can be priced by hand or refreshed automatically from a price provider you bind.

The package never hard codes a price source. It stores an opaque `provider` and `external_ref`, and asks a host-bound `HoldingPriceProvider` to resolve prices, so a CoinGecko, stock, or any other feed lives in your app, not here.

Install
-------

[](#install)

```
composer require whilesmart/eloquent-holdings
php artisan migrate

```

Routes register automatically under the `api` prefix with `auth:sanctum`. Set `HOLDINGS_REGISTER_ROUTES=false` to mount them yourself.

Owning model
------------

[](#owning-model)

Add the trait to whatever owns holdings:

```
use Whilesmart\Holdings\Traits\HasHoldings;

class Workspace extends Model
{
    use HasHoldings;
}

// Manual: you maintain the price
$workspace->holdings()->create([
    'name' => 'Rental flat',
    'quantity' => 1,
    'currency' => 'USD',
    'unit_price' => 120000,
]);

// Auto: refreshed from a bound provider
$workspace->holdings()->create([
    'name' => 'Bitcoin',
    'symbol' => 'BTC',
    'quantity' => 0.5,
    'currency' => 'USD',
    'price_source' => 'auto',
    'provider' => 'coingecko',
    'external_ref' => 'bitcoin',
]);
```

`$holding->value` returns `quantity * unit_price` in the holding's currency.

Live pricing
------------

[](#live-pricing)

Implement `HoldingPriceProvider` in your app and bind it. The package groups auto-priced holdings by `(provider, currency)` and asks for current prices:

```
use Whilesmart\Holdings\Contracts\HoldingPriceProvider;

class CoingeckoPriceProvider implements HoldingPriceProvider
{
    public function prices(string $provider, array $externalRefs, string $currency): array
    {
        if ($provider !== 'coingecko') {
            return [];
        }
        // ...call CoinGecko, return [externalRef => price] in $currency
    }
}

// AppServiceProvider::register()
$this->app->bind(HoldingPriceProvider::class, CoingeckoPriceProvider::class);
```

Refresh prices via the command (schedule it as you like) or the API:

```
php artisan holdings:reprice
POST /api/holdings/reprice

```

A `HoldingsRepriced` event carries the ids of the holdings that changed, so the host can invalidate caches or recompute net worth.

Authorization
-------------

[](#authorization)

Records are owner-scoped. Bind an `OwnerAuthorizer` (see `whilesmart/eloquent-owner-access`) to decide who can see and modify each owner's holdings. Without one, the permissive default applies.

Endpoints
---------

[](#endpoints)

MethodPathActionGET`/api/holdings`List (owner-scoped; filter by `owner_type`/`owner_id`, `price_source`, `q`)POST`/api/holdings`CreateGET`/api/holdings/{holding}`ShowPUT/PATCH`/api/holdings/{holding}`UpdateDELETE`/api/holdings/{holding}`Delete (soft)POST`/api/holdings/reprice`Refresh auto-priced holdingsDevelopment
-----------

[](#development)

```
make bootstrap   # one-time: pull the package make targets out of the image
make test        # run the test suite in a container
make lint        # pint --test

```

###  Health Score

43

—

FairBetter than 90% of packages

Maintenance100

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a1ca6f6e01ecbfe6640ff410c4f0321054fb48d05a5f843c2b89887b90369bcd?d=identicon)[whilesmart](/maintainers/whilesmart)

---

Top Contributors

[![nfebe](https://avatars.githubusercontent.com/u/14317775?v=4)](https://github.com/nfebe "nfebe (1 commits)")

###  Code Quality

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/whilesmart-eloquent-holdings/health.svg)

```
[![Health](https://phpackages.com/badges/whilesmart-eloquent-holdings/health.svg)](https://phpackages.com/packages/whilesmart-eloquent-holdings)
```

###  Alternatives

[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11222.5M32](/packages/anourvalar-eloquent-serialize)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135212.4k7](/packages/statamic-rad-pack-runway)[mozex/laravel-scout-bulk-actions

Import, flush, and queue-import all your Laravel Scout searchable models at once. Auto-discovers models, runs in bulk, tracks progress.

1437.7k](/packages/mozex-laravel-scout-bulk-actions)[ramadan/easy-model

A Laravel package for enjoyably managing database queries.

111.6k](/packages/ramadan-easy-model)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
