Untitled

 avatar
unknown
plain_text
13 days ago
15 kB
4
Indexable
// Un-Mark KIV (Ticket Status - Other than On Hold)
// Check if ticket is in KIV, need to do unMarkKIV calcualtion
async function unMarkKIV(ticket_id, tableName, tenant_id, status, datetimenow) {
    const datetimenowfullformat = datetimenow.toFormat('yyyy-MM-dd HH:mm:ss');

    let fieldIdName = "un_kiv_at";
    let unKivAtDateTime = datetimenowfullformat;
    let fieldIdValue = unKivAtDateTime;
    let databaseName = 'ticketing_'+tenant_id;

    // get the kiv and un-kiv date-time from database
    let tickets = await Tickets.findById(ticket_id, tableName, tenant_id, databaseName);
    let kivDateTime = tickets[0].kiv_at;
    let unKivDateTime = tickets[0].un_kiv_at;

    // Not allow to Un-mark kiv if the ticket is not is on-hold status
    if (kivDateTime == timeStampZeroValue || unKivDateTime != timeStampZeroValue) {
        return;
    }

    // Get the sla at for first response, resolution and response
    let firstResponseAtDateTime = tickets[0].first_response_at;
    let resolutionAtDateTime = tickets[0].resolution_at;
    let responseAtDateTime = tickets[0].response_at;

    // Get the sla due for first response, resolution and response
    let firstResponseDue = tickets[0].first_response_due;
    let resolutionDue = tickets[0].resolution_due;
    let responseDue = tickets[0].response_due;

    // Get the correct date time format for luxon date compare
    let firstResponseDueDateTimeFormat = DateTime.fromFormat(firstResponseDue, 'yyyy-MM-dd HH:mm:ss');

    let resolutionDueDateTimeFormat = DateTime.fromFormat(resolutionDue, 'yyyy-MM-dd HH:mm:ss');

    let kivDateTimeFormat = DateTime.fromFormat(kivDateTime, 'yyyy-MM-dd HH:mm:ss');

    // Get the priority id of this ticket
    let priorityId = tickets[0].priority_id;

    // Get the group id of this ticket
    let groupId = tickets[0].group_id;

    // Query to sla policy target to get operation hour and sla policy info based on priority id
    let slaPoliciesTargets = await SlaPoliciesTargets.findByPriorityId(priorityId, tenant_id, groupId, databaseName);

    // Query to get holiday
    let holidays = await Holiday.getAll(tenant_id, databaseName);

    // Query to get business hour
    // let businessHoursSchedules = await BusinessHoursSchedule.getAll(tenant_id);
    let businessHoursSchedules = await BusinessHoursSchedule.findById(groupId, tenant_id, databaseName);

    try {
        // Update Un kiv at datetime
        let results = await Tickets.updateSingle(ticket_id, tableName, tenant_id, fieldIdName, fieldIdValue, databaseName);

        // Get the new sla due date time after remove on-hold status
        // Need calculate how many valid on hold(kiv) duration to add back, from due_date / from unkiv date
        // Check for business hour, holidays, sla, open/close day during KIV time amd after unkiv add back
        // If the first response at / resolution at / response at already completed, un-mark kiv will not affect the new SLA Due Time
        // if kiv_at < sla_due, only calculate the on hold duration

        // First Response New SLA Due
        if (firstResponseAtDateTime == timeStampZeroValue && (kivDateTimeFormat < firstResponseDueDateTimeFormat)) {
            let first_response_due_new = getNewSLADueAfterRemoveOnHold(tickets, firstResponseDue, kivDateTime, unKivAtDateTime, slaPoliciesTargets, holidays, businessHoursSchedules, datetimenow);
            // Update SLA Due
            let fieldIdName1 = "first_response_due";
            let fieldIdValue1 = first_response_due_new;
            let results1 = await Tickets.updateSingle(ticket_id, tableName, tenant_id, fieldIdName1, fieldIdValue1, databaseName);
        }

        // Resolution New SLA Due
        if (resolutionAtDateTime == timeStampZeroValue && (kivDateTimeFormat < resolutionDueDateTimeFormat)) {
            let resolution_due_new = getNewSLADueAfterRemoveOnHold(tickets, resolutionDue, kivDateTime, unKivAtDateTime, slaPoliciesTargets, holidays, businessHoursSchedules, datetimenow, databaseName);
            // Update SLA Due
            let fieldIdName2 = "resolution_due";
            let fieldIdValue2 = resolution_due_new;
            let results2 = await Tickets.updateSingle(ticket_id, tableName, tenant_id, fieldIdName2, fieldIdValue2, databaseName);
        }

        // Response New SLA Due
        if (responseDue != timeStampZeroValue && responseAtDateTime == timeStampZeroValue) {
            let responseDueDateTimeFormat = DateTime.fromFormat(responseDue, 'yyyy-MM-dd HH:mm:ss');
            if (kivDateTimeFormat < responseDueDateTimeFormat) {
                let response_due_new = getNewSLADueAfterRemoveOnHold(tickets, responseDue, kivDateTime, unKivAtDateTime, slaPoliciesTargets, holidays, businessHoursSchedules, datetimenow);
                // Update SLA Due
                let fieldIdName3 = "response_due";
                let fieldIdValue3 = response_due_new;
                let results3 = await Tickets.updateSingle(ticket_id, tableName, tenant_id, fieldIdName3, fieldIdValue3, databaseName);
            }
        }

        // No need audit log un mark KIV -> as ticket status change already audit logged
    } catch (e) {
        return res.status(400).send(e);
    }
}

