*** Simple Connection for Chronofresh Changelog ***

2026-10-21 - version 1.4.4
* **Added**: checkout titles are plain sentences (“Chilled delivery before 1 PM”). The shipping-zone list keeps the Chronopost name and the code (`ChronoFresh · Chrono Fresh 13 (2R)`). A method whose title is still the old name picks up the new sentence.
* **Added**: the order label box shows the parcels (offer, code, weight, pickup point) and blocks generation when the shipper phone, the store address, the pickup point or the offer is missing. Test mode stays a warning, so a sandbox label can still be created. The button asks for confirmation.
* **Added**: Getting started opens with a checklist (SOAP, store address, shipper phone, mode) and three shop setups: chilled food in France, mixed temperatures in France, dry parcels to Europe. Account number and password are hidden in Test mode. A saved password is not shown again; leave the field blank to keep it.
* **Added**: the product temperature field is Ambient, Chilled or Frozen. Chronopost codes stay in the help text. The use-by field appears only for chilled and frozen products. A product saved as “no temperature” still ships as ambient.
* **Added**: Chronopost errors 30, 33 and 35 name the next step (password, contract code, destination). The orders list has a ChronoFresh column (label ready, to generate, PDF missing), a view “To ship without a label”, and a bulk action that opens the PDFs of the selection for printing.
* **Added**: pickup points are buttons, with a keyboard, a visible chosen point and a “Change pickup point” link. An incomplete address and a Chronopost timeout each have their own message.
* **Added**: the customer sees parcel events on the thank-you page and on My Account → Order. The tracking email uses the store’s WooCommerce email template (WooCommerce → Settings → Emails → ChronoFresh tracking).
* **Added**: four offers — Chrono Fresh 18 (`5Z`), Chrono Ambient 18 (`5S`), Chrono Freeze 18 (`6A`), all France, next day before 6 PM, and Chrono Classic (`44`), dry parcels to Europe in 1 to 3 days. Enable them per shipping zone; Classic serves the countries of the zone it is added to, is hidden when the cart holds a chilled or frozen product, and sends the real destination country (with the goods value for destinations outside the EU).
* **Changed**: the label now uses the offer the customer chose and paid for. Orders that mix temperatures are completed with the offer of the same family (13 h with 13 h, 18 h with 18 h); the standard Relais 86 and the 18 h offers no longer ship as another code. An order that no offer can carry is refused before any label is created. Orders with another carrier's method keep the old temperature-based choice.
* **Changed**: every offer now lives in one table (`SCCFCW_ChronoFresh_Methods`, filter `sccfcw_shipping_methods`): code, temperature, delivery mode, use-by date, countries. Filter `sccfcw_soap_request` adjusts the request before it is sent.
* **Improved**: pickup point searches are cached for an hour (filter `sccfcw_relay_cache_ttl`) and time out after 10 seconds instead of blocking checkout when Chronopost is slow. The unused `sccfcw_available_relays_*` option is no longer written.
* **Fixed**: a pickup point is now checked against Chronopost's list for the delivery address when the order is placed, and a point chosen for one postcode no longer follows the customer to another address. If Chronopost cannot be reached the point is accepted.
* **Fixed**: labels are stored in the order's own meta, so they are found with High-Performance Order Storage without compatibility mode (labels written by earlier versions are adopted on first read). The ChronoFresh Labels box is now a normal meta box on the HPOS order screen; the script that injected it is gone.
* **Fixed**: Ask did not refuse when the Connector Approval matrix existed but did not list ChronoFresh, so prompts could reach any active connector. It now refuses until a connector is checked for ChronoFresh (filter `sccfcw_ai_unpinned_when_not_listed` restores the old behaviour).
* **Fixed**: the tracking email is plain text but its text was HTML-escaped, which showed `&#039;` for apostrophes.
* **Added**: `uninstall.php`. Deleting the plugin always removes the API password, logs and caches; a new setting "Delete all plugin data when the plugin is deleted" also removes the other settings, label PDFs and the pickup point and label data on orders.
* **Removed**: unused code for the legacy pickup point field and the cart shipping calculator.

2026-10-20 - version 1.4.3
* **Security fix**: `scc-soap-request-*.xml` / `scc-soap-response-*.xml` were written to the public uploads folder on every label generation, with predictable names, the Chronopost API password and customer contact details. They are now written only in Debug mode, password masked and PDF removed; the update deletes all existing ones.
* **Security fix**: labels, logs and debug files live in a folder closed with `.htaccess` + `index.html`, with unguessable names (random suffix for PDFs, per-site suffix for logs). PDFs are served by `admin-post.php?action=sccfcw_download_label` (`manage_woocommerce`, per-order nonce); the server path is no longer sent to the browser. A one-time pass (`sccfcw_storage_version`) renames existing PDFs and logs; stored label paths still resolve.
* **Weight fix**: product weights go through `wc_get_weight( …, 'kg' )`. Shops in grams no longer get one parcel per order line. Same conversion for the cart weight sent to the pickup point search.
* **Weight fix**: the SOAP `weight` now matches the parcel weight used for splitting, Mix and Match children included.
* **Parcel splitting**: unit by unit instead of line by line (30 × 1 kg, 20 kg limit → 20 kg + 10 kg). A single unit above the limit ships alone.
* **Duplicate labels**: each label is saved on the order right after Chronopost returns it; parcels with an active label are skipped (`labels_exist` error when none is left); "Regenerate labels" becomes "Generate missing labels"; bulk generation reports skipped orders and counts labels, not orders.
* **Relay retry**: no second `shippingMultiParcelV4` call once Chronopost returned errorCode 0. A parcel accepted without a usable PDF is saved with `pdf_missing` and shown on the order so it can be cancelled.
* **Tracking email**: sent once per parcel (`emailed` flag on each label), only after a generation that completes; auto status follows the same rule.
* **Row action**: "Generate label" from the orders list redirects with `get_edit_order_url()` and shows a success / error notice.
* **Logs**: per-request INFO lines moved to DEBUG; no raw `$_POST` or customer email in logs; daily cleanup cron (`sccfcw_daily_cleanup`, 14 days, filter `sccfcw_log_retention_days`); CSV export checks `manage_woocommerce` and escapes formula cells. Unused `scc-debug.log` writer removed.
* **Design**: ChronoFresh Labels box (classic and HPOS fallback) on native admin styles — inline notices, list rows, muted cancelled labels; admin CSS now loads on order screens; "Parcel %d" translatable.
* **Docs**: readme FAQ and both guides: log location, private label storage, why an order has several labels, generating missing labels.

2026-09-02 - version 1.4.2
* **Privacy / security fix**: the Ask feature called `wp_ai_client_prompt()` directly, without reading WordPress's Connector Approval matrix or pinning a provider — a prompt (order data, pickup point, tracking) could reach any active AI connector, not just the one checked for ChronoFresh under Settings → Connectors → Approvals. The plugin now reads the approval matrix (via the Approvals_Store class or the `wpai_connector_approvals` option) and calls `using_provider()` with a connector actually approved for ChronoFresh. If none is checked, Ask now returns a clear "No connector is checked for ChronoFresh" error instead of silently using whatever connector the client defaults to. No change when the approval matrix is not in use at all.
* **Bug fix**: the `relay_5Q` and `relay_6S` health-check ids were compared against `sanitize_key()` output, which lowercases them, so both the "Run checks" panel and the Ask ability's targeted checks never matched and silently fell through to "Unknown diagnostic." / ran every check instead of the one requested. Check ids are now lowercase end to end (`relay_5q`, `relay_6s`).

2026-08-28 - version 1.4.0
* **Ask (read only)**: optional field under Connection health check and at the bottom of the order ChronoFresh Labels box. A sentence reads health diagnostics, the saved pickup point, or tracking. It never creates or cancels a label.
* **Abilities**: `chronofresh/get-connection-health`, `chronofresh/get-pickup-point`, `chronofresh/get-tracking` (`manage_woocommerce`). WordPress 7 AI plugin + a connector; Settings → Connectors installs the AI plugin from that screen.
* **Docs**: Ask vs Run checks / Generate labels / Track in the bilingual guides and readme FAQ.

2026-08-26 - version 1.3.3
* **Mix and Match**: child items in a Mix and Match Products container are packed with the container (one label for the assortment, not one per child). Parcel weight includes the children. The "ships as Ambient" notice lists the container, not each child.
* **Chained Products**: StoreApps Chained Products still cannot be auto-grouped (linked products are independent order lines) — set a weight on each chained product so parcel splitting stays accurate.
* **Architecture**: generic `sccfcw_order_item_parent_id` filter in core; Mix and Match detection lives in a compat module loaded only when that plugin is active.

2026-08-26 - version 1.3.2
* **Display fix**: the pickup point block was missing on the order confirmation page when the theme overrides `order-details-customer.php` without the `woocommerce_order_details_after_customer_details` hook. Now also hooked on `woocommerce_order_details_after_order_table` with a per-order guard so unmodified themes never print it twice. Emails and admin display unchanged.
* **Persistence fix**: a point selected on the cart page looked deselected at checkout (and after each `updated_checkout` refresh) because the widget never restored the session selection visually. The widget now re-selects the saved point (list highlight, red map marker, opening hours) when it is still available for the current address; the hidden field and server-side session were already correct, so this is visual/UX only.
* **Label button fix**: the ChronoFresh Labels box (and the "Generate label" row action) only appeared when a product carried a non-empty `_temperature_type` meta — products never saved from the Shipping tab hid the box, while "No temperature" showed it, and both generate identical Ambient labels. The box now appears on any order with a ChronoFresh shipping method OR a product with a temperature type, and lists products that will default to Ambient.
* **Docs**: FAQ entries on the Labels box visibility and the Ambient default; troubleshooting rows in both guides.

2026-08-26 - version 1.3.1
* **Critical fix**: the pickup point chosen at checkout was never saved on the order (meta written before the order had an ID). Now written on the order object (pre-save safe, HPOS-safe), with Blocks/Store API checkout support and validation.
* **Safety fix**: removed the silent "nearest relay" fallback at label generation — a missing point now blocks the label with a clear error instead of shipping to a relay the customer did not choose.
* **Visibility**: chosen pickup point (name, address, relay ID) shown on the admin order screen, customer order pages, and emails. Pre-1.3.1 relay orders without a saved point show an explicit warning.
* **Fix**: relay postcode/city saved and used on the label; internal `chronofresh_code` meta hidden from customer-facing output.

2026-08-25 - version 1.3.0
* **Test / Production mode**: explicit setting. Test mode uses the public Chronopost sandbox account and shows a persistent wp-admin banner — sandbox labels are never actually shipped.
* **Fix**: sandbox credentials are no longer silent defaults. Unconfigured installs now run in visible Test mode; in Production mode, missing credentials block label generation with a clear error instead of silently using the sandbox.
* **Connection health check**: replaces the single "Test API connection" button. Per-service live status: SOAP extension, server reachability, credentials, and real contract checks for pickup point codes 86 / 5Q / 6S with Chronopost's own error messages. The label service is not simulated — the panel says so.
* **Compat**: Tested up to WordPress 7.1.
* **Docs**: readme FAQ, bilingual guides and the built-in Getting started tab rewritten for the new mode and health check.
* **Admin CSS**: native WordPress admin styles on WooCommerce → ChronoFresh (settings, guide, health check panel). No shipping method or rate changes.

2026-07-24 - version 1.2.1
* **i18n**: All plugin UI source strings are now in English (WordPress.org / GlotPress requirement).
* **i18n**: French UI is provided via translation (fr_FR / translate.wordpress.org), not hardcoded in PHP.

2026-07-22 - version 1.2.0
* **Fresh Pickup Points (6S)**: Added the new "Chrono Fresh Relais 13H" shipping method — fresh delivery (0°C – 8°C) to pickup points, offered by Chronofresh since the beginning of 2026.
* **Checkout Integration**: The interactive pickup point map, opening hours and point selection fully support the new fresh pickup point service.
* **Label Generation**: Fresh products are now mapped to product code 6S when a pickup point is selected, with the mandatory DLC/expiration date.
* **Documentation**: Getting Started guide updated with the 6S product code.
* **Documentation**: New bilingual user guide (docs/USER-GUIDE.md + docs/MODE-DEMPLOI.md) covering setup, product codes, daily workflow and troubleshooting.

2026-05-27 - version 1.1.0
* Released on May 27, 2026:
* Added: Live parcel tracking via trackSkybillV2 (Chronopost TrackingService) directly in the order admin metabox.
* Added: Label cancellation via cancelListSkybill — cancel any label from the order page.
* Added: Bulk label generation from WooCommerce orders list.
* Added: Automatic order status change after label generation (configurable).
* Added: Per-product DLC (days until expiration) field — required by ChronoFresh for fresh/freeze shipments.
* Added: Global default DLC setting under WooCommerce → ChronoFresh.
* Added: Built-in Getting Started guide tab with step-by-step onboarding.
* Fixed: Compliance with ChronoFresh requirements — expirationDate now respects per-product or global DLC setting.
* Updated: Tested up to WordPress 7.0.

2026-05-08 - version 1.0.4
* **Advanced Map Integration**: Added an interactive Leaflet map for seamless and visual pickup point selection at checkout.
* **Smart UI Interactions**: Implemented automatic map centering and visual markers highlighting upon point selection.
* **Checkout Stability**: Resolved critical fragment refresh issues occurring with Stripe and high-performance payment gateways.
* **Race Condition Fix**: Eliminated AJAX timing conflicts to ensure pickup point data is always saved before order placement.
* **Performance Optimization**: Massive code refactoring and removal of legacy templates/unused assets for a lighter footprint.
* **Enhanced Security**: Reinforced nonce verification and strict input sanitization across all AJAX endpoints.
* **Dependency Alerts**: Added clear admin notices to detect and report missing PHP extensions (SOAP) immediately.

2025-08-25 - version 1.0.3
* **Logic Fix**: Added explicit "Ambient" temperature fallback when no specific shipping class is defined.
* **Stability**: Prevented unrecognized states for products linked via Expedition Class, ensuring smoother label generation.

2025-08-22 - version 1.0.2
* **Multi-Temperature Support**: Enabled mixed orders (Ambient, Fresh, Freeze) within the same checkout session.
* **Extended Compatibility**: Added support for custom shipping methods and third-party plugins like alg_wc_shipping.
* **Error Handling**: Implemented safe null-product handling to prevent fatal errors during label generation for deleted items.
* **Service Mapping**: Refined label logic to use product temperature types for accurate Chronopost service codes (5M, 5Q, 2R, 2S).
* **Logging**: Improved debug logs for parcel splitting and skipped items for better merchant troubleshooting.

2025-08-09 - version 1.0.1
* **Security Fix**: Critical update for nonce verification to secure pickup point API calls.
* **Bug Fix**: Resolved a parsing issue within the pickup search response.

2025-08-01 - version 1.0.0
* **Initial Release**: Official launch featuring core Chronofresh shipping integration and pickup point support.
