Skip to content

#2033 - Validating FT and PT offering minimum length #2041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import {
ValidationOptions,
ValidationArguments,
} from "class-validator";
import {
OFFERING_STUDY_PERIOD_MAX_DAYS,
OFFERING_STUDY_PERIOD_MIN_DAYS,
} from "../../../utilities";
import { OFFERING_STUDY_PERIOD_MAX_DAYS } from "../../../utilities";
import { StudyBreak } from "../education-program-offering-validation.models";
import { OfferingCalculationValidationBaseConstraint } from "./offering-calculation-validation-base-constraint";

Expand All @@ -23,20 +20,32 @@ class HasValidOfferingPeriodForFundedDaysConstraint
implements ValidatorConstraintInterface
{
validate(studyBreaks: StudyBreak[], args: ValidationArguments): boolean {
const offeringMinDaysAllowedValue = this.getOfferingMinAllowedDays(args);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice implementation to pass the args from the form with respect to the offering intensity, but can this be shared done as a constant without passing them from the form?

const calculatedStudyBreaksAndWeeks = this.getCalculatedStudyBreaks(
studyBreaks,
args,
);
return (
calculatedStudyBreaksAndWeeks.fundedStudyPeriodDays >=
OFFERING_STUDY_PERIOD_MIN_DAYS &&
offeringMinDaysAllowedValue &&
calculatedStudyBreaksAndWeeks.fundedStudyPeriodDays <=
OFFERING_STUDY_PERIOD_MAX_DAYS
);
}

defaultMessage() {
return `The funded study amount of days is ineligible for StudentAid BC funding. Your dates must be between ${OFFERING_STUDY_PERIOD_MIN_DAYS} to ${OFFERING_STUDY_PERIOD_MAX_DAYS} days.`;
defaultMessage(args: ValidationArguments) {
const offeringMinDaysAllowedValue = this.getOfferingMinAllowedDays(args);
return `The funded study amount of days is ineligible for StudentAid BC funding. Your dates must be between ${offeringMinDaysAllowedValue} to ${OFFERING_STUDY_PERIOD_MAX_DAYS} days.`;
}

/**
* Get offering minimum allowed days from args.
* @param args validation arguments.
* @returns minimum allowed days.
*/
private getOfferingMinAllowedDays(args: ValidationArguments): number {
const [, , offeringMinDaysAllowed] = args.constraints;
return offeringMinDaysAllowed(args.object) as number;
}
}

Expand All @@ -46,12 +55,14 @@ class HasValidOfferingPeriodForFundedDaysConstraint
* allowed study period amount of days.
* @param startPeriodProperty property of the model that identifies the offering start date.
* @param endPeriodProperty property of the model that identifies the offering end date.
* @param offeringMinDaysAllowed study period minimum length in number of days.
* @param validationOptions validations options.
* @returns true if the study period is valid, otherwise, false.
*/
export function HasValidOfferingPeriodForFundedDays(
startPeriodProperty: (targetObject: unknown) => Date | string,
endPeriodProperty: (targetObject: unknown) => Date | string,
offeringMinDaysAllowed: (targetObject: unknown) => number,
validationOptions?: ValidationOptions,
) {
return (object: unknown, propertyName: string) => {
Expand All @@ -60,7 +71,11 @@ export function HasValidOfferingPeriodForFundedDays(
target: object.constructor,
propertyName,
options: validationOptions,
constraints: [startPeriodProperty, endPeriodProperty],
constraints: [
startPeriodProperty,
endPeriodProperty,
offeringMinDaysAllowed,
],
validator: HasValidOfferingPeriodForFundedDaysConstraint,
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ import {
OFFERING_STUDY_BREAK_MAX_DAYS,
OFFERING_STUDY_BREAK_MIN_DAYS,
OFFERING_STUDY_PERIOD_MAX_DAYS,
OFFERING_STUDY_PERIOD_MIN_DAYS,
OFFERING_STUDY_PERIOD_MIN_DAYS_FULL_TIME,
OFFERING_STUDY_PERIOD_MIN_DAYS_PART_TIME,
OFFERING_YEAR_OF_STUDY_MAX_VALUE,
OFFERING_YEAR_OF_STUDY_MIN_VALUE,
} from "../../utilities";
Expand Down Expand Up @@ -319,6 +320,18 @@ const studyStartDateProperty = (offering: OfferingValidationModel) =>
const studyEndDateProperty = (offering: OfferingValidationModel) =>
offering.studyEndDate;

/**
* Get study period minimum length based on offering intensity.
* @param offering offering.
* @returns minimum study period length in number of days.
*/
const studyPeriodMinLength = (offering: OfferingValidationModel) => {
if (offering.offeringIntensity === OfferingIntensity.fullTime) {
return OFFERING_STUDY_PERIOD_MIN_DAYS_FULL_TIME;
}
return OFFERING_STUDY_PERIOD_MIN_DAYS_PART_TIME;
};

/**
* Complete offering data with all validations needed to ensure data
* consistency. Program data and locations data need to be present to
Expand Down Expand Up @@ -353,7 +366,7 @@ export class OfferingValidationModel {
@IsDateAfter(studyStartDateProperty, userFriendlyNames.studyEndDate)
@PeriodMinLength(
studyStartDateProperty,
OFFERING_STUDY_PERIOD_MIN_DAYS,
studyPeriodMinLength,
userFriendlyNames.studyEndDate,
{
context: ValidationContext.CreateWarning(
Expand Down Expand Up @@ -595,6 +608,7 @@ export class OfferingValidationModel {
@HasValidOfferingPeriodForFundedDays(
studyStartDateProperty,
studyEndDateProperty,
studyPeriodMinLength,
{
context: ValidationContext.CreateWarning(
OfferingValidationWarnings.InvalidStudyDatesPeriodLength,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,38 @@ import { dateDifference, getDateOnlyFormat } from "@sims/utilities";
@ValidatorConstraint()
class PeriodMinLengthConstraint implements ValidatorConstraintInterface {
validate(value: Date | string, args: ValidationArguments): boolean {
const [startDateProperty, minDaysAllowed] = args.constraints;
const [startDateProperty] = args.constraints;
const minDaysAllowedValue = this.getMinAllowedDays(args);
const periodStartDate = startDateProperty(args.object);
if (!periodStartDate) {
// The related property does not exists in the provided object to be compared.
return false;
}
return dateDifference(value, periodStartDate) >= minDaysAllowed;
return dateDifference(value, periodStartDate) >= minDaysAllowedValue;
}

defaultMessage(args: ValidationArguments) {
const [startDateProperty, minDaysAllowed, propertyDisplayName] =
args.constraints;
const [startDateProperty, , propertyDisplayName] = args.constraints;
const startDate = getDateOnlyFormat(startDateProperty(args.object));
const endDate = getDateOnlyFormat(args.value);
const minDaysAllowedValue = this.getMinAllowedDays(args);
return `${
propertyDisplayName ?? args.property
}, the number of day(s) between ${startDate} and ${endDate} must be at least ${minDaysAllowed}.`;
}, the number of day(s) between ${startDate} and ${endDate} must be at least ${minDaysAllowedValue}.`;
}

/**
* Get minimum allowed days from args.
* @param args validation arguments.
* @returns minimum allowed days.
*/
private getMinAllowedDays(args: ValidationArguments): number {
const [, minDaysAllowed] = args.constraints;
const minDaysAllowedValue =
minDaysAllowed instanceof Function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool!

? minDaysAllowed(args.object)
: minDaysAllowed;
return minDaysAllowedValue as number;
}
}

Expand All @@ -42,14 +57,15 @@ class PeriodMinLengthConstraint implements ValidatorConstraintInterface {
* @param startDateProperty indicates the property that define the
* start of a period.
* @param minDaysAllowed min allowed days to the period be considered valid.
* This could be a number or a function that returns a value of minimum allowed days.
* @param propertyDisplayName user-friendly property name to be added to the
* validation message.
* @param validationOptions validations options.
* @returns true if the period amount of days is inside the min allowed days.
*/
export function PeriodMinLength(
startDateProperty: (targetObject: unknown) => Date | string,
minDaysAllowed: number,
minDaysAllowed: ((targetObject: unknown) => number) | number,
propertyDisplayName?: string,
validationOptions?: ValidationOptions,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,15 @@ export const OFFERING_COURSE_LOAD_MIN_VALUE = 20;
*/
export const OFFERING_COURSE_LOAD_MAX_VALUE = 59;
/**
* Minimum amount of days to an offering study period.
* Minimum amount of days required for a full time offering study period.
*/
export const OFFERING_STUDY_PERIOD_MIN_DAYS = 42;
export const OFFERING_STUDY_PERIOD_MIN_DAYS_FULL_TIME = 84;

/**
* Minimum amount of days required for a part time offering study period.
*/
export const OFFERING_STUDY_PERIOD_MIN_DAYS_PART_TIME = 42;

/**
* Maximum amount of days to an offering study period.
*/
Expand Down
Loading