Skip to main content
LR Services Business Central

Practice 02

We build Business Central modules.

When the standard application does not match how your business actually runs, the fix is a properly built extension, not a spreadsheet somebody maintains on the side. We write AL to AppSource standards, source controlled and upgrade safe, and we document it so you are not locked to us. Several of our team are full stack developers as well, so when the answer belongs outside the ERP we build that too, front end through deployment.

Extensions, never base object changes AppSource technical standards Full stack, front end to deployment Source, repo and docs handed over
Custom modules docking onto a Business Central core A central Business Central platform block with four separately built extension modules connected to it by data lines, one of them highlighted. Business Central BASE APPLICATION AL extension UPGRADE SAFE AppSource app VALIDATED BUILD Integration / API LOGGED + RETRIED Customer portal NO BC LICENSE Built as extensions, not modifications

Our position

Custom code is a liability unless it is built like a product

Most of the bad customization we inherit was not badly intentioned. It was written fast, against a deadline, by someone who was not coming back. Base objects modified directly. No source control. No documentation. Business logic hidden in a page trigger where nobody would think to look. It worked, and then an update wave arrived.

We treat every build as something that has to survive people leaving. That means extensions rather than base modifications, source control from the first commit, meaningful test coverage on the logic that touches money or stock, and documentation written for the next consultant rather than for the invoice. The result is code you own and can hand to anybody.

The standard we build to

  • Extensions only. We do not modify base objects.
  • Source control from the first commit.
  • Test coverage on anything that touches money or stock.
  • Documentation written for the next consultant, not for the invoice.

Inside Business Central

Module building inside Business Central

The largest share of the work. Functionality your operation needs, added to Business Central in a way that is still there, still working and still yours after the next update wave.

AL extensions

Functionality your operation needs and the base product does not have. Custom document types, industry specific posting behavior, approval flows, pricing and rebate logic, planning and scheduling additions.

Built the way the platform intends: table and page extensions, event subscribers and interfaces, so our code attaches to the base application rather than living inside it.

Upgrade safe

Per-tenant customizations

Where the requirement is genuinely yours alone, the module is built and installed against your tenant only, with no route to AppSource and no reason to take one. It is the shortest path from a specific business rule to working software.

Shorter does not mean looser. A per-tenant customization still gets an app identity, versioning, source control and documentation, because the alternative is the untraceable code we spend half our rescue work unpicking.

Your tenant only

AppSource-standard apps

Where the requirement is a product rather than a one-off, we build to AppSource technical standards: the validation requirements, translation handling, permission set structure, dependency declarations and the upgrade codeunits that carry data between versions.

Publish it or keep it private, the quality bar is the same. Plenty of clients never list an app and still want it built to the standard, because that standard is mostly a list of things that hurt later if you skip them.

Validation ready

Why extensions beat modifying the base application

In the Dynamics NAV years, changing Microsoft's own objects was normal, and often it was the only route available. Business Central closed that door deliberately, and the reason is worth understanding rather than taking on faith.

Code that lives inside Microsoft's objects has to be merged by hand every time Microsoft changes those objects. That is twice a year, on a schedule you do not control, and each merge is harder than the last because your changes and theirs keep accumulating against each other. Companies end up postponing updates, then postponing them again, and the gap turns a routine release into a migration project.

An extension sits outside the base application and attaches to it through published events and extension objects. Microsoft can rewrite the object underneath and your code still holds the same event, because an event is a contract rather than a line number. That is the entire argument, and it is not a matter of coding taste. It is the difference between an update wave being an afternoon and an update wave being a project.

Ahead of a wave Microsoft ships preview environments before each release. We compile your extensions against them, so anything that is going to break is found weeks early and in a sandbox.
Deprecations Removals and obsoletions are published a wave or more in advance. We track that list against your specific extensions rather than waiting to be surprised by it.
Usual outcome A recompile, a handful of obsoleted calls swapped for their replacements, and a test run. Not a rewrite, and not a renegotiation.
When it does break It breaks in a sandbox on your timetable instead of in production on Microsoft's. That is the whole benefit you are buying with upgrade-safe development.
What you keep Version history for every extension, so any wave can be traced back to exactly which code changed and why.

