This guide covers how to integrate TGM Manager with enterprise ERP systems like SAP, Microsoft Dynamics, and Oracle.

Table of Contents

  1. Overview
  2. Supported ERP Systems
  3. Architecture
  4. Configuration
  5. API Reference
  6. Entity Mappings
  7. Sync Operations
  8. Webhooks
  9. Troubleshooting

Overview

TGM Manager provides bi-directional synchronization with major ERP systems, allowing you to:

  • Import data from ERP: Sync customers, equipment, work orders from your ERP into TGM
  • Export data to ERP: Push TGM records (inspections, work orders, failures) back to your ERP
  • Real-time sync: Configure webhooks for instant synchronization
  • Scheduled sync: Automate full and incremental syncs on a schedule

Key Features

  • Support for SAP, Microsoft Dynamics 365, and Oracle ERP systems
  • Configurable field-level mappings
  • Conflict resolution strategies
  • Audit trail for all sync operations
  • Rate limiting and retry mechanisms
  • Secure credential storage (encrypted)

Supported ERP Systems

SAP

System Description Authentication
SAP S/4HANA Latest SAP ERP suite OAuth 2.0, Basic Auth
SAP ECC SAP ERP Central Component Basic Auth, Certificate
SAP Business One SMB ERP solution API Key, Basic Auth

Microsoft Dynamics

System Description Authentication
Dynamics 365 Finance & Operations Enterprise ERP OAuth 2.0 (Azure AD)
Dynamics 365 Business Central SMB ERP OAuth 2.0 (Azure AD)
Dynamics NAV On-premise NAV Basic Auth, NTLM
Dynamics AX Legacy Dynamics AX Basic Auth

Oracle

System Description Authentication
Oracle Cloud ERP Oracle Fusion Cloud OAuth 2.0, OCI
Oracle E-Business Suite On-premise EBS Basic Auth
Oracle NetSuite Cloud ERP Token-based, OAuth 2.0
Oracle JD Edwards JDE EnterpriseOne Basic Auth

Architecture

┌─────────────────────────────────────────────────────────────┐
│                        TGM Manager                          │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐ │
│  │ Admin API   │  │ Webhook     │  │ Scheduled Sync      │ │
│  │ Endpoints   │  │ Receiver    │  │ Service             │ │
│  └──────┬──────┘  └──────┬──────┘  └──────────┬──────────┘ │
│         │                │                     │            │
│         └────────────────┼─────────────────────┘            │
│                          │                                  │
│                ┌─────────▼─────────┐                       │
│                │  ERP Sync Engine  │                       │
│                │  - Connection Mgmt │                       │
│                │  - Entity Mapping  │                       │
│                │  - Transformation  │                       │
│                └─────────┬─────────┘                       │
│                          │                                  │
│         ┌────────────────┼────────────────┐                │
│         │                │                │                │
│    ┌────▼────┐     ┌────▼────┐     ┌────▼────┐           │
│    │   SAP   │     │Dynamics │     │ Oracle  │           │
│    │Connector│     │Connector│     │Connector│           │
│    └────┬────┘     └────┬────┘     └────┬────┘           │
└─────────┼───────────────┼───────────────┼───────────────┘
          │               │               │
          ▼               ▼               ▼
     ┌─────────┐    ┌─────────┐    ┌─────────┐
     │   SAP   │    │Dynamics │    │ Oracle  │
     │  System │    │   365   │    │  Cloud  │
     └─────────┘    └─────────┘    └─────────┘

Components

  1. Admin API: REST endpoints for managing connections and mappings
  2. Webhook Receiver: Handles real-time events from ERP systems
  3. Scheduled Sync Service: Runs automated full/incremental syncs
  4. ERP Sync Engine: Core sync logic, transformation, conflict resolution
  5. ERP Connectors: Protocol-specific adapters for each ERP type

Configuration

Step 1: Create an ERP Connection

Admin UI or API:

curl -X POST http://localhost:1337/api/admin/erp/connections \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production SAP",
    "description": "Main SAP S/4HANA system",
    "erpType": "SAP_S4HANA",
    "authType": "OAUTH2",
    "baseUrl": "https://my-sap-system.example.com/sap/opu/odata4/sap",
    "clientId": "your-client-id",
    "clientSecret": "your-client-secret",
    "sapClient": "100",
    "sapSystemId": "PRD",
    "sapLanguage": "EN",
    "enabled": true,
    "syncEnabled": true,
    "syncDirection": "BIDIRECTIONAL",
    "syncIntervalMinutes": 60,
    "webhookEnabled": true
  }'

Step 2: Configure Entity Mappings

