Skip to content

Commit

Permalink
move calendar and timesheet logic to single api
Browse files Browse the repository at this point in the history
  • Loading branch information
markdturner committed Aug 30, 2024
1 parent 093d15c commit 531a10f
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 203 deletions.
54 changes: 28 additions & 26 deletions src/api/rse/controllers/rse.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,31 @@

const { createCoreController } = require('@strapi/strapi').factories

module.exports = createCoreController('api::rse.rse', ({ strapi }) => ({
find: async (ctx) => {
try {
return await strapi.service('api::rse.rse').find(ctx.request.query)
} catch (err) {
console.error(err)
return err
}
},
// Override findOne to use a filter on the find method for service code reuse
findOne: async (ctx) => {
try {
ctx.request.query.filters = { id: ctx.params.id }
const response = await strapi.service('api::rse.rse').find(ctx.request.query)
if (response.results.length === 1) {
return {
data: response.results[0],
meta: {}
}
}
} catch (err) {
console.error(err)
return err
}
}
}))
module.exports = createCoreController('api::rse.rse')

// module.exports = createCoreController('api::rse.rse', ({ strapi }) => ({
// find: async (ctx) => {
// try {
// return await strapi.service('api::rse.rse').find(ctx.request.query)
// } catch (err) {
// console.error(err)
// return err
// }
// },
// // Override findOne to use a filter on the find method for service code reuse
// findOne: async (ctx) => {
// try {
// ctx.request.query.filters = { id: ctx.params.id }
// const response = await strapi.service('api::rse.rse').find(ctx.request.query)
// if (response.results.length === 1) {
// return {
// data: response.results[0],
// meta: {}
// }
// }
// } catch (err) {
// console.error(err)
// return err
// }
// }
// }))
135 changes: 3 additions & 132 deletions src/api/rse/services/rse.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,141 +4,11 @@
* rse service.
*/

const { DateTime, Interval } = require("luxon")
const { createCoreService } = require("@strapi/strapi").factories

function createCalendar(rse, holidays, leave, assignments, capacities, timesheets, startDate, endDate) {
const dates = []

let date = startDate

while(date <= endDate) {

const holiday = holidays.find(holiday => holiday.date === date.toISODate()),
leaveDay = leave.find(leave => leave.DATE === date.toISODate() && leave.ID === rse.username),
currentAssignments = assignments.filter(assignment => {
const start = DateTime.fromISO(assignment.start),
end = DateTime.fromISO(assignment.end)
return date >= start && date <= end && assignment.rse.id === rse.id
})

let dateCapacity = 0

capacities.forEach(capacity => {

capacity.end = capacity.end ? capacity.end : endDate.toISODate()

// Build interval for capacity period
const period = Interval.fromDateTimes(DateTime.fromISO(capacity.start), DateTime.fromISO(capacity.end))

// Is current date in loop within the capacity period
if(period.contains(date)) {
dateCapacity = capacity.capacity
}
})

const timesheetReport = timesheets.dates[date.toISODate()],
timesheetSummary = []

if(timesheetReport) {
timesheetReport.filter(timesheet => timesheet.userId === rse.clockifyID).forEach(timesheet => {
timesheetSummary.push({
start: timesheet.timeInterval.start,
end: timesheet.timeInterval.end,
duration: timesheet.timeInterval.duration,
billable: timesheet.billable,
project: timesheet.projectName,
})
})
}

let day = {
date: date.toISODate(),
metadata: {
day: date.day,
month: date.month,
year: date.year,
dayOfWeek: date.weekday,
isWeekend: date.weekday > 5,
isWorkingDay: date.weekday < 6 && !holiday
},
utilisation: {
capacity: dateCapacity,
allocated: currentAssignments.reduce((total, assignment) => total + assignment.fte, 0),
unallocated: dateCapacity - currentAssignments.reduce((total, assignment) => total + assignment.fte, 0),
recorded: {
billable: timesheetSummary.reduce((total, timesheet) => total + (timesheet.billable ? timesheet.duration : 0), 0),
nonBillable: timesheetSummary.reduce((total, timesheet) => total + (timesheet.billable ? 0 : timesheet.duration), 0)
}
},
holiday: holiday ? holiday : null,
leave: leaveDay ? {
type: leaveDay.TYPE,
durationCode: leaveDay.DURATION,
duration: leaveDay.DURATION === 'Y' ? 7.4 : 3.7,
status: leaveDay.STATUS
} : null,
assignments: currentAssignments.map(({ rse, ...assignment }) => assignment),
timesheet: timesheetSummary
}

dates.push(day)

date = date.plus({days: 1})
}

return dates
}

async function fetchBankHolidays(year) {
const ukBankHolidays = await fetch('https://www.gov.uk/bank-holidays.json').then((response) => response.json())

let bankHolidays = ukBankHolidays['england-and-wales'].events,
closures = []

if(year) {
const startDate = DateTime.fromISO(`${year}-08-01`),
endDate = DateTime.fromISO(`${(Number(year)+1)}-07-31`)

bankHolidays = bankHolidays.filter(holiday => {
const holidayDate = DateTime.fromISO(holiday.date)
return holidayDate >= startDate && holidayDate <= endDate
})
}

const christmases = bankHolidays.filter(holiday => holiday.title === 'Christmas Day')

christmases.forEach(christmas => {
const christmasBankHoliday = DateTime.fromISO(christmas.date)
const christmasEve = DateTime.fromISO(`${christmasBankHoliday.year}-12-24`)

for(let i=0; i<=7; i++) {
let closureDate = christmasEve.plus({days: i})

if(closureDate.toISODate() !== christmasBankHoliday.toISODate()) {
closures.push({
title: 'University Closure',
date: closureDate.toISODate(),
notes: '',
bunting: false
})
}
}

// If Christmas Eve is a Tuesday, the closure will start the day before
if(christmasEve.weekday === 2) {
closures.push({
title: 'University Closure',
date: christmasEve.minus({days: 1}).toISODate(),
notes: '',
bunting: false
})
}
})

return [...closures, ...bankHolidays]
}

module.exports = createCoreService('api::rse.rse')
/*
module.exports = createCoreService("api::rse.rse", ({ strapi }) => ({
async find(...args) {
let { results, pagination } = await super.find(...args)
Expand Down Expand Up @@ -201,3 +71,4 @@ module.exports = createCoreService("api::rse.rse", ({ strapi }) => ({
return { data: results, meta: pagination }
}
}))
*/
22 changes: 19 additions & 3 deletions src/api/timesheet/controllers/timesheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,33 @@
const service = require('../services/timesheet')

module.exports = {
find: async (ctx, next) => {
find: async (ctx) => {
try {
ctx.body = await service.find(ctx.request.query)
} catch (err) {
ctx.body = err
console.error(err)
}
},
leave: async (ctx, next) => {
leave: async (ctx) => {
try {
ctx.body = await service.findLeave(ctx.request.query)
ctx.body = await service.leave(ctx.request.query)
} catch (err) {
ctx.body = err
console.error(err)
}
},
calendar: async (ctx) => {
try {
ctx.body = await service.calendar(ctx.request.query)
} catch (err) {
ctx.body = err
console.error(err)
}
},
summary: async (ctx) => {
try {
ctx.body = await service.summary(ctx.request.query)
} catch (err) {
ctx.body = err
console.error(err)
Expand Down
27 changes: 27 additions & 0 deletions src/api/timesheet/middlewares/financial-year.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';

module.exports = (config, { strapi }) => {

return async (ctx, next) => {
const currentDate = new Date()

// Year present in query
if(!ctx.query.filters || !ctx.query.filters.year || !ctx.query.filters.year.$eq) {

if(!ctx.query.filters || !ctx.query.filters.year) {
ctx.query.filters = { ...{ year: { $eq: null } } }
}

// Is after december of the current financial year
if(currentDate.getMonth() < 7) {
ctx.query.filters.year.$eq = (currentDate.getFullYear()) - 1
}
// Is before december of the current financial year
else {
ctx.query.filters.year.$eq = currentDate.getFullYear()
}
}

await next()
}
}
22 changes: 20 additions & 2 deletions src/api/timesheet/routes/timesheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
handler: "timesheet.find",
config: {
policies: [],
middlewares: [],
middlewares: ['api::timesheet.financial-year'],
},
},
{
Expand All @@ -15,7 +15,25 @@ module.exports = {
handler: "timesheet.leave",
config: {
policies: [],
middlewares: [],
middlewares: ['api::timesheet.financial-year'],
},
},
{
method: "GET",
path: "/timesheets/calendar",
handler: "timesheet.calendar",
config: {
policies: [],
middlewares: ['api::timesheet.financial-year'],
},
},
{
method: "GET",
path: "/timesheets/summary",
handler: "timesheet.summary",
config: {
policies: [],
middlewares: ['api::timesheet.financial-year'],
},
}
],
Expand Down
Loading

0 comments on commit 531a10f

Please sign in to comment.