# Journal des modifications — MyDoorling HubSpot

Ce fichier retrace les évolutions décrites dans les développements récents du plugin (synchro WooCommerce / HubSpot).

Le format s’inspire de [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/).

---

## [1.10.3] — 2026-05-05

### Corrigé

- **Factures et commandes HubSpot** : propriété HubSpot standard **`hs_position_on_quote`** sur chaque line item (0 = premier, livraison = dernier après les produits) pour stabiliser l’ordre d’affichage (évite notamment la livraison en tête de liste sur la facture PDF).

---

## [1.10.2] — 2026-05-05

### Corrigé

- **Livraison à 0 € (franco)** : une ligne d’expédition Woo (`Livraison gratuite`, etc.) est désormais créée sur la commande HubSpot et sur la facture (montant 0 lorsque c’est le cas).
- **Bloc « Total de la commande » HubSpot** : envoi des propriétés standard `hs_subtotal_price`, `hs_shipping_cost`, `hs_tax`, `hs_order_discount`, `hs_total_price` (alignées sur Woo), via **PATCH** après création des line items, et aussi à chaque synchro lorsque la commande HubSpot existe déjà (mise à jour des totaux sans recréer la commande).

### Ajouté

- **`HubSpot_Client::patch_order()`**
- **Filtres** : `mdl_hs_sync_hubspot_order_financials`, `mdl_hs_order_financial_properties`

---

## [1.10.1] — 2026-05-05

### Modifié

- **Montants HubSpot alignés sur WooCommerce (admin)** : classe `Commerce_HubSpot_Amounts` — pour chaque ligne produit, `price` / `amount` reflètent le **HT + taxes** de ligne (TTC payé) par défaut, avec mention des taxes dans `description` si > 0 ; même logique pour la **livraison** (frais + taxes).
- **Commande HubSpot** : les line items produits utilisent ces montants ; ajout optionnel d’une **ligne livraison** sur l’ordre HubSpot (filtre `mdl_hs_sync_shipping_line_to_hubspot_order`, défaut `true`) avec `mdl_hs_shipping_line_item_properties` / `mdl_hs_after_shipping_line_item_sync`.
- **Facture HubSpot** : les lignes (produits + livraison) utilisent le **même calcul** que la commande HubSpot ; filtre `mdl_hs_invoice_shipping_line_item_properties` pour la ligne livraison.
- **Filtres** : `mdl_hs_hubspot_line_amount_basis` (`gross` par défaut, ou `net` pour l’ancien comportement HT seul) ; `mdl_hs_invoice_skip_wc_line_items` — si `true`, aucune ligne n’est créée depuis Woo (cas futur : facture entièrement portée par la commande HubSpot).

---

## [1.10.0] — 2026-05-05

### Ajouté

- **Création de factures HubSpot via l’API** : brouillon (`hs_currency`, pas d’encaissement en ligne), associations **facture → contact** et **facture → commande HubSpot**, lignes (articles WooCommerce + livraison si le total d’expédition est positif), passage à **open** puis option **paid** selon le flux.
- **Flux — Factures (automatique)** : liste blanche de **statuts WooCommerce** déclenchant la création, et choix du **statut final** HubSpot (`open` / `paid`). Métas commande **`_mdl_hs_feed_{id}_hs_invoice_id`** pour éviter les doublons côté plugin.
- **Métabox commande** : bouton **Créer une facture HubSpot** par flux éligible (si aucune facture enregistrée pour ce flux).
- **`HubSpot_Client`** : `create_invoice()`, `patch_invoice()`, `put_association_v3()`, `put_association_v3_first_match()`, `create_line_item_for_invoice()`.
- **`HubSpot_Invoice_Creator`** et hooks : `mdl_hs_should_create_hubspot_invoice`, `mdl_hs_allow_hubspot_invoice_when_order_has_invoices`, `mdl_hs_create_invoice_initial_properties`, `mdl_hs_invoice_open_patch_properties`, `mdl_hs_invoice_final_status`, `mdl_hs_invoice_line_item_properties`, `mdl_hs_invoice_add_shipping_line`, `mdl_hs_after_hubspot_invoice_created`, `mdl_hs_after_invoice_line_item_sync`.

### Base de données

- Colonnes **`hs_invoice_auto_wc_statuses`** et **`hs_invoice_final_status`** sur **`mdl_hs_feeds`** (mise à jour via `dbDelta`).

### Configuration HubSpot

- Scopes **écriture** sur **factures** et **line items** (ex. `crm.objects.invoices.write`, `crm.objects.line_items.write`) et association ; selon portail, le passage à **`paid`** peut être refusé (journal conservé en **open**).

---

## [1.9.0] — 2026-05-05

### Ajouté

- **Écran commande WooCommerce** : métabox latérale **Factures HubSpot** qui interroge l’API à l’ouverture de la fiche (AJAX). Affiche l’absence de commande HubSpot liée, l’absence de facture associée à l’objet **Order** HubSpot, ou la liste des factures avec **Télécharger le PDF** (`hs_pdf_download_link`) et **Ouvrir dans HubSpot** (`hs_invoice_link`).
- **`HubSpot_Client`** : `get_invoice_ids_associated_to_hubspot_order()` (associations order → invoice) et `read_invoices_batch()`.
- **Compatibilité HPOS** : déclaration `custom_order_tables` via `FeaturesUtil::declare_compatibility`.
- **Filtres** : `mdl_hs_order_invoice_api_properties`, `mdl_hs_hubspot_order_invoice_association`, `mdl_hs_order_invoice_ids_merged`, `mdl_hs_order_invoice_row_title`, `mdl_hs_order_invoice_sections_html`.

### Configuration HubSpot

- La **clé privée** du compte utilisé pour la synchro doit autoriser l’accès en lecture aux **factures** (scopes de type `crm.objects.invoices.read` selon la doc du portail développeur). Sans ces droits, la métabox affiche un message d’erreur explicite.

---

## [1.8.2] — 2026-05-05

### Corrigé / Modifié

- **Import contacts (utilisateurs)** : si HubSpot possède déjà un contact pour l’e-mail, le plugin **associe** désormais l’utilisateur WordPress (`mdl_hs_hubspot_contact_id`) et envoie un **PATCH** des propriétés non vides (comme la synchro depuis la liste utilisateurs), au lieu de simplement ignorer la ligne.
- **Résumé de fin d’import** : compteurs distincts **créés**, **mis à jour**, **déjà dans HubSpot (aucune propriété à envoyer)** ; ancien libellé « déjà présents (email) » retiré.
- **Journal de synchro** : entrées pour les **mises à jour réussies** de contacts lors de l’import (filtre **`mdl_hs_bulk_contact_import_log_success`**, activé par défaut ; **`connector_entry_id`** = ID HubSpot du contact).

### Technique — rupture mineure

- Réponse AJAX de **`mdl_hs_contact_import_batch`** : **`skipped_hs_exists`** supprimé ; remplacé par **`updated_existing`** et **`linked_existing_no_patch`**.
- Hook **`mdl_hs_bulk_contact_import_skip_existing`** supprimé ; à la place **`mdl_hs_after_bulk_contact_import_existing`** (`$contact_id`, `$user`, `$props`, `$client`, `$patch_ok`) où `$patch_ok` vaut `true` / `false` / `null` (aucune propriété à PATCH).

---

## [1.8.1] — 2026-05-06

### Modifié

- **Intégrations HubSpot (liste + édition de flux)** : interrupteurs visuels (switch) à la place des anciennes cases à cocher pour **Actif** (liste et formulaire) et pour les **objets synchronisés** (contact / transaction / commande).
- Libellés alignés sur l’interface HubSpot en français : **Transaction** (ex. affaire / deal) et **Commande** ; mise à jour des titres et textes d’aide associés (pipelines, statuts WooCommerce, panneaux de correspondance).

### Technique

- **`Feed_Sync_Config::targets_admin_label()`** : affiche désormais **Transaction** et **Commande** dans la colonne « Objets synchronisés ».

---

## [1.8.0] — 2026-05-06

### Ajouté

- **Import utilisateurs** et **synchro depuis la liste Utilisateurs WordPress** : application des correspondances **contact** du flux WooCommerce pour le **compte HubSpot** utilisé — premier flux **actif** du compte qui définit au moins une correspondance « contacts » (filtre **`mdl_hs_contact_mappings_feed_id_for_account`** pour surcharger l’ID de flux).
- **`Contact_Field_Mapping`** et **`Contact_Import::hubspot_contact_props_for_wp_user_ready()`**.

