package weaver.fna.invoice.utils;


import com.engine.personalIncomeTax.biz.RecordsBiz;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import sun.misc.BASE64Decoder;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import weaver.conn.RecordSet;
import weaver.fna.general.FnaCommon;
import weaver.fna.general.FnaLogSqlUtil;
import weaver.fna.invoice.Constants;
import weaver.fna.invoice.common.FnaAbstractInterface;
import weaver.fna.invoice.common.FnaInvoiceCommon;
import weaver.fna.invoice.sdk.SdkInvoiceUtil;
import weaver.general.BaseBean;
import weaver.general.GCONST;
import weaver.general.MD5;
import weaver.general.Util;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;
import weaver.hrm.resource.ResourceComInfo;
import weaver.systeminfo.SystemEnv;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * @Author: lb2018
 * @Description:发票云工具类
 * @Date: 2020/6/9 10:45
 */
public class InvoiceCloudUtil {


    /**
     * 判断是否有生效的ocr接口、查验接口、发票云接口，并返回相关接口信息
     * @param user
     * @param queryOcr
     * @param queryCheck
     * @param queryCloud
     * @return
     */
    public static JSONObject getInterfaceInfo(User user,boolean queryOcr,boolean queryCheck,boolean queryCloud){
        JSONObject resultJson = new JSONObject();
        RecordSet rs = new RecordSet();
        if(queryOcr){
            boolean existEffectOcr=false;
            int imageCatalog = 0;
            String interfaceurl = "";
            String appKey = "";
            String secret = "";
            //如果有生效的未开启分部的ocr，直接使用
            rs.executeQuery("select * from fnainvoiceinterface where interfaceType=0 and status=1 and subIdStatus=0 ");
            if(rs.next()){
                imageCatalog = Util.getIntValue(rs.getString("imageCatalog"),0);
                interfaceurl = Util.null2String(rs.getString("interfaceurl"));
                appKey = Util.null2String(rs.getString("username"));
                secret = Util.null2String(rs.getString("password"));
                existEffectOcr = true;
            }
            if(!existEffectOcr){
                //查询当前人员所在分部的ocr接口
                rs.executeQuery("select * from fnainvoiceinterface where interfaceType=0 and status=1 and subIdStatus=1 ");
                while (rs.next()){
                    String subIds = Util.null2String(rs.getString("subIds"));
                    String[] subIds_split = subIds.split(",");
                    for(int i=0;i<subIds_split.length;i++){
                        if(subIds_split[i].equals(String.valueOf(user.getUserSubCompany1()))){
                            imageCatalog = Util.getIntValue(rs.getString("imageCatalog"),0);
                            interfaceurl = Util.null2String(rs.getString("interfaceurl"));
                            appKey = Util.null2String(rs.getString("username"));
                            secret = Util.null2String(rs.getString("password"));
                            existEffectOcr = true;
                            break;
                        }
                    }
                    if(existEffectOcr){
                        break;
                    }
                }
            }
            JSONObject ocrJson = new JSONObject();
            ocrJson.put("existEffectOcr",existEffectOcr);
            ocrJson.put("imageCatalog",imageCatalog);
            ocrJson.put("interfaceurl",interfaceurl);
            ocrJson.put("appKey",appKey);
            ocrJson.put("secret",secret);
            resultJson.put("ocr",ocrJson);
        }


        if(queryCheck){
            String tokenURL = "";
            String openIdURL = "";
            String verifyURL = "";
            String client_id = "";
            String client_secret = "";
            String Client = "";
            String GTAXID = "";
            //如果有生效的未开启分部的查验接口，直接使用
            boolean existEffectCheck=false;


            rs.executeQuery("select * from fnainvoiceinterface where interfaceType=1 and status=1 and subIdStatus=0 ");
            if(rs.next()){
                tokenURL = Util.null2String(rs.getString("tokenURL"));
                openIdURL = Util.null2String(rs.getString("openIdURL"));
                verifyURL = Util.null2String(rs.getString("interfaceurl"));
                client_id = Util.null2String(rs.getString("client_id"));
                client_secret = FnaInvoiceCommon.fnaDecrypt(Util.null2String(rs.getString("client_secret")));
                Client = Util.null2String(rs.getString("Client"));
                GTAXID = Util.null2String(rs.getString("GTAXID"));
                existEffectCheck = true;
            }
            if(!existEffectCheck){
                //查询当前人员所在分部的查验接口
                rs.executeQuery("select * from fnainvoiceinterface where interfaceType=1 and status=1 and subIdStatus=1 ");
                while (rs.next()){
                    String subIds = Util.null2String(rs.getString("subIds"));
                    String[] subIds_split = subIds.split(",");
                    for(int i=0;i<subIds_split.length;i++){
                        if(subIds_split[i].equals(String.valueOf(user.getUserSubCompany1()))){
                            tokenURL = Util.null2String(rs.getString("tokenURL"));
                            openIdURL = Util.null2String(rs.getString("openIdURL"));
                            verifyURL = Util.null2String(rs.getString("interfaceurl"));
                            client_id = Util.null2String(rs.getString("client_id"));
                            client_secret = FnaInvoiceCommon.fnaDecrypt(Util.null2String(rs.getString("client_secret")));
                            Client = Util.null2String(rs.getString("Client"));
                            GTAXID = Util.null2String(rs.getString("GTAXID"));
                            existEffectCheck = true;
                            break;
                        }
                    }
                    if(existEffectCheck){
                        break;
                    }
                }
            }

            JSONObject checkJson = new JSONObject();
            checkJson.put("existEffectCheck",existEffectCheck);
            checkJson.put("tokenURL",tokenURL);
            checkJson.put("openIdURL",openIdURL);
            checkJson.put("verifyURL",verifyURL);
            checkJson.put("client_id",client_id);
            checkJson.put("client_secret",client_secret);
            checkJson.put("Client",Client);
            checkJson.put("GTAXID",GTAXID);
            resultJson.put("check",checkJson);
        }


        if(queryCloud){
            boolean existEffectCloud=false;//是否存在生效的发票云接口
            String userName="";
            String password="";
            String cid="";
            String jsUrl="";
            String jsUrlE10="";
            String javaUrl="";
            String webUrl = "";
            int imageCatalog = 0;
            String aesKey="";
            String e10TokenUrl = "";
            String openIDurl = "";
            String sqm = "";
            String oaUrl = "";
            //如果有生效的未开启分部的发票云接口，直接使用
            rs.executeQuery("select * from fnainvoiceinterface where interfaceType=2 and status=1 and subIdStatus=0 ");
            if(rs.next()){
                cid = Util.null2String(rs.getString("cid"));
                userName = Util.null2String(rs.getString("userName"));
                password = FnaInvoiceCommon.fnaDecrypt(Util.null2String(rs.getString("password")));
                jsUrl = Util.null2String(rs.getString("jsUrl"));
                jsUrlE10 = Util.null2String(rs.getString("client_id"));
                javaUrl = Util.null2String(rs.getString("javaUrl"));
                webUrl = Util.null2String(rs.getString("webUrl"));
                imageCatalog = Util.getIntValue(rs.getString("imageCatalog"),0);
                aesKey = Util.null2String(rs.getString("aesKey"));
                e10TokenUrl = Util.null2String(rs.getString("tokenurl"));
                oaUrl = Util.null2String(rs.getString("oaUrl"));
                openIDurl = Util.null2String(rs.getString("openIDurl"));
                sqm = Util.null2String(rs.getString("sqm"));
                existEffectCloud = true;
            }

            if(!existEffectCloud){
                //查询当前人员所在分部的发票云接口
                rs.executeQuery("select * from fnainvoiceinterface where interfaceType=2 and status=1 and subIdStatus=1 ");
                while (rs.next()){
                    String subIds = Util.null2String(rs.getString("subIds"));
                    String[] subIds_split = subIds.split(",");
                    for(int i=0;i<subIds_split.length;i++){
                        if(subIds_split[i].equals(String.valueOf(user.getUserSubCompany1()))){
                            cid = Util.null2String(rs.getString("cid"));
                            userName = Util.null2String(rs.getString("userName"));
                            password = FnaInvoiceCommon.fnaDecrypt(Util.null2String(rs.getString("password")));
                            jsUrl = Util.null2String(rs.getString("jsUrl"));
                            jsUrlE10 = Util.null2String(rs.getString("client_id"));
                            javaUrl = Util.null2String(rs.getString("javaUrl"));
                            webUrl = Util.null2String(rs.getString("webUrl"));
                            imageCatalog = Util.getIntValue(rs.getString("imageCatalog"),0);
                            aesKey = Util.null2String(rs.getString("aesKey"));
                            e10TokenUrl = Util.null2String(rs.getString("tokenurl"));
                            oaUrl = Util.null2String(rs.getString("oaUrl"));
                            openIDurl = Util.null2String(rs.getString("openIDurl"));
                            sqm = Util.null2String(rs.getString("sqm"));
                            existEffectCloud = true;
                            break;
                        }
                    }
                    if(existEffectCloud){
                        break;
                    }
                }
            }

            JSONObject cloudJson = new JSONObject();
            cloudJson.put("existEffectCloud",existEffectCloud);
            cloudJson.put("userName",userName);
            cloudJson.put("password",password);
            cloudJson.put("cid",cid);
            cloudJson.put("imageCatalog",imageCatalog);
            cloudJson.put("jsUrl",jsUrl);
            cloudJson.put("jsUrlE10",jsUrlE10);
            cloudJson.put("webUrl",webUrl);
            cloudJson.put("javaUrl",javaUrl);
            cloudJson.put("privatizationUrl",sqm);
            cloudJson.put("e10TokenUrl",e10TokenUrl);
            cloudJson.put("effectE10",openIDurl);
            cloudJson.put("oaUrl",oaUrl);
            JSONObject invoiceCloudUrl = getInvoiceCloudUrl();
            cloudJson.put("createCorpUrl",javaUrl+"/"+getString(invoiceCloudUrl,"createCorpUrl"));
            cloudJson.put("createAppUrl",javaUrl+"/"+getString(invoiceCloudUrl,"createAppUrl"));
            cloudJson.put("tokenUrl",javaUrl+"/"+getString(invoiceCloudUrl,"tokenUrl"));
            cloudJson.put("synInvoiceUrl",javaUrl+"/"+getString(invoiceCloudUrl,"synInvoiceUrl"));
            cloudJson.put("synBillingInfoUrl",javaUrl+"/"+getString(invoiceCloudUrl,"synBillingInfoUrl"));
            cloudJson.put("synDocUrl",javaUrl+"/"+getString(invoiceCloudUrl,"synDocUrl"));
            cloudJson.put("checkUrl",javaUrl+"/"+getString(invoiceCloudUrl,"checkUrl"));
            cloudJson.put("ocrUrl",javaUrl+"/"+getString(invoiceCloudUrl,"ocrUrl"));
            cloudJson.put("uploadFileUrl",javaUrl+"/"+getString(invoiceCloudUrl,"uploadFileUrl"));
            cloudJson.put("invoiceUsedNumberInfo",javaUrl+"/"+getString(invoiceCloudUrl,"invoiceUsedNumberInfo"));
            cloudJson.put("createAesKey",javaUrl+"/"+getString(invoiceCloudUrl,"createAesKey"));
            cloudJson.put("reimburseUrl",javaUrl+"/"+getString(invoiceCloudUrl,"reimburseUrl"));
            cloudJson.put("updateAppInfoUrl",javaUrl+"/"+getString(invoiceCloudUrl,"updateAppInfoUrl"));
            cloudJson.put("localCheckUrl",javaUrl+"/"+getString(invoiceCloudUrl,"localCheckUrl"));
            if("".equals(aesKey) && existEffectCloud){
                if("".equals(aesKey)){
                    JSONObject aesKeyJson = createAesKey(cloudJson.getString("createAesKey"), password, userName);
                    if(!aesKeyJson.getBoolean("flag")){
                        new BaseBean().writeLog("createAesKey失败"+aesKeyJson.getString("msg"));
                    }else{
                        JSONObject jsonData = aesKeyJson.getJSONObject("data");
                        aesKey = jsonData.getString("aesSecret");
                    }
                    rs.executeUpdate("update fnainvoiceinterface set aesKey=? where cid=?",aesKey,cid);
                }
            }
            cloudJson.put("aesKey",aesKey);
            resultJson.put("cloud",cloudJson);

        }

        return resultJson;
    }


    /**
     * 获取发票云接口域名后的地址后缀
     * @return
     */
    public static JSONObject getInvoiceCloudUrl(){
        RecordSet rs = new RecordSet();
        JSONObject jsonObject = new JSONObject();
        rs.executeQuery("select * from fnaInvoiceCloudUrl");
        while (rs.next()){
            String urlAddress = Util.null2String(rs.getString("urlAddress"));
            String sign = Util.null2String(rs.getString("sign"));
            jsonObject.put(sign,urlAddress);
        }
        return jsonObject;
    }

