// src/harvest/harvest.service.ts import { Injectable } from '@nestjs/common'; import { HarvestActivity } from './activity.schema'; import { CreateActivityDto, UpdateActivityDto } from './activity.dto'; import { ObjectId } from 'mongodb'; import { MongoService } from 'src/services/mongo.service'; @Injectable() export class ActivityService { private readonly collectionName = 'activities'; constructor(private readonly mongo: MongoService) { } /* ------------------------------ * Utility: Convert DTO to Schema * ------------------------------ */ private dtoToHarvestActivity(dto: CreateActivityDto): HarvestActivity { return { name: dto.name, type: dto.type, resources: dto.resources.map((r) => ({ ...r, id: r.id ? new ObjectId(r.id) : new ObjectId(), })), duration: dto.duration, outputs: dto.outputs.map((o) => ({ ...o, id: o.id ? new ObjectId(o.id) : new ObjectId(), })), targets: dto.targets.map((t) => ({ ...t, id: t.id ? new ObjectId(t.id) : new ObjectId(), })), dateStart: new Date(dto.dateStart), dateEnd: new Date(dto.dateEnd), }; } /* ------------------------------ * CRUD OPERATIONS * ------------------------------ */ async create(dto: CreateActivityDto) { const activity = this.dtoToHarvestActivity(dto); return this.mongo.createActivity(activity); } async findAll(filter: Record = {}) { return this.mongo.getAllActivities(filter); } async findById(id: string) { return this.mongo.getActivityById(id); } async update(id: string, dto: UpdateActivityDto) { // For partial updates, we only convert provided IDs const update: any = { ...dto }; if (dto.duration) { update.duration = { value: { quantity: dto.duration.value?.quantity ?? 0, uom: dto.duration.value?.uom ?? 'hours', }, }; } if (dto.resources) { update.resources = dto.resources.map((r) => ({ ...r, id: r.id ? new ObjectId(r.id) : new ObjectId(), })); } if (dto.outputs) { update.outputs = dto.outputs.map((o) => ({ ...o, id: o.id ? new ObjectId(o.id) : new ObjectId(), })); } if (dto.targets) { update.targets = dto.targets.map((t) => ({ ...t, id: t.id ? new ObjectId(t.id) : new ObjectId(), })); } if (dto.dateStart) update.dateStart = new Date(dto.dateStart); if (dto.dateEnd) update.dateEnd = new Date(dto.dateEnd); return this.mongo.updateActivity(id, update); } async delete(id: string) { return this.mongo.deleteActivity(id); } /* ------------------------------ * Aggregations / Queries * ------------------------------ */ async getTotalResourceHours() { return this.mongo.getTotalResourceHours(); } async getTotalOutputWeight() { return this.mongo.getTotalOutputWeight(); } async findByDateRange(start: Date, end: Date) { return this.mongo.getActivitiesByDateRange(start, end); } /* ------------------------------ * Aggregations / Custom Queries * ------------------------------ */ async getTotalWorkers(filter: { start?: Date; end?: Date; location?: string }) { return this.mongo.getTotalWorkers(filter); } async getTotalOutputs(filter: { start?: Date; end?: Date }) { return this.mongo.getTotalOutputs(filter); } }