= 2.3.9 - 2026-09-08 =
* Added - **A REST API at `easy-invoice/v1`.** The plugin had 83 admin-ajax handlers and no REST surface, and the documentation told integrators to POST at admin-ajax.php with a nonce — which only works from inside a logged-in browser session, ruling out mobile apps, headless front-ends and anything authenticating with an application password. Routes cover listing, reading, creating and trashing invoices, reading quotes, listing clients, and downloading an invoice as a PDF.
* Note - **Every REST route is authenticated and capability-checked**, using the same `ei_*` capabilities as the admin screens, so an EI Viewer gets read access and nothing more and the Team Roles addon keeps working unchanged. There are no public routes. Responses are assembled field by field rather than dumping post meta, specifically so the per-document access key — which acts as a bearer credential for the public payment page — is never exposed; verified that it appears nowhere in a response.
* Added - **Reverse charge and export handling for cross-border invoices.** A German agency invoicing a French business must not charge VAT — the customer accounts for it — and the invoice has to say so. The plugin could previously only apply its single rate or switch tax off entirely, and switching it off leaves no statement on the document, which makes the invoice invalid rather than zero-rated. Enable it under Settings → Tax, add your VAT number and country under Company Information and the customer's on the invoice, and cross-border EU B2B supplies are treated as a reverse charge while supplies outside the EU are zero-rated as exports. The required legal wording appears with the totals on screen, in the PDF and in emails.
* Added - **VAT identifiers for both parties.** Your VAT number and country under Company Information; the customer's on each invoice. Both are required fields of EN 16931, the standard behind Factur-X, XRechnung and Peppol BIS, so this is also the groundwork for structured e-invoicing.
* Added - **EN 16931 tax categories** — standard, zero-rated, exempt, reverse charge, intra-community, export and out-of-scope — using the standard's own codes so they can be written directly into a structured document. Zero-rated, exempt and reverse-charge all show 0.00 in the tax column and mean entirely different things to a tax authority; the plugin can now tell them apart, and knows which ones must carry a stated reason.
* Note - **Existing invoices are unaffected.** Automatic determination is off by default, and even when switched on it resolves to the ordinary rate unless both parties' countries and VAT numbers are known. It can only ever remove tax, never add it, and an explicit category set by you always overrides it. Verified that an existing invoice's total is unchanged before and after.
* Added - **Server-side PDF rendering.** Until now every PDF was made in the visitor's browser: html2canvas screenshotted the page and jsPDF wrapped the bitmap. The result was a picture — no selectable text, no search, no accessibility, and around 180 KB for a one-page invoice. The same invoice now renders on the server at 25 KB with real, selectable text and no embedded image. This is the change the rest of the roadmap depends on: the server never held a document before, which is why nothing could be attached to an email, why scheduled runs could not carry one, and why structured e-invoicing (which needs XML embedded inside a PDF/A-3 file) was impossible.
* Added - **Invoice emails can attach a PDF copy.** Off by default under Settings → Email → General, because attaching a document changes what every customer receives and makes messages much larger than some SMTP relays accept. `easy_invoice_attach_pdf_to_email` filters it. The attachment is written, sent and deleted within the request.
* Added - **PDF paper size setting** — A4, Letter or Legal, defaulting to A4. Verified to produce exactly 595×842pt and 612×792pt respectively.
* Changed - **dompdf now ships with the plugin**, taking the package from 2.3 MB to 6.5 MB. It was previously present in the tree but not registered with Composer, not tracked in version control, and excluded from the build — effectively dead weight. The bundled DejaVu fonts are most of that size and cannot be dropped: the core PDF fonts are WinAnsi-only and cannot render Polish or several French characters, which are exactly the markets where e-invoicing is now mandatory.
* Note - PDF output uses its own template at `templates/pdf/invoice.php`, overridable with the `easy_invoice_pdf_template_path` filter. The on-screen designs could not be reused: they are laid out with flexbox, and dompdf implements CSS 2.1 and ignores it, which turns a two-column header into two stacked rows. The PDF template is table-based for that reason.
* Fixed - **Deleting a client failed with a critical error, whichever option you chose.** Both branches of the delete handler called `$this->log()`, a method that does not exist on that class or any trait it uses, so the request died the moment an administrator confirmed. Neither "Delete Client Only" nor "Delete All" could complete. They now log the way the rest of the plugin does. Verified afterwards through the Clients screen: deleting a client with an invoice and a payment attached reports "Client and all associated documents (2 total) deleted successfully", the count matches what is actually removed, and no orphaned payment rows are left behind.
* Fixed - **Accepting a quote crashed for the customer on any site running the Team Roles addon.** The quote-to-invoice conversion fires `save_post_easy_invoice` itself, and it passed two arguments where WordPress core's `save_post_{post_type}` passes three. Team Roles' audit logger declares all three as required, so the conversion raised an ArgumentCountError and the customer saw "There has been a critical error on this website" — after the invoice had already been created, leaving a stray draft behind. Both dispatch sites now pass the third argument, matching core. Verified by accepting a quote as an anonymous customer through the real page: the quote moves to accepted, the invoice is created with the quote's items and total, and it links back to the quote.
* Added - **`easy_invoice_email_headers` is now applied when an invoice, quote or receipt email is built**, with the email type and the document passed alongside the headers. Easy Invoice Pro's Email Enhancements addon has always registered against this filter; nothing ever applied it, so its per-document-type Reply-To never took effect.
* Fixed - **Corrected the PDF Toolkit description.** It advertised "custom headers and footers" and "color and font controls"; neither is implemented, and neither is offered anywhere in the addon's settings, which expose watermark options only. The handlers for them hang off six `easy_invoice_pdf_*` filters that nothing in either plugin fires, because PDFs are rendered in the browser from the document view rather than by a server-side pipeline. The watermark is real and is now what the addon says it does.
* Security - **The payment-callback endpoint let anyone attach forged cheque details, and a file, to any invoice.** `easy_invoice_payment_callback` is registered for logged-out access and the only thing in front of it was the shared, page-wide payment nonce, which is rendered on every public invoice page — so anyone able to open a single invoice could take one and call this for any id. The id was handed to the gateway without even checking it was an invoice, and the cheque gateway's callback writes: it stores the cheque number, bank name, date and an uploaded image against whatever id it receives, so forged payment records could be attached to any invoice on the site, or meta written onto any post at all. The endpoint now validates the invoice and applies the same access-key, administrator or bound-client check as every other payment path. No JavaScript in either plugin calls it, and PayPal's IPN could never have satisfied its nonce check, so nothing legitimate was relying on the old behaviour.
* Security - **The PDF download nonces were not tied to a document.** `easy_invoice_generate_pdf` and its quote equivalent accepted a nonce created for the action name alone, so a nonce obtained for a document you were allowed to see could be replayed against any other id. The document content stayed protected — the redirect target enforces access and returns a 404 — but the response still disclosed the permalink, and therefore the existence and title, of documents outside the caller's reach. Both nonces are now bound to the specific invoice or quote id.
* Fixed - **The search box inside the multi-select settings fields had no accessible name.** Select2 builds that input itself and gives it neither a label nor an `aria-label`, so a screen reader announced it as an unnamed text field on the email-reminder and other multiselect settings. It now takes the name of the field it belongs to.
* Security - **Every Pro card gateway bypassed the new payment authorisation check entirely.** The check was added this release, but it sat below `apply_filters('easy_invoice_before_process_payment')` — and that filter is not a notification, it is a dispatch point that answers and ends the request. Easy Invoice Pro attaches four handlers to it (Stripe, Authorize.Net, Moneris and Partial Payments), so for those four the access key was never examined: the gate only ever covered the free plugin's own gateways. Authorisation now runs before the filter, where it belongs, and the invoice is validated first so handlers can no longer be dispatched for an id that does not exist. Verified by confirming a Stripe payment request with no key, and one with a forged key, are both refused.
* Fixed - **Client card payments would have broken on sites running an older Easy Invoice Pro.** The payment endpoint now authorises on the per-invoice access key, and Pro only began sending that key in 2.2.7. The two plugins update through different channels — this plugin from WordPress.org, Pro from the licence server — so a site running a newer free against an older Pro is the normal state for a while after release, not an edge case. On Stripe the consequence was the worst kind: the script confirms the charge with Stripe first and only then records it here, so a refusal would have taken the customer's money and left the invoice unpaid. Payments from an older Pro are now accepted through the authorisation that shipped in 2.3.8, and only then: an older Pro must be installed, no key may be presented (a wrong key is a forgery and is still refused), and the gateway must be one Pro provides. The allowance disappears on its own when Pro is updated, a warning appears while it is in use, and `easy_invoice_allow_legacy_pro_payment_fallback` turns it off for anyone who would rather the payment fail.
* Fixed - **Addon screens that were not an addon's main page showed raw WordPress notices, clipped in half.** Notice suppression was built from each addon's registered settings URL, which is only its primary page — so a second screen, such as Accounting Sync's "Sync Log", was left out. Those notices print before this plugin's markup, outside the app shell, so the fixed sidebar covered the first words of every line and pushed the real heading far down the page: it looked broken rather than styled. Suppression now matches on the page slug prefix, covering every Easy Invoice screen including any added later, and the same rule the admin stylesheet already used. Any notice that does still render — WordPress core prints some outside that hook — is now indented clear of the sidebar instead of being cut off.
* Fixed - **The Bulk Operations addon had no link to its own Export screen, and opening it painted the Dashboard first.** The addon's registry entry left its settings URL empty. The admin dispatcher uses that list to recognise addon-owned pages, so the export slug fell through to the Dashboard and the export form rendered underneath it — two pages stacked, the exact case the dispatcher's fallback warns about. The entry now points at the Export screen, which also gives the Addons card a working link into it.
* Fixed - **Choosing an invoice or quote design on a document you had not saved yet crashed.** The template loader passed a null document and a null currency formatter into the design templates, which call methods on both without checking — so the request died mid-render and the picker returned a broken response instead of a preview. Both are now given an empty document and a matching formatter, so an unsaved invoice or quote previews as a blank version of the chosen design. All ten invoice designs and all six quote designs were exercised against both a new and an existing document.
* Fixed - Saving settings raised an "Undefined array key" warning before its nonce check could run, on any request that arrived without the nonce field.
* Added - **A one-time notice after updating, explaining the access-key change.** WordPress updates a plugin by replacing files and does not run the activation hook, so without this the first sign a site owner would have that older invoice links stopped working is a customer telling them. The notice appears on the Dashboard and Plugins screens for sites that already have invoices or quotes, explains that previously-sent links need re-sending, and dismisses permanently. Fresh installs never see it, since they have no old links to break.
* Fixed - **Two admin hooks pointed at methods that do not exist**, in `AdminController` and `InvoiceAdmin`. Neither class is ever instantiated, so nothing fired them, but they are the same latent-fatal pattern found and removed elsewhere in this release and are documented as dead rather than left to mislead.
* Security - **Two more unauthenticated payment endpoints did not check who was asking.** `easy_invoice_get_payment_instructions` guarded guests with a "published invoices only" test that could never fail, since every invoice is stored as published — so any caller with the page's shared nonce could read the rendered payment instructions for an arbitrary invoice id. `easy_invoice_process_payment` had no per-invoice check at all and would start a payment against any id, returning its amount and gateway detail. Both now require the same per-document access key, administrator, or bound-client check as the rest of the plugin, and a key issued for one invoice cannot be used against another.
* Fixed - **The invoice page did not pass its access key to the payment scripts.** `templates/invoices/single.php` builds its own HTML document and defines `easy_invoice_vars` inline, which overwrote the copy `PaymentController` localises — so the key from the emailed link never reached the payment requests. Left unfixed alongside the authorisation change above, clients following a legitimate link would have been able to open their invoice but not pay it. The key is now included in that object and forwarded by the online-payment and payment-instruction requests, matching what the manual-payment script already did.
* Security - **Invoices and quotes were readable by anyone with the URL, including drafts. All sites should update.** Both post types are stored with `post_status` `publish` regardless of their workflow status (the workflow status lives in post meta), and both are registered public and publicly queryable — but nothing checked authorisation before rendering. Any unauthenticated visitor who guessed or was forwarded a link, or who walked `?p=<id>`, could read the full document: customer name, email, address, invoice number, line items, prices, notes and totals. Access is now checked before any output, on every front-end entry point — permalink, `?p=<id>`, feeds, embeds and the PDF download path — using the same rules the rest of the plugin already applied to payment and accept/decline: a valid per-document access key, an administrator, or the signed-in client the document is bound to. Unauthorised requests get a plain 404 so the response does not reveal whether an invoice number exists.
* Security - **Invoices and quotes could be enumerated even without opening them.** Site search, `?post_type=easy_invoice` and the type feeds returned archive listings of document titles and permalinks to anonymous visitors. Both post types are now excluded from search, and listing-style front-end queries for them return nothing.
* Security - **Two public AJAX endpoints did not really check authorisation.** `easy_invoice_download_invoice_pdf` and the public invoice/quote email resends gated non-administrators with a "published only" repository lookup, which was no protection at all because every document is stored as published — so the lookup returned the same record for any caller. Both endpoints are registered for logged-out access, so a caller holding a nonce could pull PDF data for an arbitrary invoice, or make the site email one out. They now use the same access check as the rest of the plugin.
* Note - **Invoice and quote links emailed before per-document access keys existed do not carry one**, so their recipients will now see a 404 until you resend the document — resending issues a fresh link that works. Administrators are unaffected, and links sent by recent versions already carry a key. A site that needs the previous open-by-URL behaviour can restore it with the `easy_invoice_require_document_authorisation` filter, but doing so re-exposes customer data to anyone holding a URL.
* Fixed - **The admin was unusable on phones and small tablets.** The sidebar was a fixed 256px column with no responsive rules and the content area reserved 256px of padding unconditionally, so on a 390px screen roughly 134px was left for the actual page — stat cards became unreadable slivers, tables collapsed to a column of checkboxes, and 17 of 25 screens scrolled sideways. The sidebar is now an off-canvas drawer below 1024px, with a backdrop, Escape-to-close and close-on-navigation; from 1024px up nothing changes. The previous mobile menu button could never have worked: it bound to the first element in the page matching `button[aria-expanded="false"]`, toggled a `hidden` class the sidebar never had, and only appeared below 640px.
* Fixed - **The Dashboard's "Edit" and "View" links were broken.** Both pointed at `page=easy-invoice-invoices`, which is not a registered admin page, so every Recent Invoices action returned a permissions error. Edit now opens the invoice builder and View opens the public invoice, matching the invoice list. The same dead page slug also broke the redirect after verifying a manual payment.
* Fixed - **Row actions could not be reached by keyboard or on touch devices.** View / Edit / Draft / Trash / Send Email / Download PDF / Duplicate were revealed only on mouse hover, and because they were hidden with `visibility: hidden` they were also skipped by tab navigation entirely. They now appear on keyboard focus, and are always visible on touch devices and narrow screens.
* Fixed - **New invoices could not be saved on the first attempt.** Issue Date and Due Date are required but shipped with no default, so a new invoice always failed validation — while the live preview beside the form already displayed dates, making the error look wrong. Issue Date now defaults to today and Due Date to the payment term configured in Settings (30 days by default). Quote forms already worked this way.
* Fixed - The Quotes list scrolled the whole page sideways. Its table card was missing the `overflow-hidden` the invoice list has, so a table wider than the card leaked out through every parent.
* Fixed - "Add New Client" was rendered twice in the invoice builder under the same element id. Every script bound to the first copy — the older markup, missing the dialog role and labelling the newer copy had — so the accessible version was dead markup.
* Fixed - Bulk-action menus, select-all and per-row checkboxes, and the invoice/quote template pickers had no accessible names, so screen readers announced them as unlabelled controls.
* Fixed - Empty states on the invoice list were hardcoded English and could not be translated. The payments list offered only "No payments found." with no way forward; it now links to Add New Payment.
* Improved - "Total Revenue" on the dashboard showed the sentence "No revenue recorded" where every neighbouring tile shows a number; it now shows a formatted zero. The two client tiles also rendered at roughly double the width of the other four and now share the same grid.
* Improved - The "Flush Rewrite Rules" maintenance button no longer sits beside the primary action on the invoice and quote lists. It is a troubleshooting tool, and is now shown only when `WP_DEBUG` is on or a site opts in via the `easy_invoice_show_maintenance_tools` filter.
* Fixed - The License screen restyled `.easy-invoice-admin` — a global class used by every Easy Invoice page — from its own page template, which pushed that screen 49px wider than the viewport on phones.
* Fixed - **All third-party CDN assets are now bundled with the plugin.** jsPDF and html2canvas were loaded from cdnjs and Chart.js from jsDelivr, across eight places — including a runtime `<script>` injector inside `document-pdf.js` and a hardcoded tag on the reports screen. This broke the WordPress.org rule that all plugin assets ship inside the plugin, and made PDF generation and reporting depend on a third-party host staying up. jsPDF 2.5.1 and html2canvas 1.4.1 now ship in `assets/js/vendors/`; Chart.js was already bundled locally and the CDN copies were simply redundant.
* Fixed - **Removed an admin endpoint that fatally errored on use.** `admin_post_fix_easy_invoice_quote_slugs` was registered against a handler method that does not exist anywhere in the plugin.
* Fixed - **Duplicate AJAX registrations resolved.** `easy_invoice_delete_client` was registered by both `EasyInvoiceAjax` and `ClientController`, and `easy_invoice_create_new_invoice` was registered twice inside `InvoiceController`. In each case WordPress held two handlers for one action and which implementation answered depended on load order — the same class of bug already tombstoned for `easy_invoice_search_clients`. The stricter handler now owns each action: the client-delete path that checks capabilities, refuses administrator accounts, and cleans up related documents.
* Fixed - **Client deletion queried two different meta keys** for the same thing — the "this will delete N payments" count and the deletion itself disagreed. Unified. Note that payment cleanup was, and remains, inert: payments carry no client ID of their own and are linked only through their invoice. Making deletion actually remove payment records will destroy data it currently leaves alone, so it is deliberately left for a change of its own.
* Performance - **Stopped rebuilding the rewrite rules on every request.** Post-type registration ran an unconditional `flush_rewrite_rules(true)` on every `init`, regenerating the entire rule set and rewriting the `rewrite_rules` option on every page load — while a throttled flush sat directly above it doing the job properly. Activation still flushes explicitly.
* Fixed - **Corrected the Email Enhancements description.** It advertised "PDF attached" and "CC / BCC"; neither is implemented — no email in either plugin passes an attachment, and the only BCC is the free "BCC admin" toggle. PDF attachment is blocked until PDFs are generated server-side rather than in the browser. The addon's real features (branded HTML email templates and per-template Reply-To) are described accurately now, in the plugin, both readmes, and the documentation.
* Internal - The build no longer ships the Tailwind purge harness in `tools/`, or the unused dompdf / masterminds / sabberworm Composer packages (~11 MB, referenced by zero lines of code).

