All files / libs/payout-calculation/compute-engine/core-plan-template/src/planTemplate/evaluate evaluate-token.ts

73.91% Statements 51/69
40% Branches 2/5
100% Functions 1/1
73.91% Lines 51/69

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 701x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x                       5x 5x 5x 5x 5x 5x 5x 5x               5x 1x  
import {
  RowConverterUtils,
  type CalculationParser,
  type CalculationScope,
} from '@amalia/amalia-lang/formula/evaluate/shared';
import { type AmaliaFormula } from '@amalia/amalia-lang/formula/types';
import { CalculationError, type EngineErrorContext } from '@amalia/core/types';
import { type BaseCustomObjectDefinition } from '@amalia/data-capture/record-models/types';
import { assert, toError } from '@amalia/ext/typescript';
import { type ComputeEngineResult, type DatasetRowContent } from '@amalia/payout-calculation/types';
 
import { type UserStatement } from '../userStatement/UserStatement';
 
export class EvaluateToken {
  /**
   * Run a mathjs evaluation in the context of the current token.
   *
   * @param calculationParser
   * @param userStatement
   * @param formula
   * @param moreScope
   * @param context
   * @param rowContent
   * @param objectDefinition
   * @param silenceDefaultError
   */
  public static execute<TReturnValue extends ComputeEngineResult = ComputeEngineResult>(
    calculationParser: CalculationParser,
    userStatement: UserStatement | null,
    formula: AmaliaFormula,
    moreScope: CalculationScope,
    context: EngineErrorContext,
    rowContent?: DatasetRowContent,
    objectDefinition?: BaseCustomObjectDefinition,
    silenceDefaultError = false,
  ): TReturnValue {
    // Add the current row into the calculation parser if needed.
    const scopeRow = (() => {
      if (!(rowContent && objectDefinition)) {
        return null;
      }

      assert(userStatement, 'UserStatement required when passing a scopeRow');

      return {
        [objectDefinition.machineName]: RowConverterUtils.convertRowDatesAndCurrencies(
          objectDefinition.machineName,
          rowContent,
          userStatement.getDefinitions().relationships,
          userStatement.getDefinitions().customObjects,
        ),
      };
    })();
 
    try {
      return calculationParser.computeFormula(formula, {
        ...moreScope,
        ...scopeRow,
      }) as TReturnValue;
    } catch (err) {
      const error = toError(err);
      if (silenceDefaultError && error.message.includes('Cannot read properties of undefined')) {
        return null as TReturnValue;
      }

      throw new CalculationError(error, context);
    }
  }
}