Desde hace tiempo quería compartir con ustedes esta pequeña clase en PHP que nos permite obtener la cantidad con letras de un número dado. Esta clase la escribi en PHP a partir de una macro que encontré hace tiempo escrita para Excel y que solíamos utilizar hace tiempo en ese programa para elaborar nuestras facturas sin tener que estar escribiendo la cantidad con letras.
El código lo pueden encontrar a continuación o bien descargar Numero2Text.zip.
<?php
/********************************************************
* Numero2Texto convierte un numero a una cadena
* de texto que indica con palabras la cantidad que
* representa el numero.
*
* El script se baso en el trabajo realizado por:
* César Castro
* Enero-97
* http://chamarrasdepiel.com/SrExcel.html
* para un libro de excel.
*
* La funcionalidad para PHP fue realizada por
* Gerardo Gonzalez Flores, 2007
* gerardo@clic.com.mx
*
*
* 'Optional Fraccion_Letras = False, _
* 'Optional Fraccion = "", _
* 'Optional Texto_Inicial = "", _
* 'Optional Texto_Final = "", _
* 'Optional Estilo = 1)
*
**********************************************************/
class Numero2Texto extends Object{
/*****************************************************************************
'-- Funcion principal para convertir el numero en texto --
'-- Argumentos: --
'-- $numero = Valor que deseamos convertir en texto --
'-- $moneda = es el nombre de la moneda a mostrar --
'-- $fraccionLetras = Verdadero para que la fraccion de la moneda --
'-- tambien la convierta a letras --
'-- $fraccion = Es el nombre de la fraccion de la moneda --
'-- $textoInicial = Cualquier texto que quieras al principio del resultado --
'-- $texto_Final = Cualquier texto que quieras al final del resultado --
'-- $estilo = Formato de salida --
'-- 1 = MAYUSCULAS --
'-- 2 = minusculas --
'-- 3 = Tipo Titulo (no habilitada por el momento) --
'-- Los valores negativos los convierte a positivos --
'-- El valor minimo en 0, el valor maximo es 9,999,999,999,999.99 --
******************************************************************************/
function numeroTexto($numero, $moneda = 'peso' , $fraccionLetras = true, $fraccion = ' centavo', $textoInicial = "", $textoFinal="", $estilo = 2){
$strLetras = "";
$numTmp = "";
$intFraccion = "";
$strLetras = $textoInicial;
//'Convertimos a positivo si es negativo
$numero = abs($numero);
$numTmp = $this->format($numero, "000000000000000.00");
if($numero < 1 ){
$strLetras = $strLetras . "cero " . $this->plural($moneda) . " ";
}else{
$strLetras = $strLetras . $this->numLet($this->val(substr($numTmp, 0, 15)));
if($this->val($numTmp) == 1 || $this->val($numTmp) <= 2)
{
$strLetras = $strLetras . $moneda . " ";
}elseif($this->val(substr($numTmp, 3, 12)) == 0 || $this->val(substr($numTmp, 9, 6)) == 0){
$strLetras = $strLetras . "de " . $this->plural($moneda) . " ";
}else{
$strLetras = $strLetras . $this->plural($moneda) . " ";
}
}
if($fraccionLetras){
$intFraccion = $this->val(substr($numTmp, strlen($numTmp)-2, 2));
switch($intFraccion){
case 0:
$strLetras = $strLetras . "con cero " . $this->plural($fraccion);
break;
case 1:
$strLetras = $strLetras . "con un " . $fraccion;
break;
default:
// se podra usar intFraccion?
//-->strLetras = strLetras + "con " + numLet($intFraccion) + $this->plural($fraccion);
$strLetras = $strLetras . "con " . $this->numLet(substr($numTmp, strlen($numTmp)-2, 2)) . $this->plural($fraccion);
}
}else{
// se podra usar intFraccion?
//-->$strLetras = $strLetras + $intFraccion;
$strLetras = $strLetras . substr($numTmp, strlen($numTmp)-2, 2) . '/100';
}
$strLetras = $strLetras . $textoFinal;
switch($estilo){
case 1:
$strLetras = strtoupper($strLetras);
break;
case 2:
$strLetras = strtolower($strLetras);
break;
case 3:
$strLetras = strtolower(strLetras); //'StrConv(strLetras, vbPropercase);
break;
}
return $strLetras;
}
function numLet($numero ) {
$numTmp = "";
$co1 = "";
$co2 = "";
$pos = "";
$dig = "";
$cen = "";
$dec = "";
$uni = "";
$letra1 = "";
$letra2 = "";
$letra3 = "";
$leyenda = "";
$tFNumero = "";
$numTmp = $this->format($numero, "000000000000000"); // 'Le da un formato fijo
$co1 = 1;
$pos = 0;
//'Para extraer tres digitos cada vez
while($co1 <= 5){
$co2 = 1;
while($co2 <= 3){
//'Extrae un digito cada vez de izquierda a derecha
$dig = $this->val(substr($numTmp, $pos, 1));
switch($co2){
case 1: $cen = $dig+0; break;
case 2: $dec = $dig+0; break;
case 3: $uni = $dig+0; break;
}
$co2++;
$pos++;
}
$letra3 = $this->centena($uni, $dec, $cen);
$letra2 = $this->decena($uni, $dec);
$letra1 = $this->unidad($uni, $dec);
switch($co1){
case 1:
if(($cen + $dec + $uni) == 1 ){
$leyenda = "billon ";
}elseif(($cen + $dec + $uni) > 1){
$leyenda = "billones ";
}
break;
case 2:
if(($cen + $dec + $uni >= 1) && $this->val(substr($numTmp, 6, 3)) == 0){
$leyenda = "mil millones ";
}elseif($cen + $dec + $uni >= 1){
$leyenda = "mil ";
}
break;
case 3:
if(($cen + $dec == 0) && ($uni == 1)){
$leyenda = "millon ";
}elseif(($cen > 0) || ($dec > 0) || ($uni > 1)){
$leyenda = "millones ";
}
break;
case 4:
if(($cen + $dec + $uni) >= 1){
$leyenda = "mil ";
}
break;
case 5:
if($cen + $dec + $uni >= 1){
$leyenda = "";
}
break;
}
$co1++;
$tFNumero = $tFNumero . $letra3 . $letra2 . $letra1 . $leyenda;
$leyenda = "";
$letra1 = "";
$letra2 = "";
$letra3 = "";
}//fin while
return $tFNumero;
}
function centena($uni , $dec , $cen) {
$cTexto = "";
switch($cen){
case 1:
if(($dec + $uni) == 0){
$cTexto = "cien ";
}else{
$cTexto = "ciento ";
}
break;
case 2: $cTexto = "doscientos "; break;
case 3: $cTexto = "trescientos "; break;
case 4: $cTexto = "cuatrocientos "; break;
case 5: $cTexto = "quinientos "; break;
case 6: $cTexto = "seiscientos "; break;
case 7: $cTexto = "setecientos "; break;
case 8: $cTexto = "ochocientos "; break;
case 9: $cTexto = "novecientos "; break;
default: $cTexto = "";
}
return $cTexto;
}
function decena($uni , $dec ){
$cTexto = "";
switch($dec){
case 1:
switch($uni){
case 0: $cTexto = "diez "; break;
case 1: $cTexto = "once "; break;
case 2: $cTexto = "doce "; break;
case 3: $cTexto = "trece "; break;
case 4: $cTexto = "catorce "; break;
case 5: $cTexto = "quince "; break;
case 6: $cTexto = "dieci"; break;
case 7: $cTexto = "dieci"; break;
case 8: $cTexto = "dieci"; break;
case 9: $cTexto = "dieci"; break;
}
break;
case 2:
if($uni == 0){
$cTexto = "veinte ";
}elseif($uni > 0){
$cTexto = "veinti";
}
break;
case 3: $cTexto = "treinta "; break;
case 4: $cTexto = "cuarenta "; break;
case 5: $cTexto = "cincuenta "; break;
case 6: $cTexto = "sesenta "; break;
case 7: $cTexto = "setenta "; break;
case 8: $cTexto = "ochenta "; break;
case 9: $cTexto = "noventa "; break;
default: $cTexto = "";
}
$cTexto = $uni > 0 && $dec > 2 ? $cTexto . "y " : $cTexto;
return $cTexto;
}
function unidad($uni, $dec){
$cTexto = "";
if($dec != 1){
switch($uni){
case 1: $cTexto = "un "; break;
case 2: $cTexto = "dos "; break;
case 3: $cTexto = "tres "; break;
case 4: $cTexto = "cuatro "; break;
case 5: $cTexto = "cinco "; break;
}
}
switch($uni){
case 6: $cTexto = "seis "; break;
case 7: $cTexto = "siete "; break;
case 8: $cTexto = "ocho "; break;
case 9: $cTexto = "nueve "; break;
}
return $cTexto;
}
//'Funcion que convierte al plural el argumento pasado
function plural($palabra) {
$pos = "";
$strPal = "";
if(strlen(trim($palabra)) > 0){
$pos = strpos("aeiou", substr($palabra, -1, 1));
if($pos > 0){
$strPal = $palabra . "s";
}else{
$strPal = $palabra . "es";
}
}
return $strPal;
}
//'--- Pequeños Hacks para funciones que no tenemos disponibles en VbScript ---
function format($cadena, $formato){
$arr = "";
$entero = "";
$decimal = "";
if(!is_numeric($cadena)){
$cadena = 0;
}
$cadena = number_format($cadena, 2);
if(substr_count($formato, ".") == 1){
// Indispensables [] para detectat los siguientes caracteres / . -
$arr = split("[.]", $formato);
$entero = trim($arr[0]);
$decimal = trim($arr[1]);
}else{
$entero = $formato;
}
//--Eliminamos la coma
$cadena = str_replace(",","",$cadena);
// Crea una cadena standar con ceros a la izquierda (podria usarse sprintf?)
$cadena = substr($entero, 0, (strlen($entero)-(strlen($cadena)-3))) . $cadena;
return $cadena;
}
function val($parametro){
$parametro = trim($parametro);
if((!empty($parametro) && $parametro!="" && !is_null($parametro)) && is_numeric($parametro)){
$parametro = $parametro * 1;
}else{
$parametro = 0;
}
return $parametro;
}
}
?>
El uso es bastante sencillo como lo demuestro a continuación:
$num2Texto = new Numero2Texto(); $num2Texto->numeroTexto($numero, $moneda, $fraccionLetras, $fraccion, $textoInicial, $textoFinal, $estilo)