Not able to get booking available slots, hence not able to populate it.

Hello All,

In my booking website, I am trying to create a booking form and trying to retrieve all booking slots available for a given day. I looked at the wix community example available at " https://www.wix.com/corvid/example/quick-book-and-pending-appointments "

The only difference is that in the above example, Coder creating a drop down with 7 days of date to pick the date, where I am using the calendar input to pick the date. Please have a look and help me, where I am missing:

// For full API documentation, including code examples, visit https://wix.to/94BuAAs
import wixWindow from 'wix-window';
import wixBookings from 'wix-bookings';
import wixData from 'wix-data';
import wixWindow1 from 'wix-window';

const manandvan = '21d8b748-b342-43b4-b16e-63049bb8e0fb';
const twomenvan = '51d09f78-39f9-424c-8456-91450c43db78';

let slotMap = {};
let servicedata = wixWindow1.lightbox.getContext();
let date = 0;
// List of the days of the week.
const daysOfTheWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
let mainservice = null;
let subservice = null;

$w.onReady(function () {

    $w("#repeatersvc").value = servicedata.servicename;
    $w('#Amount').value = "Delivery cost " + servicedata.serviceprice;
    $w("#slotPicker").options = [];
 // $w("#datePicker").onChange(() => selectDate());
 // // $w("#dayPicker").options = getWeekDays(today).map(day => {
 // //   return {
 // //       // Set the label to be the name of the day of the week and its formatted date (e.g Tue 18/12/2018).
 // //       label: `${daysOfTheWeek[day.date.getDay()]} ${day.date.toLocaleDateString("en-GB")}`,
 // //       // Set the value to be the ISO string representation of the date (e.g. 2018-12-17T22:00:00.000Z).
 // //       value: day.date.toISOString()
 // //   }

 // date = selectDate.selectedDate;
    selectDate();

});

export function datePicker_change(event, $w) {
 const selectedDate = $w("#datePicker").value.toISOString();
 // const pickdate = $w("#datePicker").value.toISOString();
 // const pickday = daysOfTheWeek[pickdate]
    console.log("Selected Date = " + selectedDate);
    findAvailableslots(selectedDate);
    $w("#submitButton").onClick(() => validateandSubmitform());
}

export function submitButton_click(event) {
    validateandSubmitform()
}

export function selectDate() {
 const selectedDate = $w("#datePicker").value.toISOString()
    findAvailableslots(selectedDate);
    $w("#submitButton").onClick(() => validateandSubmitform());
 return

}
async function findAvailableslots(date) {

    console.log("Date in Find Available slot function = " + date);
    slotMap = {};
 const startdatetime = getmidnight(date);
 const enddatetime = getnextmidnight(date);
 const options = {
        startdatetime,
        enddatetime
    };
    console.log(options)

 let servicename = ($w("#repeatersvc").value).split("/")
    mainservice = servicename[0];
    subservice = servicename[1];
    console.log("mainservice = " + servicename[0])
    console.log("subservice = " + servicename[1])
    console.log(mainservice)
    console.log(subservice)
 if (mainservice === "Two Men and a Van Service") {
 let serviceid = twomenvan;
    } else if (mainservice === "One Man and a Van Service") {
 let serviceid = manandvan;
    }
 const availableslots = await getNonPendingAvailableSlots(mainservice, options);
 // console.log(availableslots1)
 // const availableslots2 = await findavailableslots(twomenvan, options);
    console.log("Service name to check available slot = " + $w("#repeatersvc").value);
 // if ($w("#repeatersvc").value === "Two Men and a Van Service") {
 //  if (availableslots2.length === 0) {

 //      $w("#slotPicker").options = [];
 //      $w("#slotPicker").placeholder = "No slots available for " + date;
 //      $w("#slotPicker").selectedIndex = undefined;
 //      $w("#slotPicker").disable();
 //  } else {
 //      console.log("Slots available for Two Men Service");
 //      $w("#slotPicker").options = availableslots2.map(slot => {

 //          const uniqueId = new Date().getUTCMilliseconds().toString() // Generate a short unique ID to identify options in the slotPicker

 //          slotMap[uniqueId] = slot;
 //          let starttime = slot.startdatetime
 //          console.log("StartTime = " + slot.startdatetime)
 //          let timestring = getTimeOfDay(starttime);

 //          return {
 //              label: timestring,
 //              value: uniqueId
 //          }
 //      });
 //      $w("#slotPicker").placeholder = "Pick a time for " + date;
 //      $w("#slotPicker").selectedIndex = undefined;
 //      $w("#slotPicker").enable();

 //  }
 // }

 // if ($w("#repeatersvc").value === "One Man and a Van Service") {
 if (availableslots.length === 0) {

        $w("#slotPicker").options = [];
        $w("#slotPicker").placeholder = "No slots available for " + date;
        $w("#slotPicker").selectedIndex = undefined;
        $w("#slotPicker").disable();
    } else {

        console.log("Slots available for Two Men Service");
        $w("#slotPicker").options = availableslots.map(slot => {

 const uniqueId = new Date().getUTCMilliseconds().toString() // Generate a short unique ID to identify options in the slotPicker
            slotMap[uniqueId] = slot;
 let starttime = slot.startdatetime
            console.log("Start Time is = " + starttime)
 let timestring = getTimeOfDay(starttime);
 return {
                label: timestring,
                value: uniqueId
            }
        });
        $w("#slotPicker").placeholder = "Pick a time for " + date;
        $w("#slotPicker").selectedIndex = undefined;
        $w("#slotPicker").enable();

    }
}
// }

