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
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));
|
|
}
|
|
}
|