using ExtensionMethods; using Kingdee.BOS.App.Data; using Kingdee.BOS.Core.DynamicForm; using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; using Kingdee.BOS.Core.List.PlugIn; using Kingdee.BOS.Core.Validation; using Kingdee.BOS.Orm.DataEntity; using Kingdee.BOS.TCP; using Kingdee.BOS.Util; using Newtonsoft.Json; using SAL_OUTSTOCK.Request; using SAL_OUTSTOCK.Response; using SAL_OUTSTOCK.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using static SAL_OUTSTOCK.Request.BaseRequest; using static SAL_OUTSTOCK.Request.GP_FPKJ; namespace SAL_OUTSTOCK { [Description("销售出库单-列表插件-发票开具合并打印"), HotUpdate] public class MergePrintIssueAnInvPlugIn : AbstractListPlugIn { private bool _doingButtonFlag = false; private IOperationResult opResult; public override void BarItemClick(BarItemClickEventArgs e) { base.BarItemClick(e); //数电普票 if (e.BarItemKey.Equals("tbElectronic030", StringComparison.OrdinalIgnoreCase)) { DoCheckConditions("030"); return; } //数电专票 if (e.BarItemKey.Equals("tbElectronic032", StringComparison.OrdinalIgnoreCase)) { DoCheckConditions("032"); return; } //增值税专票(纸质) if (e.BarItemKey.Equals("tbPaper004", StringComparison.OrdinalIgnoreCase)) { DoCheckConditions("004"); return; } //增值税普票(纸质) if (e.BarItemKey.Equals("tbPaper007", StringComparison.OrdinalIgnoreCase)) { DoCheckConditions("007"); return; } } /// /// 检测选中数据是否符合执行条件 /// /// public void DoCheckConditions(string FPLXDM) { if (!_doingButtonFlag) { _doingButtonFlag = true; var orgId = 0L; var list = this.ListView.SelectedRowsInfo; var orgIdList = list.Select(x => x.MainOrgId).Distinct(); if (orgIdList.Any()) { if (orgIdList.Count() == 1) { opResult = new OperationResult(); var checkId = 101542L; orgId = orgIdList.First(); //checkId = orgId; if (orgId == checkId) DoIssueAnInvoice2List(FPLXDM, orgId); else this.View.ShowMessage("此功能未开放!如有需要请联系管理员!"); } else { this.View.ShowErrMessage("选择的单据的组织不统一!"); } } } _doingButtonFlag = false; } /// /// 设置content报文明文信息 /// /// 发票类型 /// 开票信息 /// 返回信息 /// public string ListMergeInv_FPKJ(string FPLXDM, DynamicObject invoiceInfo) { var list = this.ListView.SelectedRowsInfo; var fidList = list.Select(x => x.PrimaryKeyValue).Distinct(); //var sHeadInfo = this.View.Model.GetEntityDataObject(subHeadEntity, 0); var result = new GP_FPKJ(); var fpkj = result.FPKJ = new REQUEST_COMMON_FPKJ(); var headSql = $@" SELECT ID,DOCUMENTSTATUS,APPLYID,APPLYNAME,BILLALLAMOUNT,BILLAMOUNT,BILLTAXAMOUNT,BILLNO, CUSTID,CUSTNAME,INVOICETITLE,INVOICEBANKNAME,INVOICEBANKACCOUNT,INVOICENUMBER, TAXREGISTERCODE,SOCIALCRECODE,INVOICETEL,INVOICEADDRESS FROM V_INVINFO_OUTSTOCK WHERE ID IN ({string.Join(",", fidList)}) "; var sHeadInfos = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{headSql}"); var sHeadInfo = sHeadInfos[0]; #region 针对非农产收购发票 #region 基础信息 var custIds = sHeadInfos.Select(x => x["CUSTID"].Long2Int()).Distinct(); if (custIds.Count() != 1) opResult.OperateResult.Add(new OperateResult { Name = "客户信息", Message = "选择的开票数据客户信息不统一!", SuccessStatus = false }); var applyIds = sHeadInfos.Select(x => x["APPLYID"].Long2Int()).Distinct(); if (applyIds.Count() != 1) opResult.OperateResult.Add(new OperateResult { Name = "申领单位", Message = "选择的开票数据申领单位不统一!", SuccessStatus = false }); if (applyIds.Any() && applyIds.First() == 0) opResult.OperateResult.Add(new OperateResult { Name = "申领单位", Message = "选择的开票数据申领单位不能为空!", SuccessStatus = false }); if (sHeadInfos != null && sHeadInfos.Any()) { foreach (var item in sHeadInfos) { if (!item["INVOICENUMBER"].IsNullOrEmptyOrWhiteSpace()) { opResult.OperateResult.Add(new OperateResult { Name = item["BILLNO"].ToString(), Message = $"{item["BILLNO"]}该订单已打印过发票!", SuccessStatus = false }); continue; } if (!item["DOCUMENTSTATUS"].ToString().Trim().Equals("C")) opResult.OperateResult.Add(new OperateResult { Name = item["BILLNO"].ToString(), Message = $"{item["BILLNO"]}该订单未审核完毕!", SuccessStatus = false }); } } if (opResult.OperateResult.Any()) throw new Exception("检验信息"); 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 = sHeadInfos.Sum(x => x["BILLALLAMOUNT"].ToDecimalR()).ToString(); fpkj.HJJE = sHeadInfos.Sum(x => x["BILLAMOUNT"].ToDecimalR()).ToString(); fpkj.HJSE = sHeadInfos.Sum(x => x["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.KPR = invoiceInfo["FDRAWER"].ToString(); fpkj.BZ = sHeadInfo["APPLYNAME"].ToString(); #endregion 销售方 #region 购买方(客户信息) fpkj.GMF_MC = (sHeadInfo["INVOICETITLE"].IsNullOrEmpty() ? (sHeadInfo["CUSTNAME"].IsNullOrEmpty() ? "" : sHeadInfo["CUSTNAME"]) : sHeadInfo["INVOICETITLE"]).ToString(); //纳税人识别号/统一社会信用代码 fpkj.GMF_NSRSBH = (sHeadInfo["SOCIALCRECODE"].IsNullOrEmpty() ? (sHeadInfo["TAXREGISTERCODE"].IsNullOrEmpty() ? "" : sHeadInfo["TAXREGISTERCODE"]) : sHeadInfo["SOCIALCRECODE"]).ToString(); fpkj.GMF_DZDH = $"{sHeadInfo["INVOICEADDRESS"]} {sHeadInfo["INVOICETEL"]}"; fpkj.GMF_YHZH = $"{sHeadInfo["INVOICEBANKNAME"]} {sHeadInfo["INVOICEBANKACCOUNT"]}"; if (fpkj.GMF_MC.IsNullOrEmptyOrWhiteSpace()) opResult.OperateResult.Add(new OperateResult { Name = "客户信息", Message = "购买方(客户信息)名称不能为空!", SuccessStatus = false }); if (fpkj.GMF_NSRSBH.IsNullOrEmptyOrWhiteSpace()) opResult.OperateResult.Add(new OperateResult { Name = "客户信息", Message = "购买方(客户信息)统一社会信用代码或纳税人识别号不能为空!", SuccessStatus = false }); if (isPaper && fpkj.GMF_DZDH.IsNullOrEmptyOrWhiteSpace()) opResult.OperateResult.Add(new OperateResult { Name = "客户信息", Message = "开具纸质发票时,购买方(客户信息)开票电话地址不完整!请检查是否缺少地址信息,电话信息", SuccessStatus = false }); if (isPaper && fpkj.GMF_YHZH.IsNullOrEmptyOrWhiteSpace()) opResult.OperateResult.Add(new OperateResult { Name = "客户信息", Message = "开具纸质发票时,购买方(客户信息)开票银行信息不完整!请检查是否缺少银行信息,银行账号信息", SuccessStatus = false }); #endregion 购买方 #region 明细信息 var details = fpkj.COMMON_FPKJ_XMXX = new List(); if (opResult.OperateResult.Any()) throw new Exception("检验信息"); var entrySql = $@" SELECT ID,TaxCategoryCodeId,Number,TaxCode,MaterialName,Qty,Specification,UnitName,Price,Amount,TaxRate,TaxAmount FROM V_INVINFO_OUTSTOCKENTRY WHERE ID in ({string.Join(",", fidList)}) "; var dbList = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{entrySql}"); foreach (var item in dbList) { if (item["TaxCategoryCodeId"].Long2Int() == 0) { opResult.OperateResult.Add(new OperateResult { Name = item["Number"].ToString(), Message = $"物料:{item["Number"]} 缺少税收分类编码!", SuccessStatus = false }); continue; } details.Add(new COMMON_FPKJ_XMXX { FPHXZ = "0", SPBM = item["TaxCode"].ToString(), //ZXBM = material["Number"].ToString(), XMMC = item["MaterialName"].ToString(), XMSL = item["Qty"].ToDecimal().ToString("F6"), GGXH = item["Specification"].ToString(), DW = item["UnitName"].ToString(), XMDJ = item["Price"].ToDecimal().ToString("F6"), XMJE = item["Amount"].ToDecimal().ToString("F2"), SL = (item["TaxRate"].ToDecimal() * 0.01M).ToString("F2"), SE = item["TaxAmount"].ToDecimal().ToString("F2"), }); } if (opResult.OperateResult.Any()) throw new Exception("物料缺少税收分类编码"); #endregion 明细信息 #endregion 针对非农产收购发票 return JsonConvert.SerializeObject(result); } /// /// 发送报文信息处理 /// /// /// /// /// public BaseRequest InterfaceDataHandle(string FPLXDM, DynamicObject invInfo , Func contentAction) { //发票开具接口Code //string interfaceCode = "GP_FPKJ"; string appId = invInfo["FAPPID"].ToString(); string encodeKey = invInfo["FENCRYPTIONKEY"].ToString(); 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()); string contentDecode = contentAction(FPLXDM, invInfo); //发票报文加密处理处理 string content = Base64Helper.Base64Encode(contentDecode); string contentSHA256 = SHA256Helper.SHA256EncryptString(content); //使用加密密钥再次加密 string contentKey = AESHepler.AesEncryptorBase64(contentSHA256, encodeKey); requestBase._interface.data.content = content; requestBase._interface.data.contentKey = contentKey; } catch (Exception ex) { throw ex; } return requestBase; } /// /// 发送报文,获取结果 /// /// /// /// /// public void RequestDataHandle(string FPLXDM, long orgId, string _interfaceCode, Func contentAction, Func endAction) { var result = string.Empty; try { #region 获取对应开票信息 string whereSql = $" AND {((FPLXDM.Equals("007") || FPLXDM.Equals("004")) ? "FIsDeviceType4" : "FIsDeviceType6")} = 1 "; var iinfoSQL = $@" SELECT TOP 1 FID, FUSEORGID, FAPPID, FTAXCODE, FDRAWER, FINVOICEBANKNAME, FINVOICEBANKACCOUNT, FINVOICEADDRESS, FINVOICETEL, FINVOICETITLE, FFIRMCODE, FSERIALNUMBER, FENCRYPTIONKEY, FISDEFAULT, FISTESTINFO, FCERTIFICATE2NAME, FCERTIFICATE2KEY, FREQUESTURL 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 info = iinfoDB[0]; bool isTest = info["FISTESTINFO"].Long2Int() == 1; var requestData = InterfaceDataHandle(FPLXDM, info, contentAction); requestData._interface.globalInfo.interfaceCode = _interfaceCode; var postData = JsonConvert.SerializeObject(requestData); #endregion 获取对应开票信息 var url = info["FREQUESTURL"].ToString();//双向通道地址 if (url.IsNullOrEmptyOrWhiteSpace()) url = "https://dev.fapiao.com:18944/fpt-rhqz/prepose"; var cerName = info["FCERTIFICATE2NAME"].ToString();//证书密钥 if (cerName.IsNullOrEmptyOrWhiteSpace()) cerName = "testISSUE.pfx"; //证书文件存放地址 string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; var keyStoreFile = baseDirectory + $@"\bin\ISSUE\{cerName}"; var cerKey = info["FCERTIFICATE2KEY"].ToString(); if (cerKey.IsNullOrEmptyOrWhiteSpace()) cerKey = "123456"; var certificate2 = new X509Certificate2(keyStoreFile, cerKey); result = HttpWebHelper.DoPost(url, postData, certificate2); var responseData = JsonConvert.DeserializeObject(result); var returnStateInfo = responseData._interface.returnStateInfo; if (returnStateInfo != null) { if (returnStateInfo.returnCode.Equals("0000")) { var resContent = Base64Helper.Base64Decode(responseData._interface.data.content); var isFlag = endAction(resContent, info); } else { throw new Exception(returnStateInfo.returnMessage); } } } catch (JsonSerializationException ex) { opResult.OperateResult.Add(new OperateResult() { Name = "信息提示", Message = ex.Message, SuccessStatus = false }); opResult.OperateResult.Add(new OperateResult() { Name = "信息提示", Message = result, SuccessStatus = false }); //this.View.ShowMessage($"错误信息:{result}", MessageBoxType.Error); } catch (Exception ex) { //this.View.ShowErrMessage($"错误信息:{ex.Message}"); opResult.OperateResult.Add(new OperateResult() { Name = "信息提示", Message = ex.Message, SuccessStatus = false }); } } /// /// 列表发票开具 /// /// public void DoIssueAnInvoice2List(string FPLXDM, long orgId) { try { RequestDataHandle(FPLXDM, orgId, "GP_FPKJ", ListMergeInv_FPKJ, DataBackFill); } catch (Exception ex) { opResult.OperateResult.Add(new OperateResult { Name = "错误提示", Message = ex.Message, SuccessStatus = false }); } finally { _doingButtonFlag = false; if (opResult.OperateResult.Any()) this.View.ShowOperateResult(opResult.OperateResult); } } /// /// 数据回填更新到数据库 /// /// 回调数据 /// /// private bool DataBackFill(string content, DynamicObject invInfo) { try { this.View.ShowMessage($"报文处理成功,正在回填发票信息【财务信息】"); var idList = this.ListView.SelectedRowsInfo.Select(x => x.PrimaryKeyValue).Distinct(); //更新对应开票信息的流水号记录 var serialNumber = invInfo["FSERIALNUMBER"].Long2Int(); var newSNumber = (serialNumber > 998 ? 1 : serialNumber + 1).ToString("D3"); var updInvSql = $"/*dialect*/UPDATE T_BD_INVOICEINFORMATION SET FSERIALNUMBER = '{newSNumber}' WHERE FID = {invInfo["FID"]}"; DBUtils.Execute(this.Context, updInvSql); var resultData = JsonConvert.DeserializeObject(content); var fpInfo = string.Empty; var data = resultData.DATA; //回填发票下载地址 if (data.FPLXDM.Equals("030") || data.FPLXDM.Equals("032")) fpInfo = data.PDF_URL; else if (data.FPLXDM.Equals("007") || data.FPLXDM.Equals("004")) fpInfo = data.FP_MW; var updSql = $@"/*dialect*/ UPDATE T_SAL_OUTSTOCKFIN SET FINVOICEURL = '{fpInfo}' ,FFPLXDM = '{data.FPLXDM}' ,FFPQQLSH = '{data.FPQQLSH}' ,FINVOICENUMBER = '{data.FP_HM}' WHERE FID in ({string.Join(",", idList)}) "; //发票信息回填到数据库 var isFlag = DBUtils.Execute(this.Context, updSql); return isFlag > 0; } catch (Exception ex) { throw ex; } } } }