package nc.net.pu.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import nc.bs.bd.bankacc.validator.CustSupBankaccAutoEnableValidation;
import nc.bs.framework.common.NCLocator;
import nc.bs.uap.tools.formula.ExtFormulaParser;
import nc.itf.bd.bankacc.cust.ICustBankaccQueryService;
import nc.itf.bd.bankacc.cust.ICustBankaccService;
import nc.itf.bd.supplier.baseinfo.ISupBaseInfoExtendService;
import nc.itf.bd.supplier.baseinfo.ISupplierBaseInfoQryService;
import nc.itf.uap.IUAPQueryBS;
import nc.itf.ws.esb.IEsbDAO;
import nc.net.servlet.IReturnStatus;
import nc.pub.sap.constant.SapConstants;
import nc.pub.sap.sort.SapVOSort;
import nc.util.mmf.framework.base.MMStringUtil;
import nc.util.mmf.framework.base.MMValueCheck;
import nc.vo.bd.bankaccount.BankAccSubVO;
import nc.vo.bd.bankaccount.BankAccbasVO;
import nc.vo.bd.bankaccount.cust.CustBankaccUnionVO;
import nc.vo.bd.cust.CustbankVO;
import nc.vo.esb.EsbInfoVO;
import nc.vo.esb.QueryInfoVO;
import nc.vo.esb.ResultEsbVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.CircularlyAccessibleValueObject;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.data.ValueUtils;
import nc.vo.sap.syproconfig.SyProConfigBVO;
import nc.vo.uap.rbac.constant.INCSystemUserConst;
import nc.vo.uapbd.mdg.JsonTransParamVo;
import nc.vo.ws.esb.CertificateVO;
import nc.vo.ws.esb.EsbinfoVO;
import sun.misc.BASE64Encoder;

public class HttpReqUtil {
	
	private static IEsbDAO service;
	private static BASE64Encoder base64;
	
	/**
	* 向指定 URL 发送POST方法的请求（发送值）
    * @param url 发送请求的 URL
    * @param paramJson json串格式的报文
    * @param esbcode 接口安全授权 编码
    * @return 所代表远程资源的响应结果(值类型为Json对象)
    */
   public static JSONObject sendJsonPost(String url, String paramJson,String esbcode) throws Exception{
	   OutputStreamWriter out = null;
       BufferedReader in = null;
       StringBuffer result = new StringBuffer();
       try {
           URL realUrl = new URL(url);
           // 打开和URL之间的连接
           URLConnection conn = realUrl.openConnection();
           // 设置通用的请求属性 
           conn.setRequestProperty("accept", "*/*");
           conn.setRequestProperty("connection", "Keep-Alive");
           conn.setRequestProperty("user-agent",  "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
           //设置请求字符集  防止请求参数因字符集原因（非UTF-8）导致调用接口不一致报错（数据类型不一致） 
           conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
           addHeaderBasic(esbcode,conn);//Http添加Basic认证
           // 发送POST请求必须设置如下两行
           conn.setDoOutput(true);
           conn.setDoInput(true);
           // 获取URLConnection对象对应的输出流
           out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
           // 发送请求参数
           out.write(paramJson);
           // flush输出流的缓冲
           out.flush();
           // 定义BufferedReader输入流来读取URL的响应
           in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
           String line;
           while ((line = in.readLine()) != null) {
               result.append(line);
           }
       } catch (Exception e) {
           throw e;
       }
       //使用finally块来关闭输出流、输入流
       finally{
           try{
               if(out!=null){
                   out.close();
               }
               if(in!=null){
                   in.close();
               }
           }
           catch(IOException ex){
               ex.printStackTrace();
           }
       }
       if(result!=null && result.length()>0)//转换为Json对象输出
    	   return JSONObject.parseObject(result.toString());
       else
    	   return null;
   }
   
   /**
	* 向指定 URL 发送POST方法的请求（发送值）
   * @param url 发送请求的 URL
   * @param paramJson json串格式的报文
   * @param esbcode 接口安全授权 编码
   * @return 所代表远程资源的响应结果(值类型为Json对象)
   */
  public static String sendJsonPostStr(String url, String paramJson,String esbcode) throws Exception{
	   OutputStreamWriter out = null;
      BufferedReader in = null;
      StringBuffer result = new StringBuffer();
      try {
          URL realUrl = new URL(url);
          // 打开和URL之间的连接
          URLConnection conn = realUrl.openConnection();
          // 设置通用的请求属性 
          conn.setRequestProperty("accept", "*/*");
          conn.setRequestProperty("connection", "Keep-Alive");
          conn.setRequestProperty("user-agent",  "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
          //设置请求字符集  防止请求参数因字符集原因（非UTF-8）导致调用接口不一致报错（数据类型不一致） 
          conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
          addHeaderBasic(esbcode,conn);//Http添加Basic认证
          // 发送POST请求必须设置如下两行
          conn.setDoOutput(true);
          conn.setDoInput(true);
          // 获取URLConnection对象对应的输出流
          out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
          // 发送请求参数
          out.write(paramJson);
          // flush输出流的缓冲
          out.flush();
          // 定义BufferedReader输入流来读取URL的响应
          in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
          String line;
          while ((line = in.readLine()) != null) {
              result.append(line);
          }
      } catch (Exception e) {
          throw e;
      }
      //使用finally块来关闭输出流、输入流
      finally{
          try{
              if(out!=null){
                  out.close();
              }
              if(in!=null){
                  in.close();
              }
          }
          catch(IOException ex){
              ex.printStackTrace();
          }
      }
      if(result!=null && result.length()>0)
   	   return result.toString();
      else
   	   return null;
  }
   
   /**
	 * 查询公式
	 * @param code			表头编码
	 * @param direction		方向【SAP->NC ? NC->SAP】
	 * @return
	 * @throws BusinessException
	 */
	public static HashMap<String,ArrayList<String>> getFormulas(String code,int direction) throws BusinessException{
		StringBuffer sqlstr = new StringBuffer("");
		sqlstr.append("item = (select pk_head").append("\r\n");
		sqlstr.append("  from sap_syproconfig").append("\r\n");
		sqlstr.append(" where billno = '");
		sqlstr.append(code);
		sqlstr.append("'").append("\r\n");
		sqlstr.append("   and nvl(dr, 0) = 0) and nvl(dr, 0) = 0");
		List<SyProConfigBVO> syProConfigBVOs = (List<SyProConfigBVO>)getQueryBS().retrieveByClause(SyProConfigBVO.class, sqlstr.toString());
		if(syProConfigBVOs!=null && syProConfigBVOs.size()>0){
			HashMap<String,ArrayList<String>> formulasMap = new HashMap<String,ArrayList<String>>();
			//非空字段
			ArrayList<String> notNullField = new ArrayList<String>();
			//SAP->NC ？ NC->SAP 公式
			ArrayList<String> formula = new ArrayList<String>();
			//NC字段编码
			ArrayList<String> nc_field_code = new ArrayList<String>();
			//NC字段名称
			ArrayList<String> nc_field_name = new ArrayList<String>();
			//SAP字段编码
			ArrayList<String> sap_field_code = new ArrayList<String>();
			Collections.sort(syProConfigBVOs, new SapVOSort(direction));
			for(SyProConfigBVO syProConfigBVO:syProConfigBVOs){
				if(SapConstants.DIRECTION_SAP2NC==direction){
					//SAP->NC
					if(syProConfigBVO.getIsenable_sn().booleanValue()){
						if(!syProConfigBVO.getNullflag().booleanValue()){
							notNullField.add(syProConfigBVO.getField_code());
							nc_field_name.add(syProConfigBVO.getField_name());
						}
						formula.add(syProConfigBVO.getFormula_sn());
					}
					//把NC编码也放进去 begin
					nc_field_code.add(syProConfigBVO.getField_code());
					//把NC编码也放进去 end
				}else if(SapConstants.DIRECTION_NC2SAP==direction){
					//NC->SAP
					if(syProConfigBVO.getIsenable_ns().booleanValue()){
						formula.add(syProConfigBVO.getFormula_ns());
						nc_field_code.add(syProConfigBVO.getField_code());
						sap_field_code.add(syProConfigBVO.getField_code_sap());
					}
				}
			}
			formulasMap.put(SapConstants.NOTNULL_FIELD_KEY, notNullField);
			formulasMap.put(SapConstants.FORMULA_KEY, formula);
			formulasMap.put(SapConstants.NC_FIELD_CODE, nc_field_code);
			formulasMap.put(SapConstants.SAP_FIELD_CODE, sap_field_code);
			formulasMap.put(SapConstants.NC_FIELD_NAME, nc_field_name);
			return formulasMap;
		}
		return null;
	}
	
	/**
	 * 查询NC字段编码和SAP编码对照
	 * @param code			表头编码
	 * @param direction		方向【SAP->NC ? NC->SAP】
	 * @return SAP->NC
	 * @throws BusinessException
	 */
	public static HashMap<String,String> getTranNCcodes(String code,int direction) throws BusinessException{
		StringBuffer sqlstr = new StringBuffer("");
		sqlstr.append("item = (select pk_head").append("\r\n");
		sqlstr.append("  from sap_syproconfig").append("\r\n");
		sqlstr.append(" where billno = '");
		sqlstr.append(code);
		sqlstr.append("'").append("\r\n");
		sqlstr.append("   and nvl(dr, 0) = 0) and nvl(dr, 0) = 0 "); 
		List<SyProConfigBVO> syProConfigBVOs = (List<SyProConfigBVO>)getQueryBS().retrieveByClause(SyProConfigBVO.class, sqlstr.toString());
		if(syProConfigBVOs!=null && syProConfigBVOs.size()>0){
			HashMap<String,String> tranNCcodeMap = new HashMap<String,String>();
			for(SyProConfigBVO syProConfigBVO:syProConfigBVOs){
				if(SapConstants.DIRECTION_SAP2NC==direction){
					//SAP->NC
					if(syProConfigBVO.getIsenable_sn().booleanValue()){//是否启用sap-nc
						String code_sap=syProConfigBVO.getField_code_sap();
						if(code_sap!=null&&!"".equals(code_sap.trim())&&!"1".equals(code_sap.trim())){
							tranNCcodeMap.put(code_sap,syProConfigBVO.getField_code());
						}
					}
					//NC->SAP
				}else if(SapConstants.DIRECTION_NC2SAP==direction) {
					if(syProConfigBVO.getIsenable_ns().booleanValue()){//是否启用sap-nc
						String code_sap=syProConfigBVO.getField_code_sap();
						if(code_sap!=null&&!"".equals(code_sap.trim())&&!"1".equals(code_sap.trim())){
							tranNCcodeMap.put(code_sap,syProConfigBVO.getField_code());
						}
					}
				}
			}
			return tranNCcodeMap;
		}
		return null;
	}
	
	public static CircularlyAccessibleValueObject processNCAction(JsonTransParamVo paramVO) throws Exception{
		HashMap<String,ArrayList<String>> hFormulaMap = getFormulas(paramVO.gethCfgCode(),SapConstants.DIRECTION_SAP2NC);
		
		Map<String,String> classCfgCodeMap= paramVO.getClassCfgCodeMap();
		Map<String,HashMap<String,ArrayList<String>>> bClassFormulaMap = null;
		CircularlyAccessibleValueObject[] bodyVOs;
		HashMap<String,ArrayList<String>> bFormulaMap;
		if(MMValueCheck.isNotEmpty(classCfgCodeMap)){
			bClassFormulaMap = new HashMap<String,HashMap<String,ArrayList<String>>>();
			Iterator<String> it = classCfgCodeMap.keySet().iterator();
			String classCode;
			while(it.hasNext()){
				classCode = it.next();
				bFormulaMap =getFormulas(classCfgCodeMap.get(classCode),SapConstants.DIRECTION_SAP2NC);
				if(MMValueCheck.isNotEmpty(bFormulaMap)){
					bClassFormulaMap.put(classCode, bFormulaMap);
				}
			}
		}
		CircularlyAccessibleValueObject ncValueObjects=json2NCVO(paramVO);
		
		if(MMValueCheck.isEmpty(ncValueObjects)){
			throw new BusinessException("json转换成NCVO为空 ！ ");
		}
		//转换前非空校验、执行公式、翻译后各项非空校验	
			notNullCheckAndExFormula(hFormulaMap,ncValueObjects);
			//表体
			if(MMValueCheck.isNotEmpty(bClassFormulaMap)){
				Class<? extends CircularlyAccessibleValueObject> bClass;
				CircularlyAccessibleValueObject bVO;
				Iterator<String> it = bClassFormulaMap.keySet().iterator();
				String classCode;
				while(it.hasNext()){
					classCode = it.next();
					bFormulaMap = bClassFormulaMap.get(classCode);
					bClass = paramVO.getClassMap().get(classCode);
					bodyVOs=(CircularlyAccessibleValueObject[]) Array.newInstance(bClass,1);
					Object[] objs = (Object[])ncValueObjects.getAttributeValue(classCode);
					if(MMValueCheck.isEmpty(objs)){
					Method[] methods=paramVO.getHeadVOClass().getMethods();
						if(MMValueCheck.isNotEmpty(methods)){
							for(int m=0;m<methods.length;m++){
								if(methods[m].getReturnType() ==bodyVOs.getClass()){
									objs=(Object[]) ncValueObjects.getClass().getMethod(methods[m].getName()).invoke(ncValueObjects,new Object[]{});
									break;
								}
							}
						}
					}
					if(MMValueCheck.isNotEmpty(objs)){
						for(Object obj:objs){
							bVO = bClass.cast(obj);
							notNullCheckAndExFormula(bFormulaMap,bVO);
						}
					}
				}
			}
		
		return ncValueObjects;
	}
	
	public static CircularlyAccessibleValueObject json2NCVO(JsonTransParamVo paramVO) throws Exception {
		String billdata = paramVO.getBilldata();
		JSONObject jsonObj = null;
		JSONObject data = JSONObject.parseObject(billdata);
		
		if(MMValueCheck.isEmpty(data)) {
			return null;
		}
		List<String> removeKys = paramVO.getRemoveKys();
		if(MMValueCheck.isNotEmpty(removeKys)){
			for(String removeKy:removeKys){
				data.remove(removeKy);
			}
		}
		Class<? extends CircularlyAccessibleValueObject> headVOClass = paramVO.getHeadVOClass();
		Map<String,Class<? extends CircularlyAccessibleValueObject>> classMap = paramVO.getClassMap();
		Map<String,ArrayList<String>> dataTypesMap = paramVO.getDataTypesMap();
		Class<? extends CircularlyAccessibleValueObject> bodyVOClass;
		Map<String,CircularlyAccessibleValueObject[]> bodyVOMap = new HashMap<String,CircularlyAccessibleValueObject[]>();
		JSONArray jsonArray;
		CircularlyAccessibleValueObject[] bodyVOs;
		CircularlyAccessibleValueObject bodyVO;
		String attributeName;
		ArrayList<String> bDataTypes;
		Iterator<String> it = (Iterator<String>)classMap.keySet().iterator();
		while (it.hasNext()) {
			attributeName = it.next();
			if(!data.containsKey(attributeName)) {
				continue;
			}
			jsonArray = (JSONArray)data.get(attributeName);
			if(jsonArray!=null && jsonArray.size()>0){
				bodyVOClass = classMap.get(attributeName);
				bDataTypes = dataTypesMap.get(attributeName);
				bodyVOs =(CircularlyAccessibleValueObject[]) Array.newInstance(bodyVOClass,jsonArray.size());
				for(int i=0,len = jsonArray.size();i<len;i++){
					jsonObj = (JSONObject) jsonArray.get(i);
					//表体赋值
					bodyVO = bodyVOClass.newInstance();
					setValue(bodyVO,jsonObj);
					bodyVOs[i] = bodyVO;
				}
				bodyVOMap.put(attributeName, bodyVOs);
			}
			data.remove(attributeName);
		}
		CircularlyAccessibleValueObject headVO = headVOClass.newInstance();
		//表头赋值
		setValue(headVO,data);
		//组装
		it = (Iterator<String>)bodyVOMap.keySet().iterator();
		while(it.hasNext()){
			attributeName = it.next();
			bodyVOs = bodyVOMap.get(attributeName);
			if(MMValueCheck.isNotEmpty(bodyVOs)){
				headVO.setAttributeValue(attributeName, bodyVOs);
			}
		}
		return headVO;
	}
	
	protected static void setValue(CircularlyAccessibleValueObject vo,JSONObject jaonObject) throws Exception{
		Map<String,String> fieldTypeMap = new HashMap<String,String>();
		String[] arr;
		Method[]  methods=vo.getClass().getMethods();
		List<Field> dataTypes=Arrays.asList(vo.getClass().getFields());
		
		for(Method m:methods){
			fieldTypeMap.put(m.getName().toLowerCase(), m.getReturnType().getSimpleName());
		}
		for(Field dataType:dataTypes){
			//			arr = dataType.split(",");
			fieldTypeMap.put(dataType.getName(), dataType.getType().getSimpleName());
		}
		String attributeName;
		String type;
		Object value;
		Iterator<String> it = (Iterator<String>) jaonObject.keySet().iterator();
		while (it.hasNext()) {
			attributeName = it.next();
			if (MMValueCheck.isEmpty(attributeName)) {
				continue;
			}
			value = jaonObject.get(attributeName);
			if (MMValueCheck.isEmpty(value)) {
				continue;
			}
			type = fieldTypeMap.get(attributeName.toLowerCase());
			if(type==null){
				type=fieldTypeMap.get("get"+attributeName.toLowerCase());
			}
			if(type==null){
				vo.setAttributeValue(attributeName, value);
			}else if ("Integer".equals(type)) {
					value=jaonObject.getIntValue(attributeName);
				for(int m=0;m<methods.length;m++){
					if(methods[m].getName().toLowerCase().equals("set"+attributeName)){
						vo.getClass().getMethod(methods[m].getName(),methods[m].getParameterTypes()[0]).invoke(vo, new Object[]{Integer.parseInt(value.toString())});
						break;
					}
				}
			} else if ("UFDouble".equals(type)) {
				vo.setAttributeValue(attributeName, new UFDouble(jaonObject.getDoubleValue(attributeName)));
			} else if ("UFBoolean".equals(type)) {
				vo.setAttributeValue(attributeName, new UFBoolean(value.toString()));
			} else if ("UFDate".equals(type)) {
				vo.setAttributeValue(attributeName, new UFDate(value.toString()));
			} else if ("UFDateTime".equals(type)) {
				SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String notdate = sdfs.format(ValueUtils.getUFLiteralDate(value).getMillis());
				vo.setAttributeValue(attributeName, new UFDateTime(notdate));
			} else {
				vo.setAttributeValue(attributeName,value);
				if(null==vo.getAttributeValue(attributeName)){
					for(int m=0;m<methods.length;m++){
						if(methods[m].getName().toLowerCase().equals("set"+attributeName)){
							vo.getClass().getMethod(methods[m].getName(),methods[m].getParameterTypes()[0]).invoke(vo, new Object[]{value});
							break;
						}
					}
					
				}
			}
		}
		//VO状态
		vo.setStatus(VOStatus.NEW);
	}
	
	public static void notNullCheckAndExFormula(HashMap<String,ArrayList<String>> formulaMap,CircularlyAccessibleValueObject ncVO) throws Exception {
		List<String> Keys = formulaMap.get(SapConstants.NOTNULL_FIELD_KEY);
		List<String> KeysName = formulaMap.get(SapConstants.NC_FIELD_NAME);

		ArrayList<String> Formula = formulaMap.get(SapConstants.FORMULA_KEY);
		ExtFormulaParser extFormulaParser = new ExtFormulaParser();
		notNullCheck(Keys,KeysName,null,null,ncVO, null,1);
		extFormulaParser.execFormulas(Formula.toArray(new String[Formula.size()]),new CircularlyAccessibleValueObject[]{ncVO});
		notNullCheck(Keys,KeysName,null,null,ncVO, null,2);
	}
	
	/**
	 * 非空字段校验
	 * @param headKeys
	 * 			表头字段
	 * @param bodyKeys
	 * 			表体字段
	 * @param bodyKeys2 
	 * @param bodyKeysName 
	 * @param headVO
	 * 			表头VO
	 * @param bodyVOs
	 * 			表体VO
	 * @param type
	 * 			1：第一次非空校验，2：转换后非空校验
	 * @throws Exception
	 */
	public static void notNullCheck(List<String> headKeys,List<String> headKeYsName,List<String> bodyKeysName, List<String> bodyKeys, CircularlyAccessibleValueObject headVO,CircularlyAccessibleValueObject[] bodyVOs,int type) throws Exception{
		Set<String> keySetName = new HashSet<String>();
		Set<String> bodyNnullkeySetName = new HashSet<String>();
		Map<Object, Set<String>> bodyCheckMap=new HashMap<Object, Set<String>>();
		Object rownum = null;
		Object value;
		if(MMValueCheck.isNotEmpty(headKeys) && headVO!=null){
			for (int i = 0; i < headKeys.size(); i++) {
				String key=headKeys.get(i);
				value = headVO.getAttributeValue(key);
				if(MMValueCheck.isEmpty(value)){
					keySetName.add(headKeYsName.get(i));
				}
			}
		}
		if(MMValueCheck.isNotEmpty(bodyKeys) && MMValueCheck.isEmpty(Arrays.asList(bodyVOs))){
		     for (int i = 0; i < bodyKeys.size(); i++) {
				for(CircularlyAccessibleValueObject bodyVO:bodyVOs){
					String key=bodyKeys.get(i);
					value = bodyVO.getAttributeValue(key);
					if(MMValueCheck.isEmpty(value)){
						keySetName.add(bodyKeysName.get(i));
					}
				}
			}
		     if(bodyKeysName.contains("行项目")){
		    	 for(CircularlyAccessibleValueObject bodyVO:bodyVOs){
		    		 for (int i = 0; i < bodyKeys.size(); i++) {
		    			 String key=bodyKeys.get(i);
		    			 value = bodyVO.getAttributeValue(key);
		    			 if(MMValueCheck.isEmpty(value)){
		    				 bodyNnullkeySetName.add(bodyKeysName.get(i));
		    			 }
		    			 if("行项目".equals(bodyKeysName.get(i))){
		    				 rownum = bodyVO.getAttributeValue(key);
		    			 }
		    		 }
		    		 bodyCheckMap.put(rownum, bodyNnullkeySetName);
		    	 }
		     }
		}
		if(keySetName.size()>0){
			String keyName = MMStringUtil.mergeString(keySetName.toArray(),"", "、");
			if(bodyCheckMap.size()>0){
				keyName=keyName+"表体行错误信息：";
				for(Entry<Object, Set<String>> entry : bodyCheckMap.entrySet()){
					Object mapKey = entry.getKey();
				    Set<String> mapValue = entry.getValue();
				    keyName=keyName+"行项目【"+mapKey+"】以下字段-->"+MMStringUtil.mergeString(mapValue.toArray(),"", "、")+"。";
				}
			}
			if(type==1){
				throw new BusinessException( "以下字段不能为空："+keyName);	
			}else{
				throw new BusinessException( "以下字段转换失败："+keyName);	
			}
		}
	}
	
	public static void converNCVO(String cfgCode,CircularlyAccessibleValueObject oldNCVO,CircularlyAccessibleValueObject newNCVO) throws BusinessException{
		HashMap<String,ArrayList<String>> formulaMap = getFormulas(cfgCode,SapConstants.DIRECTION_SAP2NC);
		List<String> hKeys = formulaMap.get(SapConstants.NC_FIELD_CODE);
		for(String hKey:hKeys){
			oldNCVO.setAttributeValue(hKey, newNCVO.getAttributeValue(hKey));
		}
		oldNCVO.setStatus(VOStatus.UPDATED);
	}
	
	/**
	 * 处理供应商/客户 银行账户
	 * @param key
	 * @param cfgCodes
	 * @param billdata
	 * @return
	 * @throws Exception
	 */
	public static BankAccbasVO[] dealBankAccbasVOs(String[] cfgCodes,String billdata) throws Exception{
		JSONObject jsonObj =JSONObject.parseObject(billdata);
		com.alibaba.fastjson.JSONArray jsonArray = (JSONArray)jsonObj.get("custbanks");
		BankAccbasVO[] bankAccbasVOs = null;
		BankAccbasVO bankAccbasVO;
		JsonTransParamVo paramVO;
		if(jsonArray!=null && jsonArray.size()>0){
			BankAccSubVO bankaccsub;
			bankAccbasVOs = new BankAccbasVO[jsonArray.size()];
			for(int i=0,len = jsonArray.size();i<len;i++){
				jsonObj = (JSONObject) jsonArray.get(i);
				paramVO = new JsonTransParamVo();
				paramVO.sethCfgCode(cfgCodes[0]);
				paramVO.setHeadVOClass(BankAccbasVO.class);
				paramVO.setBilldata(jsonObj.toString());
				bankAccbasVO = (BankAccbasVO)processNCAction(paramVO);
				//子户
				JSONObject subJson = new JSONObject();
				subJson.put("pk_currtype", jsonObj.get("pk_currtype"));
				paramVO = new JsonTransParamVo();
				paramVO.sethCfgCode(cfgCodes[1]);
				paramVO.setHeadVOClass(BankAccSubVO.class);
				paramVO.setBilldata(jsonObj.toString());
				bankaccsub = (BankAccSubVO)processNCAction(paramVO);
				bankAccbasVO.setBankaccsub(new BankAccSubVO[]{bankaccsub});
				bankAccbasVOs[i] = bankAccbasVO;
			}
		}
		return bankAccbasVOs;
	}
	
	public static void insertCustBankacc(String pk_customer,BankAccbasVO[] bankAccbasVOs,int accclass) throws BusinessException{
		CustBankaccUnionVO custBankaccUnionVO;
		CustbankVO custbankVO = new CustbankVO();
		custbankVO.setPk_cust(pk_customer);
		custbankVO.setAccclass(accclass);
		custbankVO.setDataoriginflag(0);
		for (BankAccbasVO bankAccbasVO : bankAccbasVOs) {
			custBankaccUnionVO = new CustBankaccUnionVO();
			custBankaccUnionVO.setBankaccbasVO(bankAccbasVO);
			custBankaccUnionVO.setCustbankVO(custbankVO);
			//新增银行账户
			custBankaccUnionVO = getCustBankaccService().insertCustBankacc(custBankaccUnionVO);
			//启用银行账户
			bankAccbasVO = custBankaccUnionVO.getBankaccbasVO();
			//创建人跟启用人不能一致，在此替换创建人
			bankAccbasVO.setCreator(INCSystemUserConst.NC_USER_PK);
			bankAccbasVO.setEnableuser(INCSystemUserConst.NC_USER_PK);
			CustSupBankaccAutoEnableValidation validation = new CustSupBankaccAutoEnableValidation();
			validation.validate(custBankaccUnionVO);
			getCustBankaccService().enableCustBankacc(custBankaccUnionVO);
		}
	}
	
	/**
	 * 生成ESB响应对象
	 * @param esb
	 */
	public static void createResultEsbVO(ResultEsbVO esb){
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
		EsbInfoVO esbInfo=new EsbInfoVO();
		QueryInfoVO queryInfo=new QueryInfoVO();
		Date date=Calendar.getInstance().getTime();//获取当前时间
		//设置响应时间
		esbInfo.setInstId(UUID.randomUUID().toString());//使用UUID作为流水号
		esbInfo.setRequestTime(dateFormat.format(Calendar.getInstance().getTime()));//设置请求开始时间
		esbInfo.setResponseTime(dateFormat.format(date));//设置响应时间
		esbInfo.setReturnStatus(IReturnStatus.ESB_SUCCEED);//默认响应成功
		esbInfo.setReturnCode(IReturnStatus.ESB_SUCCEED_CODE);//默认成功code
		esbInfo.setReturnMsg("成功");//默认响应成功提示
		esb.setEsbInfo(esbInfo);
		esb.setQueryInfo(queryInfo);
	}
	
	/**
	 * Http添加Basic认证
	 * @param esbcode 接口安全授权 编码
	 * @param urlConn 访问地址对象
	 */
	public static void addHeaderBasic(String esbcode,final URLConnection urlConn){
		EsbinfoVO[] esbinfos=(EsbinfoVO[]) getService().findESB("code='"+esbcode+"'");
		if(esbinfos!=null && esbinfos.length>0){
			CertificateVO typevo=getService().findByPkCode(esbinfos[0].getCertificate());
			if(typevo!=null){
				String basic=typevo.getUsername()+":"+typevo.getPassword();
				urlConn.addRequestProperty("Authorization", "Basic "+getBase64().encode(basic.getBytes()));
			}
		}
	}
	
	public static IEsbDAO getService(){
    	if(service==null)
    		service=NCLocator.getInstance().lookup(IEsbDAO.class);
    	return service;
	 }
	 public static BASE64Encoder getBase64(){
		 if(base64==null)
			 base64=new BASE64Encoder();
		 return base64;
	 }
	/**
	 * @param e	异常
	 * return 异常详细信息
	 */
	public static String getExceptionDetail(Exception e) {
		if(e==null)
			return null;
		StringBuffer stringBuffer = new StringBuffer(e.toString() + "\n");  
		if(e.getStackTrace()==null || e.getStackTrace().length==0)
			return stringBuffer.toString();  
		StackTraceElement[] messages = e.getStackTrace();  
		int length = messages.length;  
		for (int i = 0; i < length; i++) {
			stringBuffer.append("\t"+messages[i].toString()+"\n");  
		}
		return stringBuffer.toString();  
	}
	
	public static IUAPQueryBS getQueryBS() {
		return NCLocator.getInstance().lookup(IUAPQueryBS.class);
	}
	/**
	 *供应商查询接口
	 */
	public static ISupplierBaseInfoQryService getSupplierBaseInfoQryService(){
		return NCLocator.getInstance().lookup(ISupplierBaseInfoQryService.class);
	}
	/**
	 * 供应商基础操作接口
	 */
	public static ISupBaseInfoExtendService getSupBaseInfoExtendService(){
		return NCLocator.getInstance().lookup(ISupBaseInfoExtendService.class);
	}
	/** 客户银行账户接口 **/
	public static ICustBankaccService getCustBankaccService() {
		return NCLocator.getInstance().lookup(ICustBankaccService.class);
	}
	/** 客户银行账户查询接口 **/
	public static ICustBankaccQueryService getCustBankaccQueryService(){
		return NCLocator.getInstance().lookup(ICustBankaccQueryService.class);
	}
}
