{tr.reports.includesHidden}
+ ) : null} +{t.readOnly}
: null} + {kind === "expense" && ungrouped ? ( ++ {tr.kakeibo.ungroupedCount(ungrouped)} +
+ ) : null} {tree.length ? ({k.groupHints[group]}
+{formatMoney(s.groups[group])}
+
+ {formatPct(s.shares[group])} ·{" "}
+
{t.noSpending}
+ )} ++ {t.ungroupedHelp}{" "} + + {t.goCategories} + +
++ {k.bankCost} +
+ ); + const effective = (value || suggested) as KakeiboGroup | null; + return ( + + ); +} diff --git a/src/features/transactions/components/transaction-form.tsx b/src/features/transactions/components/transaction-form.tsx index 8be7bd7..f08e5cb 100644 --- a/src/features/transactions/components/transaction-form.tsx +++ b/src/features/transactions/components/transaction-form.tsx @@ -23,6 +23,7 @@ import { import { Skeleton } from "@/components/ui/skeleton"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { tr } from "@/i18n/tr"; +import { KakeiboSelect } from "./kakeibo-select"; import { cn } from "@/lib/utils"; import { todayIstanbul } from "@/shared/dates"; import { formatMoney } from "@/shared/format"; @@ -61,7 +62,7 @@ export type TransactionFormMode = | { kind: "edit"; transaction: TransactionDetail } | { kind: "copy"; transaction: TransactionDetail }; -type SplitValue = { categoryId: string; amount: string; note: string }; +type SplitValue = { categoryId: string; amount: string; note: string; kakeiboGroup: string }; type FormValues = { type: TransactionType; amount: string; @@ -70,6 +71,8 @@ type FormValues = { toAccountId: string; categoryId: string; splits: SplitValue[]; + /** Kakeibo grubu bu işlem için değiştirildiyse ("" = kategoriden). */ + kakeiboGroup: string; payee: string; description: string; tags: string; @@ -90,6 +93,7 @@ function toValues(mode: TransactionFormMode, options: TransactionFormOptions | n toAccountId: p.toAccountId ?? "", categoryId: p.categoryId ?? "", splits: [], + kakeiboGroup: "", payee: "", description: p.description ?? "", tags: "", @@ -109,7 +113,9 @@ function toValues(mode: TransactionFormMode, options: TransactionFormOptions | n categoryId: s.categoryId, amount: formatMoneyInput(s.amountMinor), note: s.note, + kakeiboGroup: s.kakeiboGroup ?? "", })), + kakeiboGroup: x.kakeiboGroup ?? "", payee: x.payeeName, description: x.description, tags: x.tags.join(", "), @@ -359,6 +365,7 @@ export function TransactionFormDialog({ const amount = useWatch({ control: form.control, name: "amount" }); const accountId = useWatch({ control: form.control, name: "accountId" }); const splitValues = useWatch({ control: form.control, name: "splits" }); + const categoryIdValue = useWatch({ control: form.control, name: "categoryId" }); const attachmentCount = useWatch({ control: form.control, name: "attachments" })?.length ?? 0; const splitMode = splits.fields.length > 0; @@ -426,9 +433,15 @@ export function TransactionFormDialog({ } const first = form.getValues("categoryId"); splits.replace([ - { categoryId: first, amount: form.getValues("amount"), note: "" }, - { categoryId: "", amount: "", note: "" }, + { + categoryId: first, + amount: form.getValues("amount"), + note: "", + kakeiboGroup: form.getValues("kakeiboGroup"), + }, + { categoryId: "", amount: "", note: "", kakeiboGroup: "" }, ]); + form.setValue("kakeiboGroup", ""); form.setValue("categoryId", ""); setAdvancedOpen(true); } @@ -711,6 +724,30 @@ export function TransactionFormDialog({ )} /> ) : null} + {type === "expense" && !splitMode && categoryIdValue ? ( +