1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 00:11:35 +02:00
invoiceninja/app/Utils/Number.php

249 lines
7.7 KiB
PHP
Raw Normal View History

2019-08-28 04:36:53 +02:00
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
2019-08-28 04:36:53 +02:00
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
2022-04-27 05:20:41 +02:00
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
2019-08-28 04:36:53 +02:00
*
2021-06-16 08:58:16 +02:00
* @license https://www.elastic.co/licensing/elastic-license
2019-08-28 04:36:53 +02:00
*/
namespace App\Utils;
2021-03-17 16:12:25 +01:00
use App\Models\Company;
2019-10-07 12:21:02 +02:00
use App\Models\Currency;
use App\Models\Vendor;
2019-08-28 04:36:53 +02:00
/**
* Class Number.
*/
class Number
{
/**
* @param float $value
* @param int $precision
*
* @return float
*/
public static function roundValue(float $value, int $precision = 2) : float
{
return round($value, $precision, PHP_ROUND_HALF_UP);
}
/**
* Formats a given value based on the clients currency.
*
2020-08-26 02:47:50 +02:00
* @param float $value The number to be formatted
2019-08-28 04:36:53 +02:00
* @param object $currency The client currency object
*
2020-08-26 02:47:50 +02:00
* @return string The formatted value
2019-08-28 04:36:53 +02:00
*/
2020-08-26 02:47:50 +02:00
public static function formatValue($value, $currency) :string
2019-08-28 04:36:53 +02:00
{
$value = floatval($value);
$thousand = $currency->thousand_separator;
$decimal = $currency->decimal_separator;
$precision = $currency->precision;
return number_format($value, $precision, $decimal, $thousand);
}
/**
* Formats a given value based on the clients currency.
*
* @param float $value The number to be formatted
*
* @return string The formatted value
*/
public static function formatValueNoTrailingZeroes($value, $entity) :string
{
$value = floatval($value);
$currency = $entity->currency();
$thousand = $currency->thousand_separator;
$decimal = $currency->decimal_separator;
// $precision = $currency->precision;
if ($entity instanceof Company) {
$country = $entity->country();
} else {
$country = $entity->country;
}
/* Country settings override client settings */
if (isset($country->thousand_separator) && strlen($country->thousand_separator) >= 1) {
$thousand = $country->thousand_separator;
}
if (isset($country->decimal_separator) && strlen($country->decimal_separator) >= 1) {
$decimal = $country->decimal_separator;
}
2022-02-26 04:04:05 +01:00
$precision = 10;
return rtrim(rtrim(number_format($value, $precision, $decimal, $thousand), '0'), $decimal);
}
2020-08-26 02:47:50 +02:00
/**
* Formats a given value based on the clients currency
* BACK to a float.
2020-08-26 02:47:50 +02:00
*
2020-10-28 11:10:49 +01:00
* @param string $value The formatted number to be converted back to float
2020-08-26 02:47:50 +02:00
* @return float The formatted value
*/
public static function parseFloat($value)
{
// convert "," to "."
$s = str_replace(',', '.', $value);
// remove everything except numbers and dot "."
$s = preg_replace("/[^0-9\.]/", '', $s);
2020-08-26 02:47:50 +02:00
if ($s < 1) {
return (float) $s;
}
2021-09-24 12:55:21 +02:00
2022-08-21 23:53:15 +02:00
// remove all separators from first part and keep the end
$s = str_replace('.', '', substr($s, 0, -3)).substr($s, -3);
2020-08-26 02:47:50 +02:00
// return float
return (float) $s;
}
2020-12-20 10:02:10 +01:00
public static function parseStringFloat($value)
{
$value = preg_replace('/[^0-9-.]+/', '', $value);
// check for comma as decimal separator
if (preg_match('/,[\d]{1,2}$/', $value)) {
$value = str_replace(',', '.', $value);
}
$value = preg_replace('/[^0-9\.\-]/', '', $value);
return floatval($value);
}
2021-03-17 16:12:25 +01:00
2019-08-28 04:36:53 +02:00
/**
* Formats a given value based on the clients currency AND country.
*
2020-10-28 11:10:49 +01:00
* @param floatval $value The number to be formatted
2021-03-17 16:12:25 +01:00
* @param $entity
2019-09-04 23:55:49 +02:00
* @return string The formatted value
2019-08-28 04:36:53 +02:00
*/
2021-03-17 16:12:25 +01:00
public static function formatMoney($value, $entity) :string
2019-08-28 04:36:53 +02:00
{
2021-03-17 16:12:25 +01:00
$currency = $entity->currency();
2019-10-07 12:21:02 +02:00
$thousand = $currency->thousand_separator;
$decimal = $currency->decimal_separator;
$precision = $currency->precision;
$code = $currency->code;
$swapSymbol = $currency->swap_currency_symbol;
2019-08-28 04:36:53 +02:00
2021-03-17 16:12:25 +01:00
// App\Models\Client::country() returns instance of BelongsTo.
// App\Models\Company::country() returns record for the country, that's why we check for the instance.
if ($entity instanceof Company) {
$country = $entity->country();
} else {
$country = $entity->country;
}
/* Country settings override client settings */
2021-03-17 16:12:25 +01:00
if (isset($country->thousand_separator) && strlen($country->thousand_separator) >= 1) {
$thousand = $country->thousand_separator;
}
2021-03-17 16:12:25 +01:00
if (isset($country->decimal_separator) && strlen($country->decimal_separator) >= 1) {
$decimal = $country->decimal_separator;
}
2021-03-17 16:12:25 +01:00
if (isset($country->swap_currency_symbol) && strlen($country->swap_currency_symbol) >= 1) {
$swapSymbol = $country->swap_currency_symbol;
}
2019-08-28 04:36:53 +02:00
$value = number_format($value, $precision, $decimal, $thousand);
$symbol = $currency->symbol;
2021-03-17 16:12:25 +01:00
if ($entity->getSetting('show_currency_code') === true && $currency->code == 'CHF') {
2020-12-08 21:35:26 +01:00
return "{$code} {$value}";
2021-03-17 16:12:25 +01:00
} elseif ($entity->getSetting('show_currency_code') === true) {
2019-08-28 04:36:53 +02:00
return "{$value} {$code}";
} elseif ($swapSymbol) {
return "{$value} ".trim($symbol);
2021-03-17 16:12:25 +01:00
} elseif ($entity->getSetting('show_currency_code') === false) {
2019-08-28 04:36:53 +02:00
return "{$symbol}{$value}";
} else {
return self::formatValue($value, $currency);
2019-08-28 04:36:53 +02:00
}
}
2022-01-08 10:16:21 +01:00
/**
2022-01-08 10:16:21 +01:00
* Formats a given value based on the clients currency AND country.
*
* @param floatval $value The number to be formatted
* @param $entity
* @return string The formatted value
*/
public static function formatMoneyNoRounding($value, $entity) :string
{
$currency = $entity->currency();
$thousand = $currency->thousand_separator;
$decimal = $currency->decimal_separator;
$precision = $currency->precision;
$code = $currency->code;
$swapSymbol = $currency->swap_currency_symbol;
if ($entity instanceof Company) {
$country = $entity->country();
} else {
$country = $entity->country;
}
/* Country settings override client settings */
if (isset($country->thousand_separator) && strlen($country->thousand_separator) >= 1) {
$thousand = $country->thousand_separator;
}
if (isset($country->decimal_separator) && strlen($country->decimal_separator) >= 1) {
$decimal = $country->decimal_separator;
}
if (isset($country->swap_currency_symbol) && strlen($country->swap_currency_symbol) >= 1) {
$swapSymbol = $country->swap_currency_symbol;
}
/* 08-01-2022 allow increased precision for unit price*/
$v = rtrim(sprintf('%f', $value), '0');
2022-02-20 08:07:05 +01:00
// $precision = strlen(substr(strrchr($v, $decimal), 1));
if ($v < 1) {
2022-02-20 08:07:05 +01:00
$precision = strlen($v) - strrpos($v, '.') - 1;
}
2022-02-20 05:49:31 +01:00
2022-02-20 08:07:05 +01:00
// if($precision == 1)
// $precision = 2;
2022-01-08 10:16:21 +01:00
$value = number_format($v, $precision, $decimal, $thousand);
$symbol = $currency->symbol;
if ($entity->getSetting('show_currency_code') === true && $currency->code == 'CHF') {
return "{$code} {$value}";
} elseif ($entity->getSetting('show_currency_code') === true) {
return "{$value} {$code}";
} elseif ($swapSymbol) {
return "{$value} ".trim($symbol);
} elseif ($entity->getSetting('show_currency_code') === false) {
return "{$symbol}{$value}";
} else {
return self::formatValue($value, $currency);
}
}
2019-08-28 04:36:53 +02:00
}