feat(odin): received-invoices expense totals with CZK conversion
get_document_totals gains type=received_invoices: whole-set gross sums per currency + total_czk via the same toCzk logic as the stats route (unknown currencies skipped + reported), month/year via the literal columns (bare year supported), unpaid/paid filter, period echo. invoices.view joined the coarse gate (the per-type re-check keeps other families locked); the tool description routes 'kolik jsme utratili' questions here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -765,6 +765,34 @@ describe("ai-tools — employees, attendance detail, trips, work plan", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("get_document_totals: received_invoices sums gross + converts to CZK", async () => {
|
||||
// invoices.view alone unlocks the received-invoices branch.
|
||||
const res = await executeTool(
|
||||
"get_document_totals",
|
||||
{ type: "received_invoices", month: 6, year: 2098 },
|
||||
VIEWER_INVOICES,
|
||||
);
|
||||
expect(res.ok).toBe(true);
|
||||
const r = res.result as {
|
||||
period: string;
|
||||
invoice_count: number;
|
||||
totals: { currency: string; amount: number }[];
|
||||
total_czk: number;
|
||||
};
|
||||
expect(r.period).toBe("6/2098");
|
||||
expect(r.invoice_count).toBe(1);
|
||||
expect(r.totals).toEqual([{ currency: "CZK", amount: 1210 }]);
|
||||
expect(r.total_czk).toBe(1210); // CZK rows convert 1:1, no rate fetch
|
||||
|
||||
// orders.view alone cannot read expense totals.
|
||||
const denied = await executeTool(
|
||||
"get_document_totals",
|
||||
{ type: "received_invoices" },
|
||||
{ userId: 999999998, roleName: "viewer", permissions: ["orders.view"] },
|
||||
);
|
||||
expect(denied.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("get_top_customers aggregates per customer across the whole table", async () => {
|
||||
const res = await executeTool(
|
||||
"get_top_customers",
|
||||
|
||||
Reference in New Issue
Block a user