jupiter-dynamic-forms 1.19.9 → 1.20.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/dist/index.mjs CHANGED
@@ -6432,50 +6432,87 @@ let JupiterFormSection = class extends LitElement {
6432
6432
  this._totalChildConceptsMap.clear();
6433
6433
  this._traverseTotalGroups(concepts);
6434
6434
  }
6435
+ /**
6436
+ * JDF-038: XBRL uses more than one preferredLabel role to mark a "total" row — the plain
6437
+ * `.../role/totalLabel` and the sign-flipped `.../role/negatedTotalLabel` (used for subtotals of
6438
+ * negated/expense items, e.g. "Total of sum of expenses"). A case-sensitive `includes('totalLabel')`
6439
+ * misses the latter, because "negatedTotalLabel" contains "TotalLabel" with a capital T. Case-insensitive
6440
+ * matching is the single source of truth for "is this row a total" everywhere in this file.
6441
+ */
6442
+ static _isTotalLabel(preferredLabel) {
6443
+ return !!(preferredLabel == null ? void 0 : preferredLabel.toLowerCase().includes("totallabel"));
6444
+ }
6445
+ /**
6446
+ * A member of a total's sibling/child group can itself be a presentation-only abstract wrapper
6447
+ * (e.g. "Group equity" wrapping Equity + Third party share + "Total of group equity") rather than
6448
+ * a value-bearing concept. Abstract concepts never have a form field, so resolve them to the nested
6449
+ * totalLabel concept that actually carries their aggregate value — otherwise the outer total's
6450
+ * calculation silently drops that whole subgroup (formData lookup on the abstract's id is always empty).
6451
+ */
6452
+ static _resolveValueConcept(node, depth = 0) {
6453
+ var _a;
6454
+ if (!node.abstract)
6455
+ return node;
6456
+ if (depth > 5 || !((_a = node.children) == null ? void 0 : _a.length))
6457
+ return null;
6458
+ const nestedTotal = node.children.find((c2) => JupiterFormSection._isTotalLabel(c2.preferredLabel));
6459
+ if (!nestedTotal)
6460
+ return null;
6461
+ return JupiterFormSection._resolveValueConcept(nestedTotal, depth + 1);
6462
+ }
6463
+ _registerTotalGroup(totalConcept, members) {
6464
+ const resolvedMembers = members.map((m) => JupiterFormSection._resolveValueConcept(m)).filter((m) => m !== null);
6465
+ if (resolvedMembers.length === 0)
6466
+ return;
6467
+ const memberIds = resolvedMembers.map((m) => m.id);
6468
+ this._totalChildrenMap.set(totalConcept.id, memberIds);
6469
+ this._totalConceptMap.set(totalConcept.id, totalConcept);
6470
+ this._totalChildConceptsMap.set(totalConcept.id, resolvedMembers);
6471
+ for (const memberId of memberIds) {
6472
+ this._memberParentMap.set(memberId, totalConcept.id);
6473
+ }
6474
+ }
6435
6475
  _traverseTotalGroups(concepts) {
6436
- var _a, _b, _c, _d;
6476
+ var _a, _b;
6437
6477
  for (let i2 = 0; i2 < concepts.length; i2++) {
6438
6478
  const concept = concepts[i2];
6439
- if ((_a = concept.preferredLabel) == null ? void 0 : _a.includes("totalLabel")) {
6440
- if ((_b = concept.children) == null ? void 0 : _b.length) {
6441
- const childIds = concept.children.map((c2) => c2.id);
6442
- this._totalChildrenMap.set(concept.id, childIds);
6443
- this._totalConceptMap.set(concept.id, concept);
6444
- this._totalChildConceptsMap.set(concept.id, concept.children);
6445
- for (const childId of childIds) {
6446
- this._memberParentMap.set(childId, concept.id);
6447
- }
6479
+ if (JupiterFormSection._isTotalLabel(concept.preferredLabel)) {
6480
+ if ((_a = concept.children) == null ? void 0 : _a.length) {
6481
+ this._registerTotalGroup(concept, concept.children);
6448
6482
  } else {
6449
6483
  let lastTotalIdx = -1;
6450
6484
  for (let j = i2 - 1; j >= 0; j--) {
6451
- if ((_c = concepts[j].preferredLabel) == null ? void 0 : _c.includes("totalLabel")) {
6485
+ if (JupiterFormSection._isTotalLabel(concepts[j].preferredLabel)) {
6452
6486
  lastTotalIdx = j;
6453
6487
  break;
6454
6488
  }
6455
6489
  }
6456
6490
  const siblings = concepts.slice(lastTotalIdx + 1, i2);
6457
6491
  if (siblings.length > 0) {
6458
- const siblingIds = siblings.map((s2) => s2.id);
6459
- this._totalChildrenMap.set(concept.id, siblingIds);
6460
- this._totalConceptMap.set(concept.id, concept);
6461
- this._totalChildConceptsMap.set(concept.id, siblings);
6462
- for (const siblingId of siblingIds) {
6463
- this._memberParentMap.set(siblingId, concept.id);
6464
- }
6492
+ this._registerTotalGroup(concept, siblings);
6493
+ } else if (lastTotalIdx >= 0) {
6494
+ this._registerTotalGroup(concept, [concepts[lastTotalIdx]]);
6465
6495
  }
6466
6496
  }
6467
6497
  }
6468
- if ((_d = concept.children) == null ? void 0 : _d.length) {
6498
+ if ((_b = concept.children) == null ? void 0 : _b.length) {
6469
6499
  this._traverseTotalGroups(concept.children);
6470
6500
  }
6471
6501
  }
6472
6502
  }
6473
6503
  _runCalculationCheck(conceptId, columnId) {
6504
+ const totalIds = /* @__PURE__ */ new Set();
6505
+ if (this._totalConceptMap.has(conceptId))
6506
+ totalIds.add(conceptId);
6507
+ const parentTotalId = this._memberParentMap.get(conceptId);
6508
+ if (parentTotalId)
6509
+ totalIds.add(parentTotalId);
6510
+ for (const totalConceptId of totalIds) {
6511
+ this._evaluateTotal(totalConceptId, columnId);
6512
+ }
6513
+ }
6514
+ _evaluateTotal(totalConceptId, columnId) {
6474
6515
  var _a;
6475
- const isSelfTotal = this._totalConceptMap.has(conceptId);
6476
- const totalConceptId = isSelfTotal ? conceptId : this._memberParentMap.get(conceptId);
6477
- if (!totalConceptId)
6478
- return;
6479
6516
  const totalConcept = this._totalConceptMap.get(totalConceptId);
6480
6517
  const totalRaw = (_a = this.formData[totalConceptId]) == null ? void 0 : _a[columnId];
6481
6518
  const key = `${totalConceptId}__${columnId}`;