package nc.impl.cmp.report.fundexedetail;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.jasper.tagplugins.jstl.core.Out;
import org.springframework.beans.factory.annotation.Autowired;

import com.ufida.dataset.IContext;

import dm.jdbc.util.StringUtil;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.cmp.utils.UFDoubleUtils;
import nc.impl.pub.util.db.TempTableDAO;
import nc.itf.cmp.report.fundexedetail.IFundExecutionDetail;
import nc.jdbc.framework.processor.BeanListProcessor;
import nc.pub.smart.data.DataSet;
import nc.pub.smart.metadata.Field;
import nc.pub.smart.metadata.MetaData;
import nc.pubitf.cmp.report.fundexedetail.FundExecutionDetailService;
import nc.util.mmf.framework.db.SqlInUtil;
import nc.vo.cmp.log.CmpPubLogVO;
import nc.vo.cmp.report.fundexedetail.FundExecutionDetailVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.query.ConditionVO;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.commons.lang.StringUtils;
/**
 * 
 * @Description: 资金执行明细（分公司）
 * 
 * @author 谢文如 【碧桂园-物业NCC-资金执行明细（分公司）】
 * @date 2021-4-11
 * @version with NCC V2005
 */
@SuppressWarnings("unchecked")
public class FundExecutionDetailImpl implements IFundExecutionDetail {

	
	@Override
	public DataSet queryData(IContext context) throws BusinessException {
		DataSet dataSet = new DataSet();
		try{
			MetaData metaData = FundExecutionDetailService.getMetaData();
			dataSet.setMetaData(metaData);
			ConditionVO[] conditionVOs = (ConditionVO[])context.getAttribute("freereport_querycondition_vos");
			if(conditionVOs==null || conditionVOs.length==0){
				return dataSet;
			}
			
			//所有结果集合 
			List<FundExecutionDetailVO> allVOList = new ArrayList<FundExecutionDetailVO>();
			query(allVOList,context);
			
			/**生成合计行**/
			if(allVOList.size()>0){
				Map<String,FundExecutionDetailVO> totalMap = new HashMap<String,FundExecutionDetailVO>();
				for(FundExecutionDetailVO vo:allVOList){
					//板块、区域、组织、收支项目 名称合计
					//小计规则：股权情况+所属板块+所属区域+公司编码+NCC收支项目+NCC资金计划+NCC现金流量+NC63收支+NC63资金计划+NC63现金流量,2021-07-30合计
					//def41_name，def6_name，def11_name，accnum，inout_ncc_name，fundplan_ncc_name,cashflow_ncc_name，inout_63_name，fundplan_63_name，cashflow_63_name
					String def41_name = vo.getDef41_name();
					String def6_name = vo.getDef6_name();
					String def11_name = vo.getDef11_name();
				//	String accnum = vo.getAccnum();
					String inout_ncc_name = vo.getInout_ncc_name();	
					String cashflow_ncc_name = vo.getCashflow_ncc_name();
					String fundplan_ncc_name = vo.getFundplan_ncc_name();
					String inout_63_name = vo.getInout_63_name();
					String fundplan_63_name = vo.getFundplan_63_name();
					String cashflow_63_name = vo.getCashflow_63_name();
					String org_name = vo.getOrg_name();					
					String pk_org = vo.getPK_ORG();
					String org_code = vo.getOrg_code();
//					String key = def41_name+"@XWR@"+def6_name+"@XWR@"+def11_name+"@XWR@"+accnum+"@XWR@"+org_name+"@XWR@"+inout_ncc_name+"@XWR@"+cashflow_ncc_name+"@XWR@"
//							+inout_63_name+"@XWR@"+fundplan_63_name+"@XWR@"+cashflow_63_name;
					String key = def41_name+"@XWR@"+def6_name+"@XWR@"+def11_name+"@XWR@"+org_name+"@XWR@"+inout_ncc_name+"@XWR@"+cashflow_ncc_name+"@XWR@"
							+inout_63_name+"@XWR@"+fundplan_63_name+"@XWR@"+cashflow_63_name;
					FundExecutionDetailVO totalVO = totalMap.get(key);
					if(totalVO==null){
						totalVO = new FundExecutionDetailVO();
						totalVO.setDef41(def41_name);
						totalVO.setDef6_name(def6_name);
						totalVO.setDef11_name(def11_name);
						totalVO.setInout_ncc_name(inout_ncc_name);
						totalVO.setFundplan_ncc_name(fundplan_ncc_name);
						totalVO.setCashflow_ncc_name(cashflow_ncc_name);
						totalVO.setInout_63_name(inout_63_name);
						totalVO.setFundplan_63_name(fundplan_63_name);
						totalVO.setCashflow_63_name(cashflow_63_name);
						//totalVO.setAccnum(accnum);
						totalVO.setPK_ORG(pk_org);
						totalVO.setOrg_code(vo.getOrg_code());
						totalVO.setOrg_name(org_name+":小计");
						totalVO.setInout_ncc_name(inout_ncc_name);
						totalMap.put(key, totalVO);
					}
					totalVO.setRec_primal(UFDoubleUtils.add(totalVO.getRec_primal(), vo.getRec_primal()));
					totalVO.setPay_primal(UFDoubleUtils.add(totalVO.getPay_primal(), vo.getPay_primal()));
					totalVO.setRec_local(UFDoubleUtils.add(totalVO.getRec_local(), vo.getRec_local()));
					totalVO.setPay_local(UFDoubleUtils.add(totalVO.getPay_local(), vo.getPay_local()));
				}
				Collection<FundExecutionDetailVO> totalVOCollection = totalMap.values();
				List<FundExecutionDetailVO> totalVOList = new ArrayList<FundExecutionDetailVO>(totalVOCollection);
//				//排序
//				Collections.sort(totalVOList, new Comparator<FundExecutionDetailVO>() {
//					@Override
//					public int compare(FundExecutionDetailVO paramT1, FundExecutionDetailVO paramT2) {
//						//板块、区域、组织、单据类型、日期
//						String def6_name1 = paramT1.getSETTLEDATE_NAME();
//						String def6_name2 = paramT2.getSETTLEDATE_NAME();
//						def6_name1 = def6_name1==null?"":def6_name1;
//						def6_name2 = def6_name2==null?"":def6_name2;
//						int diff1 = def6_name1.compareTo(def6_name2);
//						return diff1;
//				}});
				allVOList.addAll(totalVOList);
			}					
			//组装dataset
			Field[] fields = metaData.getFields();
			Object[][] datas = new Object[allVOList.size()][fields.length];
			int i=0;
			for(FundExecutionDetailVO vo:allVOList){
				for (int k = 0; k < fields.length; k++) {
					datas[i][k] = vo.getAttributeValue(fields[k].getFldname());
				}
				i++;
			}
			dataSet.setDatas(datas);
			
		}catch(Throwable e){
			ExceptionUtils.wrappBusinessException(e.getMessage(), e);
		}finally{
			
		}
		return dataSet;
	}
	/**
	 * 
	* @Title: query数据查询方法
	* @Description:
	* @author: 谢文如
	* @date 2021年7月29日 下午3:49:49
	* @param allVOList
	* @param context
	* @throws BusinessException void
	* @version
	 */
	private void query(List<FundExecutionDetailVO> allVOList,IContext context) throws BusinessException{
		//查询条件
		String allWhereSql = getAllWhereSql(context);
		
		BaseDAO dao = new BaseDAO();
		String tmpTableName = "tmp_ncc_view_zjjh";
		//查询临时表
		String queryAllSQL = 
				"select * from (select org.def47," +
				"       org.def41," + 
				"       doc_def41.name def41_name," + 
				"       org.def4," + 
				"       doc_def4.name def4_name," + 
				"       org.def6," + 
				"       doc_def6.name def6_name," + 
				"       org.def11," + 
				"       doc_def11.name def11_name," + 
				"       org.code org_code," + 
				"       org.name org_name," + 
				"       zjjh.PK_ORG," + 
				"       zjjh.BILLNAME," + 
				"       zjjh.PK_ACCOUNT," + 
				"       nvl(bsub.accnum, zjjh.PK_ACCOUNT) accnum," + 
				"       zjjh.BILL_DATE BILL_DATE," + 
				"       zjjh.SETTLEDATE SETTLEDATE," + 
				"       substr(zjjh.BILL_DATE, 0, 10) BILL_DATE_NAME," + 
				"       substr(zjjh.SETTLEDATE, 0, 10) SETTLEDATE_NAME," + 
				"       zjjh.MEMO," + 
				"       zjjh.BILL_NO," + 
				"       zjjh.PK_CUST_SUPPLIER," + 
				"       zjjh.cp_code," + 
				"       zjjh.cp_name," + 
				"       nvl(tb_dfzt.code, zjjh.DFZT_CODE) DFZT_CODE," + 
				"       nvl(tb_dfzt2.name, zjjh.DFZT_NAME) DFZT_NAME," + 
				"       zjjh.PK_DEPT," + 
				"       nvl(dept.code, dept_v.code) dept_code," + 
				"       nvl(dept.name, dept_v.name) dept_name," + 
				"       zjjh.REC_TYPE," + 
				"       doc_rec_type.code rec_type_code," + 
				"       doc_rec_type.name rec_type_name," + 
				"       zjjh.balatype_name," + 
				"       zjjh.CHARGE_TYPE," + 
				"       zjjh.EXPENSE_TYPE," + 
				"       doc_CHARGE_TYPE.code CHARGE_TYPE_code," + 
				"       nvl(doc_CHARGE_TYPE.name, zjjh.CHARGE_TYPE) CHARGE_TYPE_name," + 
				"       doc_EXPENSE_TYPE.code EXPENSE_TYPE_code," + 
				"       doc_EXPENSE_TYPE.name EXPENSE_TYPE_name," + 
				"       zjjh.PK_RECPROJECT_63," + 
				"       inout_63.code inout_63_code," + 
				"       inout_63.name inout_63_name," + 
				"       zjjh.BANKROLL_PROJET_63," + 
				"       fundplan_63.code fundplan_63_code," + 
				"       fundplan_63.name fundplan_63_name," + 
				"       zjjh.CASH_ITEM_63," + 
				"       cashflow_63.code cashflow_63_code," + 
				"       cashflow_63.name cashflow_63_name," + 
				"       zjjh.PK_RECPROJECT," + 
				"       inout_ncc.code inout_ncc_code," + 
				"       inout_ncc.name inout_ncc_name," + 
				"       zjjh.BANKROLL_PROJET," + 
				"       fundplan_ncc.code fundplan_ncc_code," + 
				"       fundplan_ncc.name fundplan_ncc_name," + 
				"       zjjh.CASH_ITEM," + 
				"       cashflow_ncc.code cashflow_ncc_code," + 
				"       cashflow_ncc.name cashflow_ncc_name," + 
				"       zjjh.RECPROJECT_ISOK," + 
				"       zjjh.PLANITEM_ISOK," + 
				"       zjjh.CASH_ITEM_ISOK," + 
				"       zjjh.PK_PROJECT," + 
				"       pr.project_code," + 
				"       pr.project_name," + 
				"       zjjh.REC_PRIMAL," + 
				"       zjjh.PAY_PRIMAL," + 
				"       zjjh.REC_LOCAL," + 
				"       zjjh.PAY_LOCAL," + 
				"       zjjh.PK_CURRTYPE," + 
				"       currtype.code currtype_code," + 
				"       currtype.name currtype_name," + 
				"       to_char(zjjh.LOCAL_RATE) LOCAL_RATE," + 
				"       zjjh.STATE," + 
				"       DECODE(nvl(tb_dfzt.code, zjjh.DFZT_CODE),'~','否','','否','null','否','是') is_df," + //xug 代付情况
				"       doc_def73.code jylbcode," + 	//xug 经营类别
				"       doc_def73.name jylbname" + 	//xug 经营类别
				"  from " + tmpTableName + " zjjh" + 
				" inner join org_orgs org" + 
				"    on zjjh.pk_org = org.pk_org" + 
				"  left join bd_defdoc doc_def73 on doc_def73.pk_defdoc = zjjh.jylb " + //xug add
				"  left join bd_defdoc doc_def41" + 
				"    on doc_def41.pk_defdoc = org.def41" + 
				"  left join bd_defdoc doc_def4" + 
				"    on doc_def4.pk_defdoc = org.def4" + 
				"  left join bd_defdoc doc_def6" + 
				"    on doc_def6.pk_defdoc = org.def6" + 
				"  left join bd_defdoc doc_def11" + 
				"    on doc_def11.pk_defdoc = org.def11" + 
				"  left join bd_bankaccsub bsub" + 
				"    on bsub.pk_bankaccsub = zjjh.PK_ACCOUNT" + 
				"  left join bd_cust_supplier tb_dfzt" + 
				"    on tb_dfzt.pk_cust_sup = zjjh.dfzt_code" + 
				"  left join bd_cust_supplier tb_dfzt2" + 
				"    on tb_dfzt2.pk_cust_sup = zjjh.dfzt_name" + 
				"  left join org_dept dept" + 
				"    on dept.pk_dept = zjjh.PK_DEPT" + 
				"  left join org_dept dept_v" + 
				"    on dept_v.pk_vid = zjjh.PK_DEPT" + 
				"  left join bd_defdoc doc_rec_type" + 
				"    on doc_rec_type.pk_defdoc = zjjh.REC_TYPE" + 
				"  left join bd_defdoc doc_CHARGE_TYPE" + 
				"    on doc_CHARGE_TYPE.pk_defdoc = zjjh.CHARGE_TYPE" + 
				"  left join bd_defdoc doc_EXPENSE_TYPE" + 
				"    on doc_EXPENSE_TYPE.pk_defdoc = zjjh.EXPENSE_TYPE" + 
				"  left join bd_defdoc inout_63" + 
				"    on inout_63.pk_defdoc = zjjh.PK_RECPROJECT_63" + 
				"  left join bd_defdoc fundplan_63" + 
				"    on fundplan_63.pk_defdoc = zjjh.BANKROLL_PROJET_63" + 
				"  left join bd_cashflow cashflow_63" + 
				"    on cashflow_63.pk_cashflow = zjjh.CASH_ITEM_63" + 
				"  left join bd_inoutbusiclass inout_ncc" + 
				"    on inout_ncc.pk_inoutbusiclass = zjjh.PK_RECPROJECT" + 
				"  left join bd_fundplan fundplan_ncc" + 
				"    on fundplan_ncc.pk_fundplan = zjjh.BANKROLL_PROJET" + 
				"  left join bd_cashflow cashflow_ncc" + 
				"    on cashflow_ncc.pk_cashflow = zjjh.CASH_ITEM" + 
				"  left join bd_project pr" + 
				"    on pr.pk_project = zjjh.PK_PROJECT" + 
				"  left join bd_currtype currtype" + 
				"    on currtype.pk_currtype = zjjh.pk_currtype)" + allWhereSql+
				" order by BILLNAME, org_code, BILL_DATE";


		List<FundExecutionDetailVO> voList = 
				(List<FundExecutionDetailVO>)dao.executeQuery(queryAllSQL, new BeanListProcessor(FundExecutionDetailVO.class));

		if(voList != null && voList.size() > 0){
			allVOList.addAll(voList);
		}
	}
    
	
	/**
	 * 
	* @Title: getAllWhereSql 获取查询中间的查询条件，isquery，这个查询条件是用来控制是否从业务数据表中抽取数据到中间表，还是直接从中中间表中查询
	* @Description:
	* @author: 谢文如
	* @date 2021年7月29日 下午3:43:20
	* @param context
	* @return
	* @throws BusinessException String
	* @version
	 */
	private String getAllWhereSql(IContext context) throws BusinessException{
		StringBuffer whereSql = new StringBuffer("");
		List<String> fields = new ArrayList<String>();
		fields.add("pk_org");
		fields.add("isquery");//不是查询参数，用来判断
		ConditionVO[] conditionVOs = (ConditionVO[])context.getAttribute("freereport_querycondition_vos");
		List<ConditionVO> conditionVOList = new ArrayList<ConditionVO>();
		String PkorgWhereSql = null;
		for(ConditionVO conditionVO : conditionVOs) {
			String fieldCode = conditionVO.getFieldCode();
			String value = conditionVO.getValue();
			if(fields.contains(fieldCode.toLowerCase())) {
				if (fieldCode.toLowerCase().equals("pk_org")) {
					//选择组织大于1000处理
					String value2 = value;
					String operaCode = conditionVO.getOperaCode();
					if("in".equalsIgnoreCase(operaCode)) {
						value2 = value.substring(1, value.length()-1).replaceAll("'", "");
					}
					//wby 20211030 选择组织大于1000处理
					String[] values = value2.split(",");
					SqlInUtil sqlInUtil = new SqlInUtil(values);
					String inSql = sqlInUtil.getInSql("tmp_ncc_view_zjjh_org_con");
					PkorgWhereSql= " and pk_org " + inSql;
				}
				continue;
			}
			conditionVOList.add(conditionVO);
		}
		whereSql.append(" where STATE = 'Y' ");
		if (!StringUtil.isEmpty(PkorgWhereSql))
			whereSql.append(PkorgWhereSql);
		
		if(conditionVOList.size()>0) {
			whereSql.append(" and ");
			whereSql.append(conditionVOs[0].getWhereSQL(conditionVOList.toArray(new ConditionVO[0])));
		}
		return whereSql.toString();
	}
	
}
