REDA One Help Center
EN
Language
English EN Español ES Português PT Italiano coming soon Français FR Deutsch coming soon العربية coming soon
reda.one ↗
Home / REDA Financials AI / API & Integration / Custom Development / Lightning Web Components

Lightning Web Components

Building custom UI around REDA Financials is ordinary LWC work — the objects are custom objects, the data services are the standard ones, and your components sit beside the package's on any Lightning page. The craft is in what you build against.

Data access from your components

  • Lightning Data Service first: lightning-record-form, the wire adapters and UI API all speak refin__ objects fluently — CRUD with layouts, FLS and validations handled for free.
  • Your Apex where logic lives: a controller that queries invoices, or calls refin.GlobalTaxService for live tax preview in your own quoting UI (see Apex Development).
  • Status changes from UI = posting: a button in your component that PATCHes status to 'Posted' via LDS runs the full engine — build your error handling around the DML message, which is user-ready text.

Composing with the package's pages

  • Record pages are open: drop your components onto the packaged record pages (or clone the flexipage and rearrange) — a custom "lease context" panel beside the invoice, a property card on the asset.
  • The forms extend without code: before writing a component to "add a field to the invoice form", check field sets — the packaged forms grow columns declaratively.
  • Navigation is standard: your components deep-link to any REDA record or list with the platform navigation service; the packaged screens do the same back.
Treat packaged components as pages, not parts. The package's LWCs (forms, workspaces, the Financial Center) are product surfaces — place them, don't program them. The stable programmatic surface is the data model + the global Apex API; your UI innovates around those, and upgrades never break you.

Patterns that earn their keep

  • Vertical context panels — your industry's data (property, project, case) rendered beside the financial document that references it.
  • Guided creation — a wizard that gathers your domain's inputs, then creates the draft document via LDS and hands the user to the standard form for the accounting half.
  • Read-only dashboards — wire-adapter queries over invoices/ledger with your visualization of choice, complementing the standard dashboards.

A worked component: Meridian's lease-quote tax preview

Meridian Properties Group's leasing team wanted tax-inclusive rent shown while negotiating, before any invoice exists. The component is a textbook REDA LWC: your UI, your controller, the package's engine. The controller assembles a request for refin.GlobalTaxService from the quote inputs:

refin.GlobalTaxService.TaxRequest req = new refin.GlobalTaxService.TaxRequest();
req.entityId        = quote.entityId;
req.accountId       = quote.tenantAccountId;
req.transactionDate = Date.today();
req.side            = 'Sales';

refin.GlobalTaxService.TaxLineRequest line = new refin.GlobalTaxService.TaxLineRequest();
line.lineKey   = 'rent-1';          // echoed back for correlation
line.amount    = quote.monthlyRent;
line.productId = quote.rentProductId;
req.lines      = new List<refin.GlobalTaxService.TaxLineRequest>{ line };

refin.GlobalTaxService.TaxResponse res = refin.GlobalTaxService.calculateTax(req);

The response carries totalTaxAmount and per-line results (rate, amount, resolved GL accounts), correlated back by lineKey. Because the contract performs no DML and never throws to the caller, the component checks res.success, shows res.errorMessage when false, and copies the values it needs into its own response shape for the wire. When the lease signs and the real invoice posts months later, the numbers match to the cent — one engine, two consumers.

The guard rails your UI inherits

Platform/package behaviorDesign consequence for your component
Posted documents are locked except whitelisted workflow fieldsDisable edit affordances when Status is Posted — the save would fail anyway, with the package's message
Posting = the Draft→Posted update, engine and guards includedYour "Post" button is one LDS update plus honest error display; never re-implement posting logic client-side
Unlicensed users are refused accounting writes with a verbatim messageSurface the message as-is — it already tells the user to contact their administrator
DML errors carry user-ready validation textYour toast can show the raw message; no error-code translation table needed
Field sets drive the packaged formsMatch them: build your line editors from the same field-set describes so your UI and the packaged form never disagree about columns

Common mistakes to avoid

MistakeWhy it hurtsDo this instead
Rebuilding the invoice form because it "needs one more field"Weeks of work duplicating a maintained product surfaceField sets add the field in minutes; build components for what field sets can't do
Computing tax client-side "for responsiveness"Your JavaScript and the posting engine will disagree eventually — in front of a customerCall GlobalTaxService through your controller; cache in the component if needed
Writing refin__Accounting_Transaction__c from a controllerHand-forged ledger rows are exactly what the guards exist to stopCreate documents and post them; the ledger writes itself
Assuming packaged components are embeddable in your DOMTheir exposure targets and internals aren't a documented contractCompose at the Lightning-page level; treat packaged LWCs as product surfaces
Testing only as an adminReal users hit FLS, permission sets and the licence seat — your component's error paths never got exercisedTest as a user holding exactly the packaged permission set your audience will have

Where to go next

  1. FieldSet Extensibility — the no-code alternative to check first.
  2. Apex Development on REDA — the logic layer.
  3. Salesforce Flows Integration — declarative middle ground.
Official Salesforce documentation Lightning Web Components are a standard Salesforce framework — the authoritative reference is the Lightning Web Components Developer Guide. Links open in a new tab.

Frequently asked questions

Compose at the page level (Lightning App Builder regions) rather than nesting programmatically. Exposed targets govern where packaged components can be placed; treat their internals as private.

Prefer LDS/UI API (enforcement built in); in custom Apex controllers use USER_MODE queries. The package uses USER_MODE for the reads that serve a user and SYSTEM_MODE where the engine must see the whole picture regardless of the running user's access — posting, sequencing, roll-ups. In your own UI code, default to USER_MODE and reach for SYSTEM_MODE only where you can say why.

Yes. No packaged permission set grants class access to refin.GlobalTaxService (only PDFGeneratorAPI and EInvoiceTrailCreator are granted, because packaged Flow actions call them), so the running user needs it granted explicitly. Verify with the real permission set in a sandbox; the failure mode is loud and immediate.

If you built against the stable surface — refin__ objects via LDS/UI API, the global Apex classes, page-level composition — yes, by the managed-package contract. What breaks is depending on packaged component internals or public classes, which is why this article keeps steering you away from both.

Verbatim. The guard messages are written as user-facing sentences ("This document requires approval before posting." and kin) — a toast showing the raw DML message is genuinely the best UX, and it stays correct as the package evolves its rules.

Was this article helpful?