function getNewSLADueAfterRemoveOnHold(tickets, slaDueDateTime, kivDateTime, unKivDateTime, slaPoliciesTargets, holidays, businessHoursSchedules, datetimenow) {
    let unKivDateTimeFormat = DateTime.fromFormat(unKivDateTime, 'yyyy-MM-dd HH:mm:ss');
    let kivDateTimeFormat = DateTime.fromFormat(kivDateTime, 'yyyy-MM-dd HH:mm:ss');

    let slaDueDateTimeFormat = DateTime.fromFormat(slaDueDateTime, 'yyyy-MM-dd HH:mm:ss');

    // Get the max duration of on-hold(kiv) time
    let kivDuration;
    if (unKivDateTime <= slaDueDateTime) {
        kivDuration = unKivDateTimeFormat.diff(kivDateTimeFormat, 'minutes').toObject();
    } else {
        kivDuration = slaDueDateTimeFormat.diff(kivDateTimeFormat, 'minutes').toObject();
    }

    // Get the holiday date only
    let holidaysArray = holidays.map(a => a.holiday_date);

    // if operation hrs == "calendar", 24 Hours x 7 Days
    if (slaPoliciesTargets[0].operation_hrs == "calendar") {
        // Need to check holidays only

        // Check exist holidays
        if (holidays.length > 0) {

            // If kiv date is same with un kiv date
            if (kivDateTimeFormat.toFormat('yyyy-MM-dd') == unKivDateTimeFormat.toFormat('yyyy-MM-dd')) {
                let isKivOnHoliday = holidaysArray.findIndex(e => e == kivDateTimeFormat.toFormat('yyyy-MM-dd'));
                if (isKivOnHoliday == -1) {
                    // Do nothing
                } else {
                    // If on hold date time is om holiday day, reset the on hold duration to 0
                    kivDuration.minutes = 0;
                }
            } else {
                // kiv date and un kiv date is different

                // Holiday is on the kiv date
                let isKivDayOnHoliday = holidaysArray.findIndex(e => e == kivDateTimeFormat.toFormat('yyyy-MM-dd'));

                // Holiday is on the un kiv date
                let isUnKivDayOnHoliday = holidaysArray.findIndex(e => e == unKivDateTimeFormat.toFormat('yyyy-MM-dd'));

                // Holidays are within the kiv date and un kiv date
                let isWithinKivHasHoliday;
                if (unKivDateTime <= slaDueDateTime) {
                    isWithinKivHasHoliday = holidaysArray.filter(e => e < unKivDateTimeFormat.toFormat('yyyy-MM-dd') && e > kivDateTimeFormat.toFormat('yyyy-MM-dd'));
                } else {
                    isWithinKivHasHoliday = holidaysArray.filter(e => e < slaDueDateTime.toFormat('yyyy-MM-dd') && e > kivDateTimeFormat.toFormat('yyyy-MM-dd'));
                }

                let totalInvalidTime = 0;
                if (isKivDayOnHoliday == -1) {
                    // Do nothing
                } else {
                    // Calculate the invalid working hour due to this day is holiday
                    let kivDateEndOfToday = kivDateTimeFormat.endOf('day');
                    let diffDuration = kivDateEndOfToday.diff(kivDateTimeFormat, 'minutes').toObject();
                    totalInvalidTime = diffDuration.minutes;
                }

                if (isUnKivDayOnHoliday == -1) {
                    // Do nothing
                } else {
                    // Calculate the invalid working hour due to this day is holiday
                    let unKivDateEndOfToday = unKivDateTimeFormat.endOf('day');
                    let diffDuration = unKivDateEndOfToday.diff(unKivDateTimeFormat, 'minutes').toObject();
                    totalInvalidTime = totalInvalidTime + diffDuration.minutes;
                }

                // Calculate the invalid working hour between kiv and un kiv date
                if (isWithinKivHasHoliday.length > 0) {
                    // Convert holiday days to minutes
                    let holidayInDay = isWithinKivHasHoliday.length;
                    let holidayInMinutes = holidayInDay * 24 * 60;
                    totalInvalidTime = totalInvalidTime + holidayInMinutes;
                }

                kivDuration.minutes = kivDuration.minutes - totalInvalidTime;
            }
        }

        // Valid On Hold Duration follow calendar setting
        let kivValidCalendarDuration = kivDuration.minutes;

        // calculate new sla due after remove on hold follow calendar
        let new_sla_due_final = calcNewSLADueAfterOnHoldCalendar(kivDateTime, unKivDateTime, slaDueDateTime, holidays, kivValidCalendarDuration);

        return new_sla_due_final;
        
    }
    else {
        // if operation hrs == "business", follow business hour settings

        // Get kiv today Day
        let todayDay = kivDateTimeFormat.weekday;
        if(todayDay == 7){
            todayDay = 0;
        }

        let kivBusinessDuration = 0;

        // Loop through day by day from kiv_at datetime to un_kiv_at datetime,
        // and calculate the valid working hour during kiv time
        // Calculate the valid on hold duration based on business hour setting
        let kivValidBusinessDuration = calcValidBusinessHour(kivDateTime, unKivDateTime, slaDueDateTime, holidaysArray, businessHoursSchedules, todayDay, kivBusinessDuration);

        // If unKIV > sla due date, then use unkiV date time, 
        // If unkiv <= sla due date, use sla due time,
        let startCountDateTimeAfterOnHold;
        if (unKivDateTimeFormat > slaDueDateTimeFormat) {
            startCountDateTimeAfterOnHold = unKivDateTimeFormat;
        } else {
            startCountDateTimeAfterOnHold = slaDueDateTimeFormat;
        }

        // Add back the on hold duration
        // and recheck business hour settings, holidays after add
        let new_first_response_due_final = checkDueWithBusinessHoursAndHolidays(startCountDateTimeAfterOnHold, kivValidBusinessDuration, holidaysArray, businessHoursSchedules, todayDay, datetimenow);

        return new_first_response_due_final;

    }
}


