Skip to content

Commit

Permalink
Refactor code to improve readability and maintainability
Browse files Browse the repository at this point in the history
  • Loading branch information
lecano committed Oct 5, 2024
1 parent cef3040 commit 4953ee6
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 64 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.idea/
/vendor
/build
composer.lock
composer.lock
*.cache
165 changes: 102 additions & 63 deletions src/NumeroALetras.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@

class NumeroALetras
{

/**
* @var array
* @var array $unidades
*
* Array that contains the Spanish words for numbers from 0 to 20.
* Each index corresponds to the number it represents.
*
* Example:
* - $unidades[1] returns 'UNO '
* - $unidades[10] returns 'DIEZ '
*/
private $unidades = [
'',
Expand All @@ -34,7 +42,11 @@ class NumeroALetras
];

/**
* @var array
* @var array $decenas Array containing Spanish words for tens (decades).
*
* This array is used to convert numbers into their corresponding Spanish words
* for tens. The values represent the words for twenty, thirty, forty, fifty,
* sixty, seventy, eighty, ninety, and one hundred.
*/
private $decenas = [
'VEINTI',
Expand All @@ -49,7 +61,9 @@ class NumeroALetras
];

/**
* @var array
* Array of strings representing the hundreds in Spanish.
*
* @var string[]
*/
private $centenas = [
'CIENTO ',
Expand All @@ -64,6 +78,12 @@ class NumeroALetras
];

/**
* Array of exceptions for accented words.
*
* This array contains specific words that require accents in their
* representation. The key is the word without the accent, and the
* value is the word with the correct accent.
*
* @var array
*/
private $acentosExcepciones = [
Expand All @@ -73,24 +93,27 @@ class NumeroALetras
];

/**
* @var string
* @var string $conector The connector string used in the NumeroALetras class.
*/
public $conector = 'CON';

/**
* @var bool
* @var bool $apocope
*
* This property determines whether the apocope (shortened form) of numbers should be used.
* When set to true, the apocope form will be applied.
* Default value is false.
*/
public $apocope = false;

/**
* Formatea y convierte un número a letras.
*
* @param int|float $number
* @param int $decimals
* Converts a numeric value to its word representation.
*
* @return string
* @param float|int $number The number to be converted.
* @param int $decimals The number of decimal places to consider. Default is 2.
* @return string The word representation of the number.
*/
public function toWords($number, $decimals = 2)
public function toWords(float|int $number, int $decimals = 2): string
{
$this->checkApocope();

Expand All @@ -104,20 +127,19 @@ public function toWords($number, $decimals = 2)
$splitNumber[1] = $this->convertNumber($splitNumber[1]);
}

return $this->glue($splitNumber);
return $this->concat($splitNumber);
}

/**
* Formatea y convierte un número a letras en formato moneda.
* Converts a numeric value to its money representation in words.
*
* @param int|float $number
* @param int $decimals
* @param string $currency
* @param string $cents
*
* @return string
* @param float $number The numeric value to be converted.
* @param int $decimals The number of decimal places to consider. Default is 2.
* @param string $currency The currency to append to the whole number part. Default is an empty string.
* @param string $cents The currency to append to the decimal part. Default is an empty string.
* @return string The money representation of the number in words.
*/
public function toMoney($number, $decimals = 2, $currency = '', $cents = '')
public function toMoney(float $number, int $decimals = 2, string $currency = '', string $cents = ''): string
{
$this->checkApocope();

Expand All @@ -135,34 +157,32 @@ public function toMoney($number, $decimals = 2, $currency = '', $cents = '')
$splitNumber[1] .= ' ' . mb_strtoupper($cents, 'UTF-8');
}

return $this->glue($splitNumber);
return $this->concat($splitNumber);
}

/**
* Formatea y convierte un número a letras en formato libre.
*
* @param int|float $number
* @param int $decimals
* @param string $whole_str
* @param string $decimal_str
* Converts a number to its string representation.
*
* @return string
* @param float|int $number The number to be converted.
* @param int $decimals The number of decimal places to include in the string representation. Default is 2.
* @param string $whole_str The string to use for the whole number part. Default is an empty string.
* @param string $decimal_str The string to use for the decimal part. Default is an empty string.
* @return string The string representation of the number.
*/
public function toString($number, $decimals = 2, $whole_str = '', $decimal_str = '')
public function toString(float|int $number, int $decimals = 2, string $whole_str = '', string $decimal_str = ''): string
{
return $this->toMoney($number, $decimals, $whole_str, $decimal_str);
}

