0

I have to make an appointment booking system with WordPress, I have a custom post type "appointments" with various various custom fields like : Name, email, date, time, office, service...

Through a frontend form, the user can fill in these fields by selecting what interests him, after filling in all the data is saved and I can look at it from the "appointments" custom post type.

So far so good, my problem is that at the moment the form takes the available dates from a JSON file without a source and currently filled in manually for test(quite useless like that), since I've never done it I would like to understand if it can be done automatically write the available dates and times in the file, deriving them from those already booked and above all if it is the best solution or can it be done in a simpler way? Not have much experience with this

it will certainly be a little more complicated because the appointment is made based on the office and not just the month, so there will be different appointments for each office

The next step will be to add the automatic sending of an email both to the office and to the user, but one step at a time, the rest must work first.

the alternative would surely be a plug-in but I don't know which one! why do I have to use that template, do you know any plugin that allows you to rewrite the template of the form to make appointments?

this is the part of the form that concerns the date of the appointment

<?php
    $offices = get_posts(array(
        'posts_per_page' => -1,
        'post_type' => 'offices'
    ));

    $months = array();
    $currentMonth = intval(date('m'));

    for ($i=0; $i < 12; $i++) {
        array_push($months, $currentMonth);
        if($currentMonth >= 12) $currentMonth = 0;
        $currentMonth++;
    }
?>
<div class="card-header ">
                    <div class="d-flex">
                        <h2 class="title-xxlarge ">Offices*</h2>
                    </div>
                    <p class="subtitle-small ">
                        choose the office
                    </p>
                </div>
                <div class="card-body ">
                    <div class="select-wrapper p-0 select-partials">
                        <label for="office-choice" class="visually-hidden">
                            type of the office
                        </label>
                        <select id="office-choice" class="">
                            <option selected="selected" value="">
                                select option
                            </option>
                            <?php foreach ($offices as $o_id) {
                                $office = get_post($o_id);
                                echo '<option value="'.$office->ID.'">'.$office->post_title.'</option>';
                            } ?>
                        </select>
                    </div>
                    <fieldset id="place-cards-wrapper"></fieldset>
                </div>




<div class="card-header ">
                    <div class="d-flex">
                    <h2 class="title-xxlarge ">
                        Free appointment*
                    </h2>
                    </div>
                </div>
                <div class="card-body ">
                    <div class="select-wrapper select-partials">
                        <label for="appointment" class="visually-hidden">
                            Select month
                        </label>
                        <select id="appointment" class="">
                            <option selected="selected" value="">
                                select month
                            </option>
                            <?php foreach ($months as $month) {
                                echo '<option value="'.$month.'">'.date_i18n('F', mktime(0, 0, 0, $month, 10)).'</option>';
                            } ?>
                        </select>
                    </div>
                    <div class="cmp-card-radio-list ">
                        <div class="card ">
                            <div class="card-body ">
                                <div class="form-check " >
                                    <fieldset id="radio-appointment">
                                        nothing appointment free.
                                    </fieldset>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

this is the json where it gets the free time slots, 1, 2.... correspond to the month

{
  "1" : [
    {
      "startDate": "2023-01-20T09:00",
      "endDate": "2023-01-20T09:45"
    },
    {
      "startDate": "2023-01-20T09:45",
      "endDate": "2023-01-20T10:30"
    },
    {
      "startDate": "2023-01-21T09:00",
      "endDate": "2023-01-21T09:45"
    }
  ],
  "2" : [
    {
      "startDate": "2023-02-09T09:00",
      "endDate": "2023-02-09T09:45"
    },
    {
      "startDate": "2023-02-09T09:45",
      "endDate": "2023-02-09T10:30"
    },
    {
      "startDate": "2023-02-11T09:00",
      "endDate": "2023-02-11T09:45"
    }
  ],
}

instead the custom post type has the start date and end date fields. how can i proceed?

