Fair PYTD comparison for current week/month
Weekly: cap pyToStr at elapsed days (not full Mon-Sun), and filter py_sales to past days only — both give WTD vs WTD. Labels show 'PY WTD' for current week, 'PY' for complete past weeks. Monthly: pyToStr already capped at same day-of-month; salesTo already capped at today. Labels now show 'PY MTD' for current month, 'PY' for complete past months. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dc1a14a070
commit
44a7caa937
2 changed files with 20 additions and 11 deletions
|
|
@ -192,7 +192,7 @@ export default function Monthly() {
|
|||
<div className="summary-card">
|
||||
<div className="label">{isCurrentMonth ? 'Actual MTD' : 'Actual'}</div>
|
||||
<div className="value">{fmtMoney(totalActual)}</div>
|
||||
{pyWages != null && <div className="sub">PY {fmtMoney(pyWages)}{pyPct(totalActual, pyWages)}</div>}
|
||||
{pyWages != null && <div className="sub">{isCurrentMonth ? 'PY MTD' : 'PY'} {fmtMoney(pyWages)}{pyPct(totalActual, pyWages)}</div>}
|
||||
</div>
|
||||
{isCurrentMonth && (
|
||||
<div className="summary-card">
|
||||
|
|
@ -221,7 +221,7 @@ export default function Monthly() {
|
|||
<div className="summary-card">
|
||||
<div className="label">{isCurrentMonth ? 'Net Sales MTD' : 'Net Sales'}</div>
|
||||
<div className="value">{fmtMoney(netSales)}</div>
|
||||
{pySales > 0 && <div className="sub">PY {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
|
||||
{pySales > 0 && <div className="sub">{isCurrentMonth ? 'PY MTD' : 'PY'} {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
|
||||
</div>
|
||||
<div className="summary-card">
|
||||
<div className="label">% Net Sales</div>
|
||||
|
|
|
|||
|
|
@ -44,11 +44,15 @@ function pctClass(pct: number | null): string {
|
|||
export default function Weekly() {
|
||||
const [fromStr, setFromStr] = useState<string>(() => mondayOf(new Date()))
|
||||
|
||||
const toStr = addDaysStr(fromStr, 6)
|
||||
const todayStr = localStr(new Date())
|
||||
// Prior-year equivalent week (52 weeks back)
|
||||
const pyFromStr = addDaysStr(fromStr, -364)
|
||||
const pyToStr = addDaysStr(toStr, -364)
|
||||
const toStr = addDaysStr(fromStr, 6)
|
||||
const todayStr = localStr(new Date())
|
||||
const isCurrentWeek = fromStr === mondayOf(new Date())
|
||||
const pyFromStr = addDaysStr(fromStr, -364)
|
||||
// For current (partial) week cap PY at equivalent elapsed day — fair WTD comparison
|
||||
const daysElapsed = isCurrentWeek
|
||||
? Math.round((new Date(todayStr + 'T00:00:00').getTime() - new Date(fromStr + 'T00:00:00').getTime()) / 86_400_000)
|
||||
: 6
|
||||
const pyToStr = addDaysStr(fromStr, -364 + daysElapsed)
|
||||
|
||||
const [depts, setDepts] = useState<DeptActuals[]>([])
|
||||
const [netSales, setNetSales] = useState(0)
|
||||
|
|
@ -74,7 +78,13 @@ export default function Weekly() {
|
|||
setShowOncosts(actRes.show_oncosts)
|
||||
setDeptPcts(actRes.dept_pcts)
|
||||
setNetSales(salesRes.days.reduce((s, d) => s + d.net_sales, 0))
|
||||
setPySales(salesRes.days.reduce((s, d) => s + d.py_sales, 0))
|
||||
// For current week only sum PY sales for elapsed days (WTD = apples to apples)
|
||||
const isCurrentWk = fromStr === mondayOf(new Date())
|
||||
setPySales(
|
||||
isCurrentWk
|
||||
? salesRes.days.filter(d => d.date <= todayStr).reduce((s, d) => s + d.py_sales, 0)
|
||||
: salesRes.days.reduce((s, d) => s + d.py_sales, 0)
|
||||
)
|
||||
|
||||
const pyTotal = pyActRes.departments.reduce(
|
||||
(s, dep) => s + Object.values(dep.days).reduce((ds, d) => ds + d.cost, 0), 0
|
||||
|
|
@ -109,7 +119,6 @@ export default function Weekly() {
|
|||
|
||||
const prev = () => setFromStr(s => addDaysStr(s, -7))
|
||||
const next = () => setFromStr(s => addDaysStr(s, 7))
|
||||
const isCurrentWeek = fromStr === mondayOf(new Date())
|
||||
|
||||
const deptWeekBudget = (deptId: string) =>
|
||||
budget != null && monthlyBudg != null && (deptPcts[deptId] ?? 0) > 0
|
||||
|
|
@ -154,7 +163,7 @@ export default function Weekly() {
|
|||
<div className="label">Total Wages</div>
|
||||
<div className="value">{fmtMoney(totalWages)}</div>
|
||||
{pyWages != null
|
||||
? <div className="sub">PY {fmtMoney(pyWages)}{pyPct(totalWages, pyWages)}</div>
|
||||
? <div className="sub">{isCurrentWeek ? 'PY WTD' : 'PY'} {fmtMoney(pyWages)}{pyPct(totalWages, pyWages)}</div>
|
||||
: <div className="sub">{showOncosts ? 'incl. on-costs' : 'base cost'}</div>}
|
||||
</div>
|
||||
<div className="summary-card">
|
||||
|
|
@ -173,7 +182,7 @@ export default function Weekly() {
|
|||
<div className="summary-card">
|
||||
<div className="label">Net Sales</div>
|
||||
<div className="value">{fmtMoney(netSales)}</div>
|
||||
{pySales > 0 && <div className="sub">PY {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
|
||||
{pySales > 0 && <div className="sub">{isCurrentWeek ? 'PY WTD' : 'PY'} {fmtMoney(pySales)}{pyPct(netSales, pySales)}</div>}
|
||||
</div>
|
||||
<div className="summary-card">
|
||||
<div className="label">% of Net Sales</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue