Fix up more purchase order stuff
This commit is contained in:
@@ -65,6 +65,14 @@ interface ReceivingStatus {
|
||||
|
||||
interface PurchaseOrdersResponse {
|
||||
orders: PurchaseOrder[];
|
||||
summary: {
|
||||
order_count: number;
|
||||
total_ordered: number;
|
||||
total_received: number;
|
||||
fulfillment_rate: number;
|
||||
total_value: number;
|
||||
avg_cost: number;
|
||||
};
|
||||
pagination: {
|
||||
total: number;
|
||||
pages: number;
|
||||
@@ -81,7 +89,7 @@ export default function PurchaseOrders() {
|
||||
const [purchaseOrders, setPurchaseOrders] = useState<PurchaseOrder[]>([]);
|
||||
const [vendorMetrics, setVendorMetrics] = useState<VendorMetrics[]>([]);
|
||||
const [costAnalysis, setCostAnalysis] = useState<CostAnalysis | null>(null);
|
||||
const [receivingStatus, setReceivingStatus] = useState<ReceivingStatus | null>(null);
|
||||
const [summary, setSummary] = useState<ReceivingStatus | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [page, setPage] = useState(1);
|
||||
const [sortColumn, setSortColumn] = useState<string>('order_date');
|
||||
@@ -120,33 +128,29 @@ export default function PurchaseOrders() {
|
||||
const [
|
||||
purchaseOrdersRes,
|
||||
vendorMetricsRes,
|
||||
costAnalysisRes,
|
||||
receivingStatusRes
|
||||
costAnalysisRes
|
||||
] = await Promise.all([
|
||||
fetch(`/api/purchase-orders?${searchParams}`),
|
||||
fetch('/api/purchase-orders/vendor-metrics'),
|
||||
fetch('/api/purchase-orders/cost-analysis'),
|
||||
fetch('/api/purchase-orders/receiving-status')
|
||||
fetch('/api/purchase-orders/cost-analysis')
|
||||
]);
|
||||
|
||||
const [
|
||||
purchaseOrdersData,
|
||||
vendorMetricsData,
|
||||
costAnalysisData,
|
||||
receivingStatusData
|
||||
costAnalysisData
|
||||
] = await Promise.all([
|
||||
purchaseOrdersRes.json(),
|
||||
vendorMetricsRes.json(),
|
||||
costAnalysisRes.json(),
|
||||
receivingStatusRes.json()
|
||||
costAnalysisRes.json()
|
||||
]);
|
||||
|
||||
setPurchaseOrders(purchaseOrdersData.orders);
|
||||
setPagination(purchaseOrdersData.pagination);
|
||||
setFilterOptions(purchaseOrdersData.filters);
|
||||
setSummary(purchaseOrdersData.summary);
|
||||
setVendorMetrics(vendorMetricsData);
|
||||
setCostAnalysis(costAnalysisData);
|
||||
setReceivingStatus(receivingStatusData);
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error);
|
||||
} finally {
|
||||
@@ -179,6 +183,20 @@ export default function PurchaseOrders() {
|
||||
return <Badge variant={statusConfig.variant}>{statusConfig.label}</Badge>;
|
||||
};
|
||||
|
||||
const formatNumber = (value: number) => {
|
||||
return value.toLocaleString('en-US', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
});
|
||||
};
|
||||
|
||||
const formatPercent = (value: number) => {
|
||||
return (value * 100).toLocaleString('en-US', {
|
||||
minimumFractionDigits: 1,
|
||||
maximumFractionDigits: 1
|
||||
}) + '%';
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
@@ -198,7 +216,7 @@ export default function PurchaseOrders() {
|
||||
<CardTitle className="text-sm font-medium">Total Orders</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">{receivingStatus?.order_count || 0}</div>
|
||||
<div className="text-2xl font-bold">{summary?.order_count.toLocaleString() || 0}</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card>
|
||||
@@ -207,7 +225,7 @@ export default function PurchaseOrders() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
${(receivingStatus?.total_value || 0).toFixed(2)}
|
||||
${formatNumber(summary?.total_value || 0)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -217,7 +235,7 @@ export default function PurchaseOrders() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
{((receivingStatus?.fulfillment_rate || 0) * 100).toFixed(1)}%
|
||||
{formatPercent(summary?.fulfillment_rate || 0)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -227,7 +245,7 @@ export default function PurchaseOrders() {
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-2xl font-bold">
|
||||
${(receivingStatus?.avg_cost || 0).toFixed(2)}
|
||||
${formatNumber(summary?.avg_cost || 0)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -326,11 +344,11 @@ export default function PurchaseOrders() {
|
||||
<TableCell>{po.vendor_name}</TableCell>
|
||||
<TableCell>{new Date(po.order_date).toLocaleDateString()}</TableCell>
|
||||
<TableCell>{getStatusBadge(po.status)}</TableCell>
|
||||
<TableCell>{po.total_items}</TableCell>
|
||||
<TableCell>{po.total_quantity}</TableCell>
|
||||
<TableCell>${po.total_cost.toFixed(2)}</TableCell>
|
||||
<TableCell>{po.total_received}</TableCell>
|
||||
<TableCell>{(po.fulfillment_rate * 100).toFixed(1)}%</TableCell>
|
||||
<TableCell>{po.total_items.toLocaleString()}</TableCell>
|
||||
<TableCell>{po.total_quantity.toLocaleString()}</TableCell>
|
||||
<TableCell>${formatNumber(po.total_cost)}</TableCell>
|
||||
<TableCell>{po.total_received.toLocaleString()}</TableCell>
|
||||
<TableCell>{formatPercent(po.fulfillment_rate)}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
{!purchaseOrders.length && (
|
||||
@@ -398,11 +416,11 @@ export default function PurchaseOrders() {
|
||||
{vendorMetrics.map((vendor) => (
|
||||
<TableRow key={vendor.vendor_name}>
|
||||
<TableCell>{vendor.vendor_name}</TableCell>
|
||||
<TableCell>{vendor.total_orders}</TableCell>
|
||||
<TableCell>{vendor.avg_delivery_days.toFixed(1)}</TableCell>
|
||||
<TableCell>{(vendor.fulfillment_rate * 100).toFixed(1)}%</TableCell>
|
||||
<TableCell>${vendor.avg_unit_cost.toFixed(2)}</TableCell>
|
||||
<TableCell>${vendor.total_spend.toFixed(2)}</TableCell>
|
||||
<TableCell>{vendor.total_orders.toLocaleString()}</TableCell>
|
||||
<TableCell>{vendor.avg_delivery_days?.toFixed(1) || 'N/A'}</TableCell>
|
||||
<TableCell>{formatPercent(vendor.fulfillment_rate)}</TableCell>
|
||||
<TableCell>${formatNumber(vendor.avg_unit_cost)}</TableCell>
|
||||
<TableCell>${formatNumber(vendor.total_spend)}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
@@ -427,7 +445,7 @@ export default function PurchaseOrders() {
|
||||
{costAnalysis?.total_spend_by_category?.map((category) => (
|
||||
<TableRow key={category.category}>
|
||||
<TableCell>{category.category}</TableCell>
|
||||
<TableCell>${category.total_spend.toFixed(2)}</TableCell>
|
||||
<TableCell>${formatNumber(category.total_spend)}</TableCell>
|
||||
</TableRow>
|
||||
)) || (
|
||||
<TableRow>
|
||||
|
||||
Reference in New Issue
Block a user