Recently, I was tasked with adding a custom field to a WooCommerce order details section. This itself is not a major task and is well documented online, but this particular field had some special requirements. It had to
- Allow users to select a date for delivery/pickup
- Restrict possible order dates to days when the facility is open
Sounds simple enough, right? Just toss a calendar widget in there and limit the days to weekdays since weekends and holidays are the only days when this particular facility is closed. Weekends are easy, but holidays? That’s where it got a little bit weird. Take Labor Day for instance. It always falls on the first Monday in September. President’s Day falls on the third Monday of February each year. These wouldn’t be difficult to code for the current year, but we don’t want our calendar widget to only work for this year. It should work for every year, so we don’t have to remember to go update our code every December 31st.
This company also has special rules regarding holidays. For example, if the 4th of July falls on a Saturday, then they are closed the Friday before. If the 4th is on a Sunday, then employees get the following Monday off. All in all, there are 11 different holidays we need to prevent orders from happening on.
I wasn’t sure how this could all be done with jQuery, so I ended up doing it in PHP and then serving up an array of dates to be blocked off in the widget with an AJAX call.
In our PHP code, I went through the normal suggested steps of enabling AJAX calls in a plugin and ended up with the function `company_holidays_callback`. This function gets our current year, and pushes each holiday onto an array. It does this for the current year, and the following year. Figuring out the date for each holiday wouldn’t have been so simple without the PHP strtotime function. That was a life saver! And the function `fri_or_mon` was the logic used to mark the previous Friday or the following Monday off of the calendar as per special rule of this particular company.
To break down the jQuery, we create the instance of our datepicker on the element `#order_fulfillment_date`. If that element exists on the page, we perform our AJAX call to get the list of dates that need to be restricted. The function `noWeekendsOrHolidays` checks to if the date is a weekend. If it is, it gets disabled. If it isn’t, it passes the day onto `nationalDays` where we check if the date is one of our holidays that needs to be disabled as well.
In all of this code there isn’t really anything special or groundbreaking, but I thought the logic that determined the holidays was useful and maybe someone else could save themselves a little bit of time and headaches. Thanks for reading!