4
  • I think you need a custom post type where you can provide available appointment dates. Personally I'd build one where you set a date, then set the hours operating as well as the location, and then on the appointment form auto-generate a list of available slots. (If it's 8 hours and appts. are 30 minutes, that's 16 automated slots.) I would also then set these available dates to auto delete with a CRON to keep things leaner. You're recording he date/time of the appt. so once a date has passed, you don't need it in the availabilities anymore. Jul 20, 2023 at 20:00
  • hi, thanks, I didn't understand well, so should I make another custom post type like "times" with a post for each office that contains custom fields filled in with the start times of all slots? these post type and linked to "appointments" which fields must contain in order to be linked ? roughly I understand your reasoning which seems like a good idea to me but I can't figure out how to implement it. in practice I have to delete the available time slot when someone saves it?
    – LesCa
    Jul 20, 2023 at 22:29
  • @TonyDjukić hello, could you help me with some more information? I'm creating another custom post type but I don't understand which fields to put and how to connect it to the already existing "appointments" post type, I would like to try to create it as you were telling me, but it's not entirely clear to me, could you guide me?
    – LesCa
    Jul 22, 2023 at 14:57
  • I'll write it out as an answer, but it's going to be difficult to be exact or 'correct' because there are numerous permutations as to how this can be done. Jul 24, 2023 at 12:57

1 Answer 1

1

The solution here ultimately depends on how this business functions and how these available appointment slots are structured. Not just in a 'best case' scenario, but also providing users with the ability to customize the output/availability of appointments.

So, to start you have an 'appointment' custom post-type, this you've already built. This appointment CPT entries however are created not by back-end users, but rather by users who are booking an appointment on the front end. What you need is a way for backend users/admins/editors to create 'appointment slots' that can be selected by front end users when they are booking an appointment. (And thus creating an entry for your appointment CPT.)

My approach would be to make a second custom post-type where you set up 'available' slots for a period of time. Again, this will vary depending on the type of business and how it operates.

For example, you mentioned there are multiple offices, so my first thought would be to build the 'availability' CPT to work on a weekly basis. Then, I would make 'location' an option (maybe as a taxonomy or as post meta) and then I would provide a 'start date' and 'end date' field.

So let's say we're making an availability custom post-type for Monday, July 24th to Friday, July 28th for OFFICE NORTH. My next step is to set the start and end hours. So OFFICE NORTH is open, that week, from 9:00am to 5:00pm. My next step is then to set 'duration of appointments'. Is each appointment 15 minutes, 30 minutes, 45 minutes? Let's say they're 30 minute blocks for the sake of this exercise.

Once all of these fields exist and the data has been input, you 'Save/Publish/Update' the availability post. From there I would calculate the available appointment slots and record them into their own custom database table. I would index the date and location values. I would also then keep the times separate and in a serialized array.

The appt_times serialized array would be key/value pairs.

9:00am => 0 would indicate unbooked.

9:30am => 1 would indicate that the time slot is booked.

Once you have this basic outline set-up, then you can start adding in customization options. I would, personally, once the data set for available slots was built, then list all of the appointment times for that week in a list in the WP backend (in the edit screen for that specific availability entry) and I'd add a checkbox next to each one so that admins/editors can manually block off entries they don't want booked. Let's say on Thursday July 27th Head Office is sending a Regional Manager to OFFICE NORTH to have a meeting with the staff from 1:00pm to 3:00pm. You'd want to give the person setting up the availability slots the option of 'blocking off' these times:

1:00pm, 1:30pm, 2:00pm, 2:30pm

I reiterate, depending on how this business operates you may be better suited to building these availability records as a 'day to day' basis, or perhaps monthly. (Would NOT recommend making every appointment slot as an individual record as that will just bloat the database and make creating the time slots available too cumbersome and time consuming. We want to automate as much of this as possible.)

Once this data is in place, you would then use AJAX to populate the dropdown of available appointment slots. So a front end user/customer goes to book an appointment, they select a date and location and then AJAX retrieves the custom DB record for the date/location combo.

It parses through the data and locates every X:XXxm => 0 record and outputs an option in the dropdown for it.

From there, you do with the data what you need to create your appointment CPT entry.

Finally, as I mentioned in my original comment, I would then write a CRON task that will take today's date and check through the 'Availability' post-types and delete/unpublish any whose 'end date' is older than today and then also purge the custom DB table of times using the same logic. Because we aren't going to have people booking appointments in the past, so lets clear out that data and keep things leaner.

You STILL retain the past appointments though, because they're a separate post-type, so that's good for record keeping and reference, but what you've done is cleared out the 'slots' that are no longer usable.

Hope that helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.