function getTimeOfDay(Date) {
    console.log("we are in getTimeOfDay  " + Date)
 return Date.toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" }).toLowerCase();

}

async function validateandSubmitform() {
    $w("#errormsg").hide();
    $w("#submitButton").disable();
 if ($w("#name").valid && $w("#email").valid && $w("#phoneNumber").valid && $w("#datePicker").valid && $w("#slotPicker").valid && $w("#TnCcheck").valid) {
 const slot = slotMap[$w("#slotPicker").value];
 const newRequest = {
            name: $w("#name").value,
            email: $w("#email").value,
            phoneNumber: $w("#phoneNumber").value,
            requestedSlot: slot,
            status: "PENDING",
            mainService : mainservice,
            subService : subservice

        }
 await wixData.insert("newAppoinments", newRequest)
        $w("#bookinggroup").hide();
        $w("#thankyouMsg").show();

    } else {
        $w("#errormsg").show;
        $w("#submitButton").enable();
    }
 // const formField =[ "name","email","phoneNumber","datePicker","slotPicker","TnCcheck"];

 // if (formField.every(input => $w('#${input}').valid))){

 // }

}

function getmidnight(dateval) {
 let midnight = new Date(dateval);
    midnight.setHours(0, 0, 0, 0);
 return midnight;
}

function getnextmidnight(dateval1) {
 let midnight = new Date(dateval1);
    midnight.setHours(24, 0, 0, 0);
 return midnight;
}

async function getNonPendingAvailableSlots(serviceid, options = {}) {
    console.log("we are in find available slots")
    console.log(serviceid)
 const pending = (await  getPendingAppointments()).map(appointment => appointment.requestedSlot._id);
 let availableSlots = (await wixBookings.getServiceAvailability(serviceid, options)).slots;
    availableSlots = availableSlots.filter(slot => !pending.includes(slot._id))

    console.log(availableSlots)
 return availableSlots;

}

async function  getPendingAppointments() {
    console.log("we are in findpendingappointments")
 return (await wixData.query("newAppointements").find()).items.filter(item => item.status === "PENDING");

}

Thanks in Advance.

I am able to sort the issue and manage to populate the slot picker drop down with slots. But now the issue is, it is populating slots till noon only and rest are not being populated. below is my code snippet:

// For full API documentation, including code examples, visit https://wix.to/94BuAAs
import wixWindow from 'wix-window';
import wixBookings from 'wix-bookings';
import wixData from 'wix-data';
import wixWindow1 from 'wix-window';

const manandvan = '21d8b748-b342-43b4-b16e-63049bb8e0fb';
const twomenvan = '51d09f78-39f9-424c-8456-91450c43db78';

let slotMap = {};
let servicedata = wixWindow1.lightbox.getContext();
let date = 0;
// List of the days of the week.
const daysOfTheWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
let mainservice = null;
let subservice = null;

$w.onReady(function () {

    $w("#repeatersvc").value = servicedata.servicename;
    $w('#Amount').value = "Delivery cost " + servicedata.serviceprice;
    $w("#slotPicker").options = [];
     selectDate();

});

export function datePicker_change(event, $w) {
 const selectedDate = $w("#datePicker").value;
     console.log("Selected Date = " + selectedDate);
    findAvailableslots(selectedDate);
    $w("#submitButton").onClick(() => validateandSubmitform());
}

export function submitButton_click(event) {
    validateandSubmitform()
}

export function selectDate() {
 const selectedDate = $w("#datePicker").value
    findAvailableslots(selectedDate);
    $w("#submitButton").onClick(() => validateandSubmitform());
 return

}
async function findAvailableslots(date) {

    console.log("Date in Find Available slot function = " + date);
    slotMap = {};
 const startDateTime = getServicestartTime(date);
 const endDateTime = getServiceendTime(date);
 const options = {
        startDateTime,
        endDateTime
    };
    console.log(options)

 let servicename = ($w("#repeatersvc").value).split("/")
    mainservice = servicename[0];
    subservice = servicename[1];
    
 var serviceid = null;
 if (mainservice === "Two Men and a Van Service") {
        serviceid = twomenvan;
    } else if (mainservice === "One Man and a Van Service") {
        serviceid = manandvan;
    }
 const availableslots = await getNonPendingAvailableSlots(serviceid, options);
 
 if (availableslots.length === 0) {
 let onlydate = date.toDateString()
        $w("#slotPicker").options = [];
        $w("#slotPicker").placeholder = "No slots available for " + onlydate;
        $w("#slotPicker").selectedIndex = undefined;
        $w("#slotPicker").disable();
    } else {

        console.log("Slots available for Two Men Service");
        $w("#slotPicker").options = availableslots.map(slot => {

 const uniqueId = new Date().getUTCMilliseconds().toString() // Generate a short unique ID to identify options in the slotPicker
            slotMap[uniqueId] = slot;
 let starttime = slot.startDateTime
            console.log("Start Time is = " + starttime)
 let timestring = getTimeOfDay(starttime);
 return {
                label: timestring,
                value: uniqueId
            }
        });
        $w("#slotPicker").placeholder = "Pick a time for " + date.toDateString();
        $w("#slotPicker").selectedIndex = undefined;
        $w("#slotPicker").enable();

    }
}
// }

function getTimeOfDay(Date) {
    console.log("we are in getTimeOfDay  " + Date)
 return Date.toLocaleTimeString("en-NZ", { hour: "2-digit", minute: "2-digit" }).toLowerCase();

}

