| @@ -3,7 +3,7 @@ import { HolidaysResult } from "../holidays"; | |||||
| import { LeaveEntry, RecordTimeLeaveInput, TimeEntry } from "./actions"; | import { LeaveEntry, RecordTimeLeaveInput, TimeEntry } from "./actions"; | ||||
| import { convertDateArrayToString } from "@/app/utils/formatUtil"; | import { convertDateArrayToString } from "@/app/utils/formatUtil"; | ||||
| import compact from "lodash/compact"; | import compact from "lodash/compact"; | ||||
| import dayjs from "dayjs"; | |||||
| import dayjs, { Dayjs } from "dayjs"; | |||||
| export type TimeEntryError = { | export type TimeEntryError = { | ||||
| [field in keyof TimeEntry]?: string; | [field in keyof TimeEntry]?: string; | ||||
| @@ -117,6 +117,7 @@ export const validateTimeLeaveRecord = ( | |||||
| // Check total hours | // Check total hours | ||||
| const totalHourError = checkTotalHours( | const totalHourError = checkTotalHours( | ||||
| dayJsObj, | |||||
| entries.filter((e) => e.type === "timeEntry") as TimeEntry[], | entries.filter((e) => e.type === "timeEntry") as TimeEntry[], | ||||
| entries.filter((e) => e.type === "leaveEntry") as LeaveEntry[], | entries.filter((e) => e.type === "leaveEntry") as LeaveEntry[], | ||||
| isHoliday, | isHoliday, | ||||
| @@ -132,6 +133,7 @@ export const validateTimeLeaveRecord = ( | |||||
| }; | }; | ||||
| export const checkTotalHours = ( | export const checkTotalHours = ( | ||||
| dayJsObj: Dayjs, | |||||
| timeEntries: TimeEntry[], | timeEntries: TimeEntry[], | ||||
| leaves: LeaveEntry[], | leaves: LeaveEntry[], | ||||
| isHoliday?: boolean, | isHoliday?: boolean, | ||||
| @@ -152,6 +154,7 @@ export const checkTotalHours = ( | |||||
| } else if ( | } else if ( | ||||
| isFullTime && | isFullTime && | ||||
| !isHoliday && | !isHoliday && | ||||
| !dayJsObj.isSame(dayjs(), "day") && | |||||
| totalInputHours + leaveHours !== DAILY_NORMAL_MAX_HOURS | totalInputHours + leaveHours !== DAILY_NORMAL_MAX_HOURS | ||||
| ) { | ) { | ||||
| return "The daily normal hours (timesheet hours + leave hours) for full-time staffs should be {{DAILY_NORMAL_MAX_HOURS}}."; | return "The daily normal hours (timesheet hours + leave hours) for full-time staffs should be {{DAILY_NORMAL_MAX_HOURS}}."; | ||||
| @@ -27,7 +27,6 @@ import LeaveEditModal from "../LeaveTable/LeaveEditModal"; | |||||
| import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
| import { checkTotalHours } from "@/app/api/timesheets/utils"; | import { checkTotalHours } from "@/app/api/timesheets/utils"; | ||||
| import unionBy from "lodash/unionBy"; | import unionBy from "lodash/unionBy"; | ||||
| import { ConnectingAirportsOutlined } from "@mui/icons-material"; | |||||
| export interface Props { | export interface Props { | ||||
| leaveTypes: LeaveType[]; | leaveTypes: LeaveType[]; | ||||
| @@ -232,6 +231,7 @@ const LeaveCalendar: React.FC<Props> = ({ | |||||
| ); | ); | ||||
| const totalHourError = checkTotalHours( | const totalHourError = checkTotalHours( | ||||
| dayJsObj, | |||||
| timesheets, | timesheets, | ||||
| leavesWithNewEntry, | leavesWithNewEntry, | ||||
| Boolean(isHoliday), | Boolean(isHoliday), | ||||
| @@ -64,6 +64,8 @@ const modalSx: SxProps = { | |||||
| maxWidth: 1400, | maxWidth: 1400, | ||||
| }; | }; | ||||
| const DAYS_TO_SHOW = 10; | |||||
| const TimeLeaveModal: React.FC<Props> = ({ | const TimeLeaveModal: React.FC<Props> = ({ | ||||
| isOpen, | isOpen, | ||||
| onClose, | onClose, | ||||
| @@ -81,7 +83,7 @@ const TimeLeaveModal: React.FC<Props> = ({ | |||||
| const defaultValues = useMemo(() => { | const defaultValues = useMemo(() => { | ||||
| const today = dayjs(); | const today = dayjs(); | ||||
| return Array(7) | |||||
| return Array(DAYS_TO_SHOW) | |||||
| .fill(undefined) | .fill(undefined) | ||||
| .reduce<RecordTimeLeaveInput>((acc, _, index) => { | .reduce<RecordTimeLeaveInput>((acc, _, index) => { | ||||
| const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT); | const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT); | ||||
| @@ -123,7 +125,7 @@ const TimeLeaveModal: React.FC<Props> = ({ | |||||
| const savedRecords = await saveTimeLeave(data); | const savedRecords = await saveTimeLeave(data); | ||||
| const today = dayjs(); | const today = dayjs(); | ||||
| const newFormValues = Array(7) | |||||
| const newFormValues = Array(DAYS_TO_SHOW) | |||||
| .fill(undefined) | .fill(undefined) | ||||
| .reduce<RecordTimeLeaveInput>((acc, _, index) => { | .reduce<RecordTimeLeaveInput>((acc, _, index) => { | ||||
| const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT); | const date = today.subtract(index, "day").format(INPUT_DATE_FORMAT); | ||||
| @@ -41,7 +41,7 @@ import LeaveEditModal from "../LeaveTable/LeaveEditModal"; | |||||
| import dayjs from "dayjs"; | import dayjs from "dayjs"; | ||||
| import { checkTotalHours } from "@/app/api/timesheets/utils"; | import { checkTotalHours } from "@/app/api/timesheets/utils"; | ||||
| import unionBy from "lodash/unionBy"; | import unionBy from "lodash/unionBy"; | ||||
| import { Language, Luggage, MoreTime } from "@mui/icons-material"; | |||||
| import { Luggage, MoreTime } from "@mui/icons-material"; | |||||
| import { Task } from "@/app/api/tasks"; | import { Task } from "@/app/api/tasks"; | ||||
| export interface Props { | export interface Props { | ||||
| @@ -368,6 +368,7 @@ const TimesheetAmendment: React.FC<Props> = ({ | |||||
| "id", | "id", | ||||
| ); | ); | ||||
| totalHourError = checkTotalHours( | totalHourError = checkTotalHours( | ||||
| dayJsObj, | |||||
| timesheets, | timesheets, | ||||
| leavesWithNewEntry, | leavesWithNewEntry, | ||||
| Boolean(isHoliday), | Boolean(isHoliday), | ||||
| @@ -380,6 +381,7 @@ const TimesheetAmendment: React.FC<Props> = ({ | |||||
| "id", | "id", | ||||
| ); | ); | ||||
| totalHourError = checkTotalHours( | totalHourError = checkTotalHours( | ||||
| dayJsObj, | |||||
| timesheetsWithNewEntry, | timesheetsWithNewEntry, | ||||
| leaves, | leaves, | ||||
| Boolean(isHoliday), | Boolean(isHoliday), | ||||
| @@ -68,7 +68,7 @@ const getID = () => { | |||||
| }; | }; | ||||
| const MISC_TASK_GROUP_ID = 5; | const MISC_TASK_GROUP_ID = 5; | ||||
| const FAST_ENTRY_TASK_ID = 43; | |||||
| const FAST_ENTRY_TASK_ID = 42; | |||||
| const FastTimeEntryModal: React.FC<Props> = ({ | const FastTimeEntryModal: React.FC<Props> = ({ | ||||
| onSave, | onSave, | ||||
| @@ -61,7 +61,7 @@ const UserWorkspacePage: React.FC<Props> = ({ | |||||
| maintainNormalStaffWorkspaceAbility, | maintainNormalStaffWorkspaceAbility, | ||||
| maintainManagementStaffWorkspaceAbility, | maintainManagementStaffWorkspaceAbility, | ||||
| isFullTime, | isFullTime, | ||||
| miscTasks | |||||
| miscTasks, | |||||
| }) => { | }) => { | ||||
| const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); | const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); | ||||