package nc.bs.gl.glreport;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;

import nc.bs.logging.Logger;
import nc.itf.fi.iuforeport.ResultVO;
import nc.vo.bd.account.pub.AccountGLVO;
import nc.vo.gl.glreport.publictool.FunctionVO;
import nc.vo.gl.glreportcache.AccountDataCache;
import nc.vo.gl.glreporttools.FormulaSepTool;
import nc.vo.gl.glreporttools.FunctionType;
import nc.vo.gl.glreporttools.GLAccsubjTool;
import nc.vo.gl.glreporttools.GlAssVOTools;
import nc.vo.gl.glreporttools.GroupFunctionTool;
import nc.vo.gl.glreporttools.PrepareParameterForReport;
import nc.vo.glcom.account.Balanorient;
import nc.vo.glcom.ass.AssVO;
import nc.vo.glcom.balance.GLQueryKey;
import nc.vo.glcom.balance.GlBalanceKey;
import nc.vo.glcom.balance.GlBalanceVO;
import nc.vo.glcom.inteltool.CDataSource;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;

@SuppressWarnings({ "unchecked", "rawtypes" })
public class ResultGetter {

	public ResultGetter() {
		super();
		// TODO 自动生成构造函数存根
	}

	/**
	 * 功能:批量处理汇总要执行的数据 作者：王剑 创建时间：(2006-10-18 14:46:32)
	 */
	private static GlBalanceVO[] combineAss(GlBalanceVO[] vos,
			String[] strType, String CurrType) throws Exception {
		/** 先对查询结果辅助项进行处理，格式化成和查询VO一致的辅助项个数 */
		for (int i = 0; i < vos.length; i++) {
			if (strType == null) {
				vos[i].setValue(GlBalanceKey.GLBALANCE_ASSVOS, null);
			} else {
				nc.vo.glcom.ass.AssVO[] formAss = new nc.vo.glcom.ass.AssVO[strType.length];
				for (int j = 0; j < strType.length && strType[j] != null; j++) {
					for (int k = 0; k < vos[i].getAssVos().length; k++) {
						if (vos[i].getAssVos()[k].getPk_Checktype().equals(strType[j])){
							formAss[j] = vos[i].getAssVos()[k];
							continue;
						}
					}
				}
				vos[i].setValue(GlBalanceKey.GLBALANCE_ASSVOS, formAss);
			}
		}
		/** End of here ! */
		if (strType == null)
			return vos;// 没有辅助项，直接返回
		nc.vo.glcom.intelvo.CIntelVO tt = new nc.vo.glcom.intelvo.CIntelVO();

		// 在此不指定分组信息,则不分组合计

		int[] intSortIndex;
		int intSumLimit = 1; // 指定合计的最小列号组合
		if (CurrType != null && CurrType.equals("所有币种")/*-=notranslate=-*/) {
			intSortIndex = new int[] { GlBalanceKey.GLBALANCE_PK_CURRTYPE,
					GlBalanceKey.GLBALANCE_ASSVOS };

		} else {
			intSortIndex = new int[] { GlBalanceKey.GLBALANCE_ASSVOS };
			intSumLimit = 0;
		}
		nc.vo.glcom.inteltool.CGenTool genTool = new nc.vo.glcom.inteltool.CGenTool();

		genTool.setLimitSumGen(intSumLimit);
		genTool.setSortIndex(intSortIndex);
		// genTool.setGenRatio(100);
		genTool.setGetSortTool(new FncSortTool());

		nc.vo.glcom.inteltool.CSumTool sumTool = new nc.vo.glcom.inteltool.CSumTool();

		int sumIndex[] = new int[] { GlBalanceKey.GLBALANCE_CREDITAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITQUANTITY,
				GlBalanceKey.GLBALANCE_DEBITAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITQUANTITY,
				GlBalanceKey.GLBALANCE_LOCALCREDITAMOUNT,
				GlBalanceKey.GLBALANCE_LOCALDEBITAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITGROUPAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITGROUPAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITGLOBALAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITGLOBALAMOUNT};
		// 要进行合计的列
		sumTool.setSumIndex(sumIndex);

		nc.vo.glcom.inteltool.COutputTool outputTool = new nc.vo.glcom.inteltool.COutputTool();
		outputTool.setRequireOutputDetail(false);
		outputTool.setSummaryCol(-1); // 设置备注信息内容及所对应的列

		CDataSource datasource = new CDataSource();

		Vector vecVos = new Vector();

		for (int i = 0; i < vos.length; i++) {
			vos[i].setUserData(null);
			vecVos.addElement(vos[i]);
		}

		datasource.setSumVector(CDataSource.sortVector(vecVos, genTool, false));

		try {
			tt.setSumTool(sumTool);
			tt.setGenTool(genTool);
			tt.setDatasource(datasource);
			tt.setOutputTool(outputTool);
		} catch (Throwable e) {
			Logger.error(e.getMessage(), e);
		}

		Vector recVector = tt.getResultVector();

		GlBalanceVO[] VOs = new GlBalanceVO[recVector.size()];

		recVector.copyInto(VOs);

		return VOs;
	}

