All files / src/pages/flowsheet-page/economics/results-panel/model resultWarnings.ts

38.63% Statements 17/44
23.25% Branches 10/43
66.66% Functions 2/3
41.02% Lines 16/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137                76x                                         3x 3x 3x 3x                   88x 88x 88x                   10x   5x                     12x                   12x 12x 12x 12x                         3x                                                                                      
import type { WarningRef } from "./types";
import {
  arrayValue,
  isPresent,
  objectValue,
  stringField,
} from "./valueParsing";
 
const REVIEW_RESULTS_HIDDEN_WARNING_CODES = new Set([
  "applicability_warning",
  "cost_curve_arithmetic_error",
  "discrete_selector_adjustment",
  "expression_arithmetic_error",
  "input_above_valid_range",
  "input_below_valid_range",
  "installed_cost_basis",
  "installed_cost_factor_double_counting",
  "missing_source_metadata",
  "missing_valid_range",
  "negative_cost_output",
  "non_finite_cost_output",
  "selected_variant_input_above_valid_range",
  "selected_variant_input_below_valid_range",
  "selected_variant_valid_range_note",
  "source_range_precision_visual_inferred",
  "valid_range_note",
]);
 
export function parseWarningRef(value: unknown): WarningRef | null {
  const source = objectValue(value);
  Iif (!source) return null;
  const code = stringField(source.code || "warning");
  return {
    code,
    severity: stringField(source.severity || "warning"),
    message: warningMessage(source, code),
    source_row_key:
      source.source_row_key == null ? null : stringField(source.source_row_key),
  };
}
 
export function warningRefsFromPayload(payload: unknown, sourceRowKey: string) {
  const source = objectValue(payload);
  const warnings = source ? arrayValue(source.warnings) : [];
  return warnings
    .map(parseWarningRef)
    .filter(isPresent)
    .map((warning) => ({
      ...warning,
      source_row_key: warning.source_row_key ?? sourceRowKey,
    }));
}
 
export function uniqueWarnings(warnings: WarningRef[]) {
  return Array.from(
    new Map(
      warnings.map((warning) => [
        `${warning.code}-${warning.message}-${warning.source_row_key ?? ""}`,
        warning,
      ]),
    ).values(),
  );
}
 
export function visibleResultWarnings<
  TWarning extends { code: string; message: string },
>(warnings: TWarning[]) {
  return warnings.filter((warning) => !isHiddenReviewResultWarning(warning));
}
 
export function isHiddenReviewResultWarning({
  code,
  message,
}: {
  code: string;
  message: string;
}) {
  const normalizedCode = code.toLowerCase();
  Iif (REVIEW_RESULTS_HIDDEN_WARNING_CODES.has(normalizedCode)) return true;
  const normalizedMessage = message.toLowerCase();
  return (
    normalizedMessage.includes("cost curve") ||
    normalizedMessage.includes("curve range") ||
    normalizedMessage.includes("visual-inferred") ||
    normalizedMessage.includes("inferred visually from source material") ||
    normalizedMessage.includes("reviewer confirmation required")
  );
}
 
function warningMessage(source: Record<string, unknown>, code: string) {
  if (code === "discrete_selector_adjustment") {
    return discreteSelectorAdjustmentMessage(source);
  }
  return stringField(source.message);
}
 
function discreteSelectorAdjustmentMessage(source: Record<string, unknown>) {
  const context = objectValue(source.context);
  const label = context ? stringField(context.label) : "";
  const enteredValue = context ? stringField(context.entered_value) : "";
  const enteredUnit = context ? stringField(context.entered_unit) : "";
  const rangeDirection = context ? stringField(context.range_direction) : "";
  const percentageDifference = context
    ? stringField(context.percentage_difference)
    : "";
  const selectorMin = context ? stringField(context.selector_min) : "";
  const selectorMax = context ? stringField(context.selector_max) : "";
  if (
    !rangeDirection ||
    !percentageDifference ||
    !selectorMin ||
    !selectorMax
  ) {
    return "";
  }
  const entered = formatWarningValue(enteredValue, enteredUnit);
  const displayLabel = label || "Cost curve variable";
  const supportedRange = `${formatWarningValue(selectorMin, enteredUnit)} to ${formatWarningValue(selectorMax, enteredUnit)}`;
  const percentage = formatPercent(percentageDifference);
  const inputLabel = displayLabel.toLowerCase();
  if (entered) {
    return `${displayLabel} is ${entered}, which is ${percentage} ${rangeDirection} the selected cost curve's supported range (${supportedRange}). Select a curve with a compatible ${inputLabel} range or enter a manual value if this is intentional.`;
  }
  return `${displayLabel} is ${percentage} ${rangeDirection} the selected cost curve's supported range (${supportedRange}). Select a curve with a compatible ${inputLabel} range or enter a manual value if this is intentional.`;
}
 
function formatWarningValue(value: string, unit: string) {
  Iif (!value) return "";
  return unit ? `${value} ${unit}` : value;
}
 
function formatPercent(value: string) {
  const parsed = Number(value);
  Iif (!Number.isFinite(parsed)) return `${value}%`;
  return `${parsed.toLocaleString(undefined, { maximumFractionDigits: 1 })}%`;
}