Remove payment amount, reference, notes and manual combining forms. Link supplier POs automatically and record paid from supplier evidence plus proof, keeping readiness and attachment safeguards. Keep active supplier/company views current and retire stale supplier evidence on routing changes. Verified 5167 tests with only the two existing script-import errors.
35 lines
3.5 KiB
TypeScript
35 lines
3.5 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
||
|
||
const requests = [
|
||
{ id: "pay1", revision: 1, created: "2026-11-02 10:00:00.000Z", status: "pending", amount: 1250, order: "order1", supplier: "supplier1", companyName: "Acme Engineering", orderNumber: "ORD26110201", supplierName: "Fastener Supply", items: ["line1"], lines: [{ id: "line1", description: "M16 × 50 hex bolts", order_qty: 100, cost_price: 12.5 }], documents: [], purchaseOrders: [{ id: "po1", number: "PO202611001FAS", documents: [{ collection: "purchase_orders", recordId: "po1", filename: "po_example.pdf", role: "support" }] }], reference: "PF-1042", note: "Supplier needs payment before collection", requested_by: "Buyer" },
|
||
{ id: "pay2", revision: 1, created: "2026-11-02 11:00:00.000Z", status: "draft", amount: 0, order: "order1", supplier: "supplier1", companyName: "Acme Engineering", orderNumber: "ORD26110201", supplierName: "Fastener Supply", items: ["line2"], lines: [{ id: "line2", description: "M16 washers", order_qty: 100, cost_price: 1 }], documents: [], purchaseOrders: [{ id: "po1", number: "PO202611001FAS", documents: [{ collection: "purchase_orders", recordId: "po1", filename: "po_example.pdf", role: "support" }] }], reference: "", note: "", requested_by: "Buyer" },
|
||
];
|
||
|
||
test("payment queue works on desktop and phone and requires proof", async ({ page }) => {
|
||
await page.addInitScript(() => {
|
||
const payload = btoa(JSON.stringify({ exp: 4102444800 }));
|
||
localStorage.setItem("pocketbase_auth", JSON.stringify({ token: `e30.${payload}.test`, record: { id: "test-user", collectionName: "users", name: "Test Buyer", email: "buyer@example.test" } }));
|
||
});
|
||
await page.route("**/api/v1/order-payments", (route) => route.fulfill({ json: { enabled: true, requests, approvals: [{ id: "approval1", order: "order2", companyName: "Mining Workshop", orderNumber: "ORD26110202", supplierName: "Supply House", description: "M20 studs", cost: 100, selling: 90, markup: -10 }] } }));
|
||
await page.route("**/api/v1/order-payments/pay1/paid", (route) => route.fulfill({ json: { request: { ...requests[0], status: "paid" } } }));
|
||
await page.goto("/orders/payments-approvals?request=pay1");
|
||
await expect(page.getByRole("heading", { name: "Payments and Approvals" })).toBeVisible();
|
||
await expect(page.getByRole("table")).toHaveCount(2);
|
||
await expect(page.getByText("-10.0%")).toBeVisible();
|
||
const row = page.getByRole("row").filter({ hasText: "M16 × 50 hex bolts" });
|
||
const markPaid = row.getByRole("button", { name: "Mark paid", exact: true });
|
||
await expect(markPaid).toBeDisabled();
|
||
await row.getByLabel("Proof of payment", { exact: true }).setInputFiles({ name: "proof.pdf", mimeType: "application/pdf", buffer: Buffer.from("%PDF-test") });
|
||
await expect(markPaid).toBeEnabled();
|
||
await page.setViewportSize({ width: 1440, height: 1100 });
|
||
await page.screenshot({ path: "test-results/order-payments-desktop.png", fullPage: true });
|
||
await page.setViewportSize({ width: 390, height: 844 });
|
||
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth)).toBe(true);
|
||
await page.screenshot({ path: "test-results/order-payments-mobile.png", fullPage: true });
|
||
const sent = page.waitForRequest((r) => r.url().endsWith("/order-payments/pay1/paid") && r.method() === "POST");
|
||
await markPaid.click();
|
||
const request = await sent;
|
||
expect(request.postData()).not.toContain("paid_amount");
|
||
expect(request.postData()).not.toContain("payment_reference");
|
||
await expect(page.getByRole("columnheader", { name: "Amount" })).toHaveCount(0);
|
||
});
|