
prerna.reactor.expression.OpSumIf Maven / Gradle / Ivy
The newest version!
package prerna.reactor.expression;
import java.math.BigDecimal;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import prerna.sablecc2.om.PixelDataType;
import prerna.sablecc2.om.ReactorKeysEnum;
import prerna.sablecc2.om.nounmeta.NounMetadata;
public class OpSumIf extends OpBasic {
private static final Logger LOGGER = LogManager.getLogger(OpSumIf.class.getName());
public OpSumIf() {
this.operation = "SumIf";
this.keysToGet = new String[]{ReactorKeysEnum.VALUES.getKey(), ReactorKeysEnum.CRITERIA.getKey(), ReactorKeysEnum.SUM_RANGE.getKey()};
}
@Override
protected NounMetadata evaluate(Object[] values) {
/*
* The first input is the range of values to be evaluated by the criteria
* The second input is the criteria - this is a number, expression, or string,
* if this is a string, it can also be regex!
* The third input is an optional sum range, if this is empty, it will add the first input
*/
int numInputs = values.length;
Object[] range = (Object[]) values[0];
Object criteriaVal = values[1];
// instead of doing a bunch of null checks later on
// just determine right now what the sum range will be
// just set it to range and if optionalSumRange is there
// change the reference
Object[] sumRange = range;
Object[] optionalSumRange = null;
if(numInputs == 3) {
optionalSumRange = (Object[]) values[2];
if(optionalSumRange != null && optionalSumRange.length > 0) {
sumRange = optionalSumRange;
}
}
BigDecimal sum = BigDecimal.valueOf(0);
// first, lets get the criteria type
PixelDataType criteriaType = this.curRow.getMeta(1);
if(criteriaType == PixelDataType.CONST_STRING) {
LOGGER.debug("Sumif evaluating for string input");
// so this is a string input
// but string can be passed in as ">number"
// so we need to account for this
String criteriaExpression = criteriaVal.toString();
boolean isNumFilter = false;
String filterPrefix = "";
Number filterNum = null;
String[] possibleFilters = new String[]{">",">=","<","<=","!=","<>","=", "=="};
FILTER_TEST : for(int i = 0; i < possibleFilters.length; i++) {
String filterToTest = possibleFilters[i];
if(criteriaExpression.startsWith(filterToTest)) {
// also test that the second portion is a valid number
try {
// make sure the rest of the string is a valid number
filterNum = new BigDecimal(criteriaExpression.substring(filterToTest.length()-1, filterToTest.length()));
filterPrefix = filterToTest;
isNumFilter = true;
break FILTER_TEST ;
} catch(NumberFormatException e) {
// do nothing
}
}
}
if(isNumFilter) {
LOGGER.debug("... but this is actually a number comparison");
// this is the simple case
// just do it where the values match
int arrLength = sumRange.length;
for(int i = 0; i < arrLength; i++) {
Number rangeVal = (Number) range[i];
Number sumVal = (Number) sumRange[i];
sum = sum.add(evalNumericalExpression(rangeVal, filterPrefix, filterNum, sumVal));
}
} else {
// we have an actual string check
if(criteriaExpression.matches(".*(?")) {
if(rangeVal.doubleValue() > filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals(">=")) {
if(rangeVal.doubleValue() >= filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals("<")) {
if(rangeVal.doubleValue() < filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals("<=")) {
if(rangeVal.doubleValue() <= filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals("!=")) {
if(rangeVal.doubleValue() != filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals("<>")) {
if(rangeVal.doubleValue() != filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals("=")) {
if(rangeVal.doubleValue() == filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
} else if(filterPrefix.equals("==")) {
if(rangeVal.doubleValue() == filterNum.doubleValue()) {
ret = BigDecimal.valueOf(sumVal.doubleValue());
} else {
ret = BigDecimal.valueOf(0);
}
}
return ret;
}
@Override
public String getReturnType() {
return "double";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy