convert($hryvnias, ['гривня','гривні','гривень'], 'f'); $result .= ' '; $result .= $this->convert($kopecks, ['копійка','копійки','копійок'], 'f'); return $result; } private function convert(int $number, array $forms, string $gender): string { if ($number === 0) { return 'нуль ' . $forms[2]; } $result = []; $order = 0; while ($number > 0) { $chunk = $number % 1000; if ($chunk > 0) { $chunkGender = $order === 0 ? $gender : $this->orders[$order-1][1]; $words = $this->convertChunk($chunk, $chunkGender); $plural = $this->pluralForm($chunk); if ($order === 0) { $words[] = $forms[$plural]; } else { $words[] = $this->orders[$order-1][0][$plural]; } $result = array_merge($words, $result); } $number = intdiv($number, 1000); $order++; } return implode(' ', $result); } private function convertChunk(int $number, string $gender): array { $words = []; if ($number >= 100) { $words[] = $this->hundreds[intdiv($number,100)-1]; $number %= 100; } if ($number >= 10 && $number <= 19) { $words[] = $this->teens[$number-10]; return $words; } if ($number >= 20) { $words[] = $this->tens[intdiv($number,10)]; $number %= 10; } if ($number > 0) { if ($number == 1 || $number == 2) { $words[] = $this->units[$number][$gender === 'f' ? 1 : 0]; } else { $words[] = $this->units[$number][0]; } } return $words; } private function pluralForm(int $number): int { $number %= 100; if ($number >= 11 && $number <= 19) return 2; $number %= 10; if ($number == 1) return 0; if ($number >= 2 && $number <= 4) return 1; return 2; } public function moneyFormatted(float $amount): string { $amount = round($amount, 2); $hryvnias = floor($amount); $kopecks = (int)round(($amount - $hryvnias) * 100); $numberFormatted = number_format($amount, 2, ',', ' '); $textHryvnias = $this->convert( $hryvnias, ['','',''], 'f' ); $plural = $this->pluralForm($hryvnias); $forms = ['гривня','гривні','гривень']; return sprintf( "%s (%s) %s %02d копійок", $numberFormatted, $textHryvnias, $forms[$plural], $kopecks ); } }