122 lines
3.5 KiB
TypeScript
122 lines
3.5 KiB
TypeScript
import { Router, Request, Response, NextFunction } from 'express';
|
|
import { DataSource, Repository, ILike } from 'typeorm';
|
|
import { Patient } from '../entities';
|
|
import { CreatePatientDto, UpdatePatientDto, PatientQueryDto } from '../dto';
|
|
|
|
export class PatientService {
|
|
private repository: Repository<Patient>;
|
|
|
|
constructor(dataSource: DataSource) {
|
|
this.repository = dataSource.getRepository(Patient);
|
|
}
|
|
|
|
async findAll(tenantId: string, query: PatientQueryDto): Promise<{ data: Patient[]; total: number }> {
|
|
const { search, status, hasInsurance, page = 1, limit = 20 } = query;
|
|
|
|
const whereConditions: any = {
|
|
tenantId,
|
|
};
|
|
|
|
if (status) {
|
|
whereConditions.status = status;
|
|
}
|
|
|
|
if (hasInsurance !== undefined) {
|
|
whereConditions.hasInsurance = hasInsurance;
|
|
}
|
|
|
|
const queryBuilder = this.repository.createQueryBuilder('patient')
|
|
.where('patient.tenant_id = :tenantId', { tenantId })
|
|
.andWhere('patient.deleted_at IS NULL');
|
|
|
|
if (status) {
|
|
queryBuilder.andWhere('patient.status = :status', { status });
|
|
}
|
|
|
|
if (hasInsurance !== undefined) {
|
|
queryBuilder.andWhere('patient.has_insurance = :hasInsurance', { hasInsurance });
|
|
}
|
|
|
|
if (search) {
|
|
queryBuilder.andWhere(
|
|
'(patient.first_name ILIKE :search OR patient.last_name ILIKE :search OR patient.mobile ILIKE :search OR patient.email ILIKE :search)',
|
|
{ search: `%${search}%` }
|
|
);
|
|
}
|
|
|
|
queryBuilder
|
|
.orderBy('patient.last_name', 'ASC')
|
|
.addOrderBy('patient.first_name', 'ASC')
|
|
.skip((page - 1) * limit)
|
|
.take(limit);
|
|
|
|
const [data, total] = await queryBuilder.getManyAndCount();
|
|
|
|
return { data, total };
|
|
}
|
|
|
|
async findById(tenantId: string, id: string): Promise<Patient | null> {
|
|
return this.repository.findOne({
|
|
where: { id, tenantId },
|
|
});
|
|
}
|
|
|
|
async findByMobile(tenantId: string, mobile: string): Promise<Patient | null> {
|
|
return this.repository.findOne({
|
|
where: { mobile, tenantId },
|
|
});
|
|
}
|
|
|
|
async create(tenantId: string, dto: CreatePatientDto): Promise<Patient> {
|
|
const patient = this.repository.create({
|
|
...dto,
|
|
tenantId,
|
|
dateOfBirth: dto.dateOfBirth ? new Date(dto.dateOfBirth) : undefined,
|
|
});
|
|
|
|
return this.repository.save(patient);
|
|
}
|
|
|
|
async update(tenantId: string, id: string, dto: UpdatePatientDto): Promise<Patient | null> {
|
|
const patient = await this.findById(tenantId, id);
|
|
if (!patient) {
|
|
return null;
|
|
}
|
|
|
|
const updateData: any = { ...dto };
|
|
if (dto.dateOfBirth) {
|
|
updateData.dateOfBirth = new Date(dto.dateOfBirth);
|
|
}
|
|
|
|
Object.assign(patient, updateData);
|
|
return this.repository.save(patient);
|
|
}
|
|
|
|
async softDelete(tenantId: string, id: string): Promise<boolean> {
|
|
const patient = await this.findById(tenantId, id);
|
|
if (!patient) {
|
|
return false;
|
|
}
|
|
|
|
await this.repository.softDelete(id);
|
|
return true;
|
|
}
|
|
|
|
async getPatientHistory(tenantId: string, patientId: string): Promise<any> {
|
|
// Este metodo devolvera el historial completo del paciente
|
|
// incluyendo citas, consultas, prescripciones, etc.
|
|
// Por ahora retorna datos basicos
|
|
const patient = await this.findById(tenantId, patientId);
|
|
if (!patient) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
patient,
|
|
appointments: [], // TODO: Integrar con AppointmentService
|
|
consultations: [], // TODO: Integrar con ConsultationService
|
|
prescriptions: [], // TODO: Integrar con PrescriptionService
|
|
};
|
|
}
|
|
}
|