using Kingdee.BOS.Core.DynamicForm.PlugIn; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using Kingdee.BOS.Util; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using SAL_OUTSTOCK.Utils; using SAL_OUTSTOCK.Request; using static SAL_OUTSTOCK.Request.GP_FPKJ; using static SAL_OUTSTOCK.Request.BaseRequest; using Kingdee.BOS.Orm.DataEntity; using System.IO; using System.Net.Security; using System.Net; using System.Security.Cryptography.X509Certificates; using Kingdee.BOS.Core.DynamicForm; using SAL_OUTSTOCK.Response; using Kingdee.BOS.App.Data; using ExtensionMethods; namespace SAL_OUTSTOCK { [Description("销售出库单-表单插件-发票开具"), HotUpdate] public class IssueAnInvoiceFormPlugIn : AbstractDynamicFormPlugIn { private bool _doingButtonFlag = false; public override void BarItemClick(BarItemClickEventArgs e) { base.BarItemClick(e); //数电普票 if (e.BarItemKey.Equals("tbElectronic030", StringComparison.OrdinalIgnoreCase)) { ToExecuteRequest("030"); } //数电专票 if (e.BarItemKey.Equals("tbElectronic032", StringComparison.OrdinalIgnoreCase)) { ToExecuteRequest("032"); } //增值税专票(纸质) if (e.BarItemKey.Equals("tbPaper004", StringComparison.OrdinalIgnoreCase)) { ToExecuteRequest("004"); } //增值税普票(纸质) if (e.BarItemKey.Equals("tbPaper007", StringComparison.OrdinalIgnoreCase)) { ToExecuteRequest("007"); } } /// /// 开始执行 /// /// public void ToExecuteRequest(string FPLXDM) { if (!_doingButtonFlag) { var org = this.View.Model.GetValue("FStockOrgId") as DynamicObject; if (org != null && org["Id"].Long2Int() == 101542) { _doingButtonFlag = true; long orgId = org["Id"].Long2Int(); //orgId = this.Context.CurrentOrganizationInfo.ID; SendRequest(FPLXDM, orgId); return; } else { this.View.ShowMessage("此功能未开放!如有需要请联系管理员!"); return; } } } /// /// 设置content报文明文信息 /// /// 发票类型 /// 开票信息 /// 返回信息 /// public GP_FPKJ SetRequestCommonFPKJ(string FPLXDM, DynamicObject invoiceInfo, ref StringBuilder errMsg) { var headKey = "FBillHead"; var localeId = 2052; //客户信息 var cust = this.View.Model.GetValue("FCustomerID") as DynamicObject; var multiLanguage = cust["MultiLanguageText"] as DynamicObjectCollection; //申领单位 var applicant = this.View.Model.GetValue("F_QNV_Base1") as DynamicObject; var deptMulti = applicant["MultiLanguageText"] as DynamicObjectCollection; var headEntity = this.View.BusinessInfo.GetEntity(headKey); var entity = this.View.BusinessInfo.GetEntity("FEntity"); var subHeadEntity = this.View.BusinessInfo.GetEntity("SubHeadEntity"); var entrys = this.View.Model.GetEntityDataObject(entity); var sHeadInfo = this.View.Model.GetEntityDataObject(subHeadEntity, 0); var result = new GP_FPKJ(); var fpkj = result.FPKJ = new REQUEST_COMMON_FPKJ(); errMsg = new StringBuilder(); #region 针对非农产收购发票 #region 基础信息 fpkj.FPQQLSH = $"{invoiceInfo["FFIRMCODE"]}{DateTime.Now.ToString("yyyyMMddHHmm")}{invoiceInfo["FSERIALNUMBER"]}"; fpkj.FPLXDM = FPLXDM; if (FPLXDM.Equals("030") || FPLXDM.Equals("032")) fpkj.SBLX = "6"; else if (FPLXDM.Equals("007") || FPLXDM.Equals("004")) fpkj.SBLX = "4"; //是否纸质发票 bool isPaper = fpkj.SBLX == "4"; if (isPaper) fpkj.KPZDDM = "cszp"; fpkj.KPLX = "0"; fpkj.ZSFS = "0"; fpkj.JSHJ = sHeadInfo["BillAllAmount"].ToDecimalR().ToString(); fpkj.HJJE = sHeadInfo["BillAmount"].ToDecimalR().ToString(); fpkj.HJSE = sHeadInfo["BillTaxAmount"].ToDecimalR().ToString(); #endregion 基础信息 #region 销售方 fpkj.XSF_NSRSBH = invoiceInfo["FTAXCODE"].ToString(); fpkj.XSF_MC = invoiceInfo["FINVOICETITLE"].ToString(); fpkj.XSF_DZDH = $"{invoiceInfo["FINVOICEADDRESS"]} {invoiceInfo["FINVOICETEL"]}"; fpkj.XSF_YHZH = $"{invoiceInfo["FINVOICEBANKNAME"]} {invoiceInfo["FINVOICEBANKACCOUNT"]}"; //fpkj.SKR = "收款人"; //fpkj.FHR = "复核人"; fpkj.KPR = invoiceInfo["FDRAWER"].ToString(); fpkj.BZ = deptMulti.FirstOrDefault(w => w["LocaleId"].Long2Int() == localeId)["Name"].ToString(); #endregion 销售方 #region 购买方(客户信息) string cName = cust["INVOICETITLE"].IsNullOrEmpty() ? "" : cust["INVOICETITLE"].ToString(); if (cName == string.Empty) cName = multiLanguage.FirstOrDefault(w => w["LocaleId"].Long2Int() == localeId)["Name"].ToString(); var cAddress = cust["INVOICEADDRESS"].IsNullOrEmpty() ? (cust["ADDRESS"].IsNullOrEmpty() ? "" : cust["ADDRESS"]) : cust["INVOICEADDRESS"]; var cTel = cust["INVOICETEL"].IsNullOrEmpty() ? (cust["TEL"].IsNullOrEmpty() ? "" : cust["TEL"]) : cust["INVOICETEL"]; fpkj.GMF_MC = cName; //纳税人识别号/统一社会信用代码 fpkj.GMF_NSRSBH = (cust["SOCIALCRECODE"].IsNullOrEmpty() ? (cust["FTAXREGISTERCODE"].IsNullOrEmpty() ? "" : cust["FTAXREGISTERCODE"]) : cust["SOCIALCRECODE"]).ToString(); fpkj.GMF_DZDH = $"{cAddress} {cTel}"; fpkj.GMF_YHZH = $"{cust["INVOICEBANKNAME"]} {cust["INVOICEBANKACCOUNT"]}"; if (fpkj.GMF_MC == string.Empty) errMsg.AppendLine("购买方(客户信息)名称不能为空!"); if (fpkj.GMF_NSRSBH == string.Empty) errMsg.AppendLine("购买方(客户信息)统一社会信用代码或纳税人识别号不能为空!"); if (isPaper && fpkj.GMF_DZDH == string.Empty) errMsg.AppendLine("开具纸质发票时,购买方(客户信息)电话地址不完整!请检查是否缺少地址信息,电话信息"); if (isPaper && fpkj.GMF_YHZH == string.Empty) errMsg.AppendLine("开具纸质发票时,购买方(客户信息)银行信息不完整!请检查是否缺少银行信息,银行账号信息"); #endregion 购买方 #region 明细信息 var details = fpkj.COMMON_FPKJ_XMXX = new List(); if (!entrys.IsNullOrEmpty() && entrys.Any()) { var DataInfo = this.Model.DataObject; var fid = DataInfo["Id"].Long2Int(); var checkTaxCategroupSql = $@" SELECT a.FMASTERID, a.FNUMBER, a.FMATERIALID , b.FTAXCATEGORYCODEID , c.FTAXCODE , d.FENTRYID FROM T_BD_MATERIAL a LEFT JOIN T_BD_MATERIALSALE b ON a.FMATERIALID = b.FMATERIALID INNER JOIN T_IV_GTTAXCODE c ON b.FTAXCATEGORYCODEID = c.FID INNER JOIN T_SAL_OUTSTOCKENTRY d ON d.FMATERIALID = a.FMATERIALID WHERE c.FDOCUMENTSTATUS = 'C' AND d.FID = {fid}"; var dbList = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{checkTaxCategroupSql}"); foreach (var entry in entrys) { var material = entry["MaterialID"] as DynamicObject; if (dbList == null || !dbList.Any()) { errMsg.AppendLine($"物料:{material["Number"]} 缺少税收分类编码!"); continue; } var dbRow = dbList.FirstOrDefault(w => w["FENTRYID"].Long2Int() == entry["Id"].Long2Int()); if (dbRow == null) { errMsg.AppendLine($"物料:{material["Number"]} 缺少税收分类编码!"); continue; } var materialMulti = (material["MultiLanguageText"] as DynamicObjectCollection).FirstOrDefault(w => w["LocaleId"].Long2Int() == localeId); var priceUnit = entry["PriceUnitId"] as DynamicObject; var priceUnitMulti = (priceUnit["MultiLanguageText"] as DynamicObjectCollection).FirstOrDefault(w => w["LocaleId"].Long2Int() == localeId); var dPrice = entry["Price"]; var dSalunitQty = entry["SALUNITQTY"]; details.Add(new COMMON_FPKJ_XMXX { FPHXZ = "0", SPBM = dbRow["FTAXCODE"].ToString(), //ZXBM = material["Number"].ToString(), XMMC = materialMulti["Name"].ToString(), XMSL = dSalunitQty.ToDecimal().ToString("F6"), GGXH = materialMulti["Specification"].ToString(), DW = priceUnitMulti["Name"].ToString(), XMDJ = dPrice.ToDecimal().ToString("F6"), XMJE = entry["Amount"].ToDecimal().ToString("F2"), SL = (entry["TaxRate"].ToDecimal() * 0.01M).ToString("F2"), SE = entry["TaxAmount"].ToDecimal().ToString("F2"), }); } } #endregion 明细信息 #endregion 针对非农产收购发票 return result; } /// /// 发送报文信息处理 /// /// /// public BaseRequest RequestDataHandle(string FPLXDM, long orgId, ref bool isTestUrl) { //发票开具接口Code string interfaceCode = "GP_FPKJ"; string whereSql = $" AND {((FPLXDM.Equals("007") || FPLXDM.Equals("004")) ? "FIsDeviceType4" : "FIsDeviceType6")} = 1 "; #region 获取对应开票信息 var iinfoSQL = $@" SELECT TOP 1 FID, FUSEORGID, FAPPID, FTAXCODE, FDRAWER, FINVOICEBANKNAME, FINVOICEBANKACCOUNT, FINVOICEADDRESS, FINVOICETEL, FINVOICETITLE, FFIRMCODE, FSERIALNUMBER, FENCRYPTIONKEY, FISDEFAULT, FISTESTINFO FROM T_BD_INVOICEINFORMATION WHERE FDOCUMENTSTATUS = 'C' AND FUSEORGID = {orgId} {whereSql} ORDER BY FISDEFAULT DESC , FISTESTINFO DESC "; var iinfoDB = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{iinfoSQL}"); if (iinfoDB == null || !iinfoDB.Any()) throw new Exception("使用组织没有配对的开票系统信息!"); var iiDt = iinfoDB[0]; //是否测试数据 isTestUrl = iiDt["FISTESTINFO"].Long2Int() == 1; string appId = iiDt["FAPPID"].ToString(); string key = iiDt["FENCRYPTIONKEY"].ToString(); #endregion 获取对应开票信息 var requestBase = new BaseRequest(); requestBase._interface = new Interface(); var date = DateTime.Now; string newDate = date.ToString("yyyy-MM-dd HH:mm:ss"); string newDate2 = date.ToString("yyyyMMdd"); string no = Guid.NewGuid().ToString("N").Substring(0, 9).ToUpper(); //数据交换id string dataExchangeId = "DZFPQZ" + "DFXJ1001" + newDate2 + no; requestBase._interface.globalInfo.appId = appId; requestBase._interface.globalInfo.interfaceCode = interfaceCode; requestBase._interface.globalInfo.requestTime = newDate; requestBase._interface.globalInfo.dataExchangeId = dataExchangeId; StringBuilder errMsg = new StringBuilder(); try { var requestCommonFPKJ = SetRequestCommonFPKJ(FPLXDM, iiDt, ref errMsg); if (!errMsg.IsNullOrEmpty() && errMsg.Length > 0) throw new Exception(errMsg.ToString()); //更新对应开票信息的流水号记录 var serialNumber = iiDt["FSERIALNUMBER"].Long2Int(); var newSNumber = (serialNumber > 998 ? 1 : serialNumber + 1).ToString("D3"); var updSql = $"/*dialect*/UPDATE T_BD_INVOICEINFORMATION SET FSERIALNUMBER = '{newSNumber}' WHERE FID = {iiDt["FID"]}"; var isFlag = DBUtils.Execute(this.Context, updSql); var contentBefore = JsonConvert.SerializeObject(requestCommonFPKJ); //发票报文加密处理处理 string content = Base64Helper.Base64Encode(contentBefore); string contentSHA256 = SHA256Helper.SHA256EncryptString(content); //使用加密密钥再次加密 string contentKey = AESHepler.AesEncryptorBase64(contentSHA256, key); requestBase._interface.data.content = content; requestBase._interface.data.contentKey = contentKey; } catch (Exception ex) { throw ex; } return requestBase; } /// /// 发送报文,获取结果 /// /// public void SendRequest(string FPLXDM, long orgId) { var result = string.Empty; //var jsonStr = string.Empty; try { var DataInfo = this.Model.DataObject; var fid = DataInfo["Id"].Long2Int(); //财务信息 var invoiveUrl = this.View.Model.GetValue("FInvoiceNumber"); if (invoiveUrl != null && invoiveUrl.ToString().Trim().Length > 0) { this.View.ShowErrMessage($"此出库订单已经打印发票【财务信息】查看对应发票信息"); return; } bool isTestUrl = false; var requestData = RequestDataHandle(FPLXDM, orgId, ref isTestUrl); var postData = JsonConvert.SerializeObject(requestData); //jsonStr = Base64Helper.Base64Decode(requestData._interface.data.content); var url = "https://dev.fapiao.com:18944/fpt-rhqz/prepose";//双向通道地址 if (isTestUrl) url = "https://dev.fapiao.com:18944/fpt-rhqz/prepose";//双向通道地址-测试 result = DoPost(url, postData); var responseData = JsonConvert.DeserializeObject(result); var returnStateInfo = responseData._interface.returnStateInfo; if (returnStateInfo != null) { if (returnStateInfo.returnCode.Equals("0000")) { this.View.ShowMessage($"报文处理成功,正在回填发票信息【财务信息】"); var resultData = JsonConvert.DeserializeObject(Base64Helper.Base64Decode(responseData._interface.data.content)); var fpInfo = string.Empty; var data = resultData.DATA; //回填发票下载地址 if (FPLXDM.Equals("030") || FPLXDM.Equals("032")) fpInfo = data.PDF_URL; else if (FPLXDM.Equals("007") || FPLXDM.Equals("004")) fpInfo = data.FP_MW; this.View.Model.SetValue("FInvoiceUrl", fpInfo); this.View.Model.SetValue("FInvoiceNumber", data.FP_HM); this.View.Model.SetValue("FFPLXDM", data.FPLXDM); this.View.Model.SetValue("FFPQQLSH", data.FPQQLSH); var updSql = $@"/*dialect*/ UPDATE T_SAL_OUTSTOCKFIN SET FINVOICEURL = '{fpInfo}' ,FFPLXDM = '{data.FPLXDM}' ,FFPQQLSH = '{data.FPQQLSH}' ,FINVOICENUMBER = '{data.FP_HM}' WHERE FID = {fid}"; //发票信息址回填到数据库 var isFlag = DBUtils.Execute(this.Context, updSql); } else { throw new Exception(returnStateInfo.returnMessage); } } } catch (JsonSerializationException ex) { this.View.ShowMessage($"错误信息:{result}", MessageBoxType.Error); } catch (Exception ex) { this.View.ShowErrMessage($"错误信息:{ex.Message}"); //IOperationResult opResult = new OperationResult(); //opResult.OperateResult.Add(new OperateResult() //{ // Name = "信息提示", // Message = ex.Message, // SuccessStatus = false //}); //opResult.OperateResult.Add(new OperateResult() //{ // Name = "信息提示", // Message = jsonStr, // SuccessStatus = false //}); //this.View.ShowOperateResult(opResult.OperateResult); } finally { _doingButtonFlag = false; } return; } /// /// post请求 /// /// /// /// private static string DoPost(string url, string postData) { try { string result = string.Empty; HttpWebRequest request = null; if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); request.ProtocolVersion = HttpVersion.Version11; // 这里设置了协议类型。 ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;// SecurityProtocolType.Tls1.2; request.KeepAlive = false; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = (HttpWebRequest)WebRequest.Create(url); } string str1 = AppDomain.CurrentDomain.BaseDirectory; //证书 var keystorefile = str1 + @"\bin\ISSUE\testISSUE.pfx"; var key = "123456"; var cer = new X509Certificate2(keystorefile, key); request.ClientCertificates.Add(cer); request.Method = "POST"; //使用get方式发送数据 request.ContentType = "application/json;charset=utf-8"; byte[] data = Encoding.UTF8.GetBytes(postData); Stream newStream = request.GetRequestStream(); newStream.Write(data, 0, data.Length); newStream.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream stream = response.GetResponseStream(); using (StreamReader sr = new StreamReader(stream)) { result = sr.ReadToEnd(); } return result; } catch (Exception ex) { throw ex; } } private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { if (errors == SslPolicyErrors.None) return true; //总是接受 return false; } } }