Monthly forecast: repeat last full actual week to end of month instead of single 7-day lookback
Fixes an edge case where days more than 7 days past the actual cutoff had no valid prior-week source day (itself a forecast day), silently contributing £0. Now walks back in 7-day steps until landing on an actual day, so the last complete actual week tiles forward for the rest of the month. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
84f5d38b10
commit
9e7f4030d2
1 changed files with 8 additions and 5 deletions
|
|
@ -21,6 +21,12 @@ function fmtDisplay(dateStr: string): string {
|
|||
function budgetColour(pct: number): string {
|
||||
return pct <= 100 ? 'var(--app-primary)' : pct <= 110 ? '#b45309' : '#dc2626'
|
||||
}
|
||||
// Baseline forecast: repeat the last full actual week's pattern forward to end of month
|
||||
function repeatingPriorCost(days: Record<string, { cost: number }>, dateStr: string, cutoffStr: string): number {
|
||||
let probe = dateStr
|
||||
while (probe > cutoffStr) probe = fmt(addDays(new Date(probe + 'T00:00:00'), -7))
|
||||
return days[probe]?.cost ?? 0
|
||||
}
|
||||
|
||||
const DEPT_COLORS = ['#065f46','#059669','#0891b2','#7c3aed','#c2410c','#b45309','#0f766e','#4338ca','#be185d','#15803d']
|
||||
|
||||
|
|
@ -154,9 +160,7 @@ export default function Monthly() {
|
|||
for (let day = 1; day <= dim; day++) {
|
||||
const dateStr = `${monthStr}-${String(day).padStart(2, '0')}`
|
||||
if (dateStr <= yesterdayStr) continue
|
||||
const priorStr = fmt(addDays(new Date(dateStr + 'T00:00:00'), -7))
|
||||
const priorCost = dep.days[priorStr]?.cost
|
||||
if (priorCost != null) forecastRem += priorCost
|
||||
forecastRem += repeatingPriorCost(dep.days, dateStr, yesterdayStr)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -211,8 +215,7 @@ export default function Monthly() {
|
|||
if (dateStr <= cutoff) {
|
||||
deptCost += srcDep?.days[dateStr]?.cost ?? 0
|
||||
} else {
|
||||
const priorStr = fmt(addDays(new Date(dateStr + 'T00:00:00'), -7))
|
||||
deptCost += srcDep?.days[priorStr]?.cost ?? 0
|
||||
deptCost += repeatingPriorCost(srcDep?.days ?? {}, dateStr, cutoff)
|
||||
}
|
||||
}
|
||||
entry[dep.department_name] = deptCost
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue