PHPackages                             compono-kit/prices - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. compono-kit/prices

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

compono-kit/prices
==================

Implementations for compono-kit/price-interfaces

2.0.1(3mo ago)031proprietaryPHPPHP &gt;=8.3

Since Oct 19Pushed 3mo agoCompare

[ Source](https://github.com/compono-kit/prices)[ Packagist](https://packagist.org/packages/compono-kit/prices)[ RSS](/packages/compono-kit-prices/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (3)Versions (5)Used By (1)

Prices
======

[](#prices)

PHP types representing prices including gross amount, net amount, vat amount and vat rate A price include the gross, net and VAT amount, as well as the VAT rate. The missing values are automatically calculated by the class depending on the instantiation method.

Contents
--------

[](#contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Instantiation](#instantiation)
- [VatRate](#vatrate)
- [Multiplication and division of prices](#multiplication-and-division-of-prices)
- [Addition and subtraction](#addition-and-subtraction)
- [TotalPrice](#totalprice)
- [Json](#json)
- [Exceptions](#exceptions)

Requirements
------------

[](#requirements)

- PHP &gt;= 8.3
- compono-kit/price-interfaces

Installation 📦
--------------

[](#installation-)

```
composer require compono-kit/prices
```

Instantiation
-------------

[](#instantiation)

You have the gross and net amount, as well as the VAT rate

```
$net     = new Money( 1672, new EUR() );
$gross   = new Money( 1990, new EUR() );
$vatRate = new VatRate( 19 );

$price = new GrossBasedPrice( $net, $gross, $vatRate );
$price->getGrossAmount(); //new Money( 1990, new EUR() )
$price->getNetAmount(); //new Money( 1672, new EUR() )
$price->getVatAmount(); //new Money( 318, new EUR() )
$price->getVatRate(); //new VatRate( 19 )
```

You have the gross amount and the VAT rate

```
$gross   = new Money( 1990, new EUR() );
$vatRate = new VatRate( 19 );

$price = GrossBasedPrice::fromGrossAmount( $gross, $vatRate );
$price->getGrossAmount(); //new Money( 1990, new EUR() )
$price->getNetAmount(); //new Money( 1672, new EUR() )
$price->getVatAmount(); //new Money( 318, new EUR() )
$price->getVatRate(); //new VatRate( 19 )
```

You have the net amount and the VAT rate

```
$net     = new Money( 1672, new EUR() );
$vatRate = new VatRate( 19 );

$price = GrossBasedPrice::fromNetAmount( $net, $vatRate );
$price->getGrossAmount(); //new Money( 1990, new EUR() )
$price->getNetAmount(); //new Money( 1672, new EUR() )
$price->getVatAmount(); //new Money( 318, new EUR() )
$price->getVatRate(); //new VatRate( 19 )
```

You want a new price type by another price type

```
$grossBasedPrice = GrossBasedPrice::fromGrossAmount( new Money( 1990, new EUR() ), new VatRate(19) );
$netBasedPrice   = NetBasedPrice::fromPrice( $price );

$netBasedPrice->getGrossAmount(); //new Money( 1990, new EUR() )
$netBasedPrice->getNetAmount(); //new Money( 1672, new EUR() )
$netBasedPrice->getVatAmount(); //new Money( 318, new EUR() )
$netBasedPrice->getVatRate(); //new VatRate( 19 )
```

---

In some circumstances, it may matter whether the price is generated from the net or gross amount.

Example:

- VAT rate: 19 %
- Gross amount: 9,99 EUR
    - Calculated net amount: 8,39 EUR (9,99 / 1,19 = rounded 8,39)
- Net amount: 8,39 EUR
    - Calculated gross amount: 9,98 EUR (8,39 \* 1,19 = rounded 9,98)

The method `fromNetAndGrossAmount`, which calculates VAT independently, does not exist because the calculation is not reliable. There are countries with VAT rates that have decimal places. If these are taken into account, rounding can result in incorrect VAT rates.

Example:

- Gross: 9,99 EUR
- Net: 8,39 EUR
- Expected vat rate: 19,00 %
- Calculated vat rate, after rounding and with 2 decimal places: 19,07 %

### VatRate

[](#vatrate)

You can instantiate the `VatRate` by a float value or by an integer value. The integer value must be the float value multiplied by 100. The following example generates the same VAT rate. The VAT rate is 21,70 %.

```
$vatRateByFloat = new VatRate( 21.7 );
$vatRateByInt = VatRate::fromInt( 2170 );
$vatRateByFloat->equals( $vatRateByInt ); //true
```

Multiplication and division of prices
-------------------------------------

[](#multiplication-and-division-of-prices)

There are two ways to calculate VAT when multiplying by the quantity. This is the difference between `GrossBasedPrice` and `NetBasePrice`.

### `NetBasedPrice`

[](#netbasedprice)

VAT is calculated after multiplying the unit price by the quantity.

Example: `90,82 € * 10 = 908,20 € * 1.19 = 1080,76 €`

```
$unitPrice  = NetBasedPrice::fromGrossAmount( new Money( 10808, new EUR() ) );
$totalPrice = $price->multiply( 10 );

$unitPrice->getGrossAmount(); //new Money( 10808, new EUR() )
$unitPrice->getNetAmount(); //new Money( 9082, new EUR() )
$totalPrice->getGrossAmount(); //new Money( 108076, new EUR() )
$totalPrice->getNetAmount(); //new Money( 90820, new EUR() )
```

### `GrossBasedPrice`

[](#grossbasedprice)

First, the VAT is calculated on the unit price and then multiplied by the quantity.

Example: `90,82 € * 1,19 = 108,08 € * 3 = 1080,80 €`

```
$unitPrice  = GrossBasedPrice::fromNetAmount( new Money( 9082, new EUR() ) );
$totalPrice = $price->multiply( 10 );

$unitPrice->getGrossAmount(); //new Money( 10808, new EUR() )
$unitPrice->getNetAmount(); //new Money( 9082, new EUR() )
$totalPrice->getGrossAmount(); //new Money( 108080, new EUR() )
$totalPrice->getNetAmount(); //new Money( 90824, new EUR() )
```

---

Division works like multiplication, except of course you divide instead of multiply.

Addition and subtraction
------------------------

[](#addition-and-subtraction)

```
$price  = GrossBasedPrice::fromGrossAmount( new Money( 1000, new EUR() ) );

$sum    = $price->add( GrossBasedPrice::fromGrossAmount( new Money( 1000, new EUR() ) ) );
$sum->getGrossAmount(); //new Money( 2000, new EUR() )

$difference = $price->subtract( GrossBasedPrice::fromGrossAmount( new Money( 1000, new EUR() ) ) );
$difference->getGrossAmount(); //new Money( 0, new EUR() )
```

TotalPrice
----------

[](#totalprice)

While `RepresentsPrice` (or the implementation of it) is used primarily for the prices of order items, `RepresentsTotalPrice` (or the implementation of it) is used as the total price of an order.

In this case, the prices are not merely added together, but can be returned, grouped by VAT rate, for example.

```
$prices = [
    GrossBasedPrice::fromGrossAmount( new Money( 100, new EUR() ), new VatRate( 19 ) ),
    FakePriceImplementation::fromGrossAmount( new Money( 300, new EUR() ), new VatRate( 7 ) ),
];
$additionalPrice = GrossBasedPrice::fromGrossAmount( new Money( 100,  new EUR() ), new VatRate( 16.5 ) );

$totalPrice = new TotalPrice( new MoneyFactory( new EUR() ), $prices );
$totalPrice->addPrice( $additionalPrice );

$anotherTotalPrice = new TotalPrice(
  new MoneyFactory( new EUR() ),
  [
    NetBasedPrice::fromGrossAmount( new Money( 200,  new EUR()  ), new VatRate( 16.5 ) ),
    FakePriceImplementation::fromGrossAmount( new Money( 300,  new EUR() ), new VatRate( 16.5 ) ),
  ]
);

$totalPrice->addTotalPrice( $anotherTotalPrice );

$totalPrice->getPrices(); // Array with prices from $prices, $additionalPrice and the prices from $anotherTotalPrice
$totalPrice->getTotalGrossAmount(); // new Money( 1000, new EUR() ) (100 + 300 + 100 + 200 + 300)
$totalPrice->getTotalNetAmount(); // new Money( 794, new EUR() ) (100/1,19 + 300/1,07 + (200 + 300)/1,165)
$totalPrice->getTotalVatAmount(); // new Money( 206, 'EUR ) (1000 - 794)
```

Return by grouped vat rates.

```
$prices = [
    GrossBasedPrice::fromGrossAmount( new Money( 100, new EUR() ), new VatRate( 19 ) ),
    GrossBasedPrice::fromGrossAmount( new Money( 200, new EUR() ), new VatRate( 19 ) ),
    FakePriceImplementation::fromGrossAmount( new Money( 300, new EUR() ), new VatRate( 7 ) ),
];
$totalPrice = new TotalPrice( new MoneyFactory( new EUR() ), $prices );
$totalPrice->getPricesGroupedByVatRates();
/**
  [
    1900 => [
      GrossBasedPrice::fromGrossAmount( new Money( 100, new EUR() ), new VatRate( 19 ) ),
      GrossBasedPrice::fromGrossAmount( new Money( 200, new EUR() ), new VatRate( 19 ) ),
    ],
    700 => [ FakePriceImplementation::fromGrossAmount( new Money( 300, new EUR() ), new VatRate( 7 ) ) ]
  ]
**/
```

Json
----

[](#json)

```
$prices = [
  GrossBasedPrice::fromGrossAmount( new Money( 100,  new EUR()  ), new VatRate( 19 ) ),
  FakePriceImplementation::fromGrossAmount( new Money( 300,  new EUR()  ), new VatRate( 19 ) ),
  NetBasedPrice::fromGrossAmount( new Money( 200,  new EUR()  ), new VatRate( 7 ) ),
];
$totalPrice = new TotalPrice( new MoneyFactory( new EUR() ), $prices );
json_encode( $totalPrice, JSON_PRETTY_PRINT );
```

```
{
    "currency-code": "EUR",
    "prices": {
        "1900": [
            {
                "gross": 100,
                "net": 84,
                "vat": 16
            },
            {
                "gross": 300,
                "net": 252,
                "vat": 48
            }
        ],
        "700": [
            {
                "gross": 200,
                "net": 187,
                "vat": 13
            }
        ]
    }
}
```

Exceptions
----------

[](#exceptions)

### InvalidPriceException

[](#invalidpriceexception)

If prices with different VAT rates are added or subtracted `InvalidPriceException` will be thrown

### InvalidVatRateException

[](#invalidvatrateexception)

If `VatRate` is instantiated with a value less than zero `InvalidVatRateException` will be thrown

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance82

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity53

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

Every ~59 days

Total

3

Last Release

94d ago

Major Versions

1.0.0 → 2.0.02025-10-19

PHP version history (2 changes)1.0.0PHP &gt;=8.0

2.0.0PHP &gt;=8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/8b4875ebadf24ddeae09bd59c44c9a86a61c3d3892fe1d4a264ad167b6d230cc?d=identicon)[Hansel23](/maintainers/Hansel23)

---

Top Contributors

[![Hansel23](https://avatars.githubusercontent.com/u/15147826?v=4)](https://github.com/Hansel23 "Hansel23 (7 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/compono-kit-prices/health.svg)

```
[![Health](https://phpackages.com/badges/compono-kit-prices/health.svg)](https://phpackages.com/packages/compono-kit-prices)
```

###  Alternatives

[funct/funct

A PHP library with commonly used code blocks

605141.2k75](/packages/funct-funct)[imanghafoori/laravel-terminator

A minimal yet powerful package to give you opportunity to refactor your controllers.

25353.0k](/packages/imanghafoori-laravel-terminator)[hanson/chinese

简繁体转换.

2317.0k](/packages/hanson-chinese)[maisondunet/module-gtm-cookie-consent

A simple cookie consent module for magento. It relies on new GTM consent functionality.

134.5k](/packages/maisondunet-module-gtm-cookie-consent)

PHPackages © 2026

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