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:
@@ -412,14 +412,8 @@ export default class ReportingAllocationController extends ReportingControllerBa
|
|||||||
let startDate: moment.Moment;
|
let startDate: moment.Moment;
|
||||||
let endDate: moment.Moment;
|
let endDate: moment.Moment;
|
||||||
if (date_range && date_range.length === 2) {
|
if (date_range && date_range.length === 2) {
|
||||||
// Parse simple YYYY-MM-DD dates
|
startDate = moment(date_range[0]);
|
||||||
startDate = moment(date_range[0]).startOf('day');
|
endDate = moment(date_range[1]);
|
||||||
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'));
|
|
||||||
} else if (duration === DATE_RANGES.ALL_TIME) {
|
} else if (duration === DATE_RANGES.ALL_TIME) {
|
||||||
// Fetch the earliest start_date (or created_at if null) from selected projects
|
// 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})`;
|
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");
|
startDate = moment().subtract(1, "day");
|
||||||
endDate = moment().subtract(1, "day");
|
endDate = moment().subtract(1, "day");
|
||||||
break;
|
break;
|
||||||
case DATE_RANGES.LAST_7_DAYS:
|
|
||||||
startDate = moment().subtract(7, "days");
|
|
||||||
endDate = moment();
|
|
||||||
break;
|
|
||||||
case DATE_RANGES.LAST_WEEK:
|
case DATE_RANGES.LAST_WEEK:
|
||||||
startDate = moment().subtract(1, "week").startOf("isoWeek");
|
startDate = moment().subtract(1, "week").startOf("isoWeek");
|
||||||
endDate = moment().subtract(1, "week").endOf("isoWeek");
|
endDate = moment().subtract(1, "week").endOf("isoWeek");
|
||||||
break;
|
break;
|
||||||
case DATE_RANGES.LAST_30_DAYS:
|
|
||||||
startDate = moment().subtract(30, "days");
|
|
||||||
endDate = moment();
|
|
||||||
break;
|
|
||||||
case DATE_RANGES.LAST_MONTH:
|
case DATE_RANGES.LAST_MONTH:
|
||||||
startDate = moment().subtract(1, "month").startOf("month");
|
startDate = moment().subtract(1, "month").startOf("month");
|
||||||
endDate = moment().subtract(1, "month").endOf("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
|
// Get organization working days
|
||||||
const selectedTeamId = req.user?.team_id;
|
const orgWorkingDaysQuery = `
|
||||||
let organizationId: string | undefined = undefined;
|
SELECT monday, tuesday, wednesday, thursday, friday, saturday, sunday
|
||||||
if (selectedTeamId) {
|
FROM organization_working_days
|
||||||
const orgIdQuery = `SELECT organization_id FROM teams WHERE id = $1`;
|
WHERE organization_id IN (
|
||||||
const orgIdResult = await db.query(orgIdQuery, [selectedTeamId]);
|
SELECT t.organization_id
|
||||||
organizationId = orgIdResult.rows[0]?.organization_id;
|
FROM teams t
|
||||||
}
|
WHERE t.id IN (${teamIds})
|
||||||
|
LIMIT 1
|
||||||
// Fetch organization working hours and working days
|
);
|
||||||
let orgWorkingHours = 8;
|
`;
|
||||||
let orgWorkingDays: { [key: string]: boolean } = {
|
const orgWorkingDaysResult = await db.query(orgWorkingDaysQuery, []);
|
||||||
monday: true, tuesday: true, wednesday: true, thursday: true, friday: true, saturday: false, sunday: false
|
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 workingDays = 0;
|
||||||
let current = startDate.clone();
|
let current = startDate.clone();
|
||||||
while (current.isSameOrBefore(endDate, 'day')) {
|
while (current.isSameOrBefore(endDate, 'day')) {
|
||||||
const weekday = current.format('dddd').toLowerCase(); // e.g., 'monday'
|
const day = current.isoWeekday();
|
||||||
if (orgWorkingDays[weekday]) workingDays++;
|
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');
|
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
|
// Get hours_per_day for all selected projects
|
||||||
const totalWorkingHours = workingDays * orgWorkingHours;
|
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
|
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}') `;
|
: `AND p.id NOT IN (SELECT project_id FROM archived_projects WHERE project_id = p.id AND user_id = '${req.user?.id}') `;
|
||||||
|
|||||||
Reference in New Issue
Block a user