= 2.3.8 - 2026-08-21 =
* Compatibility - **Tested and confirmed compatible with WordPress 7.1.** "Tested up to" bumped from 7.0. The release was audited against the 7.1 codebase rather than smoke-tested: every WordPress function the plugin calls was resolved against the 7.1 symbol table (no removed or renamed API is used), the plugin's global function, class and constant names were diffed against the 92 functions and 5 classes 7.1 introduces (no redeclaration collisions), and the full plugin tree was scanned with PHPCompatibility for PHP 7.4 through 8.4 (zero issues).
* Compatibility - **jQuery UI 1.14.2** ships in WordPress 7.1 (up from 1.13.3). The payment-gateway drag-to-reorder list on Settings -> Payment uses `.sortable()` and `.disableSelection()`; both remain available because core enables `jQuery.uiBackCompat` and still bundles the disable-selection module. The four APIs 1.14 removed (`$.fn._form`, `$.ui.ie`, `$.ui.safeActiveElement`, `$.ui.safeBlur`) are not used anywhere in the plugin.
* Compatibility - **The enforced iframed post editor in 7.1 does not affect Easy Invoice.** Invoices and quotes are edited through the plugin's own admin screens; their post types register with `show_ui => false` and the one UI-visible post type does not declare `editor` support, so no plugin JavaScript or CSS reaches across the editor document boundary.
* Compatibility - Admin styling verified against 7.1 markup: the `#adminmenu`, `#adminmenuwrap`, `#adminmenuback`, `#wpcontent`, `#wpbody-content` and `#wpfooter` containers the plugin restyles are all still emitted by `wp-admin/admin-header.php` and `menu-header.php` in 7.1, and the persistent admin toolbar change touches `#wpadminbar`, which the plugin does not style.
* Compatibility - The REST and media changes in 7.1 (image dimension validation on the sideload endpoint, size-aware encoding quality in attachment responses) are not applicable: the plugin registers no REST routes and calls no attachment or sideload APIs.
* Fixed - **Payment-gateway drag-to-reorder relied on incidental script ordering.** The `easy-invoice-settings` script handle is registered in two different places, and WordPress keeps whichever registration runs first while silently discarding the other's dependency array. The registration that wins did not list `jquery-ui-sortable`, so `settings.js` was printed ahead of jQuery UI Sortable and only worked because its code runs inside a DOM-ready callback. The jQuery UI handles are now declared explicitly on that registration, so `wp_scripts` resolves the load order instead of it falling out of enqueue sequence - worth tightening now that 7.1 ships a new jQuery UI build.

= 2.2.1 - 2026-05-15 =
* Fixed - PDF download quality: crisp text and sharp table borders.
  - html2canvas scale 1.5x → 2x (retina-grade).
  - JPEG @ 0.92 → lossless PNG (no more colour-fringe around glyphs).
  - Locked capture width so responsive CSS doesn't shrink the layout mid-capture.
  - jsPDF FlateDecode compression + 'SLOW' addImage flag for better embedded image quality.
* Internal - Cache buster bumped so browsers pick up the new document-pdf.js immediately.

= 2.2.0 - 2026-05-13 =
* Added - "Export Selected (Pro)" option in the Bulk Actions dropdown on both Invoice and Quote listings; picking it without Pro opens the Upgrade-to-Pro dialog.
* Added - "Unlock more payment gateways" teaser block on Settings → Payment when Pro is inactive (Stripe, Square, Authorize.Net, Mollie, Paystack, Moneris, Bank Transfer, Cheque, Cash).
* Improved - Pro-gated submit interceptors moved to native capture-phase listeners so they always run before the listing template's inline jQuery submit handlers.
* Improved - JS cache buster bumped so users always pick up the new bulk-action teaser script on first page load after the upgrade.
* Fixed - Quote listing search form posted to a wrong page slug (`easy-invoice-quotes-all`); corrected to `easy-quote-all`.
* Fixed - Default Invoice / Quote email bodies no longer ship the literal `[easy_(invoice|quote)_url ...]` shortcode-reference line that was emailed to clients as raw text. One-time migration strips it from saved options.