	/**
	 * 功能:汇总要执行的数据 作者：王剑 创建时间：(2006-10-18 14:46:32)
	 */
	public static GlBalanceVO[] appendAssInfoBatch(GlBalanceVO[] param,
			nc.vo.glcom.ass.AssVO[] assvos, String CurrType)
			throws java.lang.Exception {
		// 拼接辅助核算信息，由于数据中只包含辅助核算组合ID,因此需要补充具体的辅助核算组合信息
		if (param != null && param.length != 0) {
			nc.ui.glcom.balance.GlAssDeal objTemp = new nc.ui.glcom.balance.GlAssDeal();
			// 从查询VO中取核算类型主键数组
			String[] strType = null;
			Vector v = new Vector();
			if (assvos != null && assvos.length != 0) {
				strType = new String[assvos.length];
				for (int i = 0; i < assvos.length; i++) {
					if (assvos[i].getPk_Checkvalue() == null)
						v.addElement(assvos[i].getPk_Checktype());// 没有输入核算值的
				}

			}
			if (v.size() > 0) {
				strType = new String[v.size()];
				v.copyInto(strType);
			} else// 需要的辅助核算项都已经在定义分录时输入，那么不需要处理
			{

				if (param[0].getPk_currtype() != null)
					return computeSum(param,
							new int[] { GLQueryKey.K_GLQRY_CURRTYPE });
				else
					return computeSum(param, new int[] {});
			}

			objTemp.setMatchingIndex(GlBalanceKey.GLBALANCE_ASSID);
			objTemp.setAppendIndex(GlBalanceKey.GLBALANCE_ASSVOS);

			objTemp.dealWith(param, strType); // 处理加工

			param = combineAssBatch(param, strType, CurrType);

			return param;
		}

		return null;

	}

	// 多主体下多公式批取返回值
	public static ResultVO[] getRstVOsBatchOrgs(String[] funNames,
			String[] funParams, ResultVO[] resultVOs) {
		if (funNames == null || funNames.length == 0)
			return null;

		ResultVO[] multiOryResultVOs = new ResultVO[funNames.length];
		for (int i = 0; i < funNames.length; i++) {
			ResultVO tempRltvo = getRstVOBatchOrgs(funNames[i], funParams[i],
					resultVOs);
			multiOryResultVOs[i] = tempRltvo;
		}

		return multiOryResultVOs;
	}


	// 多主体下多公式批取返回值,未出现的函数返回值为零的记录
	public static ResultVO[] getFullMatchedResults(String[] funNames,
			String[] funParams, ResultVO[] resultVOs) {
		if (funNames == null || funNames.length == 0)
			return null;
		if (resultVOs == null)
			return resultVOs;
		if (resultVOs.length <= funNames.length)
			return resultVOs;
		ResultVO[] matchedResults = new ResultVO[funNames.length];
		for (int i = 0; i < funNames.length; i++) {
			boolean blMatch = false;
			for (int j = 0; j < resultVOs.length; j++) {
				if (funNames[i].equals(resultVOs[j].getFuncName())
						&& funParams[i].equals(resultVOs[j].getParams())) {
					ResultVO tempResultVO = new ResultVO();
					tempResultVO.setFuncName(resultVOs[j].getFuncName());
					tempResultVO.setParams(resultVOs[j].getParams());
					tempResultVO.setValue(resultVOs[j].getValue());
					matchedResults[i] = tempResultVO;
					blMatch = true;
					break;
				}
			}
			// 当公式中有非法公式，或公式里出现其他异常时，处理未进入正常批处理，错误公式返回0
			if (!blMatch) {
				ResultVO tempResultVO1 = new ResultVO();
				tempResultVO1.setFuncName(funNames[i]);
				tempResultVO1.setParams(funParams[i]);
				tempResultVO1.setValue(new Double(0));
				matchedResults[i] = tempResultVO1;
			}
		}

		return matchedResults;
	}

	// 多主体下单公式批取返回值
	public static ResultVO getRstVOBatchOrgs(String funName, String funParam,
			ResultVO[] resultVOs) {
		if (funName == null)
			return null;
		ResultVO multiOryResultVO = new ResultVO();
		multiOryResultVO.setFuncName(funName);
		multiOryResultVO.setParams(funParam);
		if (resultVOs == null || resultVOs.length == 0) {

			multiOryResultVO.setValue(new Double(0));
		} else {
			String[][] tempNamesAndParams = null;
			try {
				tempNamesAndParams = FormulaSepTool.getSepFunctions(funName,
						funParam);
			} catch (Exception e) {
				Logger.error(
						"方法FormulaSepTool.getSepFunction(funName, funParam)出错",
						e);
			}
			if (tempNamesAndParams == null || tempNamesAndParams.length == 0) {
				multiOryResultVO.setValue(new Double(0));
				return multiOryResultVO;
			}
			String[] tempFunNames = new String[tempNamesAndParams.length];
			String[] tempParams = new String[tempNamesAndParams.length];
			for (int i = 0; i < tempNamesAndParams.length; i++) {
				tempFunNames[i] = tempNamesAndParams[i][0];
				tempParams[i] = tempNamesAndParams[i][1];
			}
			Double dbRlt = new Double(0);
			for (int i = 0; i < tempFunNames.length; i++) {
				for (int j = 0; j < resultVOs.length; j++) {
					if (tempFunNames[i].equals(resultVOs[j].getFuncName())
							&& tempParams[i].equals(resultVOs[j].getParams())) {
						dbRlt = dbRlt + (Double) resultVOs[j].getValue();
						break;
					}
				}
			}

			multiOryResultVO.setValue(dbRlt);
		}
		return multiOryResultVO;
	}

