feat(procurement): enhance purchase order and GRN functionalities
- Updated purchase order descriptions for clarity on draft and submission processes. - Implemented submit and delete functionalities for draft purchase orders, allowing users to manage their orders more effectively. - Added discount and VAT fields to GRN lines, enabling better cost tracking and reporting. - Enhanced validation for GRN lines to ensure discount and VAT percentages are within acceptable ranges. - Updated API to support new functionalities, including submitting and deleting purchase orders. - Improved UI components for better user experience in managing purchase orders and GRNs. - Documented changes in security and backend phase documentation to reflect new processes and requirements.
This commit is contained in:
@@ -8,12 +8,14 @@ import {
|
||||
Building2,
|
||||
ChevronRight,
|
||||
ClipboardList,
|
||||
FileText,
|
||||
HelpCircle,
|
||||
LayoutGrid,
|
||||
ListTree,
|
||||
Menu,
|
||||
Package,
|
||||
PackageCheck,
|
||||
PackageX,
|
||||
Ruler,
|
||||
Settings,
|
||||
ShieldCheck,
|
||||
@@ -56,7 +58,19 @@ const navItems: {
|
||||
],
|
||||
},
|
||||
{ title: "Vendors", code: "vendors", href: "/dashboard/vendors", icon: Truck, chevron: true },
|
||||
{ title: "Procurement", code: "procurement", href: "/dashboard/procurement", icon: ClipboardList, chevron: true },
|
||||
{
|
||||
title: "Procurement",
|
||||
code: "procurement",
|
||||
href: "/dashboard/procurement",
|
||||
icon: ClipboardList,
|
||||
chevron: true,
|
||||
children: [
|
||||
{ title: "Requisitions", code: "procurement.requisitions", href: "/dashboard/procurement/requisitions", icon: ClipboardList },
|
||||
{ title: "RFQs", code: "procurement.rfqs", href: "/dashboard/procurement/rfqs", icon: FileText },
|
||||
{ title: "Purchase Orders", code: "procurement.purchase-orders", href: "/dashboard/procurement/purchase-orders", icon: ShoppingCart },
|
||||
{ title: "Purchase Returns", code: "procurement.purchase-returns", href: "/dashboard/procurement/purchase-returns", icon: PackageX },
|
||||
],
|
||||
},
|
||||
{ title: "Receiving", code: "receiving", href: "/dashboard/receiving/grn", icon: PackageCheck, chevron: true },
|
||||
{ title: "Stock", code: "stock", href: "/dashboard/stock", icon: Warehouse, chevron: true },
|
||||
{ title: "Warehouses", code: "warehouses", href: "/dashboard/warehouse", icon: Building2, chevron: true },
|
||||
|
||||
@@ -6,7 +6,40 @@ import { Select as SelectPrimitive } from "@base-ui/react/select"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
|
||||
|
||||
const Select = SelectPrimitive.Root
|
||||
// Base UI's `Select.Value` renders the raw selected value (e.g. an id) unless the Root is
|
||||
// given an `items` map to resolve the label from — the popup items are unmounted when closed,
|
||||
// so their text isn't otherwise available. Rather than pass `items` at all ~60 call sites,
|
||||
// this wrapper walks its own `SelectItem` children and derives that map automatically, so the
|
||||
// trigger shows the selected item's label instead of its value.
|
||||
function collectItems(
|
||||
children: React.ReactNode,
|
||||
acc: { value: unknown; label: React.ReactNode }[]
|
||||
) {
|
||||
React.Children.forEach(children, (child) => {
|
||||
if (!React.isValidElement(child)) return
|
||||
if (child.type === SelectItem) {
|
||||
const p = child.props as { value?: unknown; children?: React.ReactNode }
|
||||
acc.push({ value: p.value, label: p.children })
|
||||
return
|
||||
}
|
||||
const nested = (child.props as { children?: React.ReactNode }).children
|
||||
if (nested) collectItems(nested, acc)
|
||||
})
|
||||
}
|
||||
|
||||
function Select<Value, Multiple extends boolean | undefined = false>(
|
||||
props: SelectPrimitive.Root.Props<Value, Multiple>
|
||||
) {
|
||||
const { items, children } = props
|
||||
const derivedItems = React.useMemo(() => {
|
||||
if (items) return items
|
||||
const acc: { value: unknown; label: React.ReactNode }[] = []
|
||||
collectItems(children, acc)
|
||||
return acc.length ? (acc as ReadonlyArray<{ value: Value; label: React.ReactNode }>) : undefined
|
||||
}, [items, children])
|
||||
|
||||
return <SelectPrimitive.Root {...props} items={derivedItems} />
|
||||
}
|
||||
|
||||
function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user