@@ -32,7 +32,7 @@ export const truncateMoney = (amount: number | undefined) => { | |||
const fractionDigits = maximumFractionDigits ?? minimumFractionDigits ?? 0; | |||
const factor = Math.pow(10, fractionDigits); | |||
const truncatedAmount = Math.floor(amount * factor) / factor; | |||
const truncatedAmount = Math.round(amount * factor) / factor; | |||
return truncatedAmount; | |||
}; | |||
@@ -59,7 +59,7 @@ import { | |||
} from "../Swal/CustomAlerts"; | |||
import dayjs from "dayjs"; | |||
import { DELETE_PROJECT } from "@/middleware"; | |||
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; | |||
import { OUTPUT_DATE_FORMAT, sumMoney } from "@/app/utils/formatUtil"; | |||
import { deleteDraft, loadDraft, saveToLocalStorage } from "@/app/utils/draftUtils"; | |||
export interface Props { | |||
@@ -273,7 +273,7 @@ const CreateProject: React.FC<Props> = ({ | |||
const onSubmit = useCallback<SubmitHandler<CreateProjectInputs>>( | |||
async (data, event) => { | |||
try { | |||
console.log(data); | |||
// console.log(data); | |||
// detect errors | |||
let hasErrors = false; | |||
@@ -374,30 +374,43 @@ const CreateProject: React.FC<Props> = ({ | |||
data.milestones[parseFloat(key)].startDate = null | |||
data.milestones[parseFloat(key)].endDate = null | |||
} | |||
// if ( | |||
// !Boolean(startDate) || | |||
// startDate === "Invalid Date" || | |||
// !Boolean(endDate) || | |||
// endDate === "Invalid Date" || | |||
// new Date(startDate) > new Date(endDate) | |||
// ) { | |||
// formProps.setError("milestones", { | |||
// message: "milestones is not valid", | |||
// type: "invalid", | |||
// }); | |||
// setTabIndex(3); | |||
// hasErrors = true; | |||
// } | |||
/* | |||
unused code for checking the stage start date and end date | |||
if ( | |||
!Boolean(startDate) || | |||
startDate === "Invalid Date" || | |||
!Boolean(endDate) || | |||
endDate === "Invalid Date" || | |||
new Date(startDate) > new Date(endDate) | |||
) { | |||
formProps.setError("milestones", { | |||
message: "milestones is not valid", | |||
type: "invalid", | |||
}); | |||
setTabIndex(3); | |||
hasErrors = true; | |||
} | |||
unused code for bulk add milestone payment | |||
projectTotal += payments.reduce( | |||
(acc, payment) => acc + payment.amount, | |||
0, | |||
); | |||
**/ | |||
projectTotal += payments.reduce( | |||
(acc, p) => sumMoney(acc, p.amount), | |||
0, | |||
); | |||
}); | |||
// console.log(projectTotal) | |||
console.log(milestonesKeys) | |||
if ( | |||
projectTotal !== data.expectedProjectFee || | |||
milestonesKeys.length !== taskGroupKeys.length | |||
projectTotal !== data.expectedProjectFee | |||
// || milestonesKeys.length !== taskGroupKeys.length | |||
) { | |||
formProps.setError("milestones", { | |||
message: "milestones is not valid", | |||
@@ -484,7 +497,7 @@ const CreateProject: React.FC<Props> = ({ | |||
setServerError(t("An error has occurred. Please try again later.")); | |||
} | |||
}, | |||
[router, t], | |||
[router, t, draftId], | |||
); | |||
const onSubmitError = useCallback<SubmitErrorHandler<CreateProjectInputs>>( | |||
@@ -565,6 +578,7 @@ const CreateProject: React.FC<Props> = ({ | |||
const saveDraft = useCallback(async () => { | |||
const currentTimestamp = Date.now() | |||
console.log(currentTimestamp) | |||
saveToLocalStorage(draftId || currentTimestamp, formProps.getValues()); | |||
@@ -83,7 +83,7 @@ const CreateProjectWrapper: React.FC<Props> = async (props) => { | |||
var filteredTeamLeads = teamId ? teamLeads.filter( | |||
(teamLead) => teamLead.teamId === teamId, | |||
) : teamLeads | |||
if (userStaff?.id !== null && userStaff?.id == 1) { | |||
if (userStaff?.id != null && userStaff?.id == 1) { | |||
filteredTeamLeads = teamLeads.filter( | |||
(teamLead) => teamLead.teamId === teamId || teamLead.team == "ST", | |||
) | |||
@@ -23,6 +23,7 @@ import { useFormContext } from "react-hook-form"; | |||
import { CreateProjectInputs } from "@/app/api/projects/actions"; | |||
import MilestoneSection from "./MilestoneSection"; | |||
import ProjectTotalFee from "./ProjectTotalFee"; | |||
import { sumMoney } from "@/app/utils/formatUtil"; | |||
export interface Props { | |||
allTasks: Task[]; | |||
@@ -89,10 +90,17 @@ const Milestone: React.FC<Props> = ({ allTasks, isActive }) => { | |||
// hasError = true | |||
// } | |||
projectTotal += payments.reduce((acc, payment) => acc + payment.amount, 0) | |||
// projectTotal += payments.reduce((acc, payment) => acc + payment.amount, 0) | |||
projectTotal += payments.reduce( | |||
(acc, p) => sumMoney(acc, p.amount), | |||
0, | |||
); | |||
}) | |||
console.log(milestonesKeys) | |||
if (projectTotal !== expectedTotalFee || milestonesKeys.length !== taskGroupsIds.length) { | |||
// if (projectTotal !== expectedTotalFee || milestonesKeys.length !== taskGroupsIds.length) { | |||
if (projectTotal !== expectedTotalFee) { | |||
hasError = true | |||
} | |||
// console.log(Object.keys(milestones).reduce((acc, key) => acc + milestones[parseFloat(key)].payments.reduce((acc2, value) => acc2 + value.amount, 0), 0)) | |||
@@ -242,18 +242,18 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||
// (acc, wn) => ({ ...acc, [wn.id]: wn.name }), | |||
// {}, | |||
// ); | |||
const planStart = getValues("projectPlanStart") | |||
const planEnd = getValues("projectPlanEnd") | |||
const planStart = watch("projectPlanStart") | |||
const planEnd = watch("projectPlanEnd") | |||
useEffect(() => { | |||
let hasErrors = false | |||
if( | |||
!planStart || planStart > planEnd | |||
!planStart || new Date(planStart) > new Date(planEnd) | |||
){ | |||
hasErrors = true; | |||
} | |||
if( | |||
!planEnd || planStart > planEnd | |||
!planEnd || new Date(planStart) > new Date(planEnd) | |||
){ | |||
hasErrors = true; | |||
} | |||
@@ -26,7 +26,7 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; | |||
import { DemoItem } from "@mui/x-date-pickers/internals/demo"; | |||
import dayjs from "dayjs"; | |||
import { INPUT_DATE_FORMAT } from "@/app/utils/formatUtil"; | |||
import TableModal from "./TableModal"; | |||
// import TableModal from "./TableModal"; | |||
import { Preview } from "@mui/icons-material"; | |||
import SalaryEffectiveModel from "../EditStaff/SalaryEffectiveModel"; | |||
import TeamHistoryModal from "../EditStaff/TeamHistoryModal"; | |||
@@ -13,12 +13,14 @@ interface Props { | |||
leaveTypes: LeaveType[]; | |||
timesheetRecords: RecordTimesheetInput; | |||
companyHolidays: HolidaysResult[]; | |||
isSaturdayWorker: boolean; | |||
} | |||
const LeaveTable: React.FC<Props> = ({ | |||
leaveTypes, | |||
timesheetRecords, | |||
companyHolidays, | |||
isSaturdayWorker | |||
}) => { | |||
const { watch } = useFormContext<RecordLeaveInput>(); | |||
const currentInput = watch(); | |||
@@ -32,6 +34,7 @@ const LeaveTable: React.FC<Props> = ({ | |||
timesheetEntries={timesheetRecords} | |||
EntryTableComponent={LeaveEntryTable} | |||
entryTableProps={{ leaveTypes }} | |||
isSaturdayWorker={isSaturdayWorker} | |||
/> | |||
); | |||
}; | |||
@@ -110,10 +110,19 @@ const NavigationContent: React.FC<Props> = ({ abilities, username }) => { | |||
path: "/home", | |||
showOnMobile: true, | |||
}, | |||
// { | |||
// icon: <SummarizeIcon />, | |||
// label: "Financial Summary", | |||
// path: "/dashboard/ProjectFinancialSummary", | |||
// isHidden: ![VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) => | |||
// abilities!.includes(ability), | |||
// ), | |||
// showOnMobile: false, | |||
// }, | |||
{ | |||
icon: <SummarizeIcon />, | |||
label: "Financial Summary", | |||
path: "/dashboard/ProjectFinancialSummary", | |||
path: "/dashboard/ProjectFinancialSummaryV2", | |||
isHidden: ![VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) => | |||
abilities!.includes(ability), | |||
), | |||
@@ -172,16 +181,6 @@ const NavigationContent: React.FC<Props> = ({ abilities, username }) => { | |||
}, | |||
], | |||
}, | |||
// { | |||
// icon: <SummarizeIcon />, | |||
// label: "Financial Summary", | |||
// path: "/dashboard/ProjectFinancialSummaryV2", | |||
// isHidden: ![VIEW_DASHBOARD_ALL, VIEW_DASHBOARD_SELF].some((ability) => | |||
// abilities!.includes(ability), | |||
// ), | |||
// showOnMobile: true, | |||
// }, | |||
// No Claim function in Breaur, will be implement later | |||
// { | |||