"use strict"; /** * DerechohabienteService - Servicio de gestión de derechohabientes INFONAVIT * * Gestión de trabajadores con crédito INFONAVIT. * * @module Infonavit */ Object.defineProperty(exports, "__esModule", { value: true }); exports.DerechohabienteService = void 0; class DerechohabienteService { derechohabienteRepository; historicoPuntosRepository; constructor(derechohabienteRepository, historicoPuntosRepository) { this.derechohabienteRepository = derechohabienteRepository; this.historicoPuntosRepository = historicoPuntosRepository; } async findWithFilters(ctx, filters = {}, page = 1, limit = 20) { const skip = (page - 1) * limit; const queryBuilder = this.derechohabienteRepository .createQueryBuilder('dh') .leftJoinAndSelect('dh.createdBy', 'createdBy') .where('dh.tenant_id = :tenantId', { tenantId: ctx.tenantId }) .andWhere('dh.deleted_at IS NULL'); if (filters.nss) { queryBuilder.andWhere('dh.nss = :nss', { nss: filters.nss }); } if (filters.curp) { queryBuilder.andWhere('dh.curp = :curp', { curp: filters.curp }); } if (filters.status) { queryBuilder.andWhere('dh.status = :status', { status: filters.status }); } if (filters.search) { queryBuilder.andWhere('(dh.first_name ILIKE :search OR dh.last_name ILIKE :search OR dh.nss ILIKE :search)', { search: `%${filters.search}%` }); } if (filters.minPoints !== undefined) { queryBuilder.andWhere('dh.credit_points >= :minPoints', { minPoints: filters.minPoints }); } queryBuilder .orderBy('dh.last_name', 'ASC') .addOrderBy('dh.first_name', 'ASC') .skip(skip) .take(limit); const [data, total] = await queryBuilder.getManyAndCount(); return { data, meta: { total, page, limit, totalPages: Math.ceil(total / limit), }, }; } async findById(ctx, id) { return this.derechohabienteRepository.findOne({ where: { id, tenantId: ctx.tenantId, deletedAt: null, }, }); } async findByNss(ctx, nss) { return this.derechohabienteRepository.findOne({ where: { nss, tenantId: ctx.tenantId, deletedAt: null, }, }); } async findWithDetails(ctx, id) { return this.derechohabienteRepository.findOne({ where: { id, tenantId: ctx.tenantId, deletedAt: null, }, relations: ['createdBy', 'asignaciones', 'asignaciones.oferta', 'historicoPuntos'], }); } async create(ctx, dto) { // Check for existing NSS or CURP const existingNss = await this.derechohabienteRepository.findOne({ where: { nss: dto.nss, tenantId: ctx.tenantId }, }); if (existingNss) { throw new Error('A worker with this NSS already exists'); } const existingCurp = await this.derechohabienteRepository.findOne({ where: { curp: dto.curp, tenantId: ctx.tenantId }, }); if (existingCurp) { throw new Error('A worker with this CURP already exists'); } const derechohabiente = this.derechohabienteRepository.create({ tenantId: ctx.tenantId, createdById: ctx.userId, nss: dto.nss, curp: dto.curp.toUpperCase(), rfc: dto.rfc?.toUpperCase(), firstName: dto.firstName, lastName: dto.lastName, secondLastName: dto.secondLastName, phone: dto.phone, email: dto.email, address: dto.address, creditPoints: dto.creditPoints || 0, notes: dto.notes, status: 'active', }); const saved = await this.derechohabienteRepository.save(derechohabiente); // Record initial points if provided if (dto.creditPoints && dto.creditPoints > 0) { const historico = this.historicoPuntosRepository.create({ tenantId: ctx.tenantId, createdById: ctx.userId, derechohabienteId: saved.id, recordDate: new Date(), previousPoints: 0, newPoints: dto.creditPoints, pointsChange: dto.creditPoints, movementType: 'initial', source: 'Registration', }); await this.historicoPuntosRepository.save(historico); } return saved; } async update(ctx, id, dto) { const derechohabiente = await this.findById(ctx, id); if (!derechohabiente) { return null; } Object.assign(derechohabiente, { ...dto, updatedById: ctx.userId || '', }); return this.derechohabienteRepository.save(derechohabiente); } async updatePoints(ctx, id, newPoints, source, notes) { const derechohabiente = await this.findById(ctx, id); if (!derechohabiente) { return null; } const previousPoints = derechohabiente.creditPoints; // Record points change const historico = this.historicoPuntosRepository.create({ tenantId: ctx.tenantId, createdById: ctx.userId, derechohabienteId: id, recordDate: new Date(), previousPoints, newPoints, pointsChange: newPoints - previousPoints, movementType: 'update', source, notes, }); await this.historicoPuntosRepository.save(historico); // Update derechohabiente derechohabiente.creditPoints = newPoints; derechohabiente.updatedById = ctx.userId || ''; return this.derechohabienteRepository.save(derechohabiente); } async precalify(ctx, id, dto) { const derechohabiente = await this.findById(ctx, id); if (!derechohabiente) { return null; } if (derechohabiente.status !== 'active') { throw new Error('Only active workers can be precalified'); } const previousPoints = derechohabiente.creditPoints; // Record points change from precalification const historico = this.historicoPuntosRepository.create({ tenantId: ctx.tenantId, createdById: ctx.userId, derechohabienteId: id, recordDate: dto.precalificationDate, previousPoints, newPoints: dto.creditPoints, pointsChange: dto.creditPoints - previousPoints, movementType: 'precalification', source: 'INFONAVIT Precalification', }); await this.historicoPuntosRepository.save(historico); // Update derechohabiente derechohabiente.creditPoints = dto.creditPoints; derechohabiente.precalificationDate = dto.precalificationDate; derechohabiente.precalificationAmount = dto.precalificationAmount; derechohabiente.creditType = dto.creditType; derechohabiente.status = 'pre_qualified'; derechohabiente.updatedById = ctx.userId || ''; return this.derechohabienteRepository.save(derechohabiente); } async qualify(ctx, id) { const derechohabiente = await this.findById(ctx, id); if (!derechohabiente) { return null; } if (derechohabiente.status !== 'pre_qualified') { throw new Error('Only pre-qualified workers can be qualified'); } derechohabiente.status = 'qualified'; derechohabiente.updatedById = ctx.userId || ''; return this.derechohabienteRepository.save(derechohabiente); } async softDelete(ctx, id) { const derechohabiente = await this.findById(ctx, id); if (!derechohabiente) { return false; } if (derechohabiente.status === 'assigned') { throw new Error('Cannot delete workers with assigned housing'); } await this.derechohabienteRepository.update({ id, tenantId: ctx.tenantId }, { deletedAt: new Date(), deletedById: ctx.userId || '' }); return true; } async getPointsHistory(ctx, derechohabienteId) { return this.historicoPuntosRepository.find({ where: { derechohabienteId, tenantId: ctx.tenantId, }, order: { recordDate: 'DESC' }, relations: ['createdBy'], }); } } exports.DerechohabienteService = DerechohabienteService; //# sourceMappingURL=derechohabiente.service.js.map