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.
60 lines
1.6 KiB
60 lines
1.6 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 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));
|
|
}
|
|
}
|