Announcement

Collapse
No announcement yet.

Numero a letras, necesito imprimir en letras el total de una factura.... en repor PDR

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Numero a letras, necesito imprimir en letras el total de una factura.... en repor PDR

    SAludos necesito imprimir el total de una factura la cual la calculo agregando un campo y haciendo un select con un sum del los detalles agrupando por el id de la factura eso me funciona ese numero tengo que imprimirlo en letras en el reporte PDF

  • #2
    en el reporte pdf para imprimir la factura pon en el evento onrecord este codigo:

    function numtoletras($xcifra)
    {
    $xarray = array(0 => "Cero",
    1 => "UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE",
    "DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISEIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE",
    "VEINTI", 30 => "TREINTA", 40 => "CUARENTA", 50 => "CINCUENTA", 60 => "SESENTA", 70 => "SETENTA", 80 => "OCHENTA", 90 => "NOVENTA",
    100 => "CIENTO", 200 => "DOSCIENTOS", 300 => "TRESCIENTOS", 400 => "CUATROCIENTOS", 500 => "QUINIENTOS", 600 => "SEISCIENTOS", 700 => "SETECIENTOS", 800 => "OCHOCIENTOS", 900 => "NOVECIENTOS"
    );
    //
    $xcifra = trim($xcifra);
    $xlength = strlen($xcifra);
    $xpos_punto = strpos($xcifra, ".");
    $xaux_int = $xcifra;
    $xdecimales = "00";
    if (!($xpos_punto === false))
    {
    if ($xpos_punto == 0)
    {
    $xcifra = "0".$xcifra;
    $xpos_punto = strpos($xcifra, ".");
    }
    $xaux_int = substr($xcifra, 0, $xpos_punto); // obtengo el entero de la cifra a covertir
    $xdecimales = substr($xcifra."00", $xpos_punto + 1, 2); // obtengo los valores decimales
    }

    $XAUX = str_pad($xaux_int, 18, " ", STR_PAD_LEFT); // ajusto la longitud de la cifra, para que sea divisible por centenas de miles (grupos de 6)
    $xcadena = "";
    for($xz = 0; $xz < 3; $xz++)
    {
    $xaux = substr($XAUX, $xz * 6, 6);
    $xi = 0; $xlimite = 6; // inicializo el contador de centenas xi y establezco el límite a 6 dígitos en la parte entera
    $xexit = true; // bandera para controlar el ciclo del While
    while ($xexit)
    {
    if ($xi == $xlimite) // si ya llegó al límite máximo de enteros
    {
    break; // termina el ciclo
    }

    $x3digitos = ($xlimite - $xi) * -1; // comienzo con los tres primeros digitos de la cifra, comenzando por la izquierda
    $xaux = substr($xaux, $x3digitos, abs($x3digitos)); // obtengo la centena (los tres dígitos)
    for ($xy = 1; $xy < 4; $xy++) // ciclo para revisar centenas, decenas y unidades, en ese orden
    {
    switch ($xy)
    {
    case 1: // checa las centenas
    if (substr($xaux, 0, 3) < 100) // si el grupo de tres dígitos es menor a una centena ( < 99) no hace nada y pasa a revisar las decenas
    {
    }
    else
    {
    $xseek = $xarray[substr($xaux, 0, 3)]; // busco si la centena es número redondo (100, 200, 300, 400, etc..)
    if ($xseek)
    {
    $xsub = subfijo($xaux); // devuelve el subfijo correspondiente (Millón, Millones, Mil o nada)
    if (substr($xaux, 0, 3) == 100)
    $xcadena = " ".$xcadena." CIEN ".$xsub;
    else
    $xcadena = " ".$xcadena." ".$xseek." ".$xsub;
    $xy = 3; // la centena fue redonda, entonces termino el ciclo del for y ya no reviso decenas ni unidades
    }
    else // entra aquí si la centena no fue numero redondo (101, 253, 120, 980, etc.)
    {
    $xseek = $xarray[substr($xaux, 0, 1) * 100]; // toma el primer caracter de la centena y lo multiplica por cien y lo busca en el arreglo (para que busque 100,200,300, etc)
    $xcadena = " ".$xcadena." ".$xseek;
    } // ENDIF ($xseek)
    } // ENDIF (substr($xaux, 0, 3) < 100)
    break;
    case 2: // checa las decenas (con la misma lógica que las centenas)
    if (substr($xaux, 1, 2) < 10)
    {
    }
    else
    {
    $xseek = $xarray[substr($xaux, 1, 2)];
    if ($xseek)
    {
    $xsub = subfijo($xaux);
    if (substr($xaux, 1, 2) == 20)
    $xcadena = " ".$xcadena." VEINTE ".$xsub;
    else
    $xcadena = " ".$xcadena." ".$xseek." ".$xsub;
    $xy = 3;
    }
    else
    {
    $xseek = $xarray[substr($xaux, 1, 1) * 10];
    if (substr($xaux, 1, 1) * 10 == 20)
    $xcadena = " ".$xcadena." ".$xseek;
    else
    $xcadena = " ".$xcadena." ".$xseek." Y ";
    } // ENDIF ($xseek)
    } // ENDIF (substr($xaux, 1, 2) < 10)
    break;
    case 3: // checa las unidades
    if (substr($xaux, 2, 1) < 1) // si la unidad es cero, ya no hace nada
    {
    }
    else
    {
    $xseek = $xarray[substr($xaux, 2, 1)]; // obtengo directamente el valor de la unidad (del uno al nueve)
    $xsub = subfijo($xaux);
    $xcadena = " ".$xcadena." ".$xseek." ".$xsub;
    } // ENDIF (substr($xaux, 2, 1) < 1)
    break;
    } // END SWITCH
    } // END FOR
    $xi = $xi + 3;
    } // ENDDO

    if (substr(trim($xcadena), -5, 5) == "ILLON") // si la cadena obtenida termina en MILLON o BILLON, entonces le agrega al final la conjuncion DE
    $xcadena.= " DE";

    if (substr(trim($xcadena), -7, 7) == "ILLONES") // si la cadena obtenida en MILLONES o BILLONES, entoncea le agrega al final la conjuncion DE
    $xcadena.= " DE";

    // ----------- esta línea la puedes cambiar de acuerdo a tus necesidades o a tu país -------
    if (trim($xaux) != "")
    {
    switch ($xz)
    {
    case 0:
    if (trim(substr($XAUX, $xz * 6, 6)) == "1")
    $xcadena.= "UN BILLON ";
    else
    $xcadena.= " BILLONES ";
    break;
    case 1:
    if (trim(substr($XAUX, $xz * 6, 6)) == "1")
    $xcadena.= "UN MILLON ";
    else
    $xcadena.= " MILLONES ";
    break;
    case 2:
    if ($xcifra < 1 )
    {
    $xcadena = "CERO DOLARES $xdecimales/100 ";
    }
    if ($xcifra >= 1 && $xcifra < 2)
    {
    $xcadena = "UN DOLAR $xdecimales/100 ";
    }
    if ($xcifra >= 2)
    {
    $xcadena.= " DOLARES $xdecimales/100 "; //
    }
    break;
    } // endswitch ($xz)
    } // ENDIF (trim($xaux) != "")
    // ------------------ en este caso, para Ecuador se usa esta leyenda ----------------
    $xcadena = str_replace("VEINTI ", "VEINTI", $xcadena); // quito el espacio para el VEINTI, para que quede: VEINTICUATRO, VEINTIUN, VEINTIDOS, etc
    $xcadena = str_replace(" ", " ", $xcadena); // quito espacios dobles
    $xcadena = str_replace("UN UN", "UN", $xcadena); // quito la duplicidad
    $xcadena = str_replace(" ", " ", $xcadena); // quito espacios dobles
    $xcadena = str_replace("BILLON DE MILLONES", "BILLON DE", $xcadena); // corrigo la leyenda
    $xcadena = str_replace("BILLONES DE MILLONES", "BILLONES DE", $xcadena); // corrigo la leyenda
    $xcadena = str_replace("DE UN", "UN", $xcadena); // corrigo la leyenda
    } // ENDFOR ($xz)
    return trim($xcadena);
    } // END FUNCTION


    function subfijo($xx)
    { // esta función regresa un subfijo para la cifra
    $xx = trim($xx);
    $xstrlen = strlen($xx);
    if ($xstrlen == 1 || $xstrlen == 2 || $xstrlen == 3)
    $xsub = "";
    //
    if ($xstrlen == 4 || $xstrlen == 5 || $xstrlen == 6)
    $xsub = "MIL";
    //
    return $xsub;
    } // END FUNCTION

    $n = {fact_valor_total};
    $xx = numtoletras($n);
    {xletras} = $xx;

    //---------------------------------------------------------- hasta aqui solo copialo y pegalo ------------------------------------
    donde en mi caso, {fact_valor_total} es el campo de la tabla facturas donde guardo el valor total y simplemente con ese campo llamo a la funcion numtoletras
    la cual me devuelve en la variable $xx la cantidad en letras y luego esa variable la pongo en otro campo añadido a la factura pdf llamado xletras el cual lo imprimo donde deseo que salga dicha cantidad en letras.

    Saludos
    Aquiles
    Last edited by aquiles; 01-31-2014, 06:13 PM.

    Comment


    • #3
      Que tal Marianol, ojo si tu factura con subselect tiene que pasar a 2da pagina. Hay un bug ahí que estoy esperando que se dignen a solucionar.

      Saludos,

      PD: Muy buen aporte aquiles.

      Comment


      • #4
        Muchas gracias por el código que escribe el número con letras. Sin embargo, cuando lo utilizo, me marca este error cuando no son cantidades cerradas:
        "Undefined offset". Pueden ayudarme a solucionarlo por favor?
        Erika Dávalos

        Comment


        • #5
          Originally posted by aquiles View Post
          en el reporte pdf para imprimir la factura pon en el evento onrecord este codigo:

          function numtoletras($xcifra)
          {
          $xarray = array(0 => "Cero",
          1 => "UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE",
          "DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISEIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE",
          "VEINTI", 30 => "TREINTA", 40 => "CUARENTA", 50 => "CINCUENTA", 60 => "SESENTA", 70 => "SETENTA", 80 => "OCHENTA", 90 => "NOVENTA",
          100 => "CIENTO", 200 => "DOSCIENTOS", 300 => "TRESCIENTOS", 400 => "CUATROCIENTOS", 500 => "QUINIENTOS", 600 => "SEISCIENTOS", 700 => "SETECIENTOS", 800 => "OCHOCIENTOS", 900 => "NOVECIENTOS"
          );
          //
          $xcifra = trim($xcifra);
          $xlength = strlen($xcifra);
          $xpos_punto = strpos($xcifra, ".");
          $xaux_int = $xcifra;
          $xdecimales = "00";
          if (!($xpos_punto === false))
          {
          if ($xpos_punto == 0)
          {
          $xcifra = "0".$xcifra;
          $xpos_punto = strpos($xcifra, ".");
          }
          $xaux_int = substr($xcifra, 0, $xpos_punto); // obtengo el entero de la cifra a covertir
          $xdecimales = substr($xcifra."00", $xpos_punto + 1, 2); // obtengo los valores decimales
          }

          $XAUX = str_pad($xaux_int, 18, " ", STR_PAD_LEFT); // ajusto la longitud de la cifra, para que sea divisible por centenas de miles (grupos de 6)
          $xcadena = "";
          for($xz = 0; $xz < 3; $xz++)
          {
          $xaux = substr($XAUX, $xz * 6, 6);
          $xi = 0; $xlimite = 6; // inicializo el contador de centenas xi y establezco el límite a 6 dígitos en la parte entera
          $xexit = true; // bandera para controlar el ciclo del While
          while ($xexit)
          {
          if ($xi == $xlimite) // si ya llegó al límite máximo de enteros
          {
          break; // termina el ciclo
          }

          $x3digitos = ($xlimite - $xi) * -1; // comienzo con los tres primeros digitos de la cifra, comenzando por la izquierda
          $xaux = substr($xaux, $x3digitos, abs($x3digitos)); // obtengo la centena (los tres dígitos)
          for ($xy = 1; $xy < 4; $xy++) // ciclo para revisar centenas, decenas y unidades, en ese orden
          {
          switch ($xy)
          {
          case 1: // checa las centenas
          if (substr($xaux, 0, 3) < 100) // si el grupo de tres dígitos es menor a una centena ( < 99) no hace nada y pasa a revisar las decenas
          {
          }
          else
          {
          $xseek = $xarray[substr($xaux, 0, 3)]; // busco si la centena es número redondo (100, 200, 300, 400, etc..)
          if ($xseek)
          {
          $xsub = subfijo($xaux); // devuelve el subfijo correspondiente (Millón, Millones, Mil o nada)
          if (substr($xaux, 0, 3) == 100)
          $xcadena = " ".$xcadena." CIEN ".$xsub;
          else
          $xcadena = " ".$xcadena." ".$xseek." ".$xsub;
          $xy = 3; // la centena fue redonda, entonces termino el ciclo del for y ya no reviso decenas ni unidades
          }
          else // entra aquí si la centena no fue numero redondo (101, 253, 120, 980, etc.)
          {
          $xseek = $xarray[substr($xaux, 0, 1) * 100]; // toma el primer caracter de la centena y lo multiplica por cien y lo busca en el arreglo (para que busque 100,200,300, etc)
          $xcadena = " ".$xcadena." ".$xseek;
          } // ENDIF ($xseek)
          } // ENDIF (substr($xaux, 0, 3) < 100)
          break;
          case 2: // checa las decenas (con la misma lógica que las centenas)
          if (substr($xaux, 1, 2) < 10)
          {
          }
          else
          {
          $xseek = $xarray[substr($xaux, 1, 2)];
          if ($xseek)
          {
          $xsub = subfijo($xaux);
          if (substr($xaux, 1, 2) == 20)
          $xcadena = " ".$xcadena." VEINTE ".$xsub;
          else
          $xcadena = " ".$xcadena." ".$xseek." ".$xsub;
          $xy = 3;
          }
          else
          {
          $xseek = $xarray[substr($xaux, 1, 1) * 10];
          if (substr($xaux, 1, 1) * 10 == 20)
          $xcadena = " ".$xcadena." ".$xseek;
          else
          $xcadena = " ".$xcadena." ".$xseek." Y ";
          } // ENDIF ($xseek)
          } // ENDIF (substr($xaux, 1, 2) < 10)
          break;
          case 3: // checa las unidades
          if (substr($xaux, 2, 1) < 1) // si la unidad es cero, ya no hace nada
          {
          }
          else
          {
          $xseek = $xarray[substr($xaux, 2, 1)]; // obtengo directamente el valor de la unidad (del uno al nueve)
          $xsub = subfijo($xaux);
          $xcadena = " ".$xcadena." ".$xseek." ".$xsub;
          } // ENDIF (substr($xaux, 2, 1) < 1)
          break;
          } // END SWITCH
          } // END FOR
          $xi = $xi + 3;
          } // ENDDO

          if (substr(trim($xcadena), -5, 5) == "ILLON") // si la cadena obtenida termina en MILLON o BILLON, entonces le agrega al final la conjuncion DE
          $xcadena.= " DE";

          if (substr(trim($xcadena), -7, 7) == "ILLONES") // si la cadena obtenida en MILLONES o BILLONES, entoncea le agrega al final la conjuncion DE
          $xcadena.= " DE";

          // ----------- esta línea la puedes cambiar de acuerdo a tus necesidades o a tu país -------
          if (trim($xaux) != "")
          {
          switch ($xz)
          {
          case 0:
          if (trim(substr($XAUX, $xz * 6, 6)) == "1")
          $xcadena.= "UN BILLON ";
          else
          $xcadena.= " BILLONES ";
          break;
          case 1:
          if (trim(substr($XAUX, $xz * 6, 6)) == "1")
          $xcadena.= "UN MILLON ";
          else
          $xcadena.= " MILLONES ";
          break;
          case 2:
          if ($xcifra < 1 )
          {
          $xcadena = "CERO DOLARES $xdecimales/100 ";
          }
          if ($xcifra >= 1 && $xcifra < 2)
          {
          $xcadena = "UN DOLAR $xdecimales/100 ";
          }
          if ($xcifra >= 2)
          {
          $xcadena.= " DOLARES $xdecimales/100 "; //
          }
          break;
          } // endswitch ($xz)
          } // ENDIF (trim($xaux) != "")
          // ------------------ en este caso, para Ecuador se usa esta leyenda ----------------
          $xcadena = str_replace("VEINTI ", "VEINTI", $xcadena); // quito el espacio para el VEINTI, para que quede: VEINTICUATRO, VEINTIUN, VEINTIDOS, etc
          $xcadena = str_replace(" ", " ", $xcadena); // quito espacios dobles
          $xcadena = str_replace("UN UN", "UN", $xcadena); // quito la duplicidad
          $xcadena = str_replace(" ", " ", $xcadena); // quito espacios dobles
          $xcadena = str_replace("BILLON DE MILLONES", "BILLON DE", $xcadena); // corrigo la leyenda
          $xcadena = str_replace("BILLONES DE MILLONES", "BILLONES DE", $xcadena); // corrigo la leyenda
          $xcadena = str_replace("DE UN", "UN", $xcadena); // corrigo la leyenda
          } // ENDFOR ($xz)
          return trim($xcadena);
          } // END FUNCTION


          function subfijo($xx)
          { // esta función regresa un subfijo para la cifra
          $xx = trim($xx);
          $xstrlen = strlen($xx);
          if ($xstrlen == 1 || $xstrlen == 2 || $xstrlen == 3)
          $xsub = "";
          //
          if ($xstrlen == 4 || $xstrlen == 5 || $xstrlen == 6)
          $xsub = "MIL";
          //
          return $xsub;
          } // END FUNCTION

          $n = {fact_valor_total};
          $xx = numtoletras($n);
          {xletras} = $xx;

          //---------------------------------------------------------- hasta aqui solo copialo y pegalo ------------------------------------
          donde en mi caso, {fact_valor_total} es el campo de la tabla facturas donde guardo el valor total y simplemente con ese campo llamo a la funcion numtoletras
          la cual me devuelve en la variable $xx la cantidad en letras y luego esa variable la pongo en otro campo añadido a la factura pdf llamado xletras el cual lo imprimo donde deseo que salga dicha cantidad en letras.

          Saludos
          Aquiles

          Aquiles logro todo pero no puedo hacer que mi variable con el contenido de numeros a letras se imprima en el pdf.-
          Agradecería puedas darme una mano
          Saludos
          Federico

          Comment


          • #6
            Pega tu codigo (en un nuevo hilo y poniendo tu codigo usando el bbcode de php para este fin), y especifica un poco más el problema, si no es imposible ayudarte.
            /Giuseppe

            Professional Scriptcase Services
            Some Customers opinions

            Comment

            Working...
            X