"use strict"; /** * EtapaService - Gestión de etapas de fraccionamientos * * CRUD de etapas con soporte multi-tenant. * * @module Construction */ Object.defineProperty(exports, "__esModule", { value: true }); exports.EtapaService = void 0; const typeorm_1 = require("typeorm"); class EtapaService { repository; constructor(repository) { this.repository = repository; } /** * Listar etapas */ async findAll(options) { const { tenantId, fraccionamientoId, page = 1, limit = 20, search, status } = options; const query = this.repository .createQueryBuilder('e') .where('e.tenant_id = :tenantId', { tenantId }) .andWhere('e.deleted_at IS NULL'); if (fraccionamientoId) { query.andWhere('e.fraccionamiento_id = :fraccionamientoId', { fraccionamientoId }); } if (search) { query.andWhere('(e.code ILIKE :search OR e.name ILIKE :search)', { search: `%${search}%` }); } if (status) { query.andWhere('e.status = :status', { status }); } const total = await query.getCount(); const items = await query .skip((page - 1) * limit) .take(limit) .orderBy('e.sequence', 'ASC') .addOrderBy('e.name', 'ASC') .getMany(); return { items, total }; } /** * Obtener etapa por ID */ async findById(id, tenantId) { return this.repository.findOne({ where: { id, tenantId, deletedAt: (0, typeorm_1.IsNull)() }, relations: ['manzanas'], }); } /** * Obtener etapa por código dentro de un fraccionamiento */ async findByCode(code, fraccionamientoId, tenantId) { return this.repository.findOne({ where: { code, fraccionamientoId, tenantId, deletedAt: (0, typeorm_1.IsNull)() }, }); } /** * Crear etapa */ async create(tenantId, dto, createdBy) { const existing = await this.findByCode(dto.code, dto.fraccionamientoId, tenantId); if (existing) { throw new Error('Stage code already exists in this fraccionamiento'); } return this.repository.save(this.repository.create({ tenantId, ...dto, createdBy, status: dto.status || 'draft', })); } /** * Actualizar etapa */ async update(id, tenantId, dto, updatedBy) { const etapa = await this.findById(id, tenantId); if (!etapa) { throw new Error('Stage not found'); } // Verificar código único si se está cambiando if (dto.code && dto.code !== etapa.code) { const existing = await this.findByCode(dto.code, etapa.fraccionamientoId, tenantId); if (existing) { throw new Error('Stage code already exists in this fraccionamiento'); } } await this.repository.update(id, { ...dto, updatedBy, updatedAt: new Date(), }); return this.findById(id, tenantId); } /** * Eliminar etapa (soft delete) */ async delete(id, tenantId, _deletedBy) { const etapa = await this.findById(id, tenantId); if (!etapa) { throw new Error('Stage not found'); } // TODO: Verificar si tiene manzanas antes de eliminar await this.repository.update(id, { deletedAt: new Date(), }); } /** * Obtener etapas por fraccionamiento */ async findByFraccionamiento(fraccionamientoId, tenantId) { return this.repository.find({ where: { fraccionamientoId, tenantId, deletedAt: (0, typeorm_1.IsNull)() }, order: { sequence: 'ASC' }, }); } } exports.EtapaService = EtapaService; //# sourceMappingURL=etapa.service.js.map