You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
FunnelKit module — New funnel/sales pipeline module for FunnelKit (ex-WooFunnels) 3.0+. Syncs contacts → crm.lead (bidirectional) with stage progression, funnel steps → crm.stage (push-only). Configurable Odoo pipeline ID, filterable stage mapping via wp4odoo_funnelkit_stage_map
GamiPress module — New gamification/loyalty module for GamiPress 2.6+. Syncs point balances → loyalty.card (bidirectional, find-or-create by partner+program), achievement types → product.template (push-only), rank types → product.template (push-only). Same loyalty.card pattern as WC Points & Rewards
BuddyBoss module — New community module for BuddyBoss/BuddyPress 2.4+. Syncs profiles → res.partner (bidirectional, enriched with xprofile fields), groups → res.partner.category (push-only). Group membership reflected as partner category tags via Many2many [(6, 0, [ids])] tuples
WP ERP module — New HR module for WP ERP 1.6+. Syncs employees → hr.employee (bidirectional), departments → hr.department (bidirectional), leave requests → hr.leave (bidirectional). Dependency chain: leaves require employee synced first, employees require department synced first. Leave status mapping: pending/approved/rejected ↔ draft/validate/refuse (filterable via wp4odoo_wperp_leave_status_map)
Knowledge module — New content sync module for WordPress posts ↔ Odoo Knowledge articles (knowledge.article, Enterprise v16+). Bidirectional sync with HTML body preserved, parent hierarchy via entity map, configurable post type, optional category slug filter. Odoo-side availability guarded via model probe. WPML/Polylang translation support for name + body fields
Multi-batch queue processing — Sync_Engine now processes multiple batches per cron invocation (up to 20 iterations) until the time limit (55 s) or memory threshold (80%) is reached. Drains large queues 10–20× faster than single-batch
Push dedup advisory lock — push_to_odoo() now acquires a MySQL advisory lock before the search-before-create path, preventing TOCTOU race conditions where concurrent workers could create duplicate Odoo records for the same entity
Optimized cron polling — poll_entity_changes() now uses targeted entity_map loading (IN (wp_ids)) instead of loading all rows, and detects deletions via last_polled_at timestamps instead of in-memory set comparison. New DB migration adds last_polled_at column to entity_map
Changed
Sync_Engine method extraction — Extracted should_continue_batching() and process_fetched_batch() from run_with_lock() for readability and testability
Module_Base trait extraction — Extracted 3 focused traits from Module_Base: Error_Classification (exception → Error_Type classification), Push_Lock (advisory lock for push dedup), Poll_Support (targeted poll with last_polled_at). Module_Base uses all 3 via use statements
CRM_Module error classification — push_to_odoo() override now catches \RuntimeException and classifies errors via Error_Classification::classify_exception() instead of treating all failures as transient
Contact_Refiner resilience — All refinement methods (refine_name, refine_country, refine_state) now catch \Throwable and return unmodified data on failure, preventing a single refinement error from blocking the entire sync
Batch creates N+1 fix — push_batch_creates() now passes the pre-resolved $module instance to process_single_job() instead of re-resolving from Module_Registry for each job in the batch
Field_Mapper date format cache — convert_date() now caches the Odoo date format string across calls, avoiding redundant format resolution per field