114 lines
3.7 KiB
JavaScript
114 lines
3.7 KiB
JavaScript
/// <reference path="../pb_data/types.d.ts" />
|
|
migrate(
|
|
(app) => {
|
|
// ── 1. Create collection (rules set to empty string = no filter) ─
|
|
var auditCol = new Collection({
|
|
name: 'roFinancialAudit',
|
|
type: 'base',
|
|
schema: [
|
|
new TextField({ name: 'roId', required: true }),
|
|
new TextField({ name: 'field', required: true }),
|
|
new JSONField({ name: 'from', required: false }),
|
|
new JSONField({ name: 'to', required: false }),
|
|
new TextField({ name: 'by', required: false }),
|
|
new TextField({ name: 'at', required: true }),
|
|
new TextField({ name: 'prevHash', required: false }),
|
|
new TextField({ name: 'hash', required: true }),
|
|
],
|
|
listRule: '',
|
|
viewRule: '',
|
|
createRule: null,
|
|
updateRule: null,
|
|
deleteRule: null,
|
|
});
|
|
app.save(auditCol);
|
|
console.log('[M25] created roFinancialAudit collection');
|
|
|
|
// ── 2. Hook: diff financial changes ──────────────────────────────
|
|
app.onRecordUpdateRequest(function(e) {
|
|
if (e.collection.name !== 'repairOrders') return;
|
|
if (!e.oldRecord) return;
|
|
|
|
var oldFinancial = e.oldRecord.get('financial');
|
|
var newFinancial = e.record.get('financial');
|
|
if (!oldFinancial && !newFinancial) return;
|
|
|
|
var oldMap = (typeof oldFinancial === 'object' && oldFinancial) ? oldFinancial : {};
|
|
var newMap = (typeof newFinancial === 'object' && newFinancial) ? newFinancial : {};
|
|
|
|
var allKeys = [];
|
|
var seen = {};
|
|
Object.keys(oldMap).concat(Object.keys(newMap)).forEach(function(k) {
|
|
if (!seen[k]) { seen[k] = true; allKeys.push(k); }
|
|
});
|
|
|
|
var changedKeys = [];
|
|
allKeys.forEach(function(key) {
|
|
var oldVal = JSON.stringify(oldMap[key] !== undefined ? oldMap[key] : null);
|
|
var newVal = JSON.stringify(newMap[key] !== undefined ? newMap[key] : null);
|
|
if (oldVal !== newVal) changedKeys.push(key);
|
|
});
|
|
if (changedKeys.length === 0) return;
|
|
|
|
var prevHash = '';
|
|
try {
|
|
var lastEntry = e.dao.findFirstRecordByFilter(
|
|
'roFinancialAudit',
|
|
'roId = "' + e.record.id.replace(/"/g, '') + '"',
|
|
{ sort: '-at' },
|
|
);
|
|
if (lastEntry) prevHash = lastEntry.get('hash') || '';
|
|
} catch (_) {}
|
|
|
|
var roId = e.record.id;
|
|
var by = e.record.get('advisorName') || '';
|
|
var now = new Date().toISOString();
|
|
|
|
function simpleHash(str) {
|
|
var h = 0;
|
|
for (var i = 0; i < str.length; i++) {
|
|
h = ((h << 5) - h) + str.charCodeAt(i);
|
|
h = h & h;
|
|
}
|
|
return (h >>> 0).toString(16);
|
|
}
|
|
|
|
var auditCollection = app.findCollectionByNameOrId('roFinancialAudit');
|
|
|
|
changedKeys.forEach(function(key) {
|
|
var fromVal = oldMap[key] !== undefined ? oldMap[key] : null;
|
|
var toVal = newMap[key] !== undefined ? newMap[key] : null;
|
|
|
|
var payload = roId + key + now + JSON.stringify(fromVal) + JSON.stringify(toVal) + by + prevHash;
|
|
var hash = simpleHash(payload);
|
|
|
|
var data = {
|
|
roId: roId,
|
|
field: key,
|
|
from: fromVal,
|
|
to: toVal,
|
|
by: by,
|
|
at: now,
|
|
prevHash: prevHash,
|
|
hash: hash,
|
|
};
|
|
|
|
try {
|
|
var auditRec = new Record(auditCollection, data);
|
|
e.dao.saveRecord(auditRec);
|
|
} catch (err) {
|
|
console.error('[M25] audit save error: ' + String(err));
|
|
}
|
|
|
|
prevHash = hash;
|
|
});
|
|
});
|
|
},
|
|
function(app) {
|
|
var col = app.findCollectionByNameOrId('roFinancialAudit');
|
|
if (col) {
|
|
app.deleteCollection(col);
|
|
console.log('[M25] removed roFinancialAudit collection');
|
|
}
|
|
}
|
|
); |