72 lines
2.9 KiB
TypeScript
72 lines
2.9 KiB
TypeScript
/**
|
|
* Regenerates a single existing invoice using the offline session token,
|
|
* downloads the resulting PDF and pretty-prints the closing/footer text so
|
|
* we can verify the new wording end-to-end against the live dev store.
|
|
*
|
|
* Usage: npx tsx scripts/regenerate-invoice.ts [invoiceNumber]
|
|
* default invoiceNumber = RE-1001
|
|
*/
|
|
import "dotenv/config";
|
|
import { writeFileSync } from "node:fs";
|
|
import { execFileSync } from "node:child_process";
|
|
import { resolve } from "node:path";
|
|
|
|
import db from "../app/db.server";
|
|
import { unauthenticated } from "../app/shopify.server";
|
|
import { generateInvoice } from "../app/services/invoice/generateInvoice.server";
|
|
|
|
async function main() {
|
|
const wanted = process.argv[2] ?? "RE-1001";
|
|
|
|
const invoice = await db.invoice.findFirst({
|
|
where: { invoiceNumber: wanted, kind: "invoice", cancelledAt: null },
|
|
orderBy: [{ version: "desc" }, { createdAt: "desc" }],
|
|
});
|
|
if (!invoice) throw new Error(`No invoice ${wanted} found in DB`);
|
|
|
|
console.log(`Found ${invoice.invoiceNumber} (status=${invoice.status}, sentAt=${invoice.sentAt ?? "—"}) for order ${invoice.orderId}`);
|
|
|
|
const { admin } = await unauthenticated.admin(invoice.shopDomain);
|
|
|
|
const result = await generateInvoice({
|
|
shopDomain: invoice.shopDomain,
|
|
admin,
|
|
orderId: invoice.orderId,
|
|
forceRegenerate: true,
|
|
});
|
|
|
|
console.log(`Regenerated → version ${result.version}, pdfUrl=${result.pdfUrl}`);
|
|
|
|
const out = resolve(process.cwd(), "data", `regen-${result.invoiceNumber}.pdf`);
|
|
const res = await fetch(result.pdfUrl);
|
|
if (!res.ok) throw new Error(`download failed: ${res.status}`);
|
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
writeFileSync(out, buf);
|
|
console.log(`Saved ${out} (${buf.length} bytes)`);
|
|
|
|
const text = execFileSync("pdftotext", ["-layout", "-enc", "UTF-8", out, "-"], { encoding: "utf8" });
|
|
|
|
const okDe = text.includes("Danke für deinen Einkauf");
|
|
const okEn = text.includes("Thank you for your purchase.");
|
|
const oldDe = text.includes("Mit freundlichen Grüßen");
|
|
const oldEn = /\bKind regards\b/.test(text);
|
|
|
|
console.log(`\n--- closing text checks ---`);
|
|
console.log(` contains 'Danke für deinen Einkauf' : ${okDe}`);
|
|
console.log(` contains 'Thank you for your purchase.': ${okEn}`);
|
|
console.log(` contains old 'Mit freundlichen Grüßen' : ${oldDe}`);
|
|
console.log(` contains old 'Kind regards' : ${oldEn}`);
|
|
|
|
const langOk = invoice.language === "en" ? okEn : okDe;
|
|
const cleanOld = invoice.language === "en" ? !oldEn : !oldDe;
|
|
if (!langOk || !cleanOld) {
|
|
console.error(`FAIL: closing line did not match expected wording for language=${invoice.language}`);
|
|
process.exit(1);
|
|
}
|
|
console.log(`PASS: regenerated ${invoice.invoiceNumber} (lang=${invoice.language}) shows the new closing.`);
|
|
}
|
|
|
|
main()
|
|
.catch((e) => { console.error(e); process.exit(1); })
|
|
.finally(() => db.$disconnect());
|