Cross-Application Sync

Cross-Application Sync

Dolibarr to Odoo Customer Sync via Dynamic Orchestration

Demonstrated March 22, 2026 using PolySniffer, Mapping Engine, and RabbitMQ

This page documents a live demonstration of PolySaaS cross-application sync: creating a new customer in Dolibarr ERP and automatically synchronizing it to Odoo CRM as a contact/partner. The process uses PolySniffer for traffic capture, the Mapping Engine for field transformation, RabbitMQ as the message broker, and Dynamic Orchestration to wire it all together with zero code changes.

End-to-End Data Flow

1. User creates customer in Dolibarr via Passthrough Proxy
2. Instruction A matches POST /societe/card.php
3. Mapping Engine extracts & normalizes 21 fields from the POST body
4. Normalized event published to RabbitMQ (polysaas.crossapp.customer.created)
5. MQ Monitor picks up message, triggers Instruction B
6. Mapping Engine transforms normalized data to 14 Odoo partner fields
7. Odoo XML-RPC: res.partner.create() — customer appears in Odoo Contacts

Step-by-Step: Sniffing Dolibarr

Step 1 — Launch PolySniffer for Dolibarr

In the Django admin, each PassThrough endpoint has a PolySniffer Analysis button. Click it on the Dolibarr ERP row to start the traffic capture proxy.

PassThrough endpoint admin with PolySniffer Analysis button for Dolibarr
PassThrough endpoint list — Dolibarr ERP at localhost:8889 with PolySniffer Analysis

Step 2 — PolySniffer Captures All Traffic

The PolySniffer dashboard shows every HTTP request in real time. As we navigate Dolibarr, every GET and POST is captured with full headers, cookies, and body content.

PolySniffer live capture dashboard with Dolibarr traffic entries
80+ requests captured during the Dolibarr session — login, navigation, CSS, JS, and the critical form POST

Step 3 — Login to Dolibarr Through the Proxy

Dolibarr 19.0.2 loads through the PolySniffer proxy. The login request is captured, giving us the CSRF token pattern and authentication flow.

Dolibarr 19.0.2 login screen
Dolibarr 19.0.2 login — admin credentials, all traffic passively captured

Step 4 — Navigate to Third-parties

After login, the Dolibarr dashboard shows the full menu: Home, Members, Third-parties, Products, Projects, Commerce, Billing, and more. We navigate to Third-parties.

Dolibarr admin with Third-parties menu highlighted
Dolibarr navigation bar — Third-parties module selected

Step 5 — Select New Customer

The Third-parties sidebar shows the entity list. Statistics: 0 Prospects, 0 Customers, 0 Vendors. We click New Customer to begin.

Third-parties sidebar with New Customer highlighted
Zero existing records — this will be the first customer synced to Odoo

Step 6 — Fill the New Third Party Form

The form captures comprehensive customer data. We fill in the fields that will be extracted by the Mapping Engine:

Dolibarr New Third Party form filled with Mike Oliver data
Core fields: name, alias, prospect/customer classification, address, zip, city, phone
Form FieldValue EnteredNormalized To
Third-party nameMike Olivername
AliasMike Olivername_alias
Prospect / CustomerProspect / Customeris_customer = 1
Address102 Woodlily Pl.street
Zip Code77382zip
CitySpringcity
Phone2818535769phone
Emailmikeoliveraz@gmail.comemail
Third-party typeWorkforcetypent_id

Step 7 — Submit: Create Third Party

The bottom of the form shows Professional IDs, Sales tax (checked), Third-party type, and the sales representative assignment. Click CREATE THIRD PARTY.

Create Third Party button at bottom of Dolibarr form
This POST triggers the entire cross-app sync chain

When submitted, PolySniffer captures the full POST body with all 43 form fields, including the hidden CSRF token, action type, and all visible form values.

Step 8 — Customer Created in Dolibarr

Dolibarr confirms the record with auto-generated Customer Code CU2603-00001. All entered data is displayed on the card view.

Mike Oliver customer card in Dolibarr showing all synced fields
Mike Oliver — Customer Code CU2603-00001, Type: Workforce, Prospect + Customer

Result: Customer in Odoo

Step 9 — Mike Oliver Appears in Odoo Contacts

The sync chain completes: Dolibarr → Mapping Engine → RabbitMQ → Mapping Engine → Odoo XML-RPC. The customer record now appears in Odoo Contacts.

