Manage expenses¶
Recovery expenses (clsThrdpartyExpense) are individual cost entries tied to a case, and the expense-approval record (clsThrdpartyExpenseApproval) tracks the approval status for the case's expense total. As the running total of a case's expenses crosses fixed dollar thresholds, the approval object automatically resets the approval code to require the next level of sign-off.
| Field | Value |
|---|---|
| Operation ID | OP-TP-03 |
| Trigger | clsThrdpartyExpense.NewThrdpartyExpense / GetThrdpartyExpense followed by property edits and Save(); clsThrdpartyExpenseApproval.GetThrdpartyExpenseApproval followed by an approval-code edit and Save() |
| Inputs | ThrdpartyCaseSeqNum, expense text/type, expense date, expense amount, recovery amount, budget code, expense-approval code |
| Outputs | Persisted THRDPARTY_EXPENSE rows; persisted expense-approval code on the case; approver user/date stamped when an expense is approved |
| Primary components | clsThrdpartyExpense.AddBusinessRules, clsThrdpartyExpense.Save (inherited), clsThrdpartyExpenseApproval.SetExpenseApproval, clsThrdpartyExpenseApproval.AddBusinessRules |
| Entry point | Business\SAIF.Business.Claim.ThirdParty\clsThrdpartyExpense.vb |
Steps¶
- Create or retrieve an expense.
Create()seeds a new expense row against aThrdpartyCaseSeqNum; retrieval reads existing rows by case (SQL-053/SQL-054, THRDPARTY_EXPENSE). - Validate the expense (
IsValid), skipped entirely for a deleted expense: - Expense text (type) is required (BR-018).
- Expense amount is required (non-zero) and must not be negative (BR-018).
- Expense date, if entered, must fall between the claim's date of injury and today; the date-of-injury bound is obtained by retrieving the owning case.
> Origin: The date-of-injury bound is read from
clsThirdPartyCase.GetThirdPartyCase, documented in Maintain recovery case (SAIF.Business.Claim.ThirdParty). - Budget code is required whenever a non-zero recovery amount is entered (BR-019).
- Recovery amount must not be negative and must not exceed the expense amount (BR-019).
- A confidential-claim security check exists as a rule stub but always returns
True; it has no enforced effect today.* - Persist the expense through the inherited BOF save lifecycle: insert (SQL-024), update (SQL-079), or delete (SQL-092) against THRDPARTY_EXPENSE.
- On a rows-affected value other than
1: anInsertError/UpdateError/DeleteErrormessage is added. - Retrieve the expense-approval record (
clsThrdpartyExpenseApproval) for the case (SQL-052, THRDPARTY_EXPENSE); if no code is stored, it defaults toNOTR(not required). - Recompute the approval code (
SetExpenseApproval) based on the case's runningExpenseCollection.ExpenseTotalagainst two fixed limits: - Below the lower limit: the approval code is forced to
NOTRregardless of its prior value. - At or above the lower limit but below the upper limit, and the collection needs approval: transitioning into
APPR(approved) stampsApproverUser/ApprovalDateon any not-yet-approved expenses; transitioning out ofDISAback toward approved re-checks whether any expense is still unapproved. - Validate the approval code (
IsValid), evaluated only while the approval object is dirty: - If the total is at or above the lower limit and below the upper limit and the collection needs approval, an approval code of
NOTRor blank produces a warning that supervisor approval is required (BR-020). - If the total is at or above the upper limit and the collection needs approval, the same condition produces a warning that director approval is required (BR-020).
- Both checks are warnings, not hard errors, so the expense can still be saved with an unresolved approval code.
- Persist the approval code on the case-scoped approval row (SQL-078, THRDPARTY_EXPENSE).
Process flow¶
The following diagram visualizes expense validation and the escalating approval-tier logic.
flowchart TD
Start([Caller creates or edits expense]) --> ERules[Validate type, amount,<br>expense date, budget code,<br>recovery amount]
ERules --> EOk{Valid?}
EOk -->|No| Fail([Broken rules returned])
EOk -->|Yes| ESave[Insert, update, or delete<br>THRDPARTY_EXPENSE]
ESave --> Rows{RowsAffected = 1?}
Rows -->|No| Contention([Insert/Update/Delete error added])
Rows -->|Yes| Recompute[Recompute expense total<br>for the case]
Recompute --> Tier{Total vs. thresholds}
Tier -->|"< $5,000"| NotReq[Approval code forced to NOTR]
Tier -->|"$5,000-$24,999"| Lower{Approval code<br>NOTR or blank?}
Tier -->|">= $25,000"| Upper{Approval code<br>NOTR or blank?}
Lower -->|Yes| WarnLower([Warning: supervisor<br>approval required])
Lower -->|No| ApprSave[Persist approval code]
Upper -->|Yes| WarnUpper([Warning: director<br>approval required])
Upper -->|No| ApprSave
NotReq --> ApprSave
WarnLower --> ApprSave
WarnUpper --> ApprSave
ApprSave --> Done([Approval record saved])
Failure and edge-case behavior¶
- The $5,000/$25,000 approval-tier checks are warnings, so an expense total can cross a threshold and still be saved without a resolved approval code; enforcement relies on UI-level review of the warning.*
- The confidential-claim security rule for expenses is present in code as a permanently-
Truestub; it does not currently block access to expenses on confidential claims.* - The budget-code requirement only applies when a recovery amount is entered — an expense with no recovery amount can be saved without a budget code.
ValidExpenseDateretrieves the owning case on every validation pass to obtain the date-of-injury bound, adding a database round trip per validation cycle.*
Note: Statements marked with
*were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts.
Related documentation¶
Sources¶
Business\SAIF.Business.Claim.ThirdParty\clsThrdpartyExpense.vbBusiness\SAIF.Business.Claim.ThirdParty\clsThrdpartyExpenseApproval.vbBusiness\SAIF.Business.Claim.ThirdParty\clsThrdpartyExpenseCollection.vbBusiness\SAIF.Business.Claim.ThirdParty\clsThirdPartyConstants.vb