Commit 27bea61c authored by neo's avatar neo

[DEV] add psum formual

parent 215cec49
......@@ -20,4 +20,5 @@ public class Exceptions {
public static final ApiException NOT_FOUND_EXCEPTION = new NotFoundException("not found resources");
public static final ApiException REPORT_IN_PROCESS_OR_AGREED_EXCEPTION = new PreconditionFailedException("report in approval or agreed result");
public static final FormulaException PROJECT_NOT_FOUND = new FormulaException("project not found");;
public static final FormulaException PSUM_CELL_TEMP_NULL = new FormulaException("cell template group is null or empty"); ;
}
......@@ -574,7 +574,7 @@ public class ReportGeneratorImpl {
public void addFunctionsAndContext(Workbook workbook, String[] functions, FormulaContext formulaContext) {
FreeRefFunction[] functionImpls = {new SGSR(formulaContext), new FSJZ(formulaContext), new ND(formulaContext),
new BB(formulaContext), new XXFP(formulaContext), new GZSD(formulaContext), new ProjectContext(formulaContext)
, new JXFPMX(formulaContext), new JXFP(formulaContext)};
, new JXFPMX(formulaContext), new JXFP(formulaContext),new PSUM(formulaContext)};
UDFFinder udfs = new DefaultUDFFinder(functions, functionImpls);
UDFFinder udfToolpack = new AggregatingUDFFinder(udfs);
workbook.addToolPack(udfToolpack);
......
package pwc.taxtech.atms.vat.service.impl.report.functions;
import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.*;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pwc.taxtech.atms.common.util.MyAsserts;
import pwc.taxtech.atms.constant.enums.FormulaDataSourceDetailType;
import pwc.taxtech.atms.dpo.CellTemplatePerGroupDto;
import pwc.taxtech.atms.dto.vatdto.ReportCellDataSourceDto;
import pwc.taxtech.atms.exception.Exceptions;
import pwc.taxtech.atms.vat.entity.PeriodDataSource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class PSUM extends FunctionBase implements FreeRefFunction {
private Logger LOGGER = LoggerFactory.getLogger(PSUM.class);
final static ValueEval defaultEval = new StringEval("0");
public PSUM(FormulaContext formulaContext) {
super(formulaContext);
}
@Override
public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
String param = getStringParam(args[0], ec);
String expression = "PSUM(\"" + param + "\")";
List<Object> dataSource = new ArrayList<>();
BigDecimal cellValue = new BigDecimal(0);
try {
List<PCell> pCells;
if (param.contains(":")) {
pCells = getPCellListFromArea(param);
} else if (param.contains(",")) {
pCells = getPCellList(param);
} else {
LOGGER.error("[PSUM] error , psum must contains : or ,");
throw Exceptions.BAD_BBVO_PARAMS;
}
cellValue = evaluatePCells(pCells, ec, this.formulaContext, dataSource);
return new NumberEval(cellValue.doubleValue());
} catch (Exception e) {
e.printStackTrace();
return defaultEval;
} finally {
Long dataSourceId = saveDataSource(ec, dataSource, FormulaDataSourceDetailType.ReportCellDataSourceDto,
cellValue, formulaContext.getPeriod(),
formulaContext.getReportTemplateGroupId(), ec.getColumnIndex() - 1, ec.getRowIndex() - 1,
formulaContext.getProjectId());
saveFormulaBlock(formulaContext.getPeriod(), ec,
expression, cellValue, dataSourceId, formulaContext.getProjectId());
}
}
private BigDecimal evaluatePCells(List<PCell> pCells, OperationEvaluationContext ec, FormulaContext formulaContext, List<Object> dataSource) {
BigDecimal bigDecimal = new BigDecimal(0);
for (PCell pCell : pCells) {
ValueEval eval = ec.getRefEval(pCell.rowIndex, pCell.columnIndex);
List<CellTemplatePerGroupDto> cellTemplateDataList = agent.getCellTemplateGroupDto(formulaContext.getReportTemplateGroupId(),
formulaContext.getProjectId(), ec.getWorkbook().getSheetName(ec.getSheetIndex()), pCell.rowIndex-1,
pCell.columnIndex-1, formulaContext.getPeriod());
MyAsserts.assertNotEmpty(cellTemplateDataList, Exceptions.PSUM_CELL_TEMP_NULL);
CellTemplatePerGroupDto cellTemplateData = cellTemplateDataList.get(0);
List<PeriodDataSource> dss = agent.queryManualDataSource(Long.parseLong(cellTemplateData.getCellTemplateId()),
formulaContext.getProjectId(), formulaContext.getPeriod());
BigDecimal cellValue = new BigDecimal(0);
if (eval instanceof ErrorEval || eval == null || eval instanceof BlankEval) {
LOGGER.warn("[PSUM_Exception] error eval for pcell {} and error code {} and error String {}", pCell.toString(),
((ErrorEval) eval).getErrorCode(), ((ErrorEval) eval).getErrorString());
if (!dss.isEmpty()) cellValue=dss.get(0).getAmount();
} else {
String evalStr = OperandResolver.coerceValueToString(eval);
logger.debug("[PSUM_debug] eval other cell value {}", evalStr);
try {
cellValue = new BigDecimal(evalStr).setScale(4,
BigDecimal.ROUND_HALF_DOWN);
if (!dss.isEmpty())
cellValue = cellValue.add(dss.get(0).getAmount());
} catch (Exception e) {
if (!dss.isEmpty())
cellValue = dss.get(0).getAmount();
else throw e;
}
}
ReportCellDataSourceDto dto = new ReportCellDataSourceDto();
dto.fixedWithGroup(cellTemplateData );
dto.setAmount(cellValue);
dto.setPeriod(formulaContext.getPeriod());
dto.setProjectId(formulaContext.getProjectId());
dto.setReportName(cellTemplateData.getReportCode());
dataSource.add(dto);
bigDecimal=bigDecimal.add(cellValue);
}
return bigDecimal;
}
public static class PCell {
int rowIndex;
int columnIndex;
public PCell(int rowIndex, int columnIndex) {
this.rowIndex = rowIndex;
this.columnIndex = columnIndex;
}
@Override
public String toString() {
return "PCell{" +
"rowIndex=" + rowIndex +
", columnIndex=" + columnIndex +
'}';
}
}
public static PCell getColumnIndex(String columnStr) {
columnStr = columnStr.toUpperCase();
char[] excelCol = columnStr.toCharArray();
int c = 0;
int r = 0;
int splitIndex = 0;
for (int i = columnStr.length() - 1; i >= 0; i--) {
if (excelCol[i] >= 'A' && excelCol[i] <= 'Z') {
c += ((int) Math.pow(26, splitIndex - i - 1) * (excelCol[i] - 64));
} else if (excelCol[i] >= '0' && excelCol[i] <= '9') {
r += ((int) Math.pow(10, excelCol.length - 1 - i) * (excelCol[i] - 48));
splitIndex = i;
} else {
c = -1;
r = -1;
}
}
return new PCell(r, c);
}
public static void main(String[] args) {
List<PCell> result = getPCellListFromArea("A1:C3");
System.out.println(result.size());
}
static List<PCell> getPCellListFromArea(String areaStr) {
String[] area = areaStr.split(":");
List<PCell> pCells = new ArrayList<>();
PCell begin = getColumnIndex(area[0]);
PCell end = getColumnIndex(area[1]);
for (int i = begin.rowIndex; i <= end.rowIndex; i++) {
for (int j = begin.columnIndex; j <= end.columnIndex; j++) {
pCells.add(new PCell(i, j));
}
}
return pCells;
}
static List<PCell> getPCellList(String listStr) {
String[] list = listStr.split(",");
List<PCell> pCells = new ArrayList<>(list.length);
for (String s : list) {
pCells.add(getColumnIndex(s));
}
return pCells;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment