Engagement Applet
Keep the client file for audit, assurance and tax work: one engagement per client, saying which customer it is for, which company and branch bill it, who holds each role and, for clients tracked by financial year, one year-end record per year. It posts nothing and has no finalise step. Engagement codes and names arrive by bulk load and are read-only on the form, and the listing opens only for a login that has an employee record, whatever permissions it holds.
Overview
The Engagement Applet is the client-file register for the audit, assurance and tax module. One engagement is one client file: which customer entity it is for, which company and branch (job group) bill it, which staff hold the engagement roles, and — for clients tracked by financial year — one fiscal-year-end record per year with its own staff assignments.
It is a master-data applet: it posts no journal, moves no stock and has no FINAL. The documents it shows on the Gen Doc tab are generic documents raised elsewhere and linked to the engagement.
Where it fits
| Direction | What | Why |
|---|---|---|
| Before | Customer Maintenance / Entity | Customer Name is chosen from the entity list, and the server rejects an update whose customer or billing entity no longer exists. |
| Before | Organization | Selecting a branch also fills the company from that branch. Both are checked to exist on update. |
| Before | Employee | Engagement roles and fiscal-year-end staff assignments are employee records. |
| Inside | Engagement Category (Settings) | A code/name/description list; the engagement listing has an Engagement Category column. |
| After | Generic documents | The Gen Doc tab lists documents (Doc type, Doc No, Status, Txn date, Amount) raised against the engagement. |
| After | Claims | The engagement-role assignments made here are what the claim approval logic reads to route a claim raised against this engagement. A Claims tab exists in this applet’s template and is commented out, so the connection is invisible from this screen. |
| After | Memorandum of Fees | A switched-off tab; the platform carries a memorandum-of-fees record family that references the engagement. |
Screens and menus
The sidebar has a single entry — Engagement Listing; a switched-off “Claimant” group with My Claim and Line Reports is not available.
Engagement Listing
A server-side grid of engagements. Columns: Engagement Code, Engagement Name, Engagement Category, Entity Name, Created Date, Created By, Modified Date, Modified by, Status. A grid/list view toggle sits next to the search box.
The Status column is not the record’s status. It shows the free-text business status somebody typed on the Main tab. The record’s own Active / Deleted state — the one the listing filters on — is not on the grid at all, which is why a soft-deleted engagement simply vanishes rather than appearing as deleted. The search box searches eight columns at once: running number, code, name, alternate code, engagement type, department code, category and description.
Pressing + creates an empty engagement on the server straight away and opens Edit
Engagement on it — there is no draft. Unlike the applets that use a TEMP status there is no
sweeper: the record is created Active and stays.
Abandoning that screen is worse than it looks. The empty engagement has no company on it, and the listing shows only engagements whose company is one you can access — a test an engagement with no company can never pass. The stray record is invisible in the listing to everybody, including you. It is not orphaned data you can see and tidy up; it is orphaned data you cannot see at all, and the only way to find it is a query or the API.
Edit Engagement
| Tab | Shown when | Contents |
|---|---|---|
| Main | always | The engagement record — see Fields. The Engagement Roles block below it renders only while FYE Type is Perpetual; switching to Yearly takes it away, because a yearly engagement staffs each fiscal year separately on the next tab. |
| Fiscal Year End | FYE Type is Yearly | A grid of fiscal-year-end records (Date Start, Date End, Created Date, Modified Date, Status), each with its own employee assignment list (Employee Code, Employee Name, Role, Approval Level) and its own engagement-role block. |
| Gen Doc | always | Documents linked to this engagement: Doc type, Doc No, Status, Txn date, Amount. Read-only. |
Four further tabs are present in the template and commented out: Employees (the perpetual-tracking
counterpart of Fiscal Year End), Memorandum of Fees, Claims and Issue Link. The DELETE
button at the bottom of the screen is also switched off, so an engagement cannot be deleted
from the UI; only an API call holding TNT_AAT_ENGAGEMENT_HDR_DELETE can.
SAVE is disabled whenever the Main form is invalid — that is, whenever Customer Name, Engagement Code, Engagement Name or the branch is empty. It saves the engagement and the engagement-role assignments together.
Settings → Engagement Category
The settings gear opens on Engagement Category. A listing of Code, Name, Description, Created Date, Modified Date with create and edit screens; the edit screen has a Main tab and an Engagements tab listing the engagements in that category.
Settings → Applet Log
An audit-trail listing and a read-only view screen exist but have no entry in the settings
menu, so they can only be reached by URL (settings/applet-log).
Configuration
Before you can use it
| Prerequisite | Where | Why |
|---|---|---|
| Customer entities | Customer Maintenance | Customer Name is required and is picked from the entity listing. The server rejects an update whose customer or billing entity no longer exists. |
| A branch, and a company behind it | Organization | The branch (labelled Job Group when the relabel setting is on) is required on the form; picking it sets the company. Both are checked to exist on update. |
| Employees | Employee | Every engagement role and every fiscal-year-end assignment points at an employee — and so does every person who opens the listing. See the callout below. |
| Engagement categories | Settings → Engagement Category, in this applet | Only if you want the listing’s Engagement Category column populated. |
| A claim approval setting, if used | Claim Applet | When set, the approval setting must exist, on both create and update. The approval setting also decides which engagement roles count as approvers — see Engagement roles decide who approves a claim. |
You have to be an employee to open the listing at all. The listing does not use the ordinary
branch-and-company access check. It looks up the employee record whose primary login subject is you,
and if there is not one it refuses the whole request with a message naming your own address:
“Cannot find your email: … from Employee Applet. Please contact respective Managers to check your
Employee information.” No permission grant gets around it — a finance manager with
TNT_AAT_ENGAGEMENT_HDR_READ and no employee record still sees nothing but that error.
From there, the companies you can see engagements for are: your employee entity’s default company, plus every company linked to it through the engagement company-access links, plus every company linked to you personally through the employee company-access links. Neither of those two link lists has a screen in this applet. If somebody can see the listing but not the engagements they expect, that pair of link lists — not the permission set — is where the answer is.
Applet settings
Unlike the placeholder settings screen found in several other applets, this one is real: 21 settings, loaded on open and saved together.
The screen is called Application Settings in the settings menu and has two tabs — Engagement
Listing and Main. Anyone who can open it can change any of them; they are tenant-wide for this
applet. Every toggle starts false.
Fifteen of the twenty-one are plain visibility switches that do exactly what their label says: they take one control off the screen. On the Main tab those are Customer Name, Engagement Code, the branch / job-group drop-down, Engagement Name, Alternate Code, the Perpetual / Yearly radio group, Status, Description, the Entity Details button, and — in the roles block — Engagement Manager, Engagement Director, Engagement Partner, EQCR and Key Audit Partner. Hide Engagement Partner is the one exception in that list: it hides two roles rather than one. On the listing tab, one more removes the grid/list view toggle. Four settings do something a label does not predict, and two do nothing:
| Setting | What it does that the label does not say |
|---|---|
DISABLE_EDITING_ENGAGEMENTS | Makes the Main form and the engagement-role block read-only on open, for everyone. It is not a permission — it is a tenant-wide read-only switch that no grant overrides. |
HIDE_ENGAGEMENT_CREATE_BUTTON | Turning it on is how a tenant that loads engagements in bulk stops staff creating the invisible orphan rows described above. Existing engagements still open and edit normally. |
RELABEL_COMPANY_TO_ENTITY | Changes the word only. The field still stores the company, and every error message still says comp. |
RELABEL_BRANCH_TO_JOB_GROUP | Changes the word on the drop-down and inside the Engagement Name hint, so the hint text moves with the relabel while the stored value does not. |
Hiding a required field does not make it optional. Engagement Code, Engagement Name and the branch are required by the form itself, so the requirement survives the control being taken off the screen: SAVE stays greyed out and nothing on the page says why. Use these to hide fields that are already filled, never to shorten the form.
Customer Name is the one to be most careful with, for a different reason. It is a read-only field whose only purpose is to be clicked — clicking it opens the entity selector. Hiding it removes the only way to choose a customer. (Its requirement sits on the control rather than on the form, so this one is about losing the picker, not about a stuck validator.)
On the screen and doing nothing
Two toggles are saved and read by nothing.
- Hide Managing Partner never gates anything, because the Managing
Partner block is gated on
HIDE_ENGAGEMENT_PARTNERinstead. So Hide Engagement Partner hides two roles, not one, and Hide Managing Partner hides none. Nothing in the applet or the platform reads it. - Enable Audit Trail is a leftover, and the audit trail does not need it. Create, update and delete each write an audit-trail entry unconditionally, and the Applet Log screen that reads them is not gated on the toggle. The same toggle appears in three sibling applets in the audit/assurance/tax and events family and does nothing in any of them.
Settings screens that are routed but not linked
Default Selection (Default Branch / Default Location) exists but has no menu link. The whole Personalization area — personal default selection and the sidebar editor — exists with no way in. Feature Visibility, the team permission listing and the Applet Log are likewise reachable by URL only. Webhook (listed as Triggers), Applet Access, the permission wizard and the permission set, user and role permission listings are linked from the left-hand list of the Settings screen, which the shared settings shell draws for every applet that uses it.
Feature visibility and permissions
The applet contains no HIDE_*/SHOW_* client-side permission pairing; visibility is decided by
the settings above. Server-side, every action is gated:
| Action | Permission |
|---|---|
| Create an engagement | TNT_AAT_ENGAGEMENT_HDR_CREATE |
| Update an engagement | TNT_AAT_ENGAGEMENT_HDR_UPDATE |
| Delete an engagement | TNT_AAT_ENGAGEMENT_HDR_DELETE |
| Read engagements (listing, by GUID, query, custom containers) | TNT_AAT_ENGAGEMENT_HDR_READ |
The same permission set gates bulk loads, so a bulk loader needs exactly the same grants as a user.
Three things about that table are easy to get wrong:
TNT_AAT_ENGAGEMENT_HDR_OWNERand..._ADMINare accepted as a base on every engagement action, alongside the specific grant. A..._MEMBERpermission exists too, but nothing on the engagement itself uses it.- The engagement-role links are a separate permission family. Saving role assignments is gated
by
TNT_AAT_ENGAGEMENT_EMPLOYEE_LINK_CREATE/_DELETE(with OWNER and ADMIN). A user granted only the header permissions can edit the engagement and will see the role save fail on its own, after the engagement has already saved. - Permission is not the same as visibility. Passing the permission check gets you to the query; the company scoping described under Before you can use it decides what the query returns. Both have to be right.
Fields
Edit Engagement — Main
The tab takes the client, the file reference and name, the branch that bills it, an alternate code, the Perpetual/Yearly choice, a status and a free-text description. Description is free text and nothing reads it but the search box. The rest behave in ways the screen does not show:
| Field | Required | What it does that the screen does not show |
|---|---|---|
| Customer Name | Yes | Read-only — clicking it is what opens the entity selector. |
| Engagement Code | Yes | Read-only, and nothing in this applet writes it. Unique across engagements: a duplicate is rejected, and so is a blank one on update. |
| Branch (label: Job Group when relabelled) | Yes | Choosing it also sets the company, and the company is what decides whether anyone can find this engagement in the listing again. |
| Engagement Name | Yes | Read-only. The helper that would compose it from customer – code – company – branch is switched off, so existing records carry names in that shape and new ones get nothing. |
| Alternate Code | No | Loaded from the customer entity’s customer code, not from the engagement’s own stored value — so it is re-stamped from the customer record every time the screen loads. Editing it to something the customer record does not say will not survive the next open. |
| FYE Type | — | Yearly reveals the Fiscal Year End tab and removes the Engagement Roles block from this tab. A record with no value behaves as Perpetual. |
| Status | Effectively yes | A free-text input — the fixed-list drop-down is switched off — with no check on it, so the screen will let you save an empty one. The server will not: update fails with ..._ENGAGEMENT_STATUS_IS_NULL_OR_EMPTY. This is the field people type five spellings of; agree the vocabulary out of band, because nothing here will enforce one. |
| Engagement Category | — | Not on this form at all, and worse than absent. The code that copies the form onto the record still assigns the category from a form control that does not exist, so it writes an empty value — and the engagement PUT replaces the whole row. Change anything on this tab, press SAVE, and the category set from Settings → Engagement Category is gone. |
The Engagement Roles block
Six role slots — Engagement Manager, Engagement Director, Engagement Partner, Managing Partner, EQCR (Engagement Quality Control Reviewer) and Key Audit Partner — each taking any number of employees as chips. Five of the six have a Non-Applicable tick box, whose state is stored on the engagement.
Managing Partner is the odd one out and the screen does not say so. It has no Non-Applicable box, its search is disabled, its chips have no remove icon and its input is read-only. You can see who holds it; you cannot set or clear it from here. It is also the block gated by Hide Engagement Partner rather than by its own setting (see On the screen and doing nothing).
Engagement roles decide who approves a claim
This is the block’s real job, and none of it is visible from this screen.
Each slot stamps a fixed approval level on the link it writes — Manager 1, Director 2,
Engagement Partner 3, Managing Partner 4, EQCR 5, Key Audit Partner 6. When a claim line is raised
against this engagement, the claim processor looks up the claimant’s role on this engagement
(defaulting to MEMBER if they hold none), then asks for the employees on this engagement whose
approval level is higher than the claimant’s, taking the next levels in ascending order up to
the number of approvals the claim approval setting requires.
Two consequences worth knowing before you staff an engagement:
- Gaps in the ladder are deliberate. An engagement with a Manager (1) and an Engagement Partner (3) and nobody at level 2 routes straight from 1 to 3. The query takes the next distinct levels that exist, not levels 2 and 3 specifically, so you do not have to fill every slot to get a working approval chain.
- EQCR and Key Audit Partner sit at 5 and 6, above the Managing Partner, but only enter the chain if the claim approval setting names their roles. The setting’s role list is the filter; the level is only the ordering. That is the separation to reach for when a reviewer must sign the engagement’s work without becoming an approver of everybody’s expenses.
Because approval routing reads these links, changing who holds a role changes who can approve claims on that client file — with no warning on this screen and no effect on claims already in flight.
Fiscal Year End — create and edit
A fiscal year end does not store the dates you pick. The create form shows Date Start and Date End as datepickers, but only four numbers reach the database — the year and the month of each. The day of the month is thrown away at the moment you pick it.
That is not a bug so much as a shape you need to know, and it shows up three ways:
- Reopening a fiscal year end rebuilds the two datepickers as the 1st of the stored month, whatever day you originally chose. A 31 March year end reads back as 1 March.
- The grid’s Date Start and Date End columns are rendered from year and month as Mar 2026, not as a date. There is nothing to sort or filter by day, because there is no day.
- A fiscal year end is therefore a month, and two of them in the same month are the same period as far as this applet is concerned. Nothing checks that they do not overlap.
Status offers the shared status list and defaults to ACTIVE. All three fields are required by the
CREATE button, which stays disabled until they are filled. Created By, Modified By and the two audit
dates appear read-only on the edit screen only.
Each fiscal-year-end record then carries its own employee list (Employee Code, Employee Name, Role, Approval Level) and its own engagement-role block, so staffing — and therefore claim approval routing — can change from one year to the next.
Engagement Category
Code, Name, Description, plus read-only audit fields. The edit screen’s Engagements tab lists the engagements in the category, ordered by code.
Lifecycle and effects
Posting proof
| Aspect | Value |
|---|---|
| Server document type | None. An engagement is master data, not a financial document. |
| Amount signum / quantity signum | Not applicable. |
| Dr/Cr equation | None. The applet posts no journal. |
| GL precedence | Not applicable. |
| Stock processor | None. |
| What VOID reverses | There is no VOID and no posting status. Records carry a record status (Active / Inactive) and a free-text business status. |
Statuses and the save path
There is no draft. + creates an empty engagement; the server fills the identifier, created and updated dates, status Active and a revision, resolves the created-by and updated-by names, and returns the record. The toast reads “The engagement has been created”. From then on every SAVE is an update.
The server checks far more on update than on create:
| Checked on create | Checked on update |
|---|---|
| Identifier present and new; the approval setting exists if set; the code is not already taken; created/updated dates and users present; status; revision | all of the above, plus: the company exists; the branch exists; the customer entity and billing entity exist; the running number is not blank; the code is not blank and is unique; the business status is not blank |
So an engagement created by the empty-container path is invalid the moment you try to save it until code, status, branch and customer are all set — which is why the Main form’s required fields matter more than they look. And because the code is read-only with nothing in the applet writing it, the empty-container path produces a record that cannot be completed from this screen at all.
SAVE is one button and three requests
Pressing SAVE fires three independent calls, each with its own toast:
- Update the engagement — “The engagement has been updated”.
- Remove the role links you removed — “The Engagement Roles have been updated”.
- Re-send every role assignment currently on screen — “The Engagement Roles have been created”.
They are not a transaction, and the header call navigates you back to the listing as soon as it succeeds, while the other two are still in flight. If a role call fails you get an error toast over the listing, and the engagement is already saved.
Step 3 re-sending assignments that already exist is deliberate, not a bug: the server looks each one up by engagement, employee and role, inserts only what is missing, and returns the lot. That is what makes the screen safe to press twice. It also means an existing link is returned untouched — so if a link was created elsewhere with a different approval level, this screen will never correct it.
The engagement update replaces the whole record: every value is written from what the browser sent, so a value the browser leaves out is blanked rather than left alone. That is the mechanism behind the Engagement Category loss described under Fields.
Delete is a soft delete. Deleting marks the engagement Deleted; the record stays, and every listing already excludes it. Nothing is physically removed.
On update the server assigns the running number when it is blank, from the tenant’s ENGAGEMENT_NO
sequence. It refreshes the Modified By name on every update, but the Created By name only when
it is blank — so the Modified By column tracks a user’s rename and the Created By column keeps
whatever name was recorded at the time. Two columns that look like a matched pair do not behave like
one.
On create the server does not assign the code, the running number or the name.
Create, update and delete each write an audit-trail entry, unconditionally. The Applet Log screen reads them; it has no menu entry.
Related applets
- Customer Maintenance and Entity — the client behind every engagement; the Customer Name field is a picker over the entity listing.
- Organization — companies and branches; the branch choice determines the company on the engagement.
- Employee — the people assigned to engagement roles and to each fiscal year end, and the record that decides whether you can open the engagement listing at all and which companies’ engagements you see.
- Claim Applet and Claim Cycle Applet — downstream. The engagement-role links written here are what the claim approval logic reads to decide who signs off a claim raised against this engagement.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| SAVE stays greyed out with every visible field filled | Engagement Code, Engagement Name and the branch are required by the form. Hiding one with the matching HIDE_* setting removes the control but not the requirement, so an invisible empty field keeps the form invalid. | Turn the relevant HIDE_* setting off, fill the field, turn it back on. |
| The listing will not open at all: “Cannot find your email … from Employee Applet” | The listing resolves the employee record whose primary login subject is the caller before it runs any query. No employee record, no listing — whatever permissions are granted. | Create the employee record in the Employee Applet with this login as its primary subject. |
| The listing is empty, or is missing engagements a colleague can see | The listing returns only engagements whose company is in your accessible set: your employee entity’s default company plus the two engagement company-access link lists. An engagement with no company on it is in nobody’s set. | Check the engagement has a branch (and therefore a company) on it, and check the access links. Neither link list has a screen in this applet. |
| An engagement’s category empties itself | The Main tab writes the category from a form control that does not exist, and the update replaces the whole record — so any save from that tab nulls it. | Set the category from Settings → Engagement Category → Engagements, and avoid re-saving the engagement’s Main tab afterwards. |
| Managing Partner cannot be set or cleared | The Managing Partner block is read-only with its search and its remove icons switched off — it is display-only on this screen. | Write the link through the employee-links API. |
| Hide Engagement Partner removed two roles | The Managing Partner block is gated on HIDE_ENGAGEMENT_PARTNER rather than on its own key. | Expected. Hide Managing Partner does nothing. |
| A fiscal year end’s dates changed to the 1st | Only the year and month are stored; the datepickers are rebuilt as the 1st of the stored month every time the record is opened. | Expected, and there is nothing to recover — the day was never saved. Treat a fiscal year end as a month. |
| The engagement saved but the role assignments did not | SAVE fires three separate requests and returns to the listing as soon as the header call succeeds. The role calls use a different permission family (TNT_AAT_ENGAGEMENT_EMPLOYEE_LINK_*). | Re-open the engagement and check the chips. If they are still missing, check that grant. |
| Engagement Code and Engagement Name are read-only and there is no way to type them | Both are read-only, and nothing in the applet writes them. The name-composing helper (joining customer – code – company – branch) exists but is switched off. | Load engagements in bulk with the code and name set, or set them through the API. A code typed into the database must be unique. |
| Pressing + leaves engagements nobody can see | The create button creates an empty engagement immediately; the record is created Active, not TEMP, no sweeper removes it, and with no company on it the listing’s company filter excludes it for everyone. | Find them through the API and soft-delete them (needs TNT_AAT_ENGAGEMENT_HDR_DELETE) — the UI’s delete button is switched off. Turn HIDE_ENGAGEMENT_CREATE_BUTTON on if engagements are loaded in bulk. |
| The Engagement Category column is always empty | The Main tab has no category control, and its save path writes an empty category over whatever was there. | Set it from Settings → Engagement Category → Engagements, and see the row above about it emptying itself. |
| The Fiscal Year End tab is missing | It renders only while FYE Type is Yearly. | Switch FYE Type to Yearly. The Perpetual counterpart (an Employees tab) is commented out of the template, so a perpetual engagement has no staffing tab at all. |
An update fails with ..._COMP_GUID_DOES_NOT_EXIST / ..._BRANCH_GUID_DOES_NOT_EXIST / ..._CUSTOMER_ENTITY_HDR_GUID_DOES_NOT_EXIST | The update checks that the company, branch, customer entity and billing entity exist — the create checks do not. A record bulk-loaded with a stale reference passes creation and fails the first edit. | Re-point the engagement at a live company, branch and entity. |
An update fails with ..._RUNNING_NO_IS_NULL_OR_EMPTY | The running number is required on update and is auto-filled from the tenant’s ENGAGEMENT_NO sequence only on update. | Retry the save; if it persists, the sequence counter for this tenant has not been initialised. |
| The Status field accepts anything | The fixed-list drop-down is switched off and the live control is a free-text input. The server only checks that it is not blank. | Agree the vocabulary out of band, or restore the select. |
| The Enable Audit Trail toggle does nothing | The audit trail is written by the server on every create, update and delete regardless, and the Applet Log screen is not gated on the key. | Nothing to do. The log is reachable by URL only (settings/applet-log) — it has no menu entry. |
| The settings gear lists fewer screens than the applet has | The applet’s own group lists only Application Settings and Engagement Category; Default Selection and the whole Personalization area are switched off. The shared list below it adds Applet Access, the permission screens and Triggers (webhook). | Feature Visibility, the team permission listing and the Applet Log exist and can be reached by URL only. |
Related documentation
- Customer Maintenance Applet
- Employee Applet
- Organization Applet
- Claim Applet — where the engagement roles set here are used