Sales Force Automation
Overview
Sales Force Automation (SFA) is the register where a sales team records leads — a named contact at an organisation who might buy — and files each lead under a project, a source, a stage and a type so the pipeline can be listed and filtered. It also keeps an address book of contacts (people, with job position, e-mail, phone and address) that is separate from the customer master. Nothing in it is an accounting document: a lead never becomes an invoice by itself, and the applet posts no journal and moves no stock.
SFA registry row’s
es_module_url is bigledger/akaun-platform/sfa/prod/sfa-elements.js (queried 2026-09-15). Only the
older repository writes a file of that name: blg-applets-sfa’s production build script emits
sfa-elements.js (micro-fe/elements-build-scripts/sfa/sfa-applet-elements-build-prod.js L13) and
its publish script copies it to that prefix (micro-fe/bin/sfa/sales_force_automation_applet_publish_prod.sh
L15). The v2 repository’s production script targets the same prefix, but its build emits
sfa-applet-elements.js (micro-fe/elements-build-scripts/wavelet-erp/sfa-applet/sfa-applet-elements-build.js
L13) — a file the row never references. The bundle served at the row’s URL was last modified
2025-10-28, seven weeks before v2’s only commit (2025-12-19), carries the older build’s route prefix
applets/akaun/sfa and its Closed Won / Closed Lost strings, and none of v2’s. So the Applet
Store gives you the Dashboard, Leads, Deals, Import and Address Book of the older build; the
three-menu v2 described below is the rebuild in development. Until Q-0362 settles which build
leads, this page keeps v2 as its primary text and marks every place the older build differs.Two builds carry the name “Sales Force Automation”. The registry row is SFA (created
2022-03-16). The build documented on this page is the v2 rebuild
(blg-applet-wavelet-sfa-applet-v2, route prefix applet/tnt/wavelet/erp/sfa-applet), which at
commit bcd876a has three menus — Leads, AB Contacts, Organization — and four settings registers.
The older build (blg-applets-sfa, route prefix applets/akaun/sfa, 3,577 commits from
2019-06 to 2025-11) has a Dashboard, Deals with Closed Won / Closed Lost lists, a CSV lead
import, qualification criteria and lead-rating settings that v2 does not yet have. The SFA row
installs the older build (see the note above). Where the two builds differ, this page says so.
Where it fits
| Module | Digital CRM (primary); Sales & POS (supporting — the lead feeds a quotation, but only by a person re-keying it) |
| Reads | organisations from the CRM organisation register (bl_crm_organization_hdr, endpoint crm/organizations-hdrs); customers from Customer Maintenance inside the copied stock-reservation screens |
| Writes | bl_sfa_sales_lead_hdr + bl_sfa_sales_lead_event, bl_sfa_contact_hdr, bl_sfa_project_hdr, bl_sfa_source_hdr, bl_sfa_stage_hdr, bl_sfa_type_hdr; the Organization menu writes bl_inv_stock_reservation_hdr (see below) |
| Downstream | none automatic. The old build’s CSV import can create Unified Contact Center outbound tasks per lead; v2 has no import screen |
| Shared package | sales groups (bl_sfa_sales_group_hdr) live in the same sfa backend package but are the Commission Scheme applet’s — this applet has no screen for them |
Screens and menus
Route prefix applet/tnt/wavelet/erp/sfa-applet; the applet opens on Leads.
| Menu | Screens (view-column titles) | What it does |
|---|---|---|
| Leads | Leads Listing, Leads Create, plus the Select Organization and Select AB Contact pickers | Grid of leads (Org Name, Contact Name, Type, Lead Source, Probability, Priority, Stage, Date Created, Date Updated) with advanced search and column toggle; a Create form. There is no lead edit screen in v2 — the edit view-column is commented out in leads-pages.service.ts, so clicking a row selects it and opens nothing. |
| AB Contacts | AB Contact Listing (card view), AB Contact Edit | Create makes a temporary contact row (sfa-contact-hdr/temp) and opens it in the edit form; Save updates it, Delete removes it. |
| Organization | Stock Reservation Listing, Stock Reservation Edit, Stock Reservation Customer Listing, Stock Reservation Add Item, Stock Reservation Line Item Listing | Not an organisation register. The menu item routes to StockReservationContainerComponent: a copy of the Stock Reservation applet’s screens, writing bl_inv_stock_reservation_hdr and bin reservations through the same services. The organisation register that the lead form’s Organization picker reads is only reachable from that picker. |
| Settings | Default Selection · Projects · SFA Source · SFA Stage · SFA Type · Field Settings · Webhook · Feature Visibility · permission listings | See Configuration. The Application Settings entry is commented out of the menu. |
| Personalization | Field Settings · Default Selection · Sidebar | Per-user copies of the default-branch settings and the shared sidebar/column-layout preferences. |
The older build (blg-applets-sfa) adds: Dashboard (lead and deal counts by project, source and
stage, filtered by project and date range; Notifications and Sessions tabs), Deals with
Closed Won and Closed Lost listings (a deal carries organisation, project, deal source /
stage / type / rating, contact, description and duration; closing a deal fills in a template
message), Import (a CSV of leads, tab Upload then Details), Address Book, and settings
for Qualification Criteria and Qualification Criteria Sets, Product Services (template
messages), Lead Settings (ratings with a probability, sources, stages, types) and Deal Settings.
No screenshots are published for this applet: none exist under static/images/, and no image was
captured for this page.
Configuration
Before you can use it
- Projects, sources, stages, types — the lead form’s Project, Lead Type and Lead Stage drop-downs are required, and they are empty until the four settings registers below have rows. Create at least one of each before the first lead.
- Organisations — the Organization drop-down on the lead form is required and lists
bl_crm_organization_hdrrows. In v2 the only way to create one is the Select Organization picker inside the lead form; the “Organization” menu does not manage them. - Lead ratings — the Lead Rating drop-down reads
bl_sfa_rating_hdrfiltered by the chosen project. v2 has no screen to create ratings; they come from the older build’s Lead Settings or the API. - Company, branch, location — only needed for the copied stock-reservation screens, which take them from the Default Selection settings; see Organization.
- Permissions — the applet loads the client-side permission codes attached to the user’s teams
for this applet at start-up (
app.component.ts); the permission listings under Settings are the shared platform screens.
Applet settings
Settings live in the applet-local Default Selection screen (tenant-wide, saved through
saveMasterSettingsInit) and its personal twin under Personalization
(savePersonalSettingsInit). Field Settings is the shared FieldConfigurationComponent from
blg-shared-utilities; the applet’s own settings-container/field-configuration component exists
but is not routed. Anyone with access to the Settings menu can change the tenant-wide values.
| Setting | What it controls | Default | Effect when changed |
|---|---|---|---|
Default Branch (DEFAULT_BRANCH) | Declared, rendered and saved; choosing a branch also fills Default Company and Default Location from the branch’s MAIN_LOCATION | empty | No consumer found — no lead, contact or stock-reservation component in the applet reads these three keys (grep of the v2 source at bcd876a). Saving them has no visible effect. |
Default Location (DEFAULT_LOCATION) | as above | empty | as above |
Default Company (DEFAULT_COMPANY) | as above | empty | as above |
The settings model (applet-settings.model.ts) also declares the full sales-document family
(INCLUDE_*, ENABLE_*, HIDE_UNIT_PRICE_*, PRINTABLE, custom-status toggles) copied from
the document-applet template. None of those keys is rendered by any settings screen in this
applet and none is read; they are not documented as settings.
Keys read at runtime without a settings screen of their own: DEFAULT_TOGGLE_COLUMN
(SINGLE / DOUBLE), DEFAULT_ORIENTATION and VERTICAL_ORIENTATION — personal layout
preferences written by the grid-toggle control on each settings listing and read back by the
Projects / SFA Source / SFA Stage / SFA Type containers to decide one- or two-column layout.
The four settings registers
Each register is a listing (Code, Name, Status, Created Date, Modified Date) with a create and an
edit form of three fields — Code, Name, Description — none of which is required by the form.
The backend rejects a duplicate code on create and on update
(SFA_PROJECT_HDR_OBJECT_CODE_ALREADY_EXISTS, SFA_SOURCE_HDR_OBJECT_CODE_ALREADY_EXISTS,
SFA_STAGE_HDR_OBJECT_CODE_ALREADY_EXISTS, SFA_TYPE_HDR_OBJECT_CODE_ALREADY_EXISTS).
| Register | Table | What it is for on a lead |
|---|---|---|
| Projects | bl_sfa_project_hdr | The campaign or sales programme a lead belongs to; ratings are filtered by project |
| SFA Source | bl_sfa_source_hdr | Where the lead came from (the Lead Source column) |
| SFA Stage | bl_sfa_stage_hdr | Where the lead is in the pipeline (the Stage column); stages are a free list, with no ordering, no “won” or “lost” marker and no transition rule |
| SFA Type | bl_sfa_type_hdr | A free classification (the Type column) |
Document behaviour settings
Not applicable — the applet has no document type (see Lifecycle and effects).
Settings in other applets that control this applet
No exposed control found (routes and settings components checked at commit bcd876a; the
copied stock-reservation screens read the printable-format key
STOCK_RESERVATION_APPLET_EXT_CODE_PRINTABLE_FORMAT_GUID_STOCK_RESERVATION, which belongs to the
Stock Reservation applet).
Feature visibility / permissions
Feature Visibility and Webhook under Settings are the shared platform components; the applet
defines no feature-visibility key and no applet-specific client-side permission constant of its
own (grep of the v2 source for perm_code and upper-case constants at bcd876a finds only the
generic loader in app.component.ts). Server-side, every SFA endpoint is gated by the
API_TNT_DM_SFA_*_READ / _WRITE permissions of the TntSfaPermissions enum. No client-side
permission definitions are registered for this applet (0 rows in bl_applet_client_side_perm_dfn
for SFA, queried 2026-09-15) — the registry and both builds agree.
Fields
Lead — Create (tab Details)
| Field | Meaning | Required | Notes / validation |
|---|---|---|---|
| Title | Short name of the opportunity | Yes | bl_sfa_sales_lead_hdr.title |
| Project | Settings › Projects row | Yes | project_guid |
| Organization | CRM organisation | Yes | organization_guid; picker opens Select Organization |
| Lead Type | Settings › SFA Type row | Yes (control marked required) | type_guid |
| Lead Source | Settings › SFA Source row | No | source_guid |
| Lead Stage | Settings › SFA Stage row | Yes (control marked required) | stage_guid |
| Contact Name | The person | Yes | saved to name |
| Work Phone | Yes | saved to phone | |
| Work Email | Yes | pattern local@domain.tld; saved to email | |
| Contact Type | Free text | Yes (form) | Not saved — collected by the form but never copied to the model |
| Customer | Free text | Yes (form) | Not saved — same |
| Sales Agent | Drop-down | Yes (form) | Not saved, and the list shown is the Lead Type list (the template comment says “to add sales agent array”) |
| Lead Rating | bl_sfa_rating_hdr for the project | No | choosing one copies its probability into Probability |
| Probability | 0–100 | Yes | numeric(70,22) |
| Lead Category (Celebration) | Drop-down | Yes (form) | Not saved; the list shown is the Projects list (template comment “replace newProject with LeadCategory array”). The label is a leftover from a vertical build. |
| Priority | Integer | Yes | priority |
| Remarks | No | saved to description | |
| Target Start / End Date, Last / Next Follow Up Date | No | four timestamp columns |
Save (POST sfa/sales-leads) also writes one bl_sfa_sales_lead_event row with event_code = SALES_LEAD_CREATED and sets both reporter and assignee to the current user. The table has
columns the form never touches — firstname, lastname, dob, gender, nationality,
company_name, contact_hdr_guid, entity_hdr_guid, email_optp — that the older build’s
import fills.
AB Contact — Edit (created as a temporary row first)
| Field | Meaning | Required | Notes / validation |
|---|---|---|---|
| Full Name | Yes | bl_sfa_contact_hdr.full_name | |
| Yes | Angular e-mail validator | ||
| Job Position | No | job_description | |
| Organization | Name and guid of a CRM organisation | No | organization_guid |
| Phone, Mobile | No | ||
| Tax Id | No | ||
| Address (street, city, state, zip, country) | No | country defaults to Malaysia | |
| Contact type | Fixed Individual in the form | — | contact_type; the listing’s Type column shows id_type, a different column |
Listing cards show Name, Type, Job Description, Email, Phone, Status.
Stock reservation (Organization menu)
Listing columns: Doc No, Item Name, Branch, Location, UOM, Reserved Qty, Status. The forms are the Stock Reservation applet’s and are documented on its page.
Lifecycle and effects
No server document type, no journal, no stock. ServerDocTypes, GenericDocumentTypeHandler
and JournalPostingTypeHandler contain no SFA, SALES_LEAD, LEAD, DEAL or OPPORTUNITY
entry (grep of blg-akaun-platform-java at 45edc03526). A lead is a master-data row under
sfa/sales-leads (POST, PUT, DELETE /{guid}, GET, GET /query, GET /listing/query),
validated by SfaSalesLeadHdrDataConsistencyObject: guid, created/updated subject, dates,
status and revision must be present; there is no uniqueness rule on title, e-mail or phone,
so the same person can be entered as many leads.
| Effect | Where |
|---|---|
status on a lead, contact, project, source, stage or type is a free string set by the client; the only backend rule is “not null” | the six *DataConsistencyObject validators |
Lead events (bl_sfa_sales_lead_event) must point at an existing lead header | SfaSalesLeadEventDataConsistencyObject (SELECT guid FROM bl_sfa_sales_lead_hdr …) |
Update = read by guid, overwrite the header fields, append the new events, PUT | leads.effects.ts — but no v2 screen dispatches it |
Delete = DELETE sfa/sales-leads/{guid}; nothing cascades in the client | leads.effects.ts |
Deals (bl_sfa_deal_hdr, sfa/deals) have their own CRUD controller; no endpoint converts a lead into a deal — the deal is keyed in from the lead on the older build’s Deals screen | SfaDealController.java (POST, PUT, DELETE, GET, GET /query only); v2 issue #16 asks for one |
The older build’s CSV import runs four queue processors: import file → create lead → optionally create a contact from the lead → optionally create a Unified Contact Center outbound task, each line recording its result in bl_sfa_sales_lead_file_upload_line | SfaSalesLeadImportFileProcessor, SfaSalesLeadCreateProcessor, SfaSalesLeadContactProcessor, SfaOutboundTaskCreateProcessor |
The Organization menu’s screens write bl_inv_stock_reservation_hdr and bl_inv_bin_reservation_gen_doc_link rows through the Stock Reservation services, including its posting-status update | stock-reservation.effects.ts |
VOID does not exist for these rows; a lead is deleted or left with whatever status the client
wrote.
Related applets
- Customer Maintenance — a lead is not a customer; converting one means creating the customer there by hand. The copied stock-reservation screens embed the customer picker and create form.
- Entity Maintenance —
bl_sfa_sales_lead_hdr.entity_hdr_guidexists for a link to an entity; no v2 screen sets it. - Commission Scheme — owns the sales groups that
share the
sfabackend package. - Unified Contact Center — the only consumer of a lead: the older build’s import can raise an outbound task per imported lead.
- Stock Reservation — the screens behind v2’s Organization menu.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Clicking a lead in the listing does nothing | v2 has no edit screen; the row is selected and the view column it would open is commented out (leads-pages.service.ts) | Use the older build, or the API (PUT sfa/sales-leads); tracked as v2 issue #25 (Leads menu still open) |
| Lead Type / Lead Stage / Project drop-downs are empty and the form cannot be saved | The settings registers have no rows | Settings › Projects / SFA Type / SFA Stage — create at least one each |
| Sales Agent shows lead types; Lead Category (Celebration) shows projects | Placeholder bindings in the create template; neither value is saved | Ignore both; they do not reach the database |
| Customer / Contact Type entered on the lead are missing afterwards | Not mapped to the model on save | Record the customer in Customer Maintenance and the contact in AB Contacts |
| “Organization” menu shows stock reservations | It routes to the stock-reservation copy | Manage organisations from the lead form’s Select Organization picker |
Create fails with …_OBJECT_CODE_ALREADY_EXISTS in a settings register | Duplicate Code | Change the code; codes are unique per register |
| Project listing shows nothing although projects exist | Fixed in v2 issue #3 (getSfaProjectHdrByCriteria did not work) | Update the applet bundle |
| Older build: search in the Organization tab returns nothing, column toggles are not remembered | Recorded in issue #2 of the older repo (search, advanced search, column-toggle persistence) | Fixed in the November 2025 refactor; update the bundle |