Skip to content

Instantly share code, notes, and snippets.

@ale10257
Last active July 6, 2019 08:20
Show Gist options
  • Save ale10257/03e03c10b8d674b2d447c5a15041c4fd to your computer and use it in GitHub Desktop.
Save ale10257/03e03c10b8d674b2d447c5a15041c4fd to your computer and use it in GitHub Desktop.
Сумма прописью для чека - ru
<?php
/**
* @author https://github.com/adamasantares
*/
namespace app\components\helpers;
class SumToCurrencyStrRu
{
public static function toPrice($number, $thousands_sep = "'")
{
$data = self::prepare($number);
$number = number_format($data['number'][0], 0, '.', $thousands_sep);
return $number . '.' . $data['penny'];
}
/**
* @param float|int|string $number
* @return string
*/
public static function toStr($number)
{
$words = [
'null' => 'ноль',
0 => '',
'_0' => '',
1 => 'один',
2 => 'два',
3 => 'три',
4 => 'четыре',
5 => 'пять',
6 => 'шесть',
7 => 'семь',
8 => 'восемь',
9 => 'девять',
'_1' => 'одна',
'_2' => 'две',
'_3' => 'три',
'_4' => 'четыре',
'_5' => 'пять',
'_6' => 'шесть',
'_7' => 'семь',
'_8' => 'восемь',
'_9' => 'девять',
11 => 'одиннадцать',
12 => 'двенадцать',
13 => 'тринадцать',
14 => 'четырнадцать',
15 => 'пятнадцать',
16 => 'шестнадцать',
17 => 'семнадцать',
18 => 'восемнадцать',
19 => 'девятнадцать',
10 => 'десять',
20 => 'двадцать',
30 => 'тридцать',
40 => 'сорок',
50 => 'пятьдесят',
60 => 'шестьдесят',
70 => 'семьдесят',
80 => 'восемьдесят',
90 => 'девяносто',
100 => 'сто',
200 => 'двести',
300 => 'триста',
400 => 'четыреста',
500 => 'пятьсот',
600 => 'шестьсот',
700 => 'семьсот',
800 => 'восемьсот',
900 => 'девятьсот',
'1_1' => ' тысяча',
'1_2' => ' тысячи',
'1_5' => ' тысяч',
'2_1' => ' миллион',
'2_2' => ' миллиона',
'2_5' => ' миллионов',
'3_1' => ' миллиард',
'3_2' => ' миллиарда',
'3_5' => ' миллиардов',
'0_1' => '',
'0_2' => '',
'0_5' => '',
'4_1' => '',
'4_2' => '',
'4_5' => '',
'5_1' => '',
'5_2' => '',
'5_5' => '',
'r1' => ' рубль',
'r2' => ' рубля',
'r5' => ' рублей',
'cp' => 'коп.'
];
$data = self::prepare($number);
$number = $data['number'];
$penny = $data['penny'];
$penny_num = intval($penny);
if (($penny_num > 10 && $penny_num < 20) || !($penny_num % 10) || ($penny_num % 10 > 4 && $penny_num % 10 < 10)) {
$penny_label = 'копеек';
} elseif ($penny_num % 10 == 1) {
$penny_label = 'копейка';
} else {
$penny_label = 'копейки';
}
$number = $number[0];
if (intval($number) == 0) {
$result = $words['null'];
} else {
$parts = str_split($number, 3);
while (strlen($parts[count($parts) - 1]) < 3) {
$number = '0' . $number;
$parts = str_split($number, 3);
}
$parts = array_reverse($parts);
foreach ($parts as $key => $part) {
$val = intval(substr($part, -2, 2));
if ($val > 10 && $val < 20) {
$label = $key . '_5';
$string = $words[$val];
$val = intval($part) - $val;
$string = $words[$val] . ' ' . $string;
} else {
list($a, $b, $c) = str_split($part);
$a *= 100;
$b *= 10;
$c *= 1;
$string = trim($words[$a] . ' ' . $words[$b] . ' ' . $words[($key == 1 ? '_' . $c : $c)]);
$label = $key . (($c == 1) ? '_1' : (($c > 1 && $c < 5) ? '_2' : '_5'));
}
$string .= $words[$label];
$parts[$key] = trim($string);
}
$parts = array_reverse($parts);
$result = implode(' ', $parts);
}
$c = intval(substr($number, -1, 1));
$label = (($c == 1) ? 'r1' : (($c > 1 && $c < 5) ? 'r2' : 'r5'));
$result .= $words[$label] . ' ' . $penny . ' ' . $penny_label;
return $result;
}
private static function prepare($number)
{
if (!is_numeric($number)) {
throw new \DomainException('Value ' . $number . ' is not a number!');
}
$number = str_replace(',', '.', '' . floatval($number));
$number = explode('.', $number);
$penny = substr((isset($number[1]) ? $number[1] . '0' : '00'), 0, 2);
return [
'number' => $number,
'penny' => $penny
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment