=== Libre Bite – Restaurant POS, Kitchen Display (KDS) & QR Ordering for WooCommerce ===
Contributors: simon61
Donate link: https://github.com/simurech/libre-bite
Tags: woocommerce, restaurant, pos, ordering, food-delivery
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.1
Requires Plugins: woocommerce
Stable tag: 3.5.5
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Stress-free orders, happy guests, full tables — the WooCommerce plugin built for restaurants, take-aways, and cafés.

== Description ==

**More orders, less stress — Libre Bite turns WooCommerce into your restaurant's operational backbone.** No commission fees, no SaaS lock-in: your guests order online or at the table via QR code, pay with card, cash, or Twint, and your kitchen sees every order live on the board — all inside WordPress.

**Start for free. Upgrade only when you need more.**

---

= Free to Start =

All core features are available completely free of charge — no credit card, no trial period, no hidden limits.

A Pro subscription is only required for advanced features such as multi-location management, table ordering, optimised checkout, tipping, and pickup reminders. Pro plans are priced to be affordable — significantly cheaper than dedicated restaurant SaaS platforms.

**7-day free Pro trial — no payment required.**

---

= Built on WordPress & WooCommerce =

Libre Bite is a WordPress plugin. It extends WooCommerce — the proven e-commerce foundation used by millions of sites worldwide.

* **No new platform to learn** — manage everything inside your existing WordPress dashboard.
* **Your products stay WooCommerce products** — set them up once and they appear in the POS, checkout, and online shop automatically.
* **Use any WooCommerce-compatible payment gateway** — cash, card, Twint, Stripe, PayPal, or any other gateway you already have. Libre Bite charges **no transaction fees**.
* **Offline payments supported** — "Pay at pickup", "Pay at table", or any custom payment method via standard WooCommerce.

---

= For Whom Is Libre Bite? =

Libre Bite is built for **small and micro gastronomy businesses** — operations that want serious software without enterprise-level costs or delivery platform commissions.

* **Restaurants** — Take dine-in and take-away orders, keep the kitchen informed, delight guests with smooth service.
* **Take-Away & Fast Food** — Serve walk-ins fast with an integrated counter POS, accept card and Twint payments, no third-party fees.
* **Cafés & Bars** — Handle product extras, tips, and order flow without juggling multiple tools.
* **Multi-location businesses** — Run all branches from one WordPress installation, each with its own order board and POS (Pro).

---

= Modular by Design =

Only activate the features your business actually needs. Unused modules stay hidden — no cluttered menus, no unnecessary complexity.

---

= Core Features (Free) =

**Live Kanban Order Board (KDS)**
A real-time kitchen display that visualizes every incoming WooCommerce order as a card. Move an order through Pre-orders → Prepare Now → Completed with a single click — without reloading the page. Renaming, adding, or reordering columns, and dragging cards between them, is available as a Pro add-on.

**Integrated Point of Sale (POS)**
A clear POS interface for walk-in customers. Add products to the order, accept payments — all without leaving WordPress.

**Location Management**
Create and manage branches, each with its own address, opening hours, and order routing. Works immediately for single-location businesses.

**Swiss 5-Cent Rounding**
Built-in support for the Swiss rounding rule (5-cent rounding). Indispensable for restaurants and retail in Switzerland.

**Pickup Time Slots**
Customers choose a time slot for pickup directly during checkout. Relieve peak hours and better manage kitchen capacity.

**Product Options**
Add configurable options to any WooCommerce product — sizes, sauces, toppings, preparation notes — with optional price markups.

**Modular Feature Control**
Only enable what your business really needs. Each module can be independently toggled on or off in the admin area.

**WooCommerce HPOS Compatible**
Fully tested with WooCommerce High-Performance Order Storage (HPOS). Safe for modern, high-traffic setups.

**Sound Notifications**
A browser signal tone when a new order arrives on the Kanban board, so the kitchen doesn't have to watch the screen. Uploading your own custom sound file via the media library is a Pro feature.

---

= Pro Features (Subscription required) =

**Table Ordering (QR Code)**
Generate a QR code for each table. Guests scan it and order directly — no address or pickup time fields required. Orders appear in the dashboard with the table name.

**Multi-Location Management**
Manage an unlimited number of branches. Each location gets its own Kanban board, POS configuration, and separate order flow — managed centrally via one WordPress installation.

**Optimized Checkout Flow**
A conversion-focused checkout process for gastronomy businesses — fewer steps, cleaner layout, mobile-first.

**Advanced Tipping System**
Customers can select percentage tip suggestions (e.g., 5%, 10%, 15%) or enter a custom amount. Tip amounts are saved per order and broken out separately in the statistics.

**Automatic Pickup Reminders**
Automatic email reminders to customers X minutes before the scheduled pickup time. Fewer no-shows, better pickup experience.

**Nutritional Info & Allergen Labeling**
Nutritional values and allergen declarations for every product, displayed clearly on the product page. Includes a printable allergen matrix covering the 14 EU-listed allergens, to help you meet allergen labeling requirements.

**Promotions & Announcements**
Rule-based offers WooCommerce does not know by itself: buy several pay for fewer, a discount on a category, money off above a cart value — each limited to certain weekdays or times. Plus an announcement bar.

**Stamp Card**
One stamp per completed order, then a discount voucher. Guests grasp "every tenth order is cheaper" immediately.

**Theme-independent Menu View**
Output your menu in its own layout — category navigation, product cards, a dialog for variations and add-ons, and a slide-in order panel. Works with any theme, no template editing required.

**Dietary Labels & Filter**
Label dishes as vegan, vegetarian, gluten-free and more. Guests filter the menu without reloading the page.

**Scheduled Availability**
Limit products or whole categories to certain weekdays, times of day or date ranges. A breakfast menu that disappears at 11:30, a seasonal item that only shows in December.

**Order Bumps**
Offer matching extras right above the pay button. Added as real line items, so they appear on the kitchen ticket and count in the statistics.

**Time Slot Capacity**
Cap how many orders each time slot accepts, so the kitchen is not flooded at peak times.

**Guest Notes**
Keep allergies and preferences on the customer account and show them to staff when a returning guest reserves a table.

**SMS Notifications**
Send a short text message when an order is ready. Uses your own Twilio account — no order or customer data passes through us.

**Customizable Kanban Columns**
Rename, add, remove and reorder the columns of the Kanban order board to match your own workflow — mark any number of columns as "completed", add a one-step back button per order card, and optionally enable drag & drop between columns (Pro).

---

= Why Libre Bite? =

Delivery platforms take up to 30% commission. Dedicated restaurant SaaS tools charge monthly fees on top of that. Libre Bite is different: own your ordering system, pay no commissions, and keep every franc.

* **Commission-free ordering** — guests order directly on your website, no platform cut
* **No transaction fees** — ever
* **No order limits, no quotas** — take as many orders and reservations as you want, in every plan
* **No usage tracking** — your orders and reservations are never counted, hashed, or reported to any external server
* **Twint, card, cash** — accept any payment WooCommerce supports
* **Swiss 5-cent rounding built in** — essential for CHF cash payments
* **Separate VAT rates for takeaway and dine-in** — handled correctly, not bolted on (Pro)
* **QR code ordering at the table** — guests scan, choose, and pay in seconds (Pro)
* **Split payments and open tabs** — settle one bill across several payment methods, or keep a table running (Pro)
* **Multiple locations from one installation** — each branch with its own board, POS, and order flow (Pro)
* **Modular** — activate only what your business needs, nothing else
* **Your data stays yours** — in your own WordPress installation
* **Affordable Pro plans** — designed for small businesses, not enterprise budgets
* **7-day free Pro trial** — no payment required

---

= Works on Any Device =

Libre Bite works on any device — no app installation required. Use it with a mouse and keyboard on a desktop or laptop, or with touch input on a tablet. The Kanban order board, POS interface, and reservation dashboard are optimised for touch-first operation, making them well-suited for use on a tablet mounted at the counter or kitchen pass.

---

= How to Run Libre Bite =

**Option 1 — Extend your existing website**
Install Libre Bite directly into your existing WordPress/WooCommerce site. Any theme is compatible — no design changes required.

**Option 2 — Standalone installation (subdomain)**
Run Libre Bite as a dedicated installation on a subdomain, such as `order.myrestaurant.com` — completely independent from your main website, purpose-built for your gastronomy operation.

**Option 3 — Managed hosting by Libre Bite**
Libre Bite handles the complete setup: installation, configuration, hosting, and ongoing maintenance — from A to Z. Available as a paid service. Get in touch via https://pulacha-labs.ch/

---

= External Services =

This plugin uses **Freemius**, a third-party platform for managing licenses, subscriptions, and plugin updates for the Pro version.

During plugin activation, you can opt-in to data sharing with Freemius. Basic information about your website (WordPress version, PHP version, active plugins) is transmitted to Freemius to enable license validation and usage analysis. **Opt-in is completely optional.** All free core features work without opt-in.

* Freemius Privacy Policy: https://freemius.com/privacy/
* Freemius Terms of Service: https://freemius.com/terms/

No data is sent to Freemius if you skip or decline the opt-in during activation.

Libre Bite uses the **goQR.me API** (https://goqr.me/api/) to render QR code images in the WordPress admin area. This happens in two places: the location editor, which generates a QR code linking to your menu for a specific location (free feature), and the table editor, which generates a QR code for table ordering (Pro feature).

Only the encoded target URL of your own website is transmitted, so that the service can render the matching image. No personal data, customer data, or order data is sent. The request is only made while an administrator has the corresponding editor screen open — never during a customer order or on any public page.

* goQR.me API: https://goqr.me/api/
* goQR.me Privacy Policy: https://goqr.me/privacy-policy/

If you enable the optional SMS Notifications feature (Pro), Libre Bite sends the customer's phone number and a short status message to **Twilio** (https://www.twilio.com/) using your own Twilio account, so Twilio can deliver the text message. This only happens when the SMS feature is switched on and an order reaches the status you configured as the trigger — it never runs otherwise. You provide and control your own Twilio credentials; no order or customer data passes through Libre Bite's own servers.

* Twilio Privacy Policy: https://www.twilio.com/en-us/legal/privacy
* Twilio Terms of Service: https://www.twilio.com/en-us/legal/tos

== Installation ==

1. Upload the plugin folder to the `/wp-content/plugins/libre-bite` directory, or install the plugin through the WordPress plugins screen directly.
2. Activate the plugin through the **Plugins** screen in WordPress.
3. Make sure **WooCommerce** is installed and active — Libre Bite requires WooCommerce.
4. Follow the setup assistant — it checks your environment, lets you pick the modules you need, and can create a sample menu so you are not starting from an empty shop.
5. Alternatively, navigate to **Libre Bite** in the admin menu to configure locations, enable modules, and set up the POS and Kanban board.

== Frequently Asked Questions ==

= Is WooCommerce mandatory? =

Yes. Libre Bite is a WooCommerce extension. WooCommerce must be installed and active for Libre Bite to work. WooCommerce 8.0 or later is recommended.

= Which payment methods are supported? =

Libre Bite uses WooCommerce's standard payment system. Any WooCommerce-compatible payment gateway works — including Stripe, PayPal, Twint, cash on pickup, card at counter, and more. Libre Bite charges **no transaction fees**. You pay only for your payment gateway (if any) and the optional Pro subscription.

= Can customers pay in cash or at the counter? =

Yes. WooCommerce includes offline payment methods such as "Cash on Delivery" or "Pay in Person". You can rename and configure these freely — for example "Pay at pickup" or "Pay at the counter".

= Is the plugin compatible with WooCommerce HPOS? =

Yes. Libre Bite is fully compatible with WooCommerce High-Performance Order Storage (HPOS). It has been tested with both legacy post-based storage and the new Custom Order Tables.

= Does Libre Bite work with the WooCommerce Checkout block? =

Not yet. Libre Bite's location selection, time slots, order bumps, and tip settings currently rely on the classic WooCommerce checkout. If your checkout page uses the Checkout block, edit that page, select the Checkout block, and use its sidebar option to switch back to the classic shortcode (or replace it with a Shortcode block containing `[woocommerce_checkout]`). Libre Bite shows an admin notice with the same instructions whenever it detects the block on your checkout page. Official Checkout block support is on the roadmap.

= Can I manage multiple restaurant locations? =

Multi-location management is included in the Pro version. The free version supports a single location with full configuration of address, opening hours, and order routing.

= What is Swiss 5-Cent Rounding? =

In Switzerland, cash payments are rounded to the nearest 5 cents as 1- and 2-cent coins are no longer in circulation. Libre Bite applies this rounding rule at checkout, switched on by default for shops using CHF and off by default for any other currency — either way, it's a single toggle in Settings.

= Does the POS system work offline? =

The integrated POS system requires an active WordPress/WooCommerce session and an internet connection. It is a browser-based interface that currently does not support offline mode.

= Are there any order or reservation limits? =

No. Libre Bite never limits how many orders, reservations, or locations you can handle — not in the free version and not in any Pro plan. Your order volume is never counted, transmitted, or validated against an external server, so your ordering system keeps working even if our servers do not.

= Does Libre Bite share my data with third parties? =

Libre Bite uses Freemius for license management and delivery of Pro features. Data is only transmitted to Freemius if you explicitly opt-in during activation. No order, customer, or product data is transmitted — only basic website environment information (PHP version, WP version, plugin list). For more details, see the Freemius Privacy Policy: https://freemius.com/privacy/

= What are the minimum requirements? =

* WordPress 6.0 or higher
* WooCommerce 8.0 or higher
* PHP 8.1 or higher (PHP 8.2+ recommended)
* A modern browser for Kanban board and POS interface

= Is Libre Bite available in multiple languages? =

Yes. English is the source language, and the plugin ships with complete translations for Swiss, German and Austrian German (de_CH, de_DE, de_AT, plus the formal and informal variants), Swiss French (fr_CH) and Swiss Italian (it_CH). Every string is covered. Other languages can be added from the bundled .pot file or through community translations on translate.wordpress.org.

== Screenshots ==

1. **Kanban Order Board** — Real-time order management for kitchen staff. Update order status with a click as orders move through the board.
2. **POS Interface** — Integrated Point of Sale for walk-in customers and counter orders.
3. **Location Settings** — Configure branch address, opening hours, and order routing.
4. **Checkout Time Slots** — Customers choose their pickup time slot directly during checkout.
5. **Product Options** — Configurable extras and options for each menu item.
6. **Module Settings** — Toggle individual features on or off depending on business needs.

== Changelog ==

= 3.5.5 =
* Fix: The 3.5.4 fix for the two Plugin Check errors was incomplete (escaping was applied at variable assignment instead of at the point of output); corrected and verified against the official Plugin Check tool directly, not just by re-reading the code.

= 3.5.4 =
* Fix: Two WordPress Plugin Check errors (missing translators comment in the setup wizard's stamp card preview; an unescaped variable in the stamp card frontend display) that were failing the automated code-quality check.

= 3.5.3 =
* Fix: Currency symbols without a dedicated Unicode character (e.g. CHF) appeared as literal HTML entity codes instead of the actual symbol in the Setup Wizard tip preview, the Checkout Tips settings preview, the POS cart/payment screen, and the Product Options price label.

= 3.5.2 =
* Fix: On the Kanban order board, the order info text in the card footer could be squeezed out of view by the action buttons.

= 3.5.1 =

* Fixed: the two background tasks (pickup reminders, pre-order status changes) ran every minute on every installation, even on shops that never use pre-orders or reminders; they're now only scheduled while the relevant feature is actually on, and the custom schedule interval was renamed to avoid colliding with another plugin's identically-named one.
* Fixed: the pickup-reminder and pre-order background checks could have a backlog of old, already-handled orders crowd out the ones that actually need attention right now, since older entries weren't filtered out or prioritized. They're now scoped to the relevant time window and processed soonest-first.
* Fixed: three read-only endpoints (time slots, opening days, location status) required a security token that had a limited lifetime; if a page-caching plugin or CDN served a cached copy of the page for longer than that, checkout would silently stop working until the visitor reloaded. These endpoints only return public information, so the token requirement was removed.
* Fixed: the guest-notes phone lookup used a database search pattern that can't use an index and gets slower as the customer list grows; it now compares a pre-normalized number directly instead.
* Fixed: the POS product cache used a direct database delete to clear itself, which does nothing on sites using a Redis/Memcached object cache — stale product data could persist there indefinitely after a change. It also didn't clear when stock levels changed automatically. Both are fixed with a version-counter approach that works with any caching setup.
* Fixed: the till's coupon picker could be crowded out by personal, single-use reward coupons (e.g. from the stamp card) or already fully-used coupons, hiding real promotional codes on shops with many loyalty rewards.
* Fixed: reservation card details (name, phone, notes, guest allergies) were escaped twice, so an apostrophe or ampersand in a reservation showed up as a literal HTML code instead of the actual character.
* Fixed: a translation-loading order bug meant this plugin's own included translations always overrode community translations from wordpress.org for any string both contained, rather than the other way around as intended.
* Fixed: a public-facing checkout endpoint compared a security value using a plain string comparison, which is more vulnerable to timing-based attacks than the constant-time comparison already used by a nearly-identical endpoint elsewhere in the plugin.
* Changed: several inline `<script>`/`<style>` blocks are now delivered through WordPress's script/style system instead of being printed directly, and two CSS rules no longer depend on a WooCommerce stylesheet handle that some themes remove.
* Changed: the Kanban board, reservation board and table plan now pause their background refresh while their browser tab isn't visible, resuming immediately when it becomes visible again.
* Removed: an activation step that set up a database table system this plugin has never actually used.

= 3.5.0 =

* Fixed: the default POS payment method names ("Cash", "Card", "Other") were stored in German at installation time, which permanently overrode the translation on every site regardless of its language. Existing installs are migrated automatically; new installs and any site that never customized these labels now show them in the site's own language.
* Fixed: several hard-coded German or English-only strings ("Loading…", a stamp-card preview sentence, an order-created message, a "no configuration needed" message) now go through the normal translation system.
* Fixed: Du/Sie address was inconsistent across the German translations — the informal variants (Standard German, informal Swiss German) contained around 90 formal "Sie" strings each, and the formal variants contained a couple of stray informal "du" strings. Both are now consistent within each variant.
* Added: a one-time redirect to the setup assistant right after the plugin's first activation (skipped for bulk/network activation and WP-CLI), plus a persistent reminder on the dashboard and settings page for as long as setup hasn't been completed.
* Added: dashboard notices for the states that would otherwise silently prevent any order from completing — no location created yet, no POS payment method enabled, or the checkout page using the WooCommerce Checkout block.
* Fixed: importing the sample content while already at the Free plan's one-location limit created a second location that was silently saved as a draft; this is now reported clearly instead of looking like nothing happened.
* Fixed: the setup assistant's "WooCommerce is active" system check could never actually fail (the plugin doesn't load at all without an active, current-enough WooCommerce), so it only added noise — removed. Its "Continue" button had also been permanently disabled by a leftover reference to that check.
* Fixed: a "Dim Future Pre-orders" setting that could never take effect due to an unrelated internal flag with no way to enable it — even paying customers who turned the checkbox on saw no effect. The Kanban board's sound-notification default was also never read from its own setting, always defaulting to on regardless of what was configured.
* Removed: three dead/unreachable code paths found during an audit — an unused settings-registration call, an AJAX endpoint with no caller anywhere in the plugin, and a duplicate reservation-tables AJAX endpoint that was never wired to the frontend.
* Changed: the previously unreachable Debug Information page is now available under Settings → Developer.

= 3.4.9 =

* Changed: several readme descriptions no longer matched the current plugin — the Kanban board description and screenshot named drag & drop and column names that are actually a Pro add-on, nutritional info claimed a checkout display that doesn't exist, the FAQ said locations are unlimited on the free plan even though it's limited to one, Sound Notifications was listed as fully Pro when the base tone is free, and "Product Add-ons & Extras" and "Product Options" were used interchangeably for the same feature.
* Fixed: a link on the Support page to "edit these details under Settings" was visible to any role that can save plugin settings, but the Support settings tab itself is only visible to full administrators — non-admin managers saw a link that led nowhere useful.
* Fixed: the setup assistant's hint text for Product Options pointed at a menu label ("Product add-ons") that doesn't exist; the actual menu item is "Product Options".
* Fixed: activating the plugin without WooCommerce active showed a hard-coded, untranslatable error message.
* Added: Twilio is now listed under External Services, since the optional SMS Notifications feature sends the customer's phone number and a status message to Twilio when enabled.
* Changed: the default "support is free of charge" note on a fresh install no longer hard-codes a Swiss franc amount.

= 3.4.8 =

* Fixed: two license checks (the location limit on the Free plan and the pickup time-slot buffer) checked whether the code is running the Pro build rather than whether an actual Pro license or trial is active. On a Pro build without a valid license (for example after a trial ends), both stayed unlocked indefinitely.
* Fixed: the "Send receipt" button on Kanban cards always appeared, even when the code running underneath it doesn't include that feature; it's now only shown when it will actually work.
* Fixed: the dashboard tiles for disabled Pro features (Tables, Reservations) said "a manager can enable it under Settings" even without any license — they now clarify that a Pro license is required first. The Announcement Bar settings page was also missing its "Pro" badge.
* Changed: a note in the README now clarifies that the GitHub release contains the full Pro codebase, which requires a paid license (or the 7-day trial) to use the Pro features.
* Added: a warning notice when more than one location is published without an active Pro license or trial (for example right after a trial ends) — existing locations keep working, but no further locations can be published until the count is back to one or a license is active.

= 3.4.7 =

* Fixed: uninstalling the plugin with data deletion enabled left substantial data behind: order metadata on shops using High-Performance Order Storage (a separate database table the cleanup never touched), category time-schedule data, order-item metadata, and — for the underscore-prefixed keys used by guest notes and stamp cards — customer allergy notes and loyalty stamp counts. The role and capability cleanup also used an outdated, hand-maintained list that predated several current roles and permissions.
* Fixed: the option cleanup on uninstall used a very generic "oos_" prefix wildcard that could have deleted unrelated options from other plugins; it's now limited to the one legacy option name this plugin actually used.
* Added: guest notes and stamp card data (notes, allergies, stamp count, reward coupon) can now be exported or erased through Tools → Export/Erase Personal Data, and a short privacy policy suggestion is offered under Settings → Privacy.

= 3.4.6 =

* Fixed: a WooCommerce session cookie was set on every single page view (even for visitors who never touched a location link), which prevented full-page caching from working for any first-time visitor. The cookie is now only set when a location or order-type deep link parameter is actually present in the URL.
* Fixed: a translation filter for the checkout "Billing details" heading compared against a German string that could never match (the filter always receives the original English text), so it silently did nothing; it also ran an expensive page-type check for every single translated string on the site instead of only for the one relevant string.

= 3.4.5 =

* Fixed: the tip amount was never saved to the order (only added as a checkout fee), so the statistics page counted every tip as a generic add-on instead of showing it separately.
* Fixed: cart-wide and "buy N get M free" promotion discounts were recognized in the statistics page by matching the English fee name "Promotion: " — on non-English shops (including all German, French and Italian setups) this never matched, so these discounts were silently counted as regular add-on revenue.
* Fixed: the statistics page loaded the entire matching order history into memory in one query and only filtered by location afterwards in PHP; large shops with a long order history could hit memory or time limits. Orders are now fetched in batches and filtered by location directly in the database query.

= 3.4.4 =

* Fixed: time slot capacity only counted orders created in the last 24 hours, not by their pickup time. A pre-order placed more than a day in advance was invisible to the capacity check, so a fully-booked slot could still be overbooked. Capacity is now counted by pickup date; existing pre-orders are backfilled automatically on update.
* Fixed: a location's "Open now" status ignored holidays entirely — closed holidays still showed as open and accepted immediate orders, and a holiday with special hours on an otherwise closed weekday showed no available time slots at checkout.
* Fixed: the holiday date-picker in Settings also greyed out holidays that have their own special opening hours, not just fully closed ones.
* Fixed: the "next opening" text (e.g. "Opens Mon 11:00") always showed the day abbreviation in German, regardless of the site's language.

= 3.4.3 =

* Fixed: cart-wide promotion rules ("buy over X, get Y% off" and "buy N, get M free") calculated the discount as a fee that did not reduce the tax base, so VAT stayed at the pre-discount amount. The discount fee is now taxable, using the same tax class as the order (including the Takeaway/Dine-in Swiss VAT switch, if enabled).
* Fixed: on shops that display prices including tax, a percentage or minimum-order-value promotion was calculated against the tax-excluded subtotal, giving a smaller discount than advertised and applying the minimum-order threshold too late.
* Fixed: a promotion's day/time schedule was silently discarded when saved while the (unrelated) Scheduled Availability feature was switched off, and any already-saved schedule was ignored at checkout — the promotion ran around the clock regardless of its configured hours.

= 3.4.2 =

* Fixed: the Stamp Card's "Maximum amount" setting made the reward voucher invalid on carts above that amount instead of capping the discount at it. The discount is now genuinely capped, verified against carts both under and over the limit.
* Fixed: a fixed-amount reward (rather than a percentage) was rounded down to a whole number and could not exceed 100 — a CHF 7.50 reward was silently saved as CHF 7, and anything above CHF 100 was rejected.
* Fixed: the stamp card display always said "% off" even when the reward was configured as a fixed amount.
* Fixed: an already-redeemed or expired reward voucher kept showing on the stamp card indefinitely instead of clearing once it could no longer be used.
* Fixed: cancelling or refunding an order that had already earned a stamp never gave the stamp back.

= 3.4.1 =

* Fixed: Locations, Tables, and Product Options used WordPress's generic post-editing rights, so any Author (or other role able to publish posts) could create or publish one directly by URL, bypassing the plugin's own menus entirely. All three now require the same dedicated capability the plugin's own menu already expected.
* Added: a dedicated permission for managing reservations, separate from the Product Options permission it was previously tied to. Staff and Managers can now open the Reservations board and change a reservation's status or table, as documented — previously only full Administrators could.
* Fixed: the "Delete Data on Uninstall" setting could be changed by a Shop Manager; it is now restricted to full Administrators, matching how the option is presented in the interface.
* Fixed: the POS "create order" endpoint accepted the generic `edit_posts` capability as an alternative to the dedicated POS permission, which unintentionally let non-POS roles create orders through it.

= 3.4.0 =

* Fixed: the checkout, the table QR code link, and the reservation form accepted any numeric ID as a "location" or "table" without checking it was actually one — the title of an unrelated post could end up in the order, the thank-you page, and confirmation emails. Table QR codes also bypassed the location's availability window. All three now validate against the real location/table.
* Fixed: a pre-order pickup time was only checked against remaining capacity, not against its format, whether it was in the past, or whether the location actually offers that time slot at all.
* Fixed: the reservation form only checked that the date was "today or later" — a time earlier today, a time outside opening hours, a closed holiday, and double-booking the same table at the same time were all accepted.
* Fixed: a guest who created an account during checkout (turning them from logged-out to logged-in mid-request) could lose their selected location and pickup time, because a redundant nonce check no longer matched after the login state changed.

= 3.3.3 =

* Fixed: cancelling an order from the dashboard had no status check, so an already-completed or already-refunded order could be cancelled (and refunded again) a second time. Only orders still in Processing, On Hold, or Pending can be cancelled now, and a partially refunded order is refunded for the remaining amount only, not the full total again.

= 3.3.2 =

* Fixed: the location restriction for managers and staff (Settings → Manager Assignments) only applied to the REST API and the Statistics page. Over the regular admin-ajax endpoints, staff and managers could view, change, and cancel orders at any location, and retrieve the receipt of any WooCommerce order, not just their own location's. All order-related endpoints now check location access consistently through one shared class.
* Fixed: on the Statistics page, a manager or staff account with no location explicitly assigned saw an empty report instead of all locations — the opposite of what an empty assignment means everywhere else in the plugin.

= 3.3.1 =

* Fixed: on the optimized checkout's thank-you page, a guest without an email on file who requested their receipt had it sent to an internal placeholder address instead of the address they just typed in — because the email was triggered before that address was saved. The address is now saved first, and the request is also checked against the order's key, not just a nonce, so it cannot be replayed against a different order.

= 3.3.0 =

* Fixed: settings that only show a field while their feature is switched on (SMS credentials, pickup reminder settings, tip amounts, checkout mode) reset that field to empty the moment the feature was off when the page was saved. Twilio credentials, for example, were lost simply by saving Notifications while SMS was disabled. Each such field now only changes when it was actually visible on the page you saved.
* Fixed: saving Settings could trigger a "headers already sent" warning and fail to redirect back to the page with the "Settings saved" notice, because the save logic ran after WordPress had already started sending the page. It now runs earlier, before any output.
* Fixed: the Kanban board refresh interval had no server-side minimum — entering 0 caused constant requests. It is now capped at 10 seconds; the default for new installations is unchanged.

= 3.2.9 =

* Fixed: 5-cent rounding used two separate settings that could disagree — the feature toggle (on by default) and a second option that stayed off until Settings were saved once. A fresh CHF installation therefore did not round anything until that first save, and saving once turned rounding on even for EUR shops. There is now a single setting, defaulting to on only for CHF shops.
* Fixed: the POS only displayed the rounded total; the saved order kept the unrounded amount. POS orders are now rounded server-side too, before any split-payment amounts are checked against the total.

= 3.2.8 =

* Fixed: pre-orders could switch to "Preparing" up to 2 hours too early (and pickup reminder emails could go out up to 2 hours too early, or never at all for orders with less than 2 hours of lead time) outside UTC. The comparison mixed a timezone-shifted timestamp with a true UTC one; both now use the same UTC-based clock.

= 3.2.7 =

* Fixed: order card buttons on the Order Board overflowed their box when more than three Kanban columns were configured. Cancel, Send Receipt, and Print are now grouped behind a "More actions" (⋮) menu, keeping only the main workflow button(s) directly visible.

= 3.2.6 =

* Added: Libre Bite now detects when the checkout page uses the WooCommerce Checkout block instead of the classic shortcode and shows a persistent admin notice with step-by-step instructions to switch back — Libre Bite's location, time slot, order bump and tip features do not work with the block yet. The same check is part of the setup assistant's system check, and WooCommerce itself flags the incompatibility in the block editor.

= 3.2.5 =

* Changed: hiding WordPress blog posts and removing "Downloads"/"Addresses" from My Account are now two separate, optional settings under Settings → Content & Account, both off by default. Previously the plugin always hid blog posts and those two account sections with no way to turn it off, which made existing blogs disappear without the site owner knowing.
* Fixed: the CSS fallback that hid the Posts admin menu never actually applied (it ran too late to affect an already-registered stylesheet).

= 3.2.4 =

* Added: the Statistics page now shows how many orders came from the POS versus the website's own checkout, with order count, revenue and share for each — plus a matching "Source" column in the CSV export.

= 3.2.3 =

* Changed: the Statistics page's payment methods breakdown showed the same numbers twice (a bar chart followed directly by an identical table). Now shown once as a table, sorted by revenue, matching how Top Products and Promotions already present their numbers.

= 3.2.2 =

* Fixed: the Statistics page's payment methods breakdown only ever showed orders placed at the POS. Orders placed by guests through a configured WooCommerce payment gateway (Stripe, PayPal, invoice, etc.) were silently missing from both the on-screen table/chart and the CSV export. They now show up under the gateway's own name.

= 3.2.1 =

* Added: Order Bumps and Promotions now use a live product search instead of entering raw product IDs by hand; Promotions gained a category picker too.
* Added: the announcement bar supports more than one time window per day (for example 8:00–12:00 and 14:00–18:00) and an option to open its link in a new tab.
* Added: the Stamp Card reward can now be a fixed amount instead of only a percentage, a percentage reward can be capped at a maximum amount, and the reward can be limited to specific product categories and/or to a single item of the next order.
* Added: a "Promotions" section on the Statistics page shows how often each rule was used and the total discount it gave, including product-price discounts that previously left no trace anywhere.
* Fixed: the SMS section of the Notifications page sat outside the page's `<form>` and could never actually be saved. The page is now grouped into clearly separated Sound, Email and SMS sections in one form; the SMS section also gained the same Pro-badge styling used elsewhere, and the previously invisible "send reminder emails" toggle and lead time are now on the page.
* Fixed: a mistranslated German label on the Promotions page read "Regel ist scharf" ("rule is spicy") instead of "rule is active".
* Fixed: the Manager Assignments checkbox grid rendered every checkbox unchecked after saving, even though the assignment was saved correctly — a strict type comparison between a string and the stored integer IDs.
* Changed: Manager Assignments is now a checkbox grid instead of a multi-select box, and lists every relevant user (administrators, managers, shop managers, staff) for a full overview — not just managers.
* Changed: the Holidays tab moved from Appearance to Setup, next to Locations.
* Changed: the "Libre Bite Staff" role is now listed first under Menu Visibility instead of wherever WordPress happens to register it.

= 3.2.0 =

* Changed: the Settings page navigation is now a grouped, vertical sidebar (Setup, Operations, Marketing & Communication, Appearance, System) instead of a single row of tabs — easier to scan once a business turns on several modules.
* Changed: the previously long Products, Checkout, Orders, Marketing and Advanced settings pages are now split into focused, single-purpose pages (for example Tips, Order Bumps and Promotions each have their own page instead of sharing one) — no behavior change, all existing values and save logic are unaffected, and each page saves independently so turning one setting off never resets an unrelated one.
* Added: live previews on several settings that were previously hard to picture in advance — tip buttons, kanban board columns, receipt templates, the announcement banner, the stamp card, and the availability hint style now show what the guest or staff member will actually see as you change the values.
* Changed: the setup assistant's progress indicator now reflects the actual number of steps for the modules you selected instead of four fixed labels, and the welcome step leads with three short highlight cards instead of a plain bullet list.
* Added: the Tips and Stamp Card steps of the setup assistant show the same live preview as the corresponding Settings page.
* Added: a "Run setup assistant" link at the top of Settings, so the assistant can be revisited any time instead of only right after activation.
* Fixed: the setup assistant's links to Order Bumps, Promotions and the Stamp Card pointed at the wrong settings tab (a leftover from before these moved to their own Marketing tab in 3.1.0).

= 3.1.1 =

* Fixed: new orders always started in whichever column happened to be configured first, regardless of whether they were an immediate or a pre-order; a display-time workaround then silently re-routed "now" orders without ever saving the correct status. Pre-orders and immediate orders now get the right column from the moment the order is created.
* Fixed: renaming or removing the default Kanban columns silently broke the automatic cron job that moves pre-orders forward as their pickup time approaches — with no error, no log, nothing.
* Changed: the "Pre-orders" and "Prepare Now" Kanban columns are now fixed — they can be relabelled but not deleted, renamed to a different key, or reordered. The "Pre-orders" column only appears at all while pre-orders are enabled. Custom columns always follow after them.
* Added: the "Pre-orders" feature, previously only configurable once during the setup wizard, now has a permanent toggle under Settings → Locations.
* Added: a new "Developer" settings tab documents the REST API (base URL, authentication, routes, extension hooks) that was previously only described in internal notes.
* Removed: an unused, unreachable order-creation code path in the POS module that still carried the old, ambiguous column logic.
* Removed: a leftover "Beta" label on the Table Plan page.

= 3.1.0 =

* Changed: the separate "Help & Support" page is gone. Field explanations and shortcode references now live directly next to the setting they belong to; a much smaller "Support" page still shows the contact details and conditions configured under Settings → Support, for every role.
* Added: a new "Marketing" settings tab collects Order Bumps, Promotions, the announcement bar and the stamp card — previously bundled into an already overloaded Checkout tab.
* Changed: the settings tabs are reordered to follow how a new store actually gets set up (Locations → Products → Checkout → Prices & Taxes → Marketing → Orders → POS → Tables → Reservations → Notifications → Branding → Holidays → Advanced → Support).
* Fixed: the Products tab grouped the theme-independent menu view and scheduled availability under "Nutritional Information", though neither has anything to do with nutrition.
* Added: turning on the theme-independent menu view now offers a page picker with one-click page creation for the `[lbite_menu]` shortcode, the same convenience the location selector already had. Previously the feature had no next step after the toggle.
* Fixed: the Kanban column editor on the Orders tab was always visible, even with the "Customizable Kanban Columns" toggle off; saving in that state could silently reset a previously configured column layout back to the three defaults.
* Changed: the order-type selector and table picker in the POS are now large, tappable tiles and a button grid instead of radio buttons and a dropdown, for easier use on a tablet.
* Changed: the "Open Tabs" button moved next to the order-type selector, where it stays in view while taking an order, and shows a clearer count badge. In German, "Tab" is now translated as "Rechnung" to avoid clashing with the existing "Tischbestellung" (dine-in) label.
* Changed: the dashboard now shows disabled modules as greyed-out tiles at the end of the grid instead of hiding them, with a note that they can be enabled under Settings.

= 3.0.3 =

* Fixed: in the dark colour scheme a short page ended its dark area halfway down the screen, leaving a large light block below it. The background is now set on the page itself, not only on the content container.
* Fixed: the setup wizard could not be opened at all — not even by an administrator. Registering the page and then removing it from the menu also removed the path WordPress uses to authorise it.
* Fixed: the green tick marks of the wizard's system check were drawn white on white.
* Added: access to the setup wizard now follows its own capability. Administrators, managers and shop managers have it; point-of-sale staff deliberately do not.
* Added: the wizard now walks through each enabled module and asks for the settings that matter to get started, with a skip option per step. Existing configurations are left untouched — every field is pre-filled with the current value, so clicking straight through changes nothing.
* Added: the light, dark and automatic colour scheme can now be chosen under Settings → Branding, not only in the WordPress profile.
* Fixed: module names and descriptions were shown in English regardless of the site language.
* Fixed: the action buttons on the order board carried white text on colours too light to read it — in both colour schemes, not only the dark one.
* Fixed: the category buttons in the POS were unreadable in the dark colour scheme.
* Fixed: the plugin's own list screens (locations, tables, add-ons, reservations) ignored the colour scheme entirely, so you clicked from a dark page into a bright one.
* Changed: while `SCRIPT_DEBUG` is on, asset URLs carry the file's modification time. Without it a stylesheet fix inside the same plugin version only reached the browser after a hard reload.
* Fixed: three messages in the location selector were hard-coded in German and appeared that way on every site, whatever its language. They now go through the translation system like everything else.
* Added: the French (fr_CH) and Italian (it_CH) translations are complete. All seven bundled language files now cover every string.
* Fixed: the plugin's own edit screens (locations, tables, add-ons) carried the colour scheme class but never loaded the stylesheet that defines it, so the dark scheme had no effect there and WordPress logged a notice about an unregistered dependency. Whether a screen belongs to Libre Bite is now decided in one place instead of two.

= 3.0.2 =

First release tested on a live WordPress installation. Version 3.0.0 introduced a large amount of new code that had only been reviewed, not yet tested end-to-end; this release fixes what that testing brought to light.

* Fixed: with a tip and a promotion active at the same time, the final total was no longer rounded to 5 rappen. The tip rounded itself on the subtotal alone, so discounts and shipping were left out of the calculation.
* Fixed: an item added to the cart after the first price calculation — for example through an order bump — never received its promotional discount and was charged at full price.
* Fixed: guest notes could not be switched on at all. The feature had no checkbox anywhere in the settings.
* Fixed: enabling only the dietary filter loaded no code, because the module was tied to the nutritional information and allergen switches.
* Fixed: the table plan button in the settings pointed at a page that does not exist, and the table plan itself rendered without its app layout.
* Fixed: order bumps did nothing when the location selector was switched off, because the frontend script was tied to that setting.
* Fixed: the manager role was not created during activation. Anyone assigned to it ended up with no role at all and lost access to the admin area.
* Fixed: products marked for point-of-sale use only could still be added to the cart by a prepared request, although they were hidden from the catalogue, search and direct access.
* Fixed: order bumps were added to the cart without the availability checks that apply everywhere else, so an item blocked at the selected location could still be ordered.
* Fixed: the welcome notice never appeared after a first installation, and the installation date was reset on every reactivation.
* Fixed: a PHP warning was written on every cart calculation that involved a fee.

= 3.0.1 =

* Raised the minimum PHP version to 8.1. PHP 7.4 has been without security updates since November 2022, and sites still on it should not be running a payment-handling plugin. The code itself ran on 7.4, so nothing functional changes for anyone on a supported version.

= 3.0.0 =

This release rounds out the feature set that 2.6.0 started. As with any major release, testing it on a staging site first is recommended before using it in production.

**New**
* Promotions engine: buy several and pay for fewer, a discount on products or a whole category, money off above a cart value — each limited to certain weekdays or times of day (Pro)
* Announcement bar at the top of the shop, with the same scheduling (Pro)
* Stamp card: one stamp per completed order above a minimum value, then a single-use discount voucher tied to the guest's email address (Pro)

**Notes**
* Promotion discounts are applied before the tip and the 5-cent rounding, so the tip is never calculated on an amount nobody pays
* "Buy several, pay for fewer" always makes the cheapest qualifying items free
* The stamp card only works for orders placed with a customer account — guest checkouts cannot be attributed to anyone

= 2.6.0 =

**New: Menu & guest experience**
* Theme-independent menu view via the `[lbite_menu]` shortcode — category navigation, product cards in a grid or list, a dialog for variations and add-ons, and a slide-in order panel (Pro)
* Dietary labels (vegan, vegetarian, gluten-free, lactose-free, spicy, alcohol-free) with a filter bar above the shop grid (Pro)
* Scheduled availability: limit products or whole categories to certain weekdays, times of day or date ranges — a breakfast menu that disappears at 11:30 (Pro)
* Order bumps: offer matching extras above the pay button, added as real line items so they appear on the kitchen ticket and in the statistics (Pro)

**New: Kitchen & counter**
* Waiting time timer on every order card, turning amber and then red as an order ages, with an optional repeating alert sound
* Receipt templates for kitchen, customer and delivery, each with configurable content, on a proper 80 mm layout
* Time slot capacity: cap how many orders a slot accepts so the kitchen is not flooded at peak times (Pro)
* Floor plan image as the background of the table plan, so tables can be placed where they actually stand

**New: Setup & operations**
* Setup assistant with system check, module selection and an optional sample menu, so a fresh installation no longer starts empty
* Printable allergen matrix covering all products and the 14 EU allergens
* Guest notes: keep allergies and preferences on the customer account and show them to staff when a returning guest reserves (Pro)
* SMS notifications via your own Twilio account, with the auth token stored encrypted (Pro)
* Revenue charts on the statistics page: daily trend, revenue by location and payment method split

**Under the hood**
* New admin design system with central design tokens; all admin stylesheets migrated
* Dark colour scheme for the Libre Bite screens, selectable per user — easier on the eyes on kitchen displays that run all day
* REST API under `lbite/v1` alongside the existing endpoints, authenticated with WordPress application passwords
* New action hooks at the core transitions for printer bridges, secondary kitchen displays and external notifications
* Branding colours now apply to the backend as well

**Fixed**
* Table and ASAP badges on the order board were hard-coded in German and stayed German in other languages
* The "load more orders" button had the same problem
* Completed the external services declaration: the QR code service is also used by the free location feature, not only by table management

= 2.5.0 =
* New: The reservation form is now a clear, guided 3-step process — When & How Many, Your Details, and a final Confirmation summary — instead of one long form (Pro).
* New: The phone number and notes fields on the reservation form can now be hidden in the settings for guests who don't need them (Pro).

= 2.4.0 =
* New: Customizable Kanban board columns — rename, add, remove and reorder columns (2 to 5), mark any number of them as "completed", and add a one-step back button to each order card (Pro).
* New: Optional drag & drop between Kanban columns, configurable independently of the column layout (Pro).

= 2.3.1 =
* Fix: Corrected a contrast issue where the "Back" button in the location selector could become unreadable (black background/text) on hover due to theme style conflicts.
* New: Locations are now selected automatically when only one location exists — no more redundant location step in the POS, Kanban board, or storefront checkout.
* New: The location editor now shows a read-only list of all products available at that location, with quick links to edit each one.

= 2.3.0 =
* New: Split payment in the POS — divide an order's total across multiple payment methods (e.g. part cash, part card) directly in the payment dialog, with automatic reconciliation for small rounding differences (Pro).
* New: Open tabs for table service — start a tab for a table, add further rounds of items before the guest pays, and close it out with a single payment at the end; the Kanban board keeps the order open until the tab is closed (Pro).

= 2.2.4 =
* Maintenance: Confirmed compatibility with WordPress 7.1, "Tested up to" updated.

= 2.2.3 =
* Maintenance: Resolved remaining WP.org Plugin Check findings (missing translators comments, unescaped output, discouraged date()/strip_tags() usage, missing input sanitization) that were fixed on GitHub after 2.2.2 was tagged.

= 2.2.2 =
* Autor-Rebranding zu Pulacha Labs.

= 2.2.1 =
* Fix: Product availability hint no longer breaks the shop grid layout in themes that lay out product loop items as a horizontal flex row (e.g. Astra's "List Style"), where it previously appeared as an unwanted extra column instead of below the product content.
* Fix: Availability popup can no longer be clipped by product cards with hidden overflow (e.g. hover-zoom image effects) and now sizes itself correctly to its content.
* Fix: Low-contrast "Opens on ..." location status badge and text overflowing its box on mobile in the location selector.
* New: Availability hint (category & product page) and availability filter (shop page) can now be independently enabled/disabled in Settings → Products (Pro).
* New: Three display styles for the availability hint — popup (default), always-visible list, or plain text — for better compatibility with different themes.

= 2.2.0 =
* New: Locations can now have an optional activity window (active from / until date) for future or temporary locations. Until the opening date, the location stays visible but locked with an "Opens on ..." notice; pre-orders for the opening date or later are already possible.
* New: Product-location assignment switched from an opt-in whitelist to an opt-out blacklist — products are now available at all locations by default, and only need to be disabled for specific locations. New locations automatically get all existing products. Existing assignments are migrated automatically.
* New: Product availability indicator on the shop grid and single product page, showing at a glance how many (and which) locations carry the product.
* New: Availability filter on shop and category pages lets customers pick a location to see what is available there — including before any location has been selected elsewhere, and without needing to commit to an order time.
* Fix: Holiday "All locations" checkbox selection was reset to nothing after saving.
* Fix: Availability filter and its styling/scripts now load correctly on product category pages (previously only loaded on the main shop page).
* Fix: POS variant selection now respects the WooCommerce default variation instead of always preselecting the first one.
* Fix: Missing German translations for the availability filter notice in some locale variants.
* Removed: Decorative title above the location selector tiles.
* Maintenance: Updated Freemius SDK to version 2.13.4.
* Maintenance: Changelog section trimmed to stay within WordPress.org's word limit; full history available on GitHub.

= 2.1.5 =
* Update: Lowered minimum required PHP version to 7.4 (no 8.0+ language features are used)
* Fix: License field now uses the consistent SPDX identifier GPL-2.0-or-later

= 2.1.4 =
* Maintenance: Updated Freemius SDK to version 2.13.3.

= 2.1.3 =
* Performance: POS product query now uses WordPress term cache instead of individual database queries per product, significantly reducing DB load on cache miss with large product catalogs.

= 2.1.2 =
* Fix: Correct translation loading order to ensure bundled translations are always applied, even when WordPress.org language packs are present.
* Fix: Missing German translations for several recently added strings (POS-only product label, product order settings).
* Maintenance: Updated translation files for de_CH, de_DE, de_AT.

= 2.1.1 =
* New: Drag & drop product ordering in POS settings — products can now be reordered directly via a sortable list under Settings > POS System. The order is saved as WordPress menu_order and applies to both the POS and the WooCommerce store catalog.

= 2.1.0 =
* New: Location-based product filtering on shop pages — products not available at the selected location are visually dimmed, with a filter toggle to hide them entirely.
* New: POS-only products — products can now be marked as visible exclusively in the POS system, hidden from the frontend shop and all customer-facing URLs.
* New: Swiss French (fr_CH) and Swiss Italian (it_CH) translations added.
* Security: IP-based rate limiting added to the reservation form (max. 5 submissions per 60 seconds per IP), supplementing the existing honeypot protection.

= 2.0.24 =
* Improvement: Translations updated for all German locales (de_CH, de_DE, de_AT) — all new strings translated and .pot file regenerated.
* Code: Duplicate transient-delete queries replaced with shared method; SQL query now uses prepare() and esc_like() consistently.
* Code: PHPDoc added to all remaining undocumented public methods.

= 2.0.23 =
* Fix: Statistics page "Today" filter no longer includes orders from the previous day.

= 2.0.22 =
* Fix: Order creation time in the WooCommerce orders list now correctly shows the site's local time. Previously the time was shifted by the UTC offset due to a mismatch between WooCommerce's datetime attribute encoding and the timezone conversion logic.

= 2.0.21 =
* Update: Freemius SDK updated to version 2.13.2.

= 2.0.20 =
* Fix: Order creation time in the orders list now always displays in the WordPress site timezone, regardless of the browser's timezone setting.

= 2.0.19 =
* Fix: 5-cent rounding now applies to the final cart total after coupon discounts, not to the pre-discount subtotal.
* Fix: Statistics page now correctly shows orders for the current day instead of always showing zero.
* Improvement: Order creation time is now displayed below the date in the WooCommerce orders list.

= 2.0.18 =
* Fix: Sound notification settings — Free users no longer see the media library picker, which is a Pro-only feature. Free users see a preview of the default sound instead. The built-in notification sound is now always used for Free installations, regardless of any previously saved empty value.

= 2.0.17 =
* Fix: Duplicate AJAX handler for lbite_pos_get_products removed from the admin class. The admin handler was registered first and took precedence over the POS module handler, causing location-based product filtering to be bypassed entirely.
* Security: Added a honeypot field to the public reservation form to block automated spam submissions.

= 2.0.16 =
* Improvement: Sound Notifications is now a free feature — no Pro subscription required to hear new order alerts in the Order Overview.
* Improvement: Roles & Menus settings — added a tip to assign a location to each Libre Bite Staff user so they only see orders relevant to their location.

= 2.0.15 =
* Fix: Fatal error on every admin page in the free version caused by an unguarded premium-only method registration on the admin_init hook. The backend was completely inaccessible after installing the free version.

= 2.0.14 =
* Fix: Cart total now stays the same for the customer regardless of which tax class is applied (takeaway vs. dine-in). WooCommerce's internal 'unfiltered' tax class lookup was bypassing the rate switch and recalculating a different gross price.
* Fix: Email field in optimized checkout now correctly appears and stays visible after WooCommerce refreshes the payment section.

= 2.0.13 =
* Fix: Product pages no longer show a recalculated price when Multiple Tax Rates is active — the tax class filter now only applies in cart/checkout/AJAX contexts.
* Improvement: Optimized checkout — email field now appears after the payment method selection, not before. Customers only see it when their chosen payment method requires an email.
* Improvement: Optimized checkout — which payment methods require an email address is now configurable in Settings → Checkout (instead of being hardcoded).
* Fix: Location selector — location image is now correctly shown after selecting a location (tiles layout).
* Improvement: Thank-you page — detail boxes are now white with a colored left border instead of gray fill.
* Improvement: Thank-you page — for dine-in orders the pickup box is replaced by a service/table box showing the table name.

= 2.0.12 =
* Improvement: Order dashboard — table badge now shows actual table name (e.g. "Tisch 3") instead of generic "Tisch".
* Improvement: Order dashboard — card footer now shows order creation time alongside order number and customer name.
* Fix: When a table QR code is scanned, the session service type is now explicitly set to "dine_in" so VAT and checkout defaults are correct from the start.
* Fix: Table QR code box moved to the sidebar in the table edit screen for better overview.

= 2.0.11 =
* Fix: Optimized checkout — order type (takeaway / eat here) no longer pre-selected; customer must make an explicit choice. JS and server-side validation added.
* Fix: Optimized checkout — radio buttons now have proper spacing and separator from the location block above.
* Fix: Optimized checkout — table dropdown now fully visible and correctly styled.
* Improvement: Table dropdown in checkout now uses natural number sorting by default (Tisch 1, 2, 10, 11 instead of 1, 10, 11, 2).
* Improvement: New setting in Tables tab: control table sort order (natural or menu order).
* Improvement: "Please select a location and pickup time" replaced with more neutral wording.
* Translations: All 5 locales updated (1399 strings).

= 2.0.10 =
* Fix: Optimized checkout — Order Type selector is now rendered inside the "Location & Pickup Time" box instead of a separate second box below it.
* Improvement: "Swiss VAT Switching" feature renamed to "Multiple Tax Rates" for better clarity and international applicability; tax class descriptions no longer reference Swiss-specific rates.
* Translations: All 5 locales updated.

= 2.0.9 =
* Improvement: Optimized checkout — Order Type selector ("To take away" / "Eat here") is now integrated into the location info box at the top of the form.
* Improvement: Optimized checkout — Table field replaced by a dropdown of configured tables; falls back to text input if no tables are set up for the location.
* Improvement: Pickup time in info box is hidden for dine-in orders (not applicable).
* Improvement: POS settings — "Default Order Type" is now visible when Table Management is active, not only when Swiss VAT Switching is enabled. Added link to Prices & Taxes settings when relevant.
* Translations: All 5 locales updated to 1395 translated strings (0 untranslated).

= 2.0.8 =
* Security: Removed developer override constant that bypassed license verification for premium features.
* Fix: Settings — premium feature toggles can now be saved without erroneously being reset; license enforcement happens exclusively at runtime.

= 2.0.7 =
* Fix: Settings — premium features (e.g. Order Type Selection) can now be saved correctly when using the developer override constant.
* Fix: POS — Table selector is now hidden for Takeaway orders and only appears when Dine-in is selected; automatically resets to "No table" after each order.
* Improvement: POS — Order Type selector (Takeaway / Dine-in) now appears whenever Table Management or Swiss VAT Switching is active, not only when Swiss VAT is enabled.

= 2.0.6 =
* Fix: Statistics — CSV export no longer contains HTML; output buffers are now cleared before headers are sent.
* Fix: Statistics — translation strings for new columns (Top Products, By Quantity, By Revenue, etc.) now correctly loaded in all locales.
* Fix: Optimized checkout — Order Type selector (Takeaway / Dine-in) is now visible; rendered directly in the checkout form with a summary in the info box.

= 2.0.5 =
* Feature: Statistics — extended reporting with top products by quantity and revenue, add-on breakdown with product combos, payment method share bars, and CSV export.
* UI: Table Plan and Reservations pages now show a Beta badge in the page title.
* Roadmap: fr_CH and it_CH translation entries added; Barcode-Scanning removed.

= 2.0.4 =
* Feature: Order Type Selection — customers can now choose Takeaway or Dine-in directly in the checkout form (Pro). When Swiss VAT Switching is active, the selection also controls which tax rate applies. With the Table module enabled, Dine-in reveals an optional table number field.
* Feature: POS — order type indicator (Takeaway / Dine-in) is now shown in the cart box below the total.
* Feature: POS settings — new option to configure the default order type (Takeaway or Dine-in) pre-selected on page load; selection persists across automatic page refreshes via localStorage.
* Fix: GitHub README — logo path corrected.

= 2.0.3 =
* Fix: Swiss VAT — tax class is now explicitly set on the order line item during checkout, ensuring calculate_totals() uses the correct rate (e.g. 2.6%) and the order tax breakdown displays the right rate instead of the original standard rate.
* Fix: Swiss VAT now also applies to product variations (woocommerce_product_variation_get_tax_class hook added).
* Fix: Statistics tile on the overview page now links to the correct URL (/wp-admin/admin.php?page=lbite-statistics).
* Fix: Completed orders loaded via "Load more" now remain visible during automatic dashboard refresh instead of disappearing.
* Feature: Statistics page — added location selector dropdown; admin can filter by location; default period changed from "Today" to "Last 7 Days".
* Feature: Order cards in the Kanban board now show a "Takeaway" badge for non-table orders alongside the existing "Sofort/Vorbestellung" and payment method chips.

= 2.0.2 =
* Fix: Swiss VAT switching now correctly preserves the gross price for the customer; previously, wc_get_price_excluding_tax() bypassed the tax-class filter and stored the net at the base rate, causing a price discrepancy after calculate_totals() applied the target rate. Affects POS orders, frontend checkout, and add-on fee items.

= 2.0.1 =
* Fix: Add-ons now appear as separate line items in WooCommerce orders (POS and frontend); the product price is no longer inflated by the add-on amount.
* Fix: POS orders no longer inherit scheduled pickup times from previous frontend test sessions; the pickup time meta is explicitly cleared on every POS order.
* Fix: Payment method selected in POS is now visible in the Kanban board and in the statistics breakdown.
* Feature: New "Prices & Taxes" settings tab — price rounding and Swiss VAT switching settings moved from the Checkout tab; added a direct link to WooCommerce Tax Settings.

= Older versions =
* For the full changelog of versions before 2.0.0, see the release history: https://github.com/simurech/libre-bite/releases

== Upgrade Notice ==

= 3.5.1 =
Background tasks now only run while the relevant feature (pre-orders, pickup reminders) is switched on, and three checkout endpoints no longer require a security token that could expire under page caching. No action needed either way.

= 3.4.7 =
Uninstalling with data deletion enabled now cleans up considerably more (HPOS order metadata, category schedules, guest notes, stamp card data) than before. If you rely on this option, review it once after updating.

= 3.3.2 =
Security fix: location access restrictions for managers/staff now apply consistently across all order endpoints, not just the REST API and Statistics. Update promptly if you use multi-location access restrictions.

= 3.3.0 =
Settings now save via an earlier hook to fix a "headers already sent" redirect bug, and fields hidden behind a disabled feature no longer reset when you save. If you use the Settings page heavily, worth a quick check after updating.

= 3.2.5 =
Blog posts and the "Downloads"/"Addresses" sections of My Account are no longer hidden automatically. If you relied on that, enable it under Settings → Content & Account.
