package nc.bs.arapws.busireg;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

import nc.bd.accperiod.InvalidAccperiodExcetion;
import nc.bs.arap.util.ArapMaterialUtils;
import nc.bs.arap.util.SqlUtils;
import nc.bs.businessevent.BusinessEvent;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.itf.arap.fieldmap.IBillFieldGet;
import nc.itf.arap.payable.IArapPayableBillQueryService;
import nc.itf.arap.prv.IArapVerifyLogPrivate;
import nc.itf.uap.busibean.SysinitAccessor;
import nc.md.data.access.NCObject;
import nc.md.model.MetaDataException;
import nc.md.persist.framework.MDPersistenceService;
import nc.pubitf.accperiod.AccountCalendar;
import nc.pubitf.arap.termitem.IArapTermItemPubQueryService;
import nc.pubitf.uapbd.ICustomerPubService;
import nc.pubitf.uapbd.ISupplierPubService;
import nc.vo.arap.agiotage.ArapBusiDataVO;
import nc.vo.arap.basebill.BaseBillVO;
import nc.vo.arap.basebill.BaseItemVO;
import nc.vo.arap.global.ArapBillDealVOConsts;
import nc.vo.arap.payable.AggPayableBillVO;
import nc.vo.arap.payable.PayableBillItemVO;
import nc.vo.arap.payable.PayableBillVO;
import nc.vo.arap.pfflow.ArapBillMapVO;
import nc.vo.arap.pfflow.ArapBillMapVOTool;
import nc.vo.arap.sysinit.SysinitConst;
import nc.vo.arap.termitem.TermVO;
import nc.vo.arap.verify.AggverifyVO;
import nc.vo.arap.verify.RBVerify;
import nc.vo.arap.verify.SameMnyVerify;
import nc.vo.arap.verify.UnsameMnyVerify;
import nc.vo.arap.verify.VerifyDetailVO;
import nc.vo.bd.cust.CustomerVO;
import nc.vo.bd.supplier.SupplierVO;
import nc.vo.bgy.ws.log.NCWebserviceLogVO;
import nc.vo.fipub.exception.ExceptionHandler;
import nc.vo.pub.AggregatedValueObject;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.SuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDouble;
import nc.vo.verifynew.pub.DefaultVerifyRuleVO;
import nc.vo.verifynew.pub.VerifyCom;
import nccloud.commons.lang.ArrayUtils;
import nccloud.commons.lang.StringUtils;


/**
* @ClassName: ArapWsBillRegisterForBusiDataBO
* @Description: 物业板块核销类
* @author 郑瑶
* @date 2018-9-19
*
*/
@SuppressWarnings("unchecked")
public class ArapWsBillRegisterForBusiDataBO {

	private BaseDAO baseDAO;
	public BaseDAO getBaseDAO(){
		if(baseDAO == null ){
			baseDAO = new BaseDAO();
		}
		return baseDAO;
	}
	Map<String, ArrayList<AggverifyVO>> aggMap = new HashMap<String, ArrayList<AggverifyVO>>();
	Map<String, List<TermVO>> termVOMap = new HashMap<String, List<TermVO>>();
	String pkorg = "";
	private String pk_user;
	private Integer syscode;
	public Integer getSyscode() {
		return syscode;
	}
	public void setSyscode(Integer syscode) {
		this.syscode = syscode;
	}
	public String getPkorg() {
		return pkorg;
	}
	public void setPkorg(String pkorg) {
		this.pkorg = pkorg;
	}
	public String getPk_user() {
		return pk_user;
	}
	public void setPk_user(String pkUser) {
		pk_user = pkUser;
	}

	/**
	 * 统一调用批量接口
	 *
	 * @param obj
	 * @return
	 */
	protected AggregatedValueObject[] dealUserObj(Object obj) {
		if (obj instanceof BusinessEvent.BusinessUserObj) {
			obj = ((BusinessEvent.BusinessUserObj) obj).getUserObj();
		}
		AggregatedValueObject[] retvos = null;
		if (obj.getClass().isArray()) {
			retvos = (AggregatedValueObject[]) obj;
		} else {
			retvos = new AggregatedValueObject[] { (AggregatedValueObject) obj };
		}
		pk_user = (String) retvos[0].getParentVO().getAttributeValue(ArapBusiDataVO.APPROVER);
		syscode = (Integer) retvos[0].getParentVO().getAttributeValue(ArapBusiDataVO.SYSCODE);
		pkorg = (String) retvos[0].getParentVO().getAttributeValue(ArapBusiDataVO.PK_ORG);
		return retvos;
	}

	/**
	 * 业务单据登账接口
	 */
	public void doAction(AggregatedValueObject[] vos) throws BusinessException {
		doBusiAction(vos);
	}
	/**
	 * 业务单据登账接口
	 */
	public void doAction2(PayableBillVO hvo ,String guid) throws BusinessException {
		doBusiAction2(hvo,guid);
	}
	
	private void doBusiAction2(PayableBillVO hvo ,String guid) throws BusinessException,MetaDataException, DAOException {
		pk_user = (String) hvo.getAttributeValue(ArapBusiDataVO.APPROVER);
		syscode = (Integer) hvo.getAttributeValue(ArapBusiDataVO.SYSCODE);
		pkorg = (String) hvo.getAttributeValue(ArapBusiDataVO.PK_ORG);
		Hashtable<String, DefaultVerifyRuleVO> ruleVOMap = creatVerifyRuleVO();
		VerifyCom com = new VerifyCom();
	
		try {
			VerifyByContractNo2(guid, com, ruleVOMap);
		} catch (Exception e1) {
			throw ExceptionHandler.handleException(e1);
		}
	
	}
	
	private void doBusiAction(AggregatedValueObject[] vos) throws BusinessException,
			MetaDataException, DAOException {

		if (null != vos && vos.length > 0) {
			for (AggregatedValueObject obj : vos) {
				CircularlyAccessibleValueObject parentVO = obj.getParentVO();
				UFBoolean isinit = (UFBoolean) parentVO.getAttributeValue("isinit");
				if (isinit != null && isinit.booleanValue()) {
					return;
				}
			}
			Object[] transform = transform(vos);
			List<ArapBusiDataVO> insertdatas = (List<ArapBusiDataVO>) transform[0];
			List<ArapBusiDataVO> updatedatas = (List<ArapBusiDataVO>) transform[1];
			if (insertdatas != null && insertdatas.size() > 0){
				setAreaPKForBusiData(insertdatas);// 地区PK赋值
			}

			doInsertRegister(insertdatas);
			if (updatedatas != null && updatedatas.size() > 0){
				setAreaPKForBusiData(updatedatas);					// 地区PK赋值
			}

			doInsertRegister(updatedatas);

			List<ArapBillMapVO> allList = new ArrayList<ArapBillMapVO>();
			Hashtable<String, DefaultVerifyRuleVO> ruleVOMap = creatVerifyRuleVO();
			VerifyCom com = new VerifyCom();

			for (AggregatedValueObject vo : vos) {
				// 单据来源系统
				BaseItemVO[] childrenVO = (BaseItemVO[]) vo.getChildrenVO();
				for (BaseItemVO itemVO : childrenVO) {
                	ArapBillMapVO mapVO = ArapBillMapVOTool.changeVotoBillMapNew((BaseBillVO) vo.getParentVO(), itemVO);
					allList.add(mapVO);
            	}
			}
			try {
				VerifyByContractNo(allList, com, ruleVOMap);
			} catch (Exception e1) {
				throw ExceptionHandler.handleException(e1);
			}
		}
	}

	protected AggregatedValueObject[] dealUserObjForInit(Object obj) {

		AggregatedValueObject[] retvos = null;
		if (obj.getClass().isArray()) {
			retvos = (AggregatedValueObject[]) obj;
		} else {
			retvos = new AggregatedValueObject[] { (AggregatedValueObject) obj };
		}
		pk_user = (String) retvos[0].getParentVO().getAttributeValue(ArapBusiDataVO.APPROVER);
		syscode = (Integer) retvos[0].getParentVO().getAttributeValue(ArapBusiDataVO.SYSCODE);
		pkorg = (String) retvos[0].getParentVO().getAttributeValue(ArapBusiDataVO.PK_ORG);
		return retvos;
	}

	@SuppressWarnings("unused")
	private void VerifyByContractNo(AggregatedValueObject[] vos, VerifyCom com, Hashtable<String, DefaultVerifyRuleVO> ruleVOMap) throws BusinessException {

		List<ArapBusiDataVO> dataList = new ArrayList<ArapBusiDataVO>();
		List<ArapBusiDataVO> jfdataList = new ArrayList<ArapBusiDataVO>();
		List<ArapBusiDataVO> dfdataList = new ArrayList<ArapBusiDataVO>();
		ArrayList<AggverifyVO> aggVOList = new ArrayList<AggverifyVO>();
		for (AggregatedValueObject aggvo : vos) {
			BaseItemVO[] childrenVO = (BaseItemVO[]) aggvo.getChildrenVO();
			// 流程中包含 销售合同或者采购合同，才需要核销
			for (BaseItemVO childvo : childrenVO) {
				aggMap.clear();
				String pk_item = childvo.getPrimaryKey();
				Object contractno = childvo.getAttributeValue(IBillFieldGet.CONTRACTNO);
				String currtype = (String) childvo.getAttributeValue(IBillFieldGet.PK_CURRTYPE);
				String pk_billtype = (String) childvo.getAttributeValue(IBillFieldGet.PK_BILLTYPE);
				String pk_org = (String) childvo.getAttributeValue(IBillFieldGet.PK_ORG);
				// 合同号为null 继续
				if (contractno == null) {
					continue;
				}

				// 查询要核销的数据
				String qrySql = " pk_item ='" + pk_item + "' or (pk_org ='" + pk_org + "'" + " and pausetransact ='N' " + " and pk_currtype ='" + currtype + "'" + "and pk_billtype !='" + pk_billtype + "' and contractno ='" + contractno
						+ "' and pk_item <> '" + pk_item + "' and money_bal<> 0)";
				NCObject[] ncObjects = MDPersistenceService.lookupPersistenceQueryService().queryBillOfNCObjectByCond(ArapBusiDataVO.class, qrySql, false);
				if (!ArrayUtils.isEmpty(ncObjects)) {
					for (NCObject obj : ncObjects) {
						ArapBusiDataVO dataVO = (ArapBusiDataVO) obj.getContainmentObject();
						dataList.add(dataVO);
					}
					// 借贷方分组
					for (ArapBusiDataVO datavo : dataList) {
						if (datavo.getPk_billtype().equals(IBillFieldGet.F2) && ArapBillDealVOConsts.BILLTYPE_30.equals(datavo.getTop_billtype())) {
							datavo.setAttributeValue(ArapBusiDataVO.SETT_MONEY, datavo.getMoney_bal().sub(datavo.getOccupationmny()));
						} else {
							datavo.setAttributeValue(ArapBusiDataVO.SETT_MONEY, datavo.getOccupationmny());
						}
						if (datavo.getDirection().intValue() == 1) {
							jfdataList.add(datavo);
						} else {
							dfdataList.add(datavo);
						}
					}
					Map<String, ArrayList<AggverifyVO>> aggMap = onVerify(com, ruleVOMap, jfdataList.toArray(new ArapBusiDataVO[0]), dfdataList.toArray(new ArapBusiDataVO[0]));
					// 核销结果保存
					aggVOList = getAggVerifyVO(aggMap);
					if (aggVOList != null && aggVOList.size() > 0) {
						NCLocator.getInstance().lookup(IArapVerifyLogPrivate.class).save(aggVOList, ruleVOMap, com);
					}
				}
			}
		}
	}
	
