feat(purchasing): show 'Supplier unknown' badge when OCR couldn't extract supplier
This commit is contained in:
parent
e3c2e0396d
commit
9897f477b6
3 changed files with 53 additions and 6 deletions
|
|
@ -23,7 +23,7 @@ import {
|
|||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { SlipPreview } from "@/components/slip-preview";
|
||||
import { cn, formatCurrency, formatNumber } from "@/lib/utils";
|
||||
import { cn, formatCurrency, formatNumber, isUnknownSupplier } from "@/lib/utils";
|
||||
import type { DeliveryNoteProcessingStatus } from "@/lib/pb-types";
|
||||
|
||||
export interface PoDetailItem {
|
||||
|
|
@ -152,7 +152,17 @@ export function PoDetailView({ detail }: { detail: PoDetail }) {
|
|||
<h2 className="font-mono text-lg font-semibold tracking-tight">
|
||||
{detail.poNumber}
|
||||
</h2>
|
||||
<span className="text-base font-medium">{detail.supplier || "—"}</span>
|
||||
{isUnknownSupplier(detail.supplier) ? (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="gap-1.5 border-amber-500/40 bg-amber-500/15 px-2 py-0.5 text-amber-700 dark:text-amber-300"
|
||||
>
|
||||
<AlertTriangle className="h-3.5 w-3.5" />
|
||||
Supplier unknown
|
||||
</Badge>
|
||||
) : (
|
||||
<span className="text-base font-medium">{detail.supplier}</span>
|
||||
)}
|
||||
<Badge variant="outline" className="font-mono text-xs">
|
||||
{detail.projectCode || "—"}
|
||||
</Badge>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import {
|
|||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Pagination } from "@/components/ui/pagination";
|
||||
import { cn, formatCurrency, formatNumber } from "@/lib/utils";
|
||||
import { cn, formatCurrency, formatNumber, isUnknownSupplier } from "@/lib/utils";
|
||||
|
||||
const PAGE_SIZE = 25;
|
||||
const PO_BASE = "/dashboard/purchasing";
|
||||
|
|
@ -331,9 +331,19 @@ function PoListItem({ po }: { po: PoRow }) {
|
|||
<div className="min-w-0 flex-1">
|
||||
<div className="flex flex-wrap items-baseline gap-x-3 gap-y-1">
|
||||
<span className="font-mono text-sm font-semibold">{po.poNumber}</span>
|
||||
<span className="truncate text-sm text-foreground">
|
||||
{po.supplier || "—"}
|
||||
</span>
|
||||
{isUnknownSupplier(po.supplier) ? (
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="gap-1 border-amber-500/40 bg-amber-500/15 text-amber-700 dark:text-amber-300"
|
||||
>
|
||||
<AlertTriangle className="h-3 w-3" />
|
||||
Supplier unknown
|
||||
</Badge>
|
||||
) : (
|
||||
<span className="truncate text-sm text-foreground">
|
||||
{po.supplier}
|
||||
</span>
|
||||
)}
|
||||
<Badge variant="outline" className="font-mono text-xs">
|
||||
{po.projectCode || "—"}
|
||||
</Badge>
|
||||
|
|
|
|||
|
|
@ -23,3 +23,30 @@ export function formatCurrency(n: number, currency = "ZAR") {
|
|||
export function formatPercent(n: number, digits = 1) {
|
||||
return `${n.toFixed(digits)}%`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strings that mean "OCR could not extract a real supplier" rather than
|
||||
* a real vendor name. The OCR pipeline writes "Not specified in
|
||||
* document" verbatim when the supplier line is missing; other placeholders
|
||||
* ("Unknown", "N/A", "—") cover other pipelines. Anything in this set
|
||||
* (case-insensitive, trimmed) renders as "Supplier unknown" in the UI
|
||||
* instead of being displayed as if it were a real supplier.
|
||||
*
|
||||
* Kept as a Set literal rather than reading from config so it's easy to
|
||||
* grep and extend — add more aliases here when OCR pipelines change.
|
||||
*/
|
||||
const UNKNOWN_SUPPLIER_ALIASES = new Set([
|
||||
"",
|
||||
"—",
|
||||
"-",
|
||||
"n/a",
|
||||
"na",
|
||||
"unknown",
|
||||
"not specified",
|
||||
"not specified in document",
|
||||
]);
|
||||
|
||||
export function isUnknownSupplier(supplier: string | undefined | null): boolean {
|
||||
if (!supplier) return true;
|
||||
return UNKNOWN_SUPPLIER_ALIASES.has(supplier.trim().toLowerCase());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue