====== Product Add-ons ====== Optional linked products offered **per product**. On a product page the customer can tick one or more add-ons (checkbox + quantity); each is added to the cart as its **own line item**, inheriting the parent's hub and booking dates — no re-entry of dates required. * **Module:** ''product-addons/product-addons.php'' * **Status:** Done, should work * **Stock impact:** none to existing code — add-ons flow through the standard per-item stock/reservation/deduction paths, same as other proucts ===== How it works ===== ==== For the shop manager ==== - Edit a **product**. In the **Addons** box, pick the products to offer as add-ons (field ''addon_products''). - Each add-on product **must** be a plain WooCommerce product with a recipe (''recette_composants'') — **not** a PluginHive-bookable product. Its per-hub stock comes from the recipe, like any product. {{:mobil:internal:guide:capture_d_ecran_2026-06-18_a_11.00.18.png?400|}} ==== For the customer ==== - On the product page, under the add-to-cart area, an **add-ons** section lists each configured add-on with its price. - Add-ons are **greyed out** until a hub with stock is selected. Availability is computed per hub and is reservation-aware. - Ticking an add-on reveals a **quantity** input, capped at the quantity available at the chosen hub. - On add-to-cart, every ticked add-on is added as its **own cart line**, carrying the parent's hub. The parent's booking dates are copied onto the add-on at checkout. {{:mobil:internal:guide:capture_d_ecran_2026-06-18_a_11.02.00.png?400|}} ===== Data flow (developement) ===== Mirrors the existing ''hub_id'' propagation chain. - Edit product ACF ''addon_products'' - → Product page UI builds a per-hub availability map; JS greys out hubs with no stock - → On the parent's ''woocommerce_add_to_cart'', read ''$_POST['mobil_addons']'' and add each ticked add-on as its own line with ''hub_id'' + parent link in ''cart_item_data'' - → ''reserve_components_on_add_to_cart'' reserves the add-on's composants //(existing system)// - → Cart display via ''woocommerce_get_item_data'' ("Add-on for: …") - → Checkout: ''hub_id'' copied to the order item //(existing)//; parent booking dates copied onto the add-on - → ''decrementer_stock_avec_composants_auto'' deducts stock per item //(existing)// ===== Stock safety ===== The feature was designed to **not touch** any stock code. Add-ons are ordinary separate line items, so every existing hook treats them like any product. ^ Check ^ Result ^ | Stock / reservation / deduction files modified | **none** | | Add-on reservation | generic ''reserve_components_on_add_to_cart'' (separate line + ''hub_id'') | | Checkout deduction | generic per-item loop ''decrementer_stock_avec_composants_auto'' | | Legacy ''selected_addons'' meta | dead stub, never written → no double-deduction | | Quantity (parent qty overriding add-on qty) | fixed via ''mobil_requested_qty'' filter (priority 99) | | Backup before changes | ''backup-fulltheme-20260617-185451'' | | ''php -l'' | no syntax errors | ===== Caveats ===== * Add-on products **must** be plain products with ''recette_composants''. An add-on **without** a recipe is sold with **no stock control** (reservation/deduction skip it). * Add-ons are **independent** of the parent in the cart: removing the parent does **not** remove its add-ons (by design).