= 2.1.22 - 2026-05-13 =
* Added - Filter by Client dropdown on All Invoices and All Quotes listings. Filter persists across view tabs, search, pagination, and status filters.
* Improved - Listing controllers now pass the available clients list and selected client_id to the template, providing a clean extension point for Pro modules.

= 2.1.21 - 2026-05-11 =
* Added - "Documentation" link in the Easy Invoice plugin sidebar (under Join Community) that opens the new official documentation site (https://easy-invoice.matrixaddons.com/docs/).
* Updated - All in-plugin documentation references and readme.txt links now point to the new dedicated docs site.

= 2.1.20 - 2026-04-29 =
* Security: Manual payment proof uploads validated with WordPress file type APIs; safe stored extension only.
* Security: Quote accept/decline use per-quote nonces and published-quote access for non-admins.
* Security: Payment instructions for guests limited to published invoices.
* Security: Invoice/quote send-email AJAX consolidated with published checks for guests.

= 2.1.19 - 2026-04-27 =
* Minor UI issue fixed
* Minor bug fixed on both plugins

= 2.1.18 - 2026-04-21 =
* Maintenance - Version bump release

= 2.1.17 - 2026-04-17 =
* Fixed - PDF download for long invoice/quote content: corrected JPEG image data used with PNG format (blank pages); respect browser canvas size limits; capture very tall HTML in vertical slices and paginate onto A4.
* Fixed - PDF page breaks respect table row and summary block edges so items are not split across pages (row-aware canvas crops).

= 2.0 - 2024-08-14 =
* NEW - Complete plugin rewrite with modern architecture and improved codebase
* NEW - Enhanced migration system for seamless updates from previous versions
* NEW - Improved user interface with Tailwind CSS and modern design
* NEW - Better invoice and quote templates with professional layouts
* NEW - Enhanced payment gateway integration with better error handling
* NEW - Improved email templates and notifications system
* NEW - Better client management system with enhanced data handling
* NEW - Advanced settings and customization options
* NEW - Multi-language support improvements and translation enhancements
* NEW - Version badges in sidebar header showing Free and Pro versions
* NEW - Improved responsive design for mobile and tablet devices
* FIXED - Division by zero error in invoice calculations
* FIXED - JavaScript errors in invoice and quote builders
* FIXED - Duplicate ID issues in quote forms
* FIXED - Resize logic removed for better performance and stability
* FIXED - Various bug fixes and performance improvements
* FIXED - Security enhancements and code sanitization
* FIXED - WordPress 6.4 compatibility issues
* FIXED - Improved error handling and user feedback

= 1.1.3 - 2024-10-31 =
* Fixed - Email issue fixed
* Fixed - Version compatibility

== Upgrade Notice ==

= 2.0.0 =
This is a major update with a new architecture and migration system. If you are upgrading from a version older than 2.0, please run the migration when prompted to move your old invoices, quotes, and settings.


= 1.1.2 - 2024-02-19 =
* Fixed - Readme update

= 1.1.1 - 2024-02-17 =
* Fixed - Astra Compatibility fixed
* Added - Minor fixes

= 1.1 - 2024-01-19 =
* Added - Quotation feature
* Added - Report features

= 1.0.9 - 2023-12-17 =
* Fixed - WP Compatibility fixed

= 1.0.8 - 2023-09-17 =
* Fixed - WP Compatibility fixed
* Added - Added Terms and conditions option on single invoice

= 1.0.7 - 2023-09-13 =
* Fixed - WP Compatibility fixed
* Fixed - Javascript issue on backend

= 1.0.6 - 2023-04-29 =
* Fixed - 6.2 compatibility test

= 1.0.5 - 2023-01-08 =
* Fixed - Email issue fixed

= 1.0.4 - 2022-10-29 =
* Fixed - float issue resolved

= 1.0.3 - 2022-10-21 =
* Fixed - Minor issue fixed
* Added - Addon updater and license manager
