pelagia-portal/App/tests/integration/approved-this-month.test.ts
Claude (auto-fix) fdc3ebdac9 fix(dashboard): count all POs approved this month, not just current MGR_APPROVED
The manager dashboard "Approved This Month" card only counted POs whose
current status is MGR_APPROVED, so approvals that had already moved on to
payment, delivery, or closure dropped out of the count. Managers could not
see what happened to the POs they approved this month.

- Count every PO whose `approvedAt` falls in the current month across all
  post-approval statuses (MGR_APPROVED → ... → CLOSED). `approvedAt` is set
  once at approval and persists, so it is the correct anchor.
- Introduce a shared `POST_APPROVAL_STATUSES` constant (includes the
  previously-omitted PARTIALLY_CLOSED). This also fixes Total Approved Spend
  and the vessel/monthly breakdowns, which were silently dropping
  partially-received POs.
- Make the card a link into /history with an approval-date filter applied
  (?approvedFrom=<startOfMonth>) so a click shows the full set with each PO's
  current status, as requested.
- Add `approvedFrom`/`approvedTo` filtering to the history page, its filter
  UI, and the reports export route so the deep-link and exports stay in sync.

Scope note: the count remains org-wide, consistent with every other card on
the manager dashboard.

Adds an integration test covering the moved-on case and the date window.

Fixes #32
2026-06-19 12:07:53 +05:30

105 lines
4.1 KiB
TypeScript

/**
* Integration test for the manager dashboard "Approved This Month" card.
*
* Regression: the card previously counted only POs *currently* in MGR_APPROVED,
* so POs approved this month that had moved on to payment/delivery/closure were
* dropped from the count. The card must count every PO approved this month
* regardless of its current (post-approval) status, and the same approval-date
* window must be reproducible on the /history page (where the card links to).
*/
import { describe, it, expect, beforeAll, afterEach } from "vitest";
import { db } from "@/lib/db";
import { POST_APPROVAL_STATUSES } from "@/lib/utils";
import { deletePosByTitle } from "./helpers";
import type { POStatus } from "@prisma/client";
const PREFIX = "INTTEST_APPROVED_MONTH_";
let submitterId: string;
let vesselId: string;
let accountId: string;
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
const midThisMonth = new Date(now.getFullYear(), now.getMonth(), 15, 12, 0, 0);
const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 15, 12, 0, 0);
beforeAll(async () => {
// Resolve any existing cost-centre / account / user from the test DB rather
// than relying on dev-seed fixtures (the test DB is a production mirror).
const [user, vessel, account] = await Promise.all([
db.user.findFirstOrThrow({ where: { role: "MANAGER" } }),
db.vessel.findFirstOrThrow(),
db.account.findFirstOrThrow(),
]);
submitterId = user.id;
vesselId = vessel.id;
accountId = account.id;
});
afterEach(async () => {
await deletePosByTitle(PREFIX);
});
let seq = 0;
async function makePo(opts: { title: string; status: POStatus; approvedAt: Date | null }) {
seq += 1;
return db.purchaseOrder.create({
data: {
poNumber: `${PREFIX}${Date.now()}_${seq}`,
title: opts.title,
status: opts.status,
totalAmount: 1000,
approvedAt: opts.approvedAt,
submitterId,
vesselId,
accountId,
},
});
}
/** Mirrors the dashboard "Approved This Month" query. */
function approvedThisMonthWhere() {
return {
title: { startsWith: PREFIX },
status: { in: [...POST_APPROVAL_STATUSES] },
approvedAt: { gte: startOfMonth },
};
}
describe("Approved This Month count", () => {
it("counts POs approved this month across every post-approval status", async () => {
await makePo({ title: `${PREFIX}approved`, status: "MGR_APPROVED", approvedAt: midThisMonth });
await makePo({ title: `${PREFIX}sent`, status: "SENT_FOR_PAYMENT", approvedAt: midThisMonth });
await makePo({ title: `${PREFIX}partpaid`, status: "PARTIALLY_PAID", approvedAt: midThisMonth });
await makePo({ title: `${PREFIX}paid`, status: "PAID_DELIVERED", approvedAt: midThisMonth });
await makePo({ title: `${PREFIX}partclosed`, status: "PARTIALLY_CLOSED", approvedAt: midThisMonth });
await makePo({ title: `${PREFIX}closed`, status: "CLOSED", approvedAt: midThisMonth });
const count = await db.purchaseOrder.count({ where: approvedThisMonthWhere() });
expect(count).toBe(6);
});
it("excludes POs approved in a previous month and POs never approved", async () => {
await makePo({ title: `${PREFIX}closed_lastmonth`, status: "CLOSED", approvedAt: lastMonth });
await makePo({ title: `${PREFIX}awaiting`, status: "MGR_REVIEW", approvedAt: null });
await makePo({ title: `${PREFIX}closed_thismonth`, status: "CLOSED", approvedAt: midThisMonth });
const count = await db.purchaseOrder.count({ where: approvedThisMonthWhere() });
expect(count).toBe(1);
});
it("would have missed moved-on POs under the old MGR_APPROVED-only filter", async () => {
// A PO approved this month that has since closed — the case from issue #32.
await makePo({ title: `${PREFIX}moved_on`, status: "CLOSED", approvedAt: midThisMonth });
const oldCount = await db.purchaseOrder.count({
where: { title: { startsWith: PREFIX }, status: "MGR_APPROVED", approvedAt: { gte: startOfMonth } },
});
const newCount = await db.purchaseOrder.count({ where: approvedThisMonthWhere() });
expect(oldCount).toBe(0);
expect(newCount).toBe(1);
});
});