Map TGM entities to ERP entities:

curl -X POST http://localhost:1337/api/admin/erp/connections/1/mappings \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tgmEntityType": "UNIT",
    "erpEntityName": "Equipment",
    "syncEnabled": true,
    "syncDirection": "BIDIRECTIONAL",
    "conflictResolution": "ERP_WINS",
    "batchSize": 100,
    "fieldMappings": [
      {
        "tgmField": "name",
        "erpField": "Description",
        "fieldType": "STRING",
        "syncDirection": "BIDIRECTIONAL",
        "required": true
      },
      {
        "tgmField": "serialNumber",
        "erpField": "SerialNumber",
        "fieldType": "STRING",
        "syncDirection": "INBOUND",
        "isKeyField": true
      },
      {
        "tgmField": "manufacturer",
        "erpField": "ManufacturerName",
        "fieldType": "STRING",
        "syncDirection": "INBOUND"
      }
    ]
  }'

Step 3: Test the Connection

curl -X POST http://localhost:1337/api/admin/erp/connections/1/test \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "connectionId": 1,
  "connectionName": "Production SAP",
  "erpType": "SAP_S4HANA",
  "status": "success",
  "message": "Successfully connected to SAP S/4HANA",
  "testedAt": "2024-01-15T10:30:00"
}


API Reference

Connection Endpoints

Method Endpoint Description
GET /api/admin/erp/connections List all connections
GET /api/admin/erp/connections/{id} Get connection details
POST /api/admin/erp/connections Create new connection
PUT /api/admin/erp/connections/{id} Update connection
DELETE /api/admin/erp/connections/{id} Delete connection
POST /api/admin/erp/connections/{id}/test Test connection
POST /api/admin/erp/connections/{id}/enable Enable connection
POST /api/admin/erp/connections/{id}/disable Disable connection

Entity Mapping Endpoints

Method Endpoint Description
GET /api/admin/erp/connections/{id}/mappings List entity mappings
GET /api/admin/erp/mappings/{id} Get mapping details
POST /api/admin/erp/connections/{id}/mappings Create mapping
PUT /api/admin/erp/mappings/{id} Update mapping
DELETE /api/admin/erp/mappings/{id} Delete mapping

Sync Endpoints

Method Endpoint Description
GET /api/admin/erp/connections/{id}/sync-jobs List sync jobs
GET /api/admin/erp/sync-jobs/{id} Get sync job details
GET /api/admin/erp/sync-jobs/{id}/detail Get detailed job info with error logs
GET /api/admin/erp/sync-jobs/running Get all running jobs
POST /api/admin/erp/connections/{id}/sync/full Trigger full sync
POST /api/admin/erp/connections/{id}/sync/incremental Trigger incremental sync
POST /api/admin/erp/connections/{id}/sync/entity Sync single entity
POST /api/admin/erp/sync-jobs/{id}/cancel Cancel running sync
POST /api/admin/erp/sync-jobs/{id}/retry Retry failed job
GET /api/admin/erp/connections/{id}/sync/statistics Get sync statistics

Schedule Configuration Endpoints

Method Endpoint Description
GET /api/admin/erp/connections/{id}/schedule Get schedule configuration
PUT /api/admin/erp/connections/{id}/schedule Update schedule configuration
POST /api/admin/erp/connections/{id}/schedule/enable Enable scheduled sync
POST /api/admin/erp/connections/{id}/schedule/disable Disable scheduled sync

Dashboard Endpoint

Method Endpoint Description
GET /api/admin/erp/dashboard Get sync dashboard with statistics

Reference Data Endpoints

Method Endpoint Description
GET /api/admin/erp/supported-erp-types List supported ERP types
GET /api/admin/erp/syncable-entities List syncable TGM entities

Entity Mappings

Syncable TGM Entities

Entity Type Description Typical ERP Mapping
COMPANY Customer/Company records Customer, Business Partner
LOCATION Site locations Plant, Location, Address
UNIT Equipment/Assets Equipment, Fixed Asset
COMPONENT Equipment components BOM Item, Material
USER TGM Users Employee, HR Record
WORK_ORDER Work orders Service Order, PM Order
INSPECTION Inspection records Measurement Document
FAILURE Failure/Breakdown records Notification, Incident
INVENTORY Inventory items Material, Stock Item
INVOICE Billing documents Billing Document, Invoice

Field Mapping Types

Type Description
STRING Text fields
INTEGER Whole numbers
DECIMAL Decimal numbers
BOOLEAN True/false values
DATE Date only
DATETIME Date and time
ENUM Enumerated values (requires mapping)
REFERENCE Foreign key reference
JSON Complex nested data

Sync Directions

Direction Description
INBOUND ERP → TGM only
OUTBOUND TGM → ERP only
BIDIRECTIONAL Both directions

Conflict Resolution Strategies

Strategy Description
TGM_WINS TGM data overwrites ERP data
ERP_WINS ERP data overwrites TGM data
NEWEST_WINS Most recently modified record wins
MANUAL Flag for manual resolution
MERGE Attempt to merge non-conflicting fields

Schedule Configuration

Get Current Schedule

curl http://localhost:1337/api/admin/erp/connections/1/schedule \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "connectionId": 1,
  "connectionName": "Production SAP",
  "syncEnabled": true,
  "syncIntervalMinutes": 60,
  "syncIntervalFormatted": "1 hour",
  "webhookEnabled": true,
  "webhookUrl": "/api/webhooks/erp/1",
  "maxRetries": 3,
  "retryDelaySeconds": 30,
  "rateLimitRequests": 100,
  "rateLimitPeriodSeconds": 60,
  "lastFullSync": "2024-01-14T00:00:00",
  "lastIncrementalSync": "2024-01-15T09:00:00",
  "nextScheduledSync": "2024-01-15T10:00:00",
  "nextSyncIn": "30 minutes",
  "isScheduleActive": true,
  "activeJobsCount": 0
}

Update Schedule Configuration

curl -X PUT http://localhost:1337/api/admin/erp/connections/1/schedule \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "syncEnabled": true,
    "syncIntervalMinutes": 30,
    "webhookEnabled": true,
    "maxRetries": 5,
    "retryDelaySeconds": 60,
    "rateLimitRequests": 50,
    "rateLimitPeriodSeconds": 60
  }'

Enable/Disable Schedule

Enable with 30-minute interval:

curl -X POST "http://localhost:1337/api/admin/erp/connections/1/schedule/enable?intervalMinutes=30" \
  -H "Authorization: Bearer $JWT_TOKEN"

Disable schedule:

curl -X POST http://localhost:1337/api/admin/erp/connections/1/schedule/disable \
  -H "Authorization: Bearer $JWT_TOKEN"


Sync Operations

Full Sync

A full sync compares all records between TGM and the ERP:

curl -X POST http://localhost:1337/api/admin/erp/connections/1/sync/full \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "id": 123,
  "erpConnectionId": 1,
  "erpConnectionName": "Production SAP",
  "jobType": "FULL",
  "direction": "BIDIRECTIONAL",
  "status": "RUNNING",
  "totalRecords": 1500,
  "processedRecords": 0,
  "startedAt": "2024-01-15T10:30:00",
  "createdAt": "2024-01-15T10:30:00"
}

Incremental Sync

An incremental sync only processes records changed since the last sync:

curl -X POST http://localhost:1337/api/admin/erp/connections/1/sync/incremental \
  -H "Authorization: Bearer $JWT_TOKEN"

Single Record Sync

Sync a specific record immediately:

curl -X POST "http://localhost:1337/api/admin/erp/connections/1/sync/entity?entityType=UNIT&recordId=456&direction=OUTBOUND" \
  -H "Authorization: Bearer $JWT_TOKEN"

Dashboard Overview

Get a comprehensive dashboard of all ERP sync operations:

curl http://localhost:1337/api/admin/erp/dashboard \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "totalConnections": 3,
  "enabledConnections": 2,
  "connectedConnections": 2,
  "errorConnections": 0,
  "runningJobsCount": 1,
  "runningJobs": [
    {
      "jobId": 125,
      "connectionId": 1,
      "connectionName": "Production SAP",
      "jobType": "INCREMENTAL",
      "progressPercent": 45,
      "processedRecords": 450,
      "totalRecords": 1000,
      "startedAt": "2024-01-15T10:30:00",
      "runningFor": "5 minutes"
    }
  ],
  "recentFailedJobs": [
    {
      "jobId": 120,
      "connectionId": 2,
      "connectionName": "Dynamics 365",
      "jobType": "FULL",
      "errorMessage": "Authentication failed",
      "errorCount": 15,
      "failedAt": "2024-01-15T08:00:00",
      "isRetryable": true
    }
  ],
  "connectionHealth": [
    {
      "connectionId": 1,
      "connectionName": "Production SAP",
      "erpType": "SAP_S4HANA",
      "connectionStatus": "CONNECTED",
      "lastSuccessfulSync": "2024-01-15T09:00:00",
      "recentErrorCount": 0,
      "healthStatus": "HEALTHY"
    }
  ],
  "upcomingSyncs": [
    {
      "connectionId": 1,
      "connectionName": "Production SAP",
      "syncType": "INCREMENTAL",
      "nextSyncAt": "2024-01-15T11:00:00",
      "timeUntilSync": "25 minutes"
    }
  ],
  "generatedAt": "2024-01-15T10:35:00"
}

