Files
SkyMoney/api/test-overdue-payment.cjs

134 lines
4.0 KiB
JavaScript

// Script to post test income and verify overdue payment
const { PrismaClient } = require('@prisma/client');
const { randomUUID } = require('crypto');
async function main() {
const prisma = new PrismaClient();
try {
const user = await prisma.user.findUnique({
where: { email: 'test@skymoney.com' }
});
if (!user) {
console.log('❌ Test user not found. Run create-test-user.cjs first.');
return;
}
console.log('✅ Found test user:', user.email);
// Check overdue status BEFORE posting income
const plansBefore = await prisma.fixedPlan.findMany({
where: { userId: user.id },
select: {
id: true,
name: true,
totalCents: true,
fundedCents: true,
isOverdue: true,
overdueAmount: true,
},
});
console.log('\n📋 Plans BEFORE income:');
for (const plan of plansBefore) {
console.log(` ${plan.name}: $${Number(plan.fundedCents) / 100}/$${Number(plan.totalCents) / 100} (Overdue: ${plan.isOverdue ? `$${Number(plan.overdueAmount) / 100}` : 'NO'})`);
}
// Post $1000 income - should pay $500 to overdue first, then allocate $500 normally
const incomeAmount = 100000; // $1000 in cents
console.log(`\n💰 Posting income: $${incomeAmount / 100}`);
const incomeId = randomUUID();
const now = new Date().toISOString();
// Simulate what the allocateIncome function does
const result = await prisma.$transaction(async (tx) => {
await tx.incomeEvent.create({
data: {
id: incomeId,
userId: user.id,
postedAt: now,
amountCents: BigInt(incomeAmount),
note: 'Test income for overdue payment',
},
});
// Find overdue plans
const overduePlans = await tx.fixedPlan.findMany({
where: {
userId: user.id,
isOverdue: true,
overdueAmount: { gt: 0 },
},
orderBy: { overdueSince: 'asc' },
});
console.log(`\n🔍 Found ${overduePlans.length} overdue plan(s)`);
let remaining = incomeAmount;
for (const plan of overduePlans) {
if (remaining <= 0) break;
const overdueAmount = Number(plan.overdueAmount);
const amountToPay = Math.min(overdueAmount, remaining);
console.log(` Paying $${amountToPay / 100} to ${plan.name} (was $${overdueAmount / 100} overdue)`);
// Create allocation
await tx.allocation.create({
data: {
userId: user.id,
kind: 'fixed',
toId: plan.id,
amountCents: BigInt(amountToPay),
incomeId,
},
});
// Update plan
const newOverdueAmount = overdueAmount - amountToPay;
await tx.fixedPlan.update({
where: { id: plan.id },
data: {
fundedCents: (plan.fundedCents ?? 0n) + BigInt(amountToPay),
currentFundedCents: (plan.currentFundedCents ?? plan.fundedCents ?? 0n) + BigInt(amountToPay),
overdueAmount: newOverdueAmount,
isOverdue: newOverdueAmount > 0,
lastFundingDate: new Date(now),
},
});
remaining -= amountToPay;
}
return { remaining };
});
console.log(`\n💵 Remaining after overdue payments: $${result.remaining / 100}`);
// Check overdue status AFTER posting income
const plansAfter = await prisma.fixedPlan.findMany({
where: { userId: user.id },
select: {
id: true,
name: true,
totalCents: true,
fundedCents: true,
isOverdue: true,
overdueAmount: true,
},
});
console.log('\n📋 Plans AFTER income:');
for (const plan of plansAfter) {
console.log(` ${plan.name}: $${Number(plan.fundedCents) / 100}/$${Number(plan.totalCents) / 100} (Overdue: ${plan.isOverdue ? `$${Number(plan.overdueAmount) / 100}` : 'NO'})`);
}
} finally {
await prisma.$disconnect();
}
}
main();