@@ -59,8 +59,8 @@ export interface CreateProjectInputs { | |||
// Milestones | |||
milestones: { | |||
[taskGroupId: TaskGroup["id"]]: { | |||
startDate: string; | |||
endDate: string; | |||
startDate: string | null; | |||
endDate: string | null; | |||
payments: PaymentInputs[]; | |||
}; | |||
}; | |||
@@ -96,7 +96,9 @@ const hasErrorsInTab = ( | |||
errors.projectName || | |||
errors.projectDescription || | |||
errors.clientId || | |||
errors.projectCode | |||
errors.projectCode || | |||
errors.projectPlanStart || | |||
errors.projectPlanEnd | |||
); | |||
case 2: | |||
return ( | |||
@@ -273,6 +275,17 @@ const CreateProject: React.FC<Props> = ({ | |||
// detect errors | |||
let hasErrors = false; | |||
if( | |||
!data.projectPlanStart || !data.projectPlanEnd | |||
){ | |||
formProps.setError("projectPlanStart", { | |||
message: "projectPlanStart is not valid", | |||
type: "required", | |||
}); | |||
setTabIndex(0); | |||
hasErrors = true; | |||
} | |||
// Tab - Staff Allocation and Resource | |||
if ( | |||
data.totalManhour === null || | |||
@@ -349,21 +362,29 @@ const CreateProject: React.FC<Props> = ({ | |||
.forEach((key) => { | |||
const { startDate, endDate, payments } = | |||
data.milestones[parseFloat(key)]; | |||
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; | |||
} | |||
if ( | |||
!Boolean(startDate) || | |||
startDate === "Invalid Date" || | |||
!Boolean(endDate) || | |||
endDate === "Invalid Date" | |||
){ | |||
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; | |||
// } | |||
projectTotal += payments.reduce( | |||
(acc, payment) => acc + payment.amount, | |||
@@ -471,7 +492,9 @@ const CreateProject: React.FC<Props> = ({ | |||
errors.projectName || | |||
errors.projectDescription || | |||
errors.projectCode || | |||
errors.clientId | |||
errors.clientId || | |||
errors.projectPlanStart || | |||
errors.projectPlanEnd | |||
) { | |||
setTabIndex(0); | |||
} else if ( | |||
@@ -85,9 +85,9 @@ const Milestone: React.FC<Props> = ({ allTasks, isActive }) => { | |||
milestonesKeys.forEach(key => { | |||
const { startDate, endDate, payments } = milestones[parseFloat(key)] | |||
if (new Date(startDate) > new Date(endDate) || !Boolean(startDate) || !Boolean(endDate)) { | |||
hasError = true | |||
} | |||
// if (new Date(startDate) > new Date(endDate) || !Boolean(startDate) || !Boolean(endDate)) { | |||
// hasError = true | |||
// } | |||
projectTotal += payments.reduce((acc, payment) => acc + payment.amount, 0) | |||
}) | |||
@@ -326,7 +326,7 @@ const MilestoneSection: React.FC<Props> = ({ taskGroupId }) => { | |||
<Typography variant="overline" display="block" marginBlockEnd={1}> | |||
{t("Stage Milestones")} | |||
</Typography> | |||
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> | |||
{/* <Grid container spacing={2} columns={{ xs: 6, sm: 12 }}> | |||
<Grid item xs> | |||
<FormControl fullWidth> | |||
<DatePicker | |||
@@ -385,7 +385,7 @@ const MilestoneSection: React.FC<Props> = ({ taskGroupId }) => { | |||
/> | |||
</FormControl> | |||
</Grid> | |||
</Grid> | |||
</Grid> */} | |||
<Box | |||
sx={(theme) => ({ | |||
marginBlockStart: 1, | |||
@@ -86,6 +86,8 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||
getValues, | |||
reset, | |||
resetField, | |||
setError, | |||
clearErrors | |||
} = useFormContext<CreateProjectInputs>(); | |||
const subsidiaryMap = useMemo<{ | |||
@@ -242,6 +244,34 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||
const planStart = getValues("projectPlanStart") | |||
const planEnd = getValues("projectPlanEnd") | |||
useEffect(() => { | |||
let hasErrors = false | |||
if( | |||
!planStart || planStart > planEnd | |||
){ | |||
hasErrors = true; | |||
} | |||
if( | |||
!planEnd || planStart > planEnd | |||
){ | |||
hasErrors = true; | |||
} | |||
if(hasErrors){ | |||
setError("projectPlanStart", { | |||
message: "Project Plan Start date is not valid", | |||
type: "required", | |||
}); | |||
setError("projectPlanEnd", { | |||
message: "Project Plan End date is not valid", | |||
type: "required", | |||
}); | |||
}else{ | |||
clearErrors("projectPlanStart") | |||
clearErrors("projectPlanEnd") | |||
} | |||
},[planStart, planEnd]) | |||
return ( | |||
<Card sx={{ display: isActive ? "block" : "none" }}> | |||
<CardContent component={Stack} spacing={4}> | |||
@@ -311,8 +341,10 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||
textField: { | |||
// required: true, | |||
error: | |||
Boolean(errors.projectPlanStart) | |||
|| new Date(planStart) > new Date(planEnd) | |||
// Boolean(errors.projectPlanStart) | |||
// || | |||
new Date(planStart) > new Date(planEnd) | |||
|| !Boolean(planStart) | |||
, | |||
}, | |||
}} | |||
@@ -335,9 +367,12 @@ const ProjectClientDetails: React.FC<Props> = ({ | |||
}} | |||
slotProps={{ | |||
textField: { | |||
// required: true, | |||
error: | |||
Boolean(errors.projectPlanEnd) | |||
|| new Date(planStart) > new Date(planEnd) | |||
// Boolean(errors.projectPlanEnd) | |||
// || | |||
new Date(planStart) > new Date(planEnd) | |||
|| !Boolean(planEnd) | |||
, | |||
}, | |||
}} | |||