See where your customers are. See where sales happen.

Your ERP system knows the customers, orders, and revenue — but it has no map. This integration pulls that business data (read-only, opt-in) from the ERP middleware's existing REST API, geocodes the textual addresses using the platform's built-in offline geocoder, and renders customers, orders, and sales density alongside the rest of your geospatial data. The spreadsheet becomes a map.

Customers → pointsOrders → markersSales heat Read-onlyOffline geocodeDPAPI-encrypted JWT
No coordinates? No problem.

The ERP has addresses, not lat/lon

ERP customer and order records carry textual addresses (street, city, postal code), not coordinates. The integration reuses the platform's existing offline GeocoderService (OpenAddresses over DuckDB + a Nominatim cloud fallback) to turn those addresses into points — and caches every result so each address is geocoded exactly once.

  • Read-only — the GIS app pulls from the ERP middleware's JWT-gated REST API. It cannot write back or corrupt ERP sync state. A future write-back would go through the middleware's SyncController, never direct.
  • Geocode cache — a GPKG sidecar stores every geocoded address (SHA-256 keyed), so re-pulls are instant. Operator-triggered "re-geocode" invalidates the cache scope.
  • Profile-based — connection profiles (base URL + JWT + API version) are stored with DPAPI-encrypted JWTs, the same pattern as the AWS/Azure credential stores.
/api/erp
# geocoded customers as GeoJSON
GET /api/erp/{profileId}/customers/geo?max=500

→ { "type":"FeatureCollection",
    "features":[
      { "type":"Feature",
        "geometry":{ "type":"Point",
          "coordinates":[-77.04,38.90] },
        "properties":{
          "name":"Acme Corp",
          "totalAmount":48250.00 } }, … ] }

# orders in a date window
GET /api/erp/{profileId}/orders/geo?from=&to=

# sales density (same payload, renderer-side heat)
GET /api/erp/{profileId}/sales/heat
Business data meets geospatial data

One map, both worlds

Customer points and sales density render as GraphicsLayers alongside the imagery, vectors, 3D, and real-time feeds the platform already serves. The analyst's map and the business map become the same map.

📍

Customers

Cyan dots at each geocoded billing address, with popups carrying the full customer record and lifetime value.

🛒

Orders

Amber markers at shipping addresses, filterable by date window. The "where did sales happen this quarter" view.

🔥

Sales heat

The same orders payload, rendered as a density surface — where revenue concentrates, not just where individual orders land.

Opt-in via Erp:Enabled in appsettings.json (default off). The ERP middleware is a sibling .NET project (Dolibarr + Odoo connectors, Postgres/Redis/RabbitMQ); this integration is a read-only client of its existing API — no ERP-side changes.

Stop reading the spreadsheet. Start reading the map.

Business data, geospatial context — one picture. Pair with data charts and database connectors.

Get Started