mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 09:50:01 +00:00
Accounting homeowner ledger/statement defaults to full history
The customer Ledger tab + statement defaulted to the current calendar year, so older payments looked missing and didn't line up with the main-app owner ledger (all-time). Default the "From" date to the earliest transaction (user can still narrow), so the accounting ledger/statement matches the main owner ledger. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { Link, useParams } from "react-router-dom";
|
import { Link, useParams } from "react-router-dom";
|
||||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { useMemo, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { accounting } from "@/lib/accountingClient";
|
import { accounting } from "@/lib/accountingClient";
|
||||||
import { useCompanyId } from "./lib/useCompanyId";
|
import { useCompanyId } from "./lib/useCompanyId";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
@@ -18,9 +18,6 @@ import jsPDF from "jspdf";
|
|||||||
import autoTable from "jspdf-autotable";
|
import autoTable from "jspdf-autotable";
|
||||||
import { drawReportCoverPage } from "@/lib/reportCover";
|
import { drawReportCoverPage } from "@/lib/reportCover";
|
||||||
|
|
||||||
function startOfFY() {
|
|
||||||
return new Date(new Date().getFullYear(), 0, 1).toISOString().slice(0, 10);
|
|
||||||
}
|
|
||||||
function today() {
|
function today() {
|
||||||
return new Date().toLocaleDateString("en-CA", { timeZone: "America/New_York" });
|
return new Date().toLocaleDateString("en-CA", { timeZone: "America/New_York" });
|
||||||
}
|
}
|
||||||
@@ -44,7 +41,11 @@ export default function AccountingCustomerDetailPage() {
|
|||||||
const cid = companyId ?? "";
|
const cid = companyId ?? "";
|
||||||
const cur = "USD";
|
const cur = "USD";
|
||||||
const qc = useQueryClient();
|
const qc = useQueryClient();
|
||||||
const [from, setFrom] = useState(startOfFY());
|
// Default the ledger/statement to the full history so it matches the main-app
|
||||||
|
// owner ledger (all-time). Set to the earliest transaction once data loads;
|
||||||
|
// the user can still narrow the range. "" means "no lower bound" (show all).
|
||||||
|
const [from, setFrom] = useState("");
|
||||||
|
const [fromTouched, setFromTouched] = useState(false);
|
||||||
const [to, setTo] = useState(today());
|
const [to, setTo] = useState(today());
|
||||||
const [drawer, setDrawer] = useState<LedgerRow | null>(null);
|
const [drawer, setDrawer] = useState<LedgerRow | null>(null);
|
||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(false);
|
||||||
@@ -140,6 +141,12 @@ export default function AccountingCustomerDetailPage() {
|
|||||||
return rows;
|
return rows;
|
||||||
}, [invoices, payments]);
|
}, [invoices, payments]);
|
||||||
|
|
||||||
|
// Default the "From" date to the earliest entry so the full ledger shows
|
||||||
|
// (matches the main-app owner ledger). Honors a user-chosen range thereafter.
|
||||||
|
useEffect(() => {
|
||||||
|
if (!fromTouched && !from && allRows.length) setFrom(allRows[0].date);
|
||||||
|
}, [allRows, fromTouched, from]);
|
||||||
|
|
||||||
const openingBalance = useMemo(
|
const openingBalance = useMemo(
|
||||||
() => allRows.filter((r) => r.date < from).reduce((s, r) => s + r.debit - r.credit, 0),
|
() => allRows.filter((r) => r.date < from).reduce((s, r) => s + r.debit - r.credit, 0),
|
||||||
[allRows, from]
|
[allRows, from]
|
||||||
@@ -486,7 +493,7 @@ export default function AccountingCustomerDetailPage() {
|
|||||||
|
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="p-4 flex flex-wrap items-end gap-3">
|
<CardContent className="p-4 flex flex-wrap items-end gap-3">
|
||||||
<div><Label className="text-xs">From</Label><Input type="date" value={from} onChange={(e) => setFrom(e.target.value)} className="w-40" /></div>
|
<div><Label className="text-xs">From</Label><Input type="date" value={from} onChange={(e) => { setFromTouched(true); setFrom(e.target.value); }} className="w-40" /></div>
|
||||||
<div><Label className="text-xs">To</Label><Input type="date" value={to} onChange={(e) => setTo(e.target.value)} className="w-40" /></div>
|
<div><Label className="text-xs">To</Label><Input type="date" value={to} onChange={(e) => setTo(e.target.value)} className="w-40" /></div>
|
||||||
<div className="ml-auto flex gap-2">
|
<div className="ml-auto flex gap-2">
|
||||||
<Button variant="outline" onClick={exportStatement}><Download className="h-4 w-4 mr-1" /> Export Statement</Button>
|
<Button variant="outline" onClick={exportStatement}><Download className="h-4 w-4 mr-1" /> Export Statement</Button>
|
||||||
|
|||||||
Reference in New Issue
Block a user