用友nc65 uap开发-公式开发后如何执行生效

来源:互联网 发布:网络语大仲马什么意思 编辑:程序博客网 时间:2024/05/13 14:30

用友nc65  uap开发-公式开发后如何执行生效

1.应用背景:在上一篇博客已经说了如何配置一个公式:添加一个距起薪日工作日天数到薪资函数面板上。那么配置了这个公式如何生效呢?下面就以距起薪日工作日天数公式在薪资发放时点计算按钮生效计算出对应数据。如图:


在薪资发放项目对职业技术津贴配置距起薪日工作日天数公式

在薪资发放  点计算按钮  根据起薪日计算出本月1号到起薪日的工作日天数。这个时候就需要去根据公式计算了。

2.代码分析:

2.1 在nc.ui.wa.paydata.action.CaculateAction类中的doAction下的doActionForExtend方法如图所示计算:
调用:nc.ui.wa.paydata.model.WadataModelDataManager薪资发放数据管理类

调用: nc.impl.wa.paydata.PaydataServiceImp薪资发放实现类



在这里遍历单个属性开始计算。


具体代码如下:
/** * 计算薪资项目 *    * @author zhangg on 2009-9-28 * @throws DAOException * @throws BusinessException */private void doCaculateSingle(WaClassItemVO itemVO,SuperVO[] superVOs) throws BusinessException {try {getLoginContext().setInitData(itemVO);getLoginContext().getWaLoginVO().setClassItemVOs(this.classItemVOs);if (itemVO == null) {return;}if (isF6TOF9(itemVO)) {return;}// 如果是手工输入, 返回if (itemVO.getIfromflag().equals(FromEnumVO.USER_INPUT.value())) {return;}// 如果是固定值if (itemVO.getIfromflag().equals(FromEnumVO.FIX_VALUE.value())) {updateConstantItem(itemVO);return;}if (itemVO.getVformula() == null) {return;}// 公式和其他数据源if (!itemVO.getIfromflag().equals(FromEnumVO.FORMULA.value())) {execute(itemVO);//对于薪资取社保项目,如果是数值型而且选了取值条件则要判断是否进行清零处理if(itemVO.getIfromflag().equals(FromEnumVO.BM.value()) && itemVO.getIitemtype()==0){String param = itemVO.getVformula().substring(itemVO.getVformula().indexOf("(" )+1, itemVO.getVformula().indexOf(")" ));        String[] params = param.split( ",");        if(params.length==4){       //取值条件没有选择的时候不清零(即为f_f)if(params[3]!=null&&!params[3].equals("f_f")){updateBmItem(itemVO);}        }}//曾龙  对于距起薪日工作日天数重新计算  2017.12.08} else if (itemVO.getVformula() != null&&itemVO.getVformula().contains("salaryPeriodWorkDays")) {IPreTranslate waPreTranslate =new WaPreTranslate();String formua= waPreTranslate.parse(itemVO.getPk_org(), itemVO.getVformula());itemVO.setVformula(formua);List<SqlFragment> fragmentList = FuncParse.parse(formua);if (fragmentList != null && fragmentList.size() > 0) {for (SqlFragment sqlFragment : fragmentList) {for (int i = 0; i < superVOs.length; i++) {this.getLoginContext().setSuperVO(superVOs[i]);execute(itemVO, sqlFragment);}}}}else if (itemVO.getVformula() != null) {IPreTranslate waPreTranslate =new WaPreTranslate();String formua= waPreTranslate.parse(itemVO.getPk_org(), itemVO.getVformula());itemVO.setVformula(formua);List<SqlFragment> fragmentList = FuncParse.parse(formua);if (fragmentList != null && fragmentList.size() > 0) {for (SqlFragment sqlFragment : fragmentList) {execute(itemVO, sqlFragment);}}}} catch (Exception e) {if (e instanceof DAOException) {throw new BusinessException(ResHelper.getString("60130paydata","060130paydata0444")/*@res "薪资项目:"*/ + itemVO.getMultilangName() + ResHelper.getString("60130paydata","060130paydata0445")/*@res "公式设置错误。 请检查。"*/);} else if (e instanceof BusinessException) {throw (BusinessException) e;} else {throw new BusinessException(e);}}}
如上代码所示:针对不同字段属性不同方式计算


nc.impl.wa.paydata.AbstractCaculateService为薪资发放, 合并计税, 薪资补发提供的Abstract类下:

nc.impl.hr.formula.parser.WaFormulaProcessParser下
2.2开始执行公式

这里开始执行我们自己定义的公式后台功能类:
至此:将结果计算出来返回
在这里是将对应的值更新到数据库中,对应如下:nc.impl.wa.paydata.AbstractCaculateService
public String translate2ExecutableSql(WaClassItemVO itemVO, SqlFragment sqlFragment) throws BusinessException {String value = sqlFragment.getValue();value = parse(value);value = FuncParse.addSourceTable2Value(value);String valuebase=value;//guoqt  ORACLE数据库datediff精度if (getBaseDao().getDBType() == DBUtil.ORACLE &&value.startsWith("datediff")) {String param = value.substring(value.indexOf("(" )+1, value.indexOf(")" ));String begin =value.substring(0, value.indexOf("datediff" ));String end =value.substring(value.indexOf(")" )+1, value.length());String[] params = param.split( ",");        String type = params[0].toString().trim().toLowerCase();        //不包含如isnull等公式if((params[1].trim().startsWith("'")||params[1].trim().startsWith("wa_data"))&&(params[2].trim().startsWith("'")||params[2].trim().startsWith("wa_data"))){//计算月份、年份差异时,对 date2 做加1处理,以和业务运算一致  if (type.equals("year")) {  value= "trunc(months_between("+"to_date(" + params[2] + ",'yyyy-mm-dd')+1,to_date(" + params[1] + ",'yyyy-mm-dd')"+")/12)";  } else if (type.equals("month")) {  value= "trunc(months_between("+"to_date(" + params[2]+ ",'yyyy-mm-dd')+1,to_date(" + params[1]+ ",'yyyy-mm-dd')"+"))";  } else if (type.equals("day")) {  value= "(to_date(" + params[2]+ ",'yyyy-mm-dd')-to_date(" + params[1]+ ",'yyyy-mm-dd'))";  } else {  throw new RuntimeException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("1413002_0","01413002-1048")/*@res "时间单位指定错误!"*/ + type);  }  value=begin+value+end;}} //guoqt  DB2数据库datediff精度if (getBaseDao().getDBType() == DBUtil.DB2 &&value.startsWith("datediff")) {String param = value.substring(value.indexOf("(" )+1, value.indexOf(")" ));String begin =value.substring(0, value.indexOf("datediff" ));String end =value.substring(value.indexOf(")" )+1, value.length());        String[] params = param.split( ",");        String type = params[0].toString().trim().toLowerCase();        //不包含如isnull等公式if((params[1].trim().startsWith("'")||params[1].trim().startsWith("wa_data"))&&(params[2].trim().startsWith("'")||params[2].trim().startsWith("wa_data"))){  if (type.equals("year")) {  value= "(year(" + params[2] + ")-year(" + params[1] + "))";  } else if (type.equals("month")) {  value= "((year(" + params[2] + ")-year(" + params[1] + "))*12+month(" + params[2] + ")-month("  + params[1] + "))";  } else if (type.equals("day")) {  value= "(days(" + params[2] + ")-days(" + params[1] + "))";    } else {  throw new RuntimeException(nc.vo.ml.NCLangRes4VoTransl.getNCLangRes().getStrByID("1413002_0","01413002-1048")/*@res "时间单位指定错误!"*/ + type);  }  value=begin+value+end;}} String condition = sqlFragment.getCondition();condition = parse(condition);condition = FuncParse.addSourceTable2Conditon(condition);String where = getCacuRangeWhere();if (condition != null) {condition = WherePartUtil.formatAddtionalWhere(condition);where += condition;}//对于数值型,添加默认值0value = addDefaultVaule(itemVO,value);StringBuilder sbd = new StringBuilder();if ((DataVOUtils.isDigitsAttribute(itemVO.getItemkey())&& (itemVO.getRound_type() == null || itemVO.getRound_type().intValue() == 0))&& itemVO.getVformula().contains("salaryPeriodWorkDays")) {//距起薪日开始日期计算int digits = itemVO.getIflddecimal();sbd.append(" update wa_data set wa_data." + itemVO.getItemkey()+ " = round((" + value + "), " + digits + " ) " + where);sbd.append(" and wa_data.pk_wa_data ='"+this.getLoginContext().getSuperVO().getAttributeValue("pk_wa_data")+"'");} else if (DataVOUtils.isDigitsAttribute(itemVO.getItemkey())&& (itemVO.getRound_type() == null || itemVO.getRound_type().intValue() == 0)) {int digits = itemVO.getIflddecimal();sbd.append(" update wa_data set wa_data." + itemVO.getItemkey()+ " = round((" + value + "), " + digits + " ) " + where);} else {//guoqt  sqlserver数据库dateadd返回格式NCdp205034621if (getBaseDao().getDBType() == DBUtil.SQLSERVER &&value.trim().startsWith("dateadd")) {//YYYY-MM-DDint type=23;value="convert(varchar,(" +value+ ")," +type+")";} //DB2不生效//if (getBaseDao().getDBType() == DBUtil.DB2 &&value.trim().startsWith("dateadd")) {//////YYYY-MM-DD////value="char(" +value+ ",iso)";//} // guoqt解决ORACLE数据环境下,使用dateadd、datediff后转成字符格式不为'yyyy-mm-dd'的问题if (getBaseDao().getDBType() == DBUtil.ORACLE &&value.contains("dateadd")) {////YYYY-MM-DDnew BaseDAO().executeUpdate("alter session set nls_date_format='yyyy-mm-dd'; ");} sbd.append("update wa_data set wa_data." + itemVO.getItemkey()+ " = (" + value + ") " + where);}return sbd.toString();}