refactor(reporting): optimize date handling and organization working days logic

- Simplified date parsing by removing unnecessary start and end of day adjustments.
- Streamlined the fetching of organization working days from the database, consolidating queries for improved performance.
- Updated the calculation of total working hours to utilize project-specific hours per day, enhancing accuracy in reporting.
This commit is contained in:
chamiakJ
2025-05-20 15:51:33 +05:30
parent 67c62fc69b
commit 76c92b1cc6

View File

@@ -412,14 +412,8 @@ export default class ReportingAllocationController extends ReportingControllerBa
let startDate: moment.Moment;
let endDate: moment.Moment;
if (date_range && date_range.length === 2) {
// Parse simple YYYY-MM-DD dates
startDate = moment(date_range[0]).startOf('day');
endDate = moment(date_range[1]).endOf('day');
console.log("Original start date:", date_range[0]);
console.log("Original end date:", date_range[1]);
console.log("Start date:", startDate.format('YYYY-MM-DD'));
console.log("End date:", endDate.format('YYYY-MM-DD'));
startDate = moment(date_range[0]);
endDate = moment(date_range[1]);
} else if (duration === DATE_RANGES.ALL_TIME) {
// Fetch the earliest start_date (or created_at if null) from selected projects
const minDateQuery = `SELECT MIN(COALESCE(start_date, created_at)) as min_date FROM projects WHERE id IN (${projectIds})`;
@@ -433,18 +427,10 @@ export default class ReportingAllocationController extends ReportingControllerBa
startDate = moment().subtract(1, "day");
endDate = moment().subtract(1, "day");
break;
case DATE_RANGES.LAST_7_DAYS:
startDate = moment().subtract(7, "days");
endDate = moment();
break;
case DATE_RANGES.LAST_WEEK:
startDate = moment().subtract(1, "week").startOf("isoWeek");
endDate = moment().subtract(1, "week").endOf("isoWeek");
break;
case DATE_RANGES.LAST_30_DAYS:
startDate = moment().subtract(30, "days");
endDate = moment();
break;
case DATE_RANGES.LAST_MONTH:
startDate = moment().subtract(1, "month").startOf("month");
endDate = moment().subtract(1, "month").endOf("month");
@@ -459,49 +445,61 @@ export default class ReportingAllocationController extends ReportingControllerBa
}
}
// Fetch organization_id from the selected team
const selectedTeamId = req.user?.team_id;
let organizationId: string | undefined = undefined;
if (selectedTeamId) {
const orgIdQuery = `SELECT organization_id FROM teams WHERE id = $1`;
const orgIdResult = await db.query(orgIdQuery, [selectedTeamId]);
organizationId = orgIdResult.rows[0]?.organization_id;
}
// Fetch organization working hours and working days
let orgWorkingHours = 8;
let orgWorkingDays: { [key: string]: boolean } = {
monday: true, tuesday: true, wednesday: true, thursday: true, friday: true, saturday: false, sunday: false
// Get organization working days
const orgWorkingDaysQuery = `
SELECT monday, tuesday, wednesday, thursday, friday, saturday, sunday
FROM organization_working_days
WHERE organization_id IN (
SELECT t.organization_id
FROM teams t
WHERE t.id IN (${teamIds})
LIMIT 1
);
`;
const orgWorkingDaysResult = await db.query(orgWorkingDaysQuery, []);
const workingDaysConfig = orgWorkingDaysResult.rows[0] || {
monday: true,
tuesday: true,
wednesday: true,
thursday: true,
friday: true,
saturday: false,
sunday: false
};
if (organizationId) {
const orgHoursQuery = `SELECT working_hours FROM organizations WHERE id = $1`;
const orgHoursResult = await db.query(orgHoursQuery, [organizationId]);
if (orgHoursResult.rows[0]?.working_hours) {
orgWorkingHours = orgHoursResult.rows[0].working_hours;
}
const orgDaysQuery = `SELECT monday, tuesday, wednesday, thursday, friday, saturday, sunday FROM organization_working_days WHERE organization_id = $1 ORDER BY created_at DESC LIMIT 1`;
const orgDaysResult = await db.query(orgDaysQuery, [organizationId]);
if (orgDaysResult.rows[0]) {
orgWorkingDays = orgDaysResult.rows[0];
}
}
// Count only organization working days in the period
// Count working days based on organization settings
let workingDays = 0;
let current = startDate.clone();
while (current.isSameOrBefore(endDate, 'day')) {
const weekday = current.format('dddd').toLowerCase(); // e.g., 'monday'
if (orgWorkingDays[weekday]) workingDays++;
const day = current.isoWeekday();
if (
(day === 1 && workingDaysConfig.monday) ||
(day === 2 && workingDaysConfig.tuesday) ||
(day === 3 && workingDaysConfig.wednesday) ||
(day === 4 && workingDaysConfig.thursday) ||
(day === 5 && workingDaysConfig.friday) ||
(day === 6 && workingDaysConfig.saturday) ||
(day === 7 && workingDaysConfig.sunday)
) {
workingDays++;
}
current.add(1, 'day');
}
console.log("workingDays", workingDays);
console.log("Start date for working days:", startDate.format('YYYY-MM-DD'));
console.log("End date for working days:", endDate.format('YYYY-MM-DD'));
// Use organization working hours for total working hours
const totalWorkingHours = workingDays * orgWorkingHours;
// Get hours_per_day for all selected projects
const projectHoursQuery = `SELECT id, hours_per_day FROM projects WHERE id IN (${projectIds})`;
const projectHoursResult = await db.query(projectHoursQuery, []);
const projectHoursMap: Record<string, number> = {};
for (const row of projectHoursResult.rows) {
projectHoursMap[row.id] = row.hours_per_day || 8;
}
// Sum total working hours for all selected projects
let totalWorkingHours = 0;
for (const pid of Object.keys(projectHoursMap)) {
totalWorkingHours += workingDays * projectHoursMap[pid];
}
const durationClause = `AND DATE(task_work_log.created_at) >= '${startDate.format('YYYY-MM-DD')}' AND DATE(task_work_log.created_at) <= '${endDate.format('YYYY-MM-DD')}'`;
const durationClause = this.getDateRangeClause(duration || DATE_RANGES.LAST_WEEK, date_range);
const archivedClause = archived
? ""
: `AND p.id NOT IN (SELECT project_id FROM archived_projects WHERE project_id = p.id AND user_id = '${req.user?.id}') `;