Tracopus · HRMS · Leave · CFA-LEAVE-WA0

Leave approval scenarios

Coverage map for the native leave lifecycle behind leaveManagementEnabled: create → submit → approve / reject / withdraw / cancel, plus overlap, half-day, delegation, on-behalf, and ZingHR SYNCED coexistence. Side effects include balance ledger, Approvals inbox, attendance sync, and TaskActivity LEAVE promotion.

22core LS scenarios
20unit Pass (WA1+WA2)
0Watch (P5 FE harness Pass; data optional)
0WA2 residual core

Happy path (status → side effects)

1

Create draft

CREATED. Holiday-aware day count; optional half-day on single calendar day. No pending hold.

2

Submit

SUBMITTED; reserve pending balance; notify manager / delegates. Appears on Leave pending + Approvals inbox.

3a

Approve

APPROVED; debit (releases hold); promote TaskActivity LEAVE; attendance LEAVE / HALF_DAY when sync on.

3b

Reject

REJECTED; release hold; no TaskActivity / attendance write. Comment required.

4

Withdraw (owner)

CREATED or SUBMITTED → WITHDRAWN; release hold if submitted. Blocked on APPROVED / SYNCED.

5

Cancel (owner)

SUBMITTED / APPROVED / SYNCED → CANCELLED; release hold or creditOnCancelAfterApprove; demote TaskActivity; reverse attendance.

Core scenarios (LS1–LS12)

LS1

Create → Submit → Approve

Pass

Happy path: balance debit, promote, pending cleared.

Actors
Employee → Manager
Assert
APPROVED; debitOnApprove; promote; audit APPROVE
JUnit
ls1_approve_promotesAndDebitsBalance
Watch
Approvals inbox + attendance LEAVE cell (Playwright)
LS2

Create → Submit → Reject

Pass

Reject releases pending; no promote / debit.

Actors
Employee → Manager
JUnit
ls2_reject_releasesPendingBalance
LS3

Create → Withdraw

Pass

Owner withdraws draft; never pending.

JUnit
ls3_withdraw_draft_setsWithdrawn
LS4

Submit → Withdraw

Pass

Owner withdraws submitted; hold released.

JUnit
ls4_withdraw_submitted_releasesHold
LS5

Submit → Cancel

Pass

Owner cancels submitted; hold released; no approve-debit reverse.

JUnit
ls5_cancel_submitted_releasesHold
LS6

Approve → Cancel

Pass

Owner cancel after approve credits debit and re-runs promote (demote path).

JUnit
ls6_cancel_afterApprove_creditsDebit
LS7

Re-apply after terminal

Pass

Overlap ignores REJECTED / WITHDRAWN / CANCELLED; second leave can approve.

Code
LeaveOverlapService terminal filter
JUnit
ls7_overlap_ignoresTerminalStatuses
LS8

Overlap block

Pass

Second active overlap blocked; first untouched.

JUnit
ls8_submit_blockedWhenOverlap
LS9

Holiday / weekly-off day count

Pass

Create/submit resolve day count via holiday validation; non-working-only range blocked.

JUnit
ls9_submit_blockedWhenOnlyNonWorkingDays + day-count resolve on create/submit
LS9b

Half-day leave apply → approve

Pass

Half-day flag persisted on single-day create; multi-day request clears half-day.

JUnit
ls9b_create_halfDay_persistsOnSingleDay
Watch
Attendance HALF_DAY cell when sync on (integration)
LS10

Insufficient balance

Pass

Submit blocked; no orphan reserve.

JUnit
ls10_submit_blockedWhenInsufficientBalance
LS11

Illegal transitions

Pass

4xx; status unchanged — withdraw on APPROVED, cancel on CREATED, approve without authority.

JUnit
ls11_* family
LS12

Stale expectedStatus

Pass

Concurrent safe conflict on approve.

JUnit
ls12_approve_staleExpectedStatusReturnsConflict

Cancel family (LS6b–d)

LS6b

SYNCED → Cancel

Pass

Same reverse as approved (credit + promote demote).

JUnit
ls6b_cancel_synced_creditsDebit
LS6c

Cancel vs Withdraw rules

Pass

Withdraw blocked on APPROVED/SYNCED; cancel blocked on CREATED/REJECTED/WITHDRAWN/CANCELLED.

JUnit
ls6c_*
LS6d

Non-owner cancel / withdraw

Pass

Manager/delegate forbidden; manager uses reject.

JUnit
ls6d_nonOwner_cancelAndWithdrawForbidden

Delegation / on-behalf / Zing

LS-DEL-1

Delegate approves

Pass

LEAVE delegation → delegate approves; DELEGATE + actedOnBehalfOf audit.

JUnit
lsDel1_approve_allowedForDelegate
Wave
WA2
LS-DEL-2

Expired / revoked mid-pending

Pass

Delegate blocked; owner manager can still approve.

JUnit
lsDel2_* + ApprovalAuthorityServiceTest.lsDel2_*
LS-DEL-3

Attendance auto ≠ leave auto

Pass

ATTENDANCE-only delegation / persona cannot leave-approve; no debit/promote.

JUnit
lsDel3_* + authority ATTENDANCE-only vs LEAVE
LS-OB-1..2

On-behalf apply / sibling isolation

Pass

Manager create/submit for member (member balance); approve A leaves B SUBMITTED.

JUnit
lsOb1_*, lsOb2_*
FE
buildLeaveCreatePayload(..., actorId) current user as actor
LS-ZING-1

ZingHR SYNCED coexistence

Pass

Native leave with zinghrTransactionId + SYNCED; cancel credits balance + promote demote.

JUnit
lsZing1_syncedLinkedLeave_cancelCreditsBalance

Side-effect checklist

Effect Approve Reject / Withdraw (pre-approve) Cancel (post-approve / SYNCED)
Status APPROVED REJECTED / WITHDRAWN CANCELLED
Balance Debit Release hold / no debit Credit back
Pending + Approvals inbox Cleared Cleared N/A
Attendance (sync on) LEAVE / HALF_DAY Unchanged Reversed
TaskActivity Upsert LEAVE None Demoted (deleted)
Audit Actor + authority Actor CANCEL
Siblings Untouched Untouched Untouched

On approve — promote

LeavePromotionService.promote upserts TaskActivity TaskType.LEAVE, then LeaveAttendanceSyncService.syncAfterPromotion.

On cancel — demote via promote

Cancel sets CANCELLED then calls promote; cancelled path soft-deletes existing LEAVE activities and syncs attendance reverse.

Illegal transitions

From Blocked ops Allowed owner ops
CREATED Approve, Reject, Cancel Submit, Withdraw
SUBMITTED Withdraw by non-owner; Approve without authority Withdraw, Cancel (owner); Approve/Reject (authority)
APPROVED / SYNCED Withdraw, Approve, Reject Cancel (owner)
REJECTED / WITHDRAWN / CANCELLED Approve, Reject, Cancel, Withdraw —

Product / CFA scenarios (later waves)

ID Wave Baseline
LS-LOC-*W1Pass — CfaIndiaLeaveEntitlementMatrixTest
LS-FY-1W1Pass — fiscal Apr 1 CF/lapse + PL45
LS-MAT / PAT / MSL / WWLW2Pass — SpecialLeavePolicySupportTest + workflow/doc privacy
LS-CO-1..4W3Pass — CompOffCreditSupportTest + GlobalLeavePolicy / workflow
LS-PH-1..2W4Pass — FloatingHolidayPolicySupportTest + legal calendar budget/cycle

Evidence

Document
fui/docs/enhancement-evidence/CFA-LEAVE-WA0.md
fui/docs/enhancement-evidence/CFA-LEAVE-WA1.md
fui/docs/enhancement-evidence/CFA-LEAVE-WA2.md
fui/docs/enhancement-evidence/CFA-LEAVE-W0.md
fui/docs/enhancement-evidence/CFA-LEAVE-W1.md
fui/docs/enhancement-evidence/CFA-LEAVE-W2.md
fui/docs/enhancement-evidence/CFA-LEAVE-W3.md
fui/docs/enhancement-evidence/CFA-LEAVE-W4.md
fui/docs/leave/pending/CFA_LEAVE_GAP_PLAN.md
fui/docs/leave/pending/CFA_LEAVE_TRACKER.md
LeaveWorkflowServiceTest (LS-named methods)
fui/tests/e2e/05-attendance-leave-timesheet/leave-approval-scenarios.spec.js