"use strict"; /** * ConsumoObraService - Servicio de consumos de materiales * * Gestión de consumos de materiales por obra/lote. * * @module Inventory */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ConsumoObraService = void 0; class ConsumoObraService { repository; constructor(repository) { this.repository = repository; } async findWithFilters(ctx, filters = {}, page = 1, limit = 20) { const skip = (page - 1) * limit; const queryBuilder = this.repository .createQueryBuilder('consumo') .leftJoinAndSelect('consumo.fraccionamiento', 'fraccionamiento') .leftJoinAndSelect('consumo.lote', 'lote') .leftJoinAndSelect('consumo.concepto', 'concepto') .leftJoinAndSelect('consumo.registeredBy', 'registeredBy') .where('consumo.tenant_id = :tenantId', { tenantId: ctx.tenantId }) .andWhere('consumo.deleted_at IS NULL'); if (filters.fraccionamientoId) { queryBuilder.andWhere('consumo.fraccionamiento_id = :fraccionamientoId', { fraccionamientoId: filters.fraccionamientoId, }); } if (filters.loteId) { queryBuilder.andWhere('consumo.lote_id = :loteId', { loteId: filters.loteId }); } if (filters.conceptoId) { queryBuilder.andWhere('consumo.concepto_id = :conceptoId', { conceptoId: filters.conceptoId }); } if (filters.productId) { queryBuilder.andWhere('consumo.product_id = :productId', { productId: filters.productId }); } if (filters.dateFrom) { queryBuilder.andWhere('consumo.consumption_date >= :dateFrom', { dateFrom: filters.dateFrom }); } if (filters.dateTo) { queryBuilder.andWhere('consumo.consumption_date <= :dateTo', { dateTo: filters.dateTo }); } queryBuilder .orderBy('consumo.consumption_date', 'DESC') .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.repository.findOne({ where: { id, tenantId: ctx.tenantId, deletedAt: null, }, relations: ['fraccionamiento', 'lote', 'concepto', 'registeredBy'], }); } async create(ctx, dto) { const consumo = this.repository.create({ tenantId: ctx.tenantId, createdById: ctx.userId, registeredById: ctx.userId, fraccionamientoId: dto.fraccionamientoId, loteId: dto.loteId, departamentoId: dto.departamentoId, conceptoId: dto.conceptoId, productId: dto.productId, quantity: dto.quantity, unitCost: dto.unitCost, consumptionDate: dto.consumptionDate, notes: dto.notes, }); return this.repository.save(consumo); } async getStats(ctx, fraccionamientoId) { const baseQuery = this.repository .createQueryBuilder('consumo') .where('consumo.tenant_id = :tenantId', { tenantId: ctx.tenantId }) .andWhere('consumo.fraccionamiento_id = :fraccionamientoId', { fraccionamientoId }) .andWhere('consumo.deleted_at IS NULL'); // Get totals const totals = await baseQuery .clone() .select('COUNT(*)', 'total') .addSelect('SUM(consumo.quantity)', 'totalQuantity') .addSelect('SUM(consumo.quantity * COALESCE(consumo.unit_cost, 0))', 'totalCost') .getRawOne(); // Get by product const byProduct = await baseQuery .clone() .select('consumo.product_id', 'productId') .addSelect('SUM(consumo.quantity)', 'quantity') .addSelect('SUM(consumo.quantity * COALESCE(consumo.unit_cost, 0))', 'cost') .groupBy('consumo.product_id') .getRawMany(); // Get by concepto const byConcepto = await baseQuery .clone() .select('consumo.concepto_id', 'conceptoId') .addSelect('SUM(consumo.quantity)', 'quantity') .addSelect('SUM(consumo.quantity * COALESCE(consumo.unit_cost, 0))', 'cost') .where('consumo.concepto_id IS NOT NULL') .groupBy('consumo.concepto_id') .getRawMany(); return { totalConsumos: parseInt(totals.total || '0', 10), totalQuantity: parseFloat(totals.totalQuantity || '0'), totalCost: parseFloat(totals.totalCost || '0'), byProduct: byProduct.map((p) => ({ productId: p.productId, quantity: parseFloat(p.quantity || '0'), cost: parseFloat(p.cost || '0'), })), byConcepto: byConcepto.map((c) => ({ conceptoId: c.conceptoId, quantity: parseFloat(c.quantity || '0'), cost: parseFloat(c.cost || '0'), })), }; } async softDelete(ctx, id) { const consumo = await this.findById(ctx, id); if (!consumo) { return false; } await this.repository.update({ id, tenantId: ctx.tenantId }, { deletedAt: new Date(), deletedById: ctx.userId }); return true; } } exports.ConsumoObraService = ConsumoObraService; //# sourceMappingURL=consumo-obra.service.js.map