DTP Base provides a scalable and secure Node.js application development harness ready for production service.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

142 lines
3.3 KiB

// 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();
this.log.debug('computing weekly earnings', { dateStart, dateEnd });
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));
}
}