	public static ResultVO[] getRstVOs(FunctionVO[] funvos,
			nc.vo.glcom.balance.GlBalanceVO[] retvos, GroupFunctionTool tool) {
		if (funvos == null || funvos.length == 0)

			return null;
		if (retvos == null || retvos.length == 0) {

			Logger.debug("***************************************");
			Logger.debug("查询结果集为空时的处理");
			;
			Logger.debug("***************************************");
			ResultVO[] rstvos = new ResultVO[funvos.length];
			for (int i = 0; i < funvos.length; i++) {

				ResultVO rstvo = new ResultVO();
				rstvo.setFuncName(funvos[i].getName());
				rstvo.setParams(funvos[i].getParams());
				rstvo.setValue(new Double(0));
				rstvos[i] = rstvo;

			}
			return rstvos;
		}

		ResultVO[] rstvos = new ResultVO[funvos.length];

		Logger.debug("***************************************");
		Logger.debug("返回结果的funvos数量为:    " + rstvos.length);
		Logger.debug("***************************************");
		
		
		HashSet<String> pk_checktypes = new HashSet<String>();
		
		AssVO[] tempassvos = null;
		// 得到此分组的辅助核算类型组合
		if (funvos[0].getAssvo() != null && funvos[0].getAssvo().length > 0) {
			for (int i = 0; i < funvos[0].getAssvo().length; i++) {
				pk_checktypes.add(funvos[0].getAssvo()[i].getPk_Checktype());
			}
		}
		
		if (funvos[0].getOnlyTypeAssVOs()!= null && funvos[0].getOnlyTypeAssVOs().length > 0) {
			for (int i = 0; i < funvos[0].getOnlyTypeAssVOs().length; i++) {
				pk_checktypes.add(funvos[0].getOnlyTypeAssVOs()[i].getPk_Checktype());
			}
		}
		
		if(pk_checktypes.size()>0){
			tempassvos = new AssVO[pk_checktypes.size()];
			String[] types = pk_checktypes.toArray(new String[]{});
			for(int i=0;i<pk_checktypes.size();i++){
				AssVO vo = new AssVO();
				vo.setPk_Checktype(types[i]);
				tempassvos[i] = vo; 
			}
		}

		try {
			// 有辅助核算时，根据辅助核算进行分组合计
			if (tempassvos != null && tempassvos.length > 0) {
				retvos = appendAssInfoBatch(retvos, tempassvos, null);
			}

		} catch (Exception e) {
			Logger.error(e.getMessage());
		}

		for (int i = 0; i < funvos.length; i++) {
			try {
				ResultVO rstvo = new ResultVO();
				rstvo.setFuncName(funvos[i].getName());
				rstvo.setParams(funvos[i].getParams());
				
				//zhaoyhk 将辅助值放到hashmap中提高效率
				if(funvos[i].getAssvo() != null){
					AssVO[] assVO = funvos[i].getAssvo();
					for(int n = 0;n < assVO.length;n++){
						if(assVO[n].getPk_Checkvalue() != null && assVO[n].getPk_Checkvalue().length() > 20){
							HashMap<String, String> accmap = new HashMap<String, String>();
							String[] assstr=assVO[n].getPk_Checkvalue().split(",");
							for(String str:assstr){
								accmap.put(str, str);
							}
							assVO[n].setUserData(accmap);
						}
					}
					funvos[i].setAssvo(assVO);
				}
				
				GlBalanceVO[] rtvos = getBalanceVOsByFunvo(funvos[i], retvos,
						tool);
				if (rtvos != null && rtvos.length > 0)
					rstvo.setValue(countResultValue(
							rtvos,
							funvos[i],
							FunctionType.isQuantityFunction(funvos[i].getName()))
							.toDouble());
				else {
					rstvo.setValue(new Double(0));
				}
				rstvos[i] = rstvo;
			} catch (Exception e) {
				Logger.error(e.getMessage(), e);
			}
		}
		return rstvos;

	}


