Skip to main content

Multi-System ERP Architectures for European Enterprises - AegeanFlows

Design patterns for enterprise integration landscapes combining SAP S4HANA, Odoo, cloud platforms, and third-party systems — with a focus on European regulatory and operational requirements.

Kostas Polakis January 20, 2026 8 min read
Architecture SAP Odoo Integration ERP Europe

Why Single-ERP Is No Longer the Default

For decades, enterprise IT strategy favoured consolidation: one ERP to rule all business processes. SAP’s dominance was built on this promise. The reality, especially in European mid-market and multinational companies, is messier.

Acquisitions bring new subsidiaries with Odoo, Dynamics, or Oracle installations. Digital transformation initiatives create cloud-native applications that need to talk to the core ERP. Marketplace integrations (Amazon, Greek e-shop platforms, logistics portals) demand real-time connectivity that traditional batch-oriented ERP architecture can’t deliver.

The result is a multi-system ERP landscape — not a failure of consolidation strategy, but a deliberate architectural choice. This article examines the design patterns that make multi-system landscapes work reliably, with specific attention to the SAP + Odoo combination that characterises many European operations.


Architecture Patterns: Four Models

Model 1: SAP as System of Record, Odoo as Execution Layer

Use case: Large enterprise with SAP S4HANA for finance, procurement, and manufacturing. Odoo deployed for a new e-commerce or marketplace business unit.

SAP S4HANA (Core)
├── Finance (FI/CO)
├── Procurement (MM)
├── Manufacturing (PP)
└── [Master Data: Customers, Materials, Pricing]

         │  Master data sync (BTP Integration Suite)

Odoo 17 (Execution)
├── E-commerce / Sales
├── Marketplace connector
├── Customer service
└── [Operational transactions: Orders, Returns]

         │  Financial postings (invoices, payments)

SAP S4HANA (Finance receives the accounting impact)

Data flow characteristics:

  • Master data flows down: S4HANA → Odoo (customers, products, pricing)
  • Transaction data flows up: Odoo → S4HANA (invoices, goods movements)
  • No data is mastered in Odoo that SAP doesn’t know about

Where this works well: Greek retail and distribution companies that have an established SAP landscape for the “back office” but want Odoo’s agility for customer-facing operations.


Model 2: Odoo as Core, SAP as Regulatory Backend

Use case: Mid-size company that started on Odoo but operates in a country (Germany, France, Austria) where SAP-based tax reporting or industry-specific regulations (e.g. DATEV integration for German tax firms) require SAP infrastructure.

Odoo 17 (Primary Operations)
├── Sales & CRM
├── Manufacturing / Inventory
├── Project management
└── [Primary financials]

         │  Accounting data sync

SAP S4HANA (Regulatory)
├── Statutory reporting (ELSTER, DRV, Intrastat)
├── Tax return preparation
└── [Audit-ready financial statements]

Implementation consideration: This is less common but valid. The challenge is that SAP’s general ledger requires complete accounting data — you must sync every journal entry from Odoo to SAP, not just summary postings. This creates tight coupling and high integration volume.


Model 3: Hub-and-Spoke with Integration Middleware

Use case: Enterprise with multiple systems (SAP, Odoo, a WMS, a TMS, a marketplace platform) that all need to exchange data.

                    [SAP BTP Integration Suite]
                    ┌───────────────────────┐
SAP S4HANA ────────┤                       ├──── Odoo 17
                    │  Message routing       │
WMS (e.g. SAP EWM)──┤  Transformation        ├──── Marketplace APIs
                    │  Error handling        │
TMS (third-party) ──┤  Monitoring            ├──── Customs systems
                    └───────────────────────┘

                              │  Audit log, dead letter

                    [BTP Monitoring & Alerting]

Why middleware matters here: Without a central integration hub, you end up with N×(N-1)/2 point-to-point connections. With 6 systems, that’s 15 connections; with 10 systems, 45 connections. Each connection has its own error handling, authentication, and monitoring. A hub reduces this to N connections from each system to the hub.


Model 4: Event-Driven Decoupled Architecture

Use case: Modern enterprise with high transaction volumes, where synchronous integration creates bottlenecks or availability coupling.

SAP S4HANA ──→ Event Mesh (BTP)

                     ├── SalesOrder.Created → [Odoo creates delivery]
                     ├── Payment.Received → [WMS confirms shipment]
                     ├── Invoice.Posted → [AP portal notification]
                     └── Inventory.Changed → [Marketplace updates]

Each consumer processes events at its own pace. SAP doesn’t wait for Odoo to acknowledge a sales order before continuing — it publishes the event and moves on. This eliminates the availability coupling that causes downstream failures to freeze the core ERP.

CloudEvents standard: Use the CloudEvents specification (CNCF standard, supported by SAP Event Mesh) for event envelope structure:

{
  "specversion": "1.0",
  "type": "com.aegeanflows.s4hana.salesorder.created.v1",
  "source": "https://s4hana.company.com",
  "id": "SO-0010001234",
  "time": "2026-02-15T10:30:00Z",
  "datacontenttype": "application/json",
  "data": {
    "salesOrderId": "0010001234",
    "soldToParty": "0000100123",
    "requestedDeliveryDate": "2026-02-20",
    "netAmount": 12450.00,
    "currency": "EUR"
  }
}

Master Data Management: The Root Cause of Most Integration Problems

