Código fuente para mexa.NssField

# encoding: utf-8
"""Clase encargada del Nss"""
import random
from mexa.core import FieldInterface, year_by_last2digit, Partes
from mexa.ErrorMsgs import NSS_ERRORS as ERRORS

partes = Partes(r'^(\d{2})(\d{2})(\d{2})(\d{4})(\d)$')
REGION_IMSS = 1
ANIO_ALTA = 2
ANIO_NACIMIENTO = 3
FOLIO_IMSS = 4
CHECKSUM = 5

[documentos]class NssField(FieldInterface): """Clase que modela el Nss""" errorMsgs = ERRORS # region_imss, anio_alta, anio_nacimiento, folio_imss, checksum
[documentos] @staticmethod def nss_checksum(nss): """Recibe un string que representa el nss, regresa el checksum""" if len(nss) < 10: NssField.error_msg = None return -1 suma = 0 for i in range(10): factor = 1 + (i % 2) v = int(nss[i]) * factor suma += (1 + v % 10) if (v > 9) else v cs = (suma * 9) % 10 return cs
[documentos] @staticmethod def is_valid(value, match = None): """Devuelve true si value es valido""" NssField.clear_errors() if len(value) != 11: NssField.add_error(code = 100) return False partes.load(value) if partes.error: NssField.add_error(code = 100) return False # revisando los años de afiliación/nacimiento f_afi = year_by_last2digit(partes.get(ANIO_ALTA)) f_nac = year_by_last2digit(partes.get(ANIO_NACIMIENTO)) if int(f_afi) < int(f_nac): NssField.add_error(code = 101) return False # revisando el checksum cs = NssField.nss_checksum(value) if cs != int(partes.get(CHECKSUM)): NssField.add_error(code = 102, value = partes.get(CHECKSUM)) return False # Falta agregar la implementación del match return match is None
[documentos] @staticmethod def autocomplete(value): """Devuelve true si value es valido""" if len(value) != 10: return value cs = NssField.nss_checksum(value) return f"{value}{cs}"
[documentos] @staticmethod def anios(data = None): """ Devuelve un arreglo con los años de nacimiento y afiliacion :param dic data: Los datos el cual puede contener fecha_nacimiento y f_afiliacion de existir deberán ser tomados en cuenta estos valores. :return: Arreglo ordenado de la forma [fecha_nacimiento, f_afiliacion] """ if data is None: data = {} if 'fecha_nacimiento' in data and 'f_afiliacion' in data: return [ year_by_last2digit(data['fecha_nacimiento']), year_by_last2digit(data['f_afiliacion']) ] if 'fecha_nacimiento' in data: nac = year_by_last2digit(data['fecha_nacimiento']) while True: afil = year_by_last2digit(random.randrange(0, 99)) if afil >= nac: return [nac, afil] if 'f_afiliacion' in data: afil = year_by_last2digit(data['f_afiliacion']) while True: nac = year_by_last2digit(random.randrange(0, 99)) if afil >= nac: return [nac, afil] y1 = year_by_last2digit(random.randrange(0, 99)) y2 = year_by_last2digit(random.randrange(0, 99)) if y1 <= y2: return [y1, y2] return [y2, y1]
[documentos] @staticmethod def generate(data = None): """ Genera un Nss a partir de los datos recibidos. :param dic data: Los valores contenidos deberán ser tomados en cuenta. :return: str nss Un número del Seguro Social válido """ if data is None: data = {} reg = data['region_imss'] if 'region_imss' in data else random.randrange(0, 99) years = NssField.anios(data) fol = data['folio_imss'] if 'folio_imss' in data else random.randrange(0, 9999) # Asignacion y formato reg = str(reg).rjust(2, '0') afi = str(years[1])[-2:] # Año de Afiliacion nac = str(years[0])[-2:] # Año de Nacimiento fol = str(fol).rjust(4, '0') # Se envia a autocomplete los diez primeros digitos para que le agregue el cs return NssField.autocomplete(f'{reg}{afi}{nac}{fol}')