@dhyasama/totem-models 11.123.0 → 11.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Financials.js +16 -6
- package/package.json +1 -1
- package/scripts/migrate-financials-schema.js +90 -22
package/lib/Financials.js
CHANGED
|
@@ -331,8 +331,8 @@ module.exports = function(mongoose, config) {
|
|
|
331
331
|
// Check if the metric update was successful
|
|
332
332
|
const snapshot = updatedDocument.snapshots.find(s => s.uuid === snapshotUUID);
|
|
333
333
|
if (snapshot) {
|
|
334
|
-
const updatedMetric = snapshot.metrics.find(m => m.name === metric.name);
|
|
335
|
-
if (updatedMetric && updatedMetric.
|
|
334
|
+
const updatedMetric = snapshot.metrics.find(m => m.name === metric.name && m.scenario === metric.scenario);
|
|
335
|
+
if (updatedMetric && updatedMetric.value === metric.value) {
|
|
336
336
|
console.log('Metric was successfully updated:', updatedMetric);
|
|
337
337
|
result = true;
|
|
338
338
|
} else {
|
|
@@ -361,7 +361,8 @@ module.exports = function(mongoose, config) {
|
|
|
361
361
|
|
|
362
362
|
console.log('Upserting metric:', metric);
|
|
363
363
|
console.log('Upserting metric name:', metric.name);
|
|
364
|
-
console.log('Upserting metric
|
|
364
|
+
console.log('Upserting metric scenario:', metric.scenario);
|
|
365
|
+
console.log('Upserting metric value:', metric.value);
|
|
365
366
|
console.log('Upserting metric breakdown:', metric.breakdown);
|
|
366
367
|
|
|
367
368
|
// Check if the metric exists and update it
|
|
@@ -369,16 +370,25 @@ module.exports = function(mongoose, config) {
|
|
|
369
370
|
{
|
|
370
371
|
_id: financialsId,
|
|
371
372
|
'snapshots.uuid': snapshotUUID,
|
|
372
|
-
'snapshots.metrics.name': metric.name
|
|
373
|
+
'snapshots.metrics.name': metric.name,
|
|
374
|
+
'snapshots.metrics.scenario': metric.scenario
|
|
373
375
|
},
|
|
374
376
|
{
|
|
375
377
|
$set: {
|
|
376
|
-
'snapshots.$.metrics.$[metric].
|
|
378
|
+
'snapshots.$.metrics.$[metric].value': metric.value,
|
|
377
379
|
'snapshots.$.metrics.$[metric].breakdown': metric.breakdown,
|
|
380
|
+
'snapshots.$.metrics.$[metric].source': metric.source,
|
|
381
|
+
'snapshots.$.metrics.$[metric].verified': metric.verified
|
|
382
|
+
},
|
|
383
|
+
$push: {
|
|
384
|
+
'snapshots.$.metrics.$[metric].history': {
|
|
385
|
+
$each: metric.history || [],
|
|
386
|
+
$position: 0
|
|
387
|
+
}
|
|
378
388
|
}
|
|
379
389
|
},
|
|
380
390
|
{
|
|
381
|
-
arrayFilters: [{ 'metric.name': metric.name }],
|
|
391
|
+
arrayFilters: [{ 'metric.name': metric.name, 'metric.scenario': metric.scenario }],
|
|
382
392
|
new: true,
|
|
383
393
|
session: _session
|
|
384
394
|
}
|
package/package.json
CHANGED
|
@@ -6,14 +6,21 @@
|
|
|
6
6
|
* Changes being migrated:
|
|
7
7
|
* 1. Rename field: review → approval (in recurring and snapshots)
|
|
8
8
|
* 2. Update status enum value: 'In Review' → 'Pending'
|
|
9
|
-
* 3.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* 3. Remove budget, forecast, and scenario fields from form[] template (commits 71c84ac, 4bca5a3)
|
|
10
|
+
* 4. Populate history[] for documents[], questions[], and metrics[]
|
|
11
|
+
* - For documents and questions: history uses actions ['updated', 'deleted'] only
|
|
12
|
+
* History populated with submission entry only (1 entry if submitted)
|
|
13
|
+
* - For metrics: history uses actions ['updated', 'deleted', 'verified']
|
|
14
|
+
* History populated with submission and approval entries (2 entries if approved)
|
|
15
|
+
* 5. Set scenario to 'actual' for all existing documents[] (historical data is actual)
|
|
16
|
+
* 6. Remove verified field from documents[] (removed in commit 300a22a)
|
|
17
|
+
* 7. Remove verified field from questions[] (removed in commit 300a22a)
|
|
18
|
+
* 8. Add verified: true for metrics[] only
|
|
19
|
+
* 9. Convert metrics from old structure { name, actual, budget, forecast, breakdown }
|
|
13
20
|
* to new structure { name, scenario, value, breakdown, source, verified, history }
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
21
|
+
* 10. Link metrics to their source financial statement documents (Income Statement,
|
|
22
|
+
* Balance Sheet, Cash Flow Statement) when available
|
|
23
|
+
* 11. Remove projections array from root level
|
|
17
24
|
*
|
|
18
25
|
* Usage:
|
|
19
26
|
* node scripts/migrate-financials-schema.js <customerId> [--config <configPath>] [--dry-run]
|
|
@@ -155,8 +162,51 @@ async function migrateFinancials() {
|
|
|
155
162
|
changes.push(` - Snapshot ${index}: Changed status 'In Review' → 'Pending'`);
|
|
156
163
|
}
|
|
157
164
|
|
|
165
|
+
// 2c. Remove budget, forecast, and scenario fields from form[] template
|
|
166
|
+
if (snapshot.form && snapshot.form.length > 0) {
|
|
167
|
+
snapshot.form.forEach((formItem, fIndex) => {
|
|
168
|
+
let fieldsRemoved = [];
|
|
169
|
+
if ('budget' in formItem) {
|
|
170
|
+
updates.$unset = updates.$unset || {};
|
|
171
|
+
updates.$unset[`snapshots.${index}.form.${fIndex}.budget`] = '';
|
|
172
|
+
fieldsRemoved.push('budget');
|
|
173
|
+
}
|
|
174
|
+
if ('forecast' in formItem) {
|
|
175
|
+
updates.$unset = updates.$unset || {};
|
|
176
|
+
updates.$unset[`snapshots.${index}.form.${fIndex}.forecast`] = '';
|
|
177
|
+
fieldsRemoved.push('forecast');
|
|
178
|
+
}
|
|
179
|
+
if ('scenario' in formItem) {
|
|
180
|
+
updates.$unset = updates.$unset || {};
|
|
181
|
+
updates.$unset[`snapshots.${index}.form.${fIndex}.scenario`] = '';
|
|
182
|
+
fieldsRemoved.push('scenario');
|
|
183
|
+
}
|
|
184
|
+
if (fieldsRemoved.length > 0) {
|
|
185
|
+
changes.push(` - Snapshot ${index}: Removed ${fieldsRemoved.join(', ')} from form[${fIndex}]`);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
158
190
|
// Build history array from snapshot submission/approval data
|
|
159
|
-
|
|
191
|
+
// Note: For documents and questions, only 'updated' and 'deleted' actions are valid
|
|
192
|
+
// Documents/questions are not verified individually - only the snapshot is approved
|
|
193
|
+
// For metrics, 'verified' is also valid since they can be individually verified
|
|
194
|
+
const buildHistoryForDocumentsAndQuestions = () => {
|
|
195
|
+
const history = [];
|
|
196
|
+
|
|
197
|
+
// Add submission history entry only (no approval/verification for individual docs/questions)
|
|
198
|
+
if (snapshot.submittedOn && snapshot.submittedBy) {
|
|
199
|
+
history.push({
|
|
200
|
+
timestamp: snapshot.submittedOn,
|
|
201
|
+
user: snapshot.submittedBy,
|
|
202
|
+
action: 'updated'
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return history;
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const buildHistoryForMetrics = () => {
|
|
160
210
|
const history = [];
|
|
161
211
|
|
|
162
212
|
// Add submission history entry
|
|
@@ -168,7 +218,7 @@ async function migrateFinancials() {
|
|
|
168
218
|
});
|
|
169
219
|
}
|
|
170
220
|
|
|
171
|
-
// Add approval history entry
|
|
221
|
+
// Add approval history entry (use 'verified' for metrics)
|
|
172
222
|
if (snapshot.approvedOn && snapshot.approvedBy) {
|
|
173
223
|
history.push({
|
|
174
224
|
timestamp: snapshot.approvedOn,
|
|
@@ -180,29 +230,47 @@ async function migrateFinancials() {
|
|
|
180
230
|
return history;
|
|
181
231
|
};
|
|
182
232
|
|
|
183
|
-
const
|
|
233
|
+
const historyArrayForDocumentsAndQuestions = buildHistoryForDocumentsAndQuestions();
|
|
234
|
+
const historyArrayForMetrics = buildHistoryForMetrics();
|
|
184
235
|
|
|
185
|
-
//
|
|
236
|
+
// 2d. Add history to documents, set scenario to 'actual', and remove verified field
|
|
186
237
|
if (snapshot.documents && snapshot.documents.length > 0) {
|
|
187
238
|
snapshot.documents.forEach((doc, docIndex) => {
|
|
188
239
|
if (!('history' in doc)) {
|
|
189
|
-
updates[`snapshots.${index}.documents.${docIndex}.history`] =
|
|
190
|
-
changes.push(` - Snapshot ${index}: Added history (${
|
|
240
|
+
updates[`snapshots.${index}.documents.${docIndex}.history`] = historyArrayForDocumentsAndQuestions;
|
|
241
|
+
changes.push(` - Snapshot ${index}: Added history (${historyArrayForDocumentsAndQuestions.length} entries) to document ${docIndex}`);
|
|
242
|
+
}
|
|
243
|
+
// Set scenario to 'actual' for all existing documents (historical data is actual)
|
|
244
|
+
if (!('scenario' in doc)) {
|
|
245
|
+
updates[`snapshots.${index}.documents.${docIndex}.scenario`] = 'actual';
|
|
246
|
+
changes.push(` - Snapshot ${index}: Set scenario to 'actual' for document ${docIndex}`);
|
|
247
|
+
}
|
|
248
|
+
// Remove verified field if it exists (removed in commit 300a22a)
|
|
249
|
+
if ('verified' in doc) {
|
|
250
|
+
updates.$unset = updates.$unset || {};
|
|
251
|
+
updates.$unset[`snapshots.${index}.documents.${docIndex}.verified`] = '';
|
|
252
|
+
changes.push(` - Snapshot ${index}: Removed verified field from document ${docIndex}`);
|
|
191
253
|
}
|
|
192
254
|
});
|
|
193
255
|
}
|
|
194
256
|
|
|
195
|
-
//
|
|
257
|
+
// 2e. Add history to questions and remove verified field
|
|
196
258
|
if (snapshot.questions && snapshot.questions.length > 0) {
|
|
197
259
|
snapshot.questions.forEach((question, qIndex) => {
|
|
198
260
|
if (!('history' in question)) {
|
|
199
|
-
updates[`snapshots.${index}.questions.${qIndex}.history`] =
|
|
200
|
-
changes.push(` - Snapshot ${index}: Added history (${
|
|
261
|
+
updates[`snapshots.${index}.questions.${qIndex}.history`] = historyArrayForDocumentsAndQuestions;
|
|
262
|
+
changes.push(` - Snapshot ${index}: Added history (${historyArrayForDocumentsAndQuestions.length} entries) to question ${qIndex}`);
|
|
263
|
+
}
|
|
264
|
+
// Remove verified field if it exists (removed in commit 300a22a)
|
|
265
|
+
if ('verified' in question) {
|
|
266
|
+
updates.$unset = updates.$unset || {};
|
|
267
|
+
updates.$unset[`snapshots.${index}.questions.${qIndex}.verified`] = '';
|
|
268
|
+
changes.push(` - Snapshot ${index}: Removed verified field from question ${qIndex}`);
|
|
201
269
|
}
|
|
202
270
|
});
|
|
203
271
|
}
|
|
204
272
|
|
|
205
|
-
//
|
|
273
|
+
// 2f. Migrate metrics structure
|
|
206
274
|
if (snapshot.metrics && snapshot.metrics.length > 0) {
|
|
207
275
|
const oldMetrics = [...snapshot.metrics];
|
|
208
276
|
const newMetrics = [];
|
|
@@ -256,7 +324,7 @@ async function migrateFinancials() {
|
|
|
256
324
|
value: metric.actual,
|
|
257
325
|
breakdown: metric.breakdown || {},
|
|
258
326
|
verified: true,
|
|
259
|
-
history:
|
|
327
|
+
history: historyArrayForMetrics
|
|
260
328
|
};
|
|
261
329
|
if (source) newMetric.source = source;
|
|
262
330
|
newMetrics.push(newMetric);
|
|
@@ -269,7 +337,7 @@ async function migrateFinancials() {
|
|
|
269
337
|
value: metric.budget,
|
|
270
338
|
breakdown: {},
|
|
271
339
|
verified: true,
|
|
272
|
-
history:
|
|
340
|
+
history: historyArrayForMetrics
|
|
273
341
|
};
|
|
274
342
|
if (source) newMetric.source = source;
|
|
275
343
|
newMetrics.push(newMetric);
|
|
@@ -282,7 +350,7 @@ async function migrateFinancials() {
|
|
|
282
350
|
value: metric.forecast,
|
|
283
351
|
breakdown: {},
|
|
284
352
|
verified: true,
|
|
285
|
-
history:
|
|
353
|
+
history: historyArrayForMetrics
|
|
286
354
|
};
|
|
287
355
|
if (source) newMetric.source = source;
|
|
288
356
|
newMetrics.push(newMetric);
|
|
@@ -300,8 +368,8 @@ async function migrateFinancials() {
|
|
|
300
368
|
changes.push(` - Snapshot ${index}: Added verified to metric ${mIndex}`);
|
|
301
369
|
}
|
|
302
370
|
if (!('history' in metric)) {
|
|
303
|
-
updates[`snapshots.${index}.metrics.${mIndex}.history`] =
|
|
304
|
-
changes.push(` - Snapshot ${index}: Added history (${
|
|
371
|
+
updates[`snapshots.${index}.metrics.${mIndex}.history`] = historyArrayForMetrics;
|
|
372
|
+
changes.push(` - Snapshot ${index}: Added history (${historyArrayForMetrics.length} entries) to metric ${mIndex}`);
|
|
305
373
|
}
|
|
306
374
|
if (!('source' in metric)) {
|
|
307
375
|
const source = getSourceForMetric(metric.name);
|