Bug: budgetX stored per-unit smeta costs instead of totals, causing absurd overrun percentages (7140% for qty=1700, 3831% for qty=100). Fix 3 write sites: - estimates.service.ts syncFinancialTracking: .mul(qty) - financial.service.ts applyRevision: revision.delta*.mul(qty) - revisions.service.ts applyRevisionToBudget: (smeta + deltas) * qty financial.service.ts initFromSmeta was already correct (L36-40). committedX/actualX from PO.totalAmount — already totals, no fix needed. Backfill: 2 FTs corrected, alertLevel RED→NONE for both. Script is one-shot non-idempotent (never re-run). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
2.2 KiB
TypeScript
68 lines
2.2 KiB
TypeScript
#!/usr/bin/env tsx
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { Decimal } from '@prisma/client/runtime/library';
|
|
|
|
const prisma = new PrismaClient();
|
|
const apply = process.argv.includes('--apply');
|
|
|
|
async function main() {
|
|
console.log(apply ? '🔥 MODE APPLY' : '🧪 MODE DRY-RUN (--apply to write)');
|
|
|
|
const fts = await prisma.financialTracking.findMany({
|
|
include: {
|
|
order: { select: { id: true, orderCode: true, quantity: true } as any },
|
|
},
|
|
});
|
|
|
|
console.log(`Total FinancialTracking: ${fts.length}`);
|
|
let updated = 0;
|
|
let skipped = 0;
|
|
|
|
for (const ft of fts) {
|
|
const order = ft.order as any;
|
|
const qty = order?.quantity ?? 1;
|
|
if (qty <= 1) {
|
|
skipped++;
|
|
continue;
|
|
}
|
|
|
|
const qtyDec = new Decimal(qty);
|
|
const newServices = ft.budgetServices.mul(qtyDec);
|
|
const newMaterials = ft.budgetMaterials.mul(qtyDec);
|
|
const newLabor = ft.budgetLabor.mul(qtyDec);
|
|
const newSupply = ft.budgetSupply.mul(qtyDec);
|
|
|
|
const oldTotal = Number(ft.budgetServices) + Number(ft.budgetMaterials)
|
|
+ Number(ft.budgetLabor) + Number(ft.budgetSupply);
|
|
const newTotal = Number(newServices) + Number(newMaterials)
|
|
+ Number(newLabor) + Number(newSupply);
|
|
|
|
console.log(`\n${order.orderCode} (orderId=${order.id}, qty=${qty}):`);
|
|
console.log(` budget: ${oldTotal.toLocaleString('ru')} → ${newTotal.toLocaleString('ru')} ₽`);
|
|
console.log(` services: ${ft.budgetServices} → ${newServices}`);
|
|
console.log(` materials: ${ft.budgetMaterials} → ${newMaterials}`);
|
|
console.log(` labor: ${ft.budgetLabor} → ${newLabor}`);
|
|
console.log(` supply: ${ft.budgetSupply} → ${newSupply}`);
|
|
|
|
if (apply) {
|
|
await prisma.financialTracking.update({
|
|
where: { id: ft.id },
|
|
data: {
|
|
budgetServices: newServices,
|
|
budgetMaterials: newMaterials,
|
|
budgetLabor: newLabor,
|
|
budgetSupply: newSupply,
|
|
},
|
|
});
|
|
console.log(' ✅ Applied');
|
|
}
|
|
updated++;
|
|
}
|
|
|
|
console.log(`\nSummary: ${updated} to update, ${skipped} skipped (qty=1)`);
|
|
}
|
|
|
|
main()
|
|
.catch(e => { console.error(e); process.exit(1); })
|
|
.finally(() => prisma.$disconnect());
|