PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.17
Yatra – Travel Booking & Tour Operator Software v3.0.17
3.0.17 3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 All 85 releases
← All changes | readme.txt +119 -11 3.0.11 → 3.0.17 View file →
@@ -1,11 +1,11 @@
1 1 === Yatra - Travel Booking & Tour Operator Software ===
2 2 Contributors: MantraBrain
3 3 Tags: tour-booking, travel-booking, tour-operator, travel, travel-agency
4 4 Requires at least: 6.0
5 -Tested up to: 7.0
5 +Tested up to: 7.1
6 6 Requires PHP: 7.4
7 -Stable tag: 3.0.11
7 +Stable tag: 3.0.17
8 8 License: GPLv2 or later
9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html
10 10
11 11 WordPress travel booking plugin for tour operators. Trips, departures, payments, OTAs, AI. Free + [Pro](https://wpyatra.com/pricing/) from $99/yr.
@@ -139,9 +139,9 @@
139 139 * **Trip categories** — `yatra/trip-category` (same card layout as destinations; links use your trip category base from Settings).
140 140
141 141 **Shortcodes** (all accept string values as in the plugin defaults — use `yes` / `no` or `0` / `1` where noted):
142 142
143 -* **`[yatra_trip]`** — Trip listing. Alias: **`[yatra_tour]`**. Filters: `destination`, `activity`, `category` accept comma-separated classification IDs. Optional: `order`, `featured_priority` (`featured` / `new` / `limited`), `per_page`, `difficulty`, `price_min`, `price_max`, `duration_min`, `duration_max`, `search`, `columns`, `show_pagination`, `title`. Pagination: `trip_page`. Examples: `[yatra_trip]`, `[yatra_trip destination="44" activity="12"]`, `[yatra_trip featured_priority="new" per_page="6"]`.
143 +* **`[yatra_trip]`** — Trip listing. Alias: **`[yatra_tour]`**. Filters: `destination`, `activity`, `category` accept comma-separated classification IDs. Optional: `order`, `featured_priority` (`featured` / `new` / `limited`), `per_page`, `difficulty`, `price_min`, `price_max`, `duration_min`, `duration_max`, `search`, `columns`, `show_pagination`, `title`, `card_layout`. Pagination: `trip_page`. Examples: `[yatra_trip]`, `[yatra_trip destination="44" activity="12"]`, `[yatra_trip featured_priority="new" per_page="6"]`, `[yatra_trip card_layout="compact_all"]`.
144 144 * **`[yatra_activity]`** — Activity listing cards.
145 145 * **`[yatra_destination]`** — Destination showcase.
146 146 * **`[yatra_trip_category]`** — Trip category cards.
147 147 * **`[yatra_search]`** — Advanced trip search form. Per-field visibility attributes — `keyword`, `destination`, `activities`, `duration`, `budget` — each `yes` / `no`. Omit one to inherit its **Settings → Search & Listing** toggle; pass a value to force it on/off for that placement. Example: `[yatra_search budget="no" duration="no"]`. (The built-in listing page sets these automatically from your settings.)
@@ -150,8 +150,10 @@
150 150 * **`[yatra_discount_and_deals]`** — Discounted trips.
151 151
152 152 **Empty-term filtering (`hide_empty`):** `[yatra_destination]`, `[yatra_activity]` and `[yatra_trip_category]` accept `hide_empty="yes"` to skip taxonomy terms that have zero published trips. Opt-in (default `no`).
153 153
154 +**Card layout (`card_layout`):** `[yatra_trip]` / `[yatra_tour]` and `[yatra_discount_and_deals]` accept `card_layout` to set how the trip cards look for that one listing, overriding the site-wide **Settings → Design → Listing Card Layout** default. Values: `inherit` (default — follow the site setting), `standard` (full card), `compact_mobile` (compact horizontal cards on phones only, unchanged on desktop), `compact_all` (compact everywhere). The compact card shows image, title, price and a **View Details** button. Each listing is independent, so different listings on the same page can use different layouts. Example: `[yatra_trip per_page="6" card_layout="compact_all"]`. The **Trip** block offers the same choice under **Trip Settings → Card layout**.
155 +
154 156 **Note:** If you're migrating from an older build, `[yatra_cart]`, `[yatra_checkout]` and `[yatra_mini_cart]` are no longer registered — checkout and the booking flow now use Yatra's own front-end routes and templates. See **[docs.wpyatra.com](https://docs.wpyatra.com)** for full shortcode reference, URLs and page setup.
155 157
156 158 = 🎨 Compatible WordPress travel themes =
157 159
@@ -267,20 +269,126 @@
267 269 Pricing starts at **$99/yr** (Starter, sale) and goes up to **$599/yr** (Scale 15-site, sale). Lifetime plans available from **$499** one-time. Every Pro tier includes a **14-day refund** window. See the **[full pricing breakdown](https://wpyatra.com/pricing/)**.
268 270
269 271 == Screenshots ==
270 272
271 -📷 **Screenshots** (as shown on WordPress.org)
273 +1. Trip pages that sell themselves — gallery, duration, season and a sticky "Book Now" price button on any theme
274 +2. Book in a few taps, no redirects — live departure availability, traveller count and enquiry, all inline
275 +3. Your whole operation at a glance — bookings, revenue and upcoming departures the moment you log in
276 +4. Every trip in one organised list — search, filter by status, and see pricing, type and availability instantly
277 +5. Build a complete trip in one place — basics, pricing, itinerary, media and SEO, guided step by step
278 +6. Never lose track of a reservation — filter by traveller, payment state and status across every departure
279 +7. Full booking detail, one-click invoice — payment summary, traveller records and a downloadable invoice
280 +8. Every transaction accounted for — Stripe, PayPal, bank transfer and manual payments in one ledger
281 +9. Run offers without spreadsheets — coupon codes with usage limits, expiry dates and live status
272 282
273 -1. Yatra dashboard inside WordPress — bookings, revenue and quick access to daily tasks
274 -2. Trip Creation Process — content, pricing, media and settings in one workspace
275 -3. Trip list & All listing page — search, filters and status at a glance
276 -4. Trip Booking Process — hero, itinerary and book flow
277 -5. Global Settings - Payment Gateways etc.
278 -6. Traveler account — bookings, payments and documents
279 -
280 283 == Changelog ==
281 284
282 285 The two most recent releases are listed below. For the complete version history, see [changelog.txt](https://plugins.svn.wordpress.org/yatra/trunk/changelog.txt).
286 +
287 += 3.0.17 — 7 October 2026 =
288 +
289 +**New**
290 +* **Choose what happens to your data when Yatra is removed.** A new Uninstall section in Settings, after Advanced, carries a single switch: *Delete all data on uninstall*. It is off, so deleting the plugin leaves every trip, booking and customer in place and reinstalling picks up where you left off. Switch it on and deleting Yatra removes its tables, settings, scheduled tasks and user meta for good — leaving Yatra Pro's own settings and scheduled work alone for as long as Pro is still installed, so removing one plugin never half-removes the other — the screen says so plainly before you save, and Yatra Pro follows the same switch for its own data. Deactivating never removes anything either way.
291 +* **Kids-friendly and the other age filters can be re-tuned.** The age each band covers was fixed in the code — kids-friendly meant "12 and under" and nothing could change it. The four bands now come from one place and a site can set its own: `add_filter( 'yatra_age_suitability_thresholds', fn( $t ) => $t + [ 'kids_max' => 17 ] );`. The filter chips and the trips they return always agree, which they could previously drift apart on.
292 +
293 +**Fixed**
294 +* **Review request emails could go out in one large batch, long after the trip.** The request was scheduled for a fixed number of days after a booking was *marked completed*, which is not the same as days after the trip. The nightly sweep that completes finished tours can work through a backlog in one run, so customers whose trips had ended weeks or months earlier were all asked to review on the same night. The request is now timed from the date the trip ended, and a trip that finished longer ago than the new *Don't ask about trips older than* setting (14 days by default) is never asked about at all. Requests for trips ending on the same day are spread over an hour rather than sent in one burst, and any reminders already queued by an earlier version for trips that are now too old are cleared on update. Both the delay and the age limit are configurable under Settings → Review, and via the `yatra_review_reminder_days` and `yatra_review_reminder_max_age_days` filters.
295 +* **Traveller categories, attributes and itinerary item types were never exported.** The classifications table holds eight kinds of entry and a backup only ever contained four of them, so traveller categories, trip attributes, itinerary item types and itinerary items were silently missing from every export — and the trip links pointing at them could not resolve on import either, which quietly dropped a further 157 trip-to-classification links on the site this was tested against. All eight are now exported and restored.
296 +* **Restoring a backup onto a new site lost everything belonging to a Pro module that had not been switched on.** Yatra Pro creates each module's tables when that module is enabled, so on a fresh install the tables for Email Automation, Dynamic Pricing, Consent Forms and Additional Services do not exist yet, and every row destined for them was counted as a failure and discarded — 2,440 rows on the migration this was tested against, including the entire email history, pricing history and template set. The import now makes sure those tables exist before it writes. Whether you switch the modules on afterwards is a separate decision from whether your data survived the move.
297 +* **A re-import looked like it had done nothing.** The import summary only ever showed what it brought in and what failed, never what it recognised as already present. Importing a backup into the site it came from is supposed to bring in nothing — every row is already there — so the screen filled with zeroes and a red failure count, and read as a broken import. It now reports what was imported, what was already here, and what could not be linked, and says plainly when a file was already fully present. Rows that reference a record the file does not contain are no longer called failures: they are listed as "not linked", because that is what they are — usually something deleted on the original site. Data-type names with more than one underscore no longer render as "Email Sequence_steps".
298 +* **Review request emails are now off until you switch them on.** They were enabled on every new install. A review request is the one transactional email that is not a reply to something the customer just did, and several jurisdictions treat it as advertising rather than service mail — in Germany the Federal Court of Justice (VI ZR 225/17) holds that it needs prior consent, and the existing-customer exemption does not cover it. New sites therefore start with it off, so you can turn it on once you have decided how you collect that consent. **Sites that already have it switched on are unchanged.**
299 +* **The Email Logs missed everything Yatra itself sent.** Only the Pro automation and abandoned-booking modules wrote to the log, so a booking confirmation or a review request sent by Yatra's own templates left no record, and operators searching for an email a customer had received found nothing. Those sends are now logged too, marked as coming from Yatra core, with no duplicate entry for the emails Pro already records.
300 +* **Translated admin screens stayed in English unless a JS translation file happened to exist.** The React admin could only read translations from a script-translation JSON file. Translations from WordPress.org ship one, but a site translated by hand — with Loco Translate, or a .po/.mo dropped into wp-content/languages — has only the PHP catalogue, so every label, button and message in the admin stayed English no matter how complete the translation was. Yatra now hands those translations to the admin itself when no JSON file is present. Sites running in English are unaffected and carry no extra weight.
301 +* **Adding an availability date that already existed crashed the screen.** The date is unique per trip, departure date and time, so the second attempt was rejected by the database — and because the rejection was never checked, the code tripped its own return type and raised a fatal error. Operators saw "There has been a critical error on this website" and the Availability screen went blank. It now says *"Availability date already exists for the selected departure"* and the screen stays usable. The same check covers editing a date onto a slot another date already holds, which previously reported success while quietly changing nothing.
302 +* **Importing the same file twice duplicated everything.** Import gave every row a fresh id, so a second run doubled trips, bookings, discounts, availability and itineraries, while anything with a unique column was rejected outright — on one site every customer failed to import because their email addresses were already present. Import now recognises what the site already has and brings in only what is missing, so running it twice leaves you where the first run finished. That covers destinations, activities, categories and difficulty levels, which a second run used to re-add under renamed slugs, as well as service, consent-form and pricing-rule catalogues. Sent-email history is the one exception and is still appended, because two genuinely separate emails can look identical and skipping them would lose records from a restore.
303 +* **Importing could leave trip and category links pointing nowhere.** Restoring settings also restores the permalink bases, but the rules behind the URLs were not rebuilt, so trips and categories stopped resolving until someone re-saved Settings → Permalinks. The rules are now rebuilt on the next page load.
304 +* **"1 Trips" on activity, destination and category listings.** Those three templates always used the plural, so a single result read as "1 Trips" — and in a translated site, "1 Reizen". The count now picks singular or plural, and translators get a proper singular to fill in.
305 +* Import no longer probes Yatra Pro's email-template and consent tables on sites where those modules have never been enabled, which logged a database error for every row imported.
306 +
307 += 3.0.16 — 24 September 2026 =
308 +
309 +**Please read if you use reCAPTCHA.** With reCAPTCHA switched on for the booking form, checkout could not be completed on Stripe, Square or Authorize.net — the card form showed "reCAPTCHA verification failed. Please try again." and the payment never went through. Lowering the score threshold did not help, because no token was being sent at all. This release fixes that; if you turned reCAPTCHA off to take payments, you can turn it back on.
310 +
311 +**New**
312 +* **Download a booking's invoice from the dashboard.** Bookings → ⋮ → *Download invoice*, and a *Download invoice* button on the booking detail, produce a PDF for the whole booking rather than for a single payment. Available to anyone who can view bookings.
313 +* **Exclude a whole period from a recurring rule.** Trip → Availability → Recurring Rules gains **Excluded Periods**: give a first and last day and the rule skips everything in between, instead of adding a business vacation one day at a time. The existing single-date exclusions are unchanged and the two can be mixed.
314 +* **Choose what goes in the sitemap.** Settings → SEO → *Content in the sitemap* lets you publish only the types you want — trips, destinations, activities, trip categories, listing pages. Leaving a type out of the sitemap does not stop search engines indexing it, so there is a separate, deliberately opt-in **Also add noindex to excluded types**. It is off by default, because switching it on removes those pages from search results.
315 +* **Google Calendar controls** (with Yatra Pro). The Google Calendar screen gains *Resync Everything*, which walks every booking in batches and repairs the calendar in one click; an **Event reminders** editor so the 7/3/1-day reminders are no longer fixed; **Add customers as guests**, which keeps the customer's address off the event entirely so Google sends them no reminders or cancellations; and **One event per departure**, which puts every booking on the same departure into a single event with each booking's details in the description. The last one is off by default.
316 +
317 +**Fixed**
318 +* **reCAPTCHA blocked checkout.** Gateways that handle the card themselves (Stripe here, Square and Authorize.net in Pro) submit the booking directly, so they never attached a reCAPTCHA token and the server rejected every attempt. Each now sends its own fresh token. The account-registration form on the booking page had the same gap and is fixed too.
319 +* **Excluded dates were still bookable.** A date excluded from a recurring rule disappeared from the calendar but could still be booked by posting that date directly, because the resolver fell through to the trip's default availability. Excluded dates are now refused at checkout. An explicit availability row for that date, or another rule that generates it, still opens it as before.
320 +* **Availability times were demanded for tours that have none.** Adding or editing an availability date on a single-day tour insisted on a start and end time even when the tour has no time slots configured, so the date could not be saved. Times are now required only for day tours that actually use time slots, arrival time is always optional, and every field says whether it is required. The capacity field also stops overwriting a value you have already typed, and its help text names the tour's own maximum.
321 +* **Invoices and emails named the gateway, not its title.** Payment details showed the internal gateway id (`bank_transfer`) instead of the title your customers see at checkout ("Bank Transfer"). The payment invoice, the booking invoice, payment emails and the booking confirmation page now all use the checkout title, falling back to a readable version of the id for a gateway that no longer exists.
322 +* The sitemap is rebuilt as soon as you change what it contains, instead of waiting up to an hour for its cache to expire.
323 +
324 += 3.0.15 — 15 September 2026 =
325 +_With thanks to [Vista-Tours](https://vista-tours.de) for detailed testing and feedback._
326 +
327 +**Please read before updating — three things start happening that did not before:**
328 +* **Pre-trip reminder emails send again.** The reminder sweep was never scheduled and had no handler, and its booking query referenced a database column that does not exist, so no reminder has gone out. Both are fixed. Check the *Trip Reminder* template under Settings → Emails, or set *Booking Reminder (days)* to `0` to keep it off.
329 +* **Unpaid bookings are cancelled automatically** after *Settings → Booking → Booking Expiry (hours)* (default 24) — that setting previously did nothing at all. Only bookings created after you update are ever expired, so your existing pending bookings are never cancelled retroactively. Expiring a booking now also releases its departure seat. Set the hours to `0` to disable.
330 +* **Cancelling a booking now notifies your integrations.** `yatra_booking_cancelled` was never fired in-app, so Google Calendar kept cancelled bookings on the calendar and WhatsApp / webhook cancellation events never ran. Review those templates first.
331 +
332 +**New**
333 +* **Day trips show hours.** A single-day tour with a duration in hours now reads "8 hours" instead of "1 Day" everywhere — trip cards, hero, quick facts, availability dates, checkout, the confirmation page and email, saved trips, and the voucher / itinerary PDF.
334 +* **Configurable booking horizon.** *Settings → Booking → Booking horizon (months)* controls how far ahead customers can book (1–36, default 12); it was hard-coded to 12.
335 +* **Quick status changes for enquiries.** The Enquiries list's ⋮ menu gains Mark as Completed / Closed / Spam, so an enquiry can be handled without opening it.
336 +* **Auto-Confirm Bookings becomes a three-way choice** — don't auto-confirm, online payments only, or all.
337 +* **Compact listing card layout** for trip archives, shortcodes and the Trip block.
338 +* **Per-trip booking forms and per-trip email templates (with Yatra Pro).** Settings → Booking Form gains a **Conditions** button (Pro Dynamic Form Field) so selected trips, categories or trip types can use their own version of each form; Email → Templates gains **Override templates** (Pro Email Automation) — a trip-specific version of any booking email, sent *instead of* the global one. The free plugin ships the editors, a trip-aware `GET /settings/booking-form?trip_id=` endpoint, `trip_id` in every booking email's merge variables, and the `yatra_booking_form_config( $config, $tripId )` filter; without Pro nothing changes.
339 +* **Payments card on the booking detail** listing every payment recorded against the booking (amount, method, date, reference, status).
340 +
341 +**Fixed**
342 +* **A manually recorded payment now counts.** *Payments → Add New Payment* defaulted to *Pending* and offered a *Partial* status the database does not have, so a deposit recorded by hand never increased the booking's paid amount, never reduced the balance and triggered nothing. The form now defaults to **Completed**, *Partial* is gone, and a payment that becomes Completed (recorded, edited or *Mark as Completed*) fires `yatra_payment_completed` exactly like an online payment — payment-received emails, Pro `payment.partial_received` / `payment.received` automations, webhooks and WhatsApp — once per payment.
343 +* **Partial payments used the wrong email on Pro sites.** With the Pro *Partial Payment Received* template switched on, a deposit still went out as the full *Payment Received* email (`payment.received`); the chooser only honoured the free plugin's own toggle. It now honours the active Pro template, so a payment that leaves a balance sends the partial template and event.
344 +* **Language metadata followed the plugin, not the site.** Trip and listing pages printed `og:locale="en_US"`, `hreflang="en-US"` and `inLanguage="en-US"` on every site; they now follow the WordPress locale (`de_DE` / `de-DE` on a German site, including *Deutsch (Sie)*).
345 +* **Empty 360° tour and video modals were injected into every page** by `tour-viewer.js` / `video-player.js` (an empty `h3.yatra-tour-viewer-title` on the homepage, for example). Both are now built on first use only. YouTube *Shorts* URLs now embed correctly.
346 +* *Resend → Booking confirmation* on a **completed** booking sends the "Booking confirmed" email, not the pending-wording one.
347 +* Booking Form settings are now sanitised on save (the structured sanitiser was unreachable); the storefront date-pricing request no longer returns HTTP 500 on trips with date-specific departures; Edit Booking no longer hits a 401 loading tax settings.
348 +* **Duration (Hours) can now be saved.** The trip form showed the field for single-day tours but never included it in the save request, so the value was dropped and the field reloaded empty — the new hours display could not be used. Switching a trip back to multi-day now clears any stored hours rather than leaving a stale value.
349 +* Departures: *Upcoming* no longer hides sold-out departures; capacity is a separate **Availability** filter; the list is genuinely paginated and its search box works.
350 +* Enquiries: the status tabs showed `0` for every count; the bulk *Mark as Completed* action silently did nothing; a submission containing a `subject` field returned a server error.
351 +* The confirmation email is sent when a gateway payment auto-confirms a booking, and *Resend → Booking confirmation* resends the right template.
352 +* Gateways honour the Auto-Confirm setting instead of always confirming.
353 +* The "Payment not completed" notice can now be translated.
354 +
355 += 3.0.14.2 — 31 August 2026 =
356 +* **Fresh installs now create the trips table correctly:** a semicolon inside a column comment broke the `wp_yatra_trips` table creation during dbDelta, so a brand-new install could end up without the trips table — the tour list and sample-data import then failed. Existing sites were unaffected; updating recreates the table automatically.
357 +
358 += 3.0.14.1 — 31 August 2026 =
359 +* Declared compatibility with WordPress 7.1.
360 +
361 += 3.0.14 — 31 August 2026 =
362 +_With thanks to [Vista-Tours](https://vista-tours.de) for extensive beta testing and the detailed feedback behind many of the fixes in this release._
363 +
364 +* **Resend booking and payment emails by hand:** administrators can now re-send a booking's confirmation, payment, cancellation, reminder and completed emails — and the admin copies — from the booking view, after a manual change or when an automated email failed to arrive.
365 +* **Set a day tour's length in hours:** a single-day trip can carry a duration in hours (for example an 8-hour experience). The tour then shows its length in hours, and — with Yatra Pro — Google Calendar creates a same-day timed event of that length instead of an all-day, multi-day one.
366 +* **Dashboard capacity and occupancy match the Departures page:** the dashboard now reads capacity from your Availability configuration, exactly like Departures, so the two no longer disagree. Legacy "unlimited" capacity markers left on old departures are normalised, and a fully-booked upcoming tour stays visible on the dashboard instead of dropping out of the list.
367 +* **Star rating on the booking confirmation shows the right colour:** the rating stars rendered all grey on the confirmation page because a stylesheet was not loaded there; the correct colours are now applied.
368 +* **Cancelling a gateway payment returns to a working page:** cancelling PayPal (or any gateway) under a custom booking page led to a 404. Cancel and failure now land on the booking-confirmation page with a clear "payment not completed" notice.
369 +* **Offline gateways are never auto-completed:** Bank Transfer and Pay Later bookings could be marked paid automatically; they now stay pending until you confirm the payment by hand.
370 +* **Correct decimal separator in payment amounts:** amounts formatted wrongly on some European browsers; currency now formats consistently from your store settings. Invoices also use the booking reference as the invoice number.
371 +* **Completed (past) departures stay visible** in the tour list and the Past tab, independent of when the daily maintenance runs; **bulk-deleting departures** works from the all-tours view; and a new optional **date filter** in trip search and listings lets visitors find tours available on or after a chosen date.
372 +* **Changing a booking's tour moves its departure with it,** releasing the seat from the old departure and reserving it on the new one.
373 +* **Global "Always BCC" address can be saved:** the field under Settings → Email accepted an address but never stored it. It now saves, and accepts several comma-separated addresses.
374 +* **The email template list opens on the Active view,** so disabled or unused templates stay decluttered out of sight; the All and Inactive tabs remain available to review or re-enable them.
375 +
376 += 3.0.13 — 21 July 2026 =
377 +* **Star ratings now match the number shown:** a 4.9 average drew four-and-a-half stars beside the printed "4.9". Ratings round to the nearest half star everywhere — trip pages, the reviews block, listing cards and the booking confirmation all draw the same rating identically.
378 +* **Dashboard occupancy is no longer stuck at 0%:** the dashboard ignored the capacity figures the departures list actually returns, so every tour showed 0% occupied and available seats could read as a negative number, while the individual trip page calculated it correctly from the same departures.
379 +* **Departures honour the seats set on a time slot:** a private tour whose vehicle holds 9 passengers but sells a single booking unit per departure still showed 9 available. Capacity defined on a time slot is now used everywhere it applies, and where a date has several departure times each one uses its own seat count instead of the day's total.
380 +* **Sold-out dates no longer accept bookings:** a date marked sold out could still be booked, because the seat check looked past the sold-out record and fell back to the tour's overall capacity. Sold-out dates are now refused at checkout, or offered as a waitlist where the waitlist is enabled.
381 +* **Choose how sold-out dates appear:** a new *Show sold-out dates* option under Settings → Booking. Leave it on to keep them on the calendar marked "Sold out" (needed for the waitlist), or turn it off to hide them entirely, the way blocked dates are hidden. Existing sites are unchanged.
382 +* **Dates marked unavailable are hidden and unbookable:** an unavailable date stayed visible and could still be booked, unlike blocked, closed and cancelled dates.
383 +* **Manual payments recorded the wrong currency:** a payment added by hand was saved as USD regardless of the store currency, so a euro shop saw dollar amounts sitting beside correctly-formatted euro ones. Existing payment records are left as they are; new ones follow the store currency.
384 +* **Payment methods are labelled consistently:** the Payments list printed whatever each record happened to store, so gateway payments showed "paypal" while hand-entered ones showed "PayPal" or "Credit Card". Every row now shows the gateway's proper name.
385 +* **Changing the number of participants is saved:** editing the traveller count on an existing booking had no effect — the booking was saved with the original count, because the number was read from the traveller list rather than the field. Changing it now adds or removes traveller entries to match.
386 +* **Confirming a booking from the edit screen sends the confirmation email:** moving a booking to Confirmed from the booking editor saved the status but sent nothing and triggered no automation, while doing the same from the status action worked. Both routes now behave identically — and cancelling from the editor releases the seats, which it previously did not.
387 +* **Backend bookings reduce availability on tours with several departures a day:** a booking added from the admin never said *which* departure it was for, so on a tour running more than one departure a day it reserved no seats and the frontend still showed the date as free. The booking screen now asks for the departure time whenever the chosen date runs more than one, and the seats come off that departure.
388 +* **Invoices and vouchers show the complete business address:** only the street line was printed, so the town, postcode and country were missing from every document. All the address fields you have filled in are now included.
389 +* **The dashboard no longer goes blank:** a payment with no date threw an error that took the whole dashboard down with it. Dates that are missing or unreadable now simply render as "-" anywhere in the admin.
390 +* **Choosing a trigger event when creating an email template:** the template panel showed the event as a read-only badge with nothing to change it, directly beneath text asking you to pick one. It is now a working dropdown listing every available event.
283 391
284 392 = 3.0.11 — 20 July 2026 =
285 393 * **Departures now honour your recurring availability rule:** a tour with a 9-seat vehicle but a rule allowing only **1 booking per date** showed 9 under Departures. Overlapping rules were resolved in an arbitrary order (every rule carries the same priority), so the wrong one could win and the display fell back to the tour's passenger capacity. Rule matching is now deterministic — the most recently created rule wins a tie — and rules created in the editor are read correctly everywhere.
286 394 * **Departures can be deleted again:** deletion always failed with *"Manual departures or departures with bookings cannot be deleted"*, even for an empty, auto-created departure. The check required an internal value the plugin never actually stores, so **no** departure was ever deletable. A departure can now be removed once no bookings remain — checked against the real booking records rather than a counter that can drift — and departures with bookings are still protected.