fix(scheduling): use each candidate's own daysLeft for prediction
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Different assessment targets have different end dates. Previously all
candidates used the current vehicle's daysLeft, causing wrong predictions.

Now each inventory vehicle computes its own daysLeft from its assessment
target's current_year_assessment_end_date. predictedAfterSwap uses the
candidate's own daysLeft instead of the current vehicle's.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-16 22:58:47 +08:00
parent a52a77f3a2
commit aa9a29fed8
5 changed files with 22 additions and 8 deletions

View File

@@ -250,12 +250,21 @@ app.get('/', async (c) => {
// Cross-reference with assessment data
const assessment = assessmentByPlate.get(plate);
// Compute this vehicle's own daysLeft from its assessment end date
let invDaysLeft = 0;
if (assessment?.current_year_assessment_end_date) {
const endDate = new Date(assessment.current_year_assessment_end_date);
invDaysLeft = Math.max(1, Math.ceil((endDate.getTime() - now.getTime()) / 86400000));
} else {
invDaysLeft = Math.max(1, Math.ceil((yearEnd.getTime() - now.getTime()) / 86400000));
}
inventoryVehicles.push({
plateNumber: plate,
vehicleType,
region,
province,
totalMileage: assessment ? Number(assessment.vehicle_total_mileage) || 0 : 0,
daysLeft: invDaysLeft,
targetId: assessment ? (assessment.target_id as number) : null,
targetName: assessment ? (targetMap.get(assessment.target_id)?.targetName ?? null) : null,
yearTarget: assessment ? Number(assessment.current_year_mileage_task) || null : null,