收口付款批次创建与复核(08-01-reimbursement-notification-progress-clarity)
这个提交包含在:
@@ -1159,8 +1159,6 @@ test(`${trialrunIssueId} 浏览器业务先行试运行:报销、审批、请
|
||||
};
|
||||
}
|
||||
|
||||
const batchName = `${trialrunMarkerPrefix} 浏览器付款批次 ${marker}`;
|
||||
state.paymentBatchName = batchName;
|
||||
await page.goto("/payment-batches");
|
||||
await expect(page.getByRole("heading", { name: "付款", exact: true })).toBeVisible();
|
||||
if (await page.getByText(/当前功能未启用/).first().isVisible().catch(() => false)) {
|
||||
@@ -1174,21 +1172,17 @@ test(`${trialrunIssueId} 浏览器业务先行试运行:报销、审批、请
|
||||
}
|
||||
await page.getByRole("button", { name: "新建批次" }).click();
|
||||
const createCard = page.getByTestId("payment-batch-create-panel");
|
||||
await expect(createCard.getByRole("button", { name: "创建批次" })).toBeDisabled();
|
||||
await expect(createCard.getByRole("button", { name: "创建并提交复核" })).toBeDisabled();
|
||||
const createBatchResponsePromise = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.request().method() === "POST" && url.pathname === "/api/payment-batches";
|
||||
});
|
||||
await createCard.getByPlaceholder("例如:2026Q2-财务付款批次-01").fill(batchName);
|
||||
const reimbursementCode = state.reimbursementCode ?? state.reimbursementId;
|
||||
await createCard.getByTestId("payment-batch-candidate-search").fill(reimbursementCode);
|
||||
const candidateRow = createCard.getByTestId("payment-batch-candidate-row").filter({ hasText: reimbursementCode }).first();
|
||||
await expect(candidateRow).toBeVisible();
|
||||
await candidateRow.getByRole("checkbox").check();
|
||||
await createCard.locator('input[type="date"]').fill(new Date().toISOString().slice(0, 10));
|
||||
await createCard.locator("select").nth(0).selectOption("bank");
|
||||
await createCard.getByPlaceholder("例如 PBX").fill(`${trialrunSafePrefix}-${marker.slice(-6)}`);
|
||||
await createCard.getByRole("button", { name: "创建批次" }).click();
|
||||
await createCard.getByRole("button", { name: "创建并提交复核" }).click();
|
||||
const createBatchResponse = await createBatchResponsePromise;
|
||||
if (!createBatchResponse.ok()) {
|
||||
throw new Error(`创建付款批次失败:HTTP ${createBatchResponse.status()} ${await createBatchResponse.text()}`);
|
||||
@@ -1198,6 +1192,8 @@ test(`${trialrunIssueId} 浏览器业务先行试运行:报销、审批、请
|
||||
if (!batch?.id) {
|
||||
throw new Error(`创建付款批次后未返回 id: ${JSON.stringify(createBatchPayload)}`);
|
||||
}
|
||||
const batchName = batch.name;
|
||||
state.paymentBatchName = batchName;
|
||||
state.paymentBatchId = batch.id;
|
||||
await logoutLiveUser(page, { name: finance.name }).catch(() => undefined);
|
||||
|
||||
@@ -1215,10 +1211,23 @@ test(`${trialrunIssueId} 浏览器业务先行试运行:报销、审批、请
|
||||
|
||||
const financeAgain = await loginRole(page, "finance");
|
||||
await page.goto(`/payment-batches?id=${batch.id}`);
|
||||
const batchDetailCard = page.locator(".card-std").filter({ hasText: batchName }).filter({ hasText: "复核进度:" }).last();
|
||||
const batchDetailCard = page.getByTestId("payment-batch-detail-panel").filter({ hasText: batchName });
|
||||
await expect(batchDetailCard).toBeVisible();
|
||||
await batchDetailCard.getByRole("button", { name: "执行" }).click();
|
||||
await expect(batchDetailCard).toContainText("状态:已执行", { timeout: 30_000 });
|
||||
const receiptResponsePromise = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.request().method() === "POST" &&
|
||||
url.pathname === `/api/payment-batches/${batch.id}/receipt-attachments` &&
|
||||
response.ok();
|
||||
});
|
||||
await page.getByTestId("payment-batch-receipt-file-input").setInputFiles({
|
||||
name: `${trialrunSafePrefix}-bank-receipt.pdf`,
|
||||
mimeType: "application/pdf",
|
||||
buffer: Buffer.from(`%PDF-1.4\n${trialrunMarkerPrefix} ${marker}\n%%EOF\n`, "utf8"),
|
||||
});
|
||||
await receiptResponsePromise;
|
||||
await batchDetailCard.getByRole("button", { name: "登记付款完成" }).click();
|
||||
await page.getByTestId("action-confirm-submit").click();
|
||||
await expect(batchDetailCard).toContainText("已付款", { timeout: 30_000 });
|
||||
await page.goto(`/reimbursements/${state.reimbursementId}`);
|
||||
await reimbursementDetail.assertLoaded();
|
||||
await expect(page.getByTestId("reimbursement-payment-status")).toContainText(/已付款|paid/, { timeout: 30_000 });
|
||||
@@ -1232,7 +1241,7 @@ test(`${trialrunIssueId} 浏览器业务先行试运行:报销、审批、请
|
||||
if (/\/403/.test(page.url())) {
|
||||
await expect(page.getByRole("heading", { name: "无权限访问", exact: true })).toBeVisible();
|
||||
} else {
|
||||
const createButton = page.getByRole("button", { name: "创建批次" }).first();
|
||||
const createButton = page.getByRole("button", { name: "创建并提交复核" }).first();
|
||||
await expect(createButton).toBeDisabled();
|
||||
}
|
||||
await logoutLiveUser(page, { name: admin.name }).catch(() => undefined);
|
||||
|
||||
在新工单中引用
屏蔽一个用户