/// <summary> /// 手动查验发票方法 /// </summary> /// <param name="code">发票代码</param> /// <param name="no">发票号码</param> /// <param name="date">发票日期</param> /// <param name="money">不含税金额</param> /// <param name="checkCode">校验码后六位</param> /// <returns></returns> public static InvoiceCheckResult ManualCheck(string code, string no, string date, string money = "", string checkCode = "") { //验真用另一个数据结构 AuthData authData = new AuthData(); InvoiceCheckDetail invoiceCheckDetail = new InvoiceCheckDetail(); InvoiceCheckResult invoiceCheckResult = new InvoiceCheckResult() { CheckDetailList = new List <InvoiceCheckDetail>() }; invoiceCheckResult.errcode = "0000"; invoiceCheckResult.description = "手动验真正常"; string logjson = ""; string jsonstr = ""; string token; if (code.Trim().Length == 0 || no.Trim().Length == 0 || date.Trim().Length == 0) { invoiceCheckDetail.checkErrcode = "10005"; invoiceCheckDetail.checkDescription = "未查验"; } else { try { //日期处理 string tempdate = DateTime.Parse(date).ToString("yyyyMMdd"); date = tempdate; token = GetAccessToken(); authData.invoiceCode = code; authData.invoiceNo = no; authData.invoiceDate = date; authData.invoiceMoney = money; //以下大部分是空格处理,有空格内容,查验接口会返回无法使用的状态,程序退出 //这接口只是能用的状态,有时候接口问题随缘出现 if (checkCode.Length > 6) { authData.checkCode = checkCode.Replace(" ", "").Substring(checkCode.Length - 6); } else { authData.checkCode = checkCode.Replace(" ", ""); } authData.invoiceNo = no.Replace(" ", ""); authData.invoiceCode = code.Replace(" ", ""); authData.isCreateUrl = "1"; invoiceCheckDetail = KingdeeCheck(token, ref invoiceCheckDetail, authData, ref logjson, ref jsonstr, ref invoiceCheckResult, 2, "手动查验方式"); } catch (Exception ex) { invoiceCheckResult.errcode = "20000"; invoiceCheckResult.description = ex.Message; InvoiceLogger.WriteToDB("手动查验异常退出:" + ex.Message, invoiceCheckResult.errcode, "", "", "", logjson, ""); } } invoiceCheckResult.CheckDetailList.Add(invoiceCheckDetail); return(invoiceCheckResult); }
/// <summary> /// 识别与查验(需要查验的自动查验) /// </summary> /// <param name="fileName">文件名</param> /// <param name="base64String">base64 字符串 </param> /// <returns></returns> public static InvoiceCheckResult Check(string fileName, string base64string) { string jsonstr = "", logjson = ""; bool authflag = false; //识别 + json 查验 InvoiceCheckResult invoiceCheckResult = new InvoiceCheckResult() { CheckDetailList = new List <InvoiceCheckDetail>() }; try { string token = GetAccessToken(); //image和pdf用base64识别 disData = PostImage(ApiUtil.BaseUrl + ApiUtil.ImgDistguishUrl + token, base64string); logjson = disData; InvoiceDisResult invoiceDisResult = GetDisResult(disData); invoiceCheckResult.errcode = invoiceDisResult.errcode; invoiceCheckResult.description = invoiceDisResult.description; //不需要验真的状态 //识别成功 if (invoiceDisResult.errcode == "0000" || invoiceDisResult.errcode == "10300") { for (int i = 0; i < invoiceDisResult.data.Count; i++) { InvoiceCheckDetail item = invoiceDisResult.data[i]; jsonstr = ""; //默认识别结果日志 logjson = disData; ReciveData recive = new ReciveData(); //虽然识别成功有些数据可能还是null item.invoiceCode = item.invoiceCode == null ? "" : item.invoiceCode; item.invoiceNo = item.invoiceNo == null ? "" : item.invoiceNo; item.invoiceDate = item.invoiceDate == null ? "" : item.invoiceDate; item.invoiceMoney = item.invoiceMoney == null ? "" : item.invoiceMoney; item.checkCode = item.checkCode == null ? "" : item.checkCode; item.totalAmount = item.totalAmount == null ? "" : item.totalAmount; item.taxRate = item.taxRate == null ? "" : item.taxRate; item.taxAmount = item.taxAmount == null ? "" : item.taxAmount; item.printingSequenceNo = item.printingSequenceNo == null ? "" : item.printingSequenceNo; item.electronicTicketNum = item.electronicTicketNum == null ? "" : item.electronicTicketNum; //不需要验真发票必须初始化的值 item.serialNo = item.serialNo == null ? "" : item.serialNo; item.salerName = item.salerName == null ? "" : item.salerName; item.salerAccount = item.salerAccount == null ? "" : item.salerAccount; item.amount = item.amount == null ? "" : item.amount; item.buyerTaxNo = item.buyerTaxNo == null ? "" : item.buyerTaxNo; //已经初始化完成,开始判断是否串号 if (invoiceDisResult.errcode == "10300") { //发票代码转具体发票 item.invoiceType = Enum.GetName(typeof(InvoiceType), int.Parse(item.invoiceType)); item.checkErrcode = "10300"; item.checkStatus = "不通过"; item.checkDescription = "发票串号"; //添加发票 invoiceCheckResult.CheckDetailList.Add(item); invoiceCheckResult.description = "操作成功"; //修改操作码 invoiceCheckResult.errcode = "0000"; InvoiceLogger.WriteToDB("发票串号", $"{invoiceCheckResult.errcode}", "", $"{invoiceCheckResult.description}", fileName, logjson, item.invoiceType); //条件不满足 进行下一个 continue; } //验真类型 if (authType.Contains(item.invoiceType)) { authflag = false; //提前判断 如果查验条件不满足,不去验真 if (item.invoiceNo.Trim().Length == 0) { authflag = true; item.checkDescription += " 发票号码识别为空 "; } if (item.invoiceCode.Trim().Length == 0) { authflag = true; item.checkDescription += " 发票代码识别为空 "; } if (item.invoiceDate.Trim().Length == 0) { authflag = true; item.checkDescription += " 发票日期识别为空 "; } //增值税普通发票、增值税电子普通发票(含通行费发票)、增值税普通发票(卷票) if (item.invoiceType == "1" || item.invoiceType == "3" || item.invoiceType == "5" || item.invoiceType == "15") { if (item.checkCode.Trim().Length == 0) { authflag = true; item.checkDescription += " 发票检验码识别为空 "; } } //机动车和 纸质专用发票必须要有 InvoiceMoney if (item.invoiceType == "2" || item.invoiceType == "4" || item.invoiceType == "12") { if (item.invoiceMoney.Trim().Length == 0) { authflag = true; item.checkDescription += " 不含税金额识别为空 "; } } // 二手车 if (item.invoiceType == "13") { if (item.totalAmount.Trim().Length == 0) { authflag = true; item.checkDescription += " 车价合计识别为空 "; } } //必须同时满足几个条件 if (authflag) { //发票代码转具体发票 item.invoiceType = Enum.GetName(typeof(InvoiceType), int.Parse(item.invoiceType)); item.checkErrcode = "10005"; item.checkStatus = "未查验"; //先写日志 InvoiceLogger.WriteToDB("发票查验条件不满足", $"{invoiceCheckResult.errcode}", "", $"{invoiceCheckResult.description}", fileName, logjson, item.invoiceType); item.checkDescription = "未识别到完整发票信息"; //添加发票 invoiceCheckResult.CheckDetailList.Add(item); //条件不满足 进行下一个 continue; } //纸质专用发票,机动车 用invoiceMoney 验真,其他用totalAmount 避免校验码和金额同时为空 if (item.invoiceType != "4" && item.invoiceType != "12") { item.invoiceMoney = item.totalAmount; } //验真用另一个数据结构 AuthData authData = new AuthData(); authData.invoiceCode = item.invoiceCode; authData.invoiceNo = item.invoiceNo; authData.invoiceDate = item.invoiceDate; authData.invoiceMoney = item.invoiceMoney; authData.checkCode = item.checkCode; authData.isCreateUrl = "1"; KingdeeCheck(token, ref item, authData, ref logjson, ref jsonstr, ref invoiceCheckResult, 1, fileName); } //不用验真的 else { item.checkErrcode = "0000"; item.checkDescription = "不验真发票状态正常"; item.checkStatus = "通过"; //火车票 if (item.invoiceType == "9") { item.invoiceNo = item.printingSequenceNo; } //飞机票 if (item.invoiceType == "10") { item.invoiceNo = item.electronicTicketNum; } //发票代码转具体发票 item.invoiceType = Enum.GetName(typeof(InvoiceType), int.Parse(item.invoiceType)); logjson = JsonConvert.SerializeObject(item); } //在加一次判断,免税的发票,设置0%,没有税率的也设置0% if (item.taxAmount.Trim().Length > 0) { //0.00 if (double.Parse(item.taxAmount) == 0.00) { item.taxRate = "0%"; } } //添加发票 invoiceCheckResult.CheckDetailList.Add(item); } } else { InvoiceLogger.WriteToDB("识别非正常情况日志", invoiceCheckResult.errcode, "", invoiceCheckResult.description, fileName, disData); } } catch (Exception ex) { //有时候基础连接会已被意外关闭,接口下次可以正常查验 //意外关闭无错误码 通常是发票无法识别 if (invoiceCheckResult.description.Contains("意外关闭")) { invoiceCheckResult.errcode = "0310"; invoiceCheckResult.description = "识别验真时发生异常" + ex.Message; } else { invoiceCheckResult.errcode = "20000"; invoiceCheckResult.description = "识别验真时发生异常" + ex.Message; } InvoiceLogger.WriteToDB("识别验真时发生异常:" + ex.Message, invoiceCheckResult.errcode, "", invoiceCheckResult.description, fileName); } return(invoiceCheckResult); }
private static InvoiceCheckDetail KingdeeCheck(string token, ref InvoiceCheckDetail item, AuthData authData, ref string logjson, ref string jsonstr, ref InvoiceCheckResult invoiceCheckResult, int type, string fileName = "") { ReciveData recive = new ReciveData(); //转验真json字符串 jsonstr = JsonConvert.SerializeObject(authData); try { //获取查验结果 FileLogger.WriteLog("开始调用金蝶发票查验接口", 1, "KingDeeApi", "Run", "DataService", "AppMessage"); jsonstr = PostJson(ApiUtil.BaseUrl + ApiUtil.TextCheckUrl + token, jsonstr); FileLogger.WriteLog("金蝶接口查验结果" + jsonstr, 1, "KingDeeApi", "Run", "DataService", "AppMessage"); jsonstr = jsonstr.Replace("'", ""); FileLogger.WriteLog("结束调用金蝶发票查验接口", 1, "KingDeeApi", "Run", "DataService", "AppMessage"); //保存到日志的验真结果 logjson = jsonstr; recive = GetCheckResult(jsonstr); //验真状态 识别成功都有状态 item.checkErrcode = recive?.errcode == null ? "" : recive.errcode; item.checkDescription = recive?.description == null ? "" : recive.description; //避免验真不通过之后,获取null值发生异常 item.serialNo = recive?.data?.serialNo == null ? "" : recive.data.serialNo; item.salerName = recive?.data?.salerName == null ? "" : recive.data.salerName; item.salerAccount = recive?.data?.salerAccount == null ? "" : recive.data.salerAccount; item.amount = recive?.data?.amount == null ? "" : recive.data.amount; item.buyerTaxNo = recive?.data?.buyerTaxNo == null ? "" : recive.data.buyerTaxNo; item.taxAmount = recive?.data?.taxAmount == null ? "" : recive.data.taxAmount; //手动查验没有识别数据 if (type == 2) { item.invoiceType = recive?.data?.invoiceType == null ? "" : recive.data.invoiceType; item.invoiceCode = recive?.data?.invoiceCode == null ? "" : recive.data.invoiceCode; item.invoiceNo = recive?.data?.invoiceNo == null ? "" : recive.data.invoiceNo; item.invoiceDate = recive?.data?.invoiceDate == null ? "" : recive.data.invoiceDate; item.invoiceMoney = recive?.data?.invoiceMoney == null ? "" : recive.data.invoiceMoney; item.checkCode = recive?.data?.checkCode == null ? "" : recive.data.checkCode; item.totalAmount = recive?.data?.totalAmount == null ? "" : recive.data.totalAmount; item.taxRate = recive?.data?.taxRate == null ? "" : recive.data.taxRate; item.taxAmount = recive?.data?.taxAmount == null ? "" : recive.data.taxAmount; item.serialNo = recive?.data?.serialNo == null ? "" : recive.data.serialNo; item.salerName = recive?.data?.salerName == null ? "" : recive.data.salerName; item.salerAccount = recive?.data?.salerAccount == null ? "" : recive.data.salerAccount; item.amount = recive?.data?.amount == null ? "" : recive.data.amount; item.electronicTicketNum = recive?.data?.electronicTicketNum == null ? "" : recive.data.electronicTicketNum; item.printingSequenceNo = recive?.data?.printingSequenceNo ?? ""; } item.buyerTaxNo = recive?.data?.buyerTaxNo == null ? "" : recive.data.buyerTaxNo; //税率 if (taxtype.Contains(item.invoiceType)) { if (recive?.data?.items != null) { item.taxRate = recive?.data.items[0].taxRate == null ? "" : recive.data.items[0].taxRate; } } if (item.invoiceType.Trim().Length != 0) { //发票代码转具体发票 item.invoiceType = Enum.GetName(typeof(InvoiceType), int.Parse(item.invoiceType)); } //设置查验结果 if (recive?.errcode == "0000") { if (recive?.data?.cancelMark == "N") { item.checkStatus = "通过"; //在加一次判断,免税的发票,设置0%,没有税率的也设置0% if (item.taxAmount.Trim().Length > 0) { //0.00 if (double.Parse(item.taxAmount) == 0.00) { item.taxRate = "0%"; } } } else { item.checkErrcode = "10004"; item.checkStatus = "不通过"; InvoiceLogger.WriteToDB("发票作废", invoiceCheckResult.errcode, recive.errcode, recive.description, fileName, logjson, item.invoiceType); } } else { //不通过的 if (noPass.Contains(recive.errcode)) { //变成统一返回码 item.checkErrcode = "10002"; item.checkDescription = "所查发票不存在"; item.checkStatus = "不通过"; } else { item.checkStatus = "未查验"; //重新说明 接口错误 if (errAPI.Contains(recive.errcode)) { item.checkErrcode = "10003"; item.checkDescription = "发票查验应用系统错误!"; } } InvoiceLogger.WriteToDB("查验未通过", invoiceCheckResult.errcode, recive.errcode, recive.description, fileName, logjson, item.invoiceType); } } catch (Exception ex) { item.checkErrcode = "10001"; item.checkDescription = "查验失败"; //添加发票 //发票代码转具体发票 if (item.invoiceType != null) { //发票代码转具体发票 item.invoiceType = Enum.GetName(typeof(InvoiceType), int.Parse(item.invoiceType)); } //发票识别加查验的需要添加异常发票 if (type == 1) { invoiceCheckResult.CheckDetailList.Add(item); } InvoiceLogger.WriteToDB("验真异常:" + ex.Message + ex.StackTrace ?? "" + ex.InnerException ?? "", invoiceCheckResult.errcode, "", invoiceCheckResult.description, fileName, logjson, item.invoiceType); } return(item); }