A Mumbai-based enterprise solutions company needed to bridge the gap between their field sales teams and their SAP Business One ERP system. We designed and built a custom field sales CRM with deep SAP B1 Service Layer integration — enabling real-time customer data sync, automated document generation, and seamless sales order and invoice management directly from a mobile application.
The core challenge was not just connecting two systems, but doing it reliably at scale with complex business logic, live field usage, and zero tolerance for data inconsistency.
Industry: Construction · Stack: Java · Spring Boot · React Native · MySQL · AWS EC2 · Docker · Integration: SAP Business One Service Layer (OData APIs)
Field sales teams were operating in isolation from the company's SAP Business One ERP. Every customer visit, sales order, and invoice involved manual re-entry of data — creating delays, duplicate records, and a fragmented view of customer accounts.
Sales reps had no visibility into customer outstanding invoices, order history, or account status when visiting clients on site.
Sales orders created in the field had to be manually keyed into SAP by back-office staff — introducing delays and the risk of errors.
Invoice PDFs had to be generated separately and shared manually — a time-consuming process that slowed down collections and client communication.
Sales managers had no real-time picture of field activity or pipeline status — decisions were made on stale data days after the fact.
There was no single source of truth between the CRM and the ERP — duplicate records and mismatched data were a constant operational drag.
SAP Business One Service Layer integration looks straightforward on the surface but hides significant complexity in production. Here is what we encountered and how we solved each challenge.
SAP B1 OData pagination behaves differently from standard REST — $skip and $top interact with server-side session state. We built a paginated fetching engine in Spring Boot using cursor-based pagination with an application-level cache refreshed on a configurable schedule.
SAP B1 uses series-based numbering per document type with prefixes and sequences spread across multiple endpoints. We built a series cache that fetches configuration at startup, maps by document type, and applies the correct prefix logic when generating document numbers.
SAP B1 provides data but not presentation. We implemented a pipeline using OpenHTMLToPDF with Thymeleaf HTML templates — SAP data is fetched, mapped to a document model, rendered to HTML, and converted to PDF. CSS running() patterns handle consistent headers and footers across multi-page documents.
Fetching SAP lookup entities on every request was too slow and created unnecessary load. We built a structured lookup cache layer that preloads at startup, serves from memory at runtime, and exposes a manual refresh endpoint for administrators when master data changes.
SAP's BP object is complex — nested address lines, multiple contact person structures, strict field validation. We reverse-engineered the BP object through the Service Layer metadata endpoint, built a strict field mapping layer with validation before any write, and validated against a SAP sandbox before going live.
SAP Service Layer uses session-based auth with tokens that expire — unlike standard OAuth refresh flows, re-login adds latency if not handled proactively. We built a session manager that tracks session age, proactively refreshes before expiry, and implements automatic retry logic for requests that fail due to timeout.
Manual re-entry between the field CRM and SAP Business One was completely eliminated — data flows automatically, bidirectionally, with no back-office intervention.
Field sales reps gained real-time visibility into customer accounts, outstanding invoices, and order history — directly from their mobile devices, before and during client visits.
Invoices and sales order documents are now generated automatically — branded, print-ready PDFs produced directly from live SAP data, on demand, from the mobile app.
CRM and SAP now share a single source of truth — no duplicate records, no mismatched data, no reconciliation overhead between field and back office.
Sales managers gained a live view of field team activity and order pipeline — no more waiting days for data that was already happening in the field.