Fix directors forecast report counting stale pickup for past days
The report endpoint's totalPickup/totalRooms summed every day's pickup override regardless of whether the day had already passed, even though a past day's actual accommodation revenue already supersedes it (fAccomm ignores pickup for those days). This overstated Probable Pickup and the month's rooms estimate. Also fixed pickup.accomm to sum each day's own rate instead of multiplying the total by a flat session rate.
This commit is contained in:
parent
9e9e1d7400
commit
932302ebe2
1 changed files with 15 additions and 7 deletions
|
|
@ -104,8 +104,10 @@ export async function directorsForecastRoutes(fastify) {
|
|||
const actualDry = isPast ? (rev.dry?.otb ?? null) : null
|
||||
const actualWet = isPast ? (rev.wet?.otb ?? null) : null
|
||||
|
||||
// User overrides
|
||||
const pickupRooms = ovr.pickup_rooms != null ? parseInt(ovr.pickup_rooms) : 0
|
||||
// User overrides — once a day is past and has an actual, a leftover
|
||||
// pickup override from before the day arrived is stale and shouldn't count.
|
||||
const pickupApplies = !(isPast && actualAccomm != null)
|
||||
const pickupRooms = pickupApplies && ovr.pickup_rooms != null ? parseInt(ovr.pickup_rooms) : 0
|
||||
const dayRate = ovr.pickup_avg_rate != null ? parseFloat(ovr.pickup_avg_rate) : rate
|
||||
|
||||
// Forecast values
|
||||
|
|
@ -209,7 +211,7 @@ export async function directorsForecastRoutes(fastify) {
|
|||
'29–end': { accomm: 0, dry: 0, wet: 0, rooms: 0 },
|
||||
}
|
||||
|
||||
let totalAvailable = 0, totalOtbRooms = 0, totalOtbNetRev = 0, totalPickup = 0
|
||||
let totalAvailable = 0, totalOtbRooms = 0, totalOtbNetRev = 0, totalPickup = 0, totalPickupRevenue = 0
|
||||
let totalAccomm = 0, totalDry = 0, totalWet = 0
|
||||
let totalBudgetAccomm = 0, totalBudgetDry = 0, totalBudgetWet = 0
|
||||
let totalLyAccomm = 0, totalLyDry = 0, totalLyWet = 0, totalLyRooms = 0
|
||||
|
|
@ -224,14 +226,19 @@ export async function directorsForecastRoutes(fastify) {
|
|||
const available = rm.available_rooms ?? 0
|
||||
const otbRooms = rm.otb_rooms ?? 0
|
||||
const otbNetRev = rev.accom?.otb ?? 0
|
||||
const pickupRooms = ovr.pickup_rooms != null ? parseInt(ovr.pickup_rooms) : 0
|
||||
const dayRate = ovr.pickup_avg_rate != null ? parseFloat(ovr.pickup_avg_rate) : sessionRate
|
||||
const totalRooms = otbRooms + pickupRooms
|
||||
|
||||
const actualAccomm = isPast ? (rev.accom?.otb ?? null) : null
|
||||
const actualDry = isPast ? (rev.dry?.otb ?? null) : null
|
||||
const actualWet = isPast ? (rev.wet?.otb ?? null) : null
|
||||
|
||||
// Once a day is past and has an actual, it's realised — any leftover
|
||||
// pickup override from before the day arrived is stale and must not
|
||||
// still count as "probable" pickup (it never contributed to fAccomm below).
|
||||
const pickupApplies = !(isPast && actualAccomm != null)
|
||||
const pickupRooms = pickupApplies && ovr.pickup_rooms != null ? parseInt(ovr.pickup_rooms) : 0
|
||||
const dayRate = ovr.pickup_avg_rate != null ? parseFloat(ovr.pickup_avg_rate) : sessionRate
|
||||
const totalRooms = otbRooms + pickupRooms
|
||||
|
||||
const fAccomm = (isPast && actualAccomm != null) ? actualAccomm : otbNetRev + pickupRooms * dayRate
|
||||
const fDry = ovr.forecast_dry != null ? parseFloat(ovr.forecast_dry)
|
||||
: ovr.dry_override != null ? parseFloat(ovr.dry_override)
|
||||
|
|
@ -244,6 +251,7 @@ export async function directorsForecastRoutes(fastify) {
|
|||
totalOtbRooms += otbRooms
|
||||
totalOtbNetRev += otbNetRev
|
||||
totalPickup += pickupRooms
|
||||
totalPickupRevenue += pickupRooms * dayRate
|
||||
totalAccomm += fAccomm
|
||||
totalDry += fDry
|
||||
totalWet += fWet
|
||||
|
|
@ -312,7 +320,7 @@ export async function directorsForecastRoutes(fastify) {
|
|||
arr: totalOtbRooms > 0 ? totalOtbNetRev / totalOtbRooms : null,
|
||||
revpar: totalAvailable > 0 ? totalOtbNetRev / totalAvailable : null,
|
||||
},
|
||||
pickup: { rooms: totalPickup, accomm: totalPickup * sessionRate, avg_rate: sessionRate },
|
||||
pickup: { rooms: totalPickup, accomm: totalPickupRevenue, avg_rate: totalPickup > 0 ? totalPickupRevenue / totalPickup : sessionRate },
|
||||
weekly: Object.entries(weekBands).map(([label, v]) => ({ label, ...v })),
|
||||
snapshots: snapshotsRes.rows,
|
||||
utilities,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue