diff --git a/API/ROLAC.API.Tests/Services/ExpenseServiceTests.cs b/API/ROLAC.API.Tests/Services/ExpenseServiceTests.cs
index a82393b..2ed6867 100644
--- a/API/ROLAC.API.Tests/Services/ExpenseServiceTests.cs
+++ b/API/ROLAC.API.Tests/Services/ExpenseServiceTests.cs
@@ -107,11 +107,39 @@ public class ExpenseServiceTests
}
[Fact]
- public async Task Create_Reimbursement_AsFinance_IsPendingApproval()
+ public async Task Create_Reimbursement_AsFinance_OnBehalf_IsPendingApproval_AndLinksPickedMember()
{
+ // Finance entering on behalf of a member (member explicitly picked) goes straight to the
+ // approval queue and links the picked member.
var (svc, db, _) = Build();
- var id = await svc.CreateAsync(Reimb(), isFinance: true);
- Assert.Equal("PendingApproval", (await db.Expenses.FindAsync(id))!.Status);
+ db.Members.Add(new Member { Id = 9, FirstName_en = "Pat", LastName_en = "Vendor" });
+ await db.SaveChangesAsync();
+ var r = Reimb(); r.MemberId = 9;
+
+ var id = await svc.CreateAsync(r, isFinance: true);
+
+ var e = await db.Expenses.FindAsync(id);
+ Assert.Equal("PendingApproval", e!.Status);
+ Assert.Equal(9, e.MemberId);
+ }
+
+ [Fact]
+ public async Task Create_Reimbursement_AsFinance_SelfService_LinksCallerMember_AndIsDraft()
+ {
+ // Regression: a finance/super_admin user filing their OWN reimbursement via "My Reimbursements"
+ // sends no MemberId. The entry must link to the caller's own member (so the Payee shows their
+ // legal name) and stay a Draft until they explicitly Submit — not jump to PendingApproval with
+ // a null member.
+ var (svc, db, _) = Build("u1");
+ db.Members.Add(new Member { Id = 7, FirstName_en = "Grace", LastName_en = "Lee" });
+ db.Users.Add(new AppUser { Id = "u1", MemberId = 7 });
+ await db.SaveChangesAsync();
+
+ var id = await svc.CreateAsync(Reimb(), isFinance: true); // no MemberId on the request
+
+ var e = await db.Expenses.FindAsync(id);
+ Assert.Equal(7, e!.MemberId);
+ Assert.Equal("Draft", e.Status);
}
[Fact]
diff --git a/API/ROLAC.API/Services/ExpenseService.cs b/API/ROLAC.API/Services/ExpenseService.cs
index b08f53e..6ad8893 100644
--- a/API/ROLAC.API/Services/ExpenseService.cs
+++ b/API/ROLAC.API/Services/ExpenseService.cs
@@ -141,12 +141,17 @@ public class ExpenseService : IExpenseService
}
else // StaffReimbursement
{
- // Finance entering on behalf of a member goes straight to the approval queue;
- // a member's own self-service entry stays a Draft until they explicitly Submit it.
- e.Status = isFinance ? "PendingApproval" : "Draft";
+ // Distinguish the two flows by whether a member was explicitly picked, NOT by role:
+ // - On-behalf: finance picks a member (Expenses page) -> straight into the approval queue.
+ // - Self-service: no member picked ("My Reimbursements") -> link to the caller's own member
+ // so the Payee shows their legal name, and keep it a Draft until they explicitly Submit.
+ // A finance/super_admin user files their own reimbursements through the self-service flow too,
+ // so keying off the role alone would leave their entries with a null member (empty Payee).
+ var isOnBehalf = isFinance && r.MemberId.HasValue;
+ e.Status = isOnBehalf ? "PendingApproval" : "Draft";
e.SubmittedBy = CurrentUserId;
- if (isFinance) e.SubmittedAt = DateTimeOffset.UtcNow;
- e.MemberId = isFinance ? r.MemberId : await CallerMemberIdAsync();
+ if (isOnBehalf) e.SubmittedAt = DateTimeOffset.UtcNow;
+ e.MemberId = isOnBehalf ? r.MemberId : await CallerMemberIdAsync();
e.VendorName = null;
}
diff --git a/APP/src/app/features/disbursement/pages/check-register-page/check-register-page.component.html b/APP/src/app/features/disbursement/pages/check-register-page/check-register-page.component.html
index 4f88fd2..d5c6816 100644
--- a/APP/src/app/features/disbursement/pages/check-register-page/check-register-page.component.html
+++ b/APP/src/app/features/disbursement/pages/check-register-page/check-register-page.component.html
@@ -51,7 +51,7 @@
-
+