Get All Running Jobs

curl http://localhost:1337/api/admin/erp/sync-jobs/running \
  -H "Authorization: Bearer $JWT_TOKEN"

Monitoring Sync Jobs

Check sync job status:

curl http://localhost:1337/api/admin/erp/sync-jobs/123 \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "id": 123,
  "erpConnectionId": 1,
  "erpConnectionName": "Production SAP",
  "jobType": "FULL",
  "direction": "BIDIRECTIONAL",
  "status": "COMPLETED",
  "totalRecords": 1500,
  "processedRecords": 1500,
  "successCount": 1485,
  "errorCount": 15,
  "skipCount": 0,
  "progressPercent": 100,
  "startedAt": "2024-01-15T10:30:00",
  "completedAt": "2024-01-15T10:45:30",
  "durationMs": 930000,
  "durationFormatted": "15m 30s"
}

Get Detailed Job Info with Error Logs

For failed or completed jobs with errors, get detailed error information:

curl http://localhost:1337/api/admin/erp/sync-jobs/123/detail \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "id": 123,
  "erpConnectionId": 1,
  "erpConnectionName": "Production SAP",
  "jobType": "FULL",
  "status": "COMPLETED",
  "totalRecords": 1500,
  "processedRecords": 1500,
  "successCount": 1485,
  "errorCount": 15,
  "errorLogs": [
    {
      "recordIndex": 0,
      "entityType": "UNIT",
      "tgmRecordId": 456,
      "erpRecordId": "EQ-12345",
      "errorCode": "VALIDATION_ERROR",
      "errorMessage": "Required field 'SerialNumber' is missing",
      "isRetryable": true
    },
    {
      "recordIndex": 1,
      "entityType": "UNIT",
      "tgmRecordId": 789,
      "erpRecordId": null,
      "errorCode": "NOT_FOUND",
      "errorMessage": "Equipment not found in ERP",
      "isRetryable": false
    }
  ],
  "durationFormatted": "15m 30s"
}

Retry a Failed Job

If a sync job failed, you can retry it:

curl -X POST http://localhost:1337/api/admin/erp/sync-jobs/123/retry \
  -H "Authorization: Bearer $JWT_TOKEN"

This creates a new sync job based on the failed job's configuration.


Webhooks

Overview

Configure webhooks to receive real-time notifications from your ERP when data changes.

Webhook URL

When you enable webhooks on a connection, TGM provides a webhook URL:

https://your-tgm-server.com/api/webhooks/erp/{connectionId}

For ERP-specific webhooks: - SAP: https://your-tgm-server.com/api/webhooks/erp/sap/{connectionId} - Dynamics: https://your-tgm-server.com/api/webhooks/erp/dynamics/{connectionId} - Oracle: https://your-tgm-server.com/api/webhooks/erp/oracle/{connectionId}

Webhook Security

TGM validates webhooks using:

  1. Webhook Secret: A shared secret in the X-Webhook-Secret header
  2. HMAC Signature: Validates payload integrity via X-Webhook-Signature header

The webhook secret is generated when you enable webhooks and can be retrieved from the connection settings.

Configuring SAP Webhooks

  1. In SAP, go to Event Mesh or Integration Suite
  2. Create an outbound webhook subscription
  3. Configure the TGM webhook URL
  4. Add the webhook secret header

Configuring Dynamics Webhooks

  1. In Dynamics 365, go to Settings > Service Endpoints
  2. Create a new webhook endpoint
  3. Enter the TGM webhook URL
  4. Configure authentication (validation token supported)

Configuring Oracle Webhooks

  1. In Oracle Integration Cloud, configure an outbound connection
  2. Set the webhook URL
  3. Configure the signature header for payload verification

ERP-Specific Configuration

SAP S/4HANA Configuration

{
  "name": "SAP S/4HANA Production",
  "erpType": "SAP_S4HANA",
  "authType": "OAUTH2",
  "baseUrl": "https://my-s4hana.example.com/sap/opu/odata4/sap",
  "clientId": "your-oauth-client-id",
  "clientSecret": "your-oauth-client-secret",
  "sapClient": "100",
  "sapSystemId": "PRD",
  "sapInstanceNumber": "00",
  "sapLanguage": "EN",
  "connectionSettings": {
    "oauthTokenUrl": "https://my-s4hana.example.com/sap/bc/sec/oauth2/token"
  }
}

