@dhyasama/totem-models 11.122.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 -9
- package/lib/Organization.js +0 -1
- package/package.json +1 -1
- package/scripts/migrate-financials-schema.js +90 -22
package/lib/Financials.js
CHANGED
|
@@ -88,9 +88,6 @@ module.exports = function(mongoose, config) {
|
|
|
88
88
|
form: [{
|
|
89
89
|
name: { type: String, trim: true },
|
|
90
90
|
type: { type: String, enum: [null, 'header', 'block', 'document', 'metric', 'question'] },
|
|
91
|
-
scenario: { type: String, enum: ['actual', 'budget', 'forecast'] },
|
|
92
|
-
budget: { type: Number },
|
|
93
|
-
forecast: { type: Number },
|
|
94
91
|
required: { type: Boolean, default: false }
|
|
95
92
|
}],
|
|
96
93
|
|
|
@@ -334,8 +331,8 @@ module.exports = function(mongoose, config) {
|
|
|
334
331
|
// Check if the metric update was successful
|
|
335
332
|
const snapshot = updatedDocument.snapshots.find(s => s.uuid === snapshotUUID);
|
|
336
333
|
if (snapshot) {
|
|
337
|
-
const updatedMetric = snapshot.metrics.find(m => m.name === metric.name);
|
|
338
|
-
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) {
|
|
339
336
|
console.log('Metric was successfully updated:', updatedMetric);
|
|
340
337
|
result = true;
|
|
341
338
|
} else {
|
|
@@ -364,7 +361,8 @@ module.exports = function(mongoose, config) {
|
|
|
364
361
|
|
|
365
362
|
console.log('Upserting metric:', metric);
|
|
366
363
|
console.log('Upserting metric name:', metric.name);
|
|
367
|
-
console.log('Upserting metric
|
|
364
|
+
console.log('Upserting metric scenario:', metric.scenario);
|
|
365
|
+
console.log('Upserting metric value:', metric.value);
|
|
368
366
|
console.log('Upserting metric breakdown:', metric.breakdown);
|
|
369
367
|
|
|
370
368
|
// Check if the metric exists and update it
|
|
@@ -372,16 +370,25 @@ module.exports = function(mongoose, config) {
|
|
|
372
370
|
{
|
|
373
371
|
_id: financialsId,
|
|
374
372
|
'snapshots.uuid': snapshotUUID,
|
|
375
|
-
'snapshots.metrics.name': metric.name
|
|
373
|
+
'snapshots.metrics.name': metric.name,
|
|
374
|
+
'snapshots.metrics.scenario': metric.scenario
|
|
376
375
|
},
|
|
377
376
|
{
|
|
378
377
|
$set: {
|
|
379
|
-
'snapshots.$.metrics.$[metric].
|
|
378
|
+
'snapshots.$.metrics.$[metric].value': metric.value,
|
|
380
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
|
+
}
|
|
381
388
|
}
|
|
382
389
|
},
|
|
383
390
|
{
|
|
384
|
-
arrayFilters: [{ 'metric.name': metric.name }],
|
|
391
|
+
arrayFilters: [{ 'metric.name': metric.name, 'metric.scenario': metric.scenario }],
|
|
385
392
|
new: true,
|
|
386
393
|
session: _session
|
|
387
394
|
}
|
package/lib/Organization.js
CHANGED
|
@@ -320,7 +320,6 @@ module.exports = function(mongoose, config) {
|
|
|
320
320
|
_id: false,
|
|
321
321
|
name: { type: String, trim: true },
|
|
322
322
|
type: { type: String, enum: [null, 'header', 'block', 'document', 'metric', 'question'] },
|
|
323
|
-
scenario: { type: String, enum: ['actual', 'budget', 'forecast'] },
|
|
324
323
|
required: { type: Boolean, default: false }
|
|
325
324
|
}]
|
|
326
325
|
}],
|
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);
|