	private void VerifyByContractNo2(String guid, VerifyCom com, Hashtable<String, DefaultVerifyRuleVO> ruleVOMap) throws BusinessException {
		com.setReserveFlag(VerifyDetailVO.reserve_ht);

		Map<String, String> busiDataTsMap = new HashMap<String, String>();
		List<ArapBusiDataVO> dataList = new ArrayList<ArapBusiDataVO>();
		List<ArapBusiDataVO> jfdataList = new ArrayList<ArapBusiDataVO>();
		List<ArapBusiDataVO> dfdataList = new ArrayList<ArapBusiDataVO>();
		aggMap.clear();
		// 追加扣款应付单和SSC成本应付单的核销-1380工程款融资转付现
		String qrySql = " (money_bal <> 0 and pk_item in (select b.pk_payableitem from ap_payableitem b left join ap_payablebill a on a.pk_payablebill = b.pk_payablebill where (a.def71 = '"+guid+"' or a.def1 = '"+guid+"') and a.pk_tradetype = 'F1-Cxx-W01' and a.billstatus = 1 and nvl(a.dr,0) = 0 and nvl(b.dr,0) = 0)) ";
		for(DefaultVerifyRuleVO rule:ruleVOMap.values()){
			rule.setM_creditObjKeys(new String[]{ArapBusiDataVO.DEF11});
			rule.setM_debtObjKeys(new String[]{ArapBusiDataVO.DEF11});
		}
		
		NCObject[] ncObjects = MDPersistenceService.lookupPersistenceQueryService().queryBillOfNCObjectByCond(ArapBusiDataVO.class, qrySql, false);
		if (!ArrayUtils.isEmpty(ncObjects)) {
			for (NCObject obj : ncObjects) {
				ArapBusiDataVO dataVO = (ArapBusiDataVO) obj.getContainmentObject();
				dataList.add(dataVO);
				// 比较ts 使用
				busiDataTsMap.put(dataVO.getPk_busidata(), dataVO.getTs().toString());
				com.setBusiDataTsMap(busiDataTsMap);
			}
			// 借贷方分组
			for (ArapBusiDataVO datavo : dataList) {
				datavo.setAttributeValue(ArapBusiDataVO.SETT_MONEY, datavo.getOccupationmny());
				
				if(datavo.getCustomer()!=null && datavo.getSupplier()==null){
					datavo.setSupplier(datavo.getCustomer());
				}
				datavo.setDef11(guid);
				jfdataList.add(datavo);
			}
			Map<String, ArrayList<AggverifyVO>> aggMap = onVerify(com, ruleVOMap, jfdataList.toArray(new ArapBusiDataVO[0]), dfdataList.toArray(new ArapBusiDataVO[0]));
			ArrayList<AggverifyVO> aggVOList = getAggVerifyVO(aggMap);
			// 核销结果保存
			if (aggVOList != null && aggVOList.size() > 0) {
				NCLocator.getInstance().lookup(IArapVerifyLogPrivate.class).save(aggVOList, ruleVOMap, com);
			}
		}
	
	}

	private void VerifyByContractNo(List<ArapBillMapVO> MapVOList, VerifyCom com, Hashtable<String, DefaultVerifyRuleVO> ruleVOMap) throws BusinessException {
		com.setReserveFlag(VerifyDetailVO.reserve_ht);
		for(DefaultVerifyRuleVO rule:ruleVOMap.values()){
			rule.setM_creditObjKeys(new String[]{ArapBusiDataVO.SUPPLIER});
			rule.setM_debtObjKeys(new String[]{ArapBusiDataVO.SUPPLIER});
		}
		for (ArapBillMapVO vo : MapVOList) {
			Map<String, String> busiDataTsMap = new HashMap<String, String>();
			List<ArapBusiDataVO> dataList = new ArrayList<ArapBusiDataVO>();
			List<ArapBusiDataVO> jfdataList = new ArrayList<ArapBusiDataVO>();
			List<ArapBusiDataVO> dfdataList = new ArrayList<ArapBusiDataVO>();
			aggMap.clear();
			String currtype = vo.getPk_currtype();
			String pk_item = vo.getT_itemid(); 
			String contractno = vo.getContractno();
			String pk_org = vo.getPk_org();
			if (contractno == null) {
				continue;
			}
			if("F3".equals(vo.getT_billtype())){
				//付款单不做核销，紧急付款单另外开辟一个维度做处理
				continue;
			}
			String billType ="";
			if(IBillFieldGet.F0.equals(vo.getT_billtype())){
				billType = "('"+IBillFieldGet.F2+"','"+IBillFieldGet.F1+"','"+IBillFieldGet.F0+"')";
			}else if(IBillFieldGet.F1.equals(vo.getT_billtype())){
				//应付单与付款单不做核销
//				billType = "('"+IBillFieldGet.F3+"','"+IBillFieldGet.F1+"','"+IBillFieldGet.F0+"')";
				billType = "('"+IBillFieldGet.F1+"','"+IBillFieldGet.F0+"')";
			}else if(IBillFieldGet.F2.equals(vo.getT_billtype())){
				billType = "('"+IBillFieldGet.F0+"')";
			} 
			//追加扣款应付单和SSC成本应付单的核销-1380工程款融资转付现
			String qrySql = " (money_bal <> 0 and pk_item ='" + pk_item + "') or (pk_org ='" + pk_org + "'" + " and pausetransact ='N' " + " and pk_currtype ='" + currtype + "'" 
			+ "and pk_billtype in " + billType + " and contractno ='"
					+ contractno + "' and pk_item <> '" + pk_item + "' and money_bal<> 0)";
			 String pkInStr = "";
			 AggPayableBillVO[] aggPayableBillVOS = null;
			if(StringUtils.isNotEmpty(vo.getDef88())){
				String pkitemSql =	new StringBuilder("def1 = '")
				.append(vo.getDef88())
				.append("'   and nvl(dr, 0) = 0").toString();
				 aggPayableBillVOS = NCLocator.getInstance().lookup(IArapPayableBillQueryService.class).queryVOsByWhere(pkitemSql);//获取原有应付单VO
				if(ArrayUtils.isNotEmpty(aggPayableBillVOS)){
					AggPayableBillVO aggVO =  aggPayableBillVOS[0];
					StringBuilder inSql = new StringBuilder();
					inSql.append("  ( ");
					for(PayableBillItemVO itemVO : aggVO.getBodyVOs()){
						 inSql.append(" '");
					     inSql.append(itemVO.getPk_payableitem());
					     inSql.append("'  , ");
					}
					
					pkInStr = inSql.substring(0, inSql.length() - 3)  + " ) ";
				     qrySql =  new StringBuilder("(money_bal <> 0 and pk_item = '"+pk_item+"')")
				     .append("   or ( pk_item in ").append(pkInStr).append("and money_bal <> 0)").toString();//把原有查收付协议VO的sql条件改变，改为查原有的应付单的子表
				}
				for(DefaultVerifyRuleVO rule:ruleVOMap.values()){
					rule.setM_creditObjKeys(new String[]{ArapBusiDataVO.DEF11});
					rule.setM_debtObjKeys(new String[]{ArapBusiDataVO.DEF11});
				}

			}
			NCObject[] ncObjects = MDPersistenceService.lookupPersistenceQueryService().queryBillOfNCObjectByCond(ArapBusiDataVO.class, qrySql, false);
			if (!ArrayUtils.isEmpty(ncObjects)) {
				for (NCObject obj : ncObjects) {
					ArapBusiDataVO dataVO = (ArapBusiDataVO) obj.getContainmentObject();
					dataList.add(dataVO);
					// 比较ts 使用
					busiDataTsMap.put(dataVO.getPk_busidata(), dataVO.getTs().toString());
					com.setBusiDataTsMap(busiDataTsMap);
				}
				// 借贷方分组
				for (ArapBusiDataVO datavo : dataList) {
					datavo.setAttributeValue(ArapBusiDataVO.SETT_MONEY, datavo.getOccupationmny());
					
					if(datavo.getCustomer()!=null && datavo.getSupplier()==null){
						datavo.setSupplier(datavo.getCustomer());
					}
					
					if (datavo.getDirection().intValue() == 1) {
						jfdataList.add(datavo);
					} else {
						dfdataList.add(datavo);
						datavo.setDef11(datavo.getDef1());
						if(pk_item.equals(datavo.getPk_item()) && StringUtils.isNotEmpty(vo.getDef88())){
							datavo.setDef11(vo.getDef88());
						}
					}
				}
				Map<String, ArrayList<AggverifyVO>> aggMap = onVerify(com, ruleVOMap, jfdataList.toArray(new ArapBusiDataVO[0]), dfdataList.toArray(new ArapBusiDataVO[0]));
				ArrayList<AggverifyVO> aggVOList = getAggVerifyVO(aggMap);
				// 核销结果保存
				if (aggVOList != null && aggVOList.size() > 0) {
					NCLocator.getInstance().lookup(IArapVerifyLogPrivate.class).save(aggVOList, ruleVOMap, com);
				//update by zhengyao3@郑瑶 增加def92字段，保存原有应付单关联发票金额，后面付款申请拉单要使用 2018年8月7日22:23:08 end
				//add by zhengyao3@郑瑶 追加扣款应付单和SSC成本应付单的核销-1380工程款融资转付现 2018年7月16日14:50:39 end
			}
			}
		}

	}

	protected Object[] transform(AggregatedValueObject[] vos) throws BusinessException {
		List<SuperVO> insertvos = new ArrayList<SuperVO>();
		List<SuperVO> updatevos = new ArrayList<SuperVO>();
		List<String> delvos = new ArrayList<String>();
		List<String> billPKList = new ArrayList<String>();

		Object[] ret = new Object[] { insertvos, updatevos, delvos };
		// 根据单据主键查询协议表
		for (AggregatedValueObject aggvo : vos) {
			billPKList.add(aggvo.getParentVO().getPrimaryKey());
		}
		TermVO[] termVOs = NCLocator.getInstance().lookup(IArapTermItemPubQueryService.class).queryTermVOByBillParentPK(billPKList.toArray(new String[0]));
		termVOMap = getTermVOByItemPK(termVOs);
		for (AggregatedValueObject vo : vos) {
			SuperVO[] items = (SuperVO[]) vo.getChildrenVO();
			for (SuperVO item : items) {
				switch (item.getStatus()) {
				case VOStatus.NEW:
					List<ArapBusiDataVO> transform = transform(item, (SuperVO) vo.getParentVO());
					insertvos.addAll(transform);
					break;
				case VOStatus.DELETED:
					delvos.add(item.getPrimaryKey());
				default:
					List<ArapBusiDataVO> busidataList = transform(item, (SuperVO) vo.getParentVO());
					updatevos.addAll(busidataList);
					break;
				}
			}
		}

		ArapMaterialUtils.translateMaterial2NonVersion(insertvos.toArray(new ArapBusiDataVO[] {}), ArapBusiDataVO.MATERIAL, IBillFieldGet.MATERIAL_V);
		ArapMaterialUtils.translateMaterial2NonVersion(updatevos.toArray(new ArapBusiDataVO[] {}), ArapBusiDataVO.MATERIAL, IBillFieldGet.MATERIAL_V);

		return ret;
	}