async function validateandSubmitform() {
    $w("#errormsg").hide();
    $w("#submitButton").disable();
 if ($w("#name").valid && $w("#email").valid && $w("#phoneNumber").valid && $w("#datePicker").valid && $w("#slotPicker").valid && $w("#TnCcheck").valid) {
 const slot = slotMap[$w("#slotPicker").value];
 const newRequest = {
            name: $w("#name").value,
            email: $w("#email").value,
            phoneNumber: $w("#phoneNumber").value,
            requestedSlot: slot,
            status: "PENDING",
            mainService: mainservice,
            subService: subservice

        }
 await wixData.insert("newAppoinments", newRequest)
        $w("#bookinggroup").hide();
        $w("#thankyouMsg").show();

    } else {
        $w("#errormsg").show;
        $w("#submitButton").enable();
    }
 
function getServicestartTime(dateval) {
 //let midnight = new Date(dateval.toLocaleString("en-NZ"));
 let midnight =  new Date(dateval.toLocaleDateString());
    midnight.setHours(7);
    console.log("Service start time", midnight)
 return midnight;
}

function getServiceendTime(dateval1) {
 //let midnight = new Date(dateval1.toLocaleString("en-NZ"));
 let midnight = new Date(dateval1.toLocaleDateString());
    midnight.setHours(23)
    console.log("Service end time", midnight)
 return midnight;
}

async function getNonPendingAvailableSlots(serviceid, options = {}) {
    console.log("we are in find available slots")
    console.log("Service Id ", serviceid)
 var pending = [];
 await getPendingAppointments().then(PA => {
        pending = PA.map(appointment => appointment.requestedSlot._id)
    });

    console.log("Pending Appointements details", pending)
 //  
 let availableSlots = [];
 await wixBookings.getServiceAvailability(serviceid, options).then(results => {
        availableSlots = results.slots;
    });
 //slots;
    availableSlots = availableSlots.filter(slot => !pending.includes(slot._id))

    console.log(availableSlots)
 return availableSlots;

}

async function getPendingAppointments() {
    console.log("we are in findpendingappointments")
 var pendingAppointments = [];
 await wixData.query("NewAppointments").find().then((results) => {
        pendingAppointments = results.items.filter(item => item.status === "PENDING")

    });
    console.log("new appointment collection ", pendingAppointments)
 return pendingAppointments;
 

Please help.

Please have a look at my booking form and console results.

Just a quick thought without going through all of your code etc.

You are getting the date and time in UTC, which is the same as GMT and looking at your site url you are from NZ.

So when you change the time to NZ local time you will actually be 12hrs ahead and this could possibly be the reason why you are only getting from midnight to midday or from midday to midnight, depending on what time the user is on your site.

Also if you already have import wixWindow from ‘wix-window’;, why do you need the extra import wixWindow1 from ‘wix-window’; line?

https://www.wix.com/corvid/reference/wix-window.lightbox.html#getContext

Get the data that was passed to the lightbox

import wixWindow from 'wix-window';

// ...

let receivedData = wixWindow.lightbox.getContext();

@sailorcihan /GOS, thanks for the reply. you are right in saying that my website will be used in NZ. As I am building this website for my brother’s business in NZ. but I am from India and testing the website in India GMT+0530. In this case, it should give me few more details/slots.

Also, if I change the setting here and asks to reterive data from 0000 hours to 2300 hours, It was giving me right slots. And by default, I was getting 161 slots for a week.

function getServicestartTime(dateval) {
 //let midnight = new Date(dateval.toLocaleString("en-NZ"));
 let midnight =  new Date(dateval.toLocaleDateString());
    midnight.setHours(7);
    console.log("Service start time", midnight)
 return midnight;
}

function getServiceendTime(dateval1) {
 //let midnight = new Date(dateval1.toLocaleString("en-NZ"));
 let midnight = new Date(dateval1.toLocaleDateString());
    midnight.setHours(23)
    console.log("Service end time", midnight)
 return midnight;
}

As you have rightly poined that this website will be used for newzealnd, henceIf you can help me to sort our the timezone settings in code so that It will work on GMT+1200 timezone only. it will be of great help.

On your second query, I have two wixWindow imports. That was a mistake and will sortout. Thanks for pointing that out.

The setHours method can take optional minutes, seconds and ms arguments, for example:

var d = new Date();
d.setHours(0,0,0,0);

That will set the time to 00:00:00.000 of your current timezone, if you want to work in UTC time, you can use the setUTCHours method.

When you say that it was working in your code before, was that when you used the same as the example?

Example:

// Get the midnight that starts the day after the given date.
function getNextMidnight(date) {
 // Create a new date which is a copy of the given date.
 let midnight = new Date(date);
 // Set the new date's time to the next midnight.
    midnight.setHours(24, 0, 0, 0);
 // Return the new date.
 return midnight;

Your previous code in block:

function getmidnight(dateval) {
 let midnight = new Date(dateval);
    midnight.setHours(0, 0, 0, 0);
 return midnight;
}

function getnextmidnight(dateval1) {
 let midnight = new Date(dateval1);
    midnight.setHours(24, 0, 0, 0);
 return midnight;
}

Before you changed it to this:

function getServicestartTime(dateval) {
 //let midnight = new Date(dateval.toLocaleString("en-NZ"));
 let midnight =  new Date(dateval.toLocaleDateString());
    midnight.setHours(7);
    console.log("Service start time", midnight)
 return midnight;
}

function getServiceendTime(dateval1) {
 //let midnight = new Date(dateval1.toLocaleString("en-NZ"));
 let midnight = new Date(dateval1.toLocaleDateString());
    midnight.setHours(23)
    console.log("Service end time", midnight)
 return midnight;
}

Because as noted at the start of my reply, when you use d.setHours(0,0,0,0);, it will go by your current timezone and not UTC and you don’t need to use toLocaleDateString with it either.

So the nearest midnight in the past:

var d = new Date();
d.setHours(0,0,0,0); // last midnight

With the nearest midnight in future:

var d = new Date();
d.setHours(24,0,0,0); // next midnight

When you use setHours like you have with the number in brackets, you are changing the local time by that many hours from midnight.

Go this this page here.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setHours

Paste this into the demo box at the top of the page to see.

const event = new Date();

event.setHours(23);
console.log(event);

event.setHours(7);
console.log(event);
event.setHours(0);
console.log(event);
event.setHours(0,0,0,0);
console.log(event);
event.setHours(24,0,0,0);
console.log(event);

You might have already seen this previous post too, however just in case you have not.
https://www.wix.com/corvid/forum/community-discussion/solved-quick-booking-dropdown-display-available-dates-slots-starting-one-week-from-now

Thanks again @sailorcihan , I have two queries:

  1. When my website will open in New Zealand, it will automatically take NZT time. Right?

  2. is there any way that I can convert/code my timezone to NZT time using corvid?
    because if i code it to UTC time than it will create issues in creating booking time.

I also forgot to add here that depending on your timezone that you set within your own Wix settings, that it will be that which your site is set to.

https://www.wix.com/corvid/reference/wix-site.html#timezone

timezone
Gets the site’s timezone.

Description
The retrieved timezone is the timezone that has been entered in the General Info section of your site’s Dashboard.

The timezone is used your site, apps (e.g. Wix Stores, Wix Bookings), and other Wix features.