Odoo Contacts grid view showing Mike Oliver synced from Dolibarr
Odoo Contacts grid — Mike Oliver (red arrow) appears alongside existing demo data, synced from Dolibarr

Step 10 — Full Record Detail in Odoo

Opening the contact record confirms every field was correctly mapped from the Dolibarr form through both Mapping Engine transformations:

Odoo Contact detail page for Mike Oliver showing all synced fields
All fields intact: name, address (102 Woodlily Pl., Spring, 77382), phone, mobile, email
Dolibarr FieldNormalizedOdoo FieldValue
namenamenameMike Oliver
addressstreetstreet102 Woodlily Pl.
zipcodezipzip77382
towncitycitySpring
phonephonephone2818535769
faxfaxmobile2818535769
emailemailemailmikeoliveraz@gmail.com
customer_codecustomer_coderefCU2603-00001

Sync Complete — Zero code changes. Entirely driven by database-configured Mappings and Instructions.

Instructions: The Routing Rules

Instructions in the Tenant Admin

Instructions are the routing rules that connect incoming requests to atomic services. In the Oliver Enterprises tenant, two new Instructions were created for the cross-app sync flow:

Django admin Instructions list in olient tenant
Three Instructions in the olient tenant — the two new entries route Dolibarr POST and MQ messages to their respective services
Request PathMethodServicePurpose
/societe/card.phpPOSTEndpointDataExtractorServiceCaptures Dolibarr form POST, extracts & publishes to RabbitMQ
/mq/polysaas.crossapp.customer.createdPOSTOdooCustomerSyncServicePicks up MQ message, maps to Odoo partner, syncs via XML-RPC

Instruction Detail: Dolibarr POST Capture

Each Instruction defines a requestpath (substring match), method, direction, and an eventKey for tracking. The Instruction Mappings tab links it to one or more Mapping records that define the field extraction logic.

Instruction detail for Dolibarr POST capture
Instruction detail: requestpath /societe/card.php, eventKey dolibarr.customer.created, method POST, direction REQUEST

When any POST request passes through the proxy and its URL contains /societe/card.php, this Instruction fires the EndpointDataExtractorService, which uses the attached Mapping to extract and normalize the form fields.

The Mapping Engine

The Mapping Engine is database-driven — no code changes needed to add new integrations. Each mapping defines how to transform fields using an expression syntax with pipe operators:

Mapping 1: Dolibarr POST → Normalized Event

Direction: SOURCE → NORMALIZED

Extracts Dolibarr form fields and normalizes them into a cross-application customer event:

Normalized FieldExpressionResult
namerequest.POST.name|stripMike Oliver
emailrequest.POST.email|strip|lower|emailmikeoliveraz@gmail.com
phonerequest.POST.phone|strip|default:None2818535769
streetrequest.POST.address|strip102 Woodlily Pl.
ziprequest.POST.zipcode|strip77382
cityrequest.POST.town|stripSpring
is_customerrequest.POST.client|int:1:01
customer_coderequest.POST.customer_code|stripCU2603-00001

Mapping 2: Normalized → Odoo res.partner

Direction: NORMALIZED → TARGET

Transforms the normalized event into Odoo-specific partner fields for XML-RPC sync:

Odoo FieldExpressionResult
namepayload.nameMike Oliver
emailpayload.emailmikeoliveraz@gmail.com
customer_rankpayload.is_customer|int:1:01
refpayload.customer_code|default:NoneCU2603-00001
is_company'True'|boolTrue
streetpayload.street102 Woodlily Pl.
citypayload.citySpring

Pipe operators include: |strip, |lower, |upper, |email (validate), |int:1:0 (conditional cast), |default:value, |truncate:120, |prefix:DOL-, |bool, |if:path, and |coalesce:fallback.path. All configurable from the admin — no deployment needed.

Technology Stack

ComponentRoleStatus
PolySnifferPassive traffic capture to discover form fields and POST pathsActive
Mapping EngineDatabase-driven field extraction and transformation with pipe expressionsActive
RabbitMQMessage broker between source extraction and target sync servicesActive
Atomic ServicesEndpointDataExtractorService + OdooCustomerSyncServiceActive
InstructionsPath-based routing: /societe/card.php and /mq/...Active
Passthrough ProxyTransparent proxy for accessing Dolibarr through PolySaaSHandler Pending
Odoo XML-RPCCreates/updates res.partner records in Odoo CRMActive

Cross-application sync is just one example of what Dynamic Orchestration enables.

Dynamic Orchestration PolySniffer Schedule a Demo