    /**
     * 获取发票相关权限，转为二进制
     * @param user
     * @return
     */
    public static int getInvoicePermissions(User user){
        int role=0;
        //微报账，发票接口接口配置，接口使用次数查询（包括接口使用查询和票据识别查询）,票据流程，发票去重校验设置，
        //邮件识别发票配置,票据项对应科目设置，连号发票报销控制,票据识别失败记录查询,
        //发票台账，企业台账,服务商设置，查验设置
        /*String permissionArray[]={"fnaMicroReport:setting","FnaInvoiceInterface:Set","FnaInvoiceUsedtimes:Query","FnaInvoiceReset:Permissions","FnainvoiceCheckControlLogic:Set",
        "FnaEmailInvoice:setting","FnaInvoiceSubject:Check","FnaSerialInvoiceControl:Set","FnaInvoiceFail:Check",
        "FnaInvoiceLedger:settings","FnaInvoiceLedger:settingsAll","fnaServiceprovider:Set","fnaInvoiceCheck:Set","fnaMicroReport:setting"};*/

        //使用权限：企业台账,我的票夹,接口使用次数查询,接口失败记录查询,
        // 识别查验记录查询,开票信息,发票云服务商设置,发票云查验设置,发票录入设置
        //预留权限 ：发票统计,报销设置
        //我的邮箱,勾选抵扣
        boolean isOpen = "0".equals(new BaseBean().getPropValue("fnaInvoiceLedgerSettings", "permission").trim());
        String permissionArray[]={"FnaInvoiceLedger:settingsAll","FnaInvoiceLedger:settings","FnaInvoiceUsedtimes:Query","FnaInvoiceFail:Check",
        "FnaInvoiceOcrCheck:Set","fnaMicroReport:setting","fnaServiceprovider:Set","fnaInvoiceCheck:Set","fnaMicroReport:setting",
        "fnaEmail:setting","fnaCheckDeduction:setting","FnaInvoiceLedger:FeeType","FnaInvoice:SmartReview"};
        for(int i=0;i<permissionArray.length;i++){
            boolean permission =  HrmUserVarify.checkUserRight(permissionArray[i], user);
            if("FnaInvoiceLedger:settings".equals(permissionArray[i]) && isOpen) {
            	permission = true;
            }
            if(permission){
                role = role+(int)Math.pow(2, i);
            }
        }
        return role;
    }
    /**
     * 获取发票云token，并回写至生效的发票云接口
     * @return
     */
    public static JSONObject getCloudToken(User user,String cid,String password,String userName,String tokenurl){
        JSONObject jsonObject  = new JSONObject();
        try{
            RecordSet rs = new RecordSet();



            //首先从表fnaInvoiceCloudToken中查询token,如果超过12小时，重新获取
            rs.executeQuery("select * from fnaInvoiceCloudToken where userId=?",user.getUID());
            if(rs.next()){
                String token = Util.null2String(rs.getString("token"));
                long currentTimeMillis = Long.valueOf(Util.null2String(rs.getString("currentTimeMillis")));
                long time = System.currentTimeMillis();
                if((time-currentTimeMillis)<1800000){//接口规定大于12小时 43200000,重新获取，  这块规定10小时重新获取，36000000，  30分钟获取一次1800000
                    jsonObject.put("flag",true);
                    jsonObject.put("token",token);
                    return jsonObject;
                }
            }

            //获取权限：
            int role = getInvoicePermissions(user);
            JSONObject param = new JSONObject();
            param.put("cid",cid);
            param.put("userId",user.getUID());
            param.put("name",user.getLastname());
            param.put("mobile",user.getMobile());
            param.put("role",role);
            param.put("deptid",user.getUserSubCompany1());
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","获取token",tokenurl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            String token = postToUrl(tokenurl, content, map, "",uuid);

            //将token存入表中
            boolean existHistory=false;
            rs.executeQuery("select * from fnaInvoiceCloudToken where userId=?",user.getUID());
            if(rs.next()){
                existHistory = true;
            }

            String time = Util.null2String(System.currentTimeMillis());
            String updateTime = Util.date(2);
            if(existHistory){//update
                rs.executeUpdate("update fnaInvoiceCloudToken set cid=?,token=?,updateTime=?,currentTimeMillis=?,eteamsIdEt=?,hostEt=? where userId=?",
                        cid,token,updateTime,time,"","",user.getUID());
            }else{//insert
                rs.executeUpdate("insert into fnaInvoiceCloudToken(cid,token,updateTime,currentTimeMillis,userId) values(?,?,?,?,?)",
                        cid,token,updateTime,time,user.getUID());
            }
            jsonObject.put("flag",true);
            jsonObject.put("token",token);
            jsonObject.put("appKey",userName);
            jsonObject.put("cid",cid);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }
    
    /**
     * 获取发票云token，并回写至生效的发票云接口
     * @return
     */
    public static JSONObject getCloudTokenE10(User user,String cid,String password,String userName,String tokenurl,String webUrl){
        JSONObject jsonObject  = new JSONObject();
        try{
            RecordSet rs = new RecordSet();
            
            //首先从表fnaInvoiceCloudToken中查询token,如果超过12小时，重新获取
            rs.executeQuery("select * from fnaInvoiceCloudToken where userId=?",user.getUID());
            if(rs.next()){
                String token = Util.null2String(rs.getString("token"));
                String eteamsId = Util.null2String(rs.getString("eteamsIdEt"));
                String host = Util.null2String(rs.getString("hostEt"));
                long currentTimeMillis = Long.valueOf(Util.null2String(rs.getString("currentTimeMillis")));
                long time = System.currentTimeMillis();
                if((time-currentTimeMillis)<1800000){//接口规定大于12小时 43200000,重新获取，  这块规定10小时重新获取，36000000，  30分钟获取一次1800000
                	if(!"".equals(eteamsId) && !"".equals(host)) {
                        jsonObject.put("flag",true);
                        jsonObject.put("token",token);
                        jsonObject.put("eteamsId",eteamsId);
                        jsonObject.put("host",host);
                        jsonObject.put("appKey",userName);
                        jsonObject.put("cid",cid);
                        return jsonObject;
                	}
                }
            }

            //获取权限：
            int role = getInvoicePermissions(user);
            JSONObject param = new JSONObject();
            param.put("cid",cid);
            param.put("userId",user.getUID());
            param.put("employeeId",user.getUID());
            param.put("name",user.getLastname());
            param.put("mobile",user.getMobile());
            param.put("name",user.getLastname());
            param.put("role",role);
            param.put("mail",user.getEmail());
            param.put("deptid",user.getUserDepartment());
            param.put("third",new ResourceComInfo().getWorkcode(String.valueOf(user.getUID())));
            
            String encoder = org.apache.commons.codec.binary.Base64.encodeBase64String(param.toString().getBytes("utf-8"));
            String content = invoiceCloudEncode(encoder, password);
            
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","获取token",tokenurl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            JSONObject returnJson = postToUrlToken(tokenurl, content, map, "",uuid,"",null,"");
            String token = returnJson.getString("token");
            String eteamsId = returnJson.getString("eteamsId");
            String host = returnJson.getString("host");
            
            //将token存入表中 
            boolean existHistory=false;
            rs.executeQuery("select * from fnaInvoiceCloudToken where userId=?",user.getUID());
            if(rs.next()){
                existHistory = true;
            }

            String time = Util.null2String(System.currentTimeMillis());
            String updateTime = Util.date(2);
            if(existHistory){//update
                rs.executeUpdate("update fnaInvoiceCloudToken set cid=?,token=?,updateTime=?,currentTimeMillis=?,eteamsIdEt=?,hostEt=? where userId=?",
                        cid,token,updateTime,time,eteamsId,host,user.getUID());
            }else{//insert
                rs.executeUpdate("insert into fnaInvoiceCloudToken(cid,token,updateTime,currentTimeMillis,userId,eteamsIdEt,hostEt) values(?,?,?,?,?,?,?)",
                        cid,token,updateTime,time,user.getUID(),eteamsId,host);
            }
            
            jsonObject.put("flag",true);
            jsonObject.put("token",token);
            jsonObject.put("eteamsId",eteamsId);
            jsonObject.put("host",host);
            jsonObject.put("appKey",userName);
            jsonObject.put("cid",cid);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }
    

    /**
     * 获取cid
     * @return
     */
    public static JSONObject getCloudCid(String interfaceurl,String account,String corpName,String userName,String password){
        JSONObject jsonObject = new JSONObject();
        try{
            JSONObject param = new JSONObject();
            param.put("account",account);
            param.put("corpName",corpName);
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","获取CID",interfaceurl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            String cid = postToUrl(interfaceurl, content, map, "",uuid);
            jsonObject.put("flag",true);
            jsonObject.put("cid",cid);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 更新应用数据
     * @return
     */
    public static JSONObject updateAppInfo(String updateAppInfoUrl,String account,String oaUrl,String userName,String password){
        JSONObject jsonObject = new JSONObject();
        try{
            JSONObject param = new JSONObject();
            param.put("appName",account);
            param.put("thirdAddr",oaUrl);
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","更新应用数据",updateAppInfoUrl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            postToUrl(updateAppInfoUrl, content, map, "",uuid);
            jsonObject.put("flag",true);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 创建应用，获取AppId 和 secret
     * @param interfaceurl
     * @param appName
     * @return
     */
    public static JSONObject CreateApp(String interfaceurl,String appName,String thirdAppId,String thirdAddr){
        JSONObject jsonObject = new JSONObject();
        try{
            JSONObject param = new JSONObject();
            param.put("appName",appName);
            param.put("appType",2);
            param.put("thirdAppId",thirdAppId);
            param.put("thirdAddr",thirdAddr);
            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl) values(?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","创建应用",interfaceurl);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            String data = postToUrl(interfaceurl, param.toString(), null, "",uuid);
            new BaseBean().writeLog("data>>>>>>>>>>", data);
            jsonObject.put("flag",true);
            jsonObject.put("data",data);
        }catch (Exception e){
        	java.io.ByteArrayOutputStream outsss = null;
            java.io.PrintStream pout = null;
            String ret = "";
            try {
                outsss = new java.io.ByteArrayOutputStream();
                pout = new java.io.PrintStream(outsss);
                e.printStackTrace(pout);
                ret = new String(outsss.toByteArray());
                outsss.close();
            } catch (Exception eeeee) {

            } finally {
                if (pout != null) {
                    pout.close();
                }
            }
            new BaseBean().writeLog("ret>>>>>>>>>>", ret);
        	
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 同步开票信息、同步发票信息
     * @param interfaceurl
     * @param param
     * @param userName
     * @param password
     * @return
     */
    public static JSONObject synBillingInfo(String interfaceurl,JSONObject param,String userName,String password){
        JSONObject jsonObject = new JSONObject();
        try{
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","实时同步开票、发票信息",interfaceurl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            String data = postToUrl(interfaceurl, content, map, "",uuid);
            jsonObject.put("flag",true);
            jsonObject.put("data",data);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 推送目录id
     * @param synDocUrl
     * @param cid
     * @param secid
     * @param userName
     * @param password
     * @return
     */
    public static JSONObject pushSecid(String synDocUrl,String cid,String secid,String userName,String password,int userId){
        JSONObject jsonObject = new JSONObject();
        try{
            JSONObject param = new JSONObject();
            param.put("cid",cid);
            param.put("secid",secid);
            param.put("userId",userId);
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","同步目录",synDocUrl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            postToUrl(synDocUrl, content, map, "",uuid);
            jsonObject.put("flag",true);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }


    /**
     * 获取json中的值
     * @param json
     * @param key
     * @return
     */
    public static String getString(JSONObject json, String  key){
        if(json.containsKey(key)){
            return json.getString(key);
        }else{
            return "";
        }
    }


    public static String postToUrl(String url, String content,Map<String, String> headers,String xmlEncoding,String uuid,String aesKey) throws Exception {
        return postToUrl(url,content,headers,xmlEncoding,uuid,"",null,aesKey);
    }
    public static String postToUrl(String url, String content,Map<String, String> headers,String xmlEncoding,String uuid) throws Exception {
        return postToUrl(url,content,headers,xmlEncoding,uuid,"",null,"");
    }
    /**
     *
     * @param url
     * @param content
     * @param headers
     * @param xmlEncoding
     * @return
     * @throws IOException
     */
    public static String postToUrl(String url, String content,Map<String, String> headers,String xmlEncoding,String uuid,String from,User user,String aesKey) throws Exception {
        String errorMsg="";

        String data="";
        if("".equals(xmlEncoding)){
            xmlEncoding = "UTF-8";
        }
        DefaultHttpClient httpclient = null;
        HttpPost httpPost = null;
        try {
            httpclient = new DefaultHttpClient();
            if(ProxyUtil.ifExistsProxy()){
                Map<String, String> proxyProperty = ProxyUtil.getProxyProperty();
                String proxyUrl = proxyProperty.getOrDefault("proxyUrl","");
                int proxyPort = Util.getIntValue(proxyProperty.getOrDefault("proxyPort",""),8080);
                String proxyUser = proxyProperty.getOrDefault("proxyUser","");
                String proxyPwd = proxyProperty.getOrDefault("proxyPwd","");

                if(!"".equals(proxyUser)&&!"".equals(proxyPwd)) {
                    httpclient.getCredentialsProvider().setCredentials(
                            new AuthScope(proxyUrl, proxyPort),
                            new UsernamePasswordCredentials(proxyUser, proxyPwd)
                    );
                }
                HttpHost proxy = new HttpHost(proxyUrl,proxyPort);
                httpclient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,proxy);
            }

            httpPost = new HttpPost(url);
            JSONObject response = null;
            StringEntity s = new StringEntity(content, Charset.forName("UTF-8"));
            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
            httpPost.addHeader("Accept", "application/json");

            //设置超时时间
            RequestConfig config = RequestConfig.custom().setConnectTimeout(130000) //连接超时时间
                        .setConnectionRequestTimeout(130000)
                        .setSocketTimeout(130000) //数据传输的超时时间
                        .setStaleConnectionCheckEnabled(true) //提交请求前测试连接是否可用
                        .build();



            httpPost.setConfig(config);
            httpPost.setEntity(s);

            if (null != headers) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            HttpResponse res = httpclient.execute(httpPost);
            new BaseBean().writeLog("code>>>>>>>>>>", res.getStatusLine().getStatusCode());
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = res.getEntity();
                String result = Util.null2String(EntityUtils.toString(res.getEntity()));

                new BaseBean().writeLog("result>>>>>>>>>>", result);
                FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", result, "uuid", uuid, "string");
                if ("".equals(result)) {
                    throw new Exception("发票云接口返回空！");
                }
                try {
                    response = JSONObject.fromObject(result);
                } catch (Exception e) {
                    throw new Exception("发票云接口返参数json格式化异常！");
                }
                JSONObject actionMsg = response.getJSONObject("actionMsg");
                String code = actionMsg.getString("code");
                if ("0".equals(code)) {//创建成功
                    if (response.containsKey("data")) {
                        data = response.getString("data");

                        //新接口，需要解密
                        if (!"".equals(aesKey) && !"".equals(data)) {
                            data = InvoiceCloudAESUtil.decrypt(aesKey, data);
                            response.put("data", data);
                            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", response.toString(), "uuid", uuid, "string");
                        }
                    }
                } else {
                    errorMsg = actionMsg.getString("message");
                    if ("check".equals(from)) {
                        new BaseBean().writeLog("checkException", errorMsg);
                        FnaInvoiceCommon.saveFailLog(user.getUID(), 1, errorMsg);
                    }
                    throw new Exception(errorMsg);
                }
            } else {
                FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", "请求失败HttpStatus=" + res.getStatusLine().getStatusCode(), "uuid", uuid, "string");
                throw new Exception("请求失败！");
            }
        }catch (Exception e){
            errorMsg = e.getMessage();
            
        	java.io.ByteArrayOutputStream outsss = null;
            java.io.PrintStream pout = null;
            String ret = "";
            try {
                outsss = new java.io.ByteArrayOutputStream();
                pout = new java.io.PrintStream(outsss);
                e.printStackTrace(pout);
                ret = new String(outsss.toByteArray());
                outsss.close();
            } catch (Exception eeeee) {

            } finally {
                if (pout != null) {
                    pout.close();
                }
            }
            new BaseBean().writeLog("ret2>>>>>>>>>>", ret);
        }finally {
            if(httpclient!=null){
                httpclient.close();
            }
        }
        if(!"".equals(errorMsg)){
            throw new Exception(errorMsg);
        }
        return data;
    }
    
    
    /**
    *
    * @param url
    * @param content
    * @param headers
    * @param xmlEncoding
    * @return
    * @throws IOException
    */
   public static JSONObject postToUrlToken(String url, String content,Map<String, String> headers,String xmlEncoding,String uuid,String from,User user,String aesKey) throws Exception {
       String errorMsg="";

       JSONObject data = new JSONObject();
       if("".equals(xmlEncoding)){
           xmlEncoding = "UTF-8";
       }
       DefaultHttpClient httpclient = null;
       HttpPost httpPost = null;
       try {
           httpclient = new DefaultHttpClient();
           if(ProxyUtil.ifExistsProxy()){
               Map<String, String> proxyProperty = ProxyUtil.getProxyProperty();
               String proxyUrl = proxyProperty.getOrDefault("proxyUrl","");
               int proxyPort = Util.getIntValue(proxyProperty.getOrDefault("proxyPort",""),8080);
               String proxyUser = proxyProperty.getOrDefault("proxyUser","");
               String proxyPwd = proxyProperty.getOrDefault("proxyPwd","");

               if(!"".equals(proxyUser)&&!"".equals(proxyPwd)) {
                   httpclient.getCredentialsProvider().setCredentials(
                           new AuthScope(proxyUrl, proxyPort),
                           new UsernamePasswordCredentials(proxyUser, proxyPwd)
                   );
               }
               HttpHost proxy = new HttpHost(proxyUrl,proxyPort);
               httpclient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,proxy);
           }

           httpPost = new HttpPost(url);
           JSONObject response = null;
           StringEntity s = new StringEntity(content, Charset.forName("UTF-8"));
           httpPost.addHeader("Content-type", "application/json; charset=utf-8");
           httpPost.addHeader("Accept", "application/json");

           //设置超时时间
           RequestConfig config = RequestConfig.custom().setConnectTimeout(130000) //连接超时时间
                       .setConnectionRequestTimeout(130000)
                       .setSocketTimeout(130000) //数据传输的超时时间
                       .setStaleConnectionCheckEnabled(true) //提交请求前测试连接是否可用
                       .build();



           httpPost.setConfig(config);
           httpPost.setEntity(s);

           if (null != headers) {
               for (Map.Entry<String, String> entry : headers.entrySet()) {
                   httpPost.addHeader(entry.getKey(), entry.getValue());
               }
           }
           HttpResponse res = httpclient.execute(httpPost);
           if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
               HttpEntity entity = res.getEntity();
               String result = Util.null2String(EntityUtils.toString(res.getEntity()));
               FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", result, "uuid", uuid, "string");
               if ("".equals(result)) {
                   throw new Exception("发票云接口返回空！");
               }
               
               // 解密
               result = new String(new BASE64Decoder().decodeBuffer(result));
               
               try {
                   response = JSONObject.fromObject(result);
               } catch (Exception e) {
                   throw new Exception("发票云接口返参数json格式化异常！");
               }
               
               String eteamsId = response.containsKey("eteamsId")?response.getString("eteamsId"):"";
               String token = response.containsKey("token")?response.getString("token"):"";
               String host = response.containsKey("host")?response.getString("host"):"";
               String cid = response.containsKey("cid")?response.getString("cid"):"";
               data.put("eteamsId", eteamsId);
               data.put("token", token);
               data.put("host", host);
               data.put("cid", cid);
           } else {
               FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", "请求失败HttpStatus=" + res.getStatusLine().getStatusCode(), "uuid", uuid, "string");
               throw new Exception("请求失败！");
           }
       }catch (Exception e){
           errorMsg = e.getMessage();
       }finally {
           if(httpclient!=null){
               httpclient.close();
           }
       }
       if(!"".equals(errorMsg)){
           throw new Exception(errorMsg);
       }
       return data;
   }

    /**
     * 发票云加密
     * @param content
     * @param secret
     * @return
     */
    public static  String invoiceCloudEncode(String content,String secret){
        long time = System.currentTimeMillis();
        content = content+"&time="+time;
        String md5Content = Md5Encode(content + "&secret=" + secret);
        content = content+"&md5="+md5Content;
        return content;
    }

    /**
     * 发票云加密
     * @param content
     * @param secret
     * @return
     */
    public static  String invoiceCloudEncode(String content,String secret,long time){
        content = content+"&time="+time;
        String md5Content = Md5Encode(content + "&secret=" + secret);
        return md5Content;
    }

    /**
     * md5加密
     * @param content
     * @return
     */
    public static String Md5Encode(String content){
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        try {
            byte[] btInput = content.getBytes("UTF-8");
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据sql获取发票信息
     * @return
     */
    public static JSONArray getInvoiceInfos(String sql,int start_pos,int page_size){
        DecimalFormat df = new DecimalFormat("#############################0.00");
        JSONArray invoiceArray = new JSONArray();
        RecordSet rs = new RecordSet();
        RecordSet rs2 = new RecordSet();
        RecordSet rs3 = new RecordSet();
        RecordSet rs4 = new RecordSet();
        String fnainvoiceledger[] = {"id","billingDate","invoiceCode","invoiceNumber","invoiceType","seller","purchaser","invoiceServiceYype",
                "priceWithoutTax","taxRate","tax","taxIncludedPrice","authenticity","reimbursementDate","reimbursePerson","requestId","userid_new",
                "invoiceSource_new","checkcode","status","card_id_new","encrypt_code_new","openid_new","wechatstatus","imageID","purchaserTaxNo","salesTaxNo",
                "entryTime","company_seal","form_type","form_name","kind","category","imageDocId","checkStatus","updateOperate","cloudId","codeConfirm","numberConfirm","requestName",
                "receiptor","reviewer","issuer","province","city","travel_tax","fylx","purp","iele","orf","lian_id","dTax","ic",
                "custom_Field_1","custom_Field_2","custom_Field_3","custom_Field_4","custom_Field_5"};
        String fnainvoiceledgerdetail[]={"invoiceserviceyype","specification","unit","unitNumber2","originalUnitPrice","priceWithoutTax","taxRate","tax","startDate","endDate","numberPlate","type"};
        String fnaInvoiceLedgerDtl[]={"remark","checkCodeSix","sellerAddress","purchaserAddress","salesBank","purchaserBank","issuer","oilMark","highwayFlag","transit","reviewer","receiptor"};
        String trainInvoice[]={"time","name","station_geton","station_getoff","train_number","seat"};
        String taxiInvoice[]={"time_geton","time_getoff","mileage","place","license_plate"};
        String machineInvoice[]={"time","category","seller_tax_id","buyer_tax_id"};
        String tollInvoice[]={"time","entrance","export"};
        String carInvoice[]={"time","station_geton","station_getoff","name"};
        String second_carInvoice[]={"seller_id","buyer_id","company_name","company_tax_id","license_plate","registration_number","car_code","car_model"};
        String motor_VehicleInvoice[]={"machine_code","machine_number","pretax_amount","seller_tax_id","buyer_id","tax_authorities","tax_authorities_code",
        "car_code","car_engine_code","car_model","certificate_number"};
        String airInvoice[]={"user_name","user_id","agentcode","issue_by","fare","fuel_surcharge","caac_development_fund","insurance"};
        String airDtlInvoice[]={"from_city","to_city","flight_number","airdate","airtime","seat","carrier"};
        String smallInvoice[]={"storename","time","tips","currency_code","type","discount"};

        String fnaDidiInvoice[]={"startDate","endDate","phone"};
        String fnaDidiDtlInvoice[]={"carType","time_geton","city","station_geton","station_getoff","mileage","total"};
        String fnaBoatInvoice[]={"time","station_geton","station_getoff","name","currency_code"};

        //报销状况
        String fnaInvoiceReimbursement[]={"requestid","reimbursementAmt","userid","reimbursementDate","requestName"};

        int start=0;
        rs.executeQuery(sql);
        while (rs.next()){
            if(start>=start_pos && page_size>0 ) {
                JSONObject fnainvoiceledgerJo = new JSONObject();
                int id = Util.getIntValue(rs.getString("id"), 0);
                int invoiceType = Util.getIntValue(rs.getString("invoiceType"), 0);
                int requestId = Util.getIntValue(rs.getString("requestId"), 0);
                for (int i = 0; i < fnainvoiceledger.length; i++) {
                    String key = fnainvoiceledger[i];
                    if("requestName".equals(key)){
                        String requestName="";
                        if(requestId>0){
                            rs2.executeQuery("select  requestName from workflow_requestBase where requestId=?",requestId);
                            if(rs2.next()){
                                requestName = Util.null2String(rs2.getString("requestName"));
                            }
                        }
                        fnainvoiceledgerJo.put("requestName",requestName);
                    }else if("travel_tax".equals(key)){
                        fnainvoiceledgerJo.put("travelTax", Util.null2String(rs.getString(key)));
                    }else{
                    	if(key.contains("custom_Field_")) {
                    		key = key.replaceAll("_", "");
                    	}
                        fnainvoiceledgerJo.put(key, Util.null2String(rs.getString(key)));
                    }
                }

                JSONArray fnainvoiceledgerdetailJa = new JSONArray();
                rs2.executeQuery("select * from fnainvoiceledgerdetail where mainid=?", id);
                while (rs2.next()) {
                    JSONObject fnainvoiceledgerdetailJo = new JSONObject();
                    for (int i = 0; i < fnainvoiceledgerdetail.length; i++) {
                        String key = fnainvoiceledgerdetail[i];
                        fnainvoiceledgerdetailJo.put(key, Util.null2String(rs2.getString(key)));
                    }
                    fnainvoiceledgerdetailJa.add(fnainvoiceledgerdetailJo);
                }
                fnainvoiceledgerJo.put("fnainvoiceledgerdetail", fnainvoiceledgerdetailJa);
                if (invoiceType == 1 || invoiceType == 2 || invoiceType == 15 || invoiceType == 16 || invoiceType == 12
                        || invoiceType == 3 || invoiceType == 17 || invoiceType == 19 || invoiceType == 20 || invoiceType == 21
                        || invoiceType == 32 || invoiceType == 33) {
                    rs3.executeQuery("select * from FnaInvoiceLedgerDtl where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject FnaInvoiceLedgerDtlJo = new JSONObject();
                        for (int i = 0; i < fnaInvoiceLedgerDtl.length; i++) {
                            String key = fnaInvoiceLedgerDtl[i];
                            FnaInvoiceLedgerDtlJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("fnaInvoiceLedgerDtl", FnaInvoiceLedgerDtlJo);
                    }
                }
                if (invoiceType == 8) {//火车票
                    rs3.executeQuery("select * from trainInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject trainInvoiceJo = new JSONObject();
                        for (int i = 0; i < trainInvoice.length; i++) {
                            String key = trainInvoice[i];
                            trainInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("trainInvoice", trainInvoiceJo);
                    }
                } else if (invoiceType == 7) {//出租车发票
                    rs3.executeQuery("select * from taxiInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject taxiInvoiceJo = new JSONObject();
                        for (int i = 0; i < taxiInvoice.length; i++) {
                            String key = taxiInvoice[i];
                            taxiInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("taxiInvoice", taxiInvoiceJo);
                    }
                } else if (invoiceType == 3) {//通用机打发票
                    rs3.executeQuery("select * from machineInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject machineInvoiceJo = new JSONObject();
                        for (int i = 0; i < machineInvoice.length; i++) {
                            String key = machineInvoice[i];
                            machineInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("machineInvoice", machineInvoiceJo);
                    }
                } else if (invoiceType == 9) {//过路费发票表
                    rs3.executeQuery("select * from tollInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject tollInvoiceJo = new JSONObject();
                        for (int i = 0; i < tollInvoice.length; i++) {
                            String key = tollInvoice[i];
                            tollInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("tollInvoice", tollInvoiceJo);
                    }
                } else if (invoiceType == 10) {//客运汽车发票
                    rs3.executeQuery("select * from carInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject carInvoiceJo = new JSONObject();
                        for (int i = 0; i < carInvoice.length; i++) {
                            String key = carInvoice[i];
                            carInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("carInvoice", carInvoiceJo);
                    }
                } else if (invoiceType == 11) {//二手车销售统一发票表
                    rs3.executeQuery("select * from second_carInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject second_carInvoiceJo = new JSONObject();
                        for (int i = 0; i < second_carInvoice.length; i++) {
                            String key = second_carInvoice[i];
                            second_carInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("second_carInvoice", second_carInvoiceJo);
                    }
                } else if (invoiceType == 12) {//机动车销售统一发票
                    rs3.executeQuery("select * from motor_VehicleInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject motor_VehicleInvoiceJo = new JSONObject();
                        for (int i = 0; i < motor_VehicleInvoice.length; i++) {
                            String key = motor_VehicleInvoice[i];
                            motor_VehicleInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("motor_VehicleInvoice", motor_VehicleInvoiceJo);
                    }
                } else if (invoiceType == 14) {//航空运输电子客票行程单
                    rs3.executeQuery("select * from airInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject airInvoiceJo = new JSONObject();
                        for (int i = 0; i < airInvoice.length; i++) {
                            String key = airInvoice[i];
                            airInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("airInvoice", airInvoiceJo);
                    }

                    rs3.executeQuery("select * from airDtlInvoice where mainid=?", id);
                    JSONArray airDtlInvoiceJa = new JSONArray();
                    while (rs3.next()) {
                        JSONObject airDtlInvoiceJo = new JSONObject();
                        for (int i = 0; i < airDtlInvoice.length; i++) {
                            String key = airDtlInvoice[i];
                            airDtlInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        airDtlInvoiceJa.add(airDtlInvoiceJo);
                    }
                    fnainvoiceledgerJo.put("airDtlInvoice", airDtlInvoiceJa);
                } else if (invoiceType == 13) {//国际小票
                    rs3.executeQuery("select * from smallInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject smallInvoiceJo = new JSONObject();
                        for (int i = 0; i < smallInvoice.length; i++) {
                            String key = smallInvoice[i];
                            smallInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("smallInvoice", smallInvoiceJo);
                    }
                } else if (invoiceType == 22) {//船票
                    rs3.executeQuery("select * from fnaBoatInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject fnaBoatInvoiceJo = new JSONObject();
                        for (int i = 0; i < fnaBoatInvoice.length; i++) {
                            String key = fnaBoatInvoice[i];
                            fnaBoatInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("fnaBoatInvoice", fnaBoatInvoiceJo);
                    }
                } else if (invoiceType == 23) {//滴滴出行行程单
                	rs3.executeQuery("select * from fnaDidiInvoice where mainid=?", id);
                    if (rs3.next()) {
                        JSONObject fnaDidiInvoiceJo = new JSONObject();
                        for (int i = 0; i < fnaDidiInvoice.length; i++) {
                            String key = fnaDidiInvoice[i];
                            fnaDidiInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnainvoiceledgerJo.put("fnaDidiInvoice", fnaDidiInvoiceJo);
                    }

                    rs3.executeQuery("select * from fnaDidiDtlInvoice where mainid=?", id);
                    JSONArray fnaDidiDtlInvoiceJa = new JSONArray();
                    while (rs3.next()) {
                        JSONObject fnaDidiDtlInvoiceJo = new JSONObject();
                        for (int i = 0; i < fnaDidiDtlInvoice.length; i++) {
                            String key = fnaDidiDtlInvoice[i];
                            fnaDidiDtlInvoiceJo.put(key, Util.null2String(rs3.getString(key)));
                        }
                        fnaDidiDtlInvoiceJa.add(fnaDidiDtlInvoiceJo);
                    }
                    fnainvoiceledgerJo.put("fnaDidiDtlInvoice", fnaDidiDtlInvoiceJa);
                }

                JSONArray fnaInvoiceReimbursementJa = new JSONArray();
                rs3.executeQuery("select * from fnaInvoiceReimbursement where mainid=?", id);
                while (rs3.next()) {
                    int requestid3 = Util.getIntValue(rs3.getString("requestId"),0);
                    JSONObject fnaInvoiceReimbursementJo = new JSONObject();
                    for (int i = 0; i < fnaInvoiceReimbursement.length; i++) {
                        String key = fnaInvoiceReimbursement[i];
                        if("requestName".equals(key)){
                            String requestName="";
                            if(requestid3>0){
                                rs4.executeQuery("select  requestName from workflow_requestBase where requestId=?",requestid3);
                                if(rs4.next()){
                                    requestName = Util.null2String(rs4.getString("requestName"));
                                }
                            }
                            fnaInvoiceReimbursementJo.put("requestName",requestName);
                        }else{
                            fnaInvoiceReimbursementJo.put(key, Util.null2String(rs3.getString(key)));
                        }

                    }
                    fnaInvoiceReimbursementJa.add(fnaInvoiceReimbursementJo);
                }
                fnainvoiceledgerJo.put("fnaInvoiceReimbursement", fnaInvoiceReimbursementJa);
                invoiceArray.add(fnainvoiceledgerJo);
                page_size--;
            }
            start++;

        }
        return invoiceArray;
    }

    /**
     * 实时同步更新发票信息
     * @param infoJson
     * @return cloudId和id
     */
    public static JSONObject updateInvoiceInfo(JSONObject infoJson,String ipAdress) throws Exception {
        JSONObject jsonObject = new JSONObject();

        String fnainvoiceledger[] = {"billingDate","invoiceCode","invoiceNumber","invoiceType","seller","purchaser","invoiceServiceYype",
                "priceWithoutTax","taxRate","tax","taxIncludedPrice","authenticity","userid_new",//"reimbursementDate","reimbursePerson","requestId" 报销信息无需从发票云获取
                "invoiceSource_new","checkcode","status","card_id_new","encrypt_code_new","openid_new","wechatstatus","imageID","purchaserTaxNo","salesTaxNo",
                "entryTime","company_seal","form_type","form_name","kind","category","imageDocId","checkStatus","updateOperate","cloudId","codeConfirm","numberConfirm",
                "receiptor","reviewer","issuer","province","city","travel_tax","fylx","purp","iele","orf","lian_id","dTax","ic",
                "custom_Field_1","custom_Field_2","custom_Field_3","custom_Field_4","custom_Field_5"};
        String fnainvoiceledgerdetail[]={"invoiceserviceyype","specification","unit","unitNumber2","originalUnitPrice","priceWithoutTax","taxRate","tax","startDate","endDate","numberPlate","type"};
        String fnaInvoiceLedgerDtl[]={"remark","checkCodeSix","sellerAddress","purchaserAddress","salesBank","purchaserBank","issuer","oilMark","highwayFlag","transit","reviewer","receiptor"};
        String trainInvoice[]={"time","name","station_geton","station_getoff","train_number","seat"};
        String taxiInvoice[]={"time_geton","time_getoff","mileage","place","license_plate"};
        String machineInvoice[]={"time","category","seller_tax_id","buyer_tax_id"};
        String tollInvoice[]={"time","entrance","export"};
        String carInvoice[]={"time","station_geton","station_getoff","name"};
        String second_carInvoice[]={"seller_id","buyer_id","company_name","company_tax_id","license_plate","registration_number","car_code","car_model"};
        String motor_VehicleInvoice[]={"machine_code","machine_number","pretax_amount","seller_tax_id","buyer_id","tax_authorities","tax_authorities_code",
                "car_code","car_engine_code","car_model","certificate_number"};
        String airInvoice[]={"user_name","user_id","agentcode","issue_by","fare","fuel_surcharge","caac_development_fund","insurance"};
        String airDtlInvoice[]={"from_city","to_city","flight_number","airdate","airtime","seat","carrier"};
        String smallInvoice[]={"storename","time","tips","currency_code","type","discount"};

        String fnaDidiInvoice[]={"startDate","endDate","phone"};
        String fnaDidiDtlInvoice[]={"carType","time_geton","city","station_geton","station_getoff","mileage","total"};
        String fnaBoatInvoice[]={"time","station_geton","station_getoff","name","currency_code"};
        String FnaBillSummaryInfo[]={"bDate","eDate","info","invoice_number","invoice_code","invoice_no","amount","rate","tax","trip_number"};

        String formatDoubleColumn="priceWithoutTax,taxRate,tax,taxIncludedPrice,mileage,pretax_amount,travel_tax,total,dTax";//需要格式化金额的列，用逗号隔开
        List<String> formatDoubleList = Arrays.asList(formatDoubleColumn.split(","));

        String formatIntColumn="invoiceType,authenticity,reimbursePerson,requestId,userid_new,invoiceSource_new," +
                "status,imageID,company_seal,imageDocId,checkStatus,updateOperate";
        List<String> formatIntList = Arrays.asList(formatIntColumn.split(","));

        int id = Util.getIntValue(infoJson.getString("id"),0);


        String cloudId= Util.null2String(infoJson.getString("cloudId"));
        int invoiceType = Util.getIntValue(infoJson.getString("invoiceType"),0);
        int userid_new = Util.getIntValue(infoJson.getString("userid_new"),0);
        String invoiceNumber= Util.null2String(infoJson.getString("invoiceNumber"));
        String invoiceCode= Util.null2String(infoJson.getString("invoiceCode"));
        RecordSet rs = new RecordSet();
        List<String>valueList =new ArrayList<String>();

        //脏数据优化
        if(id==0){
            rs.executeQuery("select id from fnainvoiceLedger where invoicenumber=? and invoiceCode=?",invoiceNumber,invoiceCode);
            if(rs.next()){
                id = Util.getIntValue(rs.getString("id"),0);
            }
        }else{
            //判断该id在台账中是否存在
            int cnt = 0;
            rs.executeQuery("select count(id) cnt from fnainvoiceLedger where id=?",id);
            if(rs.next()){
                cnt= Util.getIntValue(rs.getString("cnt"),0);
            }
            if(cnt==0){
                id=0;
            }
        }

        //插入日志1
        FnaLogSqlUtil fnaLogSqlUtil = new FnaLogSqlUtil();
        Map<String, String> labelIdMap = new HashMap<String, String>();
        Map<String, String> beforeMap = new HashMap<String, String>();
        String opType="0";
        if(id>0){
            opType="2";
            beforeMap = fnaLogSqlUtil.getInvoiceMap(String.valueOf(id),labelIdMap);
        }

        //修改主表数据 fnainvoiceledger
        String sql = getsqlByColumn(id, fnainvoiceledger, infoJson, valueList, formatDoubleList,formatIntList,"fnainvoiceledger");
        rs.executeUpdate(sql,valueList);
        if(id<=0){
            rs.executeQuery("select id from fnainvoiceledger where cloudId=?",cloudId);
            if(rs.next()){
                id = Util.getIntValue(rs.getString("id"));
            }
        }
        
        rs.executeQuery("select imageid from fnainvoiceledger where id = ?",id);
        if(rs.next()) {
        	int imageid = Util.getIntValue(rs.getString("imageid"),0);
        	if(imageid <= 0) {
        		rs.executeUpdate("update fnainvoiceledger set imageid = NULL,imagedocid = NULL where id = ?", id);
        	}
        }

        //修改明细表数据 fnainvoiceledgerdetail
        rs.executeUpdate("delete from fnainvoiceledgerdetail where mainid=?", id);
        if (infoJson.containsKey("fnainvoiceledgerdetail")) {
            String fnainvoiceledgerdetailStr = infoJson.getString("fnainvoiceledgerdetail");
            if (fnainvoiceledgerdetailStr != null && !"".equals(fnainvoiceledgerdetailStr)) {
                JSONArray infoJsonArray = infoJson.getJSONArray("fnainvoiceledgerdetail");
                for (int i = 0; i < infoJsonArray.size(); i++) {
                    JSONObject infoJsonDtl = infoJsonArray.getJSONObject(i);
                    if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                        sql = getsqlByColumn(id, fnainvoiceledgerdetail, infoJsonDtl, valueList, formatDoubleList, formatIntList, "fnainvoiceledgerdetail");
                        rs.executeUpdate(sql, valueList);
                    }
                }
            }

        }

        if (invoiceType == 1 || invoiceType == 2 || invoiceType == 15 || invoiceType == 16 || invoiceType == 12
                || invoiceType == 3 || invoiceType == 17 || invoiceType == 19 || invoiceType == 20 || invoiceType == 21
                || invoiceType == 32 || invoiceType == 33) {
            //修改明细表数据 fnaInvoiceLedgerDtl
            rs.executeUpdate("delete from fnaInvoiceLedgerDtl where mainid=?", id);
            if (infoJson.containsKey("fnaInvoiceLedgerDtl")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("fnaInvoiceLedgerDtl");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, fnaInvoiceLedgerDtl, infoJsonDtl, valueList, formatDoubleList, formatIntList, "fnaInvoiceLedgerDtl");
                    rs.executeUpdate(sql, valueList);
                }
            }
        }
        if (invoiceType == 8) {//火车票
            //修改明细表数据 trainInvoice
            rs.executeUpdate("delete from trainInvoice where mainid=?", id);
            if (infoJson.containsKey("trainInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("trainInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, trainInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "trainInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 7) {//出租车发票
            //修改明细表数据 taxiInvoice
            rs.executeUpdate("delete from taxiInvoice where mainid=?", id);
            if (infoJson.containsKey("taxiInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("taxiInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, taxiInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "taxiInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 3) {//通用机打发票
            //修改明细表数据 machineInvoice
            rs.executeUpdate("delete from machineInvoice where mainid=?", id);
            if (infoJson.containsKey("machineInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("machineInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, machineInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "machineInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 9) {//过路费发票表
            //修改明细表数据 tollInvoice
            rs.executeUpdate("delete from tollInvoice where mainid=?", id);
            if (infoJson.containsKey("tollInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("tollInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, tollInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "tollInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 10) {//客运汽车发票
            //修改明细表数据 carInvoice
            rs.executeUpdate("delete from carInvoice where mainid=?", id);
            if (infoJson.containsKey("carInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("carInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, carInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "carInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 11) {//二手车销售统一发票表
            //修改明细表数据 second_carInvoice
            rs.executeUpdate("delete from second_carInvoice where mainid=?", id);
            if (infoJson.containsKey("second_carInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("second_carInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, second_carInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "second_carInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 12) {//机动车销售统一发票
            //修改明细表数据 motor_VehicleInvoice
            rs.executeUpdate("delete from motor_VehicleInvoice where mainid=?", id);
            if (infoJson.containsKey("motor_VehicleInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("motor_VehicleInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, motor_VehicleInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "motor_VehicleInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 14) {//航空运输电子客票行程单
            //修改明细表数据 airInvoice
            rs.executeUpdate("delete from airInvoice where mainid=?", id);
            if (infoJson.containsKey("airInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("airInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, airInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "airInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
            rs.executeUpdate("delete from airDtlInvoice where mainid=?", id);
            if (infoJson.containsKey("airDtlInvoice")) {
                String airDtlInvoiceStr = infoJson.getString("airDtlInvoice");
                if (airDtlInvoiceStr != null && !"".equals(airDtlInvoiceStr)) {
                    JSONArray infoJsonArray = infoJson.getJSONArray("airDtlInvoice");
                    for (int i = 0; i < infoJsonArray.size(); i++) {
                        JSONObject infoJsonDtl = infoJsonArray.getJSONObject(i);
                        if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                            sql = getsqlByColumn(id, airDtlInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "airDtlInvoice");
                            rs.executeUpdate(sql, valueList);
                        }
                    }
                }
            }
        } else if (invoiceType == 13) {//国际小票
            //修改明细表数据 smallInvoice
            rs.executeUpdate("delete from smallInvoice where mainid=?", id);
            if (infoJson.containsKey("smallInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("smallInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, smallInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "smallInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 22) {//船票
            //修改明细表数据 fnaBoatInvoice
            rs.executeUpdate("delete from fnaBoatInvoice where mainid=?", id);
            if (infoJson.containsKey("fnaBoatInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("fnaBoatInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, fnaBoatInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "fnaBoatInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
        } else if (invoiceType == 23) {//滴滴出行行程单
            //修改明细表数据 fnaDidiInvoice
            rs.executeUpdate("delete from fnaDidiInvoice where mainid=?", id);
            if (infoJson.containsKey("fnaDidiInvoice")) {
                JSONObject infoJsonDtl = infoJson.getJSONObject("fnaDidiInvoice");
                if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                    sql = getsqlByColumn(id, fnaDidiInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "fnaDidiInvoice");
                    rs.executeUpdate(sql, valueList);
                }
            }
            rs.executeUpdate("delete from fnaDidiDtlInvoice where mainid=?", id);
            if (infoJson.containsKey("fnaDidiDtlInvoice")) {
                String fnaDidiDtlInvoiceStr = infoJson.getString("fnaDidiDtlInvoice");
                if (fnaDidiDtlInvoiceStr != null && !"".equals(fnaDidiDtlInvoiceStr)) {
                    JSONArray infoJsonArray = infoJson.getJSONArray("fnaDidiDtlInvoice");
                    for (int i = 0; i < infoJsonArray.size(); i++) {
                        JSONObject infoJsonDtl = infoJsonArray.getJSONObject(i);
                        if (infoJsonDtl != null && infoJsonDtl.size() > 0) {
                            sql = getsqlByColumn(id, fnaDidiDtlInvoice, infoJsonDtl, valueList, formatDoubleList, formatIntList, "fnaDidiDtlInvoice");
                            rs.executeUpdate(sql, valueList);
                        }
                    }
                }

            }
        }

        // 完税证明逻辑
        try {
        	JSONObject incExt = infoJson.containsKey("incExt")?infoJson.getJSONObject("incExt"):new JSONObject();
            JSONArray items = incExt.containsKey("items")?incExt.getJSONArray("items"):new JSONArray();
            rs.executeUpdate("delete from FnaTaxpayment where mainid = ?", id);
            for(int i = 0;i<items.size();i++) {
            	JSONObject item = items.getJSONObject(i);
            	String date = item.containsKey("date")?item.getString("date"):"";
            	String amount = item.containsKey("amount")?item.getString("amount"):"";
            	String orgNo = item.containsKey("orgNo")?item.getString("orgNo"):"";
            	String name = item.containsKey("name")?item.getString("name"):"";
            	String ioDate = item.containsKey("ioDate")?item.getString("ioDate"):"";
            	String taxType = item.containsKey("taxType")?item.getString("taxType"):"";
            	rs.executeUpdate("insert into FnaTaxpayment(uuid,mainid,paydate,amount,orgNo,name,ioDate,taxType) values (?,?,?,?,?,?,?,?)",
            			FnaCommon.getPrimaryKeyGuid1(),id,date,amount,orgNo,name,ioDate,taxType);
            }
            
            JSONArray billItems = incExt.containsKey("billItems")?incExt.getJSONArray("billItems"):new JSONArray();
            rs.executeUpdate("delete from FnaBillSummaryInfo where mainid = ?", id);
            for(int i = 0;i<billItems.size();i++) {
            	JSONObject item = billItems.getJSONObject(i);
            	String bDate = item.containsKey("bDate")?item.getString("bDate"):"";
            	String eDate = item.containsKey("eDate")?item.getString("eDate"):"";
            	String info = item.containsKey("info")?item.getString("info"):"";
            	String invoice_number = item.containsKey("invoice_number")?item.getString("invoice_number"):"";
            	String invoice_code = item.containsKey("invoice_code")?item.getString("invoice_code"):"";
            	String invoice_no = item.containsKey("invoice_no")?item.getString("invoice_no"):"";
            	String amount = item.containsKey("amount")?item.getString("amount"):"";
            	String rate = item.containsKey("rate")?item.getString("rate"):"";
            	String tax = item.containsKey("tax")?item.getString("tax"):"";
            	String trip_number = item.containsKey("trip_number")?item.getString("trip_number"):"";
            	String tAmount = item.containsKey("tAmount")?item.getString("tAmount"):"";
            	String sAmount = item.containsKey("sAmount")?item.getString("sAmount"):"";
            	rs.executeUpdate("insert into FnaBillSummaryInfo(mainid,bDate,eDate,info,invoice_number,invoice_code,invoice_no,amount,rate,tax,trip_number,tAmount,sAmount) "
            			+ " values (?,?,?,?,?,?,?,?,?,?,?,?,?)",id,bDate,eDate,info,invoice_number,invoice_code,invoice_no,amount,rate,tax,trip_number,tAmount,sAmount);
            }
		} catch (Exception e) {
		}

        //插入日志2
        Map<String, String> afterMap = fnaLogSqlUtil.getInvoiceMap(String.valueOf(id), labelIdMap);
        fnaLogSqlUtil.invoiceLedgerAddlog(new User(1), ipAdress, opType, String.valueOf(id), "2",
                beforeMap, afterMap, labelIdMap);

        jsonObject.put("id",String.valueOf(id));
        jsonObject.put("cloudId",cloudId);
        return jsonObject;
    }

    /**
     * 通过数据库字段获取sql
     * @return
     */
    public static String getsqlByColumn(int id,String tableNameArray[] ,JSONObject infoJson,List<String>valueList,
                                        List<String> formatDoubleList,List<String> formatIntList,String tableName){
        DecimalFormat df = new DecimalFormat("###############################0.00");
        StringBuffer sql=new StringBuffer();
        StringBuffer sqlPlaceHolder=new StringBuffer();
        valueList.clear();
        if(id<=0 || !"fnainvoiceledger".equals(tableName)){
            sql.append("insert into ").append(tableName).append("(");
            sqlPlaceHolder.append(" values(");
            if(!"fnainvoiceledger".equals(tableName)){//明细表，插入mainid
                sql.append("mainid,");
                sqlPlaceHolder.append("?,");
                valueList.add(String.valueOf(id));
            }
            for(int i=0;i<tableNameArray.length;i++){
                String column=tableNameArray[i];
                sql.append(column);
                sqlPlaceHolder.append("?");
                if(i!=(tableNameArray.length-1)){
                    sql.append(",");
                    sqlPlaceHolder.append(",");
                }else{
                    sql.append(")");
                    sqlPlaceHolder.append(")");
                }
                if(formatDoubleList.contains(column)) {
                	if("travel_tax".equals(column)) {
                		column = "travelTax";
                	}
                    valueList.add(df.format(Util.getDoubleValue(getString(infoJson,column).replaceAll(",", ""), 0.00)));
                }else if(formatIntList.contains(column)){
                    valueList.add(Util.null2String(Util.getIntValue(getString(infoJson,column),0)));
                }else{
                	if(column.contains("custom_Field_")) {
                		column = column.replaceAll("_", "");
                	}
                    valueList.add(getString(infoJson,column));
                }
            }
        }else{
            sql.append("update ").append(tableName).append(" set ");
            for(int i=0;i<tableNameArray.length;i++){
                String column=tableNameArray[i];
                sql.append(" ").append(column).append("=?");
                if(i!=(tableNameArray.length-1)){
                    sql.append(",");
                }
                if(formatDoubleList.contains(column)){
                	if("travel_tax".equals(column)) {
                		column = "travelTax";
                	}
                    valueList.add(df.format(Util.getDoubleValue(getString(infoJson,column),0.00)));
                }else if(formatIntList.contains(column)){
                    valueList.add(Util.null2String(Util.getIntValue(getString(infoJson,column),0)));
                }else{
                	if(column.contains("custom_Field_")) {
                		column = column.replaceAll("_", "");
                	}
                    valueList.add(getString(infoJson,column));
                }
            }
            sql.append(" where id=?");
            valueList.add(String.valueOf(id));
            }
        return sql.toString()+sqlPlaceHolder.toString();
    }




    /**
     * TODO 把字节数组保存为一个文件
     *
     * @param imageBytes
     * @param filePath
     * @return
     */
    public static File getFileFromBytes(byte[] imageBytes, String filePath) {
        BufferedOutputStream stream = null;
        File file = null;
        try {
            file = new File(filePath);
            file.mkdirs();
            if (file.exists()) {
                file.delete();
                file.createNewFile();
            } else {
                file.createNewFile();
            }
            FileOutputStream fstream = new FileOutputStream(file);
            stream = new BufferedOutputStream(fstream);
            stream.write(imageBytes);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return file;
    }

    public static String getImageId(byte[] imageBytes, String cid, String tokenUrl,String uploadUrl,User user, String userName, String password,String imageFilename) throws Exception {

        //获取token
        JSONObject tokenJson = getCloudToken(user,cid,password,userName,tokenUrl);
        String token = "";
        if(tokenJson.getBoolean("flag")){
            token = tokenJson.getString("token");
        }else{
            throw new Exception(tokenJson.getString("msg"));
        }
        uploadUrl = uploadUrl+"?token="+token;
        String imageId = "";

        //获取图片路径
        String filePath = GCONST.getRootPath() +
                "WEB-INF" + File.separatorChar +
                "fna" + File.separatorChar +
                "fpyOCRImageTemp" + File.separatorChar;
        if("".equals(imageFilename)){
            filePath = filePath+FnaCommon.getPrimaryKeyGuid1();
        }else{
            filePath = filePath + imageFilename;
        }
        File imageFile = getFileFromBytes(imageBytes, filePath);


        try {
            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2), "OA发送请求", "发票识别-发票云-上传文件", uploadUrl, userName, password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", "", "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", "", "uuid", uuid, "string");

            JSONObject data = uploadPicture(imageFile, uploadUrl,imageBytes,imageFilename);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", data.toString(), "uuid", uuid, "string");
            new BaseBean().writeLog("--------fnaLog--------发票云-文件上传返回data：" + data);
            if(data.getString("status").equals("0")){
                JSONObject json = data.getJSONObject("returnInfo");
                JSONObject actionMsgJson = json.getJSONObject("actionMsg");
                if (!"0".equals(actionMsgJson.getString("code"))) {
                    throw new Exception(actionMsgJson.getString("message"));
                }

                JSONObject dataJson = json.getJSONObject("data");
                JSONArray idsArray = dataJson.getJSONArray("ids");
                for(int i = 0;i<idsArray.size();i++) {
                	String id = idsArray.getString(i);
                	if(!imageId.isEmpty()) {
                		imageId += ",";
                	}
            		imageId += id;
                }
            }

        } finally {
            //识别完成，删掉临时图片文件
            File tempImagefile = new File(filePath);
            if (tempImagefile.exists()) {
                tempImagefile.delete();
            }
        }

        return imageId;
    }

    /**
     * 发票云OCR
     *
     * @param cid
     * @param checkUrl
     * @param user
     * @return
     */
    public static JSONObject invoiceOCR(byte[] imageBytes, String cid, String ocrUrl,String tokenUrl,String uploadUrl, User user, String userName, String password) throws Exception {
        DecimalFormat df = new DecimalFormat("############################0.00");
        JSONObject resultJsonObj = new JSONObject();

        //1.先上传图片获取图片id
        String imageIdRtn = getImageId(imageBytes,cid,tokenUrl,uploadUrl,user, userName, password,"");
        new BaseBean().writeLog("--------fnaLog--------发票云返回imageId：" + imageIdRtn);
        String[] imageIds = imageIdRtn.split(",");
        

        //解析报文开始
        JSONObject dataJsonObj = new JSONObject();       //封装的接口返回标准信息
        JSONArray identify_results = new JSONArray();       //识别结果数据
        
        for(String imageId : imageIds) {

            //2.调用发票识别接口
            //传入的参数
            JSONObject param = new JSONObject();
            param.put("cid", cid);
            param.put("userId", user.getUID());
            param.put("image_index", imageId);
            param.put("operate_type", "0");
            param.put("is_save", "0");

            //通信
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2), "OA发送请求", "发票识别-发票云", ocrUrl, userName, password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", content, "uuid", uuid, "string");

            String data = postToUrl(ocrUrl, content, map, "", uuid, "check", user,"");
            new BaseBean().writeLog("--------fnaLog--------发票云返回data：" + data);
            JSONObject dataJson = JSONObject.fromObject(data);

            JSONArray infoArrayJson = dataJson.getJSONArray("infos");
            int infoArrayJson_len = infoArrayJson.size();
            for (int i = 0; i < infoArrayJson_len; i++) {
                JSONObject infoArrayJsonElt = infoArrayJson.getJSONObject(i);

                String ret = infoArrayJsonElt.getString("ret");
                if("1705".equals(ret) || "1696".equals(ret) || "1686".equals(ret)) {
                	ret = "0";
                }
                if ("0".equals(ret)) {
                    //获取发票云相关信息对象
                    JSONObject infoJson = infoArrayJsonElt.getJSONObject("info");
                    JSONObject modify_infoJson = infoJson.getJSONObject("modify_info");
                    JSONObject comm_infoJson = infoJson.getJSONObject("comm_info");
                    JSONObject proJson = comm_infoJson.getJSONObject("pro");
                    JSONObject priceJson = comm_infoJson.getJSONObject("price");
                    JSONObject buyerJson = comm_infoJson.getJSONObject("buyer");
                    JSONObject payerJson = comm_infoJson.getJSONObject("payer");
                    String fid = infoJson.getString("fid");

                    //不常用信息
                    String ext = infoJson.getString("ext");
                    JSONObject extJson = JSONObject.fromObject(ext);


                    //转化为标准的结构
                    JSONObject identifyObj = new JSONObject();
                    JSONObject detailsObj = new JSONObject();
                    String type = proJson.getString("type");

                    String standardType =Constants.STANDARDTYPE.get(type);
                    if ("".equals(standardType)) {
                        //识别失败
                        resultJsonObj.put("result", 0);
                        resultJsonObj.put("message", "发票识别失败！");
                        return resultJsonObj;
                    }
                    identifyObj.put("type", standardType);
                    identifyObj.put("orientation", "");
                    if(infoJson.containsKey("region")) {
                        identifyObj.put("region", infoJson.getString("region"));
                    }else {
                        identifyObj.put("region", "[0,0,0,0]");
                    }
                    detailsObj.put("fid", fid);
                    if ("1".equals(type) || "2".equals(type) || "3".equals(type) || "4".equals(type) || "5".equals(type) || "22".equals(type) || "28".equals(type) ) {     //增值税
                    //if ("1".equals(type) || "2".equals(type) || "3".equals(type) || "5".equals(type)) {     //增值税

                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("pretax_amount", getString(priceJson, "amount"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("tax", getString(extJson, "ttax"));
                        detailsObj.put("check_code", getString(proJson, "chcode"));
                        detailsObj.put("seller", getString(payerJson, "company"));
                        detailsObj.put("seller_tax_id", getString(payerJson, "tcode"));
                        detailsObj.put("buyer", getString(buyerJson, "company"));
                        detailsObj.put("buyer_tax_id", getString(buyerJson, "tcode"));
                        detailsObj.put("company_seal", getString(extJson, "corp_seal"));
                        detailsObj.put("form_type", getString(extJson, "form_type"));
                        detailsObj.put("form_name", getString(extJson, "form_name"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("ciphertext", getString(extJson, "ciphertext"));
                        detailsObj.put("transit_mark", getString(extJson, "transit"));
                        detailsObj.put("oil_mark", getString(extJson, "oil_mark"));
                        detailsObj.put("machine_code", getString(extJson, "machine_code"));
                        detailsObj.put("travel_tax", getString(extJson, "travel_tax"));
						detailsObj.put("fylx", getString(extJson, "fylx"));
						detailsObj.put("lian_id", getString(extJson, "lian_id"));
						detailsObj.put("purp", getString(extJson, "purp"));
						detailsObj.put("iele", getString(extJson, "iele"));
						detailsObj.put("orf", getString(extJson, "orf"));
                        detailsObj.put("receiptor", getString(extJson, "receiptor"));
                        detailsObj.put("reviewer", getString(extJson, "reviewer"));
                        detailsObj.put("issuer", getString(extJson, "issuer"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                        detailsObj.put("service_name", getString(extJson, "service_name"));
                        detailsObj.put("remark", getString(extJson, "comment"));

                        detailsObj.put("code_confirm", getString(extJson, "code_confirm"));
                        detailsObj.put("number_confirm", getString(extJson, "number_confirm"));

                        String item_names = "";
                        if(extJson.containsKey("products")) {
                            JSONArray productsArrayJson = extJson.getJSONArray("products");
                            for (int j = 0; j < productsArrayJson.size(); j++) {
                                if (!"".equals(item_names)) {
                                    item_names += ",";
                                }
                                item_names += productsArrayJson.getJSONObject(j).get("name");
                            }
                        }
                        detailsObj.put("item_names", item_names);
                        detailsObj.put("agent_mark", getString(extJson, "agent_mark"));
                        detailsObj.put("acquisition_mark", getString(extJson, "acquisition"));
                        detailsObj.put("block_chain", getString(extJson, "block_chain"));
                        if("22".equals(type)){//区块链发票
                            detailsObj.put("block_chain", "1");
                        }
                        if("5".equals(type)){//通行费
                            detailsObj.put("transit_mark", "1");
                        }

                        detailsObj.put("code_confirm", getString(extJson, "code_confirm"));
                        detailsObj.put("number_confirm", getString(extJson, "number_confirm"));




                        JSONArray items = new JSONArray();//发票明细
                        if(extJson.containsKey("products")){
                            JSONArray productsArray = extJson.getJSONArray("products");
                            for(int j=0;j<productsArray.size();j++){
                                JSONObject productJson = productsArray.getJSONObject(j);
                                String CommodityName = getString(productJson,"name");

                                String UnitPrice = getString(productJson,"price");
                                String Quantity = getString(productJson,"qty");
                                String specification = getString(productJson,"smodel");
                                String unit = getString(productJson,"muint");
                                String Amount = getString(productJson,"amount");
                                String TaxRate =  String.valueOf(Util.getDoubleValue(getString(productJson,"trate"),0.00));
                                String Tax = getString(productJson,"tprice");

                                String startDate = getString(productJson,"txrqq");
                                String endDate = getString(productJson,"txrqz");
                                String numberPlate = getString(productJson,"txfCph");
                                String carType = getString(productJson,"txfLx");

                                JSONObject jsonItems = new JSONObject();
                                jsonItems.put("quantity", Quantity);
                                jsonItems.put("price", UnitPrice);
                                jsonItems.put("name", CommodityName);
                                jsonItems.put("total", Amount);
                                jsonItems.put("tax_rate", TaxRate);
                                jsonItems.put("tax", Tax);
                                jsonItems.put("specification", specification);
                                jsonItems.put("unit", unit);
                                jsonItems.put("startDate", startDate);
                                jsonItems.put("endDate", endDate);
                                jsonItems.put("numberPlate", numberPlate);
                                jsonItems.put("type", carType);

                                items.add(jsonItems);
                            }
                        }
                        detailsObj.put("items", items);
                    } else if ("9".equals(type)) {      //出租车
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time_geton", getString(extJson, "time_geton"));
                        detailsObj.put("time_getoff", getString(extJson, "time_getoff"));
                        detailsObj.put("mileage", getString(extJson, "mileage"));
                        detailsObj.put("fare", getString(extJson, "fare"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("place", getString(extJson, "place"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                        detailsObj.put("license_plate", getString(extJson, "license_plate"));
                    } else if ("12".equals(type)) {      //火车票
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time", getString(extJson, "time"));
                        detailsObj.put("name", getString(extJson, "name"));
                        detailsObj.put("station_geton", getString(extJson, "station_geton"));
                        detailsObj.put("station_getoff", getString(extJson, "station_getoff"));
                        detailsObj.put("train_number", getString(extJson, "train_number"));
                        detailsObj.put("seat", getString(extJson, "seat"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("serial_number", getString(extJson, "serial_number"));
                        detailsObj.put("user_id", getString(extJson, "user_id"));
                    } else if ("10".equals(type)) {      //机打发票
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time", getString(extJson, "time"));
                        detailsObj.put("check_code", getString(proJson, "chcode"));
                        detailsObj.put("category", getString(extJson, "category"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("seller", getString(payerJson, "company"));
                        detailsObj.put("seller_tax_id", getString(payerJson, "tcode"));
                        detailsObj.put("buyer", getString(buyerJson, "company"));
                        detailsObj.put("buyer_tax_id", getString(buyerJson, "tcode"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                        detailsObj.put("company_seal", getString(extJson, "companySeal"));
                    } else if ("8".equals(type)) {       //定额发票
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                        detailsObj.put("company_seal", getString(extJson, "companySeal"));
                    } else if ("13".equals(type)) {       //过路费
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time", getString(extJson, "time"));
                        detailsObj.put("entrance", getString(extJson, "entrance"));
                        detailsObj.put("exit", getString(extJson, "exit"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("highway_flag", getString(extJson, "highway_flag"));
                    } else if ("15".equals(type)) {       //客运汽车
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time", getString(extJson, "time"));
                        detailsObj.put("station_geton", getString(extJson, "station_geton"));
                        detailsObj.put("station_getoff", getString(extJson, "station_getoff"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("name", getString(extJson, "name"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("user_id", getString(extJson, "user_id"));
                    } else if ("16".equals(type)) {       //航空运输电子客票行程单
                        detailsObj.put("user_name", getString(extJson, "user_name"));
                        detailsObj.put("user_id", getString(extJson, "user_id"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("check_code", getString(proJson, "chcode"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("agentcode", getString(extJson, "agentcode"));
                        detailsObj.put("issue_by", getString(extJson, "issue_by"));
                        detailsObj.put("fare", getString(extJson, "fare"));
                        detailsObj.put("tax", getString(extJson, "tax"));
                        detailsObj.put("fuel_surcharge", getString(extJson, "fuel_surcharge"));
                        detailsObj.put("caac_development_fund", getString(extJson, "caac_development_fund"));
                        detailsObj.put("insurance", getString(extJson, "insurance"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("international_flag", getString(extJson, "international_flag"));
                        detailsObj.put("print_number", getString(extJson, "print_number"));

                        JSONArray flightsArray_ret = new JSONArray();
                        if(extJson.containsKey("flights")) {
                            JSONArray flightsJsonArray = extJson.getJSONArray("flights");
                            for (int j = 0; j < flightsJsonArray.size(); j++) {
                                JSONObject flightObject = flightsJsonArray.getJSONObject(j);

                                JSONObject flightsOject_ret = new JSONObject();
                                flightsOject_ret.put("from", getString(flightObject, "from"));
                                flightsOject_ret.put("to", getString(flightObject, "to"));
                                flightsOject_ret.put("flight_number", getString(flightObject, "flight_number"));
                                flightsOject_ret.put("date", getString(flightObject, "date"));
                                flightsOject_ret.put("time", getString(flightObject, "time"));
                                flightsOject_ret.put("seat", getString(flightObject, "seat"));
                                flightsOject_ret.put("carrier", getString(flightObject, "carrier"));
                                flightsArray_ret.add(flightsOject_ret);
                            }
                        }
                        detailsObj.put("flights", flightsArray_ret);
                    } else if ("7".equals(type)) {       //二手车销售统一发票
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("seller", getString(payerJson, "company"));
                        detailsObj.put("seller_tax_id", getString(payerJson, "tcode"));
                        detailsObj.put("buyer", getString(buyerJson, "company"));
                        detailsObj.put("buyer_tax_id", getString(buyerJson, "tcode"));

                        JSONObject usedVehicleJson = extJson.getJSONObject("usedVehicle");
                        detailsObj.put("company_name", getString(usedVehicleJson, "marketCompany"));
                        detailsObj.put("company_tax_id", getString(usedVehicleJson, "marketTaxCode"));
                        detailsObj.put("license_plate", getString(usedVehicleJson, "licensePlate"));
                        detailsObj.put("registration_number", getString(usedVehicleJson, "registrationNumber"));
                        detailsObj.put("car_code", getString(usedVehicleJson, "vehicleIdentificationCode"));
                        detailsObj.put("car_model", getString(usedVehicleJson, "brankNumber"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                    } else if ("6".equals(type)) {       //机动车销售统一发票
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("machine_code", "machine_code");
                        detailsObj.put("machine_number", "machine_number");
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("pretax_amount", getString(priceJson, "amount"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("seller", getString(payerJson, "company"));
                        detailsObj.put("seller_tax_id", getString(payerJson, "tcode"));
                        detailsObj.put("buyer", getString(buyerJson, "company"));
                        detailsObj.put("buyer_tax_id", getString(buyerJson, "tcode"));

                        JSONObject vehicleDetailJson = extJson.getJSONObject("vehicleDetail");
                        detailsObj.put("tax_authorities", getString(vehicleDetailJson, "taxOfficeName"));
                        detailsObj.put("tax_authorities_code", getString(vehicleDetailJson, "taxOfficeCode"));
                        detailsObj.put("car_code", getString(vehicleDetailJson, "vehicleIdentificationCode"));
                        detailsObj.put("car_engine_code", getString(vehicleDetailJson, "engineCode"));
                        detailsObj.put("car_model", getString(vehicleDetailJson, "brankNumber"));
                        detailsObj.put("certificate_number", getString(vehicleDetailJson, "certificateNumber"));

                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                        detailsObj.put("tax", getString(extJson, "ttax"));
                        detailsObj.put("tax_rate", getString(extJson, "trate"));
                    } else if ("17".equals(type)) {       //小票
                        detailsObj.put("store_name", getString(extJson, "store_name"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time", getString(extJson, "time"));
                        detailsObj.put("subtotal", getString(priceJson, "amount"));
                        detailsObj.put("tax", getString(extJson, "tax"));
                        detailsObj.put("discount", getString(extJson, "discount"));
                        detailsObj.put("tips", getString(extJson, "tips"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("currency_code", getString(proJson, "ccy"));
                        detailsObj.put("type", getString(proJson, "kind"));
                    } else if ("18".equals(type)) {       //滴滴出行行程单
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("date_start", getString(extJson, "date_start"));
                        detailsObj.put("date_end", getString(extJson, "date_end"));
                        detailsObj.put("phone", getString(extJson, "phone"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("kind", getString(proJson, "kind"));

                        JSONArray itemsJson_ret = new JSONArray();
                        if(extJson.containsKey("items")) {
                            JSONArray itemsJson = extJson.getJSONArray("items");
                            for (int j = 0; j < itemsJson.size(); j++) {
                                JSONObject itemJson = itemsJson.getJSONObject(j);

                                JSONObject itemJson_ret = itemsJson.getJSONObject(j);
                                itemJson_ret.put("car_type", getString(itemJson, "car_type"));
                                itemJson_ret.put("time_geton", getString(itemJson, "time_geton"));
                                itemJson_ret.put("city", getString(itemJson, "city"));
                                itemJson_ret.put("station_geton", getString(itemJson, "station_geton"));
                                itemJson_ret.put("station_getoff", getString(itemJson, "station_getoff"));
                                itemJson_ret.put("mileage", getString(itemJson, "mileage"));
                                itemJson_ret.put("total", getString(itemJson, "total"));
                                itemsJson_ret.add(itemJson_ret);
                            }
                        }
                        detailsObj.put("items", itemsJson_ret);
                    } else if ("19".equals(type)) {       //完税证明
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("buyer", getString(buyerJson, "company"));
                        detailsObj.put("buyer_tax_id", getString(buyerJson, "tcode"));
                        detailsObj.put("date", getString(proJson, "date"));
                    } else if ("14".equals(type)) {       //船票
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("time", getString(extJson, "time"));
                        detailsObj.put("station_geton", getString(extJson, "station_geton"));
                        detailsObj.put("station_getoff", getString(extJson, "station_getoff"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("name", getString(extJson, "name"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                        detailsObj.put("province", getString(extJson, "province"));
                        detailsObj.put("city", getString(extJson, "city"));
                        detailsObj.put("currency_code", getString(proJson, "ccy"));
                    } else if ("11".equals(type)) {       //可报销的其他类型发票
                        detailsObj.put("code", getString(infoJson, "code"));
                        detailsObj.put("number", getString(infoJson, "number"));
                        detailsObj.put("total", getString(priceJson, "total"));
                        detailsObj.put("date", getString(proJson, "date"));
                        detailsObj.put("kind", getString(proJson, "kind"));
                    }
                    identifyObj.put("details", detailsObj);

                    //extra
                    JSONObject extraObj = new JSONObject();
                    extraObj.put("check_code_candidates", "");
                    extraObj.put("check_code_last_six", "");
                    extraObj.put("number_order_error", "");
                    extraObj.put("qrcode", "");
                    extraObj.put("barcode", "");
                    identifyObj.put("extra", extraObj);

                    identify_results.add(identifyObj);
                } else {
                	continue;
                }
            }
        }


        //返回数据
        dataJsonObj.put("result", 1);
        dataJsonObj.put("message", "");
        dataJsonObj.put("identify_results", identify_results);

        //extra
        JSONObject extraObj = new JSONObject();
        extraObj.put("qrcode", "");
        extraObj.put("barcode", "");
        dataJsonObj.put("extra", extraObj);

        //封装的完整标准数据
        JSONObject packageJsonObj = new JSONObject();
        packageJsonObj.put("result", 1);
        packageJsonObj.put("message", "");
        JSONObject responseJsonObj = new JSONObject();
        responseJsonObj.put("data", dataJsonObj);
        packageJsonObj.put("response", responseJsonObj);

        resultJsonObj.put("status", Constants.SUCCESS_CODE);
        resultJsonObj.put("returnInfo", packageJsonObj);
        return resultJsonObj;
    }


    /**
     * 发票云上传附件
     * @throws Exception
     */
    public static JSONObject uploadPicture(File localFile,String interfaceurl,byte[] imageBytes,String imageFilename) throws Exception {
    	JSONObject resultJsonObj=new JSONObject();
		HttpURLConnection connection = null;
		OutputStream outputStream = null;
        try{
            /*PostMethod filePost = new PostMethod(url);
            
            FilePart fp = new FilePart("file", localFile);
            
            // StringPart:普通的文本参数
            Part[] parts = {fp};
            // 对于MIME类型的请求，httpclient建议全用MulitPartRequestEntity进行包装
            MultipartRequestEntity mre = new MultipartRequestEntity(parts, filePost.getParams());
            filePost.setRequestEntity(mre);
            HttpClient client = new HttpClient();
            int status = client.executeMethod(filePost);
            if(status==200){
                String responseBodyAsString = filePost.getResponseBodyAsString();
                JSONObject returninfo = JSONObject.fromObject(responseBodyAsString);

                jsonObject.put("status", "0");
                jsonObject.put("returnInfo", returninfo);
            }else{
                throw new Exception("接口地址请求失败！");
            }*/
        	
        	URL url = new URL(interfaceurl);
        	//判断是是否配置代理
    		if(ProxyUtil.ifExistsProxy()){
    			connection = (HttpURLConnection) url.openConnection(ProxyUtil.getProxy());
    			Map<String,String> propertyMap = ProxyUtil.getProxyProperty();
    			String proxyUser = propertyMap.getOrDefault("proxyUser", "");//用户名
    			String proxyPwd = propertyMap.getOrDefault("proxyPwd", "");//密码
    			if(!"".equals(proxyUser)&&!"".equals(proxyPwd)){
    				String headerkey = "Proxy-Authorization";
    				String headerValue = "Basic "+Base64.encodeBase64String((proxyUser+":"+proxyPwd).getBytes());//帐号密码用:隔开，base64加密方式
    				connection.setRequestProperty(headerkey, headerValue);
    			}
    		}else{
    			connection = (HttpURLConnection) url.openConnection();
    		}
        	
        	connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=----request");
    		connection.setDoOutput(true);
    		connection.setDoInput(true);
    		connection.setRequestProperty("Charsert", "UTF-8");
    		connection.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
    		connection.setRequestProperty("Accept", "*/*");
    		connection.setRequestProperty("Range", "bytes="+"");
    		connection.setConnectTimeout(60000);
    		connection.setReadTimeout(60000);
    		connection.setRequestMethod("POST");
    		outputStream = connection.getOutputStream();
    		outputStream.write(("------request\r\n").getBytes("utf-8"));
    		outputStream.write(("Content-Disposition: form-data; name=\"file\";filename=\""+imageFilename+"\"\r\n").getBytes("utf-8"));
    		outputStream.write(("Content-Type: application/octet-stream").getBytes("utf-8"));
    		outputStream.write(("\"\r\n\r\n").getBytes("utf-8"));
    		outputStream.write(imageBytes);
    		outputStream.write(("\r\n").getBytes("utf-8"));
    		outputStream.write(("------request--\r\n").getBytes("utf-8"));
    		outputStream.flush();
    		outputStream.close();
    		StringBuffer returnInfo = new StringBuffer();
    		int resultCode = connection.getResponseCode();
    		new BaseBean().writeLog("resultCode：" + resultCode);
    		if(HttpURLConnection.HTTP_OK==resultCode){
    			BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
    			String line;
    			while ((line = reader.readLine()) != null){
    				returnInfo.append(line.trim());
    			}
        		new BaseBean().writeLog("returnInfo：" + returnInfo);
    			reader.close();
    			connection.disconnect();
    			resultJsonObj.put("status", Constants.SUCCESS_CODE);
    			resultJsonObj.put("returnInfo", JSONObject.fromObject(returnInfo.toString()));
    		}else{
                throw new Exception("接口地址请求失败！");
            }
        }catch (Exception e){
        	resultJsonObj.put("status", "1");
        	resultJsonObj.put("msg", e.getMessage());
        }finally {
			if(outputStream!=null){
				outputStream.close();
			}
			if(connection!=null){
				connection.disconnect();
			}
		}

		new BaseBean().writeLog("resultJsonObj：" + resultJsonObj);
        return resultJsonObj;
    }


    /**
     * 发票云查验
     * @param invoiceCode
     * @param invoiceNo
     * @param price
     * @param billingDate
     * @param crcCode
     * @param cid
     * @param checkUrl
     * @param user
     * @return
     */
    public static JSONObject autoCheckInvoice(String invoiceCode, String invoiceNo, String price, String billingDate, String crcCode,
                                              String cid, String checkUrl,User user,String userName,String password) throws Exception {
        DecimalFormat df = new DecimalFormat("############################0.00");
        
        RecordSet rs = new RecordSet();
        
        rs.executeQuery("select cloudid from fnainvoiceledger where invoiceCode = ? and invoiceNumber = ?", invoiceCode,invoiceNo);
        String cloudid = "";
        if(rs.next()) {
        	cloudid = Util.null2String(rs.getString("cloudid"));
        }
        
        String content = "";
        Map<String, String> map = new HashMap<String, String>();
        String uuid = FnaCommon.getPrimaryKeyGuid1();
        JSONObject resultObj = new JSONObject();
        if("".equals(cloudid)) {
            JSONObject param = new JSONObject();
            param.put("cid",cid);
            param.put("userId",user.getUID());

            param.put("code",invoiceCode);
            param.put("number",invoiceNo);

            billingDate = billingDate.replaceAll("-","");


            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            Date date = dateFormat.parse(billingDate);
            int  time = Math.round(date.getTime()/1000);
            param.put("date",time);
            param.put("chcode",crcCode);
            param.put("amount",price);
            param.put("total","");//机动车暂不支持
            param.put("is_save", "0");

            content = invoiceCloudEncode(param.toString(), password);
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2),"OA发送请求","发票查验",checkUrl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");
        }else {
        	 JSONObject param = new JSONObject();
             param.put("id", cloudid);
             param.put("is_cut", "0");
             param.put("operate_type", "2");
             param.put("cid",cid);
             param.put("userId",user.getUID());
             
             content = invoiceCloudEncode(param.toString(), password);
             map.put("appkey", userName);

             checkUrl = checkUrl.replace("/invoiceApi/invoice/valid_input", "/invoiceApi/invoice/person_local_valid");
             //插入日志表fnaInvoiceCloudLog
             rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                     uuid, Util.date(2),"OA发送请求","发票查验-特殊",checkUrl,userName,password);
             FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
             FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");
        }
        

        String data = postToUrl(checkUrl, content, map, "", uuid,"check",user,"");
        JSONObject dataJson = JSONObject.fromObject(data);

        //解析报文开始
        JSONObject infoJson = dataJson.getJSONObject("info");
        JSONObject comm_infoJson = infoJson.getJSONObject("comm_info");
        JSONObject proJson = comm_infoJson.getJSONObject("pro");
        JSONObject priceJson = comm_infoJson.getJSONObject("price");
        JSONObject buyerJson = comm_infoJson.getJSONObject("buyer");
        JSONObject payerJson = comm_infoJson.getJSONObject("payer");

        String ext = infoJson.getString("ext");
        JSONObject extJson = JSONObject.fromObject(ext);

        String status = getString(proJson,"status");//状态
        if("2".equals(status)){
            //记录错误信息
            FnaInvoiceCommon.saveFailLog(user.getUID(), 1, SystemEnv.getHtmlLabelName(509480, user.getLanguage()));
            throw new Exception(SystemEnv.getHtmlLabelName(509480, user.getLanguage()));
        }

        String type = getString(proJson,"type");//标题

        String title = getString(proJson,"cname");//标题
        String _taxIncludedPrice = getString(priceJson,"total");//价税合计
        String _priceWithoutTax = getString(priceJson,"amount");//不含税金额
        String _tax = getString(extJson,"ttax");
        String _invoiceNumber = getString(infoJson,"number");//发票号码
        String _invoicecode = getString(infoJson,"code");//代码
        String _checkCode = getString(proJson,"chcode");//校验码
        String _purchaser = getString(buyerJson,"company");//购买方
        String _seller = getString(payerJson,"company");//销售方
        String _purchaserTaxNo = getString(buyerJson,"tcode");//购买方纳税人识别号
        String _salesTaxNo = getString(payerJson,"tcode");//销售方纳税人识别号
        String _billingDate = getString(proJson,"date");//开票日期
        String _remark = getString(extJson,"comment");//备注信息
        String _sellerAddress = getString(extJson,"pcontact");//销售方电话、地址
        String _purchaserAddress = getString(extJson,"bcontact");//购买方电话、地址
        String _salesBank = getString(extJson,"pbank");//销售方开户行及账号
        String _purchaserBank = getString(extJson,"bbank");//购买方开户行及账号
        String _taxRate = getString(extJson,"trate");//税率
        String _invoiceServiceYype = "";//货物或应税服务类型
        JSONArray items = new JSONArray();//发票明细
        if(extJson.containsKey("products")){
            JSONArray productsArray = extJson.getJSONArray("products");
            for(int i=0;i<productsArray.size();i++){
                JSONObject productJson = productsArray.getJSONObject(i);
                String CommodityName = getString(productJson,"name");
                if("".equals(_invoiceServiceYype)) {
                    _invoiceServiceYype = CommodityName;
                }
                String UnitPrice = getString(productJson,"price");
                String Quantity = getString(productJson,"qty");
                String specification = getString(productJson,"smodel");
                String unit = getString(productJson,"muint");
                String Amount = getString(productJson,"amount");
                String TaxRate =  String.valueOf(Util.getDoubleValue(getString(productJson,"trate"),0.00));
                String Tax = getString(productJson,"tprice");

                String startDate = getString(productJson,"txrqq");
                String endDate = getString(productJson,"txrqz");
                String numberPlate = getString(productJson,"txfCph");
                String carType = getString(productJson,"txfLx");

                JSONObject jsonItems = new JSONObject();
                jsonItems.put("Quantity", Quantity);
                jsonItems.put("UnitPrice", UnitPrice);
                jsonItems.put("CommodityName", CommodityName);
                jsonItems.put("Amount", Amount);
                jsonItems.put("TaxRate", TaxRate);
                jsonItems.put("Tax", Tax);
                jsonItems.put("specification", specification);
                jsonItems.put("unit", unit);

                jsonItems.put("startDate", startDate);
                jsonItems.put("endDate", endDate);
                jsonItems.put("numberPlate", numberPlate);
                jsonItems.put("type", carType);

                items.add(jsonItems);
            }
        }


        //以下代码可能某些客户版本较低，不存在
        {
            int id= 0;
            rs.executeQuery("select id from fnaInvoiceDetailInfo where invoiceNumber=? and invoiceCode=?",_invoiceNumber,_invoicecode);
            if(rs.next()){
                id = Util.getIntValue(rs.getString("id"),0);
            }
            if(id <=0){
                rs.executeUpdate("insert into fnaInvoiceDetailInfo (invoiceNumber,invoiceCode) values(?,?)",_invoiceNumber,_invoicecode);
                rs.executeQuery("select id maxid from fnaInvoiceDetailInfo where invoiceNumber=? and invoiceCode=?",_invoiceNumber,_invoicecode);
                int maxid = 0;
                if(rs.next()){
                    maxid = Util.getIntValue(rs.getString("maxid"));
                }
                FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceDetailInfo", "detailInfo", items.toString(), "id", maxid+"", "int");
            }else{
                FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceDetailInfo", "detailInfo", items.toString(), "id", id+"", "int");
            }
            FnaAbstractInterface.saveInvoiceServiceYype(items, "CommodityName");
        }

        //机动车销售统一发票特殊字段
        String machine_code=getString(extJson,"machine_code");//机打代码
        String machine_number=getString(extJson,"machine_number");//机打号码
        String tax_authorities=getString(extJson,"taxOfficeName");//主管税务机关
        String tax_authorities_code=getString(extJson,"taxOfficeCode");//主管税务机关代码
        String car_code=getString(extJson,"vehicleIdentificationCode");//车架号/车辆识别代码
        String car_engine_code=getString(extJson,"engineCode");//发动机号码
        String car_model=getString(extJson,"brankNumber");//厂牌型号
        String certificate_number=getString(extJson,"certificateNumber");//合格证号



        resultObj.put("title", title);
        resultObj.put("_taxIncludedPrice", df.format(Util.getDoubleValue(_taxIncludedPrice,0.00)));
        resultObj.put("_priceWithoutTax", df.format(Util.getDoubleValue(_priceWithoutTax,0.00)));
        resultObj.put("_tax", df.format(Util.getDoubleValue(_tax,0.00)));
        resultObj.put("_taxRate", df.format(Util.getDoubleValue(_taxRate,0.00)));
        resultObj.put("_invoiceNumber", _invoiceNumber);
        resultObj.put("_invoicecode", _invoicecode);
        resultObj.put("_purchaser", _purchaser);
        resultObj.put("_seller", _seller);
        resultObj.put("_purchaserTaxNo", _purchaserTaxNo);
        resultObj.put("_salesTaxNo", _salesTaxNo);
        resultObj.put("_billingDate", _billingDate);
        resultObj.put("_remark", _remark);
        resultObj.put("_sellerAddress", _sellerAddress);
        resultObj.put("_purchaserAddress", _purchaserAddress);
        resultObj.put("_salesBank", _salesBank);
        resultObj.put("_purchaserBank", _purchaserBank);
        resultObj.put("_checkCode", _checkCode);
        resultObj.put("_invoiceServiceYype", _invoiceServiceYype);
        resultObj.put("_invoiceType", Constants.CLOUDTOOATYPE.get(type));

        int recoginizeinvoiceType = SdkInvoiceUtil.recoginizeInvoiceType(invoiceCode);
        resultObj.put("fplx", recoginizeinvoiceType);

        //机动车销售统一发票特殊字段
        resultObj.put("_machine_code", machine_code);
        resultObj.put("_machine_number", machine_number);
        resultObj.put("_tax_authorities", tax_authorities);
        resultObj.put("_tax_authorities_code", tax_authorities_code);
        resultObj.put("_car_code", car_code);
        resultObj.put("_car_engine_code", car_engine_code);
        resultObj.put("_car_model", car_model);
        resultObj.put("_certificate_number", certificate_number);

        resultObj.put("detaildata", items);
        resultObj.put("status", "1");
        return resultObj;
    }


    /**
     * 判断是否存在生效的发票云接口-流程组用
     * @param user
     * @return
     */
    public static boolean isExistInvoiceCloudInterface(User user){
        JSONObject interfaceInfo = InvoiceCloudUtil.getInterfaceInfo(user, false, false, true);
        JSONObject cloudInfo = interfaceInfo.getJSONObject("cloud");
        boolean existEffectCloud = cloudInfo.getBoolean("existEffectCloud");
        return existEffectCloud;
    }

    /**
     * 获取cloudId(发票云id)或者inoviceId(发票台账id)
     * @param ids
     * @param method 传cloudId或inoviceId  传cloudId表示要通过inoviceId获取cloudId,  传inoviceId表示要通过cloudId获取inoviceId
     * @return 返回的ids和传的ids顺序保持一致
     */
    public static String getCloudIdOrInoviceId(String ids,String method){
        StringBuffer idsBuffer = new StringBuffer();
        RecordSet rs = new RecordSet();
        String[] idsSplit = ids.split(",");
        if("cloudId".equals(method)){
            for(int i=0;i<idsSplit.length;i++){
                rs.executeQuery("select cloudId from fnaInvoiceLedger where id=?",idsSplit[i]);
                if(rs.next()){
                    String cloudId = Util.null2String(rs.getString("cloudId"));
                    if(idsBuffer.length()==0){
                        idsBuffer.append(cloudId);
                    }else{
                        idsBuffer.append(",").append(cloudId);
                    }
                }
            }
        }else if("inoviceId".equals(method)){
            for(int i=0;i<idsSplit.length;i++){
                rs.executeQuery("select id from fnaInvoiceLedger where cloudId=?",idsSplit[i]);
                if(rs.next()){
                    String id = Util.null2String(rs.getString("id"));
                    if(idsBuffer.length()==0){
                        idsBuffer.append(id);
                    }else{
                        idsBuffer.append(",").append(id);
                    }
                }
            }
        }
        return idsBuffer.toString();
    }
	
    /**
     * @Description: 同步转移归属人/共享人信息到发票云
     * @param interfaceurl
     * @param param
     * @param userName
     * @param password
     * @return: net.sf.json.JSONObject
     * @Author: konghang
     * @Date: 10:04 2020/10/14
     */
    public static JSONObject synOwnerInfo(String interfaceurl, JSONObject param, String userName, String password) {
        JSONObject jsonObject = new JSONObject();
        try {
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2), "OA发送请求", "同步转移归属人/共享人信息到发票云", interfaceurl, userName, password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", content, "uuid", uuid, "string");

            String data = postToUrl(interfaceurl, content, map, "", uuid);
            jsonObject.put("flag", true);
            jsonObject.put("data", data);
        } catch (Exception e) {
            jsonObject.put("flag", false);
            jsonObject.put("msg", e.getMessage());
        }
        return jsonObject;
    }

    /**
     * @Description: 同步共享人信息到发票云
     * @param interfaceurl
     * @param param
     * @param userName
     * @param password
     * @return: net.sf.json.JSONObject
     * @Author: konghang
     * @Date: 10:04 2020/10/14
     */
    public static JSONObject sysSharerInfo(String interfaceurl, JSONObject param, String userName, String password) {
        JSONObject jsonObject = new JSONObject();
        try {
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2), "OA发送请求", "同步共享人信息到发票云", interfaceurl, userName, password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", content, "uuid", uuid, "string");

            String data = postToUrl(interfaceurl, content, map, "", uuid);
            jsonObject.put("flag", true);
            jsonObject.put("data", data);
        } catch (Exception e) {
            jsonObject.put("flag", false);
            jsonObject.put("msg", e.getMessage());
        }
        return jsonObject;
    }


    /**
     * 获取发票使用次数接口
     * @param cid
     * @param userId
     * @return
     */
    public static JSONObject getInvoiceUsedNumberInfo(String cid,int userId){
        JSONObject invoiceCloudUrl = InvoiceCloudUtil.getInvoiceCloudUrl();
        RecordSet rs = new RecordSet();
        String userName="";
        String password="";
        String javaUrl="";
        rs.executeQuery("select * from fnaInvoiceInterface where cid=?",cid);
        if(rs.next()){
            userName = Util.null2String(rs.getString("userName"));
            password = FnaInvoiceCommon.fnaDecrypt(Util.null2String(rs.getString("password")));
            javaUrl = Util.null2String(rs.getString("javaUrl"));
        }
        return getInvoiceUsedNumberInfo(javaUrl+"/"+invoiceCloudUrl.getString("invoiceUsedNumberInfo"),cid,userName,password,userId);
    }

    /**
     * 获取发票使用次数接口
     * @param invoiceUsedNumberInfoUrl
     * @param cid
     * @param userName
     * @param password
     * @param userId
     * @return
     */
    public static JSONObject getInvoiceUsedNumberInfo(String invoiceUsedNumberInfoUrl,String cid,String userName,String password,int userId){
        JSONObject jsonObject = new JSONObject();
        try{
            JSONObject param = new JSONObject();
            param.put("cid",cid);
            param.put("userId",userId);
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);
            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","获取发票使用次数",invoiceUsedNumberInfoUrl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");
            String data = postToUrl(invoiceUsedNumberInfoUrl, content, map, "",uuid);
            jsonObject.put("flag",true);
            jsonObject.put("data",data);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 获取AES加密的key
     * @param invoiceUsedNumberInfoUrl
     * @param cid
     * @param userName
     * @param password
     * @param userId
     * @return
     */
    public static JSONObject createAesKey(String createAesKeyUrl,String password,String userName){
        JSONObject jsonObject = new JSONObject();
        try{

            String content = invoiceCloudEncode("", password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);
            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求","获取AES加密的key",createAesKeyUrl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");
            String data = postToUrl(createAesKeyUrl, content, map, "",uuid);
            jsonObject.put("flag",true);
            jsonObject.put("data",data);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 报销校验
     * @param reimburseUrl
     * @param aesKey
     * @param bodyJson
     * @param userName
     * @param password
     * @param description
     * @return
     */
    public static JSONObject reimburseInvoice(String reimburseUrl,String aesKey ,JSONObject bodyJson ,String userName,String password,String description){
        JSONObject jsonObject = new JSONObject();
        try{
            String bodyStr = InvoiceCloudAESUtil.encrypt(aesKey,bodyJson.toString());
            String content = invoiceCloudEncode(bodyStr.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);

            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid,Util.date(2),"OA发送请求",description,reimburseUrl,userName,password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", bodyJson.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content",content, "uuid", uuid, "string");

            String data = postToUrl(reimburseUrl, content, map, "",uuid,aesKey);

            jsonObject.put("flag",true);
            jsonObject.put("data",data);
        }catch (Exception e){
            jsonObject.put("flag",false);
            jsonObject.put("msg",e.getMessage());
        }

        return jsonObject;
    }


    /**
     * 发票云附件上传
     * @param imageBytes
     * @param cid
     * @param ocrUrl
     * @param tokenUrl
     * @param uploadUrl
     * @param user
     * @param userName
     * @param password
     * @return
     * @throws Exception
     */
    public static JSONArray uploadFileInvoice(byte[] imageBytes, String cid, String ocrUrl,String localCheckUrl,String tokenUrl,String uploadUrl, User user, String userName, String password,String imageFilename) throws Exception {
        JSONArray  uoloadFileArray = new JSONArray();

      //1.先上传图片获取图片id
        Map<String,Object> getImageMap = getImageIdNew(imageBytes,cid,tokenUrl,uploadUrl,user, userName, password,imageFilename);
        new BaseBean().writeLog("--------fnaLog--------发票云返回getImageMap：" + getImageMap);
        String imageIdRtn = Util.null2String(getImageMap.get("imageIds"));
        String id = Util.null2String(getImageMap.get("id"));
        String fileType = Util.null2String(getImageMap.get("fileType"));
        String fileName = Util.null2String(getImageMap.get("fileName"));
        String originFid = "";
        
        String[] imageIds = imageIdRtn.split(",");

        int index = 0;
        for(String imageId : imageIds) {
        	//2.识别
            JSONObject param = new JSONObject();
            param.put("cid", cid);
            param.put("userId", user.getUID());
            param.put("image_index", imageId);
            param.put("operate_type", "0");
            param.put("is_save", "0");
            
            if(index > 0) {
                JSONObject origin = new JSONObject();
                origin.put("id", id);
                origin.put("name", fileName);
                origin.put("type", fileType);
                origin.put("fid", originFid);
                param.put("origin", origin);
            }
            
            param.put("is_sync", "1");
            
            String content = invoiceCloudEncode(param.toString(), password);
            Map<String, String> map = new HashMap<String, String>();
            map.put("appkey", userName);
            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2), "OA发送请求", "发票识别新-发票云", ocrUrl, userName, password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param.toString(), "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", content, "uuid", uuid, "string");
            String data = postToUrl(ocrUrl, content, map, "", uuid, "check", user,"");
            JSONObject dataJson = JSONObject.fromObject(data);

            //插入调用记录日志
            JSONObject jo = new JSONObject();
            jo.put("status","0");
            jo.put("returnInfo", dataJson);
            FnaInvoiceCommon.addFnainvoiceLog("1",imageBytes,"","","","","",
                    jo, user, "OCR","");

            JSONArray infoArrayJson = dataJson.getJSONArray("infos");
            String open_valid = Util.null2String(getString(dataJson,"open_valid"));
            String is_valid = Util.null2String(getString(dataJson,"is_valid"));
            int infoArrayJson_len = infoArrayJson.size();
            if(infoArrayJson_len==0){
                FnaInvoiceCommon.saveFailLog(user.getUID(), 0, SystemEnv.getHtmlLabelName(509482, user.getLanguage()));//识别结果为空!
                throw new Exception(SystemEnv.getHtmlLabelName(	509587,user.getLanguage()));
            }
            for (int i = 0; i < infoArrayJson_len; i++) {
                JSONObject uploadFileJson = new JSONObject();
                JSONObject infoArrayJsonElt = infoArrayJson.getJSONObject(i);
                String ret = Util.null2String(getString(infoArrayJsonElt,"ret"));
                
                if(("1705".equals(ret) || "1696".equals(ret) || "1686".equals(ret)) && index > 0) {
                	continue;
                }
                
                JSONObject infoJson = infoArrayJsonElt.getJSONObject("info");
                JSONObject comm_info = infoJson.getJSONObject("comm_info");
                JSONObject pro = comm_info.getJSONObject("pro");
                String type = Util.null2String(getString(pro,"type"));
                String cloudId = Util.null2String(getString(infoJson,"fid"));
                if("1".equals(type) || "2".equals(type) || "3".equals(type) || "4".equals(type) || "5".equals(type) || "28".equals(type) || "10".equals(type) || "22".equals(type)) {
                	originFid = cloudId;
                }
                new BaseBean().writeLog("originFid:"+originFid);
                new BaseBean().writeLog("type:"+type);
                new BaseBean().writeLog("cloudId:"+cloudId);
                new BaseBean().writeLog("ret:"+ret);
                String invoiceNumber = Util.null2String(getString(infoJson,"number"));
                if ("0".equals(ret)) {
                	// 开启了自动查验，且开启了查验
                	if("0".equals(open_valid) && "1".equals(is_valid) && ("1".equals(type) || "2".equals(type) || "3".equals(type) || "4".equals(type) || "5".equals(type) || "6".equals(type) || "7".equals(type)|| "28".equals(type)|| "32".equals(type)|| "33".equals(type))){//需要查验
                		JSONObject param1 = new JSONObject();
                        param1.put("id", cloudId);
                        param1.put("is_cut", "0");
                        param1.put("operate_type", "2");
                        param1.put("cid",cid);
                        param1.put("userId",user.getUID());
                        
                        String content1 = invoiceCloudEncode(param1.toString(), password);
                        Map<String, String> map1 = new HashMap<String, String>();
                        map1.put("appkey", userName);
                        String uuid1 = FnaCommon.getPrimaryKeyGuid1();
                        rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                                uuid1, Util.date(2), "OA发送请求", "发票查验新-发票云", localCheckUrl, userName, password);
                        FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", param1.toString(), "uuid", uuid1, "string");
                        FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", content1, "uuid", uuid1, "string");
                        try{
                            String data1 = postToUrl(localCheckUrl, content1, map1, "", uuid1,"check",user,"");
                            JSONObject dataJson1 = JSONObject.fromObject(data1);
                            JSONObject infoJson1 = dataJson1.getJSONObject("info");
                            JSONObject comm_infoJson = infoJson1.getJSONObject("comm_info");
                            JSONObject proJson = comm_infoJson.getJSONObject("pro");
                            String status = getString(proJson,"status");//状态
                            if("2".equals(status)){
                                //记录错误信息
                                FnaInvoiceCommon.saveFailLog(user.getUID(), 1, SystemEnv.getHtmlLabelName(509480, user.getLanguage()));
                                uploadFileJson.put("msg",invoiceNumber+":"+SystemEnv.getHtmlLabelName(509480, user.getLanguage()));
                                uploadFileJson.put("flag",false);
                            }else{
                                uploadFileJson.put("flag",true);
                            }
                        }catch (Exception e){
                            uploadFileJson.put("flag",false);
                            uploadFileJson.put("msg",invoiceNumber+":"+e.getMessage());
                        }
                    }else{
                        uploadFileJson.put("flag",true);
                    }
                    uploadFileJson.put("cloudId",cloudId);
                }else{
                    uploadFileJson.put("cloudId",cloudId);
                    uploadFileJson.put("msg",Util.null2String(getString(infoArrayJsonElt,"message")));
                    uploadFileJson.put("flag",false);
                }

                uoloadFileArray.add(uploadFileJson);
            }
            index ++;
        }
        new BaseBean().writeLog("uoloadFileArray:"+uoloadFileArray);
        return uoloadFileArray;
    }
    
    public static Map<String,Object> getImageIdNew(byte[] imageBytes, String cid, String tokenUrl,String uploadUrl,User user, String userName, String password,String imageFilename) throws Exception {

    	Map<String,Object> returnMap = new HashMap<>();
        //获取token
        JSONObject tokenJson = getCloudToken(user,cid,password,userName,tokenUrl);
        String token = "";
        if(tokenJson.getBoolean("flag")){
            token = tokenJson.getString("token");
        }else{
            throw new Exception(tokenJson.getString("msg"));
        }
        uploadUrl = uploadUrl+"?token="+token;
        String imageId = "";

        //获取图片路径
        String filePath = GCONST.getRootPath() +
                "WEB-INF" + File.separatorChar +
                "fna" + File.separatorChar +
                "fpyOCRImageTemp" + File.separatorChar;
        if("".equals(imageFilename)){
            filePath = filePath+FnaCommon.getPrimaryKeyGuid1();
        }else{
            filePath = filePath + imageFilename;
        }
        File imageFile = getFileFromBytes(imageBytes, filePath);


        try {
            //插入日志表fnaInvoiceCloudLog
            RecordSet rs = new RecordSet();
            String uuid = FnaCommon.getPrimaryKeyGuid1();
            rs.executeUpdate("insert into fnaInvoiceCloudLog(uuid,enterTime,requestType,description,interfaceurl,userName,password) values(?,?,?,?,?,?,?)",
                    uuid, Util.date(2), "OA发送请求", "发票识别-发票云-上传文件", uploadUrl, userName, password);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "param", "", "uuid", uuid, "string");
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "md5Content", "", "uuid", uuid, "string");

            JSONObject data = uploadPicture(imageFile, uploadUrl,imageBytes,imageFilename);
            FnaCommon.updateDbClobOrTextFieldValue("fnaInvoiceCloudLog", "returnResult", data.toString(), "uuid", uuid, "string");
            new BaseBean().writeLog("--------fnaLog--------发票云-文件上传返回data：" + data);
            if(data.getString("status").equals("0")){
                JSONObject json = data.getJSONObject("returnInfo");
                JSONObject actionMsgJson = json.getJSONObject("actionMsg");
                if (!"0".equals(actionMsgJson.getString("code"))) {
                    throw new Exception(actionMsgJson.getString("message"));
                }

                JSONObject dataJson = json.getJSONObject("data");
                
                
                returnMap.put("id", dataJson.getString("id"));
                returnMap.put("fileType", dataJson.getString("fileType"));
                returnMap.put("fileName", dataJson.getString("fileName"));
                
                JSONArray idsArray = dataJson.getJSONArray("ids");
                for(int i = 0;i<idsArray.size();i++) {
                	String id = idsArray.getString(i);
                	if(!imageId.isEmpty()) {
                		imageId += ",";
                	}
            		imageId += id;
                }
                returnMap.put("imageIds", imageId);
                
            }

        } finally {
            //识别完成，删掉临时图片文件
            File tempImagefile = new File(filePath);
            if (tempImagefile.exists()) {
                tempImagefile.delete();
            }
        }

        return returnMap;
    }
}