Beyond Business Central

Full stack development beyond the ERP

Several of our team members are full stack developers. That single fact changes what we can be asked for, because not every problem belongs inside Business Central and pretending otherwise produces bad software.

An ERP is a superb system of record and a poor place to put a screen for a driver, a warehouse operator or a customer who does not work for you. Push those jobs into BC anyway and you end up licensing people who touch the system twice a week, training staff on an interface built for accountants, and writing extensions that fight the platform.

So we build the application instead, as a complete piece of software: the interface people use, the logic and data behind it, the connection back to Business Central, and the hosting that keeps it running. One team owns the whole path, which matters because the hard part of these projects is almost always the seam between the web application and the ERP, and a seam has no owner when two suppliers meet at it.

The same standards carry across from the Business Central side. Source control from the first commit, tests on anything touching money or stock, documentation written for whoever comes next, and the code handed to you at the end.

Front end The screens people actually use. Responsive down to a phone, keyboard accessible, and built to run on the hardware and browsers your staff already have rather than the ones we would prefer.
Back end Application logic, sign-in, roles and permissions, background jobs and scheduled work, plus the service layer that talks to Business Central and to anything else in the estate.
Database Schema design, indexing and migrations, and the decision that matters most: what gets stored outside BC, what gets read from it live, and which side owns each field.
Deployment Hosting, environments, a repeatable release process, backups, monitoring and logging. Software that nobody can deploy or watch is not finished software.
Handover The same terms as the BC work. Source, repository, documentation and a walkthrough, so another team could pick it up without calling us.

Customer and supplier portals

External-facing applications that read and write BC data. Customers check order status, download documents and place repeat orders. Suppliers confirm purchase orders, update delivery dates and submit invoices that arrive as a BC record instead of an email.

No BC license for each external user, and no exposure of the ERP itself. They see their own data through an interface built for them.

No per-user BC license

Internal web applications

A purpose-built screen for one job, used by people who should not have to learn the whole ERP to do it. Approval queues, data capture, review and exception handling, onboarding workflows.

Usually faster to adopt than an extension, because the interface carries one task rather than the entire application.

Built around one task

Shop floor and field interfaces

Mobile-friendly screens for people who are standing up. Large touch targets that work through a glove, scanner input handled as a first-class case, and capture that tolerates a weak signal and syncs when the connection comes back.

Designed for the environment rather than the demo. A warehouse is loud, bright and dirty, and the interface has to survive that.

Built for the environment

Dashboards and reporting front ends

A front end over BC data, and over whatever else the number depends on, so a manager gets the figure without opening the ERP or waiting for somebody to export it. Custom report layouts and Power BI models where those are the right answer, and a purpose-built screen where they are not.

Read paths are built so a heavy query does not slow down the people posting transactions.

Non-blocking extracts

Standalone tools that integrate with BC

Software that has its own life and its own users, and talks to Business Central at the points where it should. Quoting and product configurators, pricing tools, planning aids, inspection and compliance capture.

The tool runs where the work happens. BC receives the finished result as a proper record, posted through an interface rather than typed in twice.

Posts back into BC

Connections

Integrations and APIs

Almost nothing in a real business runs alone. Most of what looks like an ERP problem turns out to be a problem at the join between two systems that were never introduced properly.

Connecting BC to other systems

Warehouse and scanning systems, e-commerce platforms, EDI partners, payment gateways, CRM, banking, shop floor equipment, third party logistics and the vertical application your industry cannot operate without. Whatever the counterparty offers, from a modern REST API to a nightly file on an SFTP server, is what we build against.

Both directions

API design

Business Central's own API pages and OData endpoints where they fit, and purpose-built API pages where they do not. Where another system needs to consume ours, we design the contract first: versioned, documented, authenticated properly, and shaped around what the consumer actually needs rather than around a copy of your table structure.

Versioned and documented

Middleware and data sync

The layer that exists because two systems disagree about what a customer, an item or an order actually is. Field mapping, deduplication, conflict rules and a written decision about which side owns which field, settled before anybody writes code, because that argument is far cheaper to have on paper.

