234 lines
8.7 KiB
JavaScript
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
|