- create() wraps in $transaction, creates Document INVOICE/CLIENT alongside - update() propagates invoiceNumber change to Document title/reference - issue() sets Document.sentAt - cancel() sets Document.closedAt - delete() removes Document before deleting ClientInvoice - Backfill script for existing invoices (idempotent) - Downgrade @fastify/static to v7.0.4 (Fastify 4 compat) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
|
|
|
async function main() {
|
|
const prisma = new PrismaClient();
|
|
|
|
const invoicesWithoutDoc = await prisma.clientInvoice.findMany({
|
|
where: {
|
|
documents: { none: { documentType: 'INVOICE' } },
|
|
},
|
|
include: {
|
|
order: { select: { id: true, clientId: true, managerId: true } },
|
|
},
|
|
});
|
|
|
|
console.log(`Found ${invoicesWithoutDoc.length} invoices without Document.`);
|
|
|
|
let created = 0;
|
|
for (const inv of invoicesWithoutDoc) {
|
|
if (!inv.order) {
|
|
console.warn(`Invoice ${inv.id} has no order — skipping.`);
|
|
continue;
|
|
}
|
|
|
|
await prisma.document.create({
|
|
data: {
|
|
documentType: 'INVOICE',
|
|
direction: 'CLIENT',
|
|
title: `Счёт ${inv.invoiceNumber}`,
|
|
documentReference: inv.invoiceNumber,
|
|
orderId: inv.order.id,
|
|
clientId: inv.order.clientId,
|
|
clientInvoiceId: inv.id,
|
|
responsibleId: inv.order.managerId,
|
|
createdAt: inv.createdAt,
|
|
sentAt: inv.status === 'ISSUED' || inv.status === 'PAID' ? inv.updatedAt : null,
|
|
closedAt: inv.status === 'CANCELLED' ? inv.updatedAt : null,
|
|
},
|
|
});
|
|
console.log(` ✓ Invoice #${inv.id} (${inv.invoiceNumber}) → Document created`);
|
|
created++;
|
|
}
|
|
|
|
console.log(`Created ${created} Documents (backfill complete).`);
|
|
await prisma.$disconnect();
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error(err);
|
|
process.exit(1);
|
|
});
|