	public static UFDouble countResultValue(GlBalanceVO[] retVO,
			FunctionVO fvo, boolean isQuantityFunction) throws Exception {

		String dir = (String) fvo.getPara().elementAt(
				PrepareParameterForReport.POS_ORIENTATION);
		if (fvo.getPara().elementAt(PrepareParameterForReport.POS_RETCURRTYPE) == null)
			fvo.getPara().setElementAt("本币"/*-=notranslate=-*/,PrepareParameterForReport.POS_RETCURRTYPE);

		// 如果指定了辅助项类型，但是没有指定辅助项的值那么，只取相应方向的值，而反方向值忽略
		retVO = makeOppsiteDisableWhenOnlyType(dir, fvo.isHasOnlyTypeAss(),
				retVO, fvo);

		// 如果是非末级科目余额函数，并且方向是非默认方向。
		String subj = (String) fvo.getPara().elementAt(PrepareParameterForReport.POS_ACCOUNT);
		String thisdate;
		if (FunctionType.isDatePeriodFunction(fvo.getName())) {
			thisdate = ""
					+ new UFDate((String) fvo.getPara().elementAt(
							PrepareParameterForReport.POS_ENDDATE))
							.toStdString();
		} else {
			// 年度
			thisdate = (String) fvo.getPara().elementAt(
					PrepareParameterForReport.POS_VERDATE);
			;
		}
		UFBoolean isEnd = AccountDataCache.getInstance()
				.getAccountGLVOByPK(retVO[0].getPk_accountingbook(),subj, thisdate).getEndflag();
		if (FunctionType.isBalanceFunction(fvo.getName())
				&& !fvo.isHasOnlyTypeAss() && !isEnd.booleanValue()
				&& dir != null && (dir.equals("借")/*-=notranslate=-*/ || dir.equals("贷")/*-=notranslate=-*/))
			return getBalanceNotEnd(fvo, retVO);
		// 这个结果用于余额函数
		// GlBalanceVO usedBYBalanceFunction=getBalance(retVO);
		// 结果求和
		for (int i = 1; i < retVO.length; i++) {
			retVO[0].setCreditamount(retVO[0].getCreditamount().add(
					retVO[i].getCreditamount()));
			retVO[0].setLocalcreditamount(retVO[0].getLocalcreditamount().add(
					retVO[i].getLocalcreditamount()));
			retVO[0].setDebitamount(retVO[0].getDebitamount().add(
					retVO[i].getDebitamount()));
			retVO[0].setLocaldebitamount(retVO[0].getLocaldebitamount().add(
					retVO[i].getLocaldebitamount()));
			retVO[0].setDebitquantity(retVO[0].getDebitquantity().add(
					retVO[i].getDebitquantity())); // 数量
			retVO[0].setCreditquantity(retVO[0].getCreditquantity().add(
					retVO[i].getCreditquantity()));
			retVO[0].setDebitGroupAmount(retVO[0].getDebitGroupAmount().add(
					retVO[i].getDebitGroupAmount()));
			retVO[0].setCreditGroupAmount(retVO[0].getCreditGroupAmount().add(
					retVO[i].getCreditGroupAmount()));
			retVO[0].setDebitGlobalAmount(retVO[0].getDebitGlobalAmount().add(
					retVO[i].getDebitGlobalAmount()));
			retVO[0].setCreditGlobalAmount(retVO[0].getCreditGlobalAmount()
					.add(retVO[i].getCreditGlobalAmount()));
		}
		if (retVO == null || retVO.length == 0)
			return new nc.vo.pub.lang.UFDouble(0);
		// 根据取数函数的方向
		if (fvo.getPara().elementAt(PrepareParameterForReport.POS_ORIENTATION)
				.equals("借")/*-=notranslate=-*/) { // 用户指定借方
			UFDouble ufd = getDataAccordingtoRetCurr(retVO[0], fvo.getPara()
					.elementAt(PrepareParameterForReport.POS_RETCURRTYPE)
					.toString(), "借"/*-=notranslate=-*/, isQuantityFunction);
			if (FunctionType.isBalanceFunction(fvo.getName())) // 是余额函数
				return getBalaceDataAccordingtoRetCurr(retVO[0], fvo.getPara()
						.elementAt(PrepareParameterForReport.POS_RETCURRTYPE)
						.toString(), "借"/*-=notranslate=-*/, isQuantityFunction);
			else
				return ufd;
		} else if (fvo.getPara()
				.elementAt(PrepareParameterForReport.POS_ORIENTATION)
				.equals("贷")/*-=notranslate=-*/) { // 用户指定贷方
			UFDouble ufd = getDataAccordingtoRetCurr(retVO[0], fvo.getPara()
					.elementAt(PrepareParameterForReport.POS_RETCURRTYPE)
					.toString(), "贷"/*-=notranslate=-*/, isQuantityFunction);
			if (FunctionType.isBalanceFunction(fvo.getName())) // 余额函数
				return getBalaceDataAccordingtoRetCurr(retVO[0], fvo.getPara()
						.elementAt(PrepareParameterForReport.POS_RETCURRTYPE)
						.toString(), "贷"/*-=notranslate=-*/, isQuantityFunction);
			else
				return ufd;
		} else // 默认参数方向
				// 如果是发生函数，直接取默认方向的余额
		{
			int orient = getSubjDefaultOrient(
					retVO[0].getPk_accountingbook(),
						fvo.getPara()
							.elementAt(PrepareParameterForReport.POS_ACCOUNT)
							.toString(), thisdate);
			if (orient == Balanorient.DEBIT) {
				return getDataAccordingtoRetCurr(retVO[0], fvo.getPara()
						.elementAt(PrepareParameterForReport.POS_RETCURRTYPE)
						.toString(), "借"/*-=notranslate=-*/, isQuantityFunction);
			} else {
				return getDataAccordingtoRetCurr(retVO[0], fvo.getPara()
						.elementAt(PrepareParameterForReport.POS_RETCURRTYPE)
						.toString(), "贷"/*-=notranslate=-*/, isQuantityFunction);
			}
		}

	}

