Commit 1a0f16d8 authored by neo.wang's avatar neo.wang

Merge branch 'dev_neo3' into 'dev'

Dev neo3

See merge request root/atms!101
parents 79c52a48 4e91d1ae
......@@ -5,8 +5,12 @@ import org.apache.poi.ss.formula.OperationEvaluationContext;
import org.apache.poi.ss.formula.eval.EvaluationException;
import org.apache.poi.ss.formula.eval.ValueEval;
import java.util.ArrayList;
import java.util.List;
import static pwc.taxtech.atms.common.util.FormulaUtil.resolverInteger;
import static pwc.taxtech.atms.common.util.FormulaUtil.resolverString;
import static pwc.taxtech.atms.exception.Exceptions.BAD_BBVO_PARAMS;
@Getter
public class BBParasBo {
......@@ -16,11 +20,33 @@ public class BBParasBo {
private Integer period;
private Integer year;
private String formulaExpression;
private List<PeriodCellDataTemplate> expressionData = new ArrayList<>();
public static class PeriodCellDataTemplate {
Integer period;
Long cellTemplateId;
@Override
public String toString() {
return period + ":" + cellTemplateId;
}
public PeriodCellDataTemplate(Integer period, Long cellTemplateId) {
this.period = period;
this.cellTemplateId = cellTemplateId;
}
}
public void putPeriodCellTempate(Integer period, Long cellTemplateId) {
if (period < 1 || period > 12 || cellTemplateId < 0) throw BAD_BBVO_PARAMS;
expressionData.add(new PeriodCellDataTemplate(period, cellTemplateId));
}
public BBParasBo(ValueEval[] args, OperationEvaluationContext ec) throws EvaluationException {
StringBuilder expression = new StringBuilder("");
begin(expression);
reportCode = resolverString(args, ec, 0);
concatPara(expression, reportCode);
try {
......@@ -48,6 +74,15 @@ public class BBParasBo {
concatPara(expression, rowIndex);
period = args.length >= 4 ? resolverInteger(args, ec, 3) : 0;
year = args.length == 5 ? resolverInteger(args, ec, 4) : 0;
if (args.length >= 4) {
split(expression);
concatPara(expression, period);
}
if (args.length == 5) {
split(expression);
concatPara(expression, year);
}
end(expression);
formulaExpression = expression.toString();
}
......@@ -71,29 +106,31 @@ public class BBParasBo {
return expression.append(para);
}
public String expression(Integer currentPeriod, Integer currentYear) {
StringBuilder builder = new StringBuilder(formulaExpression);
split(builder);
concatPara(builder, currentPeriod);
split(builder);
concatPara(builder, currentYear);
end(builder);
formulaExpression = builder.toString();
return formulaExpression;
}
public void disCount() {
rowIndex--;
columnIndex--;
}
public BBParasBo(BBParasBo otherBo, int period, int curYear) {
this.reportCode = otherBo.reportCode;
this.columnIndex = otherBo.getColumnIndex();
this.rowIndex = otherBo.rowIndex;
this.period = period;
this.year = curYear;
this.formulaExpression=otherBo.formulaExpression;
this.formulaExpression = otherBo.formulaExpression;
}
public String expression() {
return formulaExpression;
}
public String expressionData() {
if (!expressionData.isEmpty()) {
StringBuilder builder = new StringBuilder("PCT(");
for (int i = 0; i < expressionData.size(); i++) {
builder.append(expressionData.get(i).toString());
if (i < expressionData.size() - 1)
builder.append(",");
}
builder.append(")");
return builder.toString();
}
return "";
}
@Override
......@@ -104,7 +141,6 @@ public class BBParasBo {
", rowIndex=" + rowIndex +
", period=" + period +
", year=" + year +
", formulaExpression='" + formulaExpression + '\'' +
'}';
}
}
......@@ -6,4 +6,5 @@ public class Exceptions {
public static final FormulaException BB_CELL_DATA_NULL = new FormulaException("cell data is null");
public static final FormulaException BB_CELL_DATA_EMPTY = new FormulaException("cell data is empty");
public static final FormulaException BB_EMPTY = new FormulaException("db name is empty");
public static final FormulaException BAD_BBVO_PARAMS = new FormulaException("bad params for bb fromular express data");
}
package pwc.taxtech.atms.vat.dao;
import java.util.List;
import java.util.Set;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.session.RowBounds;
import pwc.taxtech.atms.MyVatMapper;
import pwc.taxtech.atms.vat.entity.CellData;
import pwc.taxtech.atms.vat.entity.CellDataExample;
import pwc.taxtech.atms.vat.entity.PCTEntity;
import pwc.taxtech.atms.vat.service.impl.ReportGeneratorImpl;
@Mapper
public interface CellDataMapper extends MyVatMapper {
......@@ -105,4 +110,20 @@ public interface CellDataMapper extends MyVatMapper {
* @mbg.generated
*/
int updateByPrimaryKey(CellData record);
@Select("<script>" +
"SELECT " +
" r.period, c.cell_template_id as cellTemplateId, data " +
"FROM " +
" cell_data c, " +
" report r " +
"WHERE " +
" c.report_id = r.id AND " +
" " +
" <foreach item=\"item\" index=\"index\" collection=\"list\"" +
" open=\"(\" separator=\"OR\" close=\")\">" +
" ( r.period=#{item.period} and c.cell_template_id=#{item.cellTemplateId} )" +
" </foreach>" +
"</script>")
List<PCTEntity> queryByPCTs(@Param("list") Set<PCTEntity> parameter);
}
\ No newline at end of file
package pwc.taxtech.atms.vat.entity;
import java.math.BigDecimal;
public class PCTEntity {
Integer period;
Long cellTemplateId;
BigDecimal data;
public PCTEntity() {
}
public PCTEntity(String pctStr) {
String[] pct = pctStr.split(":");
this.period = Integer.parseInt(pct[0]);
this.cellTemplateId = Long.parseLong(pct[1]);
}
@Override
public int hashCode() {
return (period + "" + cellTemplateId).hashCode();
}
@Override
public boolean equals(Object obj) {
PCTEntity target = (PCTEntity) obj;
return period.intValue() == target.period.intValue()
&& cellTemplateId.longValue() == target.cellTemplateId.longValue();
}
public Integer getPeriod() {
return period;
}
public void setPeriod(Integer period) {
this.period = period;
}
public Long getCellTemplateId() {
return cellTemplateId;
}
public void setCellTemplateId(Long cellTemplateId) {
this.cellTemplateId = cellTemplateId;
}
public BigDecimal getData() {
return data;
}
public void setData(BigDecimal data) {
this.data = data;
}
}
package pwc.taxtech.atms.vat.service.impl;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.formula.functions.FreeRefFunction;
import org.apache.poi.ss.formula.udf.AggregatingUDFFinder;
import org.apache.poi.ss.formula.udf.DefaultUDFFinder;
import org.apache.poi.ss.formula.udf.UDFFinder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import pwc.taxtech.atms.common.POIUtil;
import pwc.taxtech.atms.common.util.SpringContextUtil;
import pwc.taxtech.atms.constant.enums.CellDataSourceType;
......@@ -31,7 +36,15 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
......@@ -263,10 +276,8 @@ public class ReportGeneratorImpl extends VatAbstractService implements ReportGen
//如果有正则匹配就进行更新公式解析
// if (isFind) {
if (!resultFormula.startsWith("BB(")) {//add by neo (bb do not nedd parsed formual)
periodCellTemplateConfig.setParsedFormula(resultFormula);
periodCellTemplateConfigMapper.updateByPrimaryKey(periodCellTemplateConfig);
}
periodCellTemplateConfig.setParsedFormula(resultFormula);
periodCellTemplateConfigMapper.updateByPrimaryKey(periodCellTemplateConfig);
// }
......@@ -470,10 +481,10 @@ public class ReportGeneratorImpl extends VatAbstractService implements ReportGen
* @param workbook 工作簿
*/
private void addFunctionsToWorkbook(Workbook workbook, FormulaContext formulaContext) {
String[] functionNames = {"SGSR", "FSJZ", "ND", "BB", "XXFP", "GZSD", "ProjectContext", "JXFPMX","JXFP"};
String[] functionNames = {"SGSR", "FSJZ", "ND", "BB", "XXFP", "GZSD", "ProjectContext", "JXFPMX", "JXFP"};
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)};
UDFFinder udfs = new DefaultUDFFinder(functionNames, functionImpls);
UDFFinder udfToolpack = new AggregatingUDFFinder(udfs);
workbook.addToolPack(udfToolpack);
......@@ -489,6 +500,7 @@ public class ReportGeneratorImpl extends VatAbstractService implements ReportGen
List<PeriodCellTemplateConfigExtendDto> periodCellTemplateConfigExtendDtos =
periodCellTemplateConfigMapper.getPeriodCellTemplateConfigExtendDtos(templateIDList, period);
fixedPCTParsedFormula(periodCellTemplateConfigExtendDtos);
List<CellCalcInfoDto> cellCalcInfoDtos = new ArrayList<>();
periodCellTemplateConfigExtendDtos.stream().collect(Collectors.groupingBy(a ->
new CellTemplateConfigGroupDto(a.getColumnIndex(), a.getRowIndex()
......@@ -520,6 +532,73 @@ public class ReportGeneratorImpl extends VatAbstractService implements ReportGen
return cellCalcInfoDtos;
}
private void fixedPCTParsedFormula(List<PeriodCellTemplateConfigExtendDto> periodCellTemplateConfigExtendDtos) {
Map<String, List<PCTEntity>> formulaMapToPCT = new HashMap<>();
Map<PeriodCellTemplateConfig, List<String>> configMapToPCTs = new HashMap<>();
Set<PCTEntity> parameter = new HashSet<>();
periodCellTemplateConfigExtendDtos.forEach(p -> {
String formula = p.getFormula();
String parsedFormula = p.getParsedFormula();
if (formula.contains("BB(")) {
logger.debug("period cell template config contains bb formula {}", formula);
if (parsedFormula.contains("PCT(")) {
List<String> parsedPCTs = new ArrayList<>();
byte[] parsedFormulaBytes = parsedFormula.getBytes();
Integer begin = null;
for (int i = 0; i < parsedFormulaBytes.length; i++) {
if (i < parsedFormulaBytes.length - 3 && parsedFormulaBytes[i] == 'P' && parsedFormulaBytes[i + 1] == 'C'
&& parsedFormulaBytes[i + 2] == 'T' && parsedFormulaBytes[i + 3] == '(') {
begin = i;
} else if (parsedFormulaBytes[i] == ')' && begin != null) {
parsedPCTs.add(new String(Arrays.copyOfRange(parsedFormulaBytes, begin, i + 1)));
begin = null;
}
}
if (!parsedPCTs.isEmpty()) {
configMapToPCTs.put(p, parsedPCTs);
}
parsedPCTs.stream().forEach(m -> {
String periodCPT = m.substring(m.indexOf("(") + 1, m.indexOf(")"));
if (periodCPT.contains(",")) {
formulaMapToPCT.put(m, Arrays.asList(periodCPT.split(",")).stream().map(n -> new PCTEntity(n))
.collect(Collectors.toList()));
} else {
formulaMapToPCT.put(m, Lists.newArrayList(new PCTEntity(periodCPT)));
}
parameter.addAll(formulaMapToPCT.get(m));
});
} else {
logger.warn("bb formula parsedformula must contains PCT but not found {}", parsedFormula);
}
}
});
if (!parameter.isEmpty()) {
List<PCTEntity> pctResults = cellDataMapper.queryByPCTs(parameter);
Map<PCTEntity, BigDecimal> pctCache = new HashMap<>();
pctResults.forEach(m -> {
pctCache.put(m, m.getData());
});
configMapToPCTs.forEach((k, v) -> {
v.forEach(pctStr -> {
List<PCTEntity> entities = formulaMapToPCT.get(pctStr);
BigDecimal result = new BigDecimal("0");
for (PCTEntity entity : entities) {
result = result.add(pctCache.get(entity));
}
k.setParsedFormula(k.getParsedFormula().replace(pctStr, result.toString()));
});
});
}
}
private String convertListToString(List<String> list) {
StringBuilder stringBuilder = new StringBuilder();
list.forEach(s -> {
......@@ -533,4 +612,6 @@ public class ReportGeneratorImpl extends VatAbstractService implements ReportGen
}
return stringBuilder.toString();
}
}
......@@ -48,32 +48,32 @@ public class BB extends FunctionBase implements FreeRefFunction {
}
public ValueEval wrapExceptionEval(ValueEval[] args, OperationEvaluationContext ec) throws Exception {
return new NumberEval(bb(new BBParasBo(args, ec), ec).doubleValue());
List<Object> ds = new ArrayList<>();
return new NumberEval(bb(new BBParasBo(args, ec), ec, ds, null).doubleValue());
}
public BigDecimal bb(BBParasBo bo, OperationEvaluationContext ec) throws Exception {
public BigDecimal bb(BBParasBo bo, OperationEvaluationContext ec, List<Object> dataSource, BBParasBo rootBo) throws Exception {
List<Object> ds = new ArrayList<>();
CurrentPeriodBo curPeriod = CurrentPeriodBo.getPeriod(bo.getPeriod().intValue(), formulaContext.getPeriod());
curPeriod.fixedCurYear(getYear(bo.getYear()));
ReportCellDataSourceDto nullCellDto = ReportCellDataSourceDto.nullDataSource(bo, curPeriod);
ds.add(nullCellDto);
dataSource.add(nullCellDto);
BigDecimal cellValue = BigDecimal.ZERO;
CellTemplatePerGroupDto cellTemplateData = agent.getCellTemplateGroupDto(formulaContext.getReportTemplateGroupID(),
formulaContext.getProjectID()).stream().filter(dto -> dto.getRowIndex() == bo.getColumnIndex() - 1
&& dto.getColumnIndex() == bo.getColumnIndex() - 1).findFirst().orElseThrow(() -> {
return Exceptions.BB_CELL_TEMP_NULL;
});
try {
CellTemplatePerGroupDto cellTemplateData = agent.getCellTemplateGroupDto(formulaContext.getReportTemplateGroupID(),
formulaContext.getProjectID()).stream().filter(dto -> dto.getRowIndex() == bo.getColumnIndex() - 1
&& dto.getColumnIndex() == bo.getColumnIndex() - 1).findFirst().orElseThrow(() -> {
return Exceptions.BB_CELL_TEMP_NULL;
});
MyAsserts.assertNotNull(cellTemplateData, Exceptions.BB_CELL_TEMP_NULL);
nullCellDto.fixedWithGroup(cellTemplateData);
// todo: fix datasource name by templateList(neo)
if (curPeriod.getCurPeriod() == -99) {
ds.clear();
dataSource.clear();
BigDecimal returnEval = defaultBigDecimal;
if (formulaContext.getPeriod() <= 1) {
return defaultBigDecimal;
......@@ -81,7 +81,7 @@ public class BB extends FunctionBase implements FreeRefFunction {
for (int p = 1; p < formulaContext.getPeriod(); p++) {
try {
returnEval = returnEval.add(bb(new BBParasBo(bo, p, curPeriod.getCurYear()), ec));
returnEval = returnEval.add(bb(new BBParasBo(bo, p, curPeriod.getCurYear()), ec, dataSource, bo));
} catch (Exception e) {
if (e instanceof FormulaException) {
LOGGER.warn("Formula Exception || {}", e.getMessage());
......@@ -96,10 +96,11 @@ public class BB extends FunctionBase implements FreeRefFunction {
WorkbookEvaluator evaluator = (WorkbookEvaluator) evaluatorField.get(ec);
ValueEval eval = evaluator.evaluate(ec.getWorkbook().getSheet(ec.getWorkbook().getSheetIndex(bo.getReportCode()))
.getCell(bo.getRowIndex() - 1, bo.getColumnIndex() - 1));
bo.putPeriodCellTempate(formulaContext.getPeriod(), Long.parseLong(cellTemplateData.getCellTemplateID()));
return cellValue = new BigDecimal(OperandResolver.coerceValueToDouble(eval));
}
// bo.disCount();
CellData cellData = null;
......@@ -125,8 +126,7 @@ public class BB extends FunctionBase implements FreeRefFunction {
}
nullCellDto = ReportCellDataSourceDto.extractFromGroup(bo, curPeriod, cellData, cellTemplateData);
ds.clear();
ds.add(nullCellDto);
dataSource.add(nullCellDto);
// todo: fix datasource name by templateList(neo)
MyAsserts.assertNotNull(cellData.getData(), Exceptions.BB_CELL_DATA_NULL);
......@@ -135,15 +135,23 @@ public class BB extends FunctionBase implements FreeRefFunction {
cellValue = new BigDecimal(cellData.getData()).setScale(4,
BigDecimal.ROUND_HALF_DOWN);
nullCellDto.setAmount(cellValue);
if (rootBo != null) {
rootBo.putPeriodCellTempate(curPeriod.getCurPeriod(), Long.parseLong(cellTemplateData.getCellTemplateID()));
} else {
bo.putPeriodCellTempate(curPeriod.getCurPeriod(), Long.parseLong(cellTemplateData.getCellTemplateID()));
}
LOGGER.debug("cell static value ");
return cellValue;
} finally {
LOGGER.warn("error for bb cacls for {} and current for {}", bo.toString(), curPeriod.toString());
Long dataSourceID = saveDataSource(ec, ds, FormulaDataSourceDetailType.ReportCellDataSourceDto,
cellValue, formulaContext.getPeriod(),
formulaContext.getReportTemplateGroupID(), bo.getColumnIndex() - 1, bo.getRowIndex() - 1);
saveFormulaBlock(formulaContext.getPeriod(), ec,
bo.expression(curPeriod.getCurPeriod(), curPeriod.getCurYear()), cellValue, dataSourceID);
if (rootBo == null) {
LOGGER.warn("error for bb cacls for {} and current for {}", bo.toString(), curPeriod.toString());
Long dataSourceID = saveDataSource(ec, dataSource, FormulaDataSourceDetailType.ReportCellDataSourceDto,
cellValue, formulaContext.getPeriod(),
formulaContext.getReportTemplateGroupID(), bo.getColumnIndex() - 1, bo.getRowIndex() - 1);
saveFormulaBlock(formulaContext.getPeriod(), ec,
bo.expression(), bo.expressionData(), dataSourceID);
}
}
}
......
......@@ -152,7 +152,7 @@ public class FunctionBase {
}
public void saveFormulaBlock(int period, OperationEvaluationContext ec,
String formulaExpression, BigDecimal val, Long dataSourceID) {
String formulaExpression, BigDecimal val, Long dataSourceID) {
Long cellTemplateID = getCellTemplateID(period, ec);
Date creatime = new Date();
PeriodFormulaBlock periodFormulaBlock = new PeriodFormulaBlock();
......@@ -170,4 +170,23 @@ public class FunctionBase {
SpringContextUtil.periodFormulaBlockMapper.insertSelective(periodFormulaBlock);
}
public void saveFormulaBlock(int period, OperationEvaluationContext ec,
String formulaExpression, String val, Long dataSourceID) {
Long cellTemplateID = getCellTemplateID(period, ec);
Date creatime = new Date();
PeriodFormulaBlock periodFormulaBlock = new PeriodFormulaBlock();
periodFormulaBlock.setId(SpringContextUtil.distributedIDService.nextId());
periodFormulaBlock.setPeriod(period);
periodFormulaBlock.setReportId(0L);
periodFormulaBlock.setCellTemplateId(cellTemplateID);
periodFormulaBlock.setFormulaExpression(formulaExpression);
periodFormulaBlock.setData(val);
periodFormulaBlock.setDataSourceId(dataSourceID);
periodFormulaBlock.setCreateBy("Admin");
periodFormulaBlock.setCreateTime(creatime);
periodFormulaBlock.setUpdateBy("Admin");
periodFormulaBlock.setUpdateTime(creatime);
SpringContextUtil.periodFormulaBlockMapper.insertSelective(periodFormulaBlock);
}
}
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