### Modifié

- **`Order_Fields`** : même jeu de clés pour **`WC_Order`** ou **`WC_Customer`** (facturation / livraison ; pas de données réservées à une commande côté client).
- Envoi HubSpot **contact** : propriétés dont la valeur est vide après trim **exclues** ; **PATCH** uniquement s’il reste au moins une propriété non vide (commandes WooCommerce et synchro liste utilisateurs).
- Synchro liste utilisateurs + contact HubSpot déjà existant : **PATCH** des champs non vides en plus de l’association **`mdl_hs_hubspot_contact_id`**.

---

## [1.7.0] — 2026-05-06

### Ajouté

- Correspondances WooCommerce → HubSpot : type **« Plusieurs champs (concaténation) »** — liste à sélection multiple (ordre conservé), **séparateur** configurable (espace, virgule, ou séquences `\n` / `\t` pour saut de ligne ou tabulation). Valeurs vides ignorées ; stockage JSON dans **`mdl_hs_feed_fields`** avec **`fields_type` = `concat`**.
- **`Order_Fields::concat`** et **`Order_Fields::concat_from_stored`** ; prise en charge dans les mappings **contact**, **affaire** et **commande HubSpot**.

---

## [1.6.4] — 2026-05-06

### Modifié

- **Correspondance des propriétés HubSpot** (contact, affaire, commande HubSpot) : listes avec **`<optgroup>`** par **famille** renvoyée par HubSpot (`groupName` + libellés de **`GET /crm/v3/properties/{objectType}/groups`**). Tri par famille puis par libellé de propriété ; champs sans groupe dans **« Autres propriétés »**.

---

## [1.6.3] — 2026-05-06

### Corrigé

- **Import contacts** : la liste des rôles autorisés utilisait **`is_object( $wp_roles->roles )`** alors que **`roles`** est un **tableau** — la liste était toujours vide et tout import échouait avec « Sélectionnez au moins un rôle ». Correction avec **`instanceof \WP_Roles`** et **`is_array( $wp_roles->roles )`**.
- Formulaire HTML **`#mdl_hs_contact_import_form`** : cases **`name="roles[]"`**, liste **`name="account_id"`**, envoi AJAX via **`new FormData(form)`** pour aligner le POST sur un formulaire classique.

---

## [1.6.2] — 2026-05-06

### Corrigé

- **Import contacts** : envoi des rôles en **`FormData`** avec clés **`roles[]`** pour que `$_POST['roles']` soit toujours un tableau côté PHP ; parsing serveur assoupli (chaîne CSV / JSON) pour éviter l’erreur « Sélectionnez au moins un rôle » alors que des cases sont cochées.

---

## [1.6.1] — 2026-05-06

### Ajouté

- Colonne **HubSpot** sur **Utilisateurs** : icône verte si la méta **`mdl_hs_hubspot_contact_id`** est renseignée, icône rouge cliquable sinon ; confirmation avant envoi, puis création du contact ou association si un contact existe déjà avec le même e-mail (sans doublon).
- Filtre **`mdl_hs_users_list_default_account_id`** pour forcer le compte HubSpot utilisé depuis cette liste (sinon premier compte par ID croissant).
- Hook **`mdl_hs_users_list_sync_linked_existing`** lorsque le contact existait déjà dans HubSpot et que la méta utilisateur est mise à jour.
- **`Contact_Import::build_hubspot_properties_for_user()`** rendue publique pour réutiliser les mêmes propriétés que l’import en masse.

---

## [1.6.0] — 2026-05-06

### Ajouté

- Écran **Import contacts** (HubSpot) : sélection du **compte**, des **rôles WordPress** à inclure, puis bouton **Lancer l’import**.
- Import **par lots** (AJAX) pour éviter les timeouts ; création des contacts avec **e-mail, prénom, nom** (profil WP ou **client WooCommerce** si disponible).
- **Pas de doublon** : recherche HubSpot par **e-mail** avant création ; si le contact existe déjà, **ignoré** ; si l’e-mail est invalide, **ignoré**.
- En cas de succès : mise à jour de la méta utilisateur **`mdl_hs_hubspot_contact_id`** ; hooks **`mdl_hs_bulk_contact_import_properties`**, **`mdl_hs_bulk_contact_import_roles_allowed`**, **`mdl_hs_bulk_contact_import_skip_existing`**, **`mdl_hs_after_bulk_contact_import_user`** ; journalisation des échecs API si **`mdl_hs_bulk_contact_import_log_failures`** reste à true.

### Modifié

- Les actions AJAX **`mdl_hs_*`** sont enregistrées même hors contexte `is_admin()`, pour fiabiliser les appels depuis `admin-ajax.php`.

---

## [1.5.4] — 2026-05-05

### Ajouté

- Filtre **`mdl_hs_pipeline_ui_label`** (`$label`, tableau avec `context` : `deal_pipeline` \| `deal_stage` \| `order_pipeline` \| `order_stage`, `id`, `pipeline_id` optionnel) pour surcharger l’affichage des pipelines et étapes dans l’admin.
- Filtre **`mdl_hs_http_request_args`** (`$args`, `$method`, `$url`) pour ajouter ou modifier les en-têtes des appels vers `api.hubapi.com` (ex. tests avec `Accept-Language`).
- Correspondance **FR** automatique pour les libellés anglais des **étapes / pipeline modèles** HubSpot (sales pipeline type « Appointment scheduled », « Closed won », etc.) lorsque la locale utilisateur WordPress commence par **`fr`** ; les libellés personnalisés restent tels que renvoyés par l’API.

### Modifié

- Presets FR **affaires** vs **commandes HubSpot (Orders)** séparés (évite de traduire par erreur un libellé « Open » hors pipeline commande) ; libellé de pipeline **`Order Pipeline` → Pipeline des commandes** ; étapes type **Open / Processed / Shipped / Delivered / Cancelled** alignées sur les libellés HubSpot FR (**Ouvrir, Traité, Envoyé, Remis, Annulé**) avec casse normalisée ; alias **Sent → Envoyé**, **Canceled → Annulé**.

### Notes

