All files / src/pages/flowsheet-page/economics/cost-items-panel/model unitCostGrouping.ts

60.52% Statements 23/38
41.37% Branches 12/29
100% Functions 0/0
61.76% Lines 21/34

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                            19x 19x   19x   19x       7x   7x 7x         7x             7x       7x       14x 14x         7x       7x 7x 7x             7x         21x 21x 6x                                           6x              
import {
  formatEquipmentCategoryLabel,
  formatUnitOperationType,
} from "./capitalLineHelpers";
import type { UnitCostRow } from "./capitalLineTypes";
 
export type UnitCostGroupModel = {
  key: string;
  label: string;
  title: string;
  rows: UnitCostRow[];
};
 
export function rowHasSizingValue(row: UnitCostRow) {
  const driver = row.costableItem?.cost_driver;
  Iif (!driver) return false;
  const selectedProperty =
    driver.property_info &&
    driver.property_info !== driver.manual_property_info;
  return Boolean(selectedProperty || driver.design_value);
}
 
export function groupRowsByEquipmentCategory(rows: UnitCostRow[]) {
  const groups = new Map<string, UnitCostGroupModel>();
  for (const row of rows) {
    const key = equipmentCategoryKey(row);
    const group = groups.get(key);
    if (group) {
      group.rows.push(row);
      continue;
    }
    groups.set(key, {
      key,
      label: equipmentCategoryLabel(row),
      title: equipmentCategoryTitle(row),
      rows: [row],
    });
  }
  return [...groups.values()];
}
 
function equipmentCategoryKey(row: UnitCostRow) {
  return canonicalEquipmentCategory(row) || "unit_operation";
}
 
function equipmentCategoryLabel(row: UnitCostRow) {
  const category = canonicalEquipmentCategory(row);
  if (category) return formatEquipmentCategoryLabel(category);
  return formatUnitOperationType(row.unit.objectType);
}
 
function equipmentCategoryTitle(row: UnitCostRow) {
  return pluralizeCategoryLabel(equipmentCategoryLabel(row));
}
 
function pluralizeCategoryLabel(label: string) {
  const normalized = label.trim();
  const lower = normalized.toLowerCase();
  Iif (!normalized || lower.endsWith("equipment")) return label;
  if (/[sxz]$/i.test(normalized) || /(ch|sh)$/i.test(normalized)) {
    return `${normalized}es`;
  }
  if (/[^aeiou]y$/i.test(normalized)) {
    return `${normalized.slice(0, -1)}ies`;
  }
  return `${normalized}s`;
}
 
function canonicalEquipmentCategory(row: UnitCostRow) {
  const mappedCategory =
    row.costableItem?.equipment_mapping?.equipment_category?.trim();
  if (mappedCategory) return mappedCategory;
  return equipmentCategoryForObjectType(row.unit.objectType);
}
 
function equipmentCategoryForObjectType(objectType?: string) {
  switch (objectType) {
    case "Tank":
      return "liquid_storage_tank";
    case "compressor":
      return "compressor";
    case "crystallizer":
      return "crystallizer";
    case "heatExchanger":
    case "heat_exchanger_1d":
    case "plate_heat_exchanger":
    case "heat_exchanger_ntu":
    case "heat_exchanger_lc":
      return "heat_exchanger";
    case "mixer":
      return "mixer";
    case "phaseSeparator":
      return "phase_separator";
    case "pump":
      return "pump";
    case "reverse_osmosis_0d":
      return "reverse_osmosis";
    default:
      return objectType || "";
  }
}