serial numbers

This commit is contained in:
2026-10-07 14:00:32 +05:30
committed by ImanThiyanga
parent 3abcfa6e6f
commit a788349138
89 changed files with 15320 additions and 216 deletions
@@ -44,6 +44,7 @@ import {
Receipt,
ReceiptText,
Scale,
ScanLine,
ScrollText,
Settings,
ShieldCheck,
@@ -60,6 +61,9 @@ import {
import { cn } from "@/lib/utils"
import { useAuth } from "@/components/auth/AuthProvider"
import { useTrackingSettings } from "@/hooks/use-tracking-settings"
const SERIALS_HREF = "/dashboard/stock/serials"
// `code` must match the seeded NavItem/SubNavItem codes in ERPCore
// (Infra/Persistence/Configurations/NavItemConfiguration.cs / SubNavItemConfiguration.cs)
@@ -148,6 +152,9 @@ const navItems: {
children: [
{ title: "Stock Ledger", code: "stock.ledger", href: "/dashboard/stock/ledger", icon: ScrollText },
{ title: "Stock Enquiry", code: "stock.enquiry", href: "/dashboard/stock/enquiry", icon: PackageSearch },
// Serial register and batch expiry are enquiries — they reuse stock.enquiry's permission code.
{ title: "Serials", code: "stock.enquiry", href: "/dashboard/stock/serials", icon: ScanLine },
{ title: "Batch Expiry", code: "stock.enquiry", href: "/dashboard/stock/batches", icon: CalendarClock },
{ title: "Valuation", code: "stock.valuation", href: "/dashboard/stock/valuation", icon: BadgeDollarSign },
{ title: "Transfers", code: "stock.transfers", href: "/dashboard/stock/transfers", icon: ArrowLeftRight },
{ title: "Adjustments", code: "stock.adjustments", href: "/dashboard/stock/adjustments", icon: SlidersHorizontal },
@@ -427,6 +434,8 @@ export function AppSidebar() {
const [collapsed, setCollapsed] = useState(false)
const [mobileOpen, setMobileOpen] = useState(false)
const { navCodes, loading } = useAuth()
// The Serials register is hidden while serial numbers are switched off in Product Configuration.
const { serialNumbersEnabled } = useTrackingSettings()
// While /auth/me hasn't resolved yet, show nothing rather than briefly
// flashing the full menu to a restricted role. Once resolved, a nav item
@@ -452,9 +461,10 @@ export function AppSidebar() {
)
.map((item) => ({
...item,
children: bypassCodes.has(item.code)
children: (bypassCodes.has(item.code)
? item.children
: item.children?.filter((c) => navCodes.includes(c.code) || c.altCodes?.some((ac) => navCodes.includes(ac))),
: item.children?.filter((c) => navCodes.includes(c.code) || c.altCodes?.some((ac) => navCodes.includes(ac)))
)?.filter((c) => !(serialNumbersEnabled === false && c.href === SERIALS_HREF)),
}))
// Close mobile menu on route change
@@ -30,6 +30,9 @@ const SEGMENT_LABELS: Record<string, string> = {
counts: "Counts",
"reorder-alerts": "Reorder Alerts",
wastage: "Wastage",
serials: "Serials",
batches: "Batch Expiry",
warranties: "Warranties",
procurement: "Procurement",
requisitions: "Requisitions",
rfqs: "RFQs",
@@ -88,6 +88,8 @@ const STOCK_TITLES: Record<string, string> = {
"/dashboard/stock/reorder-alerts": "Reorder Alerts",
"/dashboard/stock/wastage": "Wastage",
"/dashboard/stock/wastage/new": "Record Wastage",
"/dashboard/stock/serials": "Serials",
"/dashboard/stock/batches": "Batch Expiry",
}
const PRODUCTION_TITLES: Record<string, string> = {
@@ -101,6 +103,7 @@ const PRODUCTION_TITLES: Record<string, string> = {
function titleFromPath(pathname: string) {
if (pathname === "/dashboard/sales/invoices") return "Sales"
if (pathname === "/dashboard/sales/invoices/new") return "New Sale"
if (pathname === "/dashboard/sales/warranties") return "Warranties"
if (pathname === "/dashboard/receiving/grn") return "Goods Receipt Notes"
if (pathname === "/dashboard/receiving/grn/new") return "Create Goods Receipt Note"