Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor code to improve readability and maintainability #13

Merged
merged 7 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

strategy:
matrix:
php-versions: ['7.2', '7.3', '7.4', '8.0']
php-versions: ['8.2', '8.3']

runs-on: ubuntu-latest

Expand All @@ -35,4 +35,4 @@ jobs:
run: composer install --prefer-dist --no-progress --no-suggest

- name: Run test suite
run: vendor/bin/phpunit --verbose
run: vendor/bin/phpunit
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
.idea/
/vendor
/build
composer.lock
composer.lock
*.cache
*.bak
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
}
],
"require": {
"php": "^7.2|^8.0"
"php": "^8.2"
},
"autoload": {
"psr-4": {
"Luecano\\NumeroALetras\\": "src/"
}
},
"require-dev": {
"phpunit/phpunit": "^8.5|^9.0"
"phpunit/phpunit": "^11.0"
}
}
26 changes: 7 additions & 19 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,20 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnError="false"
stopOnFailure="false"
verbose="true"
>
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
</phpunit>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnError="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.3/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<testsuites>
<testsuite name="Test Suite">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
</phpunit>
157 changes: 100 additions & 57 deletions src/NumeroALetras.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ class NumeroALetras
{
/**
* @var array
*
* 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 +41,11 @@ class NumeroALetras
];

/**
* @var array
* @var array 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 +60,9 @@ class NumeroALetras
];

/**
* @var array
* Array of strings representing the hundreds in Spanish.
*
* @var string[]
*/
private $centenas = [
'CIENTO ',
Expand All @@ -64,6 +77,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 +92,28 @@ class NumeroALetras
];

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

/**
* @var bool
*
* 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.
* Converts a numeric value to its word representation.
*
* @param int|float $number
* @param int $decimals
* @param float|int $number The number to be converted.
* @param int $decimals The number of decimal places to consider. Default is 2.
*
* @return string
* @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,20 @@ 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
* @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
* @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 +158,34 @@ 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.
* Converts a number to its string representation.
*
* @param int|float $number
* @param int $decimals
* @param string $whole_str
* @param string $decimal_str
* @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
* @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.
* Converts a number to its invoice representation in words.
*
* @param int|float $number
* @param int $decimals
* @param string $currency
* @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
* @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 +201,35 @@ 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 +241,39 @@ private function wholeNumber($number)
}

/**
* Concatena las partes formateadas del número convertido.
* Concatenates an array of strings with a connector.
*
* 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.
*
* @param array $splitNumber
* @param array $splitNumber The array of strings to concatenate.
*
* @return string
* @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.
*
* @throws ParseError If the number is less than 0 or greater than 999,999,999.
*
* @return string The number converted into Spanish words.
*/
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 +309,34 @@ 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.
*
* @param string $n The group of numbers to be converted.
*
* @return string
* @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
Loading
Loading