Fix null payee.
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@
|
||||
<button kendoButton fillMode="flat" themeColor="primary" (click)="print(dataItem)">Print</button>
|
||||
<button *ngIf="canSign(dataItem)" kendoButton fillMode="flat" themeColor="success"
|
||||
(click)="openSign(dataItem)">簽收</button>
|
||||
<button *ngIf="dataItem.signed" kendoButton fillMode="flat" (click)="viewSignature(dataItem)">Signature</button>
|
||||
<!-- <button *ngIf="dataItem.signed" kendoButton fillMode="flat" (click)="viewSignature(dataItem)">Signature</button> -->
|
||||
<button *ngIf="dataItem.signed" kendoButton fillMode="flat" themeColor="primary"
|
||||
(click)="printReceipt(dataItem)">收據</button>
|
||||
<button *ngIf="canVoid(dataItem)" kendoButton fillMode="flat" themeColor="error"
|
||||
|
||||
Reference in New Issue
Block a user