mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-01-11 17:58:41 +00:00
375 lines
8.1 KiB
PHP
375 lines
8.1 KiB
PHP
<?php
|
|
/**
|
|
* Orange Management
|
|
*
|
|
* PHP Version 7.2
|
|
*
|
|
* @package phpOMS\Localization
|
|
* @copyright Dennis Eichhorn
|
|
* @license OMS License 1.0
|
|
* @version 1.0.0
|
|
* @link http://website.orange-management.de
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace phpOMS\Localization;
|
|
|
|
/**
|
|
* Money class.
|
|
*
|
|
* @package phpOMS\Localization
|
|
* @license OMS License 1.0
|
|
* @link http://website.orange-management.de
|
|
* @since 1.0.0
|
|
*/
|
|
final class Money implements \Serializable
|
|
{
|
|
|
|
/**
|
|
* Max amount of decimals.
|
|
*
|
|
* @var int
|
|
* @since 1.0.0
|
|
*/
|
|
public const MAX_DECIMALS = 4;
|
|
|
|
/**
|
|
* Thousands separator.
|
|
*
|
|
* @var string
|
|
* @since 1.0.0
|
|
*/
|
|
private $thousands = ',';
|
|
|
|
/**
|
|
* Decimal separator.
|
|
*
|
|
* @var string
|
|
* @since 1.0.0
|
|
*/
|
|
private $decimal = '.';
|
|
|
|
/**
|
|
* Currency symbol position
|
|
*
|
|
* @var int
|
|
* @since 1.0.0
|
|
*/
|
|
private $position = 1;
|
|
|
|
/**
|
|
* Currency symbol.
|
|
*
|
|
* @var string
|
|
* @since 1.0.0
|
|
*/
|
|
private $symbol = ISO4217SymbolEnum::_USD;
|
|
|
|
/**
|
|
* Value.
|
|
*
|
|
* @var int
|
|
* @since 1.0.0
|
|
*/
|
|
private $value = 0;
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param float|int|string $value Value
|
|
* @param string $thousands Thousands separator
|
|
* @param string $decimal Decimal separator
|
|
* @param string $symbol Currency symbol
|
|
* @param int $position Symbol position
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function __construct($value = 0, string $thousands = ',', string $decimal = '.', string $symbol = '', int $position = 0)
|
|
{
|
|
$this->value = \is_int($value) ? $value : self::toInt((string) $value);
|
|
$this->thousands = $thousands;
|
|
$this->decimal = $decimal;
|
|
$this->symbol = $symbol;
|
|
$this->position = $position;
|
|
}
|
|
|
|
/**
|
|
* Money to int.
|
|
*
|
|
* @param string $value Money value
|
|
* @param string $thousands Thousands character
|
|
* @param string $decimal Decimal character
|
|
*
|
|
* @return int
|
|
*
|
|
* @throws \Exception this exception is thrown if an internal explode or substr error occurs
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public static function toInt(string $value, string $thousands = ',', string $decimal = '.') : int
|
|
{
|
|
$split = \explode($decimal, $value);
|
|
|
|
if ($split === false) {
|
|
throw new \Exception('Internal explode error.'); // @codeCoverageIgnore
|
|
}
|
|
|
|
$left = $split[0];
|
|
$left = \str_replace($thousands, '', $left);
|
|
$right = '';
|
|
|
|
if (\count($split) > 1) {
|
|
$right = $split[1];
|
|
}
|
|
|
|
$right = \substr($right, 0, self::MAX_DECIMALS);
|
|
if ($right === false) {
|
|
throw new \Exception('Internal substr error.'); // @codeCoverageIgnore
|
|
}
|
|
|
|
return ((int) $left) * 10 ** self::MAX_DECIMALS + (int) \str_pad($right, self::MAX_DECIMALS, '0');
|
|
}
|
|
|
|
/**
|
|
* Set localization.
|
|
*
|
|
* @param string $thousands Thousands separator
|
|
* @param string $decimal Decimal separator
|
|
* @param string $symbol Currency symbol
|
|
* @param int $position Symbol position
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function setLocalization(string $thousands = ',', string $decimal = '.', string $symbol = '', int $position = 0) : self
|
|
{
|
|
$this->thousands = $thousands;
|
|
$this->decimal = $decimal;
|
|
$this->symbol = $symbol;
|
|
$this->position = $position;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set value by string.
|
|
*
|
|
* @param string $value Money value
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function setString(string $value) : self
|
|
{
|
|
$this->value = self::toInt($value, $this->thousands, $this->decimal);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get money.
|
|
*
|
|
* @param int $decimals Precision
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function getCurrency(int $decimals = 2) : string
|
|
{
|
|
return ($this->position === 0 ? $this->symbol : '') . $this->getAmount($decimals) . ($this->position === 1 ? $this->symbol : '');
|
|
}
|
|
|
|
/**
|
|
* Get money.
|
|
*
|
|
* @param int $decimals Precision
|
|
*
|
|
* @return string
|
|
*
|
|
* @throws \Exception this exception is thrown if an internal substr error occurs
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function getAmount(int $decimals = 2) : string
|
|
{
|
|
$value = (string) \round($this->value, -self::MAX_DECIMALS + $decimals);
|
|
|
|
$left = \substr($value, 0, -self::MAX_DECIMALS);
|
|
$right = \substr($value, -self::MAX_DECIMALS);
|
|
if ($left === false || $right === false) {
|
|
throw new \Exception();
|
|
}
|
|
|
|
return ($decimals > 0) ? \number_format((float) $left, 0, $this->decimal, $this->thousands) . $this->decimal . \substr($right, 0, $decimals) : $left;
|
|
}
|
|
|
|
/**
|
|
* Add money.
|
|
*
|
|
* @param float|int|Money|string $value Value to add
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function add($value) : self
|
|
{
|
|
if (\is_string($value) || \is_float($value)) {
|
|
$this->value += self::toInt((string) $value, $this->thousands, $this->decimal);
|
|
} elseif (\is_int($value)) {
|
|
$this->value += $value;
|
|
} elseif ($value instanceof self) {
|
|
$this->value += $value->getInt();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get money value.
|
|
*
|
|
* @return int
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function getInt() : int
|
|
{
|
|
return $this->value;
|
|
}
|
|
|
|
/**
|
|
* Sub money.
|
|
*
|
|
* @param float|int|Money|string $value Value to subtract
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function sub($value) : self
|
|
{
|
|
if (\is_string($value) || \is_float($value)) {
|
|
$this->value -= self::toInt((string) $value, $this->thousands, $this->decimal);
|
|
} elseif (\is_int($value)) {
|
|
$this->value -= $value;
|
|
} elseif ($value instanceof self) {
|
|
$this->value -= $value->getInt();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Mult.
|
|
*
|
|
* @param float|int $value Value to multiply with
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function mult($value) : self
|
|
{
|
|
if (\is_float($value) || \is_int($value)) {
|
|
$this->value = (int) ($this->value * $value);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Div.
|
|
*
|
|
* @param float|int $value Value to divide by
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function div($value) : self
|
|
{
|
|
if (\is_float($value) || \is_int($value)) {
|
|
$this->value = (int) ($this->value / $value);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Abs.
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function abs() : self
|
|
{
|
|
$this->value = \abs($this->value);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Power.
|
|
*
|
|
* @param float|int $value Value to power
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function pow($value) : self
|
|
{
|
|
if (\is_float($value) || \is_int($value)) {
|
|
$this->value = (int) ($this->value ** $value);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Searialze.
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function serialize() : string
|
|
{
|
|
return (string) $this->getInt();
|
|
}
|
|
|
|
/**
|
|
* Unserialize.
|
|
*
|
|
* @param mixed $value Value to unserialize
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function unserialize($value) : void
|
|
{
|
|
$this->setInt((int) $value);
|
|
}
|
|
|
|
/**
|
|
* Set money value.
|
|
*
|
|
* @param int $value Value
|
|
*
|
|
* @return Money
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function setInt(int $value) : self
|
|
{
|
|
$this->value = $value;
|
|
|
|
return $this;
|
|
}
|
|
}
|