// 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 { client: clientService } = this.dtp.services; const NOW = new Date(); const dateStart = this.startOfWeek(NOW); const dateEnd = dayjs(dateStart).add(1, 'week').toDate(); const data = await TaskSession.aggregate([ { $match: { user: user._id, $and: [ { created: { $gte: dateStart } }, { finished: { $lt: dateEnd } }, ], }, }, { $group: { _id: { project: '$project' }, sessionCount: { $sum: 1 }, duration: { $sum: '$duration' }, billable: { $sum: { $multiply: [ '$hourlyRate', { $divide: ['$duration', 3600 ] }, ], }, }, }, }, { $project: { _id: 0, project: '$_id.project', sessionCount: '$sessionCount', duration: '$duration', billable: '$billable', }, }, ]); const response = await TaskSession.populate(data, [ { path: 'project', populate: clientService.populateClientProject, }, ]); return response; } async getDailyHoursWorkedForUser (user) { const NOW = new Date(); const dateStart = this.startOfWeek(NOW); const dateEnd = dayjs(dateStart).add(1, 'week').toDate(); const response = await TaskSession.aggregate([ { $match: { $and: [ { user: user._id }, { finished: { $gt: dateStart } }, { created: { $lt: dateEnd } }, ], } }, { $group: { _id: { year: { $year: '$created' }, month: { $month: '$created' }, day: { $dayOfMonth: '$created' }, }, workSessionCount: { $sum: 1 }, timeWorked: { $sum: '$duration' }, }, }, { $project: { _id: false, date: { $dateFromParts: { year: '$_id.year', month: '$_id.month', day: '$_id.day', }, }, workSessionCount: '$workSessionCount', hoursWorked: { $divide: ['$timeWorked', 3600] }, }, }, ]); if (response.length < 7) { let currentDay = dayjs(dateStart).add(response.length, 'day'); while (response.length < 7) { response.push({ date: currentDay, workSessionCount: 0, hoursWorked: 0, }); currentDay = dayjs(currentDay).add(1, 'day'); } } 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)); } }