Ownership settled first

Webhooks and event-driven patterns

Push rather than poll, wherever the counterparty supports it. Business Central raises an event, a subscriber reacts, and the other system knows within seconds instead of at the next scheduled sweep. Work is queued on the way through, so a downstream outage delays a message rather than losing it.

Queued, not dropped
The part that decides whether an integration is any good

Every interface fails eventually. A certificate expires, a partner changes a field, a network drops mid-transfer. The question is never whether that happens, it is how quickly you find out and how much reconstruction it costs you.

So every integration we build carries structured logging of what was sent and received, retries with sensible backoff for the failures that are worth retrying, and an error queue a human being can actually open, read and reprocess from. Alerting goes to a person, not to a mailbox nobody watches. It is unglamorous work and it is the difference between a twenty minute problem and a lost week.

Method

How an engagement actually runs

The same six stages every time, whether the build is an AL extension that takes two weeks or a full application that takes two quarters. The sequence does not change, only how long each part of it lasts.

Scope and specification

We write down what it does before we write what it costs, including what it deliberately does not do and how we will both know it is finished. Scope creep is far easier to resist when the exclusions are in writing alongside the inclusions.

Design

Data model, interface and integration points, agreed before code. Anything with real user experience or an unresolved workflow question gets something clickable early, because it is much cheaper to argue with a prototype than with a finished module.

Iterative build

Delivered in slices into a sandbox you can log into, with a checkpoint at the end of each one. You see it working while it is being built rather than at the end, which is the only point at which feedback is still cheap. Code is reviewed internally before it reaches you.

Testing

Automated tests on the logic that touches money or stock, and a user acceptance pass run by your people against the written specification rather than against a demo script we control. Integrations get tested against failure, not only against success.

Deployment

A rehearsed release, into a sandbox first and then into production in a window you choose, with a rollback path decided before we start rather than improvised if it is needed. For full stack work this covers hosting, environments, backups and monitoring.

Handover and support

Source, documentation and a working walkthrough with your people or your partner. After that you either carry it yourself, which the handover is designed to make possible, or we support it under a retainer with named consultants who already know the code.

When the scope changes, and it will

Somewhere around the second or third checkpoint, someone sees the thing running and realises what they actually wanted. That is not a failure of scoping. It is what happens when an abstract requirement finally becomes a screen, and any process that pretends otherwise is selling you a fiction.

So we handle it openly instead. Anything outside the written specification is priced and scheduled as a change before it gets built, in writing, with the effect on the date stated plainly. Small items usually fold into the current phase when they do not move the finish line, and we will say so rather than raising paperwork for an hour of work. Larger ones become a second phase, and when a request is genuinely better dropped than built, we will tell you that too and accept the smaller invoice.

What we will not do is absorb changes quietly and present a surprise at the end, or let a date slip without saying why while it is still slipping.

Inside scope Built as agreed. If we underestimated it, that is our problem, not a change request wearing a disguise.
Small additions Absorbed into the current phase where they do not move the finish line, and flagged to you either way so nothing arrives unannounced.
Real changes Priced and scheduled in writing before any work starts, with the effect on the delivery date stated at the same time as the cost.
Large changes Split into a second phase rather than bolted onto the first, so the original build still lands and starts earning.
Bad ideas We say so. A request that will cost more to live with than to skip gets that argument put to you before it gets an estimate.

Terms

You own what we build

Bespoke work is yours: source code, repository access and documentation, delivered as part of the engagement rather than held back as leverage. We would rather earn the next project than hold the last one hostage. Where we reuse our own general purpose components, we say which ones and license them to you cleanly.

Source Full source for everything built under the engagement, AL extensions and application code alike, in your repository.
Repository Repository access and branching history, not a zipped drop at the end.
Documentation What it does, why it was built that way, and how to change it.
Walkthrough A working session with your people or your partner at handover.
Reused parts Our own general purpose components named up front and licensed to you cleanly.

Next step

Have a requirement that BC does not cover

Send the description, even a rough one. We will come back with whether it needs custom code at all, since a fair share of requests turn out to be configuration or an existing app on AppSource. If it does need building, you get an approach and a range.