diff --git a/src/layouts/schedule/constants/schedule-constants.js b/src/constants/schedule-constants.js similarity index 100% rename from src/layouts/schedule/constants/schedule-constants.js rename to src/constants/schedule-constants.js diff --git a/src/constants/store-mutations.js b/src/constants/store-mutations.js index 8eeb70c99..82cc2082d 100644 --- a/src/constants/store-mutations.js +++ b/src/constants/store-mutations.js @@ -58,6 +58,7 @@ const storeMutations = { RESET_GLASS_PARTS_STATE: "resetGlassPartsState", RESET_STATE: "resetState", RESET_SAVE_SESSION_PROMISE: "resetSaveSessionPromise", + RESET_SCHEDULE: "resetSchedule", // OTHER MUTATIONS UPDATE_PAGE_DATA: "updatePageData", diff --git a/src/layouts/schedule/schedule.vue b/src/layouts/schedule/schedule.vue index e316edfd2..fe9f3dac8 100644 --- a/src/layouts/schedule/schedule.vue +++ b/src/layouts/schedule/schedule.vue @@ -67,7 +67,7 @@ import { getRouterLinkRouteFromCopy, getRouterLinkDisplayTextFromCopy, } from "@/helpers/cms-content-helper"; -import { AppointmentTypeStrings } from "./constants/schedule-constants"; +import { AppointmentTypeStrings } from "@/constants/schedule-constants"; import { errorMessages } from "@/constants/error-messages"; import { required } from "@/helpers/validation-rules"; import store from "@/store"; diff --git a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue index 10640dfd9..7e9b5a279 100644 --- a/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue +++ b/src/layouts/schedule/time-slot-modal-question/time-slot-modal-question.vue @@ -53,7 +53,7 @@ import { AppointmentTypeStrings, PREMIUM_TIME_SLOT_ID_FLAG, PREMIUM_FEE_PART_TYPE, -} from "../constants/schedule-constants"; +} from "@/constants/schedule-constants"; // Validation for the modal button defineRule("time-slot-required", required(errorMessages.OPTION_REQUIRED)); diff --git a/src/store/index.js b/src/store/index.js index 67917bf01..eac41c311 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -11,6 +11,7 @@ import { damageLocationsSelected } from "@/constants/damage-locations-selected"; import { fmgPageValues } from "@/router/router-constants/fmgPage-values"; import router from "@/router"; import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js"; +import { AppointmentTypeStrings } from "@/constants/schedule-constants"; // Export State const getDefaultState = () => { @@ -342,6 +343,13 @@ export const mutations = { state.applicationUser.pageData[fmgPageValues.MOLDING_QUESTIONS] = null; state.applicationUser.pageData[fmgPageValues.CAPABILITY_QUESTIONS] = null; }, + resetSchedule(state) { + state.order.schedule.date = null; + state.order.schedule.startTime = null; + state.order.schedule.endTime = null; + state.order.schedule.routeCode = null; + state.order.schedule.jobMaxMinutes = null; + }, resetState(state) { Object.assign(state, getDefaultState()); }, @@ -1384,7 +1392,7 @@ export const actions = { }, }) .then( - (response) => { + async (response) => { // Flatten location and name properties response.data.order.damage?.glassToReplace?.map((glass) => { glass.glassLocation = glass.location; @@ -1402,6 +1410,8 @@ export const actions = { storeMutations.UPDATE_STATE_WITH_ORDER_INFORMATION, response.data ); + + await validateAppointment(context, response.data.order); return response; }, (error) => { @@ -2012,3 +2022,83 @@ function convertGlassPieceToBackEndCompatibleFormat(glassPieces) { }; }); } + +// This function will verify schedule info is still valid. +// check to see if we have an appointment date on the order object. +// if so, make sure it's not in the past. if in the past, clear schedule info in store. +// if date not in past, then call schedule service to verify appointment is still available. +async function validateAppointment(context, order) { + if (!order.schedule?.date) { + return; + } + + // Date string with slashes is parsed as local time, not UTC. Our date has dashes, '-'. + // If you put any kind of time stamp on the date string with dashes, then it IS parsed as local time. + var aptDate = new Date(order.schedule.date + "T00:00:00"); + var curDate = new Date(); + + // if appointment date is in the past, clear schedule + if (aptDate.getTime() < curDate.getTime()) { + context.commit(storeMutations.RESET_SCHEDULE); + return; + } + + // create date range to pass to the schedule service to see if our appointment is still available. + var endRange = new Date(aptDate); + endRange.setDate(aptDate.getDate() + 1); + + var endDay = "" + endRange.getDate(); + var endMonth = "" + (endRange.getMonth() + 1); // 0 based so add 1 + const endYear = endRange.getFullYear(); + + if (endMonth.length < 2) { + endMonth = "0" + endMonth; + } + if (endDay.length < 2) { + endDay = "0" + endDay; + } + + const endDate = [endYear, endMonth, endDay].join("-"); + + let newTimeSlotsResponse; + if (order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE) { + newTimeSlotsResponse = await context.dispatch( + storeActions.GET_MOBILE_TIME_SLOTS, + { + startDate: order.schedule.date, + endDate: endDate, + }, + false + ); + } else { + newTimeSlotsResponse = await context.dispatch( + storeActions.GET_SHOP_TIME_SLOTS, + { + startDate: order.schedule.date, + endDate: endDate, + shopAppointmentType: order.serviceLocation.appointmentType, + providerNumber: order.serviceLocation.provider.providerNumber, + }, + false + ); + } + + if (newTimeSlotsResponse?.data.days?.length === 0) { + context.commit(storeMutations.RESET_SCHEDULE); + return; + } + + var routeCodeFound = false; + newTimeSlotsResponse.data.days?.forEach((day) => { + day.timeSlots.forEach((ts) => { + if (ts.id === order.schedule.routeCode) { + routeCodeFound = true; + } + }); + }); + + if (!routeCodeFound) { + context.commit(storeMutations.RESET_SCHEDULE); + return; + } +}