	private Map<String, List<TermVO>> getTermVOByItemPK(TermVO[] termVOs) {
		Map<String, List<TermVO>> termMap = new HashMap<String, List<TermVO>>();
		for (TermVO vo : termVOs) {
			if (termMap.containsKey(vo.getPk_item())) {
				termMap.get(vo.getPk_item()).add(vo);
			} else {
				List<TermVO> temp = new ArrayList<TermVO>();
				temp.add(vo);
				termMap.put(vo.getPk_item(), temp);
			}
		}
		return termMap;
	}
	//设置审批时，表头不会同步到表体的字段，按照表体来取值
	static String[] itemKeys ={IBillFieldGet.CUSTOMER,IBillFieldGet.SUPPLIER,IBillFieldGet.PK_DEPTID,IBillFieldGet.PK_DEPTID_V
		                        ,IBillFieldGet.PK_PSNDOC}; 
	protected List<ArapBusiDataVO> transform(SuperVO item, SuperVO head) throws BusinessException {
		ArapBusiDataVO retvo = new ArapBusiDataVO();
		String[] attrs = retvo.getAttributeNames();
		for (String attr : attrs) {
			Object attributeValue = item.getAttributeValue(attr);
			if (attributeValue == null && !Arrays.asList(itemKeys).contains(attr)) {
				attributeValue = head.getAttributeValue(attr);
			}
			retvo.setAttributeValue(attr, attributeValue);
			// 收支项目
			if (attr.equals(ArapBusiDataVO.PK_COSTSUBJ)) {
				retvo.setAttributeValue(ArapBusiDataVO.PK_COSTSUBJ, item.getAttributeValue(IBillFieldGet.PK_SUBJCODE));
			}
			// 含税单价赋值
			if (attr.equals(ArapBusiDataVO.PRICE)) {
				retvo.setAttributeValue(ArapBusiDataVO.PRICE, item.getAttributeValue(IBillFieldGet.TAXPRICE));
			}
			//利润中心
			if (attr.equals(ArapBusiDataVO.PK_PCORG)) {
				retvo.setAttributeValue(ArapBusiDataVO.PK_PCORG, item.getAttributeValue(IBillFieldGet.PK_PCORG));
			}
			// 金额字段为空赋默认值0
			if (attributeValue == null) {
				if (attr.equals(ArapBusiDataVO.GLOBAL_MONEY_BAL) || attr.equals(ArapBusiDataVO.GROUP_MONEY_BAL) || attr.equals(ArapBusiDataVO.GLOBAL_MONEY_DE) || attr.equals(ArapBusiDataVO.GLOBAL_MONEY_CR)
						|| attr.equals(ArapBusiDataVO.GROUP_MONEY_DE) || attr.equals(ArapBusiDataVO.GROUP_MONEY_CR)) {
					retvo.setAttributeValue(attr, UFDouble.ZERO_DBL);
				}
			}
		}
		retvo.setPk_bill(head.getPrimaryKey());
		retvo.setPk_item(item.getPrimaryKey());
		// 单据表头原币金额
		retvo.setSum_headmoney((UFDouble) head.getAttributeValue(IBillFieldGet.MONEY));
		// 单据表体原币金额
		String billcalss = (String) item.getAttributeValue(IBillFieldGet.BILLCLASS);
		if (billcalss.equals(IBillFieldGet.YS) || (billcalss.equals(IBillFieldGet.FK))) {
			retvo.setSum_itemmoney((UFDouble) item.getAttributeValue(IBillFieldGet.MONEY_DE));
		} else {
			retvo.setSum_itemmoney((UFDouble) item.getAttributeValue(IBillFieldGet.MONEY_CR));
		}
		// 单据状态
		retvo.setBillstatus(Integer.valueOf(1)); // 默认已生效 1，挂起 订单挂起6
		// 表头科目
		retvo.setHeadsubjcode((String) head.getAttributeValue("subjcode"));
		// 业务流程
		retvo.setPk_busitype((String) head.getAttributeValue(ArapBusiDataVO.PK_BUSITYPE));
		retvo.setOperator((String)head.getAttributeValue(IBillFieldGet.BILLMAKER));
		// 利润中心 取表体的
		// retvo.setPk_pcorg((String)head.getAttributeValue(ArapBusiDataVO.PK_PCORG));
		// 单据编号
		retvo.setBillno((String) head.getAttributeValue(ArapBusiDataVO.BILLNO));
		// 暂估标志
		retvo.setEstflag(head.getAttributeValue(ArapBusiDataVO.ESTFLAG) == null ? Integer.valueOf(0) : (Integer) head.getAttributeValue(ArapBusiDataVO.ESTFLAG));
		// 查询收付款协议表数据
		List<ArapBusiDataVO> busiDataList = queryTermVOByBillParentPK(retvo);
		// setAreaPKForBusiData(busiDataList);
		return busiDataList;
	}

	private void setAreaPKForBusiData(List<ArapBusiDataVO> busiDataList) {
		if (busiDataList.get(0).getObjtype().intValue() == 0) {
			String[] custPKS = getCustOrSuppPKS(busiDataList, true);
			try {
				CustomerVO[] customerVOs = NCLocator.getInstance().lookup(ICustomerPubService.class).getCustomerVO(custPKS, new String[] { "pk_areacl", "pk_customer" });
				Map<String, CustomerVO> custMap = new HashMap<String, CustomerVO>();
				if (!ArrayUtils.isEmpty(customerVOs)) {
					{
						for (CustomerVO cust : customerVOs) {
							if (cust != null) {
								custMap.put(cust.getPk_customer(), cust);
							}
						}
					}
				}
				// 客户地区pk 赋值
				for (ArapBusiDataVO data : busiDataList) {
					if (custMap.get(data.getCustomer()) != null) {
						data.setPk_areacl(custMap.get(data.getCustomer()).getPk_areacl());
					}
				}

			} catch (BusinessException e) {
				Logger.error(e.getMessage(), e);
			}
		} else if (busiDataList.get(0).getObjtype().intValue() == 1) {
			String[] suppPKS = getCustOrSuppPKS(busiDataList, false);
			try {
				SupplierVO[] supplierVOs = NCLocator.getInstance().lookup(ISupplierPubService.class).getSupplierVO(suppPKS, new String[] { "pk_areacl", "pk_supplier" });
				Map<String, SupplierVO> suppMap = new HashMap<String, SupplierVO>();
				if (!ArrayUtils.isEmpty(supplierVOs)) {
					for (SupplierVO cust : supplierVOs) {
						if (cust != null) {
							suppMap.put(cust.getPk_supplier(), cust);
						}
					}
				}
				// 供应商地区pk 赋值
				for (ArapBusiDataVO data : busiDataList) {
					if (suppMap.get(data.getSupplier()) != null) {
						data.setPk_areacl(suppMap.get(data.getSupplier()).getPk_areacl());
					}
				}

			} catch (BusinessException e) {
				Logger.error(e.getMessage(), e);
			}
		}
	}

