Files
spq-v2/pb_migrations/1740000000023_quote_approval_notify.js
2026-07-12 10:01:39 -04:00

66 lines
2.1 KiB
JavaScript

/// <reference path="../pb_data/types.d.ts" />
//
// M23 — Quote Approval Notifications.
//
// Sends an email to the shop owner when a customer approves or declines
// a quote via the public share-token path.
//
// Uses onRecordUpdateRequest (fires before update) to inspect old vs new
// status, then sends the email fire-and-forget.
//
migrate(
(app) => {
app.onRecordUpdateRequest((e) => {
if (e.collection.name !== 'quotes') return;
const record = e.record;
const oldRecord = e.oldRecord;
if (!oldRecord) return;
const oldStatus = oldRecord.get('status') ?? '';
const newStatus = record.get('status') ?? '';
if (oldStatus !== 'sent') return;
if (newStatus !== 'approved' && newStatus !== 'declined') return;
const userId = record.get('userId');
if (!userId) return;
let user;
try {
user = e.dao.findRecordById('users', userId);
} catch {
return;
}
const email = user.get('email');
if (!email) return;
const shopName = record.get('customerInfo')?.name || '';
const vehicleInfo = record.get('customerInfo')?.vehicleInfo || '';
const statusLabel = newStatus === 'approved' ? 'Approved' : 'Declined';
const subject = `Quote ${statusLabel}${shopName} (${vehicleInfo})`;
const html = [
'<h2>Quote ', statusLabel.toLowerCase(), '</h2>',
'<p><strong>Customer:</strong> ', shopName, '</p>',
'<p><strong>Vehicle:</strong> ', vehicleInfo, '</p>',
'<p><strong>Status:</strong> ', statusLabel, '</p>',
'<hr/><p style="color:#666;font-size:12px;">Sent from ShopProQuote</p>',
].join('');
try {
app.getMailer().send({
to: [{ address: email }],
subject,
html,
});
console.log('[M23] quote ' + newStatus + ' notification sent to ' + email);
} catch (mailErr) {
console.error('[M23] failed to send notification email', mailErr);
}
});
},
(app) => {
console.log('[M23] rollback — restart PocketBase to remove the hook');
}
);