- La [référence CRM Pipelines](https://developers.hubspot.com/docs/api-reference/latest/crm/pipelines/guide) n’expose qu’un champ `label` unique par pipeline ou étape, **sans paramètre de langue**. L’interface HubSpot peut afficher une traduction selon les préférences du compte alors que l’API renvoie la valeur stockée sur le portail — ce n’est pas un défaut du plugin. Pour que l’API renvoie du français partout : renommer explicitement pipelines et étapes dans les réglages HubSpot, ou s’appuyer sur les filtres ci-dessus.

---

## [1.5.3] — 2026-05-05

### Supprimé

- Écran et logique **Migration legacy** (import depuis l’extension historique WeConnect) : sous-menu admin, traitement POST et classe associée retirés.

### Modifié

- En-têtes des pages HubSpot : bloc titre **centré** dans la carte (grille 3 colonnes) ; suppression du soulignement / styles de titre hérités de l’admin WordPress sur les `h1` du bandeau.

---

## [1.5.2] — 2026-05-05

### Ajouté

- Refonte visuelle de **toutes les pages admin** du plugin : en-têtes avec signature « orb », cartes (`mdl-hs-panel`), tableau des flux et du journal modernisés, pastilles pour les objets / statuts dans le journal.
- Classe `body` `mdl-hs-admin-screen` sur les écrans HubSpot pour scoper charte, fond en dégradés légers et variables CSS.

### Modifié

- Formulaires d’édition de flux découpés en sections (réglages + correspondances) dans des panneaux distincts ; même logique pour Comptes, Réglages et Formidable.

---

## [1.5.1] — 2026-05-05

### Modifié

- Mise à jour de l’affaire après **chaque synchro réussie** de la commande HubSpot (objet Orders), que la commande HubSpot soit **nouvelle ou déjà connue** dans les métas WooCommerce — aligné avec un cycle de vie deal qui évolue à chaque passage du flux (statuts Woo, page merci, etc.).
- Libellés admin et messages du journal : « après **synchro** » plutôt qu’après création exclusive ; titre du bloc de réglages harmonisé (`Après synchro de la commande HubSpot`).
- Suppression du indicateur interne `created_new` sur le retour de la création de commande HubSpot (la logique « affaire après commande » ne dépend plus de la distinction création / existence).

---

## [1.5.0] — 2026-05-05

### Ajouté

- Réglages par flux (**sans exemple métier codé en dur**) pour agir sur le **deal** après synchronisation de la commande HubSpot :
  - ne rien modifier ;
  - déplacer vers un pipeline / étape HubSpot dédiés ;
  - réaligner sur le pipeline et l’étape « affaire » déjà configurés dans le même flux ;
  - marquer comme affaire **gagnée** ou **perdue** en détectant la première étape fermée correspondante (`probability` / `isClosed` dans les métadonnées des étapes du pipeline affaires).
- Colonnes SQL : `after_hs_order_deal_action`, `after_hs_order_deal_pipeline`, `after_hs_order_dealstage` (schéma mis à jour via `dbDelta`).
- Client API : `patch_deal`, lecture détaillée des étapes de pipeline affaires (`get_deal_stages_detailed`), résolution des étapes closed won / closed lost.
- **Filtres et hooks** pour étendre ou court-circuiter le comportement :
  - `mdl_hs_should_update_deal_after_hs_order` ;
  - `mdl_hs_after_hs_order_deal_patch_properties` (PATCH personnalisé prioritaire) ;
  - `mdl_hs_deal_patch_properties_after_hs_order` ;
  - action `mdl_hs_after_deal_patch_post_hs_order`.
- Interface admin : liste déroulante + pipelines / étapes cibles lorsque l’option « pipeline / étape précis » est choisie ; chargement AJAX aligné sur les pipelines affaires existants.
- Constantes et validation dans `Feed_Sync_Config` (`AFTER_HS_ORDER_DEAL_*`, `sanitize_after_hs_order_deal_action`).
- Import legacy : valeurs par défaut pour les nouvelles colonnes « après commande HubSpot ».

### Modifié

- Au moment de l’introduction de cette fonctionnalité, la mise à jour du deal ne s’appliquait **que** lorsque HubSpot **créait** une nouvelle commande dans ce passage — comportement élargi dans **1.5.1** (voir ci-dessus).

---

## [1.4.0] — 2026-05-04

### Ajouté

- Écoute du hook WooCommerce **`woocommerce_order_status_changed`** en complément de **`woocommerce_thankyou`**, pour réexécuter les flux lors des changements de statut de commande (pas les webhooks HubSpot — tout part du site WooCommerce).
- Colonne **`sync_on_status_change`** dans la table des flux : permet par flux d’activer ou non la synchro lors des changements de statut (défaut : activé).
- Case à cocher admin **« Réexécuter ce flux lorsque le statut WooCommerce de la commande change »** avec description générique (listes blanches `deal_wc_statuses` / `order_wc_statuses` toujours appliquées au statut courant).
- **Idempotence par flux** pour éviter les doubles créations HubSpot :
  - métas `_mdl_hs_feed_{feed_id}_deal_id` et `_mdl_hs_feed_{feed_id}_hs_order_id` ;
  - reprise des anciennes métas `_mdl_hs_deal_id` et `_mdl_hs_order_id` pour les installations déjà synchronisées.
- Écriture des métas commande via **`$order->update_meta_data()` / `save_meta_data()`** (compatibilité stockage commandes HPOS).
- Filtres **`mdl_hs_should_handle_order_status_change`** et **`mdl_hs_should_run_feed_sync`** (avec le déclencheur : page merci ou changement de statut).
- Journalisation des opérations avec le bon libellé de déclencheur (`order_thankyou` | `wc_order_status_changed`).

### Modifié

- Libellés admin : distinction flux actif vs synchro sur changement de statut ; formulations sans scénario métier figé (ex. « devis ») dans les aides.
- Import **legacy** : prise en charge de `sync_on_status_change` lors de l’insert des flux.

---

## [1.3.2] et antérieur

Versions précédentes du plugin (contacts, affaires, commandes HubSpot, Formidable, pipelines, listes de statuts Woo, etc.) sans entrée détaillée dans ce journal — considérer cette ligne comme **référence de base** avant les livraisons **1.4.0** à **1.5.1** ci-dessus.
