diff --git a/src/pages/accounting/AccountingChartOfAccountsPage.tsx b/src/pages/accounting/AccountingChartOfAccountsPage.tsx index 7b8bcef..191b1d6 100644 --- a/src/pages/accounting/AccountingChartOfAccountsPage.tsx +++ b/src/pages/accounting/AccountingChartOfAccountsPage.tsx @@ -49,6 +49,7 @@ export default function AccountingChartOfAccountsPage() { const [type, setType] = useState("asset"); const [isBank, setIsBank] = useState(false); const [isReserve, setIsReserve] = useState(false); + const [category, setCategory] = useState(""); const [description, setDescription] = useState(""); const [parentId, setParentId] = useState(""); @@ -63,6 +64,7 @@ export default function AccountingChartOfAccountsPage() { parent_account_id: "no_change", is_bank: "no_change", is_reserve: "no_change", + category: "", }); // ── Opening balances state ── @@ -139,10 +141,16 @@ export default function AccountingChartOfAccountsPage() { return out; }, [accounts]); + // Existing category names (for the Income Statement subgroups) — used as autocomplete suggestions. + const existingCategories = useMemo( + () => [...new Set((accounts as any[]).map((a) => a.category).filter(Boolean) as string[])].sort((a, b) => a.localeCompare(b)), + [accounts], + ); + // ── Accounts actions ── const resetForm = () => { setEditId(null); setName(""); setCode(""); setType("asset"); - setIsBank(false); setIsReserve(false); setDescription(""); setParentId(""); + setIsBank(false); setIsReserve(false); setCategory(""); setDescription(""); setParentId(""); }; const openEdit = (a: any) => { @@ -152,6 +160,7 @@ export default function AccountingChartOfAccountsPage() { setType(a.type ?? "asset"); setIsBank(a.is_bank ?? false); setIsReserve(a.is_reserve ?? false); + setCategory(a.category ?? ""); setDescription(a.description ?? ""); setParentId(a.parent_account_id ?? ""); setOpen(true); @@ -165,6 +174,7 @@ export default function AccountingChartOfAccountsPage() { type: type as any, is_bank: isBank, is_reserve: isReserve, + category: category.trim() || null, description: description || null, parent_account_id: parentId || null, }; @@ -207,7 +217,7 @@ export default function AccountingChartOfAccountsPage() { const clearSelection = () => setSelectedIds(new Set()); const openBulkEdit = () => { - setBulkEdit({ type: "no_change", parent_account_id: "no_change", is_bank: "no_change", is_reserve: "no_change" }); + setBulkEdit({ type: "no_change", parent_account_id: "no_change", is_bank: "no_change", is_reserve: "no_change", category: "" }); setBulkEditOpen(true); }; @@ -221,6 +231,7 @@ export default function AccountingChartOfAccountsPage() { patch.parent_account_id = bulkEdit.parent_account_id === "none" ? null : bulkEdit.parent_account_id; if (bulkEdit.is_bank !== "no_change") patch.is_bank = bulkEdit.is_bank === "true"; if (bulkEdit.is_reserve !== "no_change") patch.is_reserve = bulkEdit.is_reserve === "true"; + if (bulkEdit.category.trim()) patch.category = bulkEdit.category.trim() === "__clear__" ? null : bulkEdit.category.trim(); if (Object.keys(patch).length === 0) return toast.error("No changes selected"); if (patch.parent_account_id && ids.includes(patch.parent_account_id)) @@ -407,6 +418,13 @@ export default function AccountingChartOfAccountsPage() { +
+ + setCategory(e.target.value)} placeholder="Ungrouped" /> + + {existingCategories.map((c) => +