JEISA-WEBAPP/scripts/add-quote-deleted-flag.mjs
Dave 9d2ba5a430 feat(quotes): delete quotes from the app, add customer inline with full details
Two things that meant going into PocketBase by hand or jumping between
screens.

Deleting a quote
- Quotes had no delete action - a test quote could only be removed
  through the PocketBase admin UI. Purchase orders already soft delete
  by flipping a `deleted` flag, so quotes now do the same: the Delete
  action confirms first, then hides the quote from the list while the
  record and its PDF stay in PocketBase for audit.
- The quotes list filters out soft-deleted quotes, so a deleted quote
  is out of the way but recoverable by clearing the flag.

Adding a customer while writing a quote
- Typing a customer name that was not in the list used to create a
  name-only stub, which then had to be edited from the Customers screen
  before the quote could show an address or VAT number.
- The picker now opens the full customer form right there - address,
  VAT number, email and phone - with the name pre-filled. The new
  customer is created, added to the list and selected, so the quote
  carries on and the PDF has the details.
2026-10-21 05:09:11 +02:00

58 lines
1.8 KiB
JavaScript

#!/usr/bin/env node
/**
* Add the `deleted` flag to the `quotes` collection.
*
* Purchase orders already soft delete this way - the record and its PDF
* stay in PocketBase for audit, but the list hides it. Quotes had no
* such flag, so a test quote could only be removed through the
* PocketBase admin UI by hand.
*
* Usage:
* node scripts/add-quote-deleted-flag.mjs # dry run (default)
* node scripts/add-quote-deleted-flag.mjs --apply # apply to the instance
*/
import PocketBase from "pocketbase";
const PB_URL = process.env.POCKETBASE_URL || "https://pb.jeistk.apphub.co.za";
const PB_EMAIL = process.env.POCKETBASE_ADMIN_EMAIL || "david@wfsales.co.za";
const PB_PASSWORD = process.env.POCKETBASE_ADMIN_PASSWORD || "1234567890";
const APPLY = process.argv.includes("--apply");
const pb = new PocketBase(PB_URL);
pb.autoCancellation(false);
await pb.admins.authWithPassword(PB_EMAIL, PB_PASSWORD);
const collection = await pb.collections.getOne("quotes");
const hasField = collection.fields.some((f) => f.name === "deleted");
console.log("=== BEFORE ===");
console.log(` fields: ${collection.fields.map((f) => f.name).join(", ")}`);
console.log(` deleted flag: ${hasField ? "already present" : "MISSING - will be added"}`);
if (!APPLY) {
console.log("\nDry run. Re-run with --apply to write the field to the instance.");
process.exit(0);
}
if (!hasField) {
collection.fields.push({
hidden: false,
id: "bool_quote_deleted",
name: "deleted",
presentable: false,
required: false,
system: false,
type: "bool",
});
const updated = await pb.collections.update(collection.id, collection);
console.log("\n=== AFTER ===");
console.log(` fields: ${updated.fields.map((f) => f.name).join(", ")}`);
}
console.log("\nDone. Existing quotes keep deleted = false - nothing disappears.");