Forex Applet
Watch these as presentations — 2 on this page, slides with narration.
Keep the exchange rates your foreign-currency documents copy from. Picking a pair on a document copies the newest recorded rate once, whatever the document’s date, and never re-reads it, so record the day’s rate before anyone raises documents. Nothing here posts, and the product has no period-end revaluation run.
Overview
The Forex Applet is where a finance administrator defines the currency pairs a tenant trades in and records the exchange rates for them, one dated row at a time. Each pair is a Forex Data Source (for example base MYR → foreign USD), and each dated row in its History Data holds a sell rate, a buy rate and a computed mid rate. Document applets — purchase orders, purchase and sales invoices, GRNs, credit notes, receipt vouchers and claim lines — show a Forex Data Source selector when their SHOW_FOREX_DATA_SOURCE setting is on; picking a source sets the document currency and copies the latest recorded rate into the document’s Currency Rate.
The applet stores rates; it does not post anything. Forex gain and loss journals, base-currency “shadow” documents and the non-zero-rate check at FINAL all live in the document applets and the backend, and are only summarised here.
A second menu item, Forex Live, charts rates from a third-party market feed for reference. It does not write to the tenant.
Where it fits
| Direction | Applet / data | Why |
|---|---|---|
| Upstream | Tenant currency master | The Currency Base and Currency Foreign drop-downs list the tenant’s currencies, ordered by short name. A currency that is not in the master cannot be used in a pair. |
| Upstream | Organisation Applet | Each company’s base currency decides which data sources a document can pick: the selector only lists sources whose Currency Base equals the document’s base currency. |
| Downstream | Purchase Order (Internal), Purchase Invoice (Internal), Purchase Invoice No Stock In (Internal), Purchase GRN (Internal), Purchase GRN Stock In (Internal), Purchase Credit Note (Internal) | Purchase-side documents embed the shared Forex Data Source drop-down: selecting a source copies the latest sell rate into Currency Rate and records the source on the document header. |
| Downstream | Sales Invoice (Internal), Receipt Voucher (Internal) | Sales-side documents embed the same drop-down on its sales side: the latest buy rate is copied. |
| Downstream | Claim Applet | Foreign-currency claim lines record the source, and the backend checks that it still exists. |
| Downstream | Ledger And Journal, Chart of Account | Realised gain/loss on settlement is posted to the company’s FOREX_GAIN / FOREX_LOSS default GL codes, not by this applet. It is written by the backend, inside the knock-off request; a second route — a gain/loss posting on the twin’s Finalise fan-out — exists but is not switched on by default. There is no period-end revaluation and no unrealised gain/loss run anywhere in the product. |
Screens and menus
The applet has two menu items:
| Menu item | What it shows |
|---|---|
| Forex Data Source | The listing of currency pairs. Columns: Code, Name, Currency Base, Currency Foreign, Created Date, Created By, Updated Date, Updated By. Keyword search covers code, name, base and foreign currency (minimum three characters); the advanced search adds a Create Date range. Only ACTIVE rows are listed, newest update first, 50 per page. |
| Forex Live | A reference chart pulled from a third-party feed for a chosen base/foreign pair and timeframe (1 week to 5 years). Nothing on this screen is saved. |
From the listing:
- Create Forex — a single Main tab with Code, Name, Descriptions, Currency Base and Currency Foreign. RESET clears the form; CREATE is enabled once the four required fields are filled.
- View Forex — opens when you click a row. Three tabs:
- Details — Code, Name, Descriptions, Currency Base, Currency Foreign plus Created By / Creation Date / Updated By / Updated Date, and a DELETE button that needs a second click within three seconds to confirm. There is no Save on this tab: the Name and Descriptions boxes accept typing but nothing persists it.
- Chart — a Date Txn from/to pair (both default to today) and SEARCH; plots Sell, Buy and Mid rate from the History Data rows in that range.
- History Data — the rate rows for this pair: Date, Sell Rate, Buy Rate, Middle Rate, and a delete action per row (with a confirmation dialog). Above the grid: Date Txn (defaults to today), Sell Rate, Buy Rate, a search button that fills the two rates from the third-party feed, and an add button that saves the row.
Settings (gear icon) offers Field Settings, Default Selection, Webhook, the five shared permission screens and Release Notes; Personalisation offers Default Selection and Sidebar. See Configuration for what these do.
Configuration
Before you can use it
| Prerequisite | Where | Why it matters |
|---|---|---|
| Both currencies of the pair exist in the tenant currency master | Tenant currency list | Currency Base and Currency Foreign are pick-lists, not free text. |
| The company’s base currency is set | Organisation Applet — company Details | The document selector lists only data sources whose Currency Base equals the document’s base currency. A source whose base is not the company currency never appears on that company’s documents. |
SHOW_FOREX_DATA_SOURCE switched on in each document applet that should use the rates | That applet’s Settings › Application Settings › Main Details › Doc Settings (shared screen) | Off by default. Without it the document shows the plain Currency / Currency Rate pair and never reads this applet. |
FOREX_GAIN and FOREX_LOSS company default GL codes | Chart of Account | Needed by the document applets when a foreign-currency document is settled; not read by this applet. |
| API permissions | Permission Set / Role screens under this applet’s Settings, or Tenant Admin | Creating a pair needs API_BL_FI_FOREX_DATA_SOURCE_HDR_CREATE; adding a rate row needs BL_FI_FOREX_DATA_SOURCE_HISTORY_CREATE; see Feature visibility / permissions. |
Applet settings
This applet has no working setting. Its settings screens are its own, and none of them saves anything.
What the visible settings screens actually do, so you can stop looking for a switch that is not there:
| Screen | Behaviour |
|---|---|
| Field Settings | Eight toggles (Unit Discount, SST/VAT/GST, WHT, Blanket Order, Segment, G/L Dimension, Profit Center, Project) wired to nothing, and a SAVE button that does nothing. |
| Default Selection | Default Branch / Default Location drop-downs. Changing either raises an error and SAVE saves nothing. Nothing is stored. |
| Personalisation › Default Selection | The same two controls. Nothing is stored. |
| Webhook, Sidebar, permission screens | Standard shared screens; the permission screens are functional but the applet defines no client-side permission codes (below). |
| Release Notes | Two entries: 1.00 (2023-08-05) and 1.01 (2024-07-06, “resolved wrong end point call”). |
Settings in other applets that control this applet’s use
These are the switches that decide whether a document reads the rates recorded here. They live in the Application Settings screen (Main Details › Doc Settings panel) of each document applet. Any user who can open that applet’s Settings can change them.
| Setting (in the document applet) | What it controls | Default | Effect when changed |
|---|---|---|---|
SHOW_FOREX_DATA_SOURCE | Renders the Forex Data Source drop-down on the document’s Main Details. The drop-down lists this applet’s ACTIVE sources whose Currency Base equals the document’s base currency, ordered by code, and on selection sets the document currency to the source’s foreign currency and fetches the newest History Data row — the buy rate on a sales document, the sell rate on a purchase document — into Currency Rate. | Off | Off: plain Currency + Currency Rate fields; the rate comes from the Refresh button (third-party live feed) or typing. On: the selector appears; a rate is only filled if the chosen source has at least one History Data row. |
CANNOT_EDIT_CURRENCY_RATE | Locks the Currency Rate box on the document. | Off | With SHOW_FOREX_DATA_SOURCE on, this makes the recorded rate the only way to set a rate; a source with no History Data rows then leaves the document at rate 0 (see Troubleshooting). |
HIDE_FOREX_HISTORY | Rendered only for the Sales Invoice applet and saved, but nothing reads it. | Unset | None. |
Document behaviour settings
Not applicable — this is a master-data applet. The document-side effects (shadow documents, non-zero rate at FINAL) are described under Lifecycle and effects.
Third-party rate feed
The search buttons on Create Forex and History Data, the Refresh button on document applets and the whole Forex Live screen call an external market-data provider from the browser. The feed is shared by every tenant; there is no tenant-level setting for the provider or the refresh frequency. History Data takes the provider’s Ask Price as Sell Rate and Bid Price as Buy Rate; Mid Rate is (sell + buy) / 2 computed client-side.
Feature visibility / permissions
- Client-side permissions: this applet has none, and checks no
SHOW_*/HIDE_*codes. The Client-Side Permission screen under Settings is therefore empty; nothing in this applet can be hidden per role. - Backend (API) permissions:
| Action | Permission code checked |
|---|---|
| List data sources | API_BL_FI_FOREX_DATA_SOURCE_HDR_READ (or _OWNER / _ADMIN) |
| Create / delete a data source | API_BL_FI_FOREX_DATA_SOURCE_HDR_CREATE / _DELETE |
| List rate rows | BL_FI_FOREX_DATA_SOURCE_HISTORY_READ (or _OWNER / _ADMIN) |
| Add / delete a rate row | BL_FI_FOREX_DATA_SOURCE_HISTORY_CREATE / _DELETE |
The data-source header permissions and the rate-row permissions belong to two different families; a role needs codes from both to maintain a pair end to end. A user with tenant Owner / Admin passes all of them.
Fields
Create Forex — Main tab
| Field | Meaning | Required | Notes / validation |
|---|---|---|---|
| Code | Short identifier of the pair, e.g. MYR-USD. Shown as the option text in every document drop-down. | Yes | Free text. No uniqueness check — two pairs can share a code. |
| Name | Descriptive name. | Yes | Free text. Not shown in the document drop-down, which shows the Code only — so make the Code self-explanatory. |
| Descriptions | Longer note. | No | Not shown back on View, and cannot be edited after create — the Details tab has no Save (see Troubleshooting). |
| Currency Base | The currency you hold — normally the company base currency. | Yes | Pick-list from the tenant currency master. Read-only after create. |
| Currency Foreign | The currency you are pricing. | Yes | Pick-list from the tenant currency master. Read-only after create. Documents that select this source switch their document currency to this value. |
The backend validates only its own system fields on create, not the business fields.
View Forex — Details tab
Code, Currency Base and Currency Foreign are read-only. Name and Descriptions render as editable inputs but there is no Save/Update control, so the header is effectively immutable after create; to change it, delete and re-create.
View Forex — History Data tab
| Field | Meaning | Required | Notes / validation |
|---|---|---|---|
| Date Txn | The date the rate applies to. | Yes (form default: today) | Date picker. Rows are listed newest first; documents read the newest row, whatever the document date. |
| Sell Rate | The rate copied into purchase-side documents (isSales = false). The feed’s Ask Price when filled by search. | Yes | Number; no range check. |
| Buy Rate | The rate copied into sales-side documents (isSales = true). The feed’s Bid Price when filled by search. | Yes | Number; no range check. |
| Middle Rate | (sell + buy) / 2, computed on add. | — | Not editable. Plotted on the Chart tab but never copied into a document — documents take the Sell or the Buy rate. |
| Search (magnifier) | Fills Sell Rate (Ask) and Buy Rate (Bid) for this pair from the third-party feed. | — | Leaves the row unsaved until you press add. |
| Add | Saves the row. | — | Disabled while Sell or Buy Rate is empty. The backend only checks that the pair exists. Several rows for the same date are allowed. |
Forex Live
Currency Base, Currency Foreign (both required, from the currency master) and Timeframe (default 1 Month). SEARCH queries the feed’s daily time series for the concatenated pair and charts the closing values for the chosen number of trading days.
Lifecycle and effects
This is master data: there are no DRAFT/FINAL statuses and no journal posting.
- Statuses. A data source and a rate row are created as
ACTIVE; the listings and the document drop-down showACTIVErows only. - Delete is a soft delete. DELETE on the Details tab (and the per-row delete on History Data) marks the row deleted; it stays in the table.
- Deleting a data source does not touch its rate rows. The history rows remain
ACTIVEbut are unreachable from the UI once the header is gone. - What documents store. Selecting a source records the pair on the document header — which pair, not which dated row; the rate itself is copied into the document’s Currency Rate at selection time and is not re-read later. Documents do not check that the source still exists, so deleting a source leaves existing documents untouched. Claim lines are the exception: a claim line whose source no longer exists is rejected.
- Backend checks at document FINAL (not in this applet). When document and base currency differ, FINAL rejects a blank or zero exchange rate — since 30 September 2026 up front, with Generic Document exchange rate is required before posting to FINAL (HTTP 403) on the ordinary finalise route, and otherwise in validation with
FOREX_DOC_REQUIRES_NON_ZERO_XRATE— “Exchange rate is required for a foreign currency document.” A tenant whoseDOCUMENTS_SKIP_SHADOW_AND_GLapplication setting is switched on (e-invoice-only tenants) gets no shadow and no posting at all at FINAL (since 28 September 2026). On FINAL of a forex document the backend creates a base-currency shadow document and links the two; a second FINAL on a document that already has a shadow is refused with “Generic Document has already been convert to shadow”. - The foreign-currency document does not post its own books — its twin does. FINAL saves the foreign-currency document without queuing any posting and queues the postings for the shadow instead. Everything the fan-out does — the journal, the stock ledger, the cash book, the points — is therefore posted from the twin, in company currency. Journal posting refuses a foreign-currency document outright, and so do the reversal and finance-charge routes.
- VOID follows the twin; undo-to-DRAFT does not. On VOID, the shadow is set to VOID, copies the void reason onto it, and queues the void primary — plus the e-invoice-queue and historical-aging removals — against the shadow, not against the document you voided. On undo-to-DRAFT the twin stays FINAL, and nothing ever clears the document’s link to its shadow. Re-finalising after an undo therefore still meets “Generic Document has already been convert to shadow”.
- Audit trail. The forex audit trail is written when a currency is created or changed, not by this applet.
Posting proof block: not applicable — the applet has no server document type, signums, GL precedence or stock processor. Gain/loss journals are described on the document applets’ pages and on Ledger And Journal.
Related applets
- Organisation Applet — sets each company’s base currency, which is the filter the document selector applies to your data sources.
- Chart of Account — holds the
FOREX_GAIN/FOREX_LOSSdefault GL codes the document applets post to on settlement. - Purchase Order (Internal), Purchase Invoice (Internal), Purchase Invoice No Stock In (Internal), Purchase GRN (Internal), Purchase GRN Stock In (Internal), Purchase Credit Note (Internal) — purchase documents that take the sell rate from a selected source.
- Sales Invoice (Internal), Receipt Voucher (Internal) — sales-side documents that take the buy rate.
- Claim Applet — foreign-currency claim lines reference a data source and the backend validates the reference.
- Ledger And Journal — where the forex gain/loss journals and the Missing Journal Forex Gain Loss check live.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| The document has no Forex Data Source drop-down, only Currency and Currency Rate. | SHOW_FOREX_DATA_SOURCE is off (default) in that document applet. | Open the document applet’s Settings › Application Settings › Main Details › Doc Settings, switch on Show Forex Data Source, save, reload the document screen. |
| The drop-down opens but lists nothing, although pairs exist. | The selector lists only ACTIVE sources whose Currency Base equals the document’s base currency. Pairs created with the foreign currency as base, or for another company’s currency, are excluded. | Create the pair with Currency Base = the company’s base currency (e.g. MYR base, USD foreign). |
Selecting a source changes the currency but leaves Currency Rate at 0; FINAL later fails with Generic Document exchange rate is required before posting to FINAL (or FOREX_DOC_REQUIRES_NON_ZERO_XRATE on a route without the up-front check). | The source has no History Data rows — the rate is only filled when at least one row exists. With CANNOT_EDIT_CURRENCY_RATE on there is no manual fallback. | Add a dated row on the pair’s History Data tab, then re-select the source (or type the rate if the box is editable). |
| The rate on the document is not the rate for the document date. | The drop-down always takes the newest row; it does not match the document’s transaction date. | Record the rate for the day before creating documents, or overwrite Currency Rate on the document. Back-dated documents need the rate typed in. |
| Changing the supplier switches the currency but the rate stays 0 until Refresh. | Supplier selection patches the currency through the store, which does not trigger the rate fetch (reported on Purchase Credit Note, fixed there in 2026-09 by auto-fetching on currency change and warning “live vs custom rate”). | Press Refresh, or select the forex source again; upgrade the applet where the fix has shipped. |
| Re-finalising a forex document after undoing it fails with “Generic Document has already been convert to shadow”. | Undo-to-DRAFT reverts the document and leaves its twin at FINAL, and nothing clears the link, so the document still points at a shadow. | Void the document and raise a new one. Undo-and-re-finalise is not a route back for a foreign-currency document. |
| The twin is bigger than the document when the foreign currency is the stronger one — or smaller when it is the weaker one. | The rate is stored the other way round from the one the twin is built with. The shadow is built by dividing every amount by the rate, so the stored rate has to be document-currency units per one unit of company currency; print, the e-invoice payload and the accounting export all treat the same rate as the direct rate instead, and until 28 September 2026 the document-import route inverted it per currency before finalising and restored it afterwards. Since then the document header carries a second rate field for the display rate: the standard ETL and the file imports fill it, nothing reads it yet (print and the e-invoice payload still send the stored rate), and the applets’ own save paths were not re-read here (P-1388; the column names are in this page’s sources). Because one route wrote the rate one way and another read it as its inverse, a single tenant can hold documents stored in both directions — never assume yours. | Before you rely on either, finalise one small document and compare the twin’s total with the document’s. If it is out by the square of the rate, the tenant is storing the other direction and every twin, journal and realised gain built from it is wrong by that factor. Raise it with your BigLedger contact rather than editing rates by hand. |
| A foreign-currency document was finalised and no journal, no stock movement and no cash book line ever appeared. | The fan-out runs on the twin, and the twin was never created — the rate was null or zero at FINAL — refused since 30 September 2026 on the ordinary finalise route, still possible through auto-final and other routes without that check — so the document was not treated as foreign-currency and took the ordinary branch; or the FINAL came through a route that does not build one; or the tenant has DOCUMENTS_SKIP_SHADOW_AND_GL switched on, which finalises with no twin and no posting by design. A finalised foreign-currency document with no shadow is the visible sign that this happened. | Check the Currency Rate on the document first; a zero or empty rate is the common cause and FOREX_DOC_REQUIRES_NON_ZERO_XRATE should have refused it. Then use Trace Document on the Financial Report applet to see which postings are missing. |
| The search button on History Data / Forex Live returns nothing, or the console shows an error from the feed. | The third-party provider is called from the browser and rate-limits; it returns an Error Message / Note body instead of data. Forex Live requests the provider’s daily stock time series with the two currency codes concatenated as the symbol; when the response carries no daily series the chart stays empty. | Type the rates manually on History Data. Treat Forex Live as best-effort reference only. |
| Descriptions is blank on View Forex although it was filled on create. | The view reads the field by the wrong name. | Cosmetic; the value is stored. Check it in the listing export or the API. |
| Edits to Name / Descriptions on View Forex disappear. | The Details tab has no Save. | Delete and re-create the pair. Documents that referenced the old pair keep it. |
| Two pairs with the same code appear in the document drop-down and cannot be told apart. | No uniqueness check on Code; the drop-down shows only the code. | Delete the duplicate (soft delete) and keep codes unique by convention, e.g. <BASE>-<FOREIGN>. |
| A pair was deleted but old documents still show a forex source, and a claim line save fails with forex_source_hdr_guid does not exist. | Generic documents keep the stored reference with no validation; claim lines are validated. | Re-create the pair and re-select it on the claim line. |
Related documentation
- Chart of Accounts setup guide — where the Forex Gain / Forex Loss default accounts are assigned.
- Financial Accounting module and Purchasing module.
- Applets and Workflows catalogue.