	private String[] getCustOrSuppPKS(List<ArapBusiDataVO> vos, boolean iscust) {
		Set<String> pkS = new HashSet<String>();
		for (ArapBusiDataVO vo : vos) {
			if (iscust) {
				pkS.add(vo.getCustomer());
			} else {
				pkS.add(vo.getSupplier());
			}
		}
		String[] pkArr = pkS.toArray(new String[0]);
		return pkArr;
	}

	private List<ArapBusiDataVO> queryTermVOByBillParentPK(ArapBusiDataVO busidataVO) throws BusinessException {
		// Logger.debug("单据子表pk==" + busidataVO.getPk_item());
		// TermVO[] termVOs =
		// NCLocator.getInstance().lookup(IArapTermItemPubQueryService.class).queryTermVOByBillItemPK(new
		// String[]{busidataVO.getPk_item()});
		// Logger.debug("查询单据收付款协议表数量=" + (ArrayUtils.isEmpty(termVOs) ? 0 : termVOs.length));
		// TermVO[] termVOs = termlist.toArray(new TermVO[0]);
		List<TermVO> termlist = termVOMap.get(busidataVO.getPk_item());
		List<ArapBusiDataVO> busiDataList = new ArrayList<ArapBusiDataVO>();
		if (termlist != null && termlist.size() > 0) {
			for (TermVO termVO : termlist) {
				// 如果协议表有多条记录，则在ArapBusiDataVO与其数量相等
				ArapBusiDataVO copyVO = (ArapBusiDataVO) busidataVO.clone();
				copyVO.setExpiredate(termVO.getExpiredate());
				// 内控到期日
				copyVO.setInnerctldeferdays(termVO.getInnerctldeferdays());
				copyVO.setInsurance(termVO.getInsurance());
				copyVO.setPk_termitem(termVO.getPk_termitem());
				// 借方原币金额
				copyVO.setMoney_de(termVO.getMoney_de() == null ? UFDouble.ZERO_DBL : termVO.getMoney_de());
				// 借方本币金额
				copyVO.setLocal_money_de(termVO.getLocal_money_de() == null ? UFDouble.ZERO_DBL : termVO.getLocal_money_de());
				// 贷方原币金额
				copyVO.setMoney_cr(termVO.getMoney_cr() == null ? UFDouble.ZERO_DBL : termVO.getMoney_cr());
				// 贷方本币金额
				copyVO.setLocal_money_cr(termVO.getLocal_money_cr() == null ? UFDouble.ZERO_DBL : termVO.getLocal_money_cr());
				// 原币余额
				copyVO.setMoney_bal(termVO.getMoney_bal() == null ? UFDouble.ZERO_DBL : termVO.getMoney_bal());
				// 本币余额
				copyVO.setLocal_money_bal(termVO.getLocal_money_bal() == null ? UFDouble.ZERO_DBL : termVO.getLocal_money_bal());
				// 集团借方本币金额
				copyVO.setGroup_money_de(termVO.getGroupdebit() == null ? UFDouble.ZERO_DBL : termVO.getGroupdebit());
				// 集团贷方本币金额
				copyVO.setGroup_money_cr(termVO.getGroupcredit() == null ? UFDouble.ZERO_DBL : termVO.getGroupcredit());
				// 集团本币余额
				copyVO.setGroup_money_bal(termVO.getGroupbalance() == null ? UFDouble.ZERO_DBL : termVO.getGroupbalance());
				// 全局借方本币金额
				copyVO.setGlobal_money_de(termVO.getGlobaldebit() == null ? UFDouble.ZERO_DBL : termVO.getGlobaldebit());
				// 全局贷方本币金额
				copyVO.setGlobal_money_cr(termVO.getGlobalcredit() == null ? UFDouble.ZERO_DBL : termVO.getGlobalcredit());
				// 全局本币余额
				copyVO.setGlobal_money_bal(termVO.getGlobalbalance() == null ? UFDouble.ZERO_DBL : termVO.getGlobalbalance());
				// 借方数量
				copyVO.setQuantity_de(termVO.getQuantity_de() == null ? UFDouble.ZERO_DBL : termVO.getQuantity_de());
				// 贷方数量
				copyVO.setQuantity_cr(termVO.getQuantity_cr() == null ? UFDouble.ZERO_DBL : termVO.getQuantity_cr());
				// 数量余额
				copyVO.setQuantity_bal(termVO.getQuantity_bal() == null ? UFDouble.ZERO_DBL : termVO.getQuantity_bal());
				// 预占余额
				copyVO.setOccupationmny(termVO.getOccupationmny());//
				copyVO.setIstransin(UFBoolean.valueOf(false));// 默认非转入，转出N，转入Y
				copyVO.setPrepay(termVO.getPrepay()!=null && termVO.getPrepay().booleanValue()?1:0);
				busiDataList.add(copyVO);
			}
		}
		return busiDataList;
	}

	protected void doInsertRegister(List<ArapBusiDataVO> insertdatas) throws BusinessException {
		Logger.debug("插入arap_busidata 表  数量 =" + insertdatas.size());
		new BaseDAO().insertVOList(insertdatas);
	}


	public  static String SAMVERIFYFLAG = "SAMVERIFYFLAG";  //同币种核销
	public  static String UNVERIFYFLAG ="UNVERIFYFLAG";    //异币种核销
	public  static String HCSAMVERIFYFLAG  = "HCSAMVERIFYFLAG"; //同币种红冲核销
	public  static String HCUNVERIFYFLAG  = "HCUNVERIFYFLAG";   //异币种红冲核销



