- Introduced a new `ConfirmStockDialog` to handle stock collection confirmations, allowing operators to review per-line quantities and any short lines before finalizing the action. - Updated the `CollectionConfirmPage` to manage the new confirmation state and trigger the dialog upon clicking the "Confirm collection" button. - Enhanced tests to cover the new dialog functionality, ensuring correct behavior for both full and short quantity lines during the confirmation process. - Improved documentation to clarify the flow and user interactions with the new confirmation dialog.
85 lines
No EOL
2.8 KiB
TypeScript
85 lines
No EOL
2.8 KiB
TypeScript
/**
|
|
* One-shot migration: add `in_stock` (bool, default false) to the
|
|
* `order_items` collection.
|
|
*
|
|
* Run with:
|
|
*
|
|
* npx tsx scripts/migrations/2026-08-17-add-order-items-in-stock.ts
|
|
*
|
|
* What this does (idempotent — safe to re-run):
|
|
*
|
|
* 1. Reads the `order_items` collection schema.
|
|
* 2. If an `in_stock` bool field already exists, prints "already
|
|
* present" and exits.
|
|
* 3. Otherwise appends a new bool field named `in_stock` and
|
|
* PATCHes the collection.
|
|
*
|
|
* Why this migration exists
|
|
*
|
|
* The order process page has a per-line "in stock" checkbox that
|
|
* flips a boolean on the order_item. The handler writes the field
|
|
* directly via PocketBase admin PB
|
|
* (`pb.collection("order_items").update(id, { in_stock: next })`).
|
|
* The field has never been declared on the schema, which means every
|
|
* write is silently a no-op — the optimistic UI flips on, the
|
|
* refresh re-reads PB without the value, and the checkbox reverts.
|
|
* This blocks the in-stock → ready_invoice Send PO path that
|
|
* `process/page.tsx:sendPoForSupplier` implements.
|
|
*
|
|
* Adding the field here lets every existing `in_stock` write
|
|
* (process page's `toggleInStock` and `saveItem`, the
|
|
* `/api/v1/stock/fulfill` route's CREATE mode) start persisting
|
|
* without any further code change.
|
|
*
|
|
* Rollback: delete the `in_stock` field from the order_items
|
|
* collection in the PB admin UI. No data is lost because the field
|
|
* was not populated before this migration ran.
|
|
*/
|
|
import PocketBase from "pocketbase";
|
|
|
|
const PB_URL = process.env.NEXT_PUBLIC_POCKETBASE_URL || "http://127.0.0.1:8090";
|
|
const ADMIN_EMAIL = process.env.PB_ADMIN_EMAIL;
|
|
const ADMIN_PASSWORD = process.env.PB_ADMIN_PASSWORD;
|
|
|
|
async function main() {
|
|
if (!ADMIN_EMAIL || !ADMIN_PASSWORD) {
|
|
throw new Error(
|
|
"Set PB_ADMIN_EMAIL and PB_ADMIN_PASSWORD env vars (e.g. sourced from .env.local).",
|
|
);
|
|
}
|
|
|
|
const pb = new PocketBase(PB_URL);
|
|
await pb.collection("_superusers").authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
|
|
console.log(`[order-items-in-stock] Authenticated against ${PB_URL}`);
|
|
|
|
const orderItems = await pb.collections.getOne("order_items");
|
|
const hasInStock = orderItems.fields.some(
|
|
(f: { name: string }) => f.name === "in_stock",
|
|
);
|
|
|
|
if (hasInStock) {
|
|
out("[order-items-in-stock] order_items.in_stock already exists — skipping.");
|
|
return;
|
|
}
|
|
|
|
await pb.collections.update(orderItems.id, {
|
|
fields: [
|
|
...orderItems.fields,
|
|
{
|
|
name: "in_stock",
|
|
type: "bool",
|
|
required: false,
|
|
presentable: false,
|
|
},
|
|
],
|
|
});
|
|
|
|
console.log(
|
|
"[order-items-in-stock] Added order_items.in_stock (bool, optional, default false). Migration complete.",
|
|
);
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error("[order-items-in-stock] Migration failed:", err);
|
|
process.exit(1);
|
|
}); |