Microsoft Dynamics 365 Business Central

{
  "name": "Dynamics 365 BC",
  "erpType": "DYNAMICS_365_BC",
  "authType": "OAUTH2",
  "dynamicsTenantId": "your-azure-tenant-id",
  "dynamicsEnvironment": "production",
  "dynamicsCompanyId": "your-company-guid",
  "clientId": "your-azure-app-client-id",
  "clientSecret": "your-azure-app-client-secret",
  "connectionSettings": {
    "apiVersion": "v2.0"
  }
}

Microsoft Dynamics 365 Finance & Operations

{
  "name": "Dynamics 365 F&O",
  "erpType": "DYNAMICS_365_FO",
  "authType": "OAUTH2",
  "dynamicsTenantId": "your-azure-tenant-id",
  "dynamicsEnvironment": "your-environment-name",
  "clientId": "your-azure-app-client-id",
  "clientSecret": "your-azure-app-client-secret",
  "connectionSettings": {
    "resource": "https://your-environment.operations.dynamics.com"
  }
}

Oracle Cloud ERP

{
  "name": "Oracle Cloud ERP",
  "erpType": "ORACLE_CLOUD",
  "authType": "OAUTH2",
  "oracleInstanceUrl": "https://your-instance.fa.us2.oraclecloud.com",
  "oracleIdentityDomain": "your-identity-domain",
  "clientId": "your-oracle-client-id",
  "clientSecret": "your-oracle-client-secret",
  "connectionSettings": {
    "apiVersion": "v1"
  }
}

Oracle NetSuite

{
  "name": "NetSuite Production",
  "erpType": "ORACLE_NETSUITE",
  "authType": "OAUTH2",
  "baseUrl": "https://your-account-id.suitetalk.api.netsuite.com",
  "connectionSettings": {
    "accountId": "your-account-id",
    "consumerKey": "your-consumer-key",
    "consumerSecret": "your-consumer-secret",
    "tokenId": "your-token-id",
    "tokenSecret": "your-token-secret"
  }
}

Troubleshooting

Common Issues

Connection Test Fails

  1. Check credentials: Verify client ID, secret, and other auth settings
  2. Check network: Ensure TGM server can reach the ERP endpoint
  3. Check permissions: Verify the ERP user/app has required API access

Sync Job Stuck in Running State

Jobs running longer than 2 hours are automatically marked as stale. You can:

  1. Cancel the job manually: POST /api/admin/erp/sync-jobs/{id}/cancel
  2. Check for locks in the ERP system
  3. Review error logs for API timeouts

Webhook Not Received

  1. Verify webhook URL is accessible from the ERP
  2. Check webhook secret matches
  3. Review ERP webhook delivery logs
  4. Check TGM application logs for incoming requests

Data Mismatch After Sync

  1. Review field mappings for incorrect transformations
  2. Check conflict resolution strategy
  3. Verify sync direction settings
  4. Review the sync job error details

Viewing Logs

Application logs include sync details:

grep "ERP" logs/application.log
grep "ErpSync" logs/application.log

Sync Statistics

Get detailed sync statistics:

curl http://localhost:1337/api/admin/erp/connections/1/sync/statistics \
  -H "Authorization: Bearer $JWT_TOKEN"

Response:

{
  "connectionId": 1,
  "connectionName": "Production SAP",
  "lastFullSync": "2024-01-14T00:00:00",
  "lastIncrementalSync": "2024-01-15T09:00:00",
  "syncedRecordsByEntity": {
    "UNIT": 1250,
    "WORK_ORDER": 890,
    "COMPANY": 45
  },
  "recentFailures": 3,
  "lastJobStatus": "COMPLETED",
  "lastJobSuccessCount": 150,
  "lastJobErrorCount": 2
}


Security Considerations

  1. Credentials are encrypted at rest using AES-256
  2. Use OAuth2 where possible instead of basic auth
  3. Rotate secrets periodically
  4. Limit API permissions in the ERP to only required operations
  5. Enable audit logging for all sync operations
  6. Use webhooks over HTTPS only
  7. Validate webhook signatures to prevent spoofing

Best Practices

  1. Start with INBOUND sync to import data from ERP first
  2. Test with a subset before running full syncs
  3. Configure appropriate batch sizes based on ERP API limits
  4. Set up monitoring for failed sync jobs
  5. Use incremental syncs for regular synchronization
  6. Schedule full syncs during off-peak hours
  7. Document field mappings for maintenance
  8. Review conflict resolution strategy for each entity type

Support

For additional help: - Review the API documentation at /swagger-ui.html - Check application logs for detailed error messages - Contact your ERP administrator for API access issues