import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { AuditLogService } from '../audit/audit-log.service'; import { CreateExtractionDto } from './dto/create-extraction.dto'; import { UpdateExtractionDto } from './dto/update-extraction.dto'; const extractionInclude = { harvests: { include: { harvest: { include: { colonies: { include: { colony: true } } } }, }, }, } as const; @Injectable() export class ExtractionsService { constructor( private readonly prisma: PrismaService, private readonly auditLog: AuditLogService, ) {} async findAll() { return this.prisma.extraction.findMany({ include: extractionInclude, orderBy: { date: 'desc' }, }); } async findById(id: string) { const extraction = await this.prisma.extraction.findUnique({ where: { id }, include: extractionInclude, }); if (!extraction) { throw new NotFoundException('Extraction not found'); } return extraction; } async create(dto: CreateExtractionDto, actingUserId: string) { const extraction = await this.prisma.$transaction(async (tx) => { const created = await tx.extraction.create({ data: { date: new Date(dto.date), amount: dto.amount, room: dto.room, waterContent: dto.waterContent, temperature: dto.temperature, notes: dto.notes, userId: actingUserId, }, }); await tx.extractionHarvest.createMany({ data: dto.harvestIds.map((harvestId) => ({ extractionId: created.id, harvestId, })), }); return created; }); await this.auditLog.record({ entityType: 'Extraction', entityId: extraction.id, action: 'CREATE', userId: actingUserId, afterData: extraction, }); return this.findById(extraction.id); } async update(id: string, dto: UpdateExtractionDto, actingUserId: string) { const before = await this.findById(id); await this.prisma.extraction.update({ where: { id }, data: { ...dto, date: dto.date ? new Date(dto.date) : undefined }, }); const extraction = await this.findById(id); await this.auditLog.record({ entityType: 'Extraction', entityId: id, action: 'UPDATE', userId: actingUserId, beforeData: before, afterData: extraction, }); return extraction; } }