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                103x                                         17x 17x 17x 17x                   144x 144x 144x                   51x   25x                     51x                   16x 16x 16x 16x                         17x                                                                                      
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 })}%`;
}