spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
Added Formulas.DOLLAR
author
Ben Vogt <[email protected]>
date
2017-02-20 19:40:20
stats
5 file(s) changed, 55 insertions(+), 6 deletions(-)
files
README.md
src/RawFormulas/RawFormulas.ts
src/RawFormulas/Utils.ts
tests/FormulasTest.ts
tests/SheetFormulaTest.ts
  1diff --git a/README.md b/README.md
  2index 3b16fe2..d47b149 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -45,3 +45,8 @@ don't check for this, and they should.
  6 
  7 ### jStat functions should know their caller
  8 Either through `arguments`, or directly passed in like `mean("FORMULA", [10, 20, 30])`
  9+
 10+### Dollar functions have special types
 11+Although dollar functions look like they just format `number`s, it seems like they have a special type under the hood.
 12+This means that we should do dollar->number casting in all casting functions. For now, just using number primitive.
 13+See `DOLLAR` function for more info.
 14\ No newline at end of file
 15diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
 16index c995254..7c6f00b 100644
 17--- a/src/RawFormulas/RawFormulas.ts
 18+++ b/src/RawFormulas/RawFormulas.ts
 19@@ -103,7 +103,7 @@ import {
 20   TypeCaster,
 21   Serializer
 22 } from "./Utils";
 23-import {CellError, NUM_ERROR} from "../Errors"
 24+import {CellError} from "../Errors"
 25 import * as ERRORS from "../Errors"
 26 
 27 var ACCRINT = Formula["ACCRINT"];
 28@@ -117,7 +117,6 @@ var DATEVALUE = function (dateString: string) : Date {
 29 var DAY = Formula["DAY"];
 30 var DAYS = Formula["DAYS"];
 31 var DAYS360 = Formula["DAYS360"];
 32-var DOLLAR = Formula["DOLLAR"];
 33 var DOLLARDE = Formula["DOLLARDE"];
 34 var DOLLARFR = Formula["DOLLARFR"];
 35 var EDATE = function (start_date: Date, months) {
 36@@ -133,6 +132,30 @@ var __COMPLEX = {
 37 var YEARFRAC = Formula["YEARFRAC"];
 38 
 39 
 40+/**
 41+ * Formats a number into the locale-specific currency format. WARNING: Currently the equivalent of TRUNC, since this
 42+ * returns numbers
 43+ * @param values[0] number - The value to be formatted.
 44+ * @param values[1] places - [ OPTIONAL - 2 by default ] - The number of decimal places to display.
 45+ * @returns {number} dollars
 46+ * @constructor
 47+ * TODO: In GS and Excel, Dollar values are primitive types at a certain level, meaning you can do =DOLLAR(10) + 10
 48+ * TODO(cont.) and the result will be 20. Right now, JS allows you to inherit from primitives so you can use operators
 49+ * TODO(cont.) on them (eg: new Number(10) + 10 == 20) but TS does not. So for now, Dollar values will be represented
 50+ * TODO(cont.) with the primitive number type. At some point TS might allow me to suppress the warnings with
 51+ * TODO(cont.) https://github.com/Microsoft/TypeScript/issues/9448 or
 52+ * TODO(cont.) https://github.com/Microsoft/TypeScript/issues/11051
 53+ */
 54+var DOLLAR = function (...values) : number {
 55+  ArgsChecker.checkLengthWithin(values, 1, 2);
 56+  var v = TypeCaster.firstValueAsNumber(values[0]);
 57+  var places = values.length === 2 ? TypeCaster.firstValueAsNumber(values[1]) : 2;
 58+  var sign = (v > 0) ? 1 : -1;
 59+  return sign * (Math.floor(Math.abs(v) * Math.pow(10, places))) / Math.pow(10, places);
 60+};
 61+
 62+
 63+
 64 /**
 65  * Returns the number of ways to choose some number of objects from a pool of a given size of objects.
 66  * @param values[0] n - The size of the pool of objects to choose from.
 67diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
 68index 92bde34..be342ec 100644
 69--- a/src/RawFormulas/Utils.ts
 70+++ b/src/RawFormulas/Utils.ts
 71@@ -100,13 +100,13 @@ class TypeCaster {
 72         return 0;
 73       }
 74       if (value.indexOf(".") > -1) {
 75-        var fl = parseFloat(value);
 76+        var fl = parseFloat(value.replace("$", ""));
 77         if (isNaN(fl)) {
 78           throw new CellError(ERRORS.VALUE_ERROR, "Function ____ expects number values, but is text and cannot be coerced to a number.");
 79         }
 80         return fl;
 81       }
 82-      var fl = parseInt(value);
 83+      var fl = parseInt(value.replace("$", ""));
 84       if (isNaN(fl)) {
 85         throw new CellError(ERRORS.VALUE_ERROR, "Function ____ expects number values, but is text and cannot be coerced to a number.");
 86       }
 87diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
 88index 8eab87a..d71dc7c 100644
 89--- a/tests/FormulasTest.ts
 90+++ b/tests/FormulasTest.ts
 91@@ -920,7 +920,27 @@ catchAndAssertEquals(function() {
 92 }, ERRORS.REF_ERROR);
 93 
 94 
 95-assertEquals(DOLLAR(1.2351, 4), "$1.2351");
 96+// Test DOLLAR
 97+assertEquals(DOLLAR(1.2351, 4), 1.2351);
 98+assertEquals(DOLLAR(1.2351, 2), 1.23);
 99+assertEquals(DOLLAR("$3.141592653589793", "2"), 3.14);
100+assertEquals(DOLLAR("-$3.141592653589793", "2"), -3.14);
101+assertEquals(DOLLAR("$-3.141592653589793", "2"), -3.14);
102+assertEquals(DOLLAR(PI(), 1), 3.1);
103+assertEquals(DOLLAR(PI(), 0), 3);
104+assertEquals(DOLLAR(PI(), false), 3);
105+assertEquals(DOLLAR(PI(), -1), 0);
106+assertEquals(DOLLAR(31.41592653589793, -1), 30);
107+assertEquals(DOLLAR([31.41592653589793], [-1]), 30);
108+assertEquals(DOLLAR(31111.41592653589793, -4), 30000);
109+assertEquals(DOLLAR(31111.41592653589793, -2), 31100);
110+catchAndAssertEquals(function() {
111+  DOLLAR();
112+}, ERRORS.NA_ERROR);
113+catchAndAssertEquals(function() {
114+  DOLLAR(3.1, 1, 1);
115+}, ERRORS.NA_ERROR);
116+
117 
118 assertEquals(DOLLARDE(100.1, 32), 100.3125);
119 
120diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
121index 69ea836..df3e23f 100644
122--- a/tests/SheetFormulaTest.ts
123+++ b/tests/SheetFormulaTest.ts
124@@ -209,7 +209,7 @@ testFormula('=DELTA(2, 2)', 1);
125 testFormula('=DEVSQ(1, 2)', 0.5);
126 
127 // Test DOLLAR
128-testFormula('=DOLLAR(1.2351, 4)', "$1.2351");
129+testFormula('=DOLLAR(1.2351, 4)', 1.2351);
130 
131 // Test DOLLARDE
132 testFormula('=DOLLARDE(100.1, 32)', 100.3125);