// calculate new sla due after remove on hold follow calendar
function calcNewSLADueAfterOnHoldCalendar(kivDateTime, unKivDateTime, slaDueDateTime, holidays, kivValidCalendarDuration) {

    // Convert to the necessary date format
    let unKivDateTimeFormat = DateTime.fromFormat(unKivDateTime, 'yyyy-MM-dd HH:mm:ss');
    let kivDateTimeFormat = DateTime.fromFormat(kivDateTime, 'yyyy-MM-dd HH:mm:ss');
    let slaDueDateTimeFormat = DateTime.fromFormat(slaDueDateTime, 'yyyy-MM-dd HH:mm:ss');

    let unKivDateOnly = unKivDateTimeFormat.toFormat('yyyy-MM-dd');
    let alaDueDateOnly = slaDueDateTimeFormat.toFormat('yyyy-MM-dd');

    // Check start count from which date time
    let startCountDateTimeFormat;
    let startCountDateOnly;
    if (unKivDateTime <= slaDueDateTime) {
        // On hold duration start count from sla due date time
        startCountDateTimeFormat = slaDueDateTimeFormat;
        startCountDateOnly = alaDueDateOnly;
    } else {
        // On hold duration start count from un kiv date time
        startCountDateTimeFormat = unKivDateTimeFormat;
        startCountDateOnly = unKivDateOnly;
    }

    // Valid Duration in object
    let validDurationToAdd = { minutes: kivValidCalendarDuration };

    // Check exist holidays
    if (holidays.length == 0) {
        let newSlaDue = startCountDateTimeFormat.plus(validDurationToAdd);
        let new_sla_due = newSlaDue.toFormat('yyyy-MM-dd HH:mm:ss');
        return new_sla_due;
    } else {
        // Calculation need to include holidays

        // Get the holiday date only
        let holidaysArray = holidays.map(a => a.holiday_date);

        // calculate new SLA Due After Remove on Hold following calendar and holiday
        return calcNewSLADueAfterOnHoldCalendarHoliday(startCountDateTimeFormat, holidaysArray, kivValidCalendarDuration);

    }

}


function calcNewSLADueAfterOnHoldCalendarHoliday(startCountDateTimeFormat, holidaysArray, kivValidCalendarDuration) {

    // Is start count day holiday
    let startCountDateOnly = startCountDateTimeFormat.toFormat('yyyy-MM-dd');
    let isTodayHoliday = holidaysArray.findIndex(e => e == startCountDateOnly);

    let thisDateStartOfDay = startCountDateTimeFormat.startOf('day');
    let thisDateEndOfDay = startCountDateTimeFormat.endOf('day');

    // If this day is not holiday
    if (isTodayHoliday == -1) {

        // Get the duration of this day valid working hour 
        let thisDayDuration = thisDateEndOfDay.diff(startCountDateTimeFormat, 'minutes').toObject();
        if (kivValidCalendarDuration <= thisDayDuration.minutes) {
            // Plus back the remaining kiv time
            let newDueTime = startCountDateTimeFormat.plus({ minutes: kivValidCalendarDuration });
            let mew_sla_due_at = newDueTime.toFormat('yyyy-MM-dd HH:mm:ss');
            return mew_sla_due_at;

        } else {
            // Looping check again this function
            // Calculate the remaining kivValidCalendarDuration
            let remainingkivValidCalendarDurationInMinute = kivValidCalendarDuration - thisDayDuration.minutes;
            // Go to beginning time of next day, 12am
            let nextDayDateTime = startCountDateTimeFormat.plus({ days: 1 }).startOf('day');
            // Looping to calculate the new sla again
            return calcNewSLADueAfterOnHoldCalendarHoliday(nextDayDateTime, holidaysArray, remainingkivValidCalendarDurationInMinute);
        }

    }
    else {
        // If this day is holiday
        // Go to beginning time of next day, 12am
        let nextDayDateTime = startCountDateTimeFormat.plus({ days: 1 }).startOf('day');
        // Looping to calculate the new sla again
        return calcNewSLADueAfterOnHoldCalendarHoliday(nextDayDateTime, holidaysArray, kivValidCalendarDuration);
    }

}
Editor is loading...
Leave a Comment