import { CellValue, ColumnType, ITypeOptions, NumberFormat } from '../../types'; import { exhaustiveSwitch } from '../../typeUtils'; import { transformStringToNumber } from '../transformString'; import { transformCellValueToString, transformCellValueToStringArray, } from './transformCellValueToString'; import isNumber from 'lodash/isNumber'; export const transformCellValueToNumber = ({ originCellValue, originTypeOptions, targetTypeOptions, }: { originCellValue: CellValue; originTypeOptions: ITypeOptions; targetTypeOptions: Pick, 'numberFormat'>; }): number | null => { if (originCellValue === null || originCellValue === undefined) { return null; } if ( isNumber(originCellValue) && originTypeOptions.type === ColumnType.RATING && targetTypeOptions.numberFormat === NumberFormat.PERCENTAGE ) { return ( originCellValue / (originTypeOptions as ITypeOptions).ratingMax ); } switch (originTypeOptions.type) { case ColumnType.NUMBER: case ColumnType.CURRENCY: case ColumnType.RATING: case ColumnType.AUTO_NUMBER: return originCellValue as number; case ColumnType.FORMULA: case ColumnType.PROGRESS: case ColumnType.LONG_TEXT: case ColumnType.PHONE: case ColumnType.ROLLUP: case ColumnType.SELECT: case ColumnType.STATUS: case ColumnType.TEXT: { return transformCellValueToStringAndThenToNumber({ cellValue: originCellValue, typeOptions: originTypeOptions, }); } case ColumnType.LOOKUP: case ColumnType.MULTI_SELECT: case ColumnType.RECORD_REFERENCE: { const arrayCellValue = originCellValue as CellValue< | ColumnType.LOOKUP | ColumnType.MULTI_SELECT | ColumnType.RECORD_REFERENCE >; if (arrayCellValue.length >= 1) { return transformCellValueToStringArrayAndThenToNumber({ cellValue: arrayCellValue, typeOptions: originTypeOptions as ITypeOptions< | ColumnType.LOOKUP | ColumnType.MULTI_SELECT | ColumnType.RECORD_REFERENCE >, }); } return null; } case ColumnType.SUBTABLE: { const arrayCellValue = originCellValue as CellValue; if (arrayCellValue.length >= 1) { return transformCellValueToStringArrayAndThenToNumber({ cellValue: arrayCellValue, typeOptions: originTypeOptions as ITypeOptions, }); } return null; } case ColumnType.DATETIME: case ColumnType.CHECKBOX: case ColumnType.COLLABORATOR: case ColumnType.EMAIL: case ColumnType.INTEGRATION_REFERENCE: case ColumnType.MULTI_ATTACHMENT: case ColumnType.CREATED_AT: case ColumnType.CREATED_BY: case ColumnType.NOOP: case ColumnType.UNIQUE_ID: return null; default: { const { type } = originTypeOptions; return exhaustiveSwitch({ switchValue: type, returnValue: null, }); } } }; const transformCellValueToStringAndThenToNumber = < OT extends ColumnType = ColumnType >({ cellValue, typeOptions, }: { cellValue: CellValue; typeOptions: ITypeOptions; }) => { if (typeOptions.type === ColumnType.PHONE) return null; const stringValue = transformCellValueToString({ cellValue, typeOptions, }); if (stringValue === null) return null; // I'm not sure if it makes sense to check the date format // But if needed, it should be implemented in transformStringToNumber return transformStringToNumber(stringValue); }; const transformCellValueToStringArrayAndThenToNumber = < OT extends | ColumnType.MULTI_SELECT | ColumnType.LOOKUP | ColumnType.RECORD_REFERENCE | ColumnType.SUBTABLE >({ cellValue, typeOptions, }: { cellValue: CellValue; typeOptions: ITypeOptions; }) => { const stringValueArray = transformCellValueToStringArray({ cellValue, typeOptions, }); if (stringValueArray.length <= 0) return null; return transformStringToNumber(stringValueArray[0]); };