// report.js // Copyright (C) 2024 DTP Technologies, LLC // All Rights Reserved 'use strict'; import mongoose from 'mongoose'; const TaskSession = mongoose.model('TaskSession'); import dayjs from 'dayjs'; import { SiteService } from '../../lib/site-lib.js'; export default class ReportService extends SiteService { static get name ( ) { return 'ReportService'; } static get slug () { return 'report'; } constructor (dtp) { super(dtp, ReportService); } async getWeeklyEarnings (user) { const NOW = new Date(); const dateStart = this.startOfWeek(NOW); const dateEnd = dayjs(dateStart).add(1, 'week').toDate(); this.log.debug('computing weekly earnings', { dateStart, dateEnd }); /* * I'm sure there's some beautiful way to do this using aggregation but I * don't care at all (and won't) until aggregation becomes a usable API. */ const response = { sessionCount: 0, duration: 0, billable: 0 }; await TaskSession .find({ user: user._id, $and: [ { created: { $gte: dateStart } }, { finished: { $lt: dateEnd } }, ], }) .cursor() .eachAsync(async (session) => { response.sessionCount += 1; response.duration += session.duration; response.billable += session.hourlyRate * (session.duration / 60 / 60); }); return response; } startOfWeek (date) { date = date || new Date(); date.setHours(0,0,0,0); var diff = date.getDate() - date.getDay() + (date.getDay() === 0 ? -6 : 1); return new Date(date.setDate(diff)); } }