|
1 | 1 | import {find} from './polyfill.js';
|
2 |
| -import { isEmpty } from './utils.js'; |
| 2 | +import { isEmpty, logWarn } from './utils.js'; |
| 3 | +import { config } from './config.js'; |
3 | 4 |
|
4 | 5 | const _defaultPrecision = 2;
|
5 | 6 | const _lgPriceConfig = {
|
@@ -118,17 +119,35 @@ function getCpmTarget(cpm, bucket, granularityMultiplier) {
|
118 | 119 | const precision = typeof bucket.precision !== 'undefined' ? bucket.precision : _defaultPrecision;
|
119 | 120 | const increment = bucket.increment * granularityMultiplier;
|
120 | 121 | const bucketMin = bucket.min * granularityMultiplier;
|
| 122 | + let roundingFunction = Math.floor; |
| 123 | + let customRoundingFunction = config.getConfig('cpmRoundingFunction'); |
| 124 | + if (typeof customRoundingFunction === 'function') { |
| 125 | + roundingFunction = customRoundingFunction; |
| 126 | + } |
121 | 127 |
|
122 | 128 | // start increments at the bucket min and then add bucket min back to arrive at the correct rounding
|
123 | 129 | // note - we're padding the values to avoid using decimals in the math prior to flooring
|
124 | 130 | // this is done as JS can return values slightly below the expected mark which would skew the price bucket target
|
125 | 131 | // (eg 4.01 / 0.01 = 400.99999999999994)
|
126 | 132 | // min precison should be 2 to move decimal place over.
|
127 | 133 | let pow = Math.pow(10, precision + 2);
|
128 |
| - let cpmToFloor = ((cpm * pow) - (bucketMin * pow)) / (increment * pow); |
129 |
| - let cpmTarget = ((Math.floor(cpmToFloor)) * increment) + bucketMin; |
| 134 | + let cpmToRound = ((cpm * pow) - (bucketMin * pow)) / (increment * pow); |
| 135 | + let cpmTarget; |
| 136 | + let invalidRounding; |
| 137 | + // It is likely that we will be passed {cpmRoundingFunction: roundingFunction()} |
| 138 | + // rather than the expected {cpmRoundingFunction: roundingFunction}. Default back to floor in that case |
| 139 | + try { |
| 140 | + cpmTarget = (roundingFunction(cpmToRound) * increment) + bucketMin; |
| 141 | + } catch (err) { |
| 142 | + invalidRounding = true; |
| 143 | + } |
| 144 | + if (invalidRounding || typeof cpmTarget !== 'number') { |
| 145 | + logWarn('Invalid rounding function passed in config'); |
| 146 | + cpmTarget = (Math.floor(cpmToRound) * increment) + bucketMin; |
| 147 | + } |
130 | 148 | // force to 10 decimal places to deal with imprecise decimal/binary conversions
|
131 | 149 | // (for example 0.1 * 3 = 0.30000000000000004)
|
| 150 | + |
132 | 151 | cpmTarget = Number(cpmTarget.toFixed(10));
|
133 | 152 | return cpmTarget.toFixed(precision);
|
134 | 153 | }
|
|
0 commit comments