/// // // M6 — Add a Quote ↔ Repair Order link. // // `quotes.repairOrderId` — set when a quote is generated from an existing RO // (so you can jump back to the originating RO). // `repairOrders.quoteId` — set when an RO is created by "converting" an // approved quote (so you can jump back to the source // quote). Also lets the dashboard report "converted // quotes" as a metric. // // Both are nullable text columns (PocketBase relation fields would lock you // into one record type; plain text keeps the link loose and survives renames // of the related collection). The frontend treats empty/null as "no link". // migrate( (db) => { // quotes.repairOrderId const quotes = db.findCollectionByNameOrId('quotes'); if (quotes) { if (!quotes.fields.find((f) => f.name === 'repairOrderId')) { quotes.fields.push(new TextField({ name: 'repairOrderId', required: false })); db.save(quotes); console.log('[M6] added repairOrderId to quotes'); } } else { console.warn('[M6] quotes collection not found — skipping'); } // repairOrders.quoteId const ros = db.findCollectionByNameOrId('repairOrders'); if (ros) { if (!ros.fields.find((f) => f.name === 'quoteId')) { ros.fields.push(new TextField({ name: 'quoteId', required: false })); db.save(ros); console.log('[M6] added quoteId to repairOrders'); } } else { console.warn('[M6] repairOrders collection not found — skipping'); } }, (db) => { const quotes = db.findCollectionByNameOrId('quotes'); if (quotes) { const i1 = quotes.fields.findIndex((f) => f.name === 'repairOrderId'); if (i1 >= 0) { quotes.fields.splice(i1, 1); db.save(quotes); } } const ros = db.findCollectionByNameOrId('repairOrders'); if (ros) { const i2 = ros.fields.findIndex((f) => f.name === 'quoteId'); if (i2 >= 0) { ros.fields.splice(i2, 1); db.save(ros); } } } );