erp-construccion-backend/dist/modules/infonavit/services/derechohabiente.service.js

234 lines
8.7 KiB
JavaScript

"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