/**
* Formatea y convierte un número a letras en formato facturación electrónica.
*
* @param int|float $number
* @param int $decimals
* @param string $currency
* Converts a number to its invoice representation in words.
*
* @return string
* @param float $number The number to be converted.
* @param int $decimals The number of decimal places to consider. Default is 2.
* @param string $currency The currency to append to the converted number. Default is an empty string.
* @return string The number converted to its invoice representation in words, followed by the currency in uppercase.
*/
public function toInvoice($number, $decimals = 2, $currency = '')
public function toInvoice(float $number, int $decimals = 2, string $currency = ''): string
{
$this->checkApocope();

Expand All @@ -178,29 +198,34 @@ public function toInvoice($number, $decimals = 2, $currency = '')
$splitNumber[1] = '00/100 ';
}

return $this->glue($splitNumber) . mb_strtoupper($currency, 'UTF-8');
return $this->concat($splitNumber) . mb_strtoupper($currency, 'UTF-8');
}

/**
* Valida si debe aplicarse apócope de uno.
* Checks if the apocope flag is set to true and modifies the 'unidades' array accordingly.
*
* If the apocope flag is true, the value at index 1 of the 'unidades' array is set to 'UN '.
*
* @return void
*/
private function checkApocope()
private function checkApocope(): void
{
if ($this->apocope === true) {
$this->unidades[1] = 'UN ';
}
}

/**
* Formatea la parte entera del número a convertir.
* Converts a whole number to its corresponding word representation.
*
* @param string $number
* This method takes a numeric string and converts it to its word representation.
* If the number is '0', it returns 'CERO '. Otherwise, it uses the convertNumber
* method to convert the number.
*
* @return string
* @param string $number The numeric string to be converted.
* @return string The word representation of the number.
*/
private function wholeNumber($number)
private function wholeNumber(string $number): string
{
if ($number == '0') {
$number = 'CERO ';
Expand All @@ -212,30 +237,38 @@ private function wholeNumber($number)
}

/**
* Concatena las partes formateadas del número convertido.
* Concatenates an array of strings with a connector.
*
* @param array $splitNumber
* This method takes an array of strings, filters out any empty values,
* and then concatenates the remaining values using a connector string.
* The connector string is converted to uppercase using UTF-8 encoding.
*
* @return string
* @param array $splitNumber The array of strings to concatenate.
* @return string The concatenated string.
*/
private function glue($splitNumber)
private function concat(array $splitNumber): string
{
return implode(' ' . mb_strtoupper($this->conector, 'UTF-8') . ' ', array_filter($splitNumber));
}

/**
* Convierte número a letras.
* Converts a numeric value into its corresponding Spanish words representation.
*
* @param string $number
* This function handles numbers from 0 to 999,999,999. It divides the number into
* millions, thousands, and hundreds, and converts each group into words.
*
* @return string
* @param int $number The number to be converted. Must be between 0 and 999,999,999.
*
* @return string The number converted into Spanish words.
*
* @throws ParseError If the number is less than 0 or greater than 999,999,999.
*/
private function convertNumber($number)
private function convertNumber(int $number): string
{
$converted = '';

if (($number < 0) || ($number > 999999999)) {
throw new ParseError('Wrong parameter number');
if (($number < 0) || !is_numeric($number)) {
throw new ParseError('Invalid number');
}

$numberStrFill = str_pad($number, 9, '0', STR_PAD_LEFT);
Expand Down Expand Up @@ -271,29 +304,35 @@ private function convertNumber($number)
}

/**
* @param string $n
* Converts a group of numbers into its corresponding Spanish words representation.
*
* This function converts a group of numbers (from 0 to 999) into its corresponding
* Spanish words representation. It handles the hundreds, tens, and units of the group.
*
* @return string
* @param string $n The group of numbers to be converted.
*
* @return string The group of numbers converted into Spanish words.
*/
private function convertGroup($n)

private function convertGroup(string $group): string
{
$output = '';

if ($n == '100') {
if ($group == '100') {
$output = 'CIEN ';
} elseif ($n[0] !== '0') {
$output = $this->centenas[$n[0] - 1];
} elseif ($group[0] !== '0') {
$output = $this->centenas[$group[0] - 1];
}

$k = intval(substr($n, 1));
$k = intval(substr($group, 1));

if ($k <= 20) {
$unidades = $this->unidades[$k];
} else {
if (($k > 30) && ($n[2] !== '0')) {
$unidades = sprintf('%sY %s', $this->decenas[intval($n[1]) - 2], $this->unidades[intval($n[2])]);
if (($k > 30) && ($group[2] !== '0')) {
$unidades = sprintf('%sY %s', $this->decenas[intval($group[1]) - 2], $this->unidades[intval($group[2])]);
} else {
$unidades = sprintf('%s%s', $this->decenas[intval($n[1]) - 2], $this->unidades[intval($n[2])]);
$unidades = sprintf('%s%s', $this->decenas[intval($group[1]) - 2], $this->unidades[intval($group[2])]);
}
}

Expand Down

0 comments on commit 4953ee6

Please sign in to comment.