From 35a6b847e658f5ecc674457ce6fa6d292b5a273b Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Mon, 8 Dec 2025 23:01:34 +0000 Subject: [PATCH] Added inventory overview. --- .../Dashboard/Inventory/InventoryOverview.jsx | 102 ++++++++++++++++++ .../Dashboard/Inventory/InventorySidebar.jsx | 4 +- src/database/models/PartStock.js | 9 ++ src/database/models/PurchaseOrder.js | 20 ++-- src/routes/InventoryRoutes.jsx | 6 ++ 5 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 src/components/Dashboard/Inventory/InventoryOverview.jsx diff --git a/src/components/Dashboard/Inventory/InventoryOverview.jsx b/src/components/Dashboard/Inventory/InventoryOverview.jsx new file mode 100644 index 0000000..8d93f7e --- /dev/null +++ b/src/components/Dashboard/Inventory/InventoryOverview.jsx @@ -0,0 +1,102 @@ +import { useContext } from 'react' +import { Flex } from 'antd' +import useCollapseState from '../hooks/useCollapseState' +import StatsDisplay from '../common/StatsDisplay' +import InfoCollapse from '../common/InfoCollapse' +import ScrollBox from '../common/ScrollBox' + +import { ApiServerContext } from '../context/ApiServerContext' + +const InventoryOverview = () => { + const { connected } = useContext(ApiServerContext) + + const [collapseState, updateCollapseState] = useCollapseState( + 'InventoryOverview', + { + inventoryStats: true + } + ) + + if (!connected) { + return null + } + + return ( + + + + + updateCollapseState('inventoryStats', isActive) + } + className='no-t-padding-collapse' + collapseKey='inventoryStats' + > + + + + + + + + + + + + updateCollapseState('partStockHistory', isActive) + } + collapseKey='partStockHistory' + canCollapse={false} + > + + + + updateCollapseState('filamentStockHistory', isActive) + } + canCollapse={false} + collapseKey='filamentStockHistory' + > + + + + updateCollapseState('stockEventHistory', isActive) + } + canCollapse={false} + collapseKey='stockEventHistory' + > + + + + + + ) +} + +export default InventoryOverview diff --git a/src/components/Dashboard/Inventory/InventorySidebar.jsx b/src/components/Dashboard/Inventory/InventorySidebar.jsx index 10a47b7..803ed66 100644 --- a/src/components/Dashboard/Inventory/InventorySidebar.jsx +++ b/src/components/Dashboard/Inventory/InventorySidebar.jsx @@ -1,6 +1,5 @@ import { useLocation } from 'react-router-dom' import DashboardSidebar from '../common/DashboardSidebar' -import { DashboardOutlined } from '@ant-design/icons' import FilamentStockIcon from '../../Icons/FilamentStockIcon' import PartStockIcon from '../../Icons/PartStockIcon' import ProductStockIcon from '../../Icons/ProductStockIcon' @@ -9,12 +8,13 @@ import StockAuditIcon from '../../Icons/StockAuditIcon' import PurchaseOrderIcon from '../../Icons/PurchaseOrderIcon' import ShipmentIcon from '../../Icons/ShipmentIcon' import OrderItemIcon from '../../Icons/OrderItemIcon' +import InventoryIcon from '../../Icons/InventoryIcon' const items = [ { key: 'overview', label: 'Overview', - icon: , + icon: , path: '/dashboard/inventory/overview' }, { type: 'divider' }, diff --git a/src/database/models/PartStock.js b/src/database/models/PartStock.js index 2ce318c..217ee85 100644 --- a/src/database/models/PartStock.js +++ b/src/database/models/PartStock.js @@ -101,5 +101,14 @@ export const PartStock = { } } } + ], + stats: [ + { + name: 'totalCurrentQuantity.sum', + label: 'Total Current Quantity', + type: 'number', + roundNumber: 2, + cardWidth: 200 + } ] } diff --git a/src/database/models/PurchaseOrder.js b/src/database/models/PurchaseOrder.js index 8d366d7..28dfcaf 100644 --- a/src/database/models/PurchaseOrder.js +++ b/src/database/models/PurchaseOrder.js @@ -46,13 +46,22 @@ export const PurchaseOrder = { type: 'dateTime', readOnly: true }, - { name: 'state', label: 'State', type: 'state', readOnly: true }, + { + name: '_reference', + label: 'Reference', + type: 'reference', + required: true, + objectType: 'purchaseOrder', + showCopy: true, + readOnly: true + }, { name: 'updatedAt', label: 'Updated At', type: 'dateTime', readOnly: true }, + { name: 'state', label: 'State', type: 'state', readOnly: true }, { name: 'vendor', label: 'Vendor', @@ -65,17 +74,10 @@ export const PurchaseOrder = { name: 'cost', label: 'Cost', type: 'netGross', - required: true, prefix: '£', min: 0, step: 0.01, - value: (objectData) => { - const net = objectData?.items?.reduce( - (acc, item) => acc + item.price, - 0 - ) - return { net: net, gross: net } - } + readOnly: true } ] } diff --git a/src/routes/InventoryRoutes.jsx b/src/routes/InventoryRoutes.jsx index e47f1ca..733d89b 100644 --- a/src/routes/InventoryRoutes.jsx +++ b/src/routes/InventoryRoutes.jsx @@ -13,8 +13,14 @@ import OrderItems from '../components/Dashboard/Inventory/OrderItems.jsx' import OrderItemInfo from '../components/Dashboard/Inventory/OrderItems/OrderItemInfo.jsx' import Shipments from '../components/Dashboard/Inventory/Shipments.jsx' import ShipmentInfo from '../components/Dashboard/Inventory/Shipments/ShipmentInfo.jsx' +import InventoryOverview from '../components/Dashboard/Inventory/InventoryOverview.jsx' const InventoryRoutes = [ + } + />,