In our experience, 70% of integration failures in multi-system landscapes are not technical — they are master data inconsistencies. Customer 1001 in SAP is Customer C-GR-1001 in Odoo. Product AK-500-GR in SAP is product code PUMP-500 in Odoo. When these mappings are implicit (in someone’s head or a spreadsheet), integrations break whenever a new product is added.

Minimum viable master data architecture:

  1. External reference fields: Every Odoo model that maps to an SAP object must carry an x_sap_* field. This is the authoritative cross-reference.

  2. Cross-reference table: For complex many-to-many mappings (SAP condition types → Odoo pricelist items), maintain an explicit mapping table in the integration middleware:

-- BTP Integration Suite database or separate mapping service
CREATE TABLE master_data_mapping (
    source_system   VARCHAR(20) NOT NULL,
    source_key      VARCHAR(50) NOT NULL,
    target_system   VARCHAR(20) NOT NULL,
    target_key      VARCHAR(50) NOT NULL,
    valid_from      DATE NOT NULL,
    valid_to        DATE,
    created_by      VARCHAR(50),
    PRIMARY KEY (source_system, source_key, target_system)
);

-- Example records
INSERT INTO master_data_mapping VALUES 
    ('SAP', 'ZB01', 'ODOO', '2',   '2024-01-01', NULL, 'integration_setup'),
    ('SAP', 'ZB30', 'ODOO', '3',   '2024-01-01', NULL, 'integration_setup'),
    ('SAP', 'ZB60', 'ODOO', '4',   '2024-01-01', NULL, 'integration_setup');
-- SAP payment term codes → Odoo payment term IDs
  1. Master data governance process: Assign ownership. SAP BPs are created and maintained in SAP by the finance team. They sync to Odoo automatically. Odoo users cannot create partners that don’t have an SAP reference. This is a process rule enforced by the integration, not by trust.

Resilience Patterns: Designing for Failure

Multi-system landscapes fail. Systems go down for maintenance. Networks experience transient errors. The question is not whether failures occur, but whether they cascade.

Circuit Breaker Pattern

When a downstream system is unavailable, stop trying to call it:

from datetime import datetime, timedelta

class CircuitBreaker:
    def __init__(self, failure_threshold=5, recovery_timeout=60):
        self.failure_count = 0
        self.failure_threshold = failure_threshold
        self.recovery_timeout = recovery_timeout
        self.last_failure_time = None
        self.state = 'CLOSED'  # CLOSED = operating normally
    
    def call(self, func, *args, **kwargs):
        if self.state == 'OPEN':
            if datetime.now() > self.last_failure_time + timedelta(seconds=self.recovery_timeout):
                self.state = 'HALF_OPEN'
            else:
                raise RuntimeError("Circuit breaker is OPEN — skipping call")
        
        try:
            result = func(*args, **kwargs)
            if self.state == 'HALF_OPEN':
                self.state = 'CLOSED'
                self.failure_count = 0
            return result
        except Exception as e:
            self.failure_count += 1
            self.last_failure_time = datetime.now()
            if self.failure_count >= self.failure_threshold:
                self.state = 'OPEN'
            raise

In an iFlow context, use BTP Integration Suite’s retry and circuit breaker capabilities at the adapter level — they implement the same pattern without custom code.

Saga Pattern for Distributed Transactions

When an operation spans multiple systems (e.g. create SAP sales order AND create Odoo delivery AND update inventory), traditional ACID transactions don’t work across system boundaries.

The saga pattern uses compensating transactions:

Step 1: Create SAP Sales Order → SUCCESS (SO-123)
Step 2: Create Odoo Delivery   → FAIL

Compensating transaction:
→ Cancel SAP Sales Order SO-123 (BAPI_SALESORDER_CHANGE with rejection reason)
→ Log failure for manual review
→ Alert integration team

For each forward step, define the compensating action before implementation. This is architectural work done during design, not as an afterthought when a failure occurs in production.


European-Specific Integration Requirements

VAT Determination Across Systems

In EU transactions, VAT determination depends on:

  • Supplier and customer country
  • Delivery country (can differ from billing country)
  • Goods vs. services classification
  • Intra-community vs. third-country

When Odoo creates an invoice for an order originated from SAP data, ensure VAT determination uses a consistent rule engine. The safest approach: always let SAP determine VAT (it has the fiscal configuration), and pass the determined VAT code to Odoo rather than re-determining it.

Multi-Currency in the Eurozone

Even within the Eurozone, multi-currency challenges arise: Swiss operations in CHF, UK operations post-Brexit in GBP, Turkish subsidiaries in TRY. Ensure your integration architecture passes both the transaction currency amount and the group currency equivalent to avoid inconsistent revaluations.

Intrastat Reporting Across Systems

When goods move between EU member states and the commercial system (Odoo) and the statistical reporting system (SAP) are different, Intrastat reporting requires merging data from both. Build a dedicated Intrastat reconciliation process that pulls from both systems and validates consistency before submission.


Conclusion

Multi-system ERP landscapes are the operational reality for most European enterprises of any complexity. The patterns in this article — hub-and-spoke integration, event-driven decoupling, master data governance with cross-reference tables, circuit breakers, and saga compensation — are the engineering foundation for landscapes that work reliably.

The investment in these patterns pays off not just in reliability, but in maintainability. When a new system needs to be added (a new marketplace, a new subsidiary on a different ERP), a well-architected integration hub accommodates it in weeks rather than months.

Designing or modernising your multi-system ERP landscape? Contact AegeanFlows for an architecture review.


Kostas Polakis — Senior SAP ABAP Architect & Enterprise Integration Designer, Athens, Greece.