- Showing received inventory by category for the past 12 months
+
+ Showing received inventory by category for the past 12 months
+ {yearlyCategoryData.length} categories found
@@ -607,27 +731,40 @@ export default function PurchaseOrders() {
{yearlyCategoryData.map((category) => {
// Calculate percentage of total spend
- const totalSpendPercentage = 'percentage' in category && typeof category.percentage === 'number'
- ? category.percentage
- : (yearlyCategoryData.reduce((sum, cat) => sum + cat.total_spend, 0) > 0
- ? (category.total_spend /
- yearlyCategoryData.reduce((sum, cat) => sum + cat.total_spend, 0))
- : 0);
-
+ const totalSpendPercentage =
+ "percentage" in category &&
+ typeof category.percentage === "number"
+ ? category.percentage
+ : yearlyCategoryData.reduce(
+ (sum, cat) => sum + cat.total_spend,
+ 0
+ ) > 0
+ ? category.total_spend /
+ yearlyCategoryData.reduce(
+ (sum, cat) => sum + cat.total_spend,
+ 0
+ )
+ : 0;
+
return (
- {category.category || 'Uncategorized'}
+ {category.category || "Uncategorized"}
{category.unique_products?.toLocaleString() || "N/A"}
- {category.avg_cost !== undefined ? formatCurrency(category.avg_cost) : "N/A"}
+ {category.avg_cost !== undefined
+ ? formatCurrency(category.avg_cost)
+ : "N/A"}
- {category.cost_variance !== undefined ?
- parseFloat(category.cost_variance.toFixed(2)).toLocaleString() : "N/A"}
+ {category.cost_variance !== undefined
+ ? parseFloat(
+ category.cost_variance.toFixed(2)
+ ).toLocaleString()
+ : "N/A"}
{formatCurrency(category.total_spend)}
@@ -649,28 +786,40 @@ export default function PurchaseOrders() {
// Display a record type indicator with appropriate styling
const getRecordTypeIndicator = (recordType: string) => {
switch (recordType) {
- case 'po_with_receiving':
+ case "po_with_receiving":
return (
-
+
Received PO
);
- case 'po_only':
+ case "po_only":
return (
-
+
PO
);
- case 'receiving_only':
+ case "receiving_only":
return (
-
+
Receiving
);
default:
return (
-
- {recordType || 'Unknown'}
+
+ {recordType || "Unknown"}
);
}
@@ -680,40 +829,50 @@ export default function PurchaseOrders() {
const prepareSpendingChartData = () => {
// Only use yearly data, no fallback
if (!yearlyCategoryData.length) return [];
-
+
// Make a copy to avoid modifying state directly
const categoryArray = [...yearlyCategoryData];
- const totalSpend = categoryArray.reduce((sum, cat) => sum + cat.total_spend, 0);
-
+ const totalSpend = categoryArray.reduce(
+ (sum, cat) => sum + cat.total_spend,
+ 0
+ );
+
// Split into significant categories (>=1%) and others
- const significantCategories = categoryArray
- .filter(cat => cat.total_spend / totalSpend >= 0.01);
-
- const otherCategories = categoryArray
- .filter(cat => cat.total_spend / totalSpend < 0.01);
-
+ const significantCategories = categoryArray.filter(
+ (cat) => cat.total_spend / totalSpend >= 0.01
+ );
+
+ const otherCategories = categoryArray.filter(
+ (cat) => cat.total_spend / totalSpend < 0.01
+ );
+
let result = [...significantCategories];
-
+
// Add "Other" category if needed
if (otherCategories.length > 0) {
const otherTotalSpend = otherCategories.reduce(
- (sum, cat) => sum + cat.total_spend, 0
+ (sum, cat) => sum + cat.total_spend,
+ 0
);
-
+
result.push({
- category: 'Other',
+ category: "Other",
total_spend: otherTotalSpend,
percentage: otherTotalSpend / totalSpend,
unique_products: otherCategories.reduce(
- (sum, cat) => sum + (cat.unique_products || 0), 0
+ (sum, cat) => sum + (cat.unique_products || 0),
+ 0
),
- avg_cost: otherTotalSpend / otherCategories.reduce(
- (sum, cat) => sum + (cat.unique_products || 0), 1
- ),
- cost_variance: 0
+ avg_cost:
+ otherTotalSpend /
+ otherCategories.reduce(
+ (sum, cat) => sum + (cat.unique_products || 0),
+ 1
+ ),
+ cost_variance: 0,
});
}
-
+
// Sort by spend amount descending
return result.sort((a, b) => b.total_spend - a.total_spend);
};
@@ -722,34 +881,40 @@ export default function PurchaseOrders() {
const prepareVendorChartData = () => {
// Only use yearly data, no fallback
if (!yearlyVendorData.length) return [];
-
+
// Make a copy to avoid modifying state directly
const vendorArray = [...yearlyVendorData];
- const totalSpend = vendorArray.reduce((sum, vendor) => sum + vendor.total_spend, 0);
-
+ const totalSpend = vendorArray.reduce(
+ (sum, vendor) => sum + vendor.total_spend,
+ 0
+ );
+
// Split into significant vendors (>=1%) and others
- const significantVendors = vendorArray
- .filter(vendor => vendor.total_spend / totalSpend >= 0.01);
-
- const otherVendors = vendorArray
- .filter(vendor => vendor.total_spend / totalSpend < 0.01);
-
+ const significantVendors = vendorArray.filter(
+ (vendor) => vendor.total_spend / totalSpend >= 0.01
+ );
+
+ const otherVendors = vendorArray.filter(
+ (vendor) => vendor.total_spend / totalSpend < 0.01
+ );
+
let result = [...significantVendors];
-
+
// Add "Other" category if needed
if (otherVendors.length > 0) {
const otherTotalSpend = otherVendors.reduce(
- (sum, vendor) => sum + vendor.total_spend, 0
+ (sum, vendor) => sum + vendor.total_spend,
+ 0
);
-
+
result.push({
- vendor: 'Other Vendors',
+ vendor: "Other Vendors",
total_spend: otherTotalSpend,
percentage: otherTotalSpend / totalSpend,
- orders: otherVendors.reduce((sum, vendor) => sum + vendor.orders, 0)
+ orders: otherVendors.reduce((sum, vendor) => sum + vendor.orders, 0),
});
}
-
+
// Sort by spend amount descending
return result.sort((a, b) => b.total_spend - a.total_spend);
};
@@ -758,14 +923,14 @@ export default function PurchaseOrders() {
const getAllVendorsForTable = () => {
// Now only use yearlyVendorData and never fall back to current page data
if (!yearlyVendorData.length) return [];
-
+
return [...yearlyVendorData].sort((a, b) => b.total_spend - a.total_spend);
};
// Update the VendorAnalysisTable to always show yearly data
const VendorAnalysisTable = () => {
const vendorData = getAllVendorsForTable();
-
+
if (!vendorData.length) {
return yearlyDataLoading ? (
@@ -777,7 +942,7 @@ export default function PurchaseOrders() {
- Showing received inventory by vendor for the past 12 months
+
+ Showing received inventory by vendor for the past 12 months
+ {vendorData.length} vendors found