Etiquetas

20120223

ABAP Tips: Calcular RUT (Chile)

Este es el mi algoritmo definitivo para calcular el RUT de una persona, separado en distintos forms según se necesite (valida RUT, calcula DV y formatea RUT) e integrado en un solo programa validador.



REPORT  valida_rut NO STANDARD PAGE HEADING.

PARAMETERS zzrut TYPE p0002-zzrut OBLIGATORY.
DATA return TYPE bapiret2.

START-OF-SELECTION.
  PERFORM valida_rut CHANGING zzrut return.
  MESSAGE return-message TYPE return-type.

*&---------------------------------------------------------------------*
*&      Form  VALIDA_RUT
*&---------------------------------------------------------------------*
FORM valida_rut  CHANGING   zzrut TYPE char12
                            e_return TYPE bapiret2.
  DATA paso(12)   TYPE c.
  DATA largo      TYPE i.
  DATA ext        TYPE i.
  DATA valor1(10) TYPE c.
  DATA valor2(10) TYPE c.
  DATA dv         TYPE c.
  DATA dv2        TYPE c.

  paso = zzrut.
  TRANSLATE paso USING '. '.
  TRANSLATE paso USING '- '.
  CONDENSE paso NO-GAPS.

  largo = STRLEN( paso ).
  ext = largo - 1.

  IF ext = 0.
    e_return-type = 'E'.
    e_return-message ='No se ha indicado DV'.
    EXIT.
  ENDIF.

  valor1 = paso(ext).
  dv = paso+ext(1).

* validar digito verificador
  PERFORM calcula_dv USING valor1 CHANGING dv2.

  IF dv <> dv2.
    e_return-type = 'E'.
    e_return-message = text-r02.
  ELSE.
    e_return-type = 'S'.
    e_return-message = 'DV OK'.
    PERFORM formatea_rut CHANGING zzrut.
  ENDIF.

ENDFORM.                    " VALIDA_RUT

*&---------------------------------------------------------------------*
*&      Form  CALCULA_DV
*&---------------------------------------------------------------------*
FORM calcula_dv  USING    i_rut TYPE char10
                 CHANGING g_dv.
  DATA g_rut TYPE char12.
  DATA g_veces TYPE i.
  DATA g_factor TYPE i.
  DATA g_suma TYPE i.
  DATA g_pos TYPE i.

  TRANSLATE i_rut USING '. '.
  TRANSLATE i_rut USING '- '.
  CONDENSE i_rut NO-GAPS.

* Se verifica que esté compuesto sólo por números y una K
  IF NOT i_rut CO '0123456789 '.
    MESSAGE 'Debe ingresar un RUT valido' TYPE 'E'.
    EXIT.
  ENDIF.

  g_rut = i_rut.
  CONDENSE g_rut NO-GAPS.
  g_veces = STRLEN( g_rut ).

  IF g_veces <= 0.
    MESSAGE 'RUT vacío' TYPE 'E'.
    EXIT.
  ENDIF.

  g_factor = 2.
  CLEAR g_suma.
  g_pos = g_veces - 1.

  DO g_veces TIMES.
    g_suma = g_suma + g_rut+g_pos(1) * g_factor.
    g_pos = g_pos - 1.
    g_factor = g_factor + 1.
    IF g_factor = 8.
      g_factor = 2.
    ENDIF.
  ENDDO.

  g_factor = g_suma MOD 11.

  IF g_factor = 0.
    g_dv = '0'.
  ELSE.
    g_factor = 11 - g_factor.
    IF g_factor > 9.
      g_dv = 'K'.
    ELSE.
      g_dv = g_factor.
    ENDIF.
  ENDIF.

ENDFORM.                    " CALCULA_DV

*&---------------------------------------------------------------------*
*&      Form  FORMATEA_RUT
*&---------------------------------------------------------------------*
FORM formatea_rut  CHANGING i_rut TYPE char12.
  DATA pos        TYPE i.
  DATA rut(12)    TYPE c.
  DATA salida(12) TYPE c.
  DATA valor(8).
  DATA dv.
  DATA ext        TYPE i.

  TRANSLATE i_rut USING '. '.
  TRANSLATE i_rut USING '- '.
  CONDENSE i_rut NO-GAPS.

  ext = STRLEN( i_rut ) - 1.
  valor = i_rut(ext).
  dv = i_rut+ext(1).

  ext = ext - 1.

  pos = 0.

  DO.
    IF pos < 3.
      CONCATENATE valor+ext(1) rut INTO rut.
      pos = pos + 1.
      ext = ext - 1.
    ELSE.
      pos = 0.
      CONCATENATE '.' rut INTO rut.
    ENDIF.
    IF ext < 0.
      EXIT.
    ENDIF.
  ENDDO.
  CONCATENATE rut '-' dv INTO rut.
  i_rut = rut.


ENDFORM.                    " FORMATEA_RUT

No hay comentarios:

Publicar un comentario