fix(timesheets): ajusted type of function mapOneTimesheet
This commit is contained in:
parent
c59844560a
commit
14c00522db
|
|
@ -1,6 +1,5 @@
|
||||||
import { toDateFromString, toStringFromDate, weekStartSunday } from "src/time-and-attendance/utils/date-time.utils";
|
import { toDateFromString, toStringFromDate, weekStartSunday } from "src/time-and-attendance/utils/date-time.utils";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/time-and-attendance/utils/resolve-email-id.utils";
|
||||||
// import { NormalizedExpense } from "src/time-and-attendance/utils/type.utils";
|
|
||||||
import { expense_select } from "src/time-and-attendance/utils/selects.utils";
|
import { expense_select } from "src/time-and-attendance/utils/selects.utils";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { GetExpenseDto } from "src/time-and-attendance/expenses/dtos/expense-get.dto";
|
import { GetExpenseDto } from "src/time-and-attendance/expenses/dtos/expense-get.dto";
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { BankCodeEntity } from "src/modules/bank-codes/dtos/bank-code-entity";
|
|
||||||
|
|
||||||
export class ShiftEntity {
|
export class ShiftEntity {
|
||||||
id: number;
|
id: number;
|
||||||
timesheet_id: number;
|
timesheet_id: number;
|
||||||
|
|
@ -10,5 +8,4 @@ export class ShiftEntity {
|
||||||
is_remote: boolean;
|
is_remote: boolean;
|
||||||
is_approved: boolean;
|
is_approved: boolean;
|
||||||
comment?: string | null ;
|
comment?: string | null ;
|
||||||
bank_code?: BankCodeEntity;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { EmailToIdResolver } from "src/time-and-attendance/utils/resolve-email-id.utils";
|
import { EmailToIdResolver } from "src/time-and-attendance/utils/resolve-email-id.utils";
|
||||||
import { Timesheet, TimesheetEntity, Timesheets } from "src/time-and-attendance/time-tracker/timesheets/dtos/timesheet.dto";
|
import { Timesheet, TimesheetEntity, Timesheets } from "src/time-and-attendance/time-tracker/timesheets/dtos/timesheet.dto";
|
||||||
import { Result } from "src/common/errors/result-error.factory";
|
import { Result } from "src/common/errors/result-error.factory";
|
||||||
import { Users } from "@prisma/client";
|
import { Prisma, Users } from "@prisma/client";
|
||||||
import { ShiftEntity } from "src/time-and-attendance/time-tracker/shifts/dtos/shift-entity.dto";
|
import { ShiftEntity } from "src/time-and-attendance/time-tracker/shifts/dtos/shift-entity.dto";
|
||||||
import { ExpenseEntity } from "src/time-and-attendance/expenses/dtos/expense-entity.dto";
|
import { ExpenseEntity } from "src/time-and-attendance/expenses/dtos/expense-entity.dto";
|
||||||
|
|
||||||
|
|
@ -77,11 +77,11 @@ export class GetTimesheetsOverviewService {
|
||||||
//builds employee full name
|
//builds employee full name
|
||||||
const user = employee.user;
|
const user = employee.user;
|
||||||
const employee_fullname = `${user.first_name} ${user.last_name}`.trim();
|
const employee_fullname = `${user.first_name} ${user.last_name}`.trim();
|
||||||
|
|
||||||
|
|
||||||
//maps all timesheet's infos
|
//maps all timesheet's infos
|
||||||
const timesheets = await Promise.all(rows.map((timesheet) => this.mapOneTimesheet(timesheet)));
|
const timesheets = await Promise.all(rows.map((timesheet) => this.mapOneTimesheet(timesheet)));
|
||||||
if(!timesheets) return { success: false, error: 'an error occured during the mapping of a timesheet'}
|
if (!timesheets) return { success: false, error: 'an error occured during the mapping of a timesheet' }
|
||||||
|
|
||||||
return { success: true, data: { employee_fullname, timesheets } };
|
return { success: true, data: { employee_fullname, timesheets } };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -105,112 +105,118 @@ export class GetTimesheetsOverviewService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async mapOneTimesheet(timesheet: TimesheetResult): Promise<Timesheet> {
|
private async mapOneTimesheet(timesheet: Prisma.TimesheetsGetPayload<{
|
||||||
//converts string to UTC date format
|
include: {
|
||||||
const start = toDateFromString(timesheet.start_date);
|
employee: { include: { user } },
|
||||||
const day_dates = sevenDaysFrom(start);
|
shift: { include: { bank_code } },
|
||||||
|
expense: { include: { bank_code } },
|
||||||
|
}
|
||||||
|
}>): Promise<Timesheet> {
|
||||||
|
//converts string to UTC date format
|
||||||
|
const start = toDateFromString(timesheet.start_date);
|
||||||
|
const day_dates = sevenDaysFrom(start);
|
||||||
|
|
||||||
//map of shifts by days
|
//map of shifts by days
|
||||||
const shifts_by_date = new Map<string, any[]>();
|
const shifts_by_date = new Map<string, any[]>();
|
||||||
for (const shift of timesheet.shift) {
|
for (const shift of timesheet.shift) {
|
||||||
const date_string = toStringFromDate(shift.date);
|
const date_string = toStringFromDate(shift.date);
|
||||||
const arr = shifts_by_date.get(date_string) ?? [];
|
const arr = shifts_by_date.get(date_string) ?? [];
|
||||||
arr.push(shift);
|
arr.push(shift);
|
||||||
shifts_by_date.set(date_string, arr);
|
shifts_by_date.set(date_string, arr);
|
||||||
|
}
|
||||||
|
//map of expenses by days
|
||||||
|
const expenses_by_date = new Map<string, any[]>();
|
||||||
|
for (const expense of timesheet.expense) {
|
||||||
|
const date_string = toStringFromDate(expense.date);
|
||||||
|
const arr = expenses_by_date.get(date_string) ?? [];
|
||||||
|
arr.push(expense);
|
||||||
|
expenses_by_date.set(date_string, arr);
|
||||||
|
}
|
||||||
|
//weekly totals
|
||||||
|
const weekly_hours: TotalHours[] = [emptyHours()];
|
||||||
|
const weekly_expenses: TotalExpenses[] = [emptyExpenses()];
|
||||||
|
|
||||||
|
//map of days
|
||||||
|
const days = day_dates.map((date) => {
|
||||||
|
const date_iso = toStringFromDate(date);
|
||||||
|
const shifts_source = shifts_by_date.get(date_iso) ?? [];
|
||||||
|
const expenses_source = expenses_by_date.get(date_iso) ?? [];
|
||||||
|
|
||||||
|
//inner map of shifts
|
||||||
|
const shifts = shifts_source.map((shift) => ({
|
||||||
|
timesheet_id: shift.timesheet_id,
|
||||||
|
date: toStringFromDate(shift.date),
|
||||||
|
start_time: toHHmmFromDate(shift.start_time),
|
||||||
|
end_time: toHHmmFromDate(shift.end_time),
|
||||||
|
type: shift.bank_code?.type ?? '',
|
||||||
|
is_remote: shift.is_remote ?? false,
|
||||||
|
is_approved: shift.is_approved ?? false,
|
||||||
|
id: shift.id ?? null,
|
||||||
|
comment: shift.comment ?? null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
//inner map of expenses
|
||||||
|
const expenses = expenses_source.map((expense) => ({
|
||||||
|
date: toStringFromDate(expense.date),
|
||||||
|
amount: expense.amount != null ? Number(expense.amount) : undefined,
|
||||||
|
mileage: expense.mileage != null ? Number(expense.mileage) : undefined,
|
||||||
|
expense_id: expense.id ?? null,
|
||||||
|
attachment: expense.attachment_record ? String(expense.attachment_record.id) : undefined,
|
||||||
|
is_approved: expense.is_approved ?? false,
|
||||||
|
comment: expense.comment ?? '',
|
||||||
|
supervisor_comment: expense.supervisor_comment,
|
||||||
|
type: expense.type,
|
||||||
|
}));
|
||||||
|
|
||||||
|
//daily totals
|
||||||
|
const daily_hours = [emptyHours()];
|
||||||
|
const daily_expenses = [emptyExpenses()];
|
||||||
|
|
||||||
|
//totals by shift types
|
||||||
|
for (const shift of shifts_source) {
|
||||||
|
const hours = diffOfHours(shift.start_time, shift.end_time);
|
||||||
|
const subgroup = hoursSubGroupFromBankCode(shift.bank_code);
|
||||||
|
daily_hours[0][subgroup] += hours;
|
||||||
|
weekly_hours[0][subgroup] += hours;
|
||||||
}
|
}
|
||||||
//map of expenses by days
|
|
||||||
const expenses_by_date = new Map<string, any[]>();
|
//totals by expense types
|
||||||
for (const expense of timesheet.expense) {
|
for (const expense of expenses_source) {
|
||||||
const date_string = toStringFromDate(expense.date);
|
const subgroup = expenseSubgroupFromBankCode(expense.bank_code);
|
||||||
const arr = expenses_by_date.get(date_string) ?? [];
|
if (subgroup === 'mileage') {
|
||||||
arr.push(expense);
|
const mileage = num(expense.mileage);
|
||||||
expenses_by_date.set(date_string, arr);
|
daily_expenses[0].mileage += mileage;
|
||||||
|
weekly_expenses[0].mileage += mileage;
|
||||||
|
} else if (subgroup === 'per_diem') {
|
||||||
|
const amount = num(expense.amount);
|
||||||
|
daily_expenses[0].per_diem += amount;
|
||||||
|
weekly_expenses[0].per_diem += amount;
|
||||||
|
} else if (subgroup === 'on_call') {
|
||||||
|
const amount = num(expense.amount);
|
||||||
|
daily_expenses[0].on_call += amount;
|
||||||
|
weekly_expenses[0].on_call += amount;
|
||||||
|
} else {
|
||||||
|
const amount = num(expense.amount);
|
||||||
|
daily_expenses[0].expenses += amount;
|
||||||
|
weekly_expenses[0].expenses += amount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//weekly totals
|
|
||||||
const weekly_hours: TotalHours[] = [emptyHours()];
|
|
||||||
const weekly_expenses: TotalExpenses[] = [emptyExpenses()];
|
|
||||||
|
|
||||||
//map of days
|
|
||||||
const days = day_dates.map((date) => {
|
|
||||||
const date_iso = toStringFromDate(date);
|
|
||||||
const shifts_source = shifts_by_date.get(date_iso) ?? [];
|
|
||||||
const expenses_source = expenses_by_date.get(date_iso) ?? [];
|
|
||||||
|
|
||||||
//inner map of shifts
|
|
||||||
const shifts = shifts_source.map((shift) => ({
|
|
||||||
timesheet_id: shift.timesheet_id,
|
|
||||||
date: toStringFromDate(shift.date),
|
|
||||||
start_time: toHHmmFromDate(shift.start_time),
|
|
||||||
end_time: toHHmmFromDate(shift.end_time),
|
|
||||||
type: shift.bank_code?.type ?? '',
|
|
||||||
is_remote: shift.is_remote ?? false,
|
|
||||||
is_approved: shift.is_approved ?? false,
|
|
||||||
id: shift.id ?? null,
|
|
||||||
comment: shift.comment ?? null,
|
|
||||||
}));
|
|
||||||
|
|
||||||
//inner map of expenses
|
|
||||||
const expenses = expenses_source.map((expense) => ({
|
|
||||||
date: toStringFromDate(expense.date),
|
|
||||||
amount: expense.amount != null ? Number(expense.amount) : undefined,
|
|
||||||
mileage: expense.mileage != null ? Number(expense.mileage) : undefined,
|
|
||||||
expense_id: expense.id ?? null,
|
|
||||||
attachment: expense.attachment_record ? String(expense.attachment_record.id) : undefined,
|
|
||||||
is_approved: expense.is_approved ?? false,
|
|
||||||
comment: expense.comment ?? '',
|
|
||||||
supervisor_comment: expense.supervisor_comment,
|
|
||||||
type: expense.type,
|
|
||||||
}));
|
|
||||||
|
|
||||||
//daily totals
|
|
||||||
const daily_hours = [emptyHours()];
|
|
||||||
const daily_expenses = [emptyExpenses()];
|
|
||||||
|
|
||||||
//totals by shift types
|
|
||||||
for (const shift of shifts_source) {
|
|
||||||
const hours = diffOfHours(shift.start_time, shift.end_time);
|
|
||||||
const subgroup = hoursSubGroupFromBankCode(shift.bank_code);
|
|
||||||
daily_hours[0][subgroup] += hours;
|
|
||||||
weekly_hours[0][subgroup] += hours;
|
|
||||||
}
|
|
||||||
|
|
||||||
//totals by expense types
|
|
||||||
for (const expense of expenses_source) {
|
|
||||||
const subgroup = expenseSubgroupFromBankCode(expense.bank_code);
|
|
||||||
if (subgroup === 'mileage') {
|
|
||||||
const mileage = num(expense.mileage);
|
|
||||||
daily_expenses[0].mileage += mileage;
|
|
||||||
weekly_expenses[0].mileage += mileage;
|
|
||||||
} else if (subgroup === 'per_diem') {
|
|
||||||
const amount = num(expense.amount);
|
|
||||||
daily_expenses[0].per_diem += amount;
|
|
||||||
weekly_expenses[0].per_diem += amount;
|
|
||||||
} else if (subgroup === 'on_call') {
|
|
||||||
const amount = num(expense.amount);
|
|
||||||
daily_expenses[0].on_call += amount;
|
|
||||||
weekly_expenses[0].on_call += amount;
|
|
||||||
} else {
|
|
||||||
const amount = num(expense.amount);
|
|
||||||
daily_expenses[0].expenses += amount;
|
|
||||||
weekly_expenses[0].expenses += amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
date: date_iso,
|
|
||||||
shifts,
|
|
||||||
expenses,
|
|
||||||
daily_hours,
|
|
||||||
daily_expenses,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
timesheet_id: timesheet.id,
|
date: date_iso,
|
||||||
is_approved: timesheet.is_approved ?? false,
|
shifts,
|
||||||
days,
|
expenses,
|
||||||
weekly_hours,
|
daily_hours,
|
||||||
weekly_expenses,
|
daily_expenses,
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
timesheet_id: timesheet.id,
|
||||||
|
is_approved: timesheet.is_approved ?? false,
|
||||||
|
days,
|
||||||
|
weekly_hours,
|
||||||
|
weekly_expenses,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private ensureTimesheet = async (employee_id: number, start_date: Date | string) => {
|
private ensureTimesheet = async (employee_id: number, start_date: Date | string) => {
|
||||||
|
|
@ -246,14 +252,6 @@ export class GetTimesheetsOverviewService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TimesheetResult extends TimesheetEntity {
|
|
||||||
employee: {
|
|
||||||
user: Users
|
|
||||||
},
|
|
||||||
shift: ShiftEntity[],
|
|
||||||
expense: ExpenseEntity[],
|
|
||||||
}
|
|
||||||
|
|
||||||
//filled array with default values
|
//filled array with default values
|
||||||
const emptyHours = (): TotalHours => { return { regular: 0, evening: 0, emergency: 0, overtime: 0, vacation: 0, holiday: 0, sick: 0 } };
|
const emptyHours = (): TotalHours => { return { regular: 0, evening: 0, emergency: 0, overtime: 0, vacation: 0, holiday: 0, sick: 0 } };
|
||||||
const emptyExpenses = (): TotalExpenses => { return { expenses: 0, per_diem: 0, on_call: 0, mileage: 0 } };
|
const emptyExpenses = (): TotalExpenses => { return { expenses: 0, per_diem: 0, on_call: 0, mileage: 0 } };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user