	private Map<String, ArrayList<AggverifyVO>> onVerify(VerifyCom com, Map<String, DefaultVerifyRuleVO> ruleVOMap, ArapBusiDataVO[] jf_vos, ArapBusiDataVO[] df_vos) {

		// 自动核销 只有红蓝对冲，同币种核销

		com.setM_creditSelected(df_vos);
		com.setM_debitSelected(jf_vos);
		AggverifyVO aggvo = null;
		if (!ArrayUtils.isEmpty(jf_vos) || !ArrayUtils.isEmpty(df_vos)) {
			for (String key : ruleVOMap.keySet()) {
				if (ArrayUtils.isEmpty(jf_vos) || ArrayUtils.isEmpty(df_vos)){//如果 jf空了或者贷方空了，就没办法同币种核销
					if(key.equals("SAME_VERIFY")){
						continue;
					}
				}else{
					String billclass = jf_vos[0].getBillclass();
					String billclass2 = df_vos[0].getBillclass();

					if((billclass.equals(IBillFieldGet.YS) && billclass2.equals(IBillFieldGet.FK))
							|| (billclass.equals(IBillFieldGet.FK) && billclass2.equals(IBillFieldGet.YS))){
						if(key.equals("SAME_VERIFY")||key.equals("UNSAME_VERIFY")){
							continue;
						}
					}
					if((billclass.equals(IBillFieldGet.YS) && billclass2.equals(IBillFieldGet.SK))
							|| (billclass.equals(IBillFieldGet.SK) && billclass2.equals(IBillFieldGet.YS))
							||(billclass.equals(IBillFieldGet.YF) && billclass2.equals(IBillFieldGet.FK))
							|| (billclass.equals(IBillFieldGet.FK) && billclass2.equals(IBillFieldGet.YF))){
						if(key.equals("RB_VERIFY")){
							continue;
						}
					}
				}

				DefaultVerifyRuleVO rulevo = ruleVOMap.get(key);
				if (key.equals("SAME_VERIFY")) {

					SameMnyVerify smverify = new SameMnyVerify(com);
					aggvo = smverify.onVerify(jf_vos, df_vos, rulevo);
					if (aggvo == null) {
						continue;
					}
					if (!ArrayUtils.isEmpty(aggvo.getChildrenVO())) {
						if (aggMap.containsKey("SAME_VERIFY")) {
							aggMap.get(key).add(aggvo);
						} else {
							ArrayList<AggverifyVO> temp = new ArrayList<AggverifyVO>();
							temp.add(aggvo);
							aggMap.put("SAME_VERIFY", temp);
						}
					}
				} else if(key.equals("RB_VERIFY")){//红蓝对冲
					RBVerify rbverify = new RBVerify(com);
					aggvo = rbverify.onVerify(jf_vos, df_vos, rulevo);
					if (!ArrayUtils.isEmpty(aggvo.getChildrenVO())) {
						if (aggMap.containsKey("RB_VERIFY")) {
							aggMap.get(key).add(aggvo);
						} else {
							ArrayList<AggverifyVO> temp = new ArrayList<AggverifyVO>();
							temp.add(aggvo);
							aggMap.put("RB_VERIFY", temp);
						}
					}
				}else if(key.equals("UNSAME_VERIFY")){
					UnsameMnyVerify unsameMnyVerify =new UnsameMnyVerify(com);
					aggvo = unsameMnyVerify.onVerify(jf_vos, df_vos, rulevo);
					if(!ArrayUtils.isEmpty(aggvo.getChildrenVO())){
						if (aggMap.containsKey("UNSAME_VERIFY")) {
							aggMap.get(key).add(aggvo);
						} else {
							ArrayList<AggverifyVO> temp = new ArrayList<AggverifyVO>();
							temp.add(aggvo);
							aggMap.put("UNSAME_VERIFY", temp);
						}

					}
				}

			}
		}

		return aggMap;

	}

	private ArrayList<AggverifyVO> getAggVerifyVO(Map<String, ArrayList<AggverifyVO>> aggMap) throws BusinessException {
		ArrayList<AggverifyVO> resultList = new ArrayList<AggverifyVO>();
		if (aggMap == null) {
			return resultList;
		}
		for (String key : aggMap.keySet()) {
			List<VerifyDetailVO> detailVOList = new ArrayList<VerifyDetailVO>();
			ArrayList<AggverifyVO> arrayList = aggMap.get(key);
			if (arrayList != null) {
				for (AggverifyVO aggVO : arrayList) {
					VerifyDetailVO[] childrenVO = (VerifyDetailVO[]) aggVO.getChildrenVO();
					// 审核后自动核销，设置标志位 核销记录查询不出来
					for (VerifyDetailVO verifyvo : childrenVO) {
						verifyvo.setIsauto(UFBoolean.TRUE);
						detailVOList.add(verifyvo);
					}
				}
				// 组织聚合vo
				AggverifyVO aggVO = new AggverifyVO();
				aggVO.setChildrenVO(detailVOList.toArray(new VerifyDetailVO[0]));
				// 计算全局 集团本位币
				VerifyCom.calGroupAndGloablMny(aggVO);
				ArrayList<AggverifyVO> aggvolist = (ArrayList<AggverifyVO>) VerifyCom.verifySumData(aggVO);

				resultList.addAll(aggvolist);
			}
		}
		return resultList;
	}


    private  DefaultVerifyRuleVO getVerifyRuleVO(){
    		DefaultVerifyRuleVO rulevo = new DefaultVerifyRuleVO();
    		Integer m_hxSeq = Integer.valueOf(0);
    		try {
    			String hxSeq = "";
    			if (getSyscode() == 0) {
    				hxSeq = SysinitAccessor.getInstance().getParaString(this.getPkorg(), "AR1");
    			} else {
    				hxSeq = SysinitAccessor.getInstance().getParaString(this.getPkorg(), "AP1");
    			}
    			if (hxSeq.equals(SysinitConst.VERIFY_ZAO)) {
    				m_hxSeq = Integer.valueOf(0);
    			} else {
    				m_hxSeq = Integer.valueOf(1);
    			}

    		} catch (Exception e) {
    			ExceptionHandler.consume(e);
    		}
    		rulevo.setM_verifySeq(m_hxSeq);
    		UFDate clrq = new UFDate(InvocationInfoProxy.getInstance().getBizDateTime());
    		rulevo.setM_Clrq(clrq);
    		AccountCalendar ac = AccountCalendar.getInstanceByPk_org(this.getPkorg());
    		try {
    			ac.setDate(clrq);
    		} catch (InvalidAccperiodExcetion e) {
    			ExceptionHandler.consume(e);
    		}
    		rulevo.setSystem(getSyscode());
    		rulevo.setPk_org(getPkorg());
    		rulevo.setM_Clnd(ac.getYearVO().getPeriodyear());
    		rulevo.setM_Clqj(ac.getMonthVO().getAccperiodmth());
    		rulevo.setIsOccuption(true);
    		rulevo.setM_clr(getPk_user());
    		return rulevo;
    }
	private Hashtable<String, DefaultVerifyRuleVO> creatVerifyRuleVO() {

		Hashtable<String, DefaultVerifyRuleVO> ruleMap = new Hashtable<String, DefaultVerifyRuleVO>();
		DefaultVerifyRuleVO rulevo = getVerifyRuleVO();
		rulevo.setM_verifyName("SAME_VERIFY");
		DefaultVerifyRuleVO rbrulevo = (DefaultVerifyRuleVO) rulevo.clone();
		rbrulevo.setM_verifyName("RB_VERIFY");
		ruleMap.put("SAME_VERIFY", rulevo);
		ruleMap.put("RB_VERIFY", rbrulevo);

		return ruleMap;
	}

	/**
	 * 
	 * @param isSuccess		状态(Y:成功,N:失败)
	 * @param operation		操作
	 * @param resultInfo	结果信息
	 * @param errorInfo		异常信息
	 * @param sendData		发送的数据
	 * @param billId		单据id
	 * @param billType		单据类型编码
	 * @param billName		单据名称
	 */
	public void insertLog(UFBoolean isSuccess,String operation,String resultInfo,String errorInfo,String sendData,String billId,String billType,String billName){
		try {
			NCWebserviceLogVO logVO = new NCWebserviceLogVO();
			logVO.setIssuccess(isSuccess);//是否成功
			logVO.setOperation(operation);//操作
			logVO.setResultinfo(resultInfo);//结果信息
			logVO.setErrorinfo(errorInfo);//异常信息
			logVO.setSenddata(sendData);//发送的数据
			logVO.setSrc_pk_billtype(billType);//所属单据编码
			logVO.setSrc_pk_billname(billName);//所属单据名称
			logVO.setSrc_pk_bill(billId);//单据主键
			new BaseDAO().insertVO(logVO);
		} catch (Exception e) {
			Logger.error("====应付单同步日志插入异常===" + e.getMessage());
		}
	}

	@SuppressWarnings("unused")
	private void VerifyByF0F1F3F2(List<ArapBillMapVO> MapVOList, VerifyCom com,
			Hashtable<String, DefaultVerifyRuleVO> ruleVOMap)
			throws BusinessException {
		com.setReserveFlag(20);
		Map<String, String> busiDataTsMap = new HashMap<String, String>();
		List<ArapBusiDataVO> jfdataList = new ArrayList<ArapBusiDataVO>();
		List<ArapBusiDataVO> dfdataList = new ArrayList<ArapBusiDataVO>();
		this.aggMap.clear();
		for (ArapBillMapVO vo : MapVOList) {
			List<ArapBusiDataVO> dataList = new ArrayList<ArapBusiDataVO>();
			List<String> pks = new ArrayList<String>();
			if (vo.getS_itemid() == null) { // 源头id 为空 ，没有数据不用核销
				continue;
			} else {
				pks.add(vo.getS_itemid());
				pks.add(vo.getT_itemid());
			}
			// 查询要核销的数据
			Collection<ArapBusiDataVO> busiList = null;
			if (pks != null && pks.size() > 0) {
				busiList = new BaseDAO().retrieveByClause(
						ArapBusiDataVO.class,
						SqlUtils.getInStr("pk_item",
								pks.toArray(new String[] {}))
								+ " and money_bal <> 0 "
								+ " and pausetransact ='N' ");
			} else {
			}
			for (ArapBusiDataVO dataVO : busiList) {
				dataList.add(dataVO);
				// 比较ts 使用
				busiDataTsMap.put(dataVO.getPk_busidata(), dataVO.getTs()
						.toString());
				com.setBusiDataTsMap(busiDataTsMap);
			}
			// 借贷方分组
			for (ArapBusiDataVO datavo : dataList) {
				datavo.setAttributeValue(ArapBusiDataVO.SETT_MONEY,
						datavo.getOccupationmny());
				if (datavo.getDirection().intValue() == 1) {
					jfdataList.add(datavo);
				} else {
					dfdataList.add(datavo);
				}
			}

		}
		Map<String, ArrayList<AggverifyVO>> aggMap = this.onVerify(com,
				ruleVOMap, jfdataList.toArray(new ArapBusiDataVO[0]),
				dfdataList.toArray(new ArapBusiDataVO[0]));
		ArrayList<AggverifyVO> aggVOList = this.getAggVerifyVO(aggMap);
		// 核销结果保存
		if (aggVOList != null && aggVOList.size() > 0) {
			NCLocator.getInstance().lookup(IArapVerifyLogPrivate.class)
					.save(aggVOList, ruleVOMap, com);
		}
	}
}
