UNPKG

@syncfusion/ej2-gantt

Version:
973 lines 96.2 kB
import { isNullOrUndefined, getValue, setValue } from '@syncfusion/ej2-base'; import { ConstraintType } from './enum'; /** * Date processor is used to handle date of task data. */ var DateProcessor = /** @class */ (function () { function DateProcessor(parent) { this.fromSegments = false; this.mondayTimeRangeLength = 0; this.tuesdayTimeRangeLength = 0; this.wednesdayTimeRangeLength = 0; this.thursdayTimeRangeLength = 0; this.fridayTimeRangeLength = 0; this.saturdayTimeRangeLength = 0; this.sundayTimeRangeLength = 0; this.parent = parent; } /** * @param {ITaskData} ganttProp . * @returns {boolean} . */ DateProcessor.prototype.isValidateNonWorkDays = function (ganttProp) { return (!isNullOrUndefined(ganttProp) && ganttProp.isAutoSchedule && (!this.parent.includeWeekend || this.parent.totalHolidayDates.length > 0)) || (isNullOrUndefined(ganttProp) && (!this.parent.includeWeekend || this.parent.totalHolidayDates.length > 0)); }; /** * Method to convert given date value as valid start date * * @param {Date} date . * @param {ITaskData} ganttProp - The Gantt properties related to the task. * @param {boolean} validateAsMilestone - Indicates whether the date should be validated as a milestone. * @param {boolean} isLoad - A flag indicating if the method is called during the loading process. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {Date} . * @private */ DateProcessor.prototype.checkStartDate = function (date, ganttProp, validateAsMilestone, isLoad, isBaseline) { if (isNullOrUndefined(date)) { return null; } var currentDay = new Date(date.getTime()); var dayStartTime = this.parent['getCurrentDayStartTime'](currentDay); var dayEndTime = this.parent['getCurrentDayEndTime'](currentDay); var cloneStartDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneStartDate); validateAsMilestone = isNullOrUndefined(validateAsMilestone) ? !isNullOrUndefined(ganttProp) ? ganttProp.isMilestone : false : validateAsMilestone; if (hour < dayStartTime && (!validateAsMilestone || isLoad)) { this.setTime(dayStartTime, cloneStartDate); } else if (hour < dayStartTime && validateAsMilestone) { this.setTime(dayStartTime, cloneStartDate); } else if ((hour === dayEndTime && (!ganttProp || !validateAsMilestone)) || hour > dayEndTime) { cloneStartDate.setDate(cloneStartDate.getDate() + 1); dayStartTime = this.parent['getCurrentDayStartTime'](cloneStartDate); this.setTime(dayStartTime, cloneStartDate); } else if (hour > dayStartTime && hour < dayEndTime) { var workingRange = this.parent.workingTimeRanges; if (this.parent.weekWorkingTime.length > 0) { workingRange = this.parent['getWorkingRange'](cloneStartDate); } for (var index = 0; index < workingRange.length; index++) { var value = workingRange[index]; if (hour >= value.to && (workingRange[index + 1] && hour < workingRange[index + 1].from)) { // milestone can fall at end any interval time if ((hour === value.to && (!ganttProp || !validateAsMilestone)) || hour !== value.to) { this.setTime(workingRange[index + 1].from, cloneStartDate); } break; } } } var tStartDate; if (this.parent.autoCalculateDateScheduling && !(this.parent.isLoad && this.parent.treeGrid.loadChildOnDemand && this.parent.taskFields.hasChildMapping)) { do { tStartDate = new Date(cloneStartDate.getTime()); var holidayLength = this.parent.totalHolidayDates.length; // check holidays and weekends if (this.isValidateNonWorkDays(ganttProp)) { dayStartTime = this.parent['getCurrentDayStartTime'](tStartDate); if (ganttProp) { if (!isBaseline) { dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.endDate ? ganttProp.isAutoSchedule ? ganttProp.endDate : ganttProp.autoEndDate : tStartDate); } else { dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.baselineEndDate ? ganttProp.baselineEndDate : tStartDate); } } var startTime = (!validateAsMilestone || isLoad) ? dayStartTime : dayEndTime; if (!this.parent.includeWeekend && !isBaseline) { var tempDate = new Date(cloneStartDate.getTime()); cloneStartDate = this.getNextWorkingDay(cloneStartDate); startTime = this.parent['getCurrentDayStartTime'](cloneStartDate); if (tempDate.getTime() !== cloneStartDate.getTime() && !validateAsMilestone) { this.setTime(startTime, cloneStartDate); } } if (!isBaseline) { for (var count = 0; count < holidayLength; count++) { var holidayFrom = this.getDateFromFormat(new Date(this.parent.totalHolidayDates[count])); var holidayTo = new Date(holidayFrom.getTime()); holidayFrom.setHours(0, 0, 0, 0); holidayTo.setHours(23, 59, 59, 59); if (cloneStartDate.getTime() >= holidayFrom.getTime() && cloneStartDate.getTime() < holidayTo.getTime()) { cloneStartDate.setDate(cloneStartDate.getDate() + 1); startTime = this.parent['getCurrentDayStartTime'](cloneStartDate); this.setTime(startTime, cloneStartDate); } } } } } while (tStartDate.getTime() !== cloneStartDate.getTime()); return new Date(cloneStartDate.getTime()); } else { return new Date(cloneStartDate.getTime()); } }; DateProcessor.prototype.getAdjustedStartDate = function (constraintDate, ganttProp) { var adjustedDate = new Date(constraintDate); adjustedDate.setDate(adjustedDate.getDate() + 1); var checkedEnd = this.parent.dateValidationModule.checkEndDate(adjustedDate); return this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp); }; DateProcessor.prototype.getDateByConstraint = function (ganttData, date, validPredecessor) { var ganttProp = ganttData['ganttProperties'] ? ganttData['ganttProperties'] : ganttData; var constraintDate = new Date(ganttProp.constraintDate); var isLoad = this.parent.isLoad; if (isNullOrUndefined(validPredecessor)) { validPredecessor = true; } if ((!constraintDate || !date) && validPredecessor) { return null; } if (this.parent.editModule && this.parent.editModule.dialogModule && this.parent.editModule.dialogModule['dialogConstraintDate']) { constraintDate = new Date(this.parent.editModule.dialogModule['dialogConstraintDate']); } else { constraintDate = this.parent['assignTimeToDate'](constraintDate, this.parent['getCurrentDayStartTime'](constraintDate)); } var parentRecord = null; var record = this.parent.getRecordByID(ganttProp.taskId); if (record && record.parentItem) { parentRecord = record.parentItem; } switch (ganttProp.constraintType) { case ConstraintType.AsSoonAsPossible: if (isLoad) { return date; } else { ganttProp.constraintDate = null; if (ganttProp.predecessor && ganttProp.predecessor.length > 0) { return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } else if (parentRecord) { return this.parent.getRecordByID(parentRecord.taskId).ganttProperties.startDate; } else { return this.parent.dateValidationModule.checkStartDate(new Date(this.parent.projectStartDate)); } } case ConstraintType.AsLateAsPossible: if (isLoad) { return date; } else { if (parentRecord) { var checkedEnd = this.parent.dateValidationModule.checkEndDate(this.parent.getRecordByID(parentRecord.taskId).ganttProperties.endDate); var start = this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp); return start; } else { var checkedEnd = this.parent.dateValidationModule.checkEndDate(new Date(this.parent.projectEndDate)); var start = this.parent.dateValidationModule.getStartDate(checkedEnd, ganttProp.duration, ganttProp.durationUnit, ganttProp); return start; } } case ConstraintType.MustStartOn: { var isViolation = constraintDate.getTime() !== ganttProp.startDate.getTime(); var constraintValue = void 0; if (this.parent.editModule && this.parent.editModule.dialogModule) { constraintValue = this.parent.editModule.dialogModule['dialogConstraintValue']; } var isConstraintTypeRestricted = isNullOrUndefined(constraintValue) || constraintValue === 2 || constraintValue === 3; if (isViolation && !isLoad && isConstraintTypeRestricted) { this.parent.constraintViolationType = 'MustStartOn'; } constraintValue = null; if (isLoad) { return this.parent.dateValidationModule.checkStartDate(new Date(constraintDate)); } else { return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } } case ConstraintType.MustFinishOn: { var isViolation = constraintDate.getTime() !== ganttProp.endDate.getTime(); if (isViolation && !isLoad) { this.parent.constraintViolationType = 'MustFinishOn'; } return this.getAdjustedStartDate(constraintDate, ganttProp); } case ConstraintType.StartNoEarlierThan: { if (constraintDate.getTime() < date.getTime() || !isLoad) { return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } return this.parent.dateValidationModule.checkStartDate(new Date(constraintDate)); } case ConstraintType.StartNoLaterThan: { var isViolation = constraintDate.getTime() < date.getTime(); if (isViolation && !isLoad) { this.parent.constraintViolationType = 'StartNoLaterThan'; } if (!isLoad) { var cellEditModule = this.parent.editModule && this.parent.editModule.cellEditModule; var constraintField = this.parent.taskFields && this.parent.taskFields.constraintDate; if (cellEditModule && cellEditModule.isCellEdit && cellEditModule.editedColumn && isViolation && cellEditModule.editedColumn.field === constraintField) { return constraintDate; } if (this.parent.editModule && this.parent.editModule.dialogModule && isViolation && this.parent.editModule.dialogModule['dialogConstraintDate']) { return constraintDate; } return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayStartTime'](date)); } if (isViolation && isLoad) { return this.parent.dateValidationModule.checkStartDate(new Date(constraintDate)); } else { return date; } } case ConstraintType.FinishNoEarlierThan: { var endDate = this.getEndDate(date, ganttProp.duration, ganttProp.durationUnit, ganttProp, false, false); if (endDate.getTime() < constraintDate.getTime()) { return this.getAdjustedStartDate(constraintDate, ganttProp); } else { return date; } } case ConstraintType.FinishNoLaterThan: { var endDate = this.getEndDate(date, ganttProp.duration, ganttProp.durationUnit, ganttProp, false, false); var isViolation = constraintDate.getTime() < endDate.getTime(); if (isViolation && !isLoad) { this.parent.constraintViolationType = 'FinishNoLaterThan'; } if (!isLoad) { if (isViolation) { return this.getAdjustedStartDate(constraintDate, ganttProp); } return this.parent['assignTimeToDate'](date, this.parent['getCurrentDayEndTime'](date)); } if (isViolation) { return this.getAdjustedStartDate(constraintDate, ganttProp); } else { return date; } } default: return date; } }; /** * To update given date value to valid end date * * @param {Date} date . * @param {ITaskData} ganttProp . * @param {boolean} validateAsMilestone . * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {Date} . * @private */ DateProcessor.prototype.checkEndDate = function (date, ganttProp, validateAsMilestone, isBaseline) { if (isNullOrUndefined(date)) { return null; } var dayStartTime; var dayEndTime; if (this.parent.weekWorkingTime.length > 0) { var currentDay = new Date(date.getTime()); if (!this.parent.includeWeekend && ganttProp && ganttProp.isAutoSchedule || (this.parent.editModule && this.parent.editModule.taskbarEditModule && this.parent.editModule.taskbarEditModule.taskBarEditRecord && !this.parent.editModule.taskbarEditModule.taskBarEditRecord.ganttProperties.isAutoSchedule)) { currentDay = this.getNextWorkingDay(currentDay); } dayStartTime = this.parent['getStartTime'](currentDay); dayEndTime = this.parent['getEndTime'](currentDay); } else { dayStartTime = this.parent.defaultStartTime; dayEndTime = this.parent.defaultEndTime; } var cloneEndDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneEndDate); if (hour > dayEndTime) { this.setTime(dayEndTime, cloneEndDate); } else if (hour <= dayStartTime && dayEndTime !== 86400 && !validateAsMilestone) { var taskfields = this.parent.taskFields; if (this.parent.editModule && this.parent.editModule['editedRecord'] && (!this.parent.editModule['editedRecord'][taskfields.startDate] && this.parent.editModule['editedRecord'][taskfields.endDate])) { cloneEndDate.setDate(cloneEndDate.getDate()); } else { cloneEndDate.setDate(cloneEndDate.getDate() - 1); } dayEndTime = this.parent['getCurrentDayEndTime'](cloneEndDate); this.setTime(dayEndTime, cloneEndDate); } else if (hour > dayStartTime && hour < dayEndTime) { for (var index = 0; index < this.parent.workingTimeRanges.length; index++) { var value = this.parent.workingTimeRanges[index]; if (hour > value.to && (this.parent.workingTimeRanges[index + 1] && hour <= this.parent.workingTimeRanges[index + 1].from)) { this.setTime(this.parent.workingTimeRanges[index].to, cloneEndDate); break; } } } var tempCheckDate; if (this.parent.autoCalculateDateScheduling && !(this.parent.isLoad && this.parent.treeGrid.loadChildOnDemand && this.parent.taskFields.hasChildMapping)) { do { tempCheckDate = new Date(cloneEndDate.getTime()); var holidayLength = this.parent.totalHolidayDates.length; if (this.isValidateNonWorkDays(ganttProp) && !isBaseline) { if (!this.parent.includeWeekend) { var tempDate = new Date(cloneEndDate.getTime()); cloneEndDate = this.getPreviousWorkingDay(cloneEndDate); dayEndTime = this.parent['getCurrentDayEndTime'](cloneEndDate); if (tempDate.getTime() !== cloneEndDate.getTime()) { this.setTime(dayEndTime, cloneEndDate); } } for (var count = 0; count < holidayLength; count++) { var holidayFrom = this.getDateFromFormat(new Date(this.parent.totalHolidayDates[count])); var holidayTo = new Date(holidayFrom.getTime()); var tempHoliday = new Date(cloneEndDate.getTime()); tempHoliday.setMinutes(cloneEndDate.getMilliseconds() - 2); holidayFrom.setHours(0, 0, 0, 0); holidayTo.setHours(23, 59, 59, 59); if (cloneEndDate.getTime() >= holidayFrom.getTime() && cloneEndDate.getTime() < holidayTo.getTime() || tempHoliday.getTime() >= holidayFrom.getTime() && tempHoliday.getTime() < holidayTo.getTime()) { cloneEndDate.setDate(cloneEndDate.getDate() - 1); dayEndTime = this.parent['getCurrentDayEndTime'](cloneEndDate); if (!(cloneEndDate.getTime() === holidayFrom.getTime() && dayEndTime === 86400 && this.getSecondsInDecimal(cloneEndDate) === 0)) { this.setTime(dayEndTime, cloneEndDate); } } } } } while (tempCheckDate.getTime() !== cloneEndDate.getTime()); return new Date(cloneEndDate.getTime()); } else { if (!isNullOrUndefined(cloneEndDate) && this.parent.defaultEndTime !== 86400) { dayEndTime = this.parent['getCurrentDayEndTime'](date); this.setTime(dayEndTime, cloneEndDate); } return new Date(cloneEndDate.getTime()); } }; /** * To validate the baseline start date * * @param {Date} date . * @param {ITaskData} ganttProp . * @returns {Date} . * @private */ DateProcessor.prototype.checkBaselineStartDate = function (date, ganttProp) { if (isNullOrUndefined(date)) { return null; } else { var dayStartTime = this.parent['getCurrentDayStartTime'](date); var dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp ? ganttProp.endDate ? ganttProp.isAutoSchedule ? ganttProp.endDate : ganttProp.autoEndDate : date : date); var cloneDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneDate); if (hour < dayStartTime) { this.setTime(dayStartTime, cloneDate); } else if (hour > dayEndTime) { cloneDate.setDate(cloneDate.getDate() + 1); if (this.parent.weekWorkingTime.length > 0) { dayStartTime = this.parent['getStartTime'](cloneDate); } else { dayStartTime = this.parent.defaultStartTime; } this.setTime(dayStartTime, cloneDate); } else if (hour > dayStartTime && hour < dayEndTime) { for (var i = 0; i < this.parent.workingTimeRanges.length; i++) { var value = this.parent.workingTimeRanges[i]; if (hour > value.to && (this.parent.workingTimeRanges[i + 1] && hour < this.parent.workingTimeRanges[i + 1].from)) { this.setTime(this.parent.workingTimeRanges[i + 1].from, cloneDate); break; } } } return cloneDate; } }; /** * To validate baseline end date * * @param {Date} date . * @param {ITaskData} ganttProp . * @returns {Date} . * @private */ DateProcessor.prototype.checkBaselineEndDate = function (date, ganttProp) { if (isNullOrUndefined(date)) { return null; } else { var dayEndTime = this.parent['getCurrentDayEndTime'](date); var dayStartTime = this.parent['getCurrentDayStartTime'](ganttProp ? ganttProp.startDate ? ganttProp.isAutoSchedule ? ganttProp.startDate : ganttProp.autoStartDate : date : date); var cloneDate = new Date(date.getTime()); var hour = this.getSecondsInDecimal(cloneDate); if (hour > dayEndTime) { this.setTime(dayEndTime, cloneDate); } else if (hour < dayStartTime && !isNullOrUndefined(ganttProp) && !ganttProp.isMilestone) { cloneDate.setDate(cloneDate.getDate() - 1); dayEndTime = this.parent['getCurrentDayEndTime'](cloneDate); this.setTime(dayEndTime, cloneDate); } else if (hour > dayStartTime && hour < dayEndTime) { for (var i = 0; i < this.parent.workingTimeRanges.length; i++) { var value = this.parent.workingTimeRanges[i]; if (hour > value.to && (this.parent.workingTimeRanges[i + 1] && hour <= this.parent.workingTimeRanges[i + 1].from)) { this.setTime(this.parent.workingTimeRanges[i].to, cloneDate); break; } } } if (ganttProp && ganttProp.baselineStartDate && cloneDate && ganttProp.baselineStartDate.getTime() > cloneDate.getTime()) { cloneDate.setDate(cloneDate.getDate() + 1); } return cloneDate; } }; /** * To calculate start date value from duration and end date * * @param {IGanttData} ganttData - Defines the gantt data. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {void} . * @private */ DateProcessor.prototype.calculateStartDate = function (ganttData, isBaseline) { var ganttProp = ganttData.ganttProperties; var tempStartDate = null; if (isBaseline) { if (!isNullOrUndefined(ganttProp.baselineEndDate) && !isNullOrUndefined(ganttProp.baselineDuration)) { tempStartDate = this.getStartDate(ganttProp.baselineEndDate, ganttProp.baselineDuration, ganttProp.durationUnit, ganttProp, undefined, true); } this.parent.setRecordValue('baselineStartDate', tempStartDate, ganttProp, true); if (this.parent.taskFields.baselineStartDate) { this.parent.dataOperation.updateMappingData(ganttData, 'baselineStartDate'); } } else { if (!isNullOrUndefined(ganttProp.endDate) && !isNullOrUndefined(ganttProp.duration)) { tempStartDate = this.getStartDate(ganttProp.endDate, ganttProp.duration, ganttProp.durationUnit, ganttProp); } this.parent.setRecordValue('startDate', tempStartDate, ganttProp, true); if (this.parent.taskFields.startDate) { this.parent.dataOperation.updateMappingData(ganttData, 'startDate'); } } }; /** * Gets task field mappings based on baseline context. * * @param {boolean} isBaseline - Flag indicating if baseline fields should be used. * @returns {{ startdateField: string, enddateField: string, durationField: string }} - Object containing field names for start date, end date, and duration. */ DateProcessor.prototype.getFieldMappings = function (isBaseline) { return { startdateField: isBaseline ? 'baselineStartDate' : 'startDate', enddateField: isBaseline ? 'baselineEndDate' : 'endDate', durationField: isBaseline ? 'baselineDuration' : 'duration' }; }; /** * * @param {IGanttData} ganttData - Defines the gantt data. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {void} . * @public */ /* eslint-disable */ DateProcessor.prototype.calculateEndDate = function (ganttData, isBaseline) { var ganttProp = ganttData.ganttProperties; var tempEndDate = null; var dayStartTime; var dayEndTime; var _a = this.getFieldMappings(isBaseline), startdateField = _a.startdateField, enddateField = _a.enddateField, durationField = _a.durationField; if (!isNullOrUndefined(ganttProp[startdateField])) { if (!isNullOrUndefined(ganttProp[enddateField]) && isNullOrUndefined(ganttProp[durationField])) { if (this.compareDates(ganttProp[startdateField], ganttProp[enddateField]) === 1) { this.parent.setRecordValue(startdateField, new Date(ganttProp[enddateField].getTime()), ganttProp, true); dayStartTime = this.parent['getCurrentDayStartTime'](ganttProp.isAutoSchedule && !isBaseline ? ganttProp.autoStartDate : ganttProp[startdateField]); dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.isAutoSchedule && !isBaseline ? ganttProp.autoEndDate : ganttProp[enddateField]); this.setTime(dayStartTime, ganttProp[startdateField]); } this.calculateDuration(ganttData, isBaseline); } if (!isNullOrUndefined(ganttProp[durationField])) { var duration = !isBaseline && !isNullOrUndefined(ganttProp.segments) && ganttProp.segments.length > 1 ? this.totalDuration(ganttProp.segments) : ganttProp[durationField]; tempEndDate = this.getEndDate(ganttProp[startdateField], duration, ganttProp.durationUnit, ganttProp, false, isBaseline); } this.parent.setRecordValue(enddateField, tempEndDate, ganttProp, true); } else { tempEndDate = ganttData[this.parent.taskFields[enddateField]]; if (!isNullOrUndefined(tempEndDate)) { dayEndTime = this.parent['getCurrentDayEndTime'](tempEndDate); this.setTime(dayEndTime, tempEndDate); } this.parent.setRecordValue(enddateField, tempEndDate, ganttProp, true); } if (this.parent.taskFields[enddateField]) { this.parent.dataOperation.updateMappingData(ganttData, enddateField); } }; /* eslint-enable */ DateProcessor.prototype.totalDuration = function (segments) { var duration = 0; for (var i = 0; i < segments.length; i++) { duration += segments[i].duration + segments[i].offsetDuration; } return duration; }; /** * To calculate duration from start date and end date * * @param {IGanttData} ganttData - Defines the gantt data. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {void} . */ DateProcessor.prototype.calculateDuration = function (ganttData, isBaseline) { var ganttProperties = ganttData.ganttProperties; var tDuration; if (!isBaseline && !isNullOrUndefined(ganttProperties.segments) && ganttProperties.segments.length > 0 && !isNullOrUndefined(this.parent.editModule.taskbarEditModule)) { tDuration = this.parent.editModule.taskbarEditModule.sumOfDuration(ganttProperties.segments); } else { if (!isBaseline && (!isNullOrUndefined(this.parent.taskFields.milestone)) && (!isNullOrUndefined(ganttProperties.startDate)) && !isNullOrUndefined(ganttProperties.endDate) && (ganttProperties.startDate).getTime() === (ganttProperties.endDate).getTime() && (ganttData.taskData[this.parent.taskFields.milestone] === false)) { tDuration = 1; } else { var startDate = isBaseline ? ganttProperties.baselineStartDate : ganttProperties.startDate; var endDate = isBaseline ? ganttProperties.baselineEndDate : ganttProperties.endDate; var durationUnit = ganttProperties.durationUnit; var isAutoSchedule = isBaseline ? false : ganttProperties.isAutoSchedule; var isMilestone = isBaseline ? false : ganttProperties.isMilestone; tDuration = this.getDuration(startDate, endDate, durationUnit, isAutoSchedule, isMilestone); } } var duration = isBaseline ? 'baselineDuration' : 'duration'; this.parent.setRecordValue(duration, tDuration, ganttProperties, true); var col = isBaseline ? this.parent.columnByField[this.parent.columnMapping.baselineDuration] : this.parent.columnByField[this.parent.columnMapping.duration]; if (!isNullOrUndefined(this.parent.editModule) && !isNullOrUndefined(this.parent.editModule.cellEditModule) && !this.parent.editModule.cellEditModule.isCellEdit && !isNullOrUndefined(col)) { if (!isNullOrUndefined(col.edit) && !isNullOrUndefined(col.edit.read)) { var dialog = this.parent.editModule.dialogModule.dialog; if (!isNullOrUndefined(dialog)) { var textBoxElement = isBaseline ? dialog.querySelector('#' + this.parent.element.id + 'BaselineDuration') : dialog.querySelector('#' + this.parent.element.id + 'Duration'); if (!isNullOrUndefined(textBoxElement)) { var textBox = textBoxElement.ej2_instances[0]; if (!isNullOrUndefined(textBox) && textBox.value !== tDuration.toString()) { textBox.value = tDuration.toString(); textBox.dataBind(); } } } } if (this.parent.taskFields.duration || this.parent.taskFields.baselineDuration) { this.parent.dataOperation.updateMappingData(ganttData, duration); if (this.parent.taskFields.durationUnit) { this.parent.dataOperation.updateMappingData(ganttData, 'durationUnit'); } } } }; /** * * @param {Date} sDate Method to get total nonworking time between two date values * @param {Date} eDate . * @param {boolean} isAutoSchedule . * @param {boolean} isCheckTimeZone . * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {number} . */ DateProcessor.prototype.getNonworkingTime = function (sDate, eDate, isAutoSchedule, isCheckTimeZone, isBaseline) { var parent = this.parent; isCheckTimeZone = isNullOrUndefined(isCheckTimeZone) ? true : isCheckTimeZone; var shouldCheckWeekend = (!isBaseline && !parent.includeWeekend && parent.autoCalculateDateScheduling && !(parent.isLoad && parent.treeGrid.loadChildOnDemand && parent.taskFields.hasChildMapping)) && isAutoSchedule; var weekendCount = shouldCheckWeekend ? this.getWeekendCount(sDate, eDate) : 0; var totalSeconds = this.getNumberOfSeconds(sDate, eDate, isCheckTimeZone); var shouldCheckHolidays = (isAutoSchedule && parent.autoCalculateDateScheduling && !(parent.isLoad && parent.treeGrid.loadChildOnDemand && parent.taskFields.hasChildMapping)) && !isBaseline; var holidaysCount = shouldCheckHolidays ? this.getHolidaysCount(sDate, eDate) : 0; var totalWorkDays = (totalSeconds - (weekendCount * 86400) - (holidaysCount * 86400)) / 86400; var nonWorkingSecondsOnDate = this.getNonWorkingSecondsOnDate(sDate, eDate, isAutoSchedule, isBaseline); var nonWorkingTime = parent.weekWorkingTime.length > 0 ? this.nonWorkingSeconds(sDate, eDate, isAutoSchedule, totalWorkDays) : (totalWorkDays * (86400 - parent.secondsPerDay)); return nonWorkingTime + (weekendCount * 86400) + (holidaysCount * 86400) + nonWorkingSecondsOnDate; }; DateProcessor.prototype.nonWorkingSeconds = function (sDate, eDate, isAutoSchedule, workDays, fromDuration) { var newStartDate = sDate.getTime() > eDate.getTime() ? new Date(eDate.getTime()) : new Date(sDate.getTime()); var newEndDate = sDate.getTime() > eDate.getTime() ? new Date(sDate.getTime()) : new Date(eDate.getTime()); var timeDiff = 0; var count = 0; if (fromDuration) { var dayStartTime = this.parent['getCurrentDayStartTime'](newStartDate); var dayEndTime = this.parent['getCurrentDayEndTime'](newStartDate); if (!(newStartDate.getHours() < dayEndTime / 3600 && newStartDate.getHours() >= dayStartTime / 3600)) { newStartDate.setDate(newStartDate.getDate() + 1); } } else { newStartDate.setDate(newStartDate.getDate() + 1); newStartDate.setHours(0, 0, 0, 0); newEndDate.setHours(0, 0, 0, 0); } if (workDays > 0 || isNullOrUndefined(workDays)) { while ((fromDuration && newStartDate.getTime() <= newEndDate.getTime()) || (!fromDuration && newStartDate.getTime() < newEndDate.getTime())) { if (isAutoSchedule) { if (this.isOnHolidayOrWeekEnd(newStartDate, true)) { do { newStartDate.setDate(newStartDate.getDate() + 1); } while (this.isOnHolidayOrWeekEnd(newStartDate, true)); } if (!this.parent.includeWeekend) { this.getNextWorkingDay(newStartDate); } } if (newStartDate.getTime() <= newEndDate.getTime()) { count++; var currentDaySeconds = this.parent['getSecondsPerDay'](newStartDate); if (fromDuration) { timeDiff += currentDaySeconds; } else { timeDiff += 86400 - currentDaySeconds; } newStartDate.setDate(newStartDate.getDate() + 1); if (isAutoSchedule) { if (this.isOnHolidayOrWeekEnd(newStartDate, true)) { do { newStartDate.setDate(newStartDate.getDate() + 1); } while (this.isOnHolidayOrWeekEnd(newStartDate, true)); } if (!this.parent.includeWeekend) { this.getNextWorkingDay(newStartDate); } } } } } else { return 0; } if (fromDuration) { if (timeDiff > 0) { timeDiff = timeDiff / count; } else { timeDiff = this.parent.secondsPerDay; } } return timeDiff; }; /** * * @param {Date} startDate . * @param {Date} endDate . * @param {string} durationUnit . * @param {boolean} isAutoSchedule . * @param {boolean} isMilestone . * @param {boolean} isCheckTimeZone . * @returns {number} . * @private */ DateProcessor.prototype.getDuration = function (startDate, endDate, durationUnit, isAutoSchedule, isMilestone, isCheckTimeZone) { if (isCheckTimeZone === void 0) { isCheckTimeZone = true; } if (!startDate || !endDate) { return null; } var durationValue = 0; var isSameDay = this.parent.getFormatedDate(startDate) === this.parent.getFormatedDate(endDate); var totSeconds; if (this.parent.weekWorkingTime.length > 0) { var tempStartDate = new Date(startDate); totSeconds = this.nonWorkingSeconds(startDate, endDate, isAutoSchedule, undefined, true); var totalDurationInDays = 0; while (tempStartDate <= endDate) { var currentDateString = this.parent.getFormatedDate(tempStartDate); var dayWorkingSeconds = this.parent['getSecondsPerDay'](tempStartDate); var currentStartDate = new Date(tempStartDate); var currentEndDate = new Date(tempStartDate); currentStartDate.setHours(0, 0, 0, 0); currentEndDate.setHours(0, 0, 0, 0); currentStartDate.setSeconds(this.parent['getCurrentDayStartTime'](tempStartDate)); currentEndDate.setSeconds(this.parent['getCurrentDayEndTime'](tempStartDate)); if (currentDateString === this.parent.getFormatedDate(startDate)) { currentStartDate.setTime(startDate.getTime()); } if (currentDateString === this.parent.getFormatedDate(endDate)) { currentEndDate.setTime(endDate.getTime()); } var timeDiffSeconds = this.getTimeDifference(currentStartDate, currentEndDate, isCheckTimeZone) / 1000; var nonWorkSeconds = this.getNonworkingTime(currentStartDate, currentEndDate, isAutoSchedule, isCheckTimeZone); totalDurationInDays += Math.max(0, timeDiffSeconds - nonWorkSeconds) / dayWorkingSeconds; tempStartDate.setDate(tempStartDate.getDate() + 1); } if (!(isMilestone && isSameDay)) { durationValue = this.calculateDurationValue(durationUnit, totalDurationInDays, totSeconds); } } else { totSeconds = this.parent.secondsPerDay; var timeDiff = this.getTimeDifference(startDate, endDate, isCheckTimeZone) / 1000; var nonWorkHours = this.getNonworkingTime(startDate, endDate, isAutoSchedule, isCheckTimeZone); var durationHours = timeDiff - nonWorkHours; if (!(isMilestone && isSameDay)) { durationValue = this.calculateDurationValue(durationUnit, durationHours / totSeconds, totSeconds); } } return parseFloat(durationValue.toString()); }; DateProcessor.prototype.calculateDurationValue = function (durationUnit, duration, totSeconds) { if (!durationUnit || durationUnit === 'day') { return duration; } else if (durationUnit === 'minute') { return duration * (totSeconds / 60); } else { return duration * (totSeconds / 3600); } }; /** * * @param {number} duration . * @param {string} durationUnit . * @param {Date} date . * @returns {number} . */ DateProcessor.prototype.getDurationAsSeconds = function (duration, durationUnit, date) { var value = 0; var totSeconds; if (this.parent.weekWorkingTime.length > 0) { totSeconds = this.parent['getSecondsPerDay'](date); } else { totSeconds = this.parent.secondsPerDay; } if (!durationUnit || durationUnit.toLocaleLowerCase() === 'day') { value = totSeconds * duration; } else if (durationUnit.toLocaleLowerCase() === 'hour') { value = duration * 3600; } else { value = duration * 60; } return value; }; /** * To get date from start date and duration * * @param {Date} startDate . * @param {number} duration . * @param {string} durationUnit . * @param {ITaskData} ganttProp . * @param {boolean} validateAsMilestone . * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {Date} . * @private */ DateProcessor.prototype.getEndDate = function (startDate, duration, durationUnit, ganttProp, validateAsMilestone, isBaseline) { var tempStart = new Date(startDate.getTime()); var endDate = new Date(startDate.getTime()); var sDate = new Date(startDate.getTime()); var secondDuration; if (this.parent.weekWorkingTime.length > 0 && (!durationUnit || durationUnit.toLocaleLowerCase() === 'day')) { secondDuration = this.calculateSecondDuration(duration, sDate, secondDuration, startDate, true); } else { secondDuration = this.getDurationAsSeconds(duration, durationUnit, startDate); } var nonWork = 0; var workHours = 0; while (secondDuration > 0) { endDate.setSeconds(endDate.getSeconds() + secondDuration); nonWork = this.getNonworkingTime(tempStart, endDate, ganttProp.isAutoSchedule, true, isBaseline); workHours = secondDuration - nonWork; secondDuration = secondDuration - workHours; if (secondDuration > 0) { endDate = this.checkStartDate(endDate, ganttProp, validateAsMilestone, undefined, isBaseline); } tempStart = new Date(endDate.getTime()); } return endDate; }; /** * Calculate start date based on end date and duration. * * @param {Date} endDate - To calculate start date value from end date and duration. * @param {number} duration - The duration value. * @param {string} durationUnit - The unit of duration. * @param {ITaskData} ganttProp - The Gantt task properties. * @param {boolean} fromValidation - A flag indicating if the calculation is from validation. * @param {boolean} isBaseline - Indicates whether the calculation is specific to baseline dates. * @returns {Date} The calculated start date. * @private */ DateProcessor.prototype.getStartDate = function (endDate, duration, durationUnit, ganttProp, fromValidation, isBaseline) { var tempEnd = new Date(endDate.getTime()); var startDate = new Date(endDate.getTime()); var secondDuration; var eDate = new Date(tempEnd.getTime()); if (this.parent.weekWorkingTime.length > 0) { secondDuration = this.calculateSecondDuration(duration, eDate, secondDuration, tempEnd, false); } else { secondDuration = this.getDurationAsSeconds(duration, durationUnit, tempEnd); } var nonWork = 0; var workHours = 0; while (secondDuration > 0) { startDate.setSeconds(startDate.getSeconds() - secondDuration); nonWork = this.getNonworkingTime(startDate, tempEnd, ganttProp.isAutoSchedule, true, isBaseline); workHours = secondDuration - nonWork; secondDuration = secondDuration - workHours; if (secondDuration > 0) { tempEnd = this.checkEndDate(startDate, ganttProp, isBaseline); } tempEnd = new Date(startDate.getTime()); } /* To render the milestone in proper date while loading */ if (fromValidation && ganttProp.isMilestone) { startDate.setDate(startDate.getDate() - 1); var dayEndTime = this.parent['getCurrentDayEndTime'](ganttProp.endDate ? ganttProp.isAutoSchedule ? ganttProp.endDate : ganttProp.autoEndDate : startDate); this.parent.dateValidationModule.setTime(dayEndTime, startDate); startDate = this.parent.dateValidationModule.checkStartDate(startDate, ganttProp, true); } return startDate; }; DateProcessor.prototype.calculateSecondDuration = function (duration, sDate, secondDuration, startDate, fromEndDate) { if (duration < 1) { secondDuration = this.parent['getSecondsPerDay'](sDate) * duration; } else { secondDuration = 0; var durationValue = duration; var dayStartTime = this.parent['getCurrentDayStartTime'](sDate); var dayEndTime = this.parent['getCurrentDayEndTime'](sDate); if (!(sDate.getHours() < dayEndTime / 3600 && sDate.getHours() > dayStartTime / 3600) && this.fromSegments) { if (fromEndDate) { sDate.setDate(sDate.getDate() + 1); } else { sDate.setDate(sDate.getDate() - 1); } } while (durationValue > 0) { if (this.isOnHolidayOrWeekEnd(sDate, true)) { do { if (fromEndDate) { sDate.setDate(sDate.getDate() + 1); } else { sDate.setDate(sDate.getDate() - 1); } } while (this.isOnHolidayOrWeekEnd(sDate, true)); } if (!this.parent.includeWeekend) { sDate = fromEndDate ? this.getNextWorkingDay(sDate) : this.getPreviousWorkingDay(sDate); } var totSeconds = this.parent['getSecondsPerDay'](sDate); var num = 0; if (this.getSecondsInDecimal(startDate) !== this.parent['getStartTime'](startDate) && !Number.isInteger(durationValue)) { var deciNumber = duration.toString().split('.'); num = parseFloat('.' + deciNumber[1]); totSeconds = totSeconds * num; durationValue = durationValue - num; } if (durationValue < 1) { totSeconds = totSeconds * durationValue; } secondDuration = secondDuration + totSeconds; if (fromEndDate) { sDate.setDate(sDate.getDate() + 1); } else { sDate.setDate(sDate.getDate() - 1); } if (!num) { durationValue--; } } } return secondDuration; }; /** * @param {ITaskData} ganttProp . * @param {boolean} isLoad . * @returns {Date} . * @private */ DateProcessor.prototype.getProjectStartDate = function (ganttProp, isLoad) { if (!isNullOrUndefined(this.parent.cloneProjectStartDate)) { if (typeof this.parent.cloneProjectStartDate === 'string') { this.parent.cloneProjectStartDate = this.getDateFromFormat(this.parent.cloneProjectStartDate); } var cloneStartDate = this.checkStartDate(this.parent.cloneProjectStartDate); this.parent.cloneProjectStartDate = cloneStartDate; return new Date(cloneStartDate.getTime()); } else if (!isNullOrUndefined(this.parent.projectStartDate)) { var cloneStartDate = this.getDateFromFormat(this.parent.projectStartDate); this.parent.cloneProjectStartDate = this.checkStartDate(cloneStartDate); } else if (!isNullOrUndefined(isLoad)) { var flatData = this.parent.flatData; var minStartDate = void 0; if (flatData.length > 0) { minStartDate = flatData[0].ganttProperties.startDate; } else { minStartDate = new Date(); minStartDate.setHours(0, 0, 0, 0); } for (var index = 1; index < flatData.length; index++) { var startDate = flatData[index].ganttProperties.startDate; if (!isNullOrUndefined(startDate) && this.compareDates(startDate, minStartDate) === -1) { minStartDate = startDate; } } this.parent.cloneProjectStartDate = this.ch