From 7ac19ab20db387d42448c2dfa72ebb88b9fce57f Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:51:42 +0000 Subject: [PATCH 1/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- .../collections/payment-plans-panel.tsx | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/components/collections/payment-plans-panel.tsx b/src/components/collections/payment-plans-panel.tsx index cef9093..fd9f86b 100644 --- a/src/components/collections/payment-plans-panel.tsx +++ b/src/components/collections/payment-plans-panel.tsx @@ -65,7 +65,13 @@ function addInterval(dateStr: string, frequency: Frequency, n: number) { return d.toISOString().slice(0, 10); } -export function PaymentPlansPanel({ collectionId }: { collectionId: string }) { +export function PaymentPlansPanel({ + collectionId, + caseId, +}: { + collectionId: string; + caseId?: string | null; +}) { const { user } = useAuth(); const [plans, setPlans] = useState([]); const [installments, setInstallments] = useState>({}); @@ -119,6 +125,25 @@ export function PaymentPlansPanel({ collectionId }: { collectionId: string }) { else load(); }; + const updatePaidAmount = async (id: string, value: string) => { + const num = value === "" ? null : parseFloat(value) || 0; + setInstallments((prev) => { + const next: Record = {}; + Object.entries(prev).forEach(([k, list]) => { + next[k] = list.map((x) => (x.id === id ? { ...x, paid_amount: num } : x)); + }); + return next; + }); + const { error } = await supabase + .from("payment_plan_installments") + .update({ paid_amount: num }) + .eq("id", id); + if (error) { + toast.error("Could not save", { description: error.message }); + load(); + } + }; + const updatePlanStatus = async (planId: string, status: PlanStatus) => { const { error } = await supabase .from("payment_plans") From e5db24c728b0b0c900cacc3ca4448f0805307570 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:51:52 +0000 Subject: [PATCH 2/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- .../collections/payment-plans-panel.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/collections/payment-plans-panel.tsx b/src/components/collections/payment-plans-panel.tsx index fd9f86b..773d33c 100644 --- a/src/components/collections/payment-plans-panel.tsx +++ b/src/components/collections/payment-plans-panel.tsx @@ -245,8 +245,21 @@ export function PaymentPlansPanel({ {overdue && " ยท overdue"} -
- {formatCurrency(i.amount)} +
+ {i.paid ? ( + updatePaidAmount(i.id, e.target.value)} + className="h-7 w-[100px] text-sm text-right tabular-nums" + title="Amount paid" + /> + ) : ( +
+ {formatCurrency(i.amount)} +
+ )}
); From 06f9127422d967993b9c5967fe8c7a139c6acf0f Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:52:01 +0000 Subject: [PATCH 3/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/components/collections/payment-plans-panel.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/collections/payment-plans-panel.tsx b/src/components/collections/payment-plans-panel.tsx index 773d33c..33bff81 100644 --- a/src/components/collections/payment-plans-panel.tsx +++ b/src/components/collections/payment-plans-panel.tsx @@ -281,6 +281,7 @@ export function PaymentPlansPanel({ open={createOpen} onOpenChange={setCreateOpen} collectionId={collectionId} + caseId={caseId ?? null} userId={user?.id} onSaved={load} /> @@ -302,12 +303,14 @@ function CreatePlanDialog({ open, onOpenChange, collectionId, + caseId, userId, onSaved, }: { open: boolean; onOpenChange: (v: boolean) => void; collectionId: string; + caseId?: string | null; userId?: string; onSaved: () => void; }) { @@ -345,6 +348,7 @@ function CreatePlanDialog({ .from("payment_plans") .insert({ collection_id: collectionId, + case_id: caseId ?? null, name: name || null, total_amount: t, down_payment: parseFloat(down) || 0, From 936e9b17f422f05ba5d31002262bc2e06de5dbbd Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:52:07 +0000 Subject: [PATCH 4/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/collections.$collectionId.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/collections.$collectionId.tsx b/src/routes/collections.$collectionId.tsx index 5d0fcc4..351d5cb 100644 --- a/src/routes/collections.$collectionId.tsx +++ b/src/routes/collections.$collectionId.tsx @@ -598,7 +598,7 @@ function CollectionDetailRoute() { {/* Payment plans */} - + {/* Ledger */} Date: Sun, 26 Apr 2026 08:52:31 +0000 Subject: [PATCH 5/5] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- ...8_8b01c824-d7a9-43e8-aedb-3c0a89d3c06d.sql | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 supabase/migrations/20260426085228_8b01c824-d7a9-43e8-aedb-3c0a89d3c06d.sql diff --git a/supabase/migrations/20260426085228_8b01c824-d7a9-43e8-aedb-3c0a89d3c06d.sql b/supabase/migrations/20260426085228_8b01c824-d7a9-43e8-aedb-3c0a89d3c06d.sql new file mode 100644 index 0000000..3adcabf --- /dev/null +++ b/supabase/migrations/20260426085228_8b01c824-d7a9-43e8-aedb-3c0a89d3c06d.sql @@ -0,0 +1,29 @@ +-- Backfill case_id on payment_plans created via collections so they show up +-- on the case Payment Plans tab. +UPDATE public.payment_plans pp +SET case_id = c.case_id +FROM public.collections c +WHERE pp.collection_id = c.id + AND pp.case_id IS NULL + AND c.case_id IS NOT NULL; + +-- Trigger to auto-populate case_id on insert/update when collection_id is set +-- but case_id is missing. +CREATE OR REPLACE FUNCTION public.payment_plans_fill_case_id() +RETURNS TRIGGER +LANGUAGE plpgsql +SECURITY DEFINER +SET search_path = public +AS $$ +BEGIN + IF NEW.case_id IS NULL AND NEW.collection_id IS NOT NULL THEN + SELECT case_id INTO NEW.case_id FROM public.collections WHERE id = NEW.collection_id; + END IF; + RETURN NEW; +END; +$$; + +DROP TRIGGER IF EXISTS payment_plans_fill_case_id_trg ON public.payment_plans; +CREATE TRIGGER payment_plans_fill_case_id_trg +BEFORE INSERT OR UPDATE ON public.payment_plans +FOR EACH ROW EXECUTE FUNCTION public.payment_plans_fill_case_id(); \ No newline at end of file