allow vendord
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s

This commit is contained in:
2026-03-30 14:54:57 +07:00
parent 66aed7c4e8
commit b5e3a778ce
21316 changed files with 2777892 additions and 13 deletions

13
vendor/moneyphp/money/.readthedocs.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3"
python:
install:
- requirements: doc/requirements.txt
sphinx:
configuration: doc/conf.py

569
vendor/moneyphp/money/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,569 @@
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [4.8.0] - 2025-10-23
### Added
- PHP 8.5 support
## [4.7.1] - 2025-06-06
### Updated
- Updated the ISO and Crypto currencies
## [4.7.0] - 2025-04-03
### Added
- Subtypes of InvalidArgumentException
## [4.6.0] - 2024-11-22
### Added
- PHP 8.4 support
## [4.5.0] - 2024-02-15
### Fixed
- PHPUnit 10 support
- Update currencies
- Updated doctrine/coding-standard
- Updated other dev dependencies
### Removed
- PHP 8.0 support
## [4.4.0] - 2024-01-24
### Added
- Extended support for psr/cache, now version 1.0.1 up until 3.0 is supported.
## [4.3.0] - 2023-11-22
### Added
- Support for PHP 8.3
- Allow divisor in mod to be a number as well
### Removed
- PHPSpec tests, we are using PHPUnit only now
## [4.2.0] - 2023-08-16
### Added
- Teller object to help legacy applications
## [4.1.1] - 2023-04-11
### Fixed
- Optimized result representation for BcMathCalculator
- Use sprintf for float to string conversion in swap exchange
- Fix rounding to unit with value between 10 and 49
- Return type for DecimalMoneyFormatter::format is numeric-string
- Money::ratioOf throws exception if currencies don't match.
- Updated currencies: added SLE and VED, removed HRK.
- Do not let php-http/discovery change composer.json.
## [4.1.0] - 2022-12-19
### Added
- Full PHP8.2 compatibility
### Fixed
- Fix parsing amounts with leading zero's
- Fix invalid exception message in DecimalMoneyParser
- Upgrade enchant to newer version
- Support Psalm 5.3
- Fix ROUND_UP and ROUND_DOWN in roundToUnit
### Changes
- `composer.lock` is not committed anymore
- MoneyFactory now also contains crypto-currencies
### Added
- `CryptoCurrencies` class that serves crypto-currencies from [moneyphp/crypto-currencies](https://github.com/moneyphp/crypto-currencies)
## [4.0.5] - 2022-08-11
### Fixed
- Enabled zend.assertions during CI
- Fixed invalid assertions
## [4.0.4] - 2022-05-18
### Added
- Full PHP8.1 compatibility (#670)
### Changes
- Dropped mutation testing as the library owners are unfamiliar with it
- CHANGELOG BC change improvement
## [4.0.3] - 2021-12-01
### Fixed
- `jsonSerialize` return types, resulting in no PHP 8.1 warnings.
- Documentation CI pipeline failure.
## [4.0.2] - 2021-06-30
### Changes
- Added all extensions to `composer.json`, including those bundled with PHP.
### Fixed
- Remove all `empty` uses. Money values of '0' gave an assertion error in decimal formats (#655)
## [4.0.1] - 2021-05-25
### Changed
- Allow `int` as multiplier for `Money::multiply`
- Allow `int` as divisor for `Money::divide`
## [4.0.0] - 2021-05-17
### Added
- PHP8.0 compatibility (#633 and #619)
- Recommendation to use a type-checker like psalm or phpstan
- Rounding to units
- `Converter#convertAndReturnWithCurrencyPair` to get the combination of the converted money and currency pair
- `Converter#convertAgainstCurrencyPair` to convert against a currency pair
### Changed
- **[BC break]** BC Math required as it is the default calculator
- **[BC break]** The methods `multiply` and `divide` do not accept floating points any more. Callers are required to
convert a float to string (e.g. `sprintf('%.14F', $float)`) before calling these methods.
- **[BC break]** The constructor of the `FixedExchange` does not accept floating points any more. Callers are required to
convert a float to string (e.g. `sprintf('%.14F', $float)`) before calling the constructor.
- Allow multiple arguments to `Money#isSameCurrency`
- Renamed second parameter of `Parser#parse` to `$fallbackCurrency`
### Fixed
- Fix GMP multiply and divide by negative (#640 #626)
- Currency code must be uppercase (#639 #638 #637)
- The CPU no longer overheats when using this library (#634)
- No longer allowing null amount (#615)
- Update cached currencies (#583)
- Only numeric strings allowed (#575)
- Calculator and Number are internal (#465)
- Negative ratio in `Money#allocate()` is now allowed (#258)
### Removed
- **[BC break]** Removed `PhpCalculator`
- **[BC break]** Removed `Currency#isAvailableWithin()`
- **[BC break]** Removed string as allowed type for second parameter to `MoneyParser#parse`, only Currency objects are accepted now
- **[BC break]** Completely remove float usage, methods now return numeric-strings
## [3.3.1] - 2019-03-13
### Fixed
- GMP: division of negative values
- GMP: compare 0.x value
## [3.3.0] - 2019-12-27
### Changed
- Added types for `Money` to be understood as pure/immutable downstream (#576)
### Fixed
- JSON serialization (#551)
- Several documentation fixes
- Minor fixes
## [3.2.1] - 2019-02-07
### Changed
- `Money::allocate` now maintains keys of ratios array
- All parsers now emit a deprecation warning when passing currency as string
### Fixed
- Docs fix : plus sign in numeric strings is allowed
- Added ext-json as required extension
- Throw exception in case of empty currency
- BCMath calculator now uses scale parameters for addition and subtracting
- Fixed allocation remainder bug
- Added PHP 7.3 in test suite
- Fixed dockerignore to ignore Dockerfile
- Fixed Bitcoin parsing bug when using trailing zeros
## [3.2.0] - 2018-12-05
### Added
- [Exchanger](https://github.com/florianv/exchanger) exchange
- Generated static factory to help IDEs understand code like `Money::EUR(500)`
- Aggregation functions (min, max, avg, sum)
### Changed
- `Money::add` and `Money::subtract` now accept variadic arguments
### Fixed
- Division causing unnecessary fractional parts
- Numeric comparison for negative numbers
## [3.1.3] - 2018-02-16
### Fixed
- Allocation when the amount is smaller than the number of ratios
## [3.1.2] - 2018-02-16
### Added
- `Number::fromNumber` to be used when the actual type is not known
### Changed
- Refactored `Number` usage to make the code cleaner and use less casting
### Fixed
- Float cast to string issue on certain locales
## [3.1.1] - 2018-01-19
### Fixed
- Float cast to string issue on certain locales
- Deal with numbers represented with E-XX
## [3.1.0] - 2018-01-10
### Added
- CurrencyList to instantiate in-memory currencies
- modulus method to Money
- ratioOf method to Money
- Comparator for easier testing Money object with PHPUnit
- IntlLocalizedDecimalParser and IntlLocalizedDecimalFormatter
### Changed
- `MoneyParser::parse` method now expects a Currency object
- Dropped PHP 5.5
### Deprecated
- Passing currency code as string to `MoneyParser::parse`
### Fixed
- Do not allocate remainder to a ratio of zero
- Conversion result is always 0 when subunit difference is large enough
- Unexpected result when converting small Bitcoin amounts
- Fixed StyleCI being too aggressive
## [3.0.9] - 2017-11-05
### Fixed
- Bitcoin currency symbol
## [3.0.8] - 2017-10-03
### Fixed
- Rounding issue in Number class.
- Reduce composer package file size by leaving out docs and logo.
- Missing Travis tests for PHP 7.2.
## [3.0.7] - 2017-08-07
### Changed
- Currencies
## [3.0.6] - 2017-07-25
### Added
- IndirectExchange: a way to get an exchange rate through a minimal set of intermediate conversions.
### Fixed
- Tests for HHVM
- Incorrect documentation on Bitcoin parser
## [3.0.5] - 2017-04-26
### Added
- numericCodeFor method to ISOCurrencies
## [3.0.4] - 2017-04-21
### Added
- Negative method
### Changed
- Updated ISO Currencies
- Removed old Belarusian ruble from ISOCurrencies (BYR)
### Fixed
- ISOCurrencies will no longer have a blank currency
- Double symbol when formatting negative Bitcoin amounts
## [3.0.3] - 2017-03-22
### Fixed
- Parsing empty strings and number starting or ending with a decimal point for DecimalMoneyParser
- Parsing zero for DecimalMoneyParser
- Multiplying and dividing with a locale that use commas as separator
## [3.0.2] - 2017-03-11
### Fixed
- BCMath / GMP: comparing values smaller than one
- GMP: multiplying with zero
- ISOCurrencies: minor refactoring, remove duplication of code
## [3.0.1] - 2017-02-14
### Added
- Reversed Currencies Exchange to try resolving reverse of a currency pair
- Documentation on allowed integer(ish) values when constructing Money
### Fixed
- Passing integer validation when chunk started with a dash
- Passing integer validation when the fractional part started with a dash
- Formatting problem for Bitcoin currency with small amounts in PHP < 7.0
- Money constructed from a string with fractional zeroes equals to a Money constructed without the fractional part (eg. `'5.00'` and `'5'`)
## [3.0.0] - 2016-10-26
### Added
- DecimalMoneyFormatter: returns locale-independent raw decimal string
### Changed
- **[BC break]** Replaced StringToUnitsParser with DecimalMoneyParser
- **[BC break]** Moved `Money\Exception\Exception` to `Money\Exception`
- **[BC break]** UnkownCurrencyException is now DomainException instead of RuntimeException
- **[Doctrine break]** In `Currency` the private variable `name` was renamed to `code`, which could break your Doctrine mapping if you are using embeddables or any other Reflection related implementation.
## [3.0.0-beta.3] - 2016-10-04
### Added
- FixedExchange: returns fixed exchange rates based on a list (array)
### Changed
- **[BC break]** Convert method now moved to its own class: Converter
- **[BC break]** Exchange had one method getCurrencyPair which is now renamed to quote
- Minor documentation issues
### Fixed
- Integer detection when the number overflows the integer type and contains zeros
- Rounding numbers containg trailing zeros
- Converting Money to currency with different number of subunits
## [3.0.0-beta.2] - 2016-08-03
### Added
- PHP Spec tests
- absolute method to Money and Calculator
- subunitFor method to Currencies
- Currencies now extends IteratorAggregate
- Library exceptions now implement a common interface
- Formatter and Parser implementation are now rounding half up
### Changed
- **[BC break]** Dropped PHP 5.4 support
- **[BC break]** Intl and Bitcoin formatters and parsers now require Currencies
- ISOCurrencies now uses moneyphp/iso-currencies as currency data source
### Fixed
- Documentation to be inline with upcoming version 3
- Rounding issues in calculators with negative numbers
- Formatting and parser issues for amounts and numbers with a trailing zero
- Improved many exception messages
- Registration of own Calculator implementations
## [3.0.0-beta] - 2016-03-01
### Added
- Bitcoin parser and formatter
- Also checking tests folder for StyleCI
### Fixed
- Currencies are now included in the repo
- Currency list generation moved to dev dependency: reduces repo size
- BC Math calculator adding and subtracting failed when bcscale was set
- Parsing zero for StringToUnitsParser
## 3.0.0-alpha - 2016-02-04
### Added
- Currency repositories (ISO currencies included)
- Money exchange (including [Swap](https://github.com/florianv/swap) implementation)
- Money formatting (including intl formatter)
- Money parsing (including intl parser)
- Big integer support utilizing different, transparent calculation logic upon availability (bcmath, gmp, plain php)
- Money and Currency implements JsonSerializable
- Rounding up and down
- Allocation to N targets
### Changed
- **[BC break]** Money::getAmount() returns a string instead of an int value
- **[BC break]** Moved stringToUnits to StringToUnitsParser parser
- Library requires at least PHP 5.4
- Library uses PSR-4
### Fixed
- Integer overflow
### Removed
- **[BC break]** UnkownCurrency exception
- **[BC break]** Currency list is now provided by [umpirsky/currency-list](https://github.com/umpirsky/currency-list/)
- **[BC break]** RoundingMode class
- **[BC break]** Announced deprecations are removed (Currency::getName, CurrencyPair::getRatio, Money::getUnits)
## Pre 3.0
- 2015-03-23 Minimum php version is now 5.4
- 2015-03-23 JsonSerializable
- (... missing changelog because who remembers to document stuff anyway?)
- 2014-03-22 Removed \Money\InvalidArgumentException in favour of plain old InvalidArgumentException
- 2014-03-22 Introduce RoundingMode object, used to specify desired rounding
- 2014-03-22 Introduced RoundingMode backwards compatible API changes to Money::multiply and Money::divide
- 2014-03-22 Allow RoundingMode to be specified when converting currencies
- 2014-03-22 CurrencyPair has an equals() method
- 2013-10-13 Base currency and counter currency in CurrencyPair named correctly.
- 2013-01-08 Removed the Doctrine2\MoneyType helper, to be replaced by something better in the future. It's available
at https://gist.github.com/4485025 in case you need it.
- 2013-01-08 Use vendor/autoload.php instead of lib/bootstrap.php (or use PSR-0 autolaoding)
- 2012-12-10 Renamed Money::getUnits() to Money::getAmount()
[Unreleased]: https://github.com/moneyphp/money/compare/v4.4.0...HEAD
[4.8.0]: https://github.com/moneyphp/money/compare/v4.7.1...v4.8.0
[4.7.1]: https://github.com/moneyphp/money/compare/v4.7.0...v4.7.1
[4.7.0]: https://github.com/moneyphp/money/compare/v4.6.0...v4.7.0
[4.6.0]: https://github.com/moneyphp/money/compare/v4.5.0...v4.6.0
[4.5.0]: https://github.com/moneyphp/money/compare/v4.4.0...v4.5.0
[4.4.0]: https://github.com/moneyphp/money/compare/v4.3.0...v4.4.0
[4.3.0]: https://github.com/moneyphp/money/compare/v4.2.0...v4.3.0
[4.2.0]: https://github.com/moneyphp/money/compare/v4.1.1...v4.2.0
[4.1.1]: https://github.com/moneyphp/money/compare/v4.1.0...v4.1.1
[4.1.0]: https://github.com/moneyphp/money/compare/v4.0.5...v4.1.0
[4.0.5]: https://github.com/moneyphp/money/compare/v4.0.4...v4.0.5
[4.0.4]: https://github.com/moneyphp/money/compare/v4.0.3...v4.0.4
[4.0.3]: https://github.com/moneyphp/money/compare/v4.0.2...v4.0.3
[4.0.2]: https://github.com/moneyphp/money/compare/v4.0.1...v4.0.2
[4.0.1]: https://github.com/moneyphp/money/compare/v4.0.0...v4.0.1
[4.0.0]: https://github.com/moneyphp/money/compare/v3.3.1...v4.0.0
[3.3.1]: https://github.com/moneyphp/money/compare/v3.3.0...v3.3.1
[3.3.0]: https://github.com/moneyphp/money/compare/v3.2.1...v3.3.0
[3.2.1]: https://github.com/moneyphp/money/compare/v3.2.0...v3.2.1
[3.2.0]: https://github.com/moneyphp/money/compare/v3.1.3...v3.2.0
[3.1.3]: https://github.com/moneyphp/money/compare/v3.1.2...v3.1.3
[3.1.2]: https://github.com/moneyphp/money/compare/v3.1.1...v3.1.2
[3.1.1]: https://github.com/moneyphp/money/compare/v3.1.0...v3.1.1
[3.1.0]: https://github.com/moneyphp/money/compare/v3.0.9...v3.1.0
[3.0.9]: https://github.com/moneyphp/money/compare/v3.0.8...v3.0.9
[3.0.8]: https://github.com/moneyphp/money/compare/v3.0.7...v3.0.8
[3.0.7]: https://github.com/moneyphp/money/compare/v3.0.6...v3.0.7
[3.0.6]: https://github.com/moneyphp/money/compare/v3.0.5...v3.0.6
[3.0.5]: https://github.com/moneyphp/money/compare/v3.0.4...v3.0.5
[3.0.4]: https://github.com/moneyphp/money/compare/v3.0.3...v3.0.4
[3.0.3]: https://github.com/moneyphp/money/compare/v3.0.2...v3.0.3
[3.0.2]: https://github.com/moneyphp/money/compare/v3.0.1...v3.0.2
[3.0.1]: https://github.com/moneyphp/money/compare/v3.0.0...v3.0.1
[3.0.0]: https://github.com/moneyphp/money/compare/v3.0.0-beta.4...v3.0.0
[3.0.0-beta4]: https://github.com/moneyphp/money/compare/v3.0.0-beta.3...v3.0.0-beta.4
[3.0.0-beta3]: https://github.com/moneyphp/money/compare/v3.0.0-beta.2...v3.0.0-beta.3
[3.0.0-beta2]: https://github.com/moneyphp/money/compare/v3.0.0-beta...v3.0.0-beta.2
[3.0.0-beta]: https://github.com/moneyphp/money/compare/v3.0.0-alpha...v3.0.0-beta

21
vendor/moneyphp/money/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) 2011-2016 Mathias Verraes
Copyright (c) 2016 Márk Sági-Kazár <mark.sagikazar@gmail.com>
Copyright (c) 2016 Frederik Bosch <f.bosch@genkgo.nl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

117
vendor/moneyphp/money/README.md vendored Normal file
View File

@@ -0,0 +1,117 @@
# Money
[![Latest Version](https://img.shields.io/github/release/moneyphp/money.svg?style=flat-square)](https://github.com/moneyphp/money/releases)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/moneyphp/money/ci.yml?branch=master&style=flat-square)
[![Total Downloads](https://img.shields.io/packagist/dt/moneyphp/money.svg?style=flat-square)](https://packagist.org/packages/moneyphp/money)
[![Email](https://img.shields.io/badge/email-team@moneyphp.org-blue.svg?style=flat-square)](mailto:team@moneyphp.org)
![Money PHP](/resources/logo.png?raw=true)
PHP library to make working with money safer, easier, and fun!
> "If I had a dime for every time I've seen someone use FLOAT to store currency, I'd have $999.997634" -- [Bill Karwin](https://twitter.com/billkarwin/status/347561901460447232)
In short: You shouldn't represent monetary values by a float Wherever
you need to represent money, use this Money value object. Since version
3.0 this library uses [strings internally](https://github.com/moneyphp/money/pull/136)
in order to support unlimited integers.
```php
<?php
use Money\Money;
$fiveEur = Money::EUR(500);
$tenEur = $fiveEur->add($fiveEur);
list($part1, $part2, $part3) = $tenEur->allocate([1, 1, 1]);
assert($part1->equals(Money::EUR(334)));
assert($part2->equals(Money::EUR(333)));
assert($part3->equals(Money::EUR(333)));
```
The documentation is available at http://moneyphp.org
## Requirements
This library requires the [BCMath PHP extension](https://www.php.net/manual/en/book.bc.php). There might be additional dependencies for specific feature, e.g. the
Swap exchange implementation, check the documentation for more information.
Version 4 requires PHP 8.0. For older version of PHP, use version 3 of this library. From version 4.5 this package
will only support [PHP versions that actually receive updates by PHP itself](https://www.php.net/supported-versions.php).
If you want to use the package with older PHP versions, you can of course use older versions of this package.
## Install
Via Composer
```bash
$ composer require moneyphp/money
```
## Features
- JSON Serialization
- Big integer support utilizing different, transparent calculation logic upon availability (bcmath, gmp, plain php)
- Money formatting (including intl formatter)
- Currency repositories (ISO currencies included)
- Money exchange (including [Swap](http://swap.voutzinos.org) implementation)
## Documentation
Please see the [official documentation](http://moneyphp.org).
## Testing
We try to follow TDD by using [phpunit](https://phpunit.de) to test this library.
```bash
$ composer test
```
### Running the tests in Docker
Money requires a set of dependencies, so you might want to run it in Docker.
First, build the image locally:
```bash
$ docker build -t moneyphp .
```
Then run the tests:
```bash
$ docker run --rm -it -v $PWD:/app -w /app moneyphp vendor/bin/phpunit --exclude-group segmentation
```
## Contributing
We would love to see you helping us to make this library better and better.
Please keep in mind we do not use suffixes and prefixes in class names,
so not `CurrenciesInterface`, but `Currencies`. Other than that, Style CI will help you
using the same code style as we are using. Please provide tests when creating a PR and clear descriptions of bugs when filing issues.
## Security
If you discover any security related issues, please contact us at [team@moneyphp.org](mailto:team@moneyphp.org).
## License
The MIT License (MIT). Please see [License File](LICENSE) for more information.
## Acknowledgements
This library is heavily inspired by [Martin Fowler's Money pattern](http://martinfowler.com/eaaCatalog/money.html).
A special remark goes to [Mathias Verraes](https://github.com/mathiasverraes), without his contributions,
in code and via his [blog](http://verraes.net/#blog), this library would not be where it stands now.

109
vendor/moneyphp/money/composer.json vendored Normal file
View File

@@ -0,0 +1,109 @@
{
"name": "moneyphp/money",
"description": "PHP implementation of Fowler's Money pattern",
"license": "MIT",
"keywords": [
"money",
"vo",
"value object"
],
"authors": [
{
"name": "Mathias Verraes",
"email": "mathias@verraes.net",
"homepage": "http://verraes.net"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com"
},
{
"name": "Frederik Bosch",
"email": "f.bosch@genkgo.nl"
}
],
"homepage": "http://moneyphp.org",
"require": {
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"ext-bcmath": "*",
"ext-filter": "*",
"ext-json": "*"
},
"require-dev": {
"ext-gmp": "*",
"ext-intl": "*",
"cache/taggable-cache": "^1.1.0",
"doctrine/coding-standard": "^12.0",
"doctrine/instantiator": "^1.5.0 || ^2.0",
"florianv/exchanger": "^2.8.1",
"florianv/swap": "^4.3.0",
"moneyphp/crypto-currencies": "^1.1.0",
"moneyphp/iso-currencies": "^3.4",
"php-http/message": "^1.16.0",
"php-http/mock-client": "^1.6.0",
"phpbench/phpbench": "^1.2.5",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.1.9",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.5.9",
"psr/cache": "^1.0.1 || ^2.0 || ^3.0",
"ticketswap/phpstan-error-formatter": "^1.1"
},
"suggest": {
"ext-gmp": "Calculate without integer limits",
"ext-intl": "Format Money objects with intl",
"florianv/exchanger": "Exchange rates library for PHP",
"florianv/swap": "Exchange rates library for PHP",
"psr/cache-implementation": "Used for Currency caching"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"Money\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Benchmark\\Money\\": "benchmark/",
"Tests\\Money\\": "tests/"
}
},
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"ergebnis/composer-normalize": true,
"infection/extension-installer": true,
"php-http/discovery": false,
"phpstan/extension-installer": true
},
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"scripts": {
"benchmark": [
"vendor/bin/phpbench run --retry-threshold=3 --iterations=15 --revs=1000 --warmup=2"
],
"clean": "rm -rf build/ vendor/",
"test": [
"vendor/bin/phpbench run",
"vendor/bin/phpunit",
"vendor/bin/phpstan",
"vendor/bin/phpcs"
],
"test-coverage": [
"vendor/bin/phpunit --coverage-text --coverage-clover=build/unit_coverage.xml"
],
"update-currencies": [
"cp vendor/moneyphp/iso-currencies/resources/current.php resources/currency.php",
"cp vendor/moneyphp/crypto-currencies/resources/binance.php resources/binance.php",
"php resources/generate-money-factory.php",
"php resources/generate-teller-factory.php"
]
}
}

39
vendor/moneyphp/money/phpcs.xml.dist vendored Normal file
View File

@@ -0,0 +1,39 @@
<?xml version="1.0"?>
<ruleset
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd"
>
<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="80"/>
<arg name="colors"/>
<!-- Ignore warnings and show progress of the run -->
<arg value="np"/>
<!-- spec files do not seem to follow reasonable rules around the type system, and therefore should be ignored from CS -->
<!--<file>./spec</file>-->
<file>./src</file>
<file>./static-analysis</file>
<file>./tests</file>
<rule ref="Doctrine">
<!-- some variables and method names are not compliant with CS naming patterns -->
<exclude name="Squiz.NamingConventions.ValidVariableName.NotCamelCaps"/>
<exclude name="PSR1.Methods.CamelCapsMethodName.NotCamelCaps"/>
<!-- renaming exceptions in this library is too big of a BC break for no real benefit -->
<exclude name="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming.SuperfluousSuffix"/>
<!-- language-level non-strict comparison is (consciously) used in the codebase for performance reasons -->
<exclude name="SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedEqualOperator"/>
<exclude name="SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator"/>
<!-- We do not want trailing commas -->
<exclude name="SlevomatCodingStandard.Commenting.RequireOneLineDocComment"/>
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInCall"/>
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInClosureUse"/>
<exclude name="SlevomatCodingStandard.Functions.RequireTrailingCommaInDeclaration"/>
<exclude name="SlevomatCodingStandard.Arrays.TrailingArrayComma"/>
</rule>
</ruleset>

14
vendor/moneyphp/money/phpstan.neon vendored Normal file
View File

@@ -0,0 +1,14 @@
parameters:
level: 6
paths:
- src
- tests
errorFormat: ticketswap
editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
ignoreErrors:
-
identifier: staticMethod.alreadyNarrowedType
path: tests/*
-
identifier: method.alreadyNarrowedType
path: tests/*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
<?php
require __DIR__.'/../vendor/autoload.php';
use Money\Currencies;
use Money\Currency;
(static function (): void {
$buffer = <<<'PHP'
<?php
declare(strict_types=1);
namespace Money;
use InvalidArgumentException;
/**
* This is a generated file. Do not edit it manually!
*
PHPDOC
* @psalm-immutable
*/
trait MoneyFactory
{
/**
* Convenience factory method for a Money object.
*
* <code>
* $fiveDollar = Money::USD(500);
* </code>
*
* @param non-empty-string $method
* @param array{numeric-string|int} $arguments
*
* @throws InvalidArgumentException If amount is not integer(ish).
*
* @psalm-pure
*/
public static function __callStatic(string $method, array $arguments): Money
{
return new Money($arguments[0], new Currency($method));
}
}
PHP;
$methodBuffer = '';
$iterator = new Currencies\AggregateCurrencies([
new Currencies\ISOCurrencies(),
new Currencies\BitcoinCurrencies(),
new Currencies\CryptoCurrencies(),
]);
$currencies = array_unique([...$iterator]);
usort($currencies, static fn (Currency $a, Currency $b): int => strcmp($a->getCode(), $b->getCode()));
/** @var Currency[] $currencies */
foreach ($currencies as $currency) {
$code = $currency->getCode();
if (is_numeric($code[0])) {
preg_match('/^([0-9]*)(.*?)$/', $code, $extracted);
$formatter = new \NumberFormatter('en', \NumberFormatter::SPELLOUT);
$code = strtoupper(preg_replace('/\s+/', '', $formatter->format($extracted[1])) . $extracted[2]);
}
$methodBuffer .= sprintf(" * @method static Money %s(numeric-string|int \$amount)\n", $code);
}
$buffer = str_replace('PHPDOC', rtrim($methodBuffer), $buffer);
file_put_contents(__DIR__.'/../src/MoneyFactory.php', $buffer);
})();

View File

@@ -0,0 +1,93 @@
<?php
require __DIR__.'/../vendor/autoload.php';
use Money\Currencies;
use Money\Currencies\ISOCurrencies;
use Money\Currency;
use Money\Formatter\DecimalMoneyFormatter;
use Money\Money;
use Money\Parser\DecimalMoneyParser;
use Money\Teller;
(static function (): void {
$buffer = <<<'PHP'
<?php
declare(strict_types=1);
namespace Money;
use Money\Currencies\ISOCurrencies;
use Money\Formatter\DecimalMoneyFormatter;
use Money\Parser\DecimalMoneyParser;
use function array_shift;
/**
* This is a generated file. Do not edit it manually!
*
PHPDOC
* @psalm-immutable
*/
trait TellerFactory
{
/**
* Convenience factory method for a Teller object.
*
* <code>
* $teller = Teller::USD();
* </code>
*
* @param non-empty-string $method
* @param array{0?: Money::ROUND_*} $arguments
*/
public static function __callStatic(string $method, array $arguments): Teller
{
$currency = new Currency($method);
$currencies = new ISOCurrencies();
$parser = new DecimalMoneyParser($currencies);
$formatter = new DecimalMoneyFormatter($currencies);
$roundingMode = empty($arguments)
? Money::ROUND_HALF_UP
: (int) array_shift($arguments);
return new Teller(
$currency,
$parser,
$formatter,
$roundingMode
);
}
}
PHP;
$methodBuffer = '';
$iterator = new Currencies\AggregateCurrencies([
new Currencies\ISOCurrencies(),
new Currencies\BitcoinCurrencies(),
new Currencies\CryptoCurrencies(),
]);
$currencies = array_unique([...$iterator]);
usort($currencies, static fn (Currency $a, Currency $b): int => strcmp($a->getCode(), $b->getCode()));
/** @var Currency[] $currencies */
foreach ($currencies as $currency) {
$code = $currency->getCode();
if (is_numeric($code[0])) {
preg_match('/^([0-9]*)(.*?)$/', $code, $extracted);
$formatter = new \NumberFormatter('en', \NumberFormatter::SPELLOUT);
$code = strtoupper(preg_replace('/\s+/', '', $formatter->format($extracted[1])) . $extracted[2]);
}
$methodBuffer .= sprintf(" * @method static Teller %s(int \$roundingMode = Money::ROUND_HALF_UP)\n", $code);
}
$buffer = str_replace('PHPDOC', rtrim($methodBuffer), $buffer);
file_put_contents(__DIR__.'/../src/TellerFactory.php', $buffer);
})();

152
vendor/moneyphp/money/src/Calculator.php vendored Normal file
View File

@@ -0,0 +1,152 @@
<?php
declare(strict_types=1);
namespace Money;
use Money\Exception\InvalidArgumentException;
/**
* Money calculations abstracted away from the Money value object.
*
* @internal the calculator component is an internal detail of this library: it is only supposed to be replaced if
* your system requires a custom architecture for operating on large numbers.
*/
interface Calculator
{
/**
* Compare a to b.
*
* Retrieves a negative value if $a < $b.
* Retrieves a positive value if $a > $b.
* Retrieves zero if $a == $b
*
* @phpstan-param numeric-string $a
* @phpstan-param numeric-string $b
*
* @phpstan-pure
*/
public static function compare(string $a, string $b): int;
/**
* Add added to amount.
*
* @phpstan-param numeric-string $amount
* @phpstan-param numeric-string $addend
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function add(string $amount, string $addend): string;
/**
* Subtract subtrahend from amount.
*
* @phpstan-param numeric-string $amount
* @phpstan-param numeric-string $subtrahend
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function subtract(string $amount, string $subtrahend): string;
/**
* Multiply amount with multiplier.
*
* @phpstan-param numeric-string $amount
* @phpstan-param numeric-string $multiplier
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function multiply(string $amount, string $multiplier): string;
/**
* Divide amount with divisor.
*
* @phpstan-param numeric-string $amount
* @phpstan-param numeric-string $divisor
*
* @phpstan-return numeric-string
*
* @throws InvalidArgumentException when $divisor is zero.
*
* @phpstan-pure
*/
public static function divide(string $amount, string $divisor): string;
/**
* Round number to following integer.
*
* @phpstan-param numeric-string $number
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function ceil(string $number): string;
/**
* Round number to preceding integer.
*
* @phpstan-param numeric-string $number
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function floor(string $number): string;
/**
* Returns the absolute value of the number.
*
* @phpstan-param numeric-string $number
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function absolute(string $number): string;
/**
* Round number, use rounding mode for tie-breaker.
*
* @phpstan-param numeric-string $number
* @phpstan-param Money::ROUND_* $roundingMode
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function round(string $number, int $roundingMode): string;
/**
* Share amount among ratio / total portions.
*
* @phpstan-param numeric-string $amount
* @phpstan-param numeric-string $ratio
* @phpstan-param numeric-string $total
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function share(string $amount, string $ratio, string $total): string;
/**
* Get the modulus of an amount.
*
* @phpstan-param numeric-string $amount
* @phpstan-param numeric-string $divisor
*
* @phpstan-return numeric-string
*
* @throws InvalidArgumentException when $divisor is zero.
*
* @phpstan-pure
*/
public static function mod(string $amount, string $divisor): string;
}

View File

@@ -0,0 +1,227 @@
<?php
declare(strict_types=1);
namespace Money\Calculator;
use InvalidArgumentException as CoreInvalidArgumentException;
use Money\Calculator;
use Money\Exception\InvalidArgumentException;
use Money\Money;
use Money\Number;
use function bcadd;
use function bccomp;
use function bcdiv;
use function bcmod;
use function bcmul;
use function bcsub;
use function ltrim;
use function str_contains;
final class BcMathCalculator implements Calculator
{
private const SCALE = 14;
/** @phpstan-pure */
public static function compare(string $a, string $b): int
{
return bccomp($a, $b, self::SCALE);
}
/** @phpstan-pure */
public static function add(string $amount, string $addend): string
{
$scale = str_contains($amount . $addend, '.') ? self::SCALE : 0;
return bcadd($amount, $addend, $scale);
}
/** @phpstan-pure */
public static function subtract(string $amount, string $subtrahend): string
{
$scale = str_contains($amount . $subtrahend, '.') ? self::SCALE : 0;
return bcsub($amount, $subtrahend, $scale);
}
/** @phpstan-pure */
public static function multiply(string $amount, string $multiplier): string
{
return bcmul($amount, $multiplier, self::SCALE);
}
/**
* @phpstan-pure
*/
public static function divide(string $amount, string $divisor): string
{
if (bccomp($divisor, '0', self::SCALE) === 0) {
throw InvalidArgumentException::divisionByZero();
}
return bcdiv($amount, $divisor, self::SCALE);
}
/** @phpstan-pure */
public static function ceil(string $number): string
{
$number = Number::fromString($number);
if ($number->isInteger()) {
return $number->__toString();
}
if ($number->isNegative()) {
return bcadd($number->__toString(), '0', 0);
}
return bcadd($number->__toString(), '1', 0);
}
/** @phpstan-pure */
public static function floor(string $number): string
{
$number = Number::fromString($number);
if ($number->isInteger()) {
return $number->__toString();
}
if ($number->isNegative()) {
return bcadd($number->__toString(), '-1', 0);
}
return bcadd($number->__toString(), '0', 0);
}
/**
* @phpstan-pure
*/
public static function absolute(string $number): string
{
return ltrim($number, '-');
}
/**
* @phpstan-param Money::ROUND_* $roundingMode
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function round(string $number, int $roundingMode): string
{
$number = Number::fromString($number);
if ($number->isInteger()) {
return $number->__toString();
}
if ($number->isHalf() === false) {
return self::roundDigit($number);
}
if ($roundingMode === Money::ROUND_HALF_UP) {
return bcadd(
$number->__toString(),
$number->getIntegerRoundingMultiplier(),
0
);
}
if ($roundingMode === Money::ROUND_HALF_DOWN) {
return bcadd($number->__toString(), '0', 0);
}
if ($roundingMode === Money::ROUND_HALF_EVEN) {
if ($number->isCurrentEven()) {
return bcadd($number->__toString(), '0', 0);
}
return bcadd(
$number->__toString(),
$number->getIntegerRoundingMultiplier(),
0
);
}
if ($roundingMode === Money::ROUND_HALF_ODD) {
if ($number->isCurrentEven()) {
return bcadd(
$number->__toString(),
$number->getIntegerRoundingMultiplier(),
0
);
}
return bcadd($number->__toString(), '0', 0);
}
if ($roundingMode === Money::ROUND_HALF_POSITIVE_INFINITY) {
if ($number->isNegative()) {
return bcadd($number->__toString(), '0', 0);
}
return bcadd(
$number->__toString(),
$number->getIntegerRoundingMultiplier(),
0
);
}
if ($roundingMode === Money::ROUND_HALF_NEGATIVE_INFINITY) {
if ($number->isNegative()) {
return bcadd(
$number->__toString(),
$number->getIntegerRoundingMultiplier(),
0
);
}
return bcadd(
$number->__toString(),
'0',
0
);
}
throw new CoreInvalidArgumentException('Unknown rounding mode');
}
/**
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
private static function roundDigit(Number $number): string
{
if ($number->isCloserToNext()) {
return bcadd(
$number->__toString(),
$number->getIntegerRoundingMultiplier(),
0
);
}
return bcadd($number->__toString(), '0', 0);
}
/** @phpstan-pure */
public static function share(string $amount, string $ratio, string $total): string
{
return self::floor(bcdiv(bcmul($amount, $ratio, self::SCALE), $total, self::SCALE));
}
/**
* @phpstan-pure
*/
public static function mod(string $amount, string $divisor): string
{
if (bccomp($divisor, '0') === 0) {
throw InvalidArgumentException::moduloByZero();
}
return bcmod($amount, $divisor);
}
}

View File

@@ -0,0 +1,334 @@
<?php
declare(strict_types=1);
namespace Money\Calculator;
use InvalidArgumentException as CoreInvalidArgumentException;
use Money\Calculator;
use Money\Exception\InvalidArgumentException;
use Money\Money;
use Money\Number;
use function gmp_add;
use function gmp_cmp;
use function gmp_div_q;
use function gmp_div_qr;
use function gmp_init;
use function gmp_mod;
use function gmp_mul;
use function gmp_neg;
use function gmp_strval;
use function gmp_sub;
use function ltrim;
use function str_pad;
use function str_replace;
use function strlen;
use function substr;
use const GMP_ROUND_MINUSINF;
use const STR_PAD_LEFT;
/**
* @phpstan-immutable
*
* Important: the {@see GmpCalculator} is not optimized for decimal operations, as GMP
* is designed to operate on large integers. Consider using this only if your
* system does not have `ext-bcmath` installed.
*/
final class GmpCalculator implements Calculator
{
private const SCALE = 14;
/** @phpstan-pure */
public static function compare(string $a, string $b): int
{
$aNum = Number::fromString($a);
$bNum = Number::fromString($b);
if ($aNum->isDecimal() || $bNum->isDecimal()) {
$integersCompared = gmp_cmp($aNum->getIntegerPart(), $bNum->getIntegerPart());
if ($integersCompared !== 0) {
return $integersCompared;
}
$aNumFractional = $aNum->getFractionalPart() === '' ? '0' : $aNum->getFractionalPart();
$bNumFractional = $bNum->getFractionalPart() === '' ? '0' : $bNum->getFractionalPart();
return gmp_cmp($aNumFractional, $bNumFractional);
}
return gmp_cmp($a, $b);
}
/** @phpstan-pure */
public static function add(string $amount, string $addend): string
{
return gmp_strval(gmp_add($amount, $addend));
}
/** @phpstan-pure */
public static function subtract(string $amount, string $subtrahend): string
{
return gmp_strval(gmp_sub($amount, $subtrahend));
}
/** @phpstan-pure */
public static function multiply(string $amount, string $multiplier): string
{
$multiplier = Number::fromString($multiplier);
if ($multiplier->isDecimal()) {
$decimalPlaces = strlen($multiplier->getFractionalPart());
$multiplierBase = $multiplier->getIntegerPart();
$negativeZero = $multiplierBase === '-0';
if ($negativeZero) {
$multiplierBase = '-';
}
if ($multiplierBase) {
$multiplierBase .= $multiplier->getFractionalPart();
} else {
$multiplierBase = ltrim($multiplier->getFractionalPart(), '0');
}
$resultBase = gmp_strval(gmp_mul(gmp_init($amount), gmp_init($multiplierBase)));
if ($resultBase === '0') {
return '0';
}
$result = substr($resultBase, $decimalPlaces * -1);
$resultLength = strlen($result);
if ($decimalPlaces > $resultLength) {
return '0.' . str_pad('', $decimalPlaces - $resultLength, '0') . $result;
}
$finalResult = substr($resultBase, 0, $decimalPlaces * -1) . '.' . $result;
if ($negativeZero) {
// @phpstan-ignore possiblyImpure.functionCall (see https://github.com/phpstan/phpstan/issues/11884)
$finalResult = str_replace('-.', '-0.', $finalResult);
}
return $finalResult;
}
return gmp_strval(gmp_mul(gmp_init($amount), gmp_init((string) $multiplier)));
}
/** @phpstan-pure */
public static function divide(string $amount, string $divisor): string
{
if (self::compare($divisor, '0') === 0) {
throw InvalidArgumentException::divisionByZero();
}
$divisor = Number::fromString($divisor);
if ($divisor->isDecimal()) {
$decimalPlaces = strlen($divisor->getFractionalPart());
$divisorBase = $divisor->getIntegerPart();
$negativeZero = $divisorBase === '-0';
if ($negativeZero) {
$divisorBase = '-';
}
if ($divisor->getIntegerPart()) {
$divisor = new Number($divisorBase . $divisor->getFractionalPart());
} else {
$divisor = new Number(ltrim($divisor->getFractionalPart(), '0'));
}
$amount = gmp_strval(gmp_mul(gmp_init($amount), gmp_init('1' . str_pad('', $decimalPlaces, '0'))));
}
[$integer, $remainder] = gmp_div_qr(gmp_init($amount), gmp_init((string) $divisor));
if (gmp_cmp($remainder, '0') === 0) {
return gmp_strval($integer);
}
$divisionOfRemainder = gmp_strval(
gmp_div_q(
gmp_mul($remainder, gmp_init('1' . str_pad('', self::SCALE, '0'))),
gmp_init((string) $divisor),
GMP_ROUND_MINUSINF
)
);
if ($divisionOfRemainder[0] === '-') {
$divisionOfRemainder = substr($divisionOfRemainder, 1);
}
return gmp_strval($integer) . '.' . str_pad($divisionOfRemainder, self::SCALE, '0', STR_PAD_LEFT);
}
/** @phpstan-pure */
public static function ceil(string $number): string
{
$number = Number::fromString($number);
if ($number->isInteger()) {
return $number->__toString();
}
if ($number->isNegative()) {
return self::add($number->getIntegerPart(), '0');
}
return self::add($number->getIntegerPart(), '1');
}
/** @phpstan-pure */
public static function floor(string $number): string
{
$number = Number::fromString($number);
if ($number->isInteger()) {
return $number->__toString();
}
if ($number->isNegative()) {
return self::add($number->getIntegerPart(), '-1');
}
return self::add($number->getIntegerPart(), '0');
}
/**
* @phpstan-pure
*/
public static function absolute(string $number): string
{
return ltrim($number, '-');
}
/**
* @phpstan-param Money::ROUND_* $roundingMode
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public static function round(string $number, int $roundingMode): string
{
$number = Number::fromString($number);
if ($number->isInteger()) {
return $number->__toString();
}
if ($number->isHalf() === false) {
return self::roundDigit($number);
}
if ($roundingMode === Money::ROUND_HALF_UP) {
return self::add(
$number->getIntegerPart(),
$number->getIntegerRoundingMultiplier()
);
}
if ($roundingMode === Money::ROUND_HALF_DOWN) {
return self::add($number->getIntegerPart(), '0');
}
if ($roundingMode === Money::ROUND_HALF_EVEN) {
if ($number->isCurrentEven()) {
return self::add($number->getIntegerPart(), '0');
}
return self::add(
$number->getIntegerPart(),
$number->getIntegerRoundingMultiplier()
);
}
if ($roundingMode === Money::ROUND_HALF_ODD) {
if ($number->isCurrentEven()) {
return self::add(
$number->getIntegerPart(),
$number->getIntegerRoundingMultiplier()
);
}
return self::add($number->getIntegerPart(), '0');
}
if ($roundingMode === Money::ROUND_HALF_POSITIVE_INFINITY) {
if ($number->isNegative()) {
return self::add(
$number->getIntegerPart(),
'0'
);
}
return self::add(
$number->getIntegerPart(),
$number->getIntegerRoundingMultiplier()
);
}
if ($roundingMode === Money::ROUND_HALF_NEGATIVE_INFINITY) {
if ($number->isNegative()) {
return self::add(
$number->getIntegerPart(),
$number->getIntegerRoundingMultiplier()
);
}
return self::add(
$number->getIntegerPart(),
'0'
);
}
throw new CoreInvalidArgumentException('Unknown rounding mode');
}
/**
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
private static function roundDigit(Number $number): string
{
if ($number->isCloserToNext()) {
return self::add(
$number->getIntegerPart(),
$number->getIntegerRoundingMultiplier()
);
}
return self::add($number->getIntegerPart(), '0');
}
/** @phpstan-pure */
public static function share(string $amount, string $ratio, string $total): string
{
return self::floor(self::divide(self::multiply($amount, $ratio), $total));
}
/** @phpstan-pure */
public static function mod(string $amount, string $divisor): string
{
if (self::compare($divisor, '0') === 0) {
throw InvalidArgumentException::moduloByZero();
}
// gmp_mod() only calculates non-negative integers, so we use absolutes
$remainder = gmp_mod(self::absolute($amount), self::absolute($divisor));
// If the amount was negative, we negate the result of the modulus operation
$amount = Number::fromString($amount);
if ($amount->isNegative()) {
$remainder = gmp_neg($remainder);
}
return gmp_strval($remainder);
}
}

78
vendor/moneyphp/money/src/Converter.php vendored Normal file
View File

@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace Money;
use InvalidArgumentException;
use function sprintf;
/**
* Provides a way to convert Money to Money in another Currency using an exchange rate.
*/
final class Converter
{
public function __construct(private readonly Currencies $currencies, private readonly Exchange $exchange)
{
}
/**
* @param Money::ROUND_* $roundingMode
*/
public function convert(Money $money, Currency $counterCurrency, int $roundingMode = Money::ROUND_HALF_UP): Money
{
return $this->convertAgainstCurrencyPair(
$money,
$this->exchange->quote(
$money->getCurrency(),
$counterCurrency
),
$roundingMode
);
}
/**
* @param Money::ROUND_* $roundingMode
*
* @return array{0: Money, 1: CurrencyPair}
*/
public function convertAndReturnWithCurrencyPair(Money $money, Currency $counterCurrency, int $roundingMode = Money::ROUND_HALF_UP): array
{
$pair = $this->exchange->quote(
$money->getCurrency(),
$counterCurrency
);
return [$this->convertAgainstCurrencyPair($money, $pair, $roundingMode), $pair];
}
/**
* @param Money::ROUND_* $roundingMode
*/
public function convertAgainstCurrencyPair(Money $money, CurrencyPair $currencyPair, int $roundingMode = Money::ROUND_HALF_UP): Money
{
if (! $money->getCurrency()->equals($currencyPair->getBaseCurrency())) {
throw new InvalidArgumentException(
sprintf(
'Expecting to convert against base currency %s, but got %s instead',
$money->getCurrency()->getCode(),
$currencyPair->getBaseCurrency()->getCode()
)
);
}
$ratio = $currencyPair->getConversionRatio();
$baseCurrencySubunit = $this->currencies->subunitFor($currencyPair->getBaseCurrency());
$counterCurrencySubunit = $this->currencies->subunitFor($currencyPair->getCounterCurrency());
$subunitDifference = $baseCurrencySubunit - $counterCurrencySubunit;
$ratio = Number::fromString($ratio)
->base10($subunitDifference)
->__toString();
$counterValue = $money->multiply($ratio, $roundingMode);
return new Money($counterValue->getAmount(), $currencyPair->getCounterCurrency());
}
}

View File

@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Money;
use IteratorAggregate;
use Money\Exception\UnknownCurrencyException;
use Traversable;
/**
* Implement this to provide a list of currencies.
*
* @extends IteratorAggregate<int|string, Currency>
*/
interface Currencies extends IteratorAggregate
{
/**
* Checks whether a currency is available in the current context.
*/
public function contains(Currency $currency): bool;
/**
* Returns the subunit for a currency.
*
* @throws UnknownCurrencyException If currency is not available in the current context.
*/
public function subunitFor(Currency $currency): int;
/**
* @return Traversable<int|string, Currency>
*/
public function getIterator(): Traversable;
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Money\Currencies;
use AppendIterator;
use IteratorIterator;
use Money\Currencies;
use Money\Currency;
use Money\Exception\UnknownCurrencyException;
use Traversable;
/**
* Aggregates several currency repositories.
*/
final class AggregateCurrencies implements Currencies
{
/**
* @param Currencies[] $currencies
*/
public function __construct(private readonly array $currencies)
{
}
public function contains(Currency $currency): bool
{
foreach ($this->currencies as $currencies) {
if ($currencies->contains($currency)) {
return true;
}
}
return false;
}
public function subunitFor(Currency $currency): int
{
foreach ($this->currencies as $currencies) {
if ($currencies->contains($currency)) {
return $currencies->subunitFor($currency);
}
}
throw new UnknownCurrencyException('Cannot find currency ' . $currency->getCode());
}
/** {@inheritDoc} */
public function getIterator(): Traversable
{
$iterator = new AppendIterator();
foreach ($this->currencies as $currencies) {
$iterator->append(new IteratorIterator($currencies->getIterator()));
}
return $iterator;
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Money\Currencies;
use ArrayIterator;
use Money\Currencies;
use Money\Currency;
use Money\Exception\UnknownCurrencyException;
use Traversable;
final class BitcoinCurrencies implements Currencies
{
public const CODE = 'XBT';
public const SYMBOL = "\xC9\x83";
public function contains(Currency $currency): bool
{
return $currency->getCode() === self::CODE;
}
public function subunitFor(Currency $currency): int
{
if ($currency->getCode() !== self::CODE) {
throw new UnknownCurrencyException($currency->getCode() . ' is not bitcoin and is not supported by this currency repository');
}
return 8;
}
/** {@inheritDoc} */
public function getIterator(): Traversable
{
return new ArrayIterator([new Currency(self::CODE)]);
}
}

View File

@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);
namespace Money\Currencies;
use ArrayIterator;
use Cache\TagInterop\TaggableCacheItemInterface;
use CallbackFilterIterator;
use Money\Currencies;
use Money\Currency;
use Psr\Cache\CacheItemPoolInterface;
use Traversable;
use function iterator_to_array;
/**
* Cache the result of currency checking.
*/
final class CachedCurrencies implements Currencies
{
public function __construct(private readonly Currencies $currencies, private readonly CacheItemPoolInterface $pool)
{
}
public function contains(Currency $currency): bool
{
$item = $this->pool->getItem('currency|availability|' . $currency->getCode());
if ($item->isHit() === false) {
$item->set($this->currencies->contains($currency));
if ($item instanceof TaggableCacheItemInterface) {
$item->setTags(['currency.availability']);
}
$this->pool->save($item);
}
return (bool) $item->get();
}
public function subunitFor(Currency $currency): int
{
$item = $this->pool->getItem('currency|subunit|' . $currency->getCode());
if ($item->isHit() === false) {
$item->set($this->currencies->subunitFor($currency));
if ($item instanceof TaggableCacheItemInterface) {
$item->setTags(['currency.subunit']);
}
$this->pool->save($item);
}
return (int) $item->get();
}
/** {@inheritDoc} */
public function getIterator(): Traversable
{
return new CallbackFilterIterator(
new ArrayIterator(iterator_to_array($this->currencies->getIterator())),
function (Currency $currency): bool {
$item = $this->pool->getItem('currency|availability|' . $currency->getCode());
$item->set(true);
if ($item instanceof TaggableCacheItemInterface) {
$item->setTags(['currency.availability']);
}
$this->pool->save($item);
return true;
}
);
}
}

View File

@@ -0,0 +1,95 @@
<?php
declare(strict_types=1);
namespace Money\Currencies;
use ArrayIterator;
use Money\Currencies;
use Money\Currency;
use Money\Exception\UnknownCurrencyException;
use RuntimeException;
use Traversable;
use function array_keys;
use function array_map;
use function is_file;
/**
* List of supported Crypto Currencies codes and names using Binance as resource.
*/
final class CryptoCurrencies implements Currencies
{
/**
* Map of known currencies indexed by code.
*
* @phpstan-var non-empty-array<non-empty-string, array{
* symbol: non-empty-string,
* minorUnit: non-negative-int
* }>|null
*/
private static array|null $currencies = null;
public function contains(Currency $currency): bool
{
return isset($this->getCurrencies()[$currency->getCode()]);
}
public function subunitFor(Currency $currency): int
{
if (! $this->contains($currency)) {
throw new UnknownCurrencyException('Cannot find ISO currency ' . $currency->getCode());
}
return $this->getCurrencies()[$currency->getCode()]['minorUnit'];
}
/**
* @phpstan-return Traversable<int, Currency>
*/
public function getIterator(): Traversable
{
return new ArrayIterator(
array_map(
static function ($code) {
return new Currency($code);
},
array_keys($this->getCurrencies())
)
);
}
/**
* Returns a map of known currencies indexed by code.
*
* @phpstan-return non-empty-array<non-empty-string, array{
* symbol: non-empty-string,
* minorUnit: non-negative-int
* }>
*/
private function getCurrencies(): array
{
if (self::$currencies === null) {
self::$currencies = $this->loadCurrencies();
}
return self::$currencies;
}
/**
* @phpstan-return non-empty-array<non-empty-string, array{
* symbol: non-empty-string,
* minorUnit: non-negative-int
* }>
*/
private function loadCurrencies(): array
{
$file = __DIR__ . '/../../resources/binance.php';
if (is_file($file)) {
return require $file;
}
throw new RuntimeException('Failed to load currency ISO codes.');
}
}

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace Money\Currencies;
use ArrayIterator;
use Money\Currencies;
use Money\Currency;
use Money\Exception\UnknownCurrencyException;
use Traversable;
use function array_keys;
use function array_map;
/**
* A list of custom currencies.
*/
final class CurrencyList implements Currencies
{
/**
* Map of currencies and their sub-units indexed by code.
*
* @phpstan-var array<non-empty-string, int>
*/
private array $currencies;
/** @phpstan-param array<non-empty-string, non-negative-int> $currencies */
public function __construct(array $currencies)
{
$this->currencies = $currencies;
}
public function contains(Currency $currency): bool
{
return isset($this->currencies[$currency->getCode()]);
}
public function subunitFor(Currency $currency): int
{
if (! $this->contains($currency)) {
throw new UnknownCurrencyException('Cannot find currency ' . $currency->getCode());
}
return $this->currencies[$currency->getCode()];
}
/** {@inheritDoc} */
public function getIterator(): Traversable
{
return new ArrayIterator(
array_map(
static function ($code) {
return new Currency($code);
},
array_keys($this->currencies)
)
);
}
}

View File

@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);
namespace Money\Currencies;
use ArrayIterator;
use Money\Currencies;
use Money\Currency;
use Money\Exception\UnknownCurrencyException;
use RuntimeException;
use Traversable;
use function array_keys;
use function array_map;
use function is_file;
/**
* List of supported ISO 4217 currency codes and names.
*/
final class ISOCurrencies implements Currencies
{
/**
* Map of known currencies indexed by code.
*
* @phpstan-var non-empty-array<non-empty-string, array{
* alphabeticCode: non-empty-string,
* currency: non-empty-string,
* minorUnit: non-negative-int,
* numericCode: positive-int
* }>|null
*/
private static array|null $currencies = null;
public function contains(Currency $currency): bool
{
return isset($this->getCurrencies()[$currency->getCode()]);
}
public function subunitFor(Currency $currency): int
{
if (! $this->contains($currency)) {
throw new UnknownCurrencyException('Cannot find ISO currency ' . $currency->getCode());
}
return $this->getCurrencies()[$currency->getCode()]['minorUnit'];
}
/**
* Returns the numeric code for a currency.
*
* @throws UnknownCurrencyException If currency is not available in the current context.
*/
public function numericCodeFor(Currency $currency): int
{
if (! $this->contains($currency)) {
throw new UnknownCurrencyException('Cannot find ISO currency ' . $currency->getCode());
}
return $this->getCurrencies()[$currency->getCode()]['numericCode'];
}
/**
* @phpstan-return Traversable<int, Currency>
*/
public function getIterator(): Traversable
{
return new ArrayIterator(
array_map(
static function ($code) {
return new Currency($code);
},
array_keys($this->getCurrencies())
)
);
}
/**
* Returns a map of known currencies indexed by code.
*
* @phpstan-return non-empty-array<non-empty-string, array{
* alphabeticCode: non-empty-string,
* currency: non-empty-string,
* minorUnit: non-negative-int,
* numericCode: positive-int
* }>
*/
private function getCurrencies(): array
{
if (self::$currencies === null) {
self::$currencies = $this->loadCurrencies();
}
return self::$currencies;
}
/**
* @phpstan-return non-empty-array<non-empty-string, array{
* alphabeticCode: non-empty-string,
* currency: non-empty-string,
* minorUnit: non-negative-int,
* numericCode: positive-int
* }>
*/
private function loadCurrencies(): array
{
$file = __DIR__ . '/../../resources/currency.php';
if (is_file($file)) {
return require $file;
}
throw new RuntimeException('Failed to load currency ISO codes.');
}
}

64
vendor/moneyphp/money/src/Currency.php vendored Normal file
View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace Money;
use JsonSerializable;
use function strtoupper;
/**
* Currency Value Object.
*
* Holds Currency specific data.
*
* @phpstan-immutable
*/
final class Currency implements JsonSerializable
{
/**
* Currency code.
*
* @phpstan-var non-empty-string
*/
private string $code;
/**
* @phpstan-param non-empty-string $code
*
* @phpstan-pure
*/
public function __construct(string $code)
{
$this->code = strtoupper($code);
}
/**
* Returns the currency code.
*
* @phpstan-return non-empty-string
*/
public function getCode(): string
{
return $this->code;
}
/**
* Checks whether this currency is the same as an other.
*/
public function equals(Currency $other): bool
{
return $this->code === $other->code;
}
public function __toString(): string
{
return $this->code;
}
public function jsonSerialize(): string
{
return $this->code;
}
}

View File

@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);
namespace Money;
use InvalidArgumentException;
use JsonSerializable;
use function assert;
use function is_numeric;
use function preg_match;
use function sprintf;
/**
* Currency Pair holding a base, a counter currency and a conversion ratio.
*
* @see http://en.wikipedia.org/wiki/Currency_pair
*/
final class CurrencyPair implements JsonSerializable
{
/**
* @phpstan-param numeric-string $conversionRatio
*/
public function __construct(
private readonly Currency $baseCurrency,
private readonly Currency $counterCurrency,
private readonly string $conversionRatio
) {
}
/**
* Creates a new Currency Pair based on "EUR/USD 1.2500" form representation.
*
* @param string $iso String representation of the form "EUR/USD 1.2500"
*
* @throws InvalidArgumentException Format of $iso is invalid.
*/
public static function createFromIso(string $iso): CurrencyPair
{
$currency = '([A-Z]{2,3})';
$ratio = '([0-9]*\.?[0-9]+)'; // @see http://www.regular-expressions.info/floatingpoint.html
$pattern = '#' . $currency . '/' . $currency . ' ' . $ratio . '#';
$matches = [];
if (! preg_match($pattern, $iso, $matches)) {
throw new InvalidArgumentException(sprintf('Cannot create currency pair from ISO string "%s", format of string is invalid', $iso));
}
assert(is_numeric($matches[3]));
return new self(new Currency($matches[1]), new Currency($matches[2]), $matches[3]);
}
/**
* Returns the counter currency.
*/
public function getCounterCurrency(): Currency
{
return $this->counterCurrency;
}
/**
* Returns the base currency.
*/
public function getBaseCurrency(): Currency
{
return $this->baseCurrency;
}
/**
* Returns the conversion ratio.
*
* @phpstan-return numeric-string
*/
public function getConversionRatio(): string
{
return $this->conversionRatio;
}
/**
* Checks if another CurrencyPair has the same parameters as this.
*/
public function equals(CurrencyPair $other): bool
{
return $this->baseCurrency->equals($other->baseCurrency)
&& $this->counterCurrency->equals($other->counterCurrency)
&& $this->conversionRatio === $other->conversionRatio;
}
/**
* {@inheritDoc}
*
* @phpstan-return array{baseCurrency: Currency, counterCurrency: Currency, ratio: numeric-string}
*/
public function jsonSerialize(): array
{
return [
'baseCurrency' => $this->baseCurrency,
'counterCurrency' => $this->counterCurrency,
'ratio' => $this->conversionRatio,
];
}
}

12
vendor/moneyphp/money/src/Exception.php vendored Normal file
View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Money;
/**
* Common interface for all exceptions thrown by this library.
*/
interface Exception
{
}

View File

@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
final class CurrencyMismatchException extends InvalidArgumentException
{
}

View File

@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
final class DivisionByZeroException extends InvalidArgumentException
{
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
use Money\Exception;
use RuntimeException;
/**
* Thrown when a Money object cannot be formatted into a string.
*/
final class FormatterException extends RuntimeException implements Exception
{
}

View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
use InvalidArgumentException as CoreInvalidArgumentException;
use Money\Exception;
/**
* @internal
*/
class InvalidArgumentException extends CoreInvalidArgumentException implements Exception
{
/** @phpstan-pure */
public static function divisionByZero(): DivisionByZeroException
{
return new DivisionByZeroException('Cannot compute division with a zero divisor');
}
/** @phpstan-pure */
public static function moduloByZero(): ModuloByZeroException
{
return new ModuloByZeroException('Cannot compute modulo with a zero divisor');
}
/** @phpstan-pure */
public static function currencyMismatch(): CurrencyMismatchException
{
return new CurrencyMismatchException('Currencies must be identical');
}
}

View File

@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
final class ModuloByZeroException extends InvalidArgumentException
{
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
use Money\Exception;
use RuntimeException;
/**
* Thrown when a string cannot be parsed to a Money object.
*/
final class ParserException extends RuntimeException implements Exception
{
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
use DomainException;
use Money\Exception;
/**
* Thrown when trying to get ISO currency that does not exists.
*/
final class UnknownCurrencyException extends DomainException implements Exception
{
}

View File

@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Money\Exception;
use InvalidArgumentException;
use Money\Currency;
use Money\Exception;
use function sprintf;
/**
* Thrown when there is no currency pair (rate) available for the given currencies.
*/
final class UnresolvableCurrencyPairException extends InvalidArgumentException implements Exception
{
/**
* Creates an exception from Currency objects.
*/
public static function createFromCurrencies(Currency $baseCurrency, Currency $counterCurrency): UnresolvableCurrencyPairException
{
$message = sprintf(
'Cannot resolve a currency pair for currencies: %s/%s',
$baseCurrency->getCode(),
$counterCurrency->getCode()
);
return new self($message);
}
}

20
vendor/moneyphp/money/src/Exchange.php vendored Normal file
View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Money;
use Money\Exception\UnresolvableCurrencyPairException;
/**
* Provides a way to get exchange rate from a third-party source and return a currency pair.
*/
interface Exchange
{
/**
* Returns a currency pair for the passed currencies with the rate coming from a third-party source.
*
* @throws UnresolvableCurrencyPairException When there is no currency pair (rate) available for the given currencies.
*/
public function quote(Currency $baseCurrency, Currency $counterCurrency): CurrencyPair;
}

View File

@@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace Money\Exchange;
use Exchanger\Contract\ExchangeRateProvider;
use Exchanger\CurrencyPair as ExchangerCurrencyPair;
use Exchanger\Exception\Exception as ExchangerException;
use Exchanger\ExchangeRateQuery;
use Money\Currency;
use Money\CurrencyPair;
use Money\Exception\UnresolvableCurrencyPairException;
use Money\Exchange;
use function sprintf;
/**
* Provides a way to get exchange rate from a third-party source and return a currency pair.
*/
final class ExchangerExchange implements Exchange
{
public function __construct(private readonly ExchangeRateProvider $exchanger)
{
}
public function quote(Currency $baseCurrency, Currency $counterCurrency): CurrencyPair
{
try {
$query = new ExchangeRateQuery(
new ExchangerCurrencyPair($baseCurrency->getCode(), $counterCurrency->getCode())
);
$rate = $this->exchanger->getExchangeRate($query);
} catch (ExchangerException) {
throw UnresolvableCurrencyPairException::createFromCurrencies($baseCurrency, $counterCurrency);
}
$rateValue = sprintf('%.14F', $rate->getValue());
return new CurrencyPair($baseCurrency, $counterCurrency, $rateValue);
}
}

View File

@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Money\Exchange;
use Money\Currency;
use Money\CurrencyPair;
use Money\Exception\UnresolvableCurrencyPairException;
use Money\Exchange;
/**
* Provides a way to get exchange rate from a static list (array).
*/
final class FixedExchange implements Exchange
{
/** @phpstan-param array<non-empty-string, array<non-empty-string, numeric-string>> $list */
public function __construct(private readonly array $list)
{
}
public function quote(Currency $baseCurrency, Currency $counterCurrency): CurrencyPair
{
if (isset($this->list[$baseCurrency->getCode()][$counterCurrency->getCode()])) {
return new CurrencyPair(
$baseCurrency,
$counterCurrency,
$this->list[$baseCurrency->getCode()][$counterCurrency->getCode()]
);
}
throw UnresolvableCurrencyPairException::createFromCurrencies($baseCurrency, $counterCurrency);
}
}

View File

@@ -0,0 +1,124 @@
<?php
declare(strict_types=1);
namespace Money\Exchange;
use Money\Currencies;
use Money\Currency;
use Money\CurrencyPair;
use Money\Exception\UnresolvableCurrencyPairException;
use Money\Exchange;
use Money\Money;
use SplQueue;
use function array_reduce;
use function array_reverse;
/**
* Provides a way to get an exchange rate through a minimal set of intermediate conversions.
*/
final class IndirectExchange implements Exchange
{
public function __construct(private readonly Exchange $exchange, private readonly Currencies $currencies)
{
}
public function quote(Currency $baseCurrency, Currency $counterCurrency): CurrencyPair
{
try {
return $this->exchange->quote($baseCurrency, $counterCurrency);
} catch (UnresolvableCurrencyPairException) {
$rate = array_reduce(
$this->getConversions($baseCurrency, $counterCurrency),
/**
* @phpstan-param numeric-string $carry
*
* @phpstan-return numeric-string
*/
static function (string $carry, CurrencyPair $pair) {
$calculator = Money::getCalculator();
return $calculator::multiply($carry, $pair->getConversionRatio());
},
'1.0'
);
return new CurrencyPair($baseCurrency, $counterCurrency, $rate);
}
}
/**
* @return CurrencyPair[]
*
* @throws UnresolvableCurrencyPairException
*/
private function getConversions(Currency $baseCurrency, Currency $counterCurrency): array
{
$startNode = new IndirectExchangeQueuedItem($baseCurrency);
$startNode->discovered = true;
/** @phpstan-var array<non-empty-string, IndirectExchangeQueuedItem> $nodes */
$nodes = [$baseCurrency->getCode() => $startNode];
/** @psam-var SplQueue<IndirectExchangeQueuedItem> $frontier */
$frontier = new SplQueue();
$frontier->enqueue($startNode);
while ($frontier->count()) {
/** @phpstan-var IndirectExchangeQueuedItem $currentNode */
$currentNode = $frontier->dequeue();
$currentCurrency = $currentNode->currency;
if ($currentCurrency->equals($counterCurrency)) {
return $this->reconstructConversionChain($nodes, $currentNode);
}
foreach ($this->currencies as $candidateCurrency) {
if (! isset($nodes[$candidateCurrency->getCode()])) {
$nodes[$candidateCurrency->getCode()] = new IndirectExchangeQueuedItem($candidateCurrency);
}
$node = $nodes[$candidateCurrency->getCode()];
if ($node->discovered) {
continue;
}
try {
// Check if the candidate is a neighbor. This will throw an exception if it isn't.
$this->exchange->quote($currentCurrency, $candidateCurrency);
$node->discovered = true;
$node->parent = $currentNode;
$frontier->enqueue($node);
} catch (UnresolvableCurrencyPairException) {
// Not a neighbor. Move on.
}
}
}
throw UnresolvableCurrencyPairException::createFromCurrencies($baseCurrency, $counterCurrency);
}
/**
* @phpstan-param array<non-empty-string, IndirectExchangeQueuedItem> $currencies
*
* @return CurrencyPair[]
* @phpstan-return list<CurrencyPair>
*/
private function reconstructConversionChain(array $currencies, IndirectExchangeQueuedItem $goalNode): array
{
$current = $goalNode;
$conversions = [];
while ($current->parent) {
$previous = $currencies[$current->parent->currency->getCode()];
$conversions[] = $this->exchange->quote($previous->currency, $current->currency);
$current = $previous;
}
return array_reverse($conversions);
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Money\Exchange;
use Money\Currency;
/** @internal for sole consumption by {@see IndirectExchange} */
final class IndirectExchangeQueuedItem
{
public bool $discovered = false;
public self|null $parent = null;
public function __construct(public Currency $currency)
{
}
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace Money\Exchange;
use Money\Currency;
use Money\CurrencyPair;
use Money\Exception\UnresolvableCurrencyPairException;
use Money\Exchange;
use Money\Money;
/**
* Tries the reverse of the currency pair if one is not available.
*
* Note: adding nested ReversedCurrenciesExchange could cause a huge performance hit.
*/
final class ReversedCurrenciesExchange implements Exchange
{
public function __construct(private readonly Exchange $exchange)
{
}
public function quote(Currency $baseCurrency, Currency $counterCurrency): CurrencyPair
{
try {
return $this->exchange->quote($baseCurrency, $counterCurrency);
} catch (UnresolvableCurrencyPairException $exception) {
$calculator = Money::getCalculator();
try {
$currencyPair = $this->exchange->quote($counterCurrency, $baseCurrency);
return new CurrencyPair(
$baseCurrency,
$counterCurrency,
$calculator::divide('1', $currencyPair->getConversionRatio())
);
} catch (UnresolvableCurrencyPairException) {
throw $exception;
}
}
}
}

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Money\Exchange;
use Exchanger\Exception\Exception as ExchangerException;
use Money\Currency;
use Money\CurrencyPair;
use Money\Exception\UnresolvableCurrencyPairException;
use Money\Exchange;
use Swap\Swap;
use function sprintf;
/**
* Provides a way to get exchange rate from a third-party source and return a currency pair.
*/
final class SwapExchange implements Exchange
{
public function __construct(private readonly Swap $swap)
{
}
public function quote(Currency $baseCurrency, Currency $counterCurrency): CurrencyPair
{
try {
$rate = $this->swap->latest($baseCurrency->getCode() . '/' . $counterCurrency->getCode());
} catch (ExchangerException) {
throw UnresolvableCurrencyPairException::createFromCurrencies($baseCurrency, $counterCurrency);
}
$rateValue = sprintf('%.14F', $rate->getValue());
return new CurrencyPair($baseCurrency, $counterCurrency, $rateValue);
}
}

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace Money\Formatter;
use Money\Exception\FormatterException;
use Money\Money;
use Money\MoneyFormatter;
/**
* Formats a Money object using other Money formatters.
*/
final class AggregateMoneyFormatter implements MoneyFormatter
{
/**
* @var MoneyFormatter[] indexed by currency code
* @phpstan-var non-empty-array<non-empty-string, MoneyFormatter> indexed by currency code
*/
private array $formatters;
/**
* @param MoneyFormatter[] $formatters indexed by currency code
* @phpstan-param non-empty-array<non-empty-string, MoneyFormatter> $formatters indexed by currency code
*/
public function __construct(array $formatters)
{
$this->formatters = $formatters;
}
public function format(Money $money): string
{
$currencyCode = $money->getCurrency()->getCode();
if (isset($this->formatters[$currencyCode])) {
return $this->formatters[$currencyCode]->format($money);
}
if (isset($this->formatters['*'])) {
return $this->formatters['*']->format($money);
}
throw new FormatterException('No formatter found for currency ' . $currencyCode);
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace Money\Formatter;
use Money\Currencies;
use Money\Currencies\BitcoinCurrencies;
use Money\Exception\FormatterException;
use Money\Money;
use Money\MoneyFormatter;
use Money\Number;
use function str_pad;
use function strlen;
use function strpos;
use function substr;
/**
* Formats Money to Bitcoin currency.
*/
final class BitcoinMoneyFormatter implements MoneyFormatter
{
public function __construct(private readonly int $fractionDigits, private readonly Currencies $currencies)
{
}
public function format(Money $money): string
{
if ($money->getCurrency()->getCode() !== BitcoinCurrencies::CODE) {
throw new FormatterException('Bitcoin Formatter can only format Bitcoin currency');
}
$valueBase = $money->getAmount();
$negative = false;
if ($valueBase[0] === '-') {
$negative = true;
$valueBase = substr($valueBase, 1);
}
$subunit = $this->currencies->subunitFor($money->getCurrency());
$valueBase = Number::roundMoneyValue($valueBase, $this->fractionDigits, $subunit);
$valueLength = strlen($valueBase);
if ($valueLength > $subunit) {
$formatted = substr($valueBase, 0, $valueLength - $subunit);
if ($subunit) {
$formatted .= '.';
$formatted .= substr($valueBase, $valueLength - $subunit);
}
} else {
$formatted = '0.' . str_pad('', $subunit - $valueLength, '0') . $valueBase;
}
if ($this->fractionDigits === 0) {
$formatted = substr($formatted, 0, (int) strpos($formatted, '.'));
} elseif ($this->fractionDigits > $subunit) {
$formatted .= str_pad('', $this->fractionDigits - $subunit, '0');
} elseif ($this->fractionDigits < $subunit) {
$lastDigit = (int) strpos($formatted, '.') + $this->fractionDigits + 1;
$formatted = substr($formatted, 0, $lastDigit);
}
$formatted = BitcoinCurrencies::SYMBOL . $formatted;
if ($negative) {
$formatted = '-' . $formatted;
}
return $formatted;
}
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Money\Formatter;
use Money\Currencies;
use Money\Money;
use Money\MoneyFormatter;
use function assert;
use function str_pad;
use function strlen;
use function substr;
/**
* Formats a Money object as a decimal string.
*/
final class DecimalMoneyFormatter implements MoneyFormatter
{
public function __construct(private readonly Currencies $currencies)
{
}
/**
* @phpstan-return numeric-string
*/
public function format(Money $money): string
{
$valueBase = $money->getAmount();
$negative = $valueBase[0] === '-';
if ($negative) {
$valueBase = substr($valueBase, 1);
}
$subunit = $this->currencies->subunitFor($money->getCurrency());
$valueLength = strlen($valueBase);
if ($valueLength > $subunit) {
$formatted = substr($valueBase, 0, $valueLength - $subunit);
$decimalDigits = substr($valueBase, $valueLength - $subunit);
if (strlen($decimalDigits) > 0) {
$formatted .= '.' . $decimalDigits;
}
} else {
$formatted = '0.' . str_pad('', $subunit - $valueLength, '0') . $valueBase;
}
if ($negative) {
$formatted = '-' . $formatted;
}
assert($formatted !== '');
return $formatted;
}
}

View File

@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace Money\Formatter;
use Money\Currencies;
use Money\Money;
use Money\MoneyFormatter;
use NumberFormatter;
use function assert;
use function is_string;
use function str_pad;
use function strlen;
use function substr;
/**
* Formats a Money object using intl extension.
*/
final class IntlLocalizedDecimalFormatter implements MoneyFormatter
{
public function __construct(private readonly NumberFormatter $formatter, private readonly Currencies $currencies)
{
}
public function format(Money $money): string
{
$valueBase = $money->getAmount();
$negative = $valueBase[0] === '-';
if ($negative) {
$valueBase = substr($valueBase, 1);
}
$subunit = $this->currencies->subunitFor($money->getCurrency());
$valueLength = strlen($valueBase);
if ($valueLength > $subunit) {
$formatted = substr($valueBase, 0, $valueLength - $subunit);
$decimalDigits = substr($valueBase, $valueLength - $subunit);
if (strlen($decimalDigits) > 0) {
$formatted .= '.' . $decimalDigits;
}
} else {
$formatted = '0.' . str_pad('', $subunit - $valueLength, '0') . $valueBase;
}
if ($negative) {
$formatted = '-' . $formatted;
}
$formatted = $this->formatter->format((float) $formatted);
assert(is_string($formatted) && $formatted !== '');
return $formatted;
}
}

View File

@@ -0,0 +1,59 @@
<?php
declare(strict_types=1);
namespace Money\Formatter;
use Money\Currencies;
use Money\Money;
use Money\MoneyFormatter;
use NumberFormatter;
use function assert;
use function str_pad;
use function strlen;
use function substr;
/**
* Formats a Money object using intl extension.
*/
final class IntlMoneyFormatter implements MoneyFormatter
{
public function __construct(private readonly NumberFormatter $formatter, private readonly Currencies $currencies)
{
}
public function format(Money $money): string
{
$valueBase = $money->getAmount();
$negative = $valueBase[0] === '-';
if ($negative) {
$valueBase = substr($valueBase, 1);
}
$subunit = $this->currencies->subunitFor($money->getCurrency());
$valueLength = strlen($valueBase);
if ($valueLength > $subunit) {
$formatted = substr($valueBase, 0, $valueLength - $subunit);
$decimalDigits = substr($valueBase, $valueLength - $subunit);
if (strlen($decimalDigits) > 0) {
$formatted .= '.' . $decimalDigits;
}
} else {
$formatted = '0.' . str_pad('', $subunit - $valueLength, '0') . $valueBase;
}
if ($negative) {
$formatted = '-' . $formatted;
}
$formatted = $this->formatter->formatCurrency((float) $formatted, $money->getCurrency()->getCode());
assert($formatted !== '');
return $formatted;
}
}

561
vendor/moneyphp/money/src/Money.php vendored Normal file
View File

@@ -0,0 +1,561 @@
<?php
declare(strict_types=1);
namespace Money;
use JsonSerializable;
use Money\Calculator\BcMathCalculator;
use Money\Exception\InvalidArgumentException;
use function array_fill;
use function array_keys;
use function array_map;
use function array_sum;
use function count;
use function filter_var;
use function floor;
use function is_int;
use function max;
use function str_pad;
use function strlen;
use function substr;
use const FILTER_VALIDATE_INT;
use const PHP_ROUND_HALF_DOWN;
use const PHP_ROUND_HALF_EVEN;
use const PHP_ROUND_HALF_ODD;
use const PHP_ROUND_HALF_UP;
/**
* Money Value Object.
*/
final class Money implements JsonSerializable
{
use MoneyFactory;
public const ROUND_HALF_UP = PHP_ROUND_HALF_UP;
public const ROUND_HALF_DOWN = PHP_ROUND_HALF_DOWN;
public const ROUND_HALF_EVEN = PHP_ROUND_HALF_EVEN;
public const ROUND_HALF_ODD = PHP_ROUND_HALF_ODD;
public const ROUND_UP = 5;
public const ROUND_DOWN = 6;
public const ROUND_HALF_POSITIVE_INFINITY = 7;
public const ROUND_HALF_NEGATIVE_INFINITY = 8;
/**
* Internal value.
* Amount, expressed in the smallest currency units (eg cents).
*
* @phpstan-var numeric-string
*/
private string $amount;
/**
* @var class-string<Calculator>
*/
private static string $calculator = BcMathCalculator::class;
/**
* @param int|string $amount Amount, expressed in the smallest units of $currency (eg cents)
* @phpstan-param int|numeric-string $amount
*
* @throws InvalidArgumentException If amount is not integer(ish).
*
* @phpstan-pure
*/
public function __construct(int|string $amount, private readonly Currency $currency)
{
if (filter_var($amount, FILTER_VALIDATE_INT) === false) {
$numberFromString = Number::fromString((string) $amount);
if (! $numberFromString->isInteger()) {
throw new InvalidArgumentException('Amount must be an integer(ish) value');
}
$this->amount = $numberFromString->getIntegerPart();
return;
}
$this->amount = (string) $amount;
}
/**
* Checks whether a Money has the same Currency as this.
*/
public function isSameCurrency(Money ...$others): bool
{
foreach ($others as $other) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $other->currency) {
return false;
}
}
return true;
}
/**
* Checks whether the value represented by this object equals to the other.
*
* @phpstan-pure
*/
public function equals(Money $other): bool
{
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $other->currency) {
return false;
}
if ($this->amount === $other->amount) {
return true;
}
// @TODO do we want Money instance to be byte-equivalent when trailing zeroes exist? Very expensive!
// Assumption: Money#equals() is called **less** than other number-based comparisons, and probably
// only within test suites. Therefore, using complex normalization here is acceptable waste of performance.
return $this->compare($other) === 0;
}
/**
* Returns an integer less than, equal to, or greater than zero
* if the value of this object is considered to be respectively
* less than, equal to, or greater than the other.
*
* @phpstan-pure
*/
public function compare(Money $other): int
{
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $other->currency) {
throw InvalidArgumentException::currencyMismatch();
}
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
return self::$calculator::compare($this->amount, $other->amount);
}
/**
* Checks whether the value represented by this object is greater than the other.
*
* @phpstan-pure
*/
public function greaterThan(Money $other): bool
{
return $this->compare($other) > 0;
}
/**
* @phpstan-pure
*/
public function greaterThanOrEqual(Money $other): bool
{
return $this->compare($other) >= 0;
}
/**
* Checks whether the value represented by this object is less than the other.
*
* @phpstan-pure
*/
public function lessThan(Money $other): bool
{
return $this->compare($other) < 0;
}
/**
* @phpstan-pure
*/
public function lessThanOrEqual(Money $other): bool
{
return $this->compare($other) <= 0;
}
/**
* Returns the value represented by this object - amount, expressed in the smallest currency units (eg cents).
*
* @phpstan-return numeric-string
*/
public function getAmount(): string
{
return $this->amount;
}
/**
* Returns the currency of this object.
*/
public function getCurrency(): Currency
{
return $this->currency;
}
/**
* Returns a new Money object that represents
* the sum of this and an other Money object.
*
* @phpstan-pure
*/
public function add(Money ...$addends): Money
{
$amount = $this->amount;
foreach ($addends as $addend) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $addend->currency) {
throw InvalidArgumentException::currencyMismatch();
}
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
$amount = self::$calculator::add($amount, $addend->amount);
}
return new self($amount, $this->currency);
}
/**
* Returns a new Money object that represents
* the difference of this and an other Money object.
*
* @phpstan-pure
*/
public function subtract(Money ...$subtrahends): Money
{
$amount = $this->amount;
foreach ($subtrahends as $subtrahend) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $subtrahend->currency) {
throw InvalidArgumentException::currencyMismatch();
}
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
$amount = self::$calculator::subtract($amount, $subtrahend->amount);
}
return new self($amount, $this->currency);
}
/**
* Returns a new Money object that represents
* the multiplied value by the given factor.
*
* @phpstan-param int|numeric-string $multiplier
* @phpstan-param self::ROUND_* $roundingMode
*/
public function multiply(int|string $multiplier, int $roundingMode = self::ROUND_HALF_UP): Money
{
if (is_int($multiplier)) {
$multiplier = (string) $multiplier;
}
$product = $this->round(self::$calculator::multiply($this->amount, $multiplier), $roundingMode);
return new self($product, $this->currency);
}
/**
* Returns a new Money object that represents
* the divided value by the given factor.
*
* @phpstan-param int|numeric-string $divisor
* @phpstan-param self::ROUND_* $roundingMode
*
* @phpstan-pure
*/
public function divide(int|string $divisor, int $roundingMode = self::ROUND_HALF_UP): Money
{
if (is_int($divisor)) {
$divisor = (string) $divisor;
}
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
$quotient = $this->round(self::$calculator::divide($this->amount, $divisor), $roundingMode);
return new self($quotient, $this->currency);
}
/**
* Returns a new Money object that represents
* the remainder after dividing the value by
* the given factor.
*/
public function mod(Money|int|string $divisor): Money
{
if ($divisor instanceof self) {
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $divisor->currency) {
throw InvalidArgumentException::currencyMismatch();
}
$divisor = $divisor->amount;
} else {
$divisor = (string) Number::fromNumber($divisor);
}
return new self(self::$calculator::mod($this->amount, $divisor), $this->currency);
}
/**
* Allocate the money according to a list of ratios.
*
* @phpstan-param TRatios $ratios
*
* @return Money[]
* @phpstan-return (
* TRatios is list
* ? non-empty-list<Money>
* : non-empty-array<Money>
* )
*
* @template TRatios as non-empty-array<float|int>
*/
public function allocate(array $ratios): array
{
$remainder = $this->amount;
$results = [];
$total = array_sum($ratios);
if ($total <= 0) {
throw new InvalidArgumentException('Cannot allocate to none, sum of ratios must be greater than zero');
}
foreach ($ratios as $key => $ratio) {
if ($ratio < 0) {
throw new InvalidArgumentException('Cannot allocate to none, ratio must be zero or positive');
}
$share = self::$calculator::share($this->amount, (string) $ratio, (string) $total);
$results[$key] = new self($share, $this->currency);
$remainder = self::$calculator::subtract($remainder, $share);
}
if (self::$calculator::compare($remainder, '0') === 0) {
return $results;
}
$amount = $this->amount;
$fractions = array_map(static function (float|int $ratio) use ($total, $amount) {
$share = (float) $ratio / $total * (float) $amount;
return $share - floor($share);
}, $ratios);
while (self::$calculator::compare($remainder, '0') > 0) {
$index = $fractions !== [] ? array_keys($fractions, max($fractions))[0] : 0;
$results[$index] = new self(self::$calculator::add($results[$index]->amount, '1'), $results[$index]->currency);
$remainder = self::$calculator::subtract($remainder, '1');
unset($fractions[$index]);
}
return $results;
}
/**
* Allocate the money among N targets.
*
* @phpstan-param positive-int $n
*
* @return Money[]
* @phpstan-return non-empty-list<Money>
*
* @throws InvalidArgumentException If number of targets is not an integer.
*/
public function allocateTo(int $n): array
{
return $this->allocate(array_fill(0, $n, 1));
}
/**
* @phpstan-return numeric-string
*
* @throws InvalidArgumentException if the given $money is zero.
*/
public function ratioOf(Money $money): string
{
if ($money->isZero()) {
throw new InvalidArgumentException('Cannot calculate a ratio of zero');
}
// Note: non-strict equality is intentional here, since `Currency` is `final` and reliable.
if ($this->currency != $money->currency) {
throw InvalidArgumentException::currencyMismatch();
}
return self::$calculator::divide($this->amount, $money->amount);
}
/**
* @phpstan-param numeric-string $amount
* @phpstan-param self::ROUND_* $roundingMode
*
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
private function round(string $amount, int $roundingMode): string
{
if ($roundingMode === self::ROUND_UP) {
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
return self::$calculator::ceil($amount);
}
if ($roundingMode === self::ROUND_DOWN) {
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
return self::$calculator::floor($amount);
}
// @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.methodCall
return self::$calculator::round($amount, $roundingMode);
}
/**
* Round to a specific unit.
*
* @phpstan-param non-negative-int $unit
* @phpstan-param self::ROUND_* $roundingMode
*/
public function roundToUnit(int $unit, int $roundingMode = self::ROUND_HALF_UP): self
{
if ($unit === 0) {
return $this;
}
$abs = self::$calculator::absolute($this->amount);
if (strlen($abs) < $unit) {
return new self('0', $this->currency);
}
$toBeRounded = substr($this->amount, 0, strlen($this->amount) - $unit) . '.' . substr($this->amount, $unit * -1);
$result = $this->round($toBeRounded, $roundingMode);
if ($result !== '0') {
$result .= str_pad('', $unit, '0');
}
return new self($result, $this->currency);
}
public function absolute(): Money
{
return new self(
self::$calculator::absolute($this->amount),
$this->currency
);
}
public function negative(): Money
{
return (new self(0, $this->currency))
->subtract($this);
}
/**
* Checks if the value represented by this object is zero.
*/
public function isZero(): bool
{
return self::$calculator::compare($this->amount, '0') === 0;
}
/**
* Checks if the value represented by this object is positive.
*/
public function isPositive(): bool
{
return self::$calculator::compare($this->amount, '0') > 0;
}
/**
* Checks if the value represented by this object is negative.
*/
public function isNegative(): bool
{
return self::$calculator::compare($this->amount, '0') < 0;
}
/**
* {@inheritDoc}
*
* @phpstan-return array{amount: string, currency: string}
*/
public function jsonSerialize(): array
{
return [
'amount' => $this->amount,
'currency' => $this->currency->jsonSerialize(),
];
}
/**
* @param Money $first
* @param Money ...$collection
*
* @phpstan-pure
*/
public static function min(self $first, self ...$collection): Money
{
$min = $first;
foreach ($collection as $money) {
if (! $money->lessThan($min)) {
continue;
}
$min = $money;
}
return $min;
}
/**
* @param Money $first
* @param Money ...$collection
*
* @phpstan-pure
*/
public static function max(self $first, self ...$collection): Money
{
$max = $first;
foreach ($collection as $money) {
if (! $money->greaterThan($max)) {
continue;
}
$max = $money;
}
return $max;
}
/** @phpstan-pure */
public static function sum(self $first, self ...$collection): Money
{
return $first->add(...$collection);
}
/** @phpstan-pure */
public static function avg(self $first, self ...$collection): Money
{
return $first->add(...$collection)->divide((string) (count($collection) + 1));
}
/** @phpstan-param class-string<Calculator> $calculator */
public static function registerCalculator(string $calculator): void
{
self::$calculator = $calculator;
}
/** @phpstan-return class-string<Calculator> */
public static function getCalculator(): string
{
return self::$calculator;
}
}

View File

@@ -0,0 +1,616 @@
<?php
declare(strict_types=1);
namespace Money;
use InvalidArgumentException;
/**
* This is a generated file. Do not edit it manually!
*
* @method static Money ONETHOUSANDCAT(numeric-string|int $amount)
* @method static Money ONETHOUSANDCHEEMS(numeric-string|int $amount)
* @method static Money ONETHOUSANDSATS(numeric-string|int $amount)
* @method static Money ONEINCH(numeric-string|int $amount)
* @method static Money ONEMBABYDOGE(numeric-string|int $amount)
* @method static Money A(numeric-string|int $amount)
* @method static Money AAVE(numeric-string|int $amount)
* @method static Money ACA(numeric-string|int $amount)
* @method static Money ACE(numeric-string|int $amount)
* @method static Money ACH(numeric-string|int $amount)
* @method static Money ACM(numeric-string|int $amount)
* @method static Money ACT(numeric-string|int $amount)
* @method static Money ACX(numeric-string|int $amount)
* @method static Money ADA(numeric-string|int $amount)
* @method static Money ADX(numeric-string|int $amount)
* @method static Money AED(numeric-string|int $amount)
* @method static Money AEUR(numeric-string|int $amount)
* @method static Money AEVO(numeric-string|int $amount)
* @method static Money AFN(numeric-string|int $amount)
* @method static Money AGLD(numeric-string|int $amount)
* @method static Money AI(numeric-string|int $amount)
* @method static Money AIXBT(numeric-string|int $amount)
* @method static Money ALCX(numeric-string|int $amount)
* @method static Money ALGO(numeric-string|int $amount)
* @method static Money ALICE(numeric-string|int $amount)
* @method static Money ALL(numeric-string|int $amount)
* @method static Money ALPHA(numeric-string|int $amount)
* @method static Money ALPINE(numeric-string|int $amount)
* @method static Money ALT(numeric-string|int $amount)
* @method static Money AMD(numeric-string|int $amount)
* @method static Money AMP(numeric-string|int $amount)
* @method static Money ANIME(numeric-string|int $amount)
* @method static Money ANKR(numeric-string|int $amount)
* @method static Money AOA(numeric-string|int $amount)
* @method static Money APE(numeric-string|int $amount)
* @method static Money API3(numeric-string|int $amount)
* @method static Money APT(numeric-string|int $amount)
* @method static Money AR(numeric-string|int $amount)
* @method static Money ARB(numeric-string|int $amount)
* @method static Money ARDR(numeric-string|int $amount)
* @method static Money ARK(numeric-string|int $amount)
* @method static Money ARKM(numeric-string|int $amount)
* @method static Money ARPA(numeric-string|int $amount)
* @method static Money ARS(numeric-string|int $amount)
* @method static Money ASR(numeric-string|int $amount)
* @method static Money ASTR(numeric-string|int $amount)
* @method static Money ATA(numeric-string|int $amount)
* @method static Money ATM(numeric-string|int $amount)
* @method static Money ATOM(numeric-string|int $amount)
* @method static Money AUCTION(numeric-string|int $amount)
* @method static Money AUD(numeric-string|int $amount)
* @method static Money AUDIO(numeric-string|int $amount)
* @method static Money AVA(numeric-string|int $amount)
* @method static Money AVAX(numeric-string|int $amount)
* @method static Money AWE(numeric-string|int $amount)
* @method static Money AWG(numeric-string|int $amount)
* @method static Money AXL(numeric-string|int $amount)
* @method static Money AXS(numeric-string|int $amount)
* @method static Money AZN(numeric-string|int $amount)
* @method static Money BABY(numeric-string|int $amount)
* @method static Money BAKE(numeric-string|int $amount)
* @method static Money BAM(numeric-string|int $amount)
* @method static Money BANANA(numeric-string|int $amount)
* @method static Money BANANAS31(numeric-string|int $amount)
* @method static Money BAND(numeric-string|int $amount)
* @method static Money BAR(numeric-string|int $amount)
* @method static Money BAT(numeric-string|int $amount)
* @method static Money BB(numeric-string|int $amount)
* @method static Money BBD(numeric-string|int $amount)
* @method static Money BCH(numeric-string|int $amount)
* @method static Money BDT(numeric-string|int $amount)
* @method static Money BEAMX(numeric-string|int $amount)
* @method static Money BEL(numeric-string|int $amount)
* @method static Money BERA(numeric-string|int $amount)
* @method static Money BGN(numeric-string|int $amount)
* @method static Money BHD(numeric-string|int $amount)
* @method static Money BICO(numeric-string|int $amount)
* @method static Money BIF(numeric-string|int $amount)
* @method static Money BIFI(numeric-string|int $amount)
* @method static Money BIGTIME(numeric-string|int $amount)
* @method static Money BIO(numeric-string|int $amount)
* @method static Money BLUR(numeric-string|int $amount)
* @method static Money BMD(numeric-string|int $amount)
* @method static Money BMT(numeric-string|int $amount)
* @method static Money BNB(numeric-string|int $amount)
* @method static Money BND(numeric-string|int $amount)
* @method static Money BNSOL(numeric-string|int $amount)
* @method static Money BNT(numeric-string|int $amount)
* @method static Money BOB(numeric-string|int $amount)
* @method static Money BOME(numeric-string|int $amount)
* @method static Money BONK(numeric-string|int $amount)
* @method static Money BOV(numeric-string|int $amount)
* @method static Money BRL(numeric-string|int $amount)
* @method static Money BROCCOLI714(numeric-string|int $amount)
* @method static Money BSD(numeric-string|int $amount)
* @method static Money BSW(numeric-string|int $amount)
* @method static Money BTC(numeric-string|int $amount)
* @method static Money BTN(numeric-string|int $amount)
* @method static Money BTTC(numeric-string|int $amount)
* @method static Money BWP(numeric-string|int $amount)
* @method static Money BYN(numeric-string|int $amount)
* @method static Money BZD(numeric-string|int $amount)
* @method static Money C98(numeric-string|int $amount)
* @method static Money CAD(numeric-string|int $amount)
* @method static Money CAKE(numeric-string|int $amount)
* @method static Money CATI(numeric-string|int $amount)
* @method static Money CDF(numeric-string|int $amount)
* @method static Money CELO(numeric-string|int $amount)
* @method static Money CELR(numeric-string|int $amount)
* @method static Money CETUS(numeric-string|int $amount)
* @method static Money CFX(numeric-string|int $amount)
* @method static Money CGPT(numeric-string|int $amount)
* @method static Money CHE(numeric-string|int $amount)
* @method static Money CHESS(numeric-string|int $amount)
* @method static Money CHF(numeric-string|int $amount)
* @method static Money CHR(numeric-string|int $amount)
* @method static Money CHW(numeric-string|int $amount)
* @method static Money CHZ(numeric-string|int $amount)
* @method static Money CITY(numeric-string|int $amount)
* @method static Money CKB(numeric-string|int $amount)
* @method static Money CLF(numeric-string|int $amount)
* @method static Money CLP(numeric-string|int $amount)
* @method static Money CNY(numeric-string|int $amount)
* @method static Money COMP(numeric-string|int $amount)
* @method static Money COOKIE(numeric-string|int $amount)
* @method static Money COP(numeric-string|int $amount)
* @method static Money COS(numeric-string|int $amount)
* @method static Money COTI(numeric-string|int $amount)
* @method static Money COU(numeric-string|int $amount)
* @method static Money COW(numeric-string|int $amount)
* @method static Money CRC(numeric-string|int $amount)
* @method static Money CRV(numeric-string|int $amount)
* @method static Money CTK(numeric-string|int $amount)
* @method static Money CTSI(numeric-string|int $amount)
* @method static Money CUP(numeric-string|int $amount)
* @method static Money CVC(numeric-string|int $amount)
* @method static Money CVE(numeric-string|int $amount)
* @method static Money CVX(numeric-string|int $amount)
* @method static Money CYBER(numeric-string|int $amount)
* @method static Money CZK(numeric-string|int $amount)
* @method static Money D(numeric-string|int $amount)
* @method static Money DAI(numeric-string|int $amount)
* @method static Money DASH(numeric-string|int $amount)
* @method static Money DATA(numeric-string|int $amount)
* @method static Money DCR(numeric-string|int $amount)
* @method static Money DEGO(numeric-string|int $amount)
* @method static Money DENT(numeric-string|int $amount)
* @method static Money DEXE(numeric-string|int $amount)
* @method static Money DF(numeric-string|int $amount)
* @method static Money DGB(numeric-string|int $amount)
* @method static Money DIA(numeric-string|int $amount)
* @method static Money DJF(numeric-string|int $amount)
* @method static Money DKK(numeric-string|int $amount)
* @method static Money DODO(numeric-string|int $amount)
* @method static Money DOGE(numeric-string|int $amount)
* @method static Money DOGS(numeric-string|int $amount)
* @method static Money DOP(numeric-string|int $amount)
* @method static Money DOT(numeric-string|int $amount)
* @method static Money DUSK(numeric-string|int $amount)
* @method static Money DYDX(numeric-string|int $amount)
* @method static Money DYM(numeric-string|int $amount)
* @method static Money DZD(numeric-string|int $amount)
* @method static Money EDU(numeric-string|int $amount)
* @method static Money EGLD(numeric-string|int $amount)
* @method static Money EGP(numeric-string|int $amount)
* @method static Money EIGEN(numeric-string|int $amount)
* @method static Money ENA(numeric-string|int $amount)
* @method static Money ENJ(numeric-string|int $amount)
* @method static Money ENS(numeric-string|int $amount)
* @method static Money EPIC(numeric-string|int $amount)
* @method static Money ERN(numeric-string|int $amount)
* @method static Money ETB(numeric-string|int $amount)
* @method static Money ETC(numeric-string|int $amount)
* @method static Money ETH(numeric-string|int $amount)
* @method static Money ETHFI(numeric-string|int $amount)
* @method static Money EUR(numeric-string|int $amount)
* @method static Money EURI(numeric-string|int $amount)
* @method static Money FARM(numeric-string|int $amount)
* @method static Money FDUSD(numeric-string|int $amount)
* @method static Money FET(numeric-string|int $amount)
* @method static Money FIDA(numeric-string|int $amount)
* @method static Money FIL(numeric-string|int $amount)
* @method static Money FIO(numeric-string|int $amount)
* @method static Money FIS(numeric-string|int $amount)
* @method static Money FJD(numeric-string|int $amount)
* @method static Money FKP(numeric-string|int $amount)
* @method static Money FLM(numeric-string|int $amount)
* @method static Money FLOKI(numeric-string|int $amount)
* @method static Money FLOW(numeric-string|int $amount)
* @method static Money FLUX(numeric-string|int $amount)
* @method static Money FORM(numeric-string|int $amount)
* @method static Money FORTH(numeric-string|int $amount)
* @method static Money FTT(numeric-string|int $amount)
* @method static Money FUN(numeric-string|int $amount)
* @method static Money FXS(numeric-string|int $amount)
* @method static Money G(numeric-string|int $amount)
* @method static Money GALA(numeric-string|int $amount)
* @method static Money GAS(numeric-string|int $amount)
* @method static Money GBP(numeric-string|int $amount)
* @method static Money GEL(numeric-string|int $amount)
* @method static Money GHS(numeric-string|int $amount)
* @method static Money GHST(numeric-string|int $amount)
* @method static Money GIP(numeric-string|int $amount)
* @method static Money GLM(numeric-string|int $amount)
* @method static Money GLMR(numeric-string|int $amount)
* @method static Money GMD(numeric-string|int $amount)
* @method static Money GMT(numeric-string|int $amount)
* @method static Money GMX(numeric-string|int $amount)
* @method static Money GNF(numeric-string|int $amount)
* @method static Money GNO(numeric-string|int $amount)
* @method static Money GNS(numeric-string|int $amount)
* @method static Money GPS(numeric-string|int $amount)
* @method static Money GRT(numeric-string|int $amount)
* @method static Money GTC(numeric-string|int $amount)
* @method static Money GTQ(numeric-string|int $amount)
* @method static Money GUN(numeric-string|int $amount)
* @method static Money GYD(numeric-string|int $amount)
* @method static Money HAEDAL(numeric-string|int $amount)
* @method static Money HBAR(numeric-string|int $amount)
* @method static Money HEI(numeric-string|int $amount)
* @method static Money HFT(numeric-string|int $amount)
* @method static Money HIFI(numeric-string|int $amount)
* @method static Money HIGH(numeric-string|int $amount)
* @method static Money HIVE(numeric-string|int $amount)
* @method static Money HKD(numeric-string|int $amount)
* @method static Money HMSTR(numeric-string|int $amount)
* @method static Money HNL(numeric-string|int $amount)
* @method static Money HOOK(numeric-string|int $amount)
* @method static Money HOT(numeric-string|int $amount)
* @method static Money HTG(numeric-string|int $amount)
* @method static Money HUF(numeric-string|int $amount)
* @method static Money HUMA(numeric-string|int $amount)
* @method static Money HYPER(numeric-string|int $amount)
* @method static Money ICP(numeric-string|int $amount)
* @method static Money ICX(numeric-string|int $amount)
* @method static Money ID(numeric-string|int $amount)
* @method static Money IDEX(numeric-string|int $amount)
* @method static Money IDR(numeric-string|int $amount)
* @method static Money ILS(numeric-string|int $amount)
* @method static Money ILV(numeric-string|int $amount)
* @method static Money IMX(numeric-string|int $amount)
* @method static Money INIT(numeric-string|int $amount)
* @method static Money INJ(numeric-string|int $amount)
* @method static Money INR(numeric-string|int $amount)
* @method static Money IO(numeric-string|int $amount)
* @method static Money IOST(numeric-string|int $amount)
* @method static Money IOTA(numeric-string|int $amount)
* @method static Money IOTX(numeric-string|int $amount)
* @method static Money IQ(numeric-string|int $amount)
* @method static Money IQD(numeric-string|int $amount)
* @method static Money IRR(numeric-string|int $amount)
* @method static Money ISK(numeric-string|int $amount)
* @method static Money JASMY(numeric-string|int $amount)
* @method static Money JMD(numeric-string|int $amount)
* @method static Money JOD(numeric-string|int $amount)
* @method static Money JOE(numeric-string|int $amount)
* @method static Money JPY(numeric-string|int $amount)
* @method static Money JST(numeric-string|int $amount)
* @method static Money JTO(numeric-string|int $amount)
* @method static Money JUP(numeric-string|int $amount)
* @method static Money JUV(numeric-string|int $amount)
* @method static Money KAIA(numeric-string|int $amount)
* @method static Money KAITO(numeric-string|int $amount)
* @method static Money KAVA(numeric-string|int $amount)
* @method static Money KDA(numeric-string|int $amount)
* @method static Money KERNEL(numeric-string|int $amount)
* @method static Money KES(numeric-string|int $amount)
* @method static Money KGS(numeric-string|int $amount)
* @method static Money KHR(numeric-string|int $amount)
* @method static Money KMD(numeric-string|int $amount)
* @method static Money KMF(numeric-string|int $amount)
* @method static Money KMNO(numeric-string|int $amount)
* @method static Money KNC(numeric-string|int $amount)
* @method static Money KPW(numeric-string|int $amount)
* @method static Money KRW(numeric-string|int $amount)
* @method static Money KSM(numeric-string|int $amount)
* @method static Money KWD(numeric-string|int $amount)
* @method static Money KYD(numeric-string|int $amount)
* @method static Money KZT(numeric-string|int $amount)
* @method static Money LAK(numeric-string|int $amount)
* @method static Money LAYER(numeric-string|int $amount)
* @method static Money LAZIO(numeric-string|int $amount)
* @method static Money LBP(numeric-string|int $amount)
* @method static Money LDO(numeric-string|int $amount)
* @method static Money LEVER(numeric-string|int $amount)
* @method static Money LINK(numeric-string|int $amount)
* @method static Money LISTA(numeric-string|int $amount)
* @method static Money LKR(numeric-string|int $amount)
* @method static Money LOKA(numeric-string|int $amount)
* @method static Money LPT(numeric-string|int $amount)
* @method static Money LQTY(numeric-string|int $amount)
* @method static Money LRC(numeric-string|int $amount)
* @method static Money LRD(numeric-string|int $amount)
* @method static Money LSK(numeric-string|int $amount)
* @method static Money LSL(numeric-string|int $amount)
* @method static Money LTC(numeric-string|int $amount)
* @method static Money LTO(numeric-string|int $amount)
* @method static Money LUMIA(numeric-string|int $amount)
* @method static Money LUNA(numeric-string|int $amount)
* @method static Money LUNC(numeric-string|int $amount)
* @method static Money LYD(numeric-string|int $amount)
* @method static Money MAD(numeric-string|int $amount)
* @method static Money MAGIC(numeric-string|int $amount)
* @method static Money MANA(numeric-string|int $amount)
* @method static Money MANTA(numeric-string|int $amount)
* @method static Money MASK(numeric-string|int $amount)
* @method static Money MAV(numeric-string|int $amount)
* @method static Money MBL(numeric-string|int $amount)
* @method static Money MBOX(numeric-string|int $amount)
* @method static Money MDL(numeric-string|int $amount)
* @method static Money MDT(numeric-string|int $amount)
* @method static Money ME(numeric-string|int $amount)
* @method static Money MEME(numeric-string|int $amount)
* @method static Money METIS(numeric-string|int $amount)
* @method static Money MGA(numeric-string|int $amount)
* @method static Money MINA(numeric-string|int $amount)
* @method static Money MKD(numeric-string|int $amount)
* @method static Money MKR(numeric-string|int $amount)
* @method static Money MLN(numeric-string|int $amount)
* @method static Money MMK(numeric-string|int $amount)
* @method static Money MNT(numeric-string|int $amount)
* @method static Money MOP(numeric-string|int $amount)
* @method static Money MOVE(numeric-string|int $amount)
* @method static Money MOVR(numeric-string|int $amount)
* @method static Money MRU(numeric-string|int $amount)
* @method static Money MTL(numeric-string|int $amount)
* @method static Money MUBARAK(numeric-string|int $amount)
* @method static Money MUR(numeric-string|int $amount)
* @method static Money MVR(numeric-string|int $amount)
* @method static Money MWK(numeric-string|int $amount)
* @method static Money MXN(numeric-string|int $amount)
* @method static Money MXV(numeric-string|int $amount)
* @method static Money MYR(numeric-string|int $amount)
* @method static Money MZN(numeric-string|int $amount)
* @method static Money NAD(numeric-string|int $amount)
* @method static Money NEAR(numeric-string|int $amount)
* @method static Money NEIRO(numeric-string|int $amount)
* @method static Money NEO(numeric-string|int $amount)
* @method static Money NEXO(numeric-string|int $amount)
* @method static Money NFP(numeric-string|int $amount)
* @method static Money NGN(numeric-string|int $amount)
* @method static Money NIL(numeric-string|int $amount)
* @method static Money NIO(numeric-string|int $amount)
* @method static Money NKN(numeric-string|int $amount)
* @method static Money NMR(numeric-string|int $amount)
* @method static Money NOK(numeric-string|int $amount)
* @method static Money NOT(numeric-string|int $amount)
* @method static Money NPR(numeric-string|int $amount)
* @method static Money NTRN(numeric-string|int $amount)
* @method static Money NXPC(numeric-string|int $amount)
* @method static Money NZD(numeric-string|int $amount)
* @method static Money OG(numeric-string|int $amount)
* @method static Money OGN(numeric-string|int $amount)
* @method static Money OM(numeric-string|int $amount)
* @method static Money OMNI(numeric-string|int $amount)
* @method static Money OMR(numeric-string|int $amount)
* @method static Money ONDO(numeric-string|int $amount)
* @method static Money ONE(numeric-string|int $amount)
* @method static Money ONG(numeric-string|int $amount)
* @method static Money ONT(numeric-string|int $amount)
* @method static Money OP(numeric-string|int $amount)
* @method static Money ORCA(numeric-string|int $amount)
* @method static Money ORDI(numeric-string|int $amount)
* @method static Money OSMO(numeric-string|int $amount)
* @method static Money OXT(numeric-string|int $amount)
* @method static Money PAB(numeric-string|int $amount)
* @method static Money PARTI(numeric-string|int $amount)
* @method static Money PAXG(numeric-string|int $amount)
* @method static Money PEN(numeric-string|int $amount)
* @method static Money PENDLE(numeric-string|int $amount)
* @method static Money PENGU(numeric-string|int $amount)
* @method static Money PEOPLE(numeric-string|int $amount)
* @method static Money PEPE(numeric-string|int $amount)
* @method static Money PERP(numeric-string|int $amount)
* @method static Money PGK(numeric-string|int $amount)
* @method static Money PHA(numeric-string|int $amount)
* @method static Money PHB(numeric-string|int $amount)
* @method static Money PHP(numeric-string|int $amount)
* @method static Money PIVX(numeric-string|int $amount)
* @method static Money PIXEL(numeric-string|int $amount)
* @method static Money PKR(numeric-string|int $amount)
* @method static Money PLN(numeric-string|int $amount)
* @method static Money PNUT(numeric-string|int $amount)
* @method static Money POL(numeric-string|int $amount)
* @method static Money POLYX(numeric-string|int $amount)
* @method static Money POND(numeric-string|int $amount)
* @method static Money PORTAL(numeric-string|int $amount)
* @method static Money PORTO(numeric-string|int $amount)
* @method static Money POWR(numeric-string|int $amount)
* @method static Money PROM(numeric-string|int $amount)
* @method static Money PSG(numeric-string|int $amount)
* @method static Money PUNDIX(numeric-string|int $amount)
* @method static Money PYG(numeric-string|int $amount)
* @method static Money PYR(numeric-string|int $amount)
* @method static Money PYTH(numeric-string|int $amount)
* @method static Money QAR(numeric-string|int $amount)
* @method static Money QI(numeric-string|int $amount)
* @method static Money QKC(numeric-string|int $amount)
* @method static Money QNT(numeric-string|int $amount)
* @method static Money QTUM(numeric-string|int $amount)
* @method static Money QUICK(numeric-string|int $amount)
* @method static Money RAD(numeric-string|int $amount)
* @method static Money RARE(numeric-string|int $amount)
* @method static Money RAY(numeric-string|int $amount)
* @method static Money RDNT(numeric-string|int $amount)
* @method static Money RED(numeric-string|int $amount)
* @method static Money REI(numeric-string|int $amount)
* @method static Money RENDER(numeric-string|int $amount)
* @method static Money REQ(numeric-string|int $amount)
* @method static Money REZ(numeric-string|int $amount)
* @method static Money RIF(numeric-string|int $amount)
* @method static Money RLC(numeric-string|int $amount)
* @method static Money RON(numeric-string|int $amount)
* @method static Money RONIN(numeric-string|int $amount)
* @method static Money ROSE(numeric-string|int $amount)
* @method static Money RPL(numeric-string|int $amount)
* @method static Money RSD(numeric-string|int $amount)
* @method static Money RSR(numeric-string|int $amount)
* @method static Money RUB(numeric-string|int $amount)
* @method static Money RUNE(numeric-string|int $amount)
* @method static Money RVN(numeric-string|int $amount)
* @method static Money RWF(numeric-string|int $amount)
* @method static Money S(numeric-string|int $amount)
* @method static Money SAGA(numeric-string|int $amount)
* @method static Money SAND(numeric-string|int $amount)
* @method static Money SANTOS(numeric-string|int $amount)
* @method static Money SAR(numeric-string|int $amount)
* @method static Money SBD(numeric-string|int $amount)
* @method static Money SC(numeric-string|int $amount)
* @method static Money SCR(numeric-string|int $amount)
* @method static Money SCRT(numeric-string|int $amount)
* @method static Money SDG(numeric-string|int $amount)
* @method static Money SEI(numeric-string|int $amount)
* @method static Money SEK(numeric-string|int $amount)
* @method static Money SFP(numeric-string|int $amount)
* @method static Money SGD(numeric-string|int $amount)
* @method static Money SHELL(numeric-string|int $amount)
* @method static Money SHIB(numeric-string|int $amount)
* @method static Money SHP(numeric-string|int $amount)
* @method static Money SIGN(numeric-string|int $amount)
* @method static Money SKL(numeric-string|int $amount)
* @method static Money SLE(numeric-string|int $amount)
* @method static Money SLF(numeric-string|int $amount)
* @method static Money SLP(numeric-string|int $amount)
* @method static Money SNX(numeric-string|int $amount)
* @method static Money SOL(numeric-string|int $amount)
* @method static Money SOLV(numeric-string|int $amount)
* @method static Money SOPH(numeric-string|int $amount)
* @method static Money SOS(numeric-string|int $amount)
* @method static Money SPELL(numeric-string|int $amount)
* @method static Money SRD(numeric-string|int $amount)
* @method static Money SSP(numeric-string|int $amount)
* @method static Money SSV(numeric-string|int $amount)
* @method static Money STEEM(numeric-string|int $amount)
* @method static Money STG(numeric-string|int $amount)
* @method static Money STN(numeric-string|int $amount)
* @method static Money STO(numeric-string|int $amount)
* @method static Money STORJ(numeric-string|int $amount)
* @method static Money STRAX(numeric-string|int $amount)
* @method static Money STRK(numeric-string|int $amount)
* @method static Money STX(numeric-string|int $amount)
* @method static Money SUI(numeric-string|int $amount)
* @method static Money SUN(numeric-string|int $amount)
* @method static Money SUPER(numeric-string|int $amount)
* @method static Money SUSHI(numeric-string|int $amount)
* @method static Money SVC(numeric-string|int $amount)
* @method static Money SXP(numeric-string|int $amount)
* @method static Money SXT(numeric-string|int $amount)
* @method static Money SYN(numeric-string|int $amount)
* @method static Money SYP(numeric-string|int $amount)
* @method static Money SYRUP(numeric-string|int $amount)
* @method static Money SYS(numeric-string|int $amount)
* @method static Money SZL(numeric-string|int $amount)
* @method static Money T(numeric-string|int $amount)
* @method static Money TAO(numeric-string|int $amount)
* @method static Money TFUEL(numeric-string|int $amount)
* @method static Money THB(numeric-string|int $amount)
* @method static Money THE(numeric-string|int $amount)
* @method static Money THETA(numeric-string|int $amount)
* @method static Money TIA(numeric-string|int $amount)
* @method static Money TJS(numeric-string|int $amount)
* @method static Money TKO(numeric-string|int $amount)
* @method static Money TLM(numeric-string|int $amount)
* @method static Money TMT(numeric-string|int $amount)
* @method static Money TND(numeric-string|int $amount)
* @method static Money TNSR(numeric-string|int $amount)
* @method static Money TON(numeric-string|int $amount)
* @method static Money TOP(numeric-string|int $amount)
* @method static Money TRB(numeric-string|int $amount)
* @method static Money TRU(numeric-string|int $amount)
* @method static Money TRUMP(numeric-string|int $amount)
* @method static Money TRX(numeric-string|int $amount)
* @method static Money TRY(numeric-string|int $amount)
* @method static Money TST(numeric-string|int $amount)
* @method static Money TTD(numeric-string|int $amount)
* @method static Money TURBO(numeric-string|int $amount)
* @method static Money TUSD(numeric-string|int $amount)
* @method static Money TUT(numeric-string|int $amount)
* @method static Money TWD(numeric-string|int $amount)
* @method static Money TWT(numeric-string|int $amount)
* @method static Money TZS(numeric-string|int $amount)
* @method static Money UAH(numeric-string|int $amount)
* @method static Money UGX(numeric-string|int $amount)
* @method static Money UMA(numeric-string|int $amount)
* @method static Money UNI(numeric-string|int $amount)
* @method static Money USD(numeric-string|int $amount)
* @method static Money USD1(numeric-string|int $amount)
* @method static Money USDC(numeric-string|int $amount)
* @method static Money USDP(numeric-string|int $amount)
* @method static Money USDT(numeric-string|int $amount)
* @method static Money USN(numeric-string|int $amount)
* @method static Money USTC(numeric-string|int $amount)
* @method static Money USUAL(numeric-string|int $amount)
* @method static Money UTK(numeric-string|int $amount)
* @method static Money UYI(numeric-string|int $amount)
* @method static Money UYU(numeric-string|int $amount)
* @method static Money UYW(numeric-string|int $amount)
* @method static Money UZS(numeric-string|int $amount)
* @method static Money VANA(numeric-string|int $amount)
* @method static Money VANRY(numeric-string|int $amount)
* @method static Money VED(numeric-string|int $amount)
* @method static Money VELODROME(numeric-string|int $amount)
* @method static Money VES(numeric-string|int $amount)
* @method static Money VET(numeric-string|int $amount)
* @method static Money VIC(numeric-string|int $amount)
* @method static Money VIRTUAL(numeric-string|int $amount)
* @method static Money VND(numeric-string|int $amount)
* @method static Money VOXEL(numeric-string|int $amount)
* @method static Money VTHO(numeric-string|int $amount)
* @method static Money VUV(numeric-string|int $amount)
* @method static Money W(numeric-string|int $amount)
* @method static Money WAN(numeric-string|int $amount)
* @method static Money WAXP(numeric-string|int $amount)
* @method static Money WBETH(numeric-string|int $amount)
* @method static Money WBTC(numeric-string|int $amount)
* @method static Money WCT(numeric-string|int $amount)
* @method static Money WIF(numeric-string|int $amount)
* @method static Money WIN(numeric-string|int $amount)
* @method static Money WLD(numeric-string|int $amount)
* @method static Money WOO(numeric-string|int $amount)
* @method static Money WST(numeric-string|int $amount)
* @method static Money XAD(numeric-string|int $amount)
* @method static Money XAF(numeric-string|int $amount)
* @method static Money XAG(numeric-string|int $amount)
* @method static Money XAI(numeric-string|int $amount)
* @method static Money XAU(numeric-string|int $amount)
* @method static Money XBA(numeric-string|int $amount)
* @method static Money XBB(numeric-string|int $amount)
* @method static Money XBC(numeric-string|int $amount)
* @method static Money XBD(numeric-string|int $amount)
* @method static Money XBT(numeric-string|int $amount)
* @method static Money XCD(numeric-string|int $amount)
* @method static Money XCG(numeric-string|int $amount)
* @method static Money XDR(numeric-string|int $amount)
* @method static Money XEC(numeric-string|int $amount)
* @method static Money XLM(numeric-string|int $amount)
* @method static Money XNO(numeric-string|int $amount)
* @method static Money XOF(numeric-string|int $amount)
* @method static Money XPD(numeric-string|int $amount)
* @method static Money XPF(numeric-string|int $amount)
* @method static Money XPT(numeric-string|int $amount)
* @method static Money XRP(numeric-string|int $amount)
* @method static Money XSU(numeric-string|int $amount)
* @method static Money XTS(numeric-string|int $amount)
* @method static Money XTZ(numeric-string|int $amount)
* @method static Money XUA(numeric-string|int $amount)
* @method static Money XUSD(numeric-string|int $amount)
* @method static Money XVG(numeric-string|int $amount)
* @method static Money XVS(numeric-string|int $amount)
* @method static Money XXX(numeric-string|int $amount)
* @method static Money YER(numeric-string|int $amount)
* @method static Money YFI(numeric-string|int $amount)
* @method static Money YGG(numeric-string|int $amount)
* @method static Money ZAR(numeric-string|int $amount)
* @method static Money ZEC(numeric-string|int $amount)
* @method static Money ZEN(numeric-string|int $amount)
* @method static Money ZIL(numeric-string|int $amount)
* @method static Money ZK(numeric-string|int $amount)
* @method static Money ZMW(numeric-string|int $amount)
* @method static Money ZRO(numeric-string|int $amount)
* @method static Money ZRX(numeric-string|int $amount)
* @method static Money ZWG(numeric-string|int $amount)
* @psalm-immutable
*/
trait MoneyFactory
{
/**
* Convenience factory method for a Money object.
*
* <code>
* $fiveDollar = Money::USD(500);
* </code>
*
* @param non-empty-string $method
* @param array{numeric-string|int} $arguments
*
* @throws InvalidArgumentException If amount is not integer(ish).
*
* @psalm-pure
*/
public static function __callStatic(string $method, array $arguments): Money
{
return new Money($arguments[0], new Currency($method));
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Money;
/**
* Formats Money objects.
*/
interface MoneyFormatter
{
/**
* Formats a Money object as string.
*
* @phpstan-return non-empty-string
*
* Exception\FormatterException
*/
public function format(Money $money): string;
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Money;
/**
* Parses a string into a Money object.
*/
interface MoneyParser
{
/**
* Parses a string into a Money object (including currency).
*
* @throws Exception\ParserException
*/
public function parse(string $money, Currency|null $fallbackCurrency = null): Money;
}

330
vendor/moneyphp/money/src/Number.php vendored Normal file
View File

@@ -0,0 +1,330 @@
<?php
declare(strict_types=1);
namespace Money;
use InvalidArgumentException;
use function abs;
use function explode;
use function is_int;
use function ltrim;
use function min;
use function rtrim;
use function sprintf;
use function str_pad;
use function strlen;
use function substr;
/**
* Represents a numeric value.
*
* @internal this is an internal utility of the library, and may vary at any time. It is mostly used to internally validate
* that a number is represented at digits, but by improving type system integration, we may be able to completely
* get rid of it.
*
* @phpstan-immutable
*/
final class Number
{
/** @phpstan-var numeric-string */
private string $integerPart;
/** @phpstan-var numeric-string|'' */
private string $fractionalPart;
private const NUMBERS = [0 => 1, 1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1, 6 => 1, 7 => 1, 8 => 1, 9 => 1];
/**
* @phpstan-pure
*/
public function __construct(string $integerPart, string $fractionalPart = '')
{
if ($integerPart === '' && $fractionalPart === '') {
throw new InvalidArgumentException('Empty number is invalid');
}
$this->integerPart = self::parseIntegerPart($integerPart);
$this->fractionalPart = self::parseFractionalPart($fractionalPart);
}
/** @phpstan-pure */
public static function fromString(string $number): self
{
$portions = explode('.', $number, 2);
return new self(
$portions[0],
rtrim($portions[1] ?? '', '0')
);
}
/** @phpstan-pure */
public static function fromFloat(float $number): self
{
return self::fromString(sprintf('%.14F', $number));
}
/** @phpstan-pure */
public static function fromNumber(int|string $number): self
{
if (is_int($number)) {
return new self((string) $number);
}
return self::fromString($number);
}
/**
* @phpstan-pure
*/
public function isDecimal(): bool
{
return $this->fractionalPart !== '';
}
/**
* @phpstan-pure
*/
public function isInteger(): bool
{
return $this->fractionalPart === '';
}
/**
* @phpstan-pure
*/
public function isHalf(): bool
{
return $this->fractionalPart === '5';
}
/**
* @phpstan-pure
*/
public function isCurrentEven(): bool
{
$lastIntegerPartNumber = (int) $this->integerPart[strlen($this->integerPart) - 1];
return $lastIntegerPartNumber % 2 === 0;
}
/**
* @phpstan-pure
*/
public function isCloserToNext(): bool
{
if ($this->fractionalPart === '') {
return false;
}
return $this->fractionalPart[0] >= 5;
}
/**
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public function __toString(): string
{
if ($this->fractionalPart === '') {
return $this->integerPart;
}
return $this->integerPart . '.' . $this->fractionalPart;
}
/**
* @phpstan-pure
*/
public function isNegative(): bool
{
return $this->integerPart[0] === '-';
}
/**
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public function getIntegerPart(): string
{
return $this->integerPart;
}
/**
* @phpstan-return numeric-string|''
*
* @phpstan-pure
*/
public function getFractionalPart(): string
{
return $this->fractionalPart;
}
/**
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
public function getIntegerRoundingMultiplier(): string
{
if ($this->integerPart[0] === '-') {
return '-1';
}
return '1';
}
public function base10(int $number): self
{
if ($this->integerPart === '0' && ! $this->fractionalPart) {
return $this;
}
$sign = '';
$integerPart = $this->integerPart;
if ($integerPart[0] === '-') {
$sign = '-';
$integerPart = substr($integerPart, 1);
}
if ($number >= 0) {
$integerPart = ltrim($integerPart, '0');
$lengthIntegerPart = strlen($integerPart);
$integers = $lengthIntegerPart - min($number, $lengthIntegerPart);
$zeroPad = $number - min($number, $lengthIntegerPart);
return new self(
$sign . substr($integerPart, 0, $integers),
rtrim(str_pad('', $zeroPad, '0') . substr($integerPart, $integers) . $this->fractionalPart, '0')
);
}
$number = abs($number);
$lengthFractionalPart = strlen($this->fractionalPart);
$fractions = $lengthFractionalPart - min($number, $lengthFractionalPart);
$zeroPad = $number - min($number, $lengthFractionalPart);
return new self(
$sign . ltrim($integerPart . substr($this->fractionalPart, 0, $lengthFractionalPart - $fractions) . str_pad('', $zeroPad, '0'), '0'),
substr($this->fractionalPart, $lengthFractionalPart - $fractions)
);
}
/**
* @phpstan-return numeric-string
*
* @phpstan-pure
*/
private static function parseIntegerPart(string $number): string
{
if ($number === '' || $number === '0') {
return '0';
}
if ($number === '-' || $number === '-0') {
return '-0';
}
// Happy path performance optimization: number can be used as-is if it is within
// the platform's integer capabilities.
if ($number === (string) (int) $number) {
return $number;
}
$nonZero = false;
for ($position = 0, $characters = strlen($number); $position < $characters; ++$position) {
$digit = $number[$position];
if (! isset(self::NUMBERS[$digit]) && ! ($position === 0 && $digit === '-')) {
throw new InvalidArgumentException(sprintf('Invalid integer part %1$s. Invalid digit %2$s found', $number, $digit));
}
if ($digit === '-') {
continue;
}
if ($nonZero === false && $digit === '0') {
throw new InvalidArgumentException('Leading zeros are not allowed');
}
$nonZero = true;
}
return $number;
}
/**
* @phpstan-return numeric-string|''
*
* @phpstan-pure
*/
private static function parseFractionalPart(string $number): string
{
if ($number === '') {
return $number;
}
$intFraction = (int) $number;
// Happy path performance optimization: number can be used as-is if it is within
// the platform's integer capabilities, and it starts with zeroes only.
if ($intFraction > 0 && ltrim($number, '0') === (string) $intFraction) {
return $number;
}
for ($position = 0, $characters = strlen($number); $position < $characters; ++$position) {
$digit = $number[$position];
if (! isset(self::NUMBERS[$digit])) {
throw new InvalidArgumentException(sprintf('Invalid fractional part %1$s. Invalid digit %2$s found', $number, $digit));
}
}
return $number;
}
/**
* @phpstan-pure
*/
public static function roundMoneyValue(string $moneyValue, int $targetDigits, int $havingDigits): string
{
$valueLength = strlen($moneyValue);
$shouldRound = $targetDigits < $havingDigits && $valueLength - $havingDigits + $targetDigits > 0;
if ($shouldRound && $moneyValue[$valueLength - $havingDigits + $targetDigits] >= 5) {
$position = $valueLength - $havingDigits + $targetDigits;
$addend = 1;
while ($position > 0) {
// @phpstan-ignore possiblyImpure.methodCall (no idea what it thinks this)
$newValue = (string) ((int) $moneyValue[$position - 1] + $addend);
if ($newValue >= 10) {
$moneyValue[$position - 1] = $newValue[1];
$addend = $newValue[0];
--$position;
if ($position === 0) {
$moneyValue = $addend . $moneyValue;
}
} else {
if ($moneyValue[$position - 1] === '-') {
$moneyValue[$position - 1] = $newValue[0];
$moneyValue = '-' . $moneyValue;
} else {
$moneyValue[$position - 1] = $newValue[0];
}
break;
}
}
}
return $moneyValue;
}
}

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace Money\PHPUnit;
use Money\Currencies\AggregateCurrencies;
use Money\Currencies\BitcoinCurrencies;
use Money\Currencies\ISOCurrencies;
use Money\Formatter\IntlMoneyFormatter;
use Money\Money;
use NumberFormatter;
use SebastianBergmann\Comparator\ComparisonFailure;
use function assert;
/**
* The comparator is for comparing Money objects in PHPUnit tests.
*
* Add this to your bootstrap file:
*
* \SebastianBergmann\Comparator\Factory::getInstance()->register(new \Money\PHPUnit\Comparator());
*
* @internal do not use within your sources: this comparator is only to be used within the test suite of this library
*/
final class Comparator extends \SebastianBergmann\Comparator\Comparator
{
private IntlMoneyFormatter $formatter;
public function __construct()
{
$currencies = new AggregateCurrencies([
new ISOCurrencies(),
new BitcoinCurrencies(),
]);
$numberFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
$this->formatter = new IntlMoneyFormatter($numberFormatter, $currencies);
}
/** {@inheritDoc} */
public function accepts(mixed $expected, mixed $actual): bool
{
return $expected instanceof Money && $actual instanceof Money;
}
/**
* {@inheritDoc}
*
* @param float $delta
* @param bool $canonicalize
* @param bool $ignoreCase
*/
public function assertEquals(
mixed $expected,
mixed $actual,
$delta = 0.0,
$canonicalize = false,
$ignoreCase = false
): void {
assert($expected instanceof Money);
assert($actual instanceof Money);
if (! $expected->equals($actual)) {
throw new ComparisonFailure($expected, $actual, $this->formatter->format($expected), $this->formatter->format($actual), 'Failed asserting that two Money objects are equal.');
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Money\Parser;
use Money\Currency;
use Money\Exception;
use Money\Money;
use Money\MoneyParser;
use function sprintf;
/**
* Parses a string into a Money object using other parsers.
*/
final class AggregateMoneyParser implements MoneyParser
{
/**
* @param MoneyParser[] $parsers
* @phpstan-param non-empty-array<MoneyParser> $parsers
*/
public function __construct(private readonly array $parsers)
{
}
public function parse(string $money, Currency|null $fallbackCurrency = null): Money
{
foreach ($this->parsers as $parser) {
try {
return $parser->parse($money, $fallbackCurrency);
} catch (Exception\ParserException) {
}
}
throw new Exception\ParserException(sprintf('Unable to parse %s', $money));
}
}

View File

@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Money\Parser;
use Money\Currencies\BitcoinCurrencies;
use Money\Currency;
use Money\Exception\ParserException;
use Money\Money;
use Money\MoneyParser;
use function ltrim;
use function rtrim;
use function str_pad;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
/**
* Parses Bitcoin currency to Money.
*/
final class BitcoinMoneyParser implements MoneyParser
{
public function __construct(private readonly int $fractionDigits)
{
}
public function parse(string $money, Currency|null $fallbackCurrency = null): Money
{
if (strpos($money, BitcoinCurrencies::SYMBOL) === false) {
throw new ParserException('Value cannot be parsed as Bitcoin');
}
$currency = $fallbackCurrency ?? new Currency(BitcoinCurrencies::CODE);
$decimal = str_replace(BitcoinCurrencies::SYMBOL, '', $money);
$decimalSeparator = strpos($decimal, '.');
if ($decimalSeparator !== false) {
$decimal = rtrim($decimal, '0');
$lengthDecimal = strlen($decimal);
$decimal = str_replace('.', '', $decimal);
$decimal .= str_pad('', ($lengthDecimal - $decimalSeparator - $this->fractionDigits - 1) * -1, '0');
} else {
$decimal .= str_pad('', $this->fractionDigits, '0');
}
if (substr($decimal, 0, 1) === '-') {
$decimal = '-' . ltrim(substr($decimal, 1), '0');
} else {
$decimal = ltrim($decimal, '0');
}
if ($decimal === '') {
$decimal = '0';
}
return new Money($decimal, $currency);
}
}

View File

@@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace Money\Parser;
use Money\Currencies;
use Money\Currency;
use Money\Exception\ParserException;
use Money\Money;
use Money\MoneyParser;
use Money\Number;
use function ltrim;
use function preg_match;
use function sprintf;
use function str_pad;
use function strlen;
use function substr;
use function trim;
/**
* Parses a decimal string into a Money object.
*/
final class DecimalMoneyParser implements MoneyParser
{
public const DECIMAL_PATTERN = '/^(?P<sign>-)?(?P<digits>\d+)?\.?(?P<fraction>\d+)?$/';
public function __construct(private readonly Currencies $currencies)
{
}
public function parse(string $money, Currency|null $fallbackCurrency = null): Money
{
if ($fallbackCurrency === null) {
throw new ParserException('DecimalMoneyParser cannot parse currency symbols. Use fallbackCurrency argument');
}
$decimal = trim($money);
if ($decimal === '') {
return new Money(0, $fallbackCurrency);
}
if (! preg_match(self::DECIMAL_PATTERN, $decimal, $matches) || ! isset($matches['digits'])) {
throw new ParserException(sprintf('Cannot parse "%s" to Money.', $decimal));
}
$negative = isset($matches['sign']) && $matches['sign'] === '-';
$decimal = $matches['digits'];
if ($negative) {
$decimal = '-' . $decimal;
}
$subunit = $this->currencies->subunitFor($fallbackCurrency);
if (isset($matches['fraction'])) {
$fractionDigits = strlen($matches['fraction']);
$decimal .= $matches['fraction'];
$decimal = Number::roundMoneyValue($decimal, $subunit, $fractionDigits);
if ($fractionDigits > $subunit) {
$decimal = substr($decimal, 0, $subunit - $fractionDigits);
} elseif ($fractionDigits < $subunit) {
$decimal .= str_pad('', $subunit - $fractionDigits, '0');
}
} else {
$decimal .= str_pad('', $subunit, '0');
}
if ($negative) {
$decimal = '-' . ltrim(substr($decimal, 1), '0');
} else {
$decimal = ltrim($decimal, '0');
}
if ($decimal === '' || $decimal === '-') {
$decimal = '0';
}
return new Money($decimal, $fallbackCurrency);
}
}

View File

@@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace Money\Parser;
use Money\Currencies;
use Money\Currency;
use Money\Exception\ParserException;
use Money\Money;
use Money\MoneyParser;
use Money\Number;
use NumberFormatter;
use function ltrim;
use function str_pad;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
/**
* Parses a string into a Money object using intl extension.
*/
final class IntlLocalizedDecimalParser implements MoneyParser
{
public function __construct(private readonly NumberFormatter $formatter, private readonly Currencies $currencies)
{
}
public function parse(string $money, Currency|null $fallbackCurrency = null): Money
{
if ($fallbackCurrency === null) {
throw new ParserException('IntlLocalizedDecimalParser cannot parse currency symbols. Use forceCurrency argument');
}
$decimal = $this->formatter->parse($money);
if ($decimal === false) {
throw new ParserException('Cannot parse ' . $money . ' to Money. ' . $this->formatter->getErrorMessage());
}
$decimal = (string) $decimal;
$subunit = $this->currencies->subunitFor($fallbackCurrency);
$decimalPosition = strpos($decimal, '.');
if ($decimalPosition !== false) {
$decimalLength = strlen($decimal);
$fractionDigits = $decimalLength - $decimalPosition - 1;
$decimal = str_replace('.', '', $decimal);
$decimal = Number::roundMoneyValue($decimal, $subunit, $fractionDigits);
if ($fractionDigits > $subunit) {
$decimal = substr($decimal, 0, $decimalPosition + $subunit);
} elseif ($fractionDigits < $subunit) {
$decimal .= str_pad('', $subunit - $fractionDigits, '0');
}
} else {
$decimal .= str_pad('', $subunit, '0');
}
if ($decimal[0] === '-') {
$decimal = '-' . ltrim(substr($decimal, 1), '0');
} else {
$decimal = ltrim($decimal, '0');
}
if ($decimal === '') {
$decimal = '0';
}
return new Money($decimal, $fallbackCurrency);
}
}

View File

@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace Money\Parser;
use Money\Currencies;
use Money\Currency;
use Money\Exception\ParserException;
use Money\Money;
use Money\MoneyParser;
use Money\Number;
use NumberFormatter;
use function assert;
use function ltrim;
use function str_pad;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
/**
* Parses a string into a Money object using intl extension.
*/
final class IntlMoneyParser implements MoneyParser
{
public function __construct(private readonly NumberFormatter $formatter, private readonly Currencies $currencies)
{
}
public function parse(string $money, Currency|null $fallbackCurrency = null): Money
{
$currency = '';
// phpcs:ignore
/** @var string|float|bool|null $decimal */
$decimal = $this->formatter->parseCurrency($money, $currency);
if ($decimal === false || $decimal === null) {
throw new ParserException('Cannot parse ' . $money . ' to Money. ' . $this->formatter->getErrorMessage());
}
if ($fallbackCurrency === null) {
assert($currency !== '');
$fallbackCurrency = new Currency($currency);
}
$decimal = (string) $decimal;
$subunit = $this->currencies->subunitFor($fallbackCurrency);
$decimalPosition = strpos($decimal, '.');
if ($decimalPosition !== false) {
$decimalLength = strlen($decimal);
$fractionDigits = $decimalLength - $decimalPosition - 1;
$decimal = str_replace('.', '', $decimal);
$decimal = Number::roundMoneyValue($decimal, $subunit, $fractionDigits);
if ($fractionDigits > $subunit) {
$decimal = substr($decimal, 0, $decimalPosition + $subunit);
} elseif ($fractionDigits < $subunit) {
$decimal .= str_pad('', $subunit - $fractionDigits, '0');
}
} else {
$decimal .= str_pad('', $subunit, '0');
}
if ($decimal[0] === '-') {
$decimal = '-' . ltrim(substr($decimal, 1), '0');
} else {
$decimal = ltrim($decimal, '0');
}
if ($decimal === '') {
$decimal = '0';
}
return new Money($decimal, $fallbackCurrency);
}
}

428
vendor/moneyphp/money/src/Teller.php vendored Normal file
View File

@@ -0,0 +1,428 @@
<?php
declare(strict_types=1);
namespace Money;
use function is_float;
final class Teller
{
use TellerFactory;
/**
* @param Money::ROUND_* $roundingMode
*/
public function __construct(
private readonly Currency $currency,
private readonly MoneyParser $parser,
private readonly MoneyFormatter $formatter,
private readonly int $roundingMode = Money::ROUND_HALF_UP
) {
}
/**
* Are two monetary amounts equal to each other?
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function equals(mixed $amount, mixed $other): bool
{
return $this->convertToMoney($amount)->equals(
$this->convertToMoney($other)
);
}
/**
* Returns an integer less than, equal to, or greater than zero if a
* monetary amount is respectively less than, equal to, or greater than
* another.
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function compare(mixed $amount, mixed $other): int
{
return $this->convertToMoney($amount)->compare(
$this->convertToMoney($other)
);
}
/**
* Is one monetary amount greater than another?
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function greaterThan(mixed $amount, mixed $other): bool
{
return $this->convertToMoney($amount)->greaterThan(
$this->convertToMoney($other)
);
}
/**
* Is one monetary amount greater than or equal to another?
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function greaterThanOrEqual(mixed $amount, mixed $other): bool
{
return $this->convertToMoney($amount)->greaterThanOrEqual(
$this->convertToMoney($other)
);
}
/**
* Is one monetary amount less than another?
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function lessThan(mixed $amount, mixed $other): bool
{
return $this->convertToMoney($amount)->lessThan(
$this->convertToMoney($other)
);
}
/**
* Is one monetary amount less than or equal to another?
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function lessThanOrEqual(mixed $amount, mixed $other): bool
{
return $this->convertToMoney($amount)->lessThanOrEqual(
$this->convertToMoney($other)
);
}
/**
* Adds a series of monetary amounts to each other in sequence.
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
* @param mixed $others subsequent other monetary amounts
*
* @return string the calculated monetary amount
*/
public function add(mixed $amount, mixed $other, mixed ...$others): string
{
return $this->convertToString(
$this->convertToMoney($amount)->add(
$this->convertToMoney($other),
...$this->convertToMoneyArray($others)
)
);
}
/**
* Subtracts a series of monetary amounts from each other in sequence.
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
* @param mixed $others subsequent monetary amounts
*/
public function subtract(mixed $amount, mixed $other, mixed ...$others): string
{
return $this->convertToString(
$this->convertToMoney($amount)->subtract(
$this->convertToMoney($other),
...$this->convertToMoneyArray($others)
)
);
}
/**
* Multiplies a monetary amount by a factor.
*
* @param mixed $amount a monetary amount
* @param int|float|numeric-string $multiplier the multiplier
*/
public function multiply(mixed $amount, int|float|string $multiplier): string
{
$multiplier = is_float($multiplier) ? Number::fromFloat($multiplier) : Number::fromNumber($multiplier);
return $this->convertToString(
$this->convertToMoney($amount)->multiply(
(string) $multiplier,
$this->roundingMode
)
);
}
/**
* Divides a monetary amount by a divisor.
*
* @param mixed $amount a monetary amount
* @param int|float|numeric-string $divisor the divisor
*/
public function divide(mixed $amount, int|float|string $divisor): string
{
$divisor = is_float($divisor) ? Number::fromFloat($divisor) : Number::fromNumber($divisor);
return $this->convertToString(
$this->convertToMoney($amount)->divide(
(string) $divisor,
$this->roundingMode
)
);
}
/**
* Mods a monetary amount by a divisor.
*
* @param mixed $amount a monetary amount
* @param int|float|numeric-string $divisor the divisor
*/
public function mod(mixed $amount, int|float|string $divisor): string
{
$divisor = is_float($divisor) ? Number::fromFloat($divisor) : Number::fromNumber($divisor);
return $this->convertToString(
$this->convertToMoney($amount)->mod(
$this->convertToMoney((string) $divisor)
)
);
}
/**
* Allocates a monetary amount according to an array of ratios.
*
* @param mixed $amount a monetary amount
* @param non-empty-array<array-key, float|int> $ratios an array of ratios
*
* @return string[] the calculated monetary amounts
*/
public function allocate(mixed $amount, array $ratios): array
{
return $this->convertToStringArray(
$this->convertToMoney($amount)->allocate($ratios)
);
}
/**
* Allocates a monetary amount among N targets.
*
* @param mixed $amount a monetary amount
* @phpstan-param positive-int $n the number of targets
*
* @return string[] the calculated monetary amounts
*/
public function allocateTo(mixed $amount, int $n): array
{
return $this->convertToStringArray(
$this->convertToMoney($amount)->allocateTo($n)
);
}
/**
* Determines the ratio of one monetary amount to another.
*
* @param mixed $amount a monetary amount
* @param mixed $other another monetary amount
*/
public function ratioOf(mixed $amount, mixed $other): string
{
return $this->convertToString(
$this->convertToMoney($amount)->ratioOf(
$this->convertToMoney($other)
)
);
}
/**
* Returns an absolute monetary amount.
*
* @param mixed $amount a monetary amount
*/
public function absolute(mixed $amount): string
{
return $this->convertToString(
$this->convertToMoney($amount)->absolute()
);
}
/**
* Returns the negative of an amount; note that this will convert negative
* amounts to positive ones.
*
* @param mixed $amount a monetary amount
*/
public function negative(mixed $amount): string
{
return $this->convertToString(
$this->convertToMoney($amount)->negative()
);
}
/**
* Is a monetary amount equal to zero?
*
* @param mixed $amount a monetary amount
*/
public function isZero(mixed $amount): bool
{
return $this->convertToMoney($amount)->isZero();
}
/**
* Is a monetary amount greater than zero?
*
* @param mixed $amount a monetary amount
*/
public function isPositive(mixed $amount): bool
{
return $this->convertToMoney($amount)->isPositive();
}
/**
* Is a monetary amount less than zero?
*
* @param mixed $amount a monetary amount
*/
public function isNegative(mixed $amount): bool
{
return $this->convertToMoney($amount)->isNegative();
}
/**
* Returns the lowest of a series of monetary amounts.
*
* @param mixed $amount a monetary amount
* @param mixed ...$amounts additional monetary amounts
*/
public function min(mixed $amount, mixed ...$amounts): string
{
return $this->convertToString(
Money::min(
$this->convertToMoney($amount),
...$this->convertToMoneyArray($amounts)
)
);
}
/**
* Returns the highest of a series of monetary amounts.
*
* @param mixed $amount a monetary amount
* @param mixed ...$amounts additional monetary amounts
*/
public function max(mixed $amount, mixed ...$amounts): string
{
return $this->convertToString(
Money::max(
$this->convertToMoney($amount),
...$this->convertToMoneyArray($amounts)
)
);
}
/**
* Returns the sum of a series of monetary amounts.
*
* @param mixed $amount a monetary amount
* @param mixed ...$amounts additional monetary amounts
*/
public function sum(mixed $amount, mixed ...$amounts): string
{
return $this->convertToString(
Money::sum(
$this->convertToMoney($amount),
...$this->convertToMoneyArray($amounts)
)
);
}
/**
* Returns the average of a series of monetary amounts.
*
* @param mixed $amount a monetary amount
* @param mixed ...$amounts additional monetary amounts
*/
public function avg(mixed $amount, mixed ...$amounts): string
{
return $this->convertToString(
Money::avg(
$this->convertToMoney($amount),
...$this->convertToMoneyArray($amounts)
)
);
}
/**
* Converts a monetary amount to a Money object.
*
* @param mixed $amount a monetary amount
*/
public function convertToMoney(mixed $amount): Money
{
return $this->parser->parse((string) $amount, $this->currency);
}
/**
* Converts an array of monetary amounts to an array of Money objects.
*
* @param array<int|string, mixed> $amounts an array of monetary amounts
*
* @return Money[]
*/
public function convertToMoneyArray(array $amounts): array
{
$converted = [];
/** @var mixed $amount */
foreach ($amounts as $key => $amount) {
$converted[$key] = $this->convertToMoney($amount);
}
return $converted;
}
/**
* Converts a monetary amount into a Money object, then into a string.
*
* @param mixed $amount typically a Money object, int, float, or string
* representing a monetary amount
*/
public function convertToString(mixed $amount): string
{
if ($amount instanceof Money === false) {
$amount = $this->convertToMoney($amount);
}
return $this->formatter->format($amount);
}
/**
* Converts an array of monetary amounts into Money objects, then into
* strings.
*
* @param array<int|string, mixed> $amounts an array of monetary amounts
*
* @return string[]
*/
public function convertToStringArray(array $amounts): array
{
$converted = [];
/** @var mixed $amount */
foreach ($amounts as $key => $amount) {
$converted[$key] = $this->convertToString($amount);
}
return $converted;
}
/**
* Returns a "zero" monetary amount.
*/
public function zero(): string
{
return '0.00';
}
}

View File

@@ -0,0 +1,629 @@
<?php
declare(strict_types=1);
namespace Money;
use Money\Currencies\ISOCurrencies;
use Money\Formatter\DecimalMoneyFormatter;
use Money\Parser\DecimalMoneyParser;
use function array_shift;
/**
* This is a generated file. Do not edit it manually!
*
* @method static Teller ONETHOUSANDCAT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONETHOUSANDCHEEMS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONETHOUSANDSATS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONEINCH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONEMBABYDOGE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller A(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AAVE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ACA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ACE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ACH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ACM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ACT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ACX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ADA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ADX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AED(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AEUR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AEVO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AFN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AGLD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AIXBT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALCX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALGO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALICE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALPHA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALPINE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ALT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AMD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AMP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ANIME(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ANKR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AOA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller APE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller API3(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller APT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ARB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ARDR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ARK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ARKM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ARPA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ARS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ASR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ASTR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ATA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ATM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ATOM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AUCTION(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AUD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AUDIO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AVA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AVAX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AWE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AWG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AXL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AXS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller AZN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BABY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BAKE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BAM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BANANA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BANANAS31(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BAND(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BAR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BAT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BBD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BCH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BDT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BEAMX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BEL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BERA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BGN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BHD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BICO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BIF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BIFI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BIGTIME(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BIO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BLUR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BMD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BMT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BNB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BND(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BNSOL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BNT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BOB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BOME(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BONK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BOV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BRL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BROCCOLI714(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BSD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BSW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BTC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BTN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BTTC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BWP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BYN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller BZD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller C98(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CAD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CAKE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CATI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CDF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CELO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CELR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CETUS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CFX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CGPT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CHE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CHESS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CHF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CHR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CHW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CHZ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CITY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CKB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CLF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CLP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CNY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COMP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COOKIE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COTI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller COW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CRC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CRV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CTK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CTSI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CUP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CVC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CVE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CVX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CYBER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller CZK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller D(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DAI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DASH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DATA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DCR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DEGO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DENT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DEXE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DGB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DIA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DJF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DKK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DODO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DOGE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DOGS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DOP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DOT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DUSK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DYDX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DYM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller DZD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EDU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EGLD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EGP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EIGEN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ENA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ENJ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ENS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EPIC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ERN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ETB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ETC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ETH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ETHFI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EUR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller EURI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FARM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FDUSD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FET(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FIDA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FIL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FIO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FIS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FJD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FKP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FLM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FLOKI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FLOW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FLUX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FORM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FORTH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FTT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FUN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller FXS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller G(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GALA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GAS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GBP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GEL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GHS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GHST(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GIP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GLM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GLMR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GMD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GMT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GMX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GNF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GNO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GNS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GPS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GRT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GTC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GTQ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GUN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller GYD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HAEDAL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HBAR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HEI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HFT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HIFI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HIGH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HIVE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HKD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HMSTR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HNL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HOOK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HOT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HTG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HUF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HUMA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller HYPER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ICP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ICX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ID(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IDEX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IDR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ILS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ILV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IMX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller INIT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller INJ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller INR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IOST(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IOTA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IOTX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IQ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IQD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller IRR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ISK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JASMY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JMD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JOD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JOE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JPY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JST(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JTO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JUP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller JUV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KAIA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KAITO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KAVA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KDA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KERNEL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KES(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KGS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KHR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KMD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KMF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KMNO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KNC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KPW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KRW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KSM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KWD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KYD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller KZT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LAK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LAYER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LAZIO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LBP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LDO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LEVER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LINK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LISTA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LKR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LOKA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LPT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LQTY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LRC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LRD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LSK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LSL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LTC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LTO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LUMIA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LUNA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LUNC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller LYD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MAD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MAGIC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MANA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MANTA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MASK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MAV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MBL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MBOX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MDL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MDT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ME(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MEME(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller METIS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MGA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MINA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MKD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MKR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MLN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MMK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MNT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MOP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MOVE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MOVR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MRU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MTL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MUBARAK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MUR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MVR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MWK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MXN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MXV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MYR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller MZN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NAD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NEAR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NEIRO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NEO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NEXO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NFP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NGN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NIL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NIO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NKN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NMR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NOK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NOT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NPR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NTRN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NXPC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller NZD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OGN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OMNI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OMR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONDO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ONT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ORCA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ORDI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OSMO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller OXT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PAB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PARTI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PAXG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PEN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PENDLE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PENGU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PEOPLE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PEPE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PERP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PGK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PHA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PHB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PHP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PIVX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PIXEL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PKR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PLN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PNUT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller POL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller POLYX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller POND(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PORTAL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PORTO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller POWR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PROM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PSG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PUNDIX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PYG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PYR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller PYTH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller QAR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller QI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller QKC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller QNT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller QTUM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller QUICK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RAD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RARE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RAY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RDNT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RED(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller REI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RENDER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller REQ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller REZ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RIF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RLC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RON(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RONIN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ROSE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RPL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RSD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RSR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RUB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RUNE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RVN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller RWF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller S(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SAGA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SAND(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SANTOS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SAR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SBD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SCR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SCRT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SDG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SEI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SEK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SFP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SGD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SHELL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SHIB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SHP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SIGN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SKL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SLE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SLF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SLP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SNX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SOL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SOLV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SOPH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SOS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SPELL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SRD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SSP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SSV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STEEM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STORJ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STRAX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STRK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller STX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SUI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SUN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SUPER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SUSHI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SVC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SXP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SXT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SYN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SYP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SYRUP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SYS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller SZL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller T(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TAO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TFUEL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller THB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller THE(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller THETA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TIA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TJS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TKO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TLM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TMT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TND(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TNSR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TON(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TOP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TRB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TRU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TRUMP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TRX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TRY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TST(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TTD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TURBO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TUSD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TUT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TWD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TWT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller TZS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UAH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UGX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UMA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UNI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USD1(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USDC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USDP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USDT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USTC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller USUAL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UTK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UYI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UYU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UYW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller UZS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VANA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VANRY(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VED(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VELODROME(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VES(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VET(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VIC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VIRTUAL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VND(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VOXEL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VTHO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller VUV(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller W(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WAN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WAXP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WBETH(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WBTC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WCT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WIF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WIN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WLD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WOO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller WST(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XAD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XAF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XAG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XAI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XAU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XBA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XBB(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XBC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XBD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XBT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XCD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XCG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XDR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XEC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XLM(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XNO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XOF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XPD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XPF(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XPT(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XRP(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XSU(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XTS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XTZ(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XUA(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XUSD(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XVG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XVS(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller XXX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller YER(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller YFI(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller YGG(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZAR(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZEC(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZEN(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZIL(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZK(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZMW(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZRO(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZRX(int $roundingMode = Money::ROUND_HALF_UP)
* @method static Teller ZWG(int $roundingMode = Money::ROUND_HALF_UP)
* @psalm-immutable
*/
trait TellerFactory
{
/**
* Convenience factory method for a Teller object.
*
* <code>
* $teller = Teller::USD();
* </code>
*
* @param non-empty-string $method
* @param array{0?: Money::ROUND_*} $arguments
*/
public static function __callStatic(string $method, array $arguments): Teller
{
$currency = new Currency($method);
$currencies = new ISOCurrencies();
$parser = new DecimalMoneyParser($currencies);
$formatter = new DecimalMoneyFormatter($currencies);
$roundingMode = empty($arguments)
? Money::ROUND_HALF_UP
: (int) array_shift($arguments);
return new Teller(
$currency,
$parser,
$formatter,
$roundingMode
);
}
}