	private static UFDouble getDataAccordingtoRetCurr(GlBalanceVO vo,
			String Currtype, String Orientation, boolean isQuantityFunction) {
		// ----------------------数量函数--------------------------------------
		if (isQuantityFunction) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getDebitquantity();
			} else {
				return vo.getCreditquantity();
			}
		} // 数量取数函数
			// ------------------------------------------------------------
		if (Currtype.equals("组织本币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getLocaldebitamount();
			} else {
				return vo.getLocalcreditamount();
			}

		} else if (Currtype.equals("原币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getDebitamount();
			} else {
				return vo.getCreditamount();
			}
		} else if (Currtype.equals("集团本币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getDebitGroupAmount();
			} else {
				return vo.getCreditGroupAmount();
			}

		} else if (Currtype.equals("全局本币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getDebitGlobalAmount();
			} else {
				return vo.getCreditGlobalAmount();
			}

		} else {
			Logger.debug("****warning : 指定函数的返回币种不是主币、辅币、原币之一,以主币形式返回");
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getLocaldebitamount();
			} else {
				return vo.getLocalcreditamount();
			}
		}

	}


	public static GlBalanceVO[] getBalanceVOsByFunvo(FunctionVO funvo,
			GlBalanceVO[] retvos, GroupFunctionTool tool) throws Exception {
		if (retvos == null || retvos.length == 0)
			return null;
		if (funvo == null)
			return null;
		GlBalanceVO[] rstBVOs = null;
		Vector v = new Vector();
		String thisdate = "";
		if (FunctionType.isDatePeriodFunction(funvo.getName())) {
			thisdate = (String) funvo.getPara().elementAt(PrepareParameterForReport.POS_ENDDATE);
		} else {
			thisdate = (String) funvo.getPara().elementAt(PrepareParameterForReport.POS_VERDATE);
		}
		if ((funvo.getAssid() == null || funvo.getAssid().length == 0)
				&& (funvo.getAssvo() == null || funvo.getAssvo().length == 0)) {
			boolean blIsAsbjMtch = false;
			for (int i = 0; i < retvos.length; i++) {
				if (GLAccsubjTool.isAccsubjMatchByCode(retvos[i].getAccsubjCode(),
						funvo.getParams().substring(0, funvo.getParams().indexOf(",")), thisdate)) {
					if (!blIsAsbjMtch) {
						blIsAsbjMtch = true;
					}
					v.addElement(retvos[i].clone());
				} else {
					if (blIsAsbjMtch)
						break;

				}
			}
		} else {
			boolean blIsAsbjMtch = false;
			for (int i = 0; i < retvos.length; i++) {
				if (GLAccsubjTool.isAccsubjMatchByCode(retvos[i].getAccsubjCode(),
						funvo.getParams().substring(0, funvo.getParams().indexOf(",")), thisdate)) {
					if (!blIsAsbjMtch) {
						blIsAsbjMtch = true;
					}
					if (GlAssVOTools.isAssVOsSuplyedAssVOs(retvos[i].getAssVos(), funvo.getAssvo())) {
						v.addElement(retvos[i].clone());
					}
				} else {
					if (blIsAsbjMtch) {
						break;
					}
				}
			}
		}
		if (v.size() > 0) {
			rstBVOs = new GlBalanceVO[v.size()];
			v.copyInto(rstBVOs);

		}
		return rstBVOs;
	}


	private static GlBalanceVO[] makeOppsiteDisableWhenOnlyType(String dir,
			boolean isHasOnlyTypeAss, GlBalanceVO[] retVO, FunctionVO fvo) {
		if (!isHasOnlyTypeAss)
			return retVO; // 不存在只指定辅助核算类型的形式，返回
		// 对空值辅助项汇总
		retVO = sumAccordingToAss(retVO, fvo.getOnlyTypeAssVOs(), (String) fvo
				.getPara().elementAt(PrepareParameterForReport.POS_CURRTYPE));
		if (FunctionType.isBalanceFunction(fvo.getName())) {
			if (dir.equals("借")/*-=notranslate=-*/) {
				// 把所有借方<0的行清零;
				for (int i = 0; i < retVO.length; i++) {
					if (retVO[i].getLocaldebitamount().doubleValue() < 0.00) {
						retVO[i].setLocaldebitamount(UFDouble.ZERO_DBL);
						retVO[i].setDebitGroupAmount(UFDouble.ZERO_DBL);
						retVO[i].setDebitGlobalAmount(UFDouble.ZERO_DBL);
						retVO[i].setDebitamount(UFDouble.ZERO_DBL);
						retVO[i].setDebitquantity(UFDouble.ZERO_DBL);
					}
				}
			} else if (dir.equals("贷")/*-=notranslate=-*/) { // 把所有贷方<0的行清零
				for (int i = 0; i < retVO.length; i++) {
					if (retVO[i].getLocalcreditamount().doubleValue() < 0.00) {
						retVO[i].setLocalcreditamount(UFDouble.ZERO_DBL);
						retVO[i].setCreditGroupAmount(UFDouble.ZERO_DBL);
						retVO[i].setCreditGlobalAmount(UFDouble.ZERO_DBL);
						retVO[i].setCreditamount(UFDouble.ZERO_DBL);
						retVO[i].setCreditquantity(UFDouble.ZERO_DBL);
					}
				}
			} else // 默认方向不处理
			{
			}
		}
		return retVO;
	}

	private static GlBalanceVO[] sumAccordingToAss(GlBalanceVO[] vos,
			nc.vo.glcom.ass.AssVO[] assvos, String CurrType) {
		try {

			vos = appendAssInfo(vos, assvos, CurrType);// 按照assvo中核算值为空的辅助项类型分类汇总
			return vos;
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
		}
		return null;
	}

	private static UFDouble getBalanceNotEnd(FunctionVO funvo, GlBalanceVO[] vos) {
		UFDouble retvalue = UFDouble.ZERO_DBL;
		UFDouble retQuantiry = UFDouble.ZERO_DBL;

		UFDouble debit = UFDouble.ZERO_DBL;
		UFDouble credit = UFDouble.ZERO_DBL;

		UFDouble localdebit = UFDouble.ZERO_DBL;
		UFDouble localcredit = UFDouble.ZERO_DBL;

		UFDouble groupdebit = UFDouble.ZERO_DBL;
		UFDouble groupcredit = UFDouble.ZERO_DBL;

		UFDouble globaldebit = UFDouble.ZERO_DBL;
		UFDouble globalcredit = UFDouble.ZERO_DBL;

		UFDouble debitquantity = UFDouble.ZERO_DBL;
		UFDouble creditquantity = UFDouble.ZERO_DBL;

		try {
			//把vos中的下级科目全部替换为上级科目
			String funAcc = funvo.getParams().substring(0, funvo.getParams().indexOf(","));
			if(funAcc.contains("#")){
				funAcc = funAcc.split("#")[0];
			}
			if(funAcc.contains("@")){
				funAcc = funAcc.split("@")[0];
			}
			AccountGLVO accvo = AccountDataCache.getInstance().getAccountGLVOByCode(vos[0].getPk_accountingbook()
														, funAcc
														, funvo.getPara().get(PrepareParameterForReport.POS_VERDATE).toString());
			
			for(GlBalanceVO vo : vos){
				vo.setPk_accasoa(accvo.getPk_accasoa());
			}
			GlBalanceVO[] retVOs = computeSum(vos,new int[] { GLQueryKey.K_GLQRY_ACCOUNT });
			if (retVOs != null && retVOs.length > 0) {
				for (int i = 0; i < retVOs.length; i++) {
					if (retVOs[i].getLocaldebitamount().doubleValue() > 0) {
						debit = debit.add(retVOs[i].getDebitamount());
						localdebit = localdebit.add(retVOs[i].getLocaldebitamount());
						groupdebit = groupdebit.add(retVOs[i].getDebitGroupAmount());
						globaldebit = globaldebit.add(retVOs[i].getDebitGlobalAmount());
						debitquantity = debitquantity.add(retVOs[i].getDebitquantity());
					} else {
						credit = credit.add(retVOs[i].getCreditamount());
						localcredit = localcredit.add(retVOs[i].getLocalcreditamount());
						groupcredit = groupcredit.add(retVOs[i].getCreditGroupAmount());
						globalcredit = globalcredit.add(retVOs[i].getCreditGlobalAmount());
						creditquantity = creditquantity.add(retVOs[i].getCreditquantity());
					}
				}
			}

			String Currtype = (String) funvo.getPara().elementAt(PrepareParameterForReport.POS_RETCURRTYPE);
			String Orientation = (String) funvo.getPara().elementAt(PrepareParameterForReport.POS_ORIENTATION);

			if (Currtype.equals("组织本币")/*-=notranslate=-*/) {
				if (Orientation.equals("借")/*-=notranslate=-*/) {
					retvalue = localdebit;
					retQuantiry=debitquantity;
				} else {
					retvalue = localcredit;
					retQuantiry=creditquantity;
				}

			} else if (Currtype.equals("集团本币")/*-=notranslate=-*/) {
				if (Orientation.equals("借")/*-=notranslate=-*/) {
					retvalue = groupdebit;
					retQuantiry=debitquantity;
				} else {
					retvalue = groupcredit;
					retQuantiry=creditquantity;
				}

			} else if (Currtype.equals("全局本币")/*-=notranslate=-*/) {
				if (Orientation.equals("借")/*-=notranslate=-*/) {
					retvalue = globaldebit;
					retQuantiry=debitquantity;
				} else {
					retvalue = globalcredit;
					retQuantiry=creditquantity;
				}

			}else { //原币
				if (Orientation.equals("借")/*-=notranslate=-*/) {
					retvalue = localdebit;
					retQuantiry=debitquantity;
				} else {
					retvalue = localcredit;
					retQuantiry=creditquantity;
				}

			}

		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
		}
		boolean isQuantityFunction = FunctionType.isQuantityFunction(funvo.getName());// 是否数量取数函数
		if (!isQuantityFunction)
			return retvalue;
		else
			return retQuantiry;
	}

	public static GlBalanceVO[] getBalanceVOsByFunvoGrpSingles(
			FunctionVO funvo, GlBalanceVO[] retvos, GroupFunctionTool tool)
			throws Exception {
		if (retvos == null || retvos.length == 0)
			return null;
		if (funvo == null)
			return null;
		GlBalanceVO[] rstBVOs = null;
		String thisdate = "";
		if (FunctionType.isDatePeriodFunction(funvo.getName())) {
			thisdate = ""
					+ new UFDate((String) funvo.getPara().elementAt(
							PrepareParameterForReport.POS_ENDDATE))
							.toStdString();
		} else {
			// 年度
			thisdate = (String) funvo.getPara().elementAt(
					PrepareParameterForReport.POS_VERDATE);
		}
		Vector v = new Vector();

		boolean blIsMatch = false;
		for (int i = 0; i < retvos.length; i++) {
			if (GLAccsubjTool.isAccsubjMatchByCode(retvos[i].getAccsubjCode(),
					funvo.getParams().substring(0, funvo.getParams().indexOf(",")), thisdate)) {
				if (!blIsMatch) {
					blIsMatch = true;

				}

				v.addElement(retvos[i].clone());
			} else {
				if (blIsMatch) {
					break;
				}
			}

		}

		if (v.size() > 0) {
			rstBVOs = new GlBalanceVO[v.size()];
			v.copyInto(rstBVOs);

		}
		return rstBVOs;
	}

	private static UFDouble getBalaceDataAccordingtoRetCurr(GlBalanceVO vo,
			String Currtype, String Orientation, boolean isQuantityFunction) {
		// ----------------------数量函数--------------------------------------
		if (isQuantityFunction) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				return vo.getDebitquantity();
			} else {
				return vo.getCreditquantity();
			}
		} // 数量取数函数
			// ------------------------------------------------------------
		if (Currtype.equals("组织本币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				if (vo.getLocaldebitamount().doubleValue() > 0)
					return vo.getLocaldebitamount();
				else
					return new UFDouble("0");
			} else {
				if (vo.getLocalcreditamount().doubleValue() > 0)

					return vo.getLocalcreditamount();
				else
					return new UFDouble("0");
			}

		} else if (Currtype.equals("集团本币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				if (vo.getDebitGroupAmount().doubleValue() > 0)
					return vo.getDebitGroupAmount();
				else
					return new UFDouble("0");
			} else {
				if (vo.getCreditGroupAmount().doubleValue() > 0)

					return vo.getCreditGroupAmount();
				else
					return new UFDouble("0");
			}
		} else if (Currtype.equals("全局本币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				if (vo.getDebitGlobalAmount().doubleValue() > 0)
					return vo.getDebitGlobalAmount();
				else
					return new UFDouble("0");
			} else {
				if (vo.getCreditGlobalAmount().doubleValue() > 0)

					return vo.getCreditGlobalAmount();
				else
					return new UFDouble("0");
			}
		} else if (Currtype.equals("原币")/*-=notranslate=-*/) {
			if (Orientation.equals("借")/*-=notranslate=-*/) {

				if (vo.getDebitamount().doubleValue() > 0)
					return vo.getDebitamount();
				else
					return new UFDouble("0");

			} else {
				if (vo.getCreditamount().doubleValue() > 0)
					return vo.getCreditamount();
				else
					return new UFDouble("0");

			}
		} else {
			Logger.debug("****warning : 指定函数的返回币种不是主币、辅币、原币之一,以主币形式返回");
			if (Orientation.equals("借")/*-=notranslate=-*/) {
				if (vo.getLocaldebitamount().doubleValue() > 0)
					return vo.getLocaldebitamount();
				else
					return new UFDouble("0");
			} else {
				if (vo.getLocalcreditamount().doubleValue() > 0)

					return vo.getLocalcreditamount();
				else
					return new UFDouble("0");
			}
		}

	}

	private static int getSubjDefaultOrient(String pk_accountingbok, String pk_subj,
			String stddate) {
		try {
			int orient = AccountDataCache.getInstance()
					.getAccountGLVOByPK(pk_accountingbok,pk_subj, stddate).getBalanorient()
					.intValue();
			return orient;
		} catch (Exception e) {
			Logger.error(e.getMessage(), e);
		}
		return 1;
	}

	public static ResultVO[] getRstVOsGrpSingles(FunctionVO[] funvos,
			nc.vo.glcom.balance.GlBalanceVO[] retvos, GroupFunctionTool tool) {
		if (funvos == null || funvos.length == 0)

			return null;
		if (retvos == null || retvos.length == 0) {
			Logger.debug("***************************************");
			Logger.debug("查询结果集为空时的处理");
			;
			Logger.debug("***************************************");
			ResultVO[] rstvos = new ResultVO[funvos.length];
			for (int i = 0; i < funvos.length; i++) {

				ResultVO rstvo = new ResultVO();
				rstvo.setFuncName(funvos[i].getName());
				rstvo.setParams(funvos[i].getParams());
				rstvo.setValue(new Double(0));
				rstvos[i] = rstvo;

			}
			return rstvos;
		}
		
		HashSet<String> pk_checktypes = new HashSet<String>();
		
		AssVO[] tempassvos = null;
		// 得到此分组的辅助核算类型组合
		if (funvos[0].getAssvo() != null && funvos[0].getAssvo().length > 0) {
			for (int i = 0; i < funvos[0].getAssvo().length; i++) {
				pk_checktypes.add(funvos[0].getAssvo()[i].getPk_Checktype());
			}
		}
		
		if (funvos[0].getOnlyTypeAssVOs()!= null && funvos[0].getOnlyTypeAssVOs().length > 0) {
			for (int i = 0; i < funvos[0].getOnlyTypeAssVOs().length; i++) {
				pk_checktypes.add(funvos[0].getOnlyTypeAssVOs()[i].getPk_Checktype());
			}
		}
		
		if(pk_checktypes.size()>0){
			tempassvos = new AssVO[pk_checktypes.size()];
			String[] types = pk_checktypes.toArray(new String[]{});
			for(int i=0;i<pk_checktypes.size();i++){
				AssVO vo = new AssVO();
				vo.setPk_Checktype(types[i]);
				tempassvos[i] = vo; 
			}
		}

		try {
			// 有辅助核算时，根据辅助核算进行分组合计
			if (tempassvos != null && tempassvos.length > 0) {
				retvos = appendAssInfoBatch(retvos, tempassvos, null);
			}

		} catch (Exception e) {
			Logger.error(e.getMessage());
		}
		ResultVO[] rstvos = new ResultVO[funvos.length];

		Logger.debug("***************************************");
		Logger.debug("定义返回结果的VO数量为:    " + rstvos.length);
		Logger.debug("***************************************");

		for (int i = 0; i < funvos.length; i++) {
			try {
				ResultVO rstvo = new ResultVO();
				rstvo.setFuncName(funvos[i].getName());
				rstvo.setParams(funvos[i].getParams());

				GlBalanceVO[] rtvos = getBalanceVOsByFunvoGrpSingles(funvos[i],
						retvos, tool);
				if (rtvos != null && rtvos.length > 0)
					rstvo.setValue(ResultGetter
							.countResultValue(
									rtvos,
									funvos[i],
									FunctionType.isQuantityFunction(funvos[i]
											.getName())).toDouble());
				else {
					rstvo.setValue(new Double(0));
				}
				rstvos[i] = rstvo;
			} catch (Exception e) {
				Logger.error(e.getMessage(), e);
			}
		}
		return rstvos;

	}

	private static GlBalanceVO[] appendAssInfo(GlBalanceVO[] param,
			nc.vo.glcom.ass.AssVO[] assvos, String CurrType)
			throws java.lang.Exception {
		// 拼接辅助核算信息，由于数据中只包含辅助核算组合ID,因此需要补充具体的辅助核算组合信息
		if (param != null && param.length != 0) {
			nc.ui.glcom.balance.GlAssDeal objTemp = new nc.ui.glcom.balance.GlAssDeal();
			// 从查询VO中取核算类型主键数组
			String[] strType = null;
			Vector v = new Vector();
			if (assvos != null && assvos.length != 0) {
				strType = new String[assvos.length];
				for (int i = 0; i < assvos.length; i++) {
					if (assvos[i].getPk_Checkvalue() == null)
						v.addElement(assvos[i].getPk_Checktype());// 没有输入核算值的
				}
			}
			if (v.size() > 0) {
				strType = new String[v.size()];
				v.copyInto(strType);
			} else// 需要的辅助核算项都已经在定义分录时输入，那么不需要处理
			{

				if (param[0].getPk_currtype() != null)
					return computeSum(param,
							new int[] { GLQueryKey.K_GLQRY_CURRTYPE });
				else
					return computeSum(param, new int[] {});
			}
			
			objTemp.setMatchingIndex(GlBalanceKey.GLBALANCE_ASSID);
			objTemp.setAppendIndex(GlBalanceKey.GLBALANCE_ASSVOS);
			objTemp.dealWith(param, strType); // 处理加工
			
			param = combineAss(param, strType, CurrType);
			return param;
		}

		return null;

	}

	private static GlBalanceVO[] computeSum(GlBalanceVO[] glvos,
			int[] groupFields) throws Exception {
		if (glvos == null)
			return null;
		if (glvos.length <= 1)
			return glvos;

		Vector vecVO = new Vector();
		for (int i = 0; i < glvos.length; i++) {
			glvos[i].setUserData(null);
			vecVO.addElement(glvos[i]);
		}

		nc.vo.glcom.inteltool.CGenTool genTool = new nc.vo.glcom.inteltool.CGenTool();

		genTool.setSortIndex(groupFields);
		genTool.setGenRatio(100);
		genTool.setLimitSumGen((groupFields.length - 1 < 0) ? 0
				: (groupFields.length - 1) * 100);

		nc.vo.glcom.inteltool.COutputTool outputTool = new nc.vo.glcom.inteltool.COutputTool();
		outputTool.setRequireOutputDetail(false);
		outputTool.setGenTool(genTool);

		/** 设置备注信息内容及所对应的列 */
		outputTool.setSimpleSummary(false);

		CDataSource datasource = new CDataSource();
		datasource.setSumVector(CDataSource.sortVector(vecVO, genTool, false));

		nc.vo.glcom.inteltool.CSumTool sumTool = new nc.vo.glcom.inteltool.CSumTool();
		int sumIndex[] = { GlBalanceKey.GLBALANCE_CREDITAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITQUANTITY,
				GlBalanceKey.GLBALANCE_LOCALCREDITAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITQUANTITY,
				GlBalanceKey.GLBALANCE_LOCALDEBITAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITGROUPAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITGROUPAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITGLOBALAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITGLOBALAMOUNT };
		/** 要进行合计的列 */

		sumTool.setSumIndex(sumIndex);

		nc.vo.glcom.intelvo.CIntelVO tt = new nc.vo.glcom.intelvo.CIntelVO();
		try {
			tt.setGenTool(genTool);
			tt.setDatasource(datasource);
			tt.setOutputTool(outputTool);
			tt.setSumTool(sumTool);
			java.util.Vector recVector = tt.getResultVector();
			GlBalanceVO[] vos = new GlBalanceVO[recVector.size()];
			recVector.copyInto(vos);
			for (int i = 0; i < vos.length; i++)
				vos[i].setUserData(null);
			return vos;
		} catch (Throwable e) {
			Logger.error(e.getMessage(), e);
			throw new Exception(e.getMessage());
		}
	}

	private static GlBalanceVO[] combineAssBatch(GlBalanceVO[] vos,
			String[] strType, String CurrType) throws Exception {
		/** 先对查询结果辅助项进行处理，格式化成和查询VO一致的辅助项个数 */
		for (int i = 0; i < vos.length; i++) {
			if (strType == null) {
				vos[i].setValue(GlBalanceKey.GLBALANCE_ASSVOS, null);
			} else {
				nc.vo.glcom.ass.AssVO[] formAss = new nc.vo.glcom.ass.AssVO[strType.length];
				for (int j = 0; j < strType.length && strType[j] != null; j++) {
					for (int k = 0; k < vos[i].getAssVos().length; k++) {
						if (vos[i].getAssVos()[k].getPk_Checktype().equals(
								strType[j]))
							formAss[j] = vos[i].getAssVos()[k];
					}
				}
				vos[i].setValue(GlBalanceKey.GLBALANCE_ASSVOS, formAss);
			}
		}
		/** End of here ! */
		if (strType == null)
			return vos;// 没有辅助项，直接返回
		nc.vo.glcom.intelvo.CIntelVO tt = new nc.vo.glcom.intelvo.CIntelVO();

		// 在此不指定分组信息,则不分组合计

		int[] intSortIndex;
		int intSumLimit = 1; // 指定合计的最小列号组合
		if (CurrType != null && CurrType.equals("所有币种")/*-=notranslate=-*/) {
			intSortIndex = new int[] { GlBalanceKey.GLBALANCE_PK_CURRTYPE,
					GlBalanceKey.GLBALANCE_SUBJCODE,
					GlBalanceKey.GLBALANCE_ASSVOS };
			intSumLimit = 2;
		} else {
			// intSortIndex = new int[] {
			// GlBalanceKey.GLBALANCE_PK_ACCOUNT,GlBalanceKey.GLBALANCE_ASSVOS
			// };
			// intSumLimit = 1;

			intSortIndex = new int[] { GlBalanceKey.GLBALANCE_SUBJCODE,
					GlBalanceKey.GLBALANCE_ASSVOS };
			intSumLimit = 1;
		}
		// intSumLimit = 2;

		nc.vo.glcom.inteltool.CGenTool genTool = new nc.vo.glcom.inteltool.CGenTool();

		genTool.setLimitSumGen(intSumLimit);
		genTool.setSortIndex(intSortIndex);
		// genTool.setGenRatio(100);
		genTool.setGetSortTool(new FncSortTool());

		nc.vo.glcom.inteltool.CSumTool sumTool = new nc.vo.glcom.inteltool.CSumTool();

		int sumIndex[] = new int[] { GlBalanceKey.GLBALANCE_CREDITAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITQUANTITY,
				GlBalanceKey.GLBALANCE_DEBITAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITQUANTITY,
				GlBalanceKey.GLBALANCE_LOCALCREDITAMOUNT,
				GlBalanceKey.GLBALANCE_LOCALDEBITAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITGROUPAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITGROUPAMOUNT,
				GlBalanceKey.GLBALANCE_DEBITGLOBALAMOUNT,
				GlBalanceKey.GLBALANCE_CREDITGLOBALAMOUNT };

		// 要进行合计的列
		sumTool.setSumIndex(sumIndex);

		nc.vo.glcom.inteltool.COutputTool outputTool = new nc.vo.glcom.inteltool.COutputTool();
		outputTool.setRequireOutputDetail(false);
		outputTool.setSummaryCol(-1); // 设置备注信息内容及所对应的列

		CDataSource datasource = new CDataSource();

		Vector vecVos = new Vector();

		for (int i = 0; i < vos.length; i++) {
			vos[i].setUserData(null);
			vecVos.addElement(vos[i]);
		}

		datasource.setSumVector(CDataSource.sortVector(vecVos, genTool, false));

		try {
			tt.setSumTool(sumTool);
			tt.setGenTool(genTool);
			tt.setDatasource(datasource);
			tt.setOutputTool(outputTool);
		} catch (Throwable e) {
			Logger.error(e.getMessage(), e);
		}

		Vector recVector = tt.getResultVector();

		GlBalanceVO[] VOs = new GlBalanceVO[recVector.size()];

		recVector.copyInto(VOs);

		return VOs;
	}
}