diff --git a/Extensions/ExtensionMethods.csproj b/Extensions/ExtensionMethods.csproj new file mode 100644 index 0000000..89d985a --- /dev/null +++ b/Extensions/ExtensionMethods.csproj @@ -0,0 +1,47 @@ + + + + + Debug + AnyCPU + {50532462-8F7F-455C-B4B3-732ED764E2FA} + Library + Properties + ExtensionMethods + ExtensionMethods + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extensions/Properties/AssemblyInfo.cs b/Extensions/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1b736bd --- /dev/null +++ b/Extensions/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Extensions")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Extensions")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("50532462-8f7f-455c-b4b3-732ed764e2fa")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Extensions/StringExtension.cs b/Extensions/StringExtension.cs new file mode 100644 index 0000000..de479fa --- /dev/null +++ b/Extensions/StringExtension.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; + +namespace ExtensionMethods +{ + public static class StringExtension + { + /// + /// 四舍五入保留2位小数 + /// + /// + /// + public static decimal ToDecimalR(this string obj) + { + return Math.Round(obj.ToDecimal(), 2, MidpointRounding.AwayFromZero); + } + + /// + /// 四舍五入保留2位小数 + /// + /// + /// + public static decimal ToDecimalR(this object obj) + { + return Math.Round(obj.ToDecimal(), 2, MidpointRounding.AwayFromZero); + } + public static decimal ToDecimalR(this decimal obj) + { + return Math.Round(obj, 2, MidpointRounding.AwayFromZero); + } + + public static decimal ToDecimal(this object obj) + { + if (obj == null) + return 0; + var str = obj.ToString().Trim(); + + decimal result; + decimal.TryParse(str, out result); + + return result; + } + + + public static decimal ToDecimal(this string obj) + { + decimal result; + decimal.TryParse(obj.Trim(), out result); + + return result; + } + } +} diff --git a/GateDge2023.sln b/GateDge2023.sln new file mode 100644 index 0000000..605b575 --- /dev/null +++ b/GateDge2023.sln @@ -0,0 +1,69 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34221.43 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProductionMaterialRequisition", "ProductionMaterialRequisition\ProductionMaterialRequisition.csproj", "{C672A706-DEAE-4541-AD5A-DCB8938FA4D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UseGetFmaterialData", "UseGetFmaterialData\UseGetFmaterialData.csproj", "{4D6BDA2D-FED0-4514-B4CD-FF32C5389247}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "珠海市供水有限公司", "珠海市供水有限公司", "{F03B5F75-6DCD-4FF8-989F-403C5EA0AA5B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "未分类", "未分类", "{2217EA0E-E53F-4ECC-A49D-F38BC743F47A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SAL_OUTSTOCK", "SAL_OUTSTOCK\SAL_OUTSTOCK.csproj", "{12B329E1-C4F2-4CA7-BF3E-313F22AD527A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnPayableInStock", "UnPayableInStock\UnPayableInStock.csproj", "{2E8D2379-C8CB-47E1-BF89-A11111F18A08}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "扩展", "扩展", "{4ACB1DA8-8A4D-451A-A5FB-3CBD7A261263}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExtensionMethods", "Extensions\ExtensionMethods.csproj", "{50532462-8F7F-455C-B4B3-732ED764E2FA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestProject1", "UnitTestProject1\UnitTestProject1.csproj", "{6EE96AB5-8FD3-4A48-912A-CA2AF5B82300}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C672A706-DEAE-4541-AD5A-DCB8938FA4D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C672A706-DEAE-4541-AD5A-DCB8938FA4D1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C672A706-DEAE-4541-AD5A-DCB8938FA4D1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C672A706-DEAE-4541-AD5A-DCB8938FA4D1}.Release|Any CPU.Build.0 = Release|Any CPU + {4D6BDA2D-FED0-4514-B4CD-FF32C5389247}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D6BDA2D-FED0-4514-B4CD-FF32C5389247}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D6BDA2D-FED0-4514-B4CD-FF32C5389247}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D6BDA2D-FED0-4514-B4CD-FF32C5389247}.Release|Any CPU.Build.0 = Release|Any CPU + {12B329E1-C4F2-4CA7-BF3E-313F22AD527A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12B329E1-C4F2-4CA7-BF3E-313F22AD527A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12B329E1-C4F2-4CA7-BF3E-313F22AD527A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12B329E1-C4F2-4CA7-BF3E-313F22AD527A}.Release|Any CPU.Build.0 = Release|Any CPU + {2E8D2379-C8CB-47E1-BF89-A11111F18A08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E8D2379-C8CB-47E1-BF89-A11111F18A08}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E8D2379-C8CB-47E1-BF89-A11111F18A08}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E8D2379-C8CB-47E1-BF89-A11111F18A08}.Release|Any CPU.Build.0 = Release|Any CPU + {50532462-8F7F-455C-B4B3-732ED764E2FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50532462-8F7F-455C-B4B3-732ED764E2FA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50532462-8F7F-455C-B4B3-732ED764E2FA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50532462-8F7F-455C-B4B3-732ED764E2FA}.Release|Any CPU.Build.0 = Release|Any CPU + {6EE96AB5-8FD3-4A48-912A-CA2AF5B82300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6EE96AB5-8FD3-4A48-912A-CA2AF5B82300}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6EE96AB5-8FD3-4A48-912A-CA2AF5B82300}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6EE96AB5-8FD3-4A48-912A-CA2AF5B82300}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C672A706-DEAE-4541-AD5A-DCB8938FA4D1} = {2217EA0E-E53F-4ECC-A49D-F38BC743F47A} + {4D6BDA2D-FED0-4514-B4CD-FF32C5389247} = {F03B5F75-6DCD-4FF8-989F-403C5EA0AA5B} + {12B329E1-C4F2-4CA7-BF3E-313F22AD527A} = {F03B5F75-6DCD-4FF8-989F-403C5EA0AA5B} + {2E8D2379-C8CB-47E1-BF89-A11111F18A08} = {F03B5F75-6DCD-4FF8-989F-403C5EA0AA5B} + {50532462-8F7F-455C-B4B3-732ED764E2FA} = {4ACB1DA8-8A4D-451A-A5FB-3CBD7A261263} + {6EE96AB5-8FD3-4A48-912A-CA2AF5B82300} = {2217EA0E-E53F-4ECC-A49D-F38BC743F47A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {16F7DBDD-F487-41D6-A856-9E9B7B3F61C5} + EndGlobalSection +EndGlobal diff --git a/ProductionMaterialRequisition/ProductionMaterialRequisition.csproj b/ProductionMaterialRequisition/ProductionMaterialRequisition.csproj new file mode 100644 index 0000000..fab4563 --- /dev/null +++ b/ProductionMaterialRequisition/ProductionMaterialRequisition.csproj @@ -0,0 +1,59 @@ + + + + + Debug + AnyCPU + {C672A706-DEAE-4541-AD5A-DCB8938FA4D1} + Library + Properties + ProductionMaterialRequisition + ProductionMaterialRequisition + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.App.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.Core.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.DataEntity.dll + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ProductionMaterialRequisition/Properties/AssemblyInfo.cs b/ProductionMaterialRequisition/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..987c6f1 --- /dev/null +++ b/ProductionMaterialRequisition/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("ProductionMaterialRequisition")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProductionMaterialRequisition")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("c672a706-deae-4541-ad5a-dcb8938fa4d1")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ProductionMaterialRequisition/SaveVerification.cs b/ProductionMaterialRequisition/SaveVerification.cs new file mode 100644 index 0000000..ad68f03 --- /dev/null +++ b/ProductionMaterialRequisition/SaveVerification.cs @@ -0,0 +1,100 @@ +using Kingdee.BOS.Core.Bill.PlugIn; +using Kingdee.BOS.Core.Bill.PlugIn.Args; +using Kingdee.BOS.App.Data; +using Kingdee.BOS.Orm.DataEntity; +using Kingdee.BOS.Core.DynamicForm; +using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; +using Kingdee.BOS.Core.Permission; +using Kingdee.BOS.Util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Linq; +using System.Text; +using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel; +using Kingdee.BOS.Core.Metadata.Util; + +namespace ProductionMaterialRequisition +{ + [HotUpdate, Description("生产领料单保存库存数量验证")] + public class SaveVerification : AbstractBillPlugIn + { + public override void BeforeSave(BeforeSaveEventArgs e) + { + + base.BeforeSave(e); + + if (VerificationStock()) + { + //this.View.ShowMessage("保存验证失败", MessageBoxType.Error); + e.Cancel = true; + } + } + + public bool VerificationStock() + { + var details = this.View.BusinessInfo.GetEntity("FEntity"); + + var entrys = this.View.Model.GetEntityDataObject(details); + if (entrys == null || !entrys.Any()) + return false; + + var id = this.View.Model.DataObject["Id"].Long2Int(); + var inDBWhere = $" AND tpp.FID !={id} "; + if (id == 0) + inDBWhere = string.Empty; + + var selectActualQtySQL = $@" +SELECT + tbm.FMATERIALID, + tbm.FUSEORGID, + tbm.FMASTERID, + SUM ( tsi.FBASEQTY ) - SUM ( tppd.FACTUALQTY ) AS 'Difference' +FROM + T_PRD_PICKMTRL tpp + LEFT JOIN T_PRD_PICKMTRLDATA tppd ON tpp.FID= tppd.FID + LEFT JOIN T_BD_MATERIAL tbm ON tbm.FMATERIALID = tppd.FMATERIALID + LEFT JOIN T_STK_INVENTORY tsi ON tbm.FMASTERID = tsi.FMATERIALID + AND tppd.FSTOCKID= tsi.FSTOCKID +WHERE + ( tpp.FDOCUMENTSTATUS = 'A' OR tpp.FDOCUMENTSTATUS = 'Z' ) + AND tsi.FISEFFECTIVED= 1 + AND tsi.fstockstatusid = 10000 + AND FBASEQTY > 0 {inDBWhere} +GROUP BY + tbm.FUSEORGID, + tbm.FMATERIALID, + tbm.FMASTERID "; + + DynamicObjectCollection actualQtylData = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{selectActualQtySQL}"); + + StringBuilder msg = new StringBuilder(); + + var tempTockOrgId = this.View.Model.GetValue("FStockOrgId"); + + var stockOrgId = tempTockOrgId == null ? 0 : tempTockOrgId.Long2Int(); + + foreach (var entry in entrys) + { + var tempObject = entry["MaterialId"] as DynamicObject; + + var tempEntity = actualQtylData.FirstOrDefault(w => + w["FMATERIALID"].Long2Int() == entry["MaterialId_Id"].Long2Int() + && w["FUSEORGID"].Long2Int() == stockOrgId); + + if (tempEntity == null) + msg.AppendLine($"物料编码:{tempObject["Number"]},物料名称:{tempObject["Name"]},可用库存:0;"); + else if (tempEntity != null && tempEntity["Difference"].Long2Int() > entry["MaterialId_Id"].Long2Int()) + msg.AppendLine($"物料编码:{tempObject["Number"]},物料名称:{tempObject["Name"]},可用库存:{tempEntity["Difference"]};"); + } + + if (msg.Length > 0) + this.View.ShowMessage(msg.ToString(), MessageBoxType.Error); + + return msg.Length > 0; + } + + } + +} diff --git a/SAL_OUTSTOCK.dll b/SAL_OUTSTOCK.dll new file mode 100644 index 0000000..ce1b347 Binary files /dev/null and b/SAL_OUTSTOCK.dll differ diff --git a/SAL_OUTSTOCK/IssueAnInvoiceFormPlugIn.cs b/SAL_OUTSTOCK/IssueAnInvoiceFormPlugIn.cs new file mode 100644 index 0000000..bc38126 --- /dev/null +++ b/SAL_OUTSTOCK/IssueAnInvoiceFormPlugIn.cs @@ -0,0 +1,535 @@ +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; + } + } +} diff --git a/SAL_OUTSTOCK/MergePrintIssueAnInvPlugIn.cs b/SAL_OUTSTOCK/MergePrintIssueAnInvPlugIn.cs new file mode 100644 index 0000000..909c651 --- /dev/null +++ b/SAL_OUTSTOCK/MergePrintIssueAnInvPlugIn.cs @@ -0,0 +1,560 @@ +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.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 = new OperationResult(); + 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.Count() == 1) + { + orgId = orgIdList.First(); + if (orgId != 101542) + DoIssueAnInvoice2List(FPLXDM, orgId); + else + this.View.ShowMessage("此功能未开放!如有需要请联系管理员!"); + } + else + { + this.View.ShowMessage("选择的单据的组织不统一!"); + } + } + _doingButtonFlag = false; + } + + + /// + /// 设置content报文明文信息 + /// + /// 发票类型 + /// 开票信息 + /// 返回信息 + /// + public string ListMergeInv_FPKJ(string FPLXDM, DynamicObject invoiceInfo) + { + var list = this.ListView.SelectedRowsInfo; + var fidList = list.Select(x => x.FormID).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,APPLYID,APPLYNAME,BILLALLAMOUNT,BILLAMOUNT,BILLTAXAMOUNT, +CUSTID,CUSTNAME,INVOICETITLE, +INVOICEBANKNAME,INVOICEBANKACCOUNT,FTAXREGISTERCODE,SOCIALCRECODE,INVOICETEL,INVOICEADDRESS +FROM V_OUTSTOCKINVINFO_HEAD +WHERE ID IN ({string.Join(",", fidList)}) +"; + + #region 针对非农产收购发票 + + #region 基础信息 + + var sHeadInfos = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{headSql}"); + + 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 + }); + + 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(); + + ////申领单位 + //var applicant = this.View.Model.GetValue("F_QNV_Base1") as DynamicObject; + //var deptMulti = applicant["MultiLanguageText"] as DynamicObjectCollection; + + #endregion 销售方 + + #region 购买方(客户信息) + + var sHeadInfo = sHeadInfos[0]; + + fpkj.BZ = sHeadInfo["APPLYNAME"].ToString(); + + fpkj.GMF_MC = (sHeadInfo["INVOICETITLE"].IsNullOrEmpty() ? (sHeadInfo["CUSTNAME"].IsNullOrEmpty() ? "" : sHeadInfo["CUSTNAME"]) : sHeadInfo["INVOICETITLE"]).ToString(); + //纳税人识别号/统一社会信用代码 + fpkj.GMF_NSRSBH = (sHeadInfo["SOCIALCRECODE"].IsNullOrEmpty() ? (sHeadInfo["FTAXREGISTERCODE"].IsNullOrEmpty() ? "" : sHeadInfo["FTAXREGISTERCODE"]) : sHeadInfo["SOCIALCRECODE"]).ToString(); + fpkj.GMF_DZDH = $"{sHeadInfo["INVOICEADDRESS"]} {sHeadInfo["INVOICETEL"]}"; + fpkj.GMF_YHZH = $"{sHeadInfo["INVOICEBANKNAME"]} {sHeadInfo["INVOICEBANKACCOUNT"]}"; + + if (fpkj.GMF_MC == string.Empty) + opResult.OperateResult.Add(new OperateResult + { + Name = "客户信息", + Message = "购买方(客户信息)名称不能为空!", + SuccessStatus = false + }); + + if (fpkj.GMF_NSRSBH == string.Empty) + opResult.OperateResult.Add(new OperateResult + { + Name = "客户信息", + Message = "购买方(客户信息)统一社会信用代码或纳税人识别号不能为空!", + SuccessStatus = false + }); + + if (isPaper && fpkj.GMF_DZDH == string.Empty) + opResult.OperateResult.Add(new OperateResult + { + Name = "客户信息", + Message = "开具纸质发票时,购买方(客户信息)开票电话地址不完整!请检查是否缺少地址信息,电话信息", + SuccessStatus = false + }); + + if (isPaper && fpkj.GMF_YHZH == string.Empty) + opResult.OperateResult.Add(new OperateResult + { + Name = "客户信息", + Message = "开具纸质发票时,购买方(客户信息)开票银行信息不完整!请检查是否缺少银行信息,银行账号信息", + SuccessStatus = false + }); + + #endregion 购买方 + + #region 明细信息 + var details = fpkj.COMMON_FPKJ_XMXX = new List(); + if (!opResult.OperateResult.Any()) + { + 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 in ({string.Join(",", fidList)}) "; + + var entrySql = $@" +SELECT + ID,FTAXCATEGORYCODEID,Number,TaxCode,MaterialName,Salunitqty,Specification,UnitName,Price,Amount,TaxRate,TaxAmount +from V_OUTSTOCKINVINFO_ENTRY + +AND ID in ({string.Join(",", fidList)}) +"; + + var dbList = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{entrySql}"); + + foreach (var item in dbList) + { + + if (item["FTAXCATEGORYCODEID"].IsNullOrEmpty()) + { + 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["Salunitqty"].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.FormID).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; + } + } + } +} diff --git a/SAL_OUTSTOCK/Properties/AssemblyInfo.cs b/SAL_OUTSTOCK/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9bde658 --- /dev/null +++ b/SAL_OUTSTOCK/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("SAL_OUTSTOCK")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SAL_OUTSTOCK")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("12b329e1-c4f2-4ca7-bf3e-313f22ad527a")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/SAL_OUTSTOCK/Request/BaseRequest.cs b/SAL_OUTSTOCK/Request/BaseRequest.cs new file mode 100644 index 0000000..529ae6e --- /dev/null +++ b/SAL_OUTSTOCK/Request/BaseRequest.cs @@ -0,0 +1,72 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SAL_OUTSTOCK.Request +{ + public class BaseRequest + { + [JsonProperty(propertyName: "interface")] + public Interface _interface { get; set; } + + public class Interface + { + public Interface() + { + globalInfo = new Globalinfo(); + returnStateInfo = new Returnstateinfo(); + data = new Data(); + } + + public Globalinfo globalInfo { get; set; } + public Returnstateinfo returnStateInfo { get; set; } + public Data data { get; set; } + } + + public class Globalinfo + { + public Globalinfo() + { + this.requestCode = "DZFPQZ"; + this.responseCode = "DS"; + } + public string appId { get; set; } + public string interfaceId { get; set; } + public string interfaceCode { get; set; } + public string requestCode { get; set; } + public string requestTime { get; set; } + public string responseCode { get; set; } + public string dataExchangeId { get; set; } + } + + public class Returnstateinfo + { + public string returnCode { get; set; } + public string returnMessage { get; set; } + } + + public class Data + { + public Data() + { + dataDescription = new Datadescription(); + } + public Datadescription dataDescription { get; set; } + public string content { get; set; } + public string contentKey { get; set; } + } + + public class Datadescription + { + public Datadescription() + { + this.zipCode = "0"; + } + + public string zipCode { get; set; } + } + + } +} diff --git a/SAL_OUTSTOCK/Request/GP_FPKJ.cs b/SAL_OUTSTOCK/Request/GP_FPKJ.cs new file mode 100644 index 0000000..d877435 --- /dev/null +++ b/SAL_OUTSTOCK/Request/GP_FPKJ.cs @@ -0,0 +1,439 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SAL_OUTSTOCK.Request +{ + public class GP_FPKJ + { + [JsonProperty(propertyName: "REQUEST_COMMON_FPKJ")] + public REQUEST_COMMON_FPKJ FPKJ { get; set; } + public class REQUEST_COMMON_FPKJ + { + /// + /// 设备编号 + /// + public string SBLX { get; set; } + + /// + /// 设备类型 必填 + /// 1-税控盘 2-金税盘 3-Ukey 4-老税控服务器 6-数电 + /// + public string SBBH { get; set; } + + /// + /// 发票请求流水号 必填 + /// 企业内部唯一请求开票流 + /// 水号,每个请求流水号只能 + /// 开一次, 流水号前面以公司 + /// 名称前缀例如国信电票: + /// GXDP201604201454001 + /// + public string FPQQLSH { get; set; } + + /// + /// 开票终端代码 + /// + public string KPZDDM { get; set; } + + /// + /// 发票类型代码 + /// 026增值税普票(电票) + /// 004增值税专票(纸票) + /// 028增值税专票(电票) + /// 007增值税普票(纸票) + /// 030数电普票 + /// 032数电专票 + /// + public string FPLXDM { get; set; } + + /// + /// 开票类型 必填 + /// 0-蓝字发票;1-红字发票 + /// + public string KPLX { get; set; } + + + public string BMB_BBH { get; set; } + /// + /// 征税方式 必填 + /// 0:普通征税 + /// 1:减按计征 + /// 2:差额征税 + /// + public string ZSFS { get; set; } + + /// + /// 征税方式信息 数电 + /// 需要开具减按计征/差额征税的票此节点必填,否则可省略 + /// 报文结构见:八、征税方式报文 + /// + public ZSFSXX ZSFSXX { get; set; } + + /// + /// 销售方纳税人识别号 + /// + public string XSF_NSRSBH { get; set; } + + /// + /// 销售方名称 + /// + public string XSF_MC { get; set; } + + /// + /// 销售方地址 电话 + /// + public string XSF_DZDH { get; set; } + + /// + /// 销售方银行账号 + /// 销售方开户行销售方银行账号(以空格分隔开户行账号) + /// + public string XSF_YHZH { get; set; } + + /// + /// 购买方纳税人识别号 + /// + public string GMF_NSRSBH { get; set; } + + /// + /// 购买方名称 + /// + public string GMF_MC { get; set; } + + /// + /// 购买方地址 电话 + /// + public string GMF_DZDH { get; set; } + + /// + /// 购买方银行账号 + /// 购买方开户行购买方银行账号(以空格分隔开户行账号) + /// + public string GMF_YHZH { get; set; } + + /// + /// 购买方手机号 + /// + public string GMF_SJH { get; set; } + + /// + /// 购买方电子邮箱 + /// + public string GMF_DZYX { get; set; } + + /// + /// 购买方发票通平台账户 + /// 发票通平台(Fapiao.com)注册账户名,用于接收和归集电子发票 + /// + public string FPT_ZH { get; set; } + + + public string WX_OPENID { get; set; } + + /// + /// 开票人 必填 + /// + public string KPR { get; set; } + + /// + /// 收款人 + /// + public string SKR { get; set; } + + /// + /// 复核人 + /// + public string FHR { get; set; } + + /// + /// 原发票代码 + /// 红字票时必填(数电不需要填) + /// + public string YFP_DM { get; set; } + + /// + /// 原发票号码 + /// 红字发票时必填 + /// + public string YFP_HM { get; set; } + + /// + /// 价税合计 必填 + /// 单位:元(2位小数) + /// + public string JSHJ { get; set; } + + /// + /// 合计金额 必填 + /// 不含税,单位:元(2位小数) + /// + public string HJJE { get; set; } + + /// + /// 合计税额 必填 + /// 单位:元(2位小数) + /// + public string HJSE { get; set; } + + /// + /// 扣除额 + /// 小数点后2位,当ZSFS为2时扣除额为必填项 + /// + public string KCE { get; set; } + + /// + /// 备注 长度240 + /// 电普备注长度应减去”对应正数发票代码:XXXXXXXXXXXX号码:YYYYYYYY\n”字样长度,长度剩余160。 + /// 专票,最大长度为184。若zsfs同时为2,备注长度为160。 + /// 普票,最大长度138。若zsfs同时为2,备注长度为114。 + /// 蓝票差额216 + /// 蓝票无差额240 + /// 红票差额181 + /// 红票无差额205 + /// + public string BZ { get; set; } + + /// + /// 原发票类型 + /// 红字发票时必填(数电不需要填) + /// + public string YFP_LX { get; set; } + + /// + /// 原发票日期 + /// 若使用金税盘盘柜,则YFP_RQ格式为YYYYMM; + /// 若SBLX=4,红字发票时必填,YYYYMMDD + /// 若SBLX = 6,数电红字发票时必填,yyyy-MM-ddHH:mm:ss + /// + public string YFP_RQ { get; set; } + + /// + /// 冲红原因代码 + /// SBLX=4(旧税控) SBLX=6(数电) + /// 红字发票时必填 1-销货退回 2-开票有误 + /// + public string CHYYDM { get; set; } + + /// + /// 3%税率开具发票理由 + /// 2、前期已开具3%征收率发票,发生销售折让、中止或者退回等情形需要开具红字发票,或者开票有误需要重新开具。 + /// 3、因为实际经营业务需要,放弃享受减按1%征收率征收增值税政策。 + /// + public string SSLKJLY { get; set; } + public string BY1 { get; set; } + + /// + /// 备用字段2 订单号 + /// + public string BY2 { get; set; } + public string BY3 { get; set; } + public string BY4 { get; set; } + public string BY5 { get; set; } + public string BY6 { get; set; } + public string BY7 { get; set; } + public string BY8 { get; set; } + public string BY9 { get; set; } + public string BY10 { get; set; } + public string WX_ORDER_ID { get; set; } + public string WX_APP_ID { get; set; } + public string ZFB_UID { get; set; } + + /// + /// 特殊代码标识 见:6.3.特殊票种(特定要素类型)代码 + /// + public string TSPZ { get; set; } + public TSPZXX TSPZXX { get; set; } + + /// + /// 全局唯一订单ID + /// 通过税号、内部唯一流水号等做MD5后的值 + /// + public string QJ_ORDER_ID { get; set; } + + /// + /// 清单标志 + /// 纸票字段 0无清单 1有清单 + /// + public string QDBZ { get; set; } + + /// + /// 通知单编号 + /// 非数电专票字段:16位数字,通知单编号 + /// 数电专票或普票字段:代表信息表编号(XXBBH) + /// 数电开具红票,若已申请红字确认单,则必填 + /// + public string TZDBH { get; set; } + + /// + /// 红字确认单UUID + /// 数电非必填 + /// 数电开具红票,若已申请红 + /// 字确认单,则必填 + /// + public string HZQRDUUID { get; set; } + + /// + /// 经办人证件号码 数电 + /// + public string JBRZJHM { get; set; } + + /// + /// 经办人证件种类代码 数电 + /// 见:6.1经办人证件种类代码码表 + /// + public string JBRZJZLDM { get; set; } + + /// + /// 经办人国籍代码 数电 + /// 见:6.2经办人国籍代码 + /// + public string JBRGJDM { get; set; } + + /// + /// 经办人纳税人识别号 数电 + /// + public string JBRZRRNSRSBH { get; set; } + + /// + /// 经办人姓名 数电 + /// + public string JBRXM { get; set; } + + /// + /// 购买方自然人标识 数电 + /// 默认N Y-是N-否 + /// + public string GMF_ZRRBS { get; set; } + + /// + /// 是否展示购买方银行账号 数电 + /// Y-是N-否 + /// + public string SFZSGMFYHZH { get; set; } + + /// + /// 是否展示销售方银行账号 数电 + /// Y-是N-否 + /// + public string SFZSXSFYHZH { get; set; } + + /// + /// 项目明细(最大100条) + /// + public List COMMON_FPKJ_XMXX { get; set; } + + /// + /// 回调地址 500 仅异步返回时生效 + /// + public string CALLBACK_URL { get; set; } + + /// + /// 流水号 36 供异步返回或异步推送时使用,请求唯一,除非是二次查询结果的重复请求 + /// + public string LSH { get; set; } + + + } + + public class ZSFSXX + { + } + public class TSPZXX + { + public object[] TDYS { get; set; } + } + + public class COMMON_FPKJ_XMXX + { + /// + /// 发票行性质 必填 0正常行、1折扣行、2被折扣行 + /// + public string FPHXZ { get; set; } + + /// + /// 商品编码 必填 + /// + public string SPBM { get; set; } + + /// + /// 自行编码 + /// + public string ZXBM { get; set; } + + /// + /// 优惠政策标识 + /// 0:不使用,1:使用 + /// + public string YHZCBS { get; set; } + + /// + /// 零税率标识 + /// 空:非零税率,1:免税,2:不征收,3普通零税率 + /// + public string LSLBS { get; set; } + + /// + /// 增值税特殊管理 + /// + public string ZZSTSGL { get; set; } + + /// + /// 项目名称 必填 + /// 如果为折扣行,商品名称须与被折扣行的商品名称相同,不能多行折扣。 + /// + public string XMMC { get; set; } + + /// + /// 规格型号 + /// + public string GGXH { get; set; } + + /// + /// 计量单位 + /// 若TSPZ为08,此项必填,必须为“吨”或者“升” + /// + public string DW { get; set; } + + /// + /// 项目数量 + /// 总长度包含小数点不能超过15位;若TSPZ为08,此项必填,不能为0。 + /// + public string XMSL { get; set; } + + /// + /// 项目单价 + /// 卷票为含税,其他不含税。 + /// 总长度包含小数点不能超过15位(只有当ZSFS为1时,此处填含税单价) + /// 若TSPZ为08,此项必填,不能为0。 + /// + public string XMDJ { get; set; } + + /// + /// 项目金额 必填 + /// 卷票为含税,其他不含税。单位:元(最多保留2位小数) + /// (只有当ZSFS为1时,此处填含税金额) + /// + public string XMJE { get; set; } + + /// + /// 税率 必填 + /// 2位小数,例1%为0.01 + /// + public string SL { get; set; } + + /// + /// 税额 必填 + /// 单位:元(2位小数) + /// + public string SE { get; set; } + public string BY1 { get; set; } + public string BY2 { get; set; } + public string BY3 { get; set; } + public string BY4 { get; set; } + public string BY5 { get; set; } + } + } +} diff --git a/SAL_OUTSTOCK/Response/ResultData.cs b/SAL_OUTSTOCK/Response/ResultData.cs new file mode 100644 index 0000000..610f946 --- /dev/null +++ b/SAL_OUTSTOCK/Response/ResultData.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SAL_OUTSTOCK.Response +{ + public class ResultData + { + + public string CODE { get; set; } + public string MESSAGE { get; set; } + public GP_FPKJ_DATA DATA { get; set; } + + + public class GP_FPKJ_DATA + { + public string FPQQLSH { get; set; } + public string FPLXDM { get; set; } + public string FP_DM { get; set; } + public string FP_HM { get; set; } + public string KPRQ { get; set; } + public string JYM { get; set; } + public string FP_MW { get; set; } + public string PDF_URL { get; set; } + public string OFD_URL { get; set; } + public string XML_URL { get; set; } + public string SP_URL { get; set; } + } + + } +} diff --git a/SAL_OUTSTOCK/SAL_OUTSTOCK.csproj b/SAL_OUTSTOCK/SAL_OUTSTOCK.csproj new file mode 100644 index 0000000..40b69de --- /dev/null +++ b/SAL_OUTSTOCK/SAL_OUTSTOCK.csproj @@ -0,0 +1,84 @@ + + + + + Debug + AnyCPU + {12B329E1-C4F2-4CA7-BF3E-313F22AD527A} + Library + Properties + SAL_OUTSTOCK + SAL_OUTSTOCK + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.App.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.Core.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.DataEntity.dll + + + False + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {50532462-8f7f-455c-b4b3-732ed764e2fa} + ExtensionMethods + + + + \ No newline at end of file diff --git a/SAL_OUTSTOCK/Utils/AESHepler.cs b/SAL_OUTSTOCK/Utils/AESHepler.cs new file mode 100644 index 0000000..cbf3596 --- /dev/null +++ b/SAL_OUTSTOCK/Utils/AESHepler.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace SAL_OUTSTOCK.Utils +{ + internal static class AESHepler + { + /// + /// AES 算法加密(ECB模式) 将明文加密,加密后进行base64编码,返回密文 + /// + /// 明文 + /// 密钥 + /// 加密后base64编码的密文 + public static string AesEncryptorBase64(string EncryptStr, string Key) + { + try + { + //byte[] keyArray = Encoding.UTF8.GetBytes(Key); + byte[] toEncryptArray = Encoding.UTF8.GetBytes(EncryptStr); + + RijndaelManaged rDel = new RijndaelManaged(); + //rDel.Key = keyArray; + rDel.Key = Encoding.UTF8.GetBytes(Key); + rDel.Mode = CipherMode.ECB; + rDel.Padding = PaddingMode.PKCS7; + + ICryptoTransform cTransform = rDel.CreateEncryptor(); + byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); + + return Convert.ToBase64String(resultArray, 0, resultArray.Length); + } + catch (Exception ex) + { + return ex.Message; + } + } + + /// + /// + /// + /// + /// + private static byte[] hexStringToByteArray(string strHex) + { + strHex = strHex.Replace(" ", ""); + byte[] buffer = new byte[strHex.Length / 2]; + for (int i = 0; i < strHex.Length; i += 2) + { + buffer[i / 2] = (byte)Convert.ToByte(strHex.Substring(i, 2), 16); + } + return buffer; + } + } +} diff --git a/SAL_OUTSTOCK/Utils/Base64Helper.cs b/SAL_OUTSTOCK/Utils/Base64Helper.cs new file mode 100644 index 0000000..35c53b5 --- /dev/null +++ b/SAL_OUTSTOCK/Utils/Base64Helper.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SAL_OUTSTOCK.Utils +{ + + public static class Base64Helper + { + /// + /// Base64加密,采用utf8编码方式加密 + /// + /// 待加密的明文 + /// 加密后的字符串 + public static string Base64Encode(string source) + { + return Base64Encode(Encoding.UTF8, source); + } + + /// + /// Base64加密 + /// + /// 加密采用的编码方式 + /// 待加密的明文 + /// + public static string Base64Encode(Encoding encodeType, string source) + { + string encode = string.Empty; + byte[] bytes = encodeType.GetBytes(source); + try + { + encode = Convert.ToBase64String(bytes); + } + catch + { + encode = source; + } + return encode; + } + + /// + /// Base64解密,采用utf8编码方式解密 + /// + /// 待解密的密文 + /// 解密后的字符串 + public static string Base64Decode(string result) + { + return Base64Decode(Encoding.UTF8, result); + } + + /// + /// Base64解密 + /// + /// 解密采用的编码方式,注意和加密时采用的方式一致 + /// 待解密的密文 + /// 解密后的字符串 + public static string Base64Decode(Encoding encodeType, string result) + { + string decode = string.Empty; + byte[] bytes = Convert.FromBase64String(result); + try + { + decode = encodeType.GetString(bytes); + } + catch + { + decode = result; + } + return decode; + } + } + +} diff --git a/SAL_OUTSTOCK/Utils/HttpWebHelper.cs b/SAL_OUTSTOCK/Utils/HttpWebHelper.cs new file mode 100644 index 0000000..cc30191 --- /dev/null +++ b/SAL_OUTSTOCK/Utils/HttpWebHelper.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Security; +using System.Net; +using System.Security.Cryptography.X509Certificates; +using System.Text; + +namespace SAL_OUTSTOCK.Utils +{ + public static class HttpWebHelper + { + /// + /// post请求 + /// + /// 请求地址 + /// 请求数据 + /// 证书 + /// + public static string DoPost(string url, string postData, X509Certificate2 certificate2) + { + 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 baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + + ////证书 + //var keystorefile = baseDirectory + @"\bin\ISSUE\testISSUE.pfx"; + //var key = "123456"; + //var cer = new X509Certificate2(keystorefile, key); + + if (certificate2 != null) + request.ClientCertificates.Add(certificate2); + + 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; + } + + } + + /// + /// post请求 + /// + /// + /// + /// + public static string DoPost(string url, string postData) + { + return DoPost(url, postData, null); + } + + private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) + { + if (errors == SslPolicyErrors.None) + return true; //总是接受 + + return false; + } + } +} diff --git a/SAL_OUTSTOCK/Utils/SHA256Helper.cs b/SAL_OUTSTOCK/Utils/SHA256Helper.cs new file mode 100644 index 0000000..af36c0a --- /dev/null +++ b/SAL_OUTSTOCK/Utils/SHA256Helper.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; + +namespace SAL_OUTSTOCK.Utils +{ + internal static class SHA256Helper + { + /// + /// SHA256加密 + /// + /// + /// + public static string SHA256EncryptString(string data) + { + byte[] bytes = Encoding.UTF8.GetBytes(data); + byte[] hash = SHA256Managed.Create().ComputeHash(bytes); + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < hash.Length; i++) + { + builder.Append(hash[i].ToString("x2")); + } + return builder.ToString(); + } + + /// + /// SHA256加密 + /// + /// 待加密字符串 + /// 加密数组 + public static Byte[] SHA256EncryptByte(string StrIn) + { + var sha256 = new SHA256Managed(); + var Asc = new ASCIIEncoding(); + var tmpByte = Asc.GetBytes(StrIn); + var EncryptBytes = sha256.ComputeHash(tmpByte); + sha256.Clear(); + return EncryptBytes; + } + } +} diff --git a/UnPayableInStock/Properties/AssemblyInfo.cs b/UnPayableInStock/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2898fb5 --- /dev/null +++ b/UnPayableInStock/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("UnPayableInStock")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UnPayableInStock")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("2e8d2379-c8cb-47e1-bf89-a11111f18a08")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnPayableInStock/TUPISSQLFilterPlugIn.cs b/UnPayableInStock/TUPISSQLFilterPlugIn.cs new file mode 100644 index 0000000..6c99de5 --- /dev/null +++ b/UnPayableInStock/TUPISSQLFilterPlugIn.cs @@ -0,0 +1,45 @@ +using Kingdee.BOS; +using Kingdee.BOS.Core.CommonFilter; +using Kingdee.BOS.Core.CommonFilter.PlugIn; +using Kingdee.BOS.Core.DynamicForm; +using Kingdee.BOS.Core.Log; +using Kingdee.BOS.Core.Metadata; +using Kingdee.BOS.Core.Metadata.EntityElement; +using Kingdee.BOS.Core.Metadata.Expression.FuncDefine; +using Kingdee.BOS.Core.Metadata.FieldElement; +using Kingdee.BOS.Core.Objects; +using Kingdee.BOS.Core.Permission; +using Kingdee.BOS.Core.ReportFilter; +using Kingdee.BOS.Core.SqlBuilder; +using Kingdee.BOS.Model.ReportFilter; +using Kingdee.BOS.Orm.DataEntity; +using Kingdee.BOS.Orm.Metadata.DataEntity; +using Kingdee.BOS.Util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace UnPayableInStock +{ + [HotUpdate,Description("无关联应付单的采购入库单的过滤条件默认值设置")] + public class TUPISSQLFilterPlugIn : AbstractCommonFilterPlugIn + { + public override void BeforeBindData(EventArgs e) + { + base.BeforeBindData(e); + var sqlModel = this.Model as SQLReportFilterModel; + if (sqlModel == null) + return; + var startDField = sqlModel.SQLFilterObject.FilterFieldList.FirstOrDefault(m => m.KeyWord == "#FStartDate#"); + var endDField = sqlModel.SQLFilterObject.FilterFieldList.FirstOrDefault(m => m.KeyWord == "#FEndDate#"); + DateTime time = DateTime.Now; + startDField.DefaultValue = time.AddDays(1 - time.Day).ToShortDateString(); + endDField.DefaultValue = time.AddDays(1 - time.Day).AddMonths(1).AddDays(-1).ToShortDateString(); + + + } + } + +} diff --git a/UnPayableInStock/UnPayableInStock.csproj b/UnPayableInStock/UnPayableInStock.csproj new file mode 100644 index 0000000..539f5a8 --- /dev/null +++ b/UnPayableInStock/UnPayableInStock.csproj @@ -0,0 +1,62 @@ + + + + + Debug + AnyCPU + {2E8D2379-C8CB-47E1-BF89-A11111F18A08} + Library + Properties + UnPayableInStock + UnPayableInStock + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.App.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.Core.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.DataEntity.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.Model.dll + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UnitTestProject1/Properties/AssemblyInfo.cs b/UnitTestProject1/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7fda6a7 --- /dev/null +++ b/UnitTestProject1/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("UnitTestProject1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UnitTestProject1")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("6ee96ab5-8fd3-4a48-912a-ca2af5b82300")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UnitTestProject1/UnitTest1.cs b/UnitTestProject1/UnitTest1.cs new file mode 100644 index 0000000..00ec73c --- /dev/null +++ b/UnitTestProject1/UnitTest1.cs @@ -0,0 +1,20 @@ +using ExtensionMethods; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; + +namespace UnitTestProject1 +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + + object ttt = " "; + + var dd = ttt.ToDecimalR(); + return; + } + } +} diff --git a/UnitTestProject1/UnitTestProject1.csproj b/UnitTestProject1/UnitTestProject1.csproj new file mode 100644 index 0000000..017bd92 --- /dev/null +++ b/UnitTestProject1/UnitTestProject1.csproj @@ -0,0 +1,74 @@ + + + + + + Debug + AnyCPU + {6EE96AB5-8FD3-4A48-912A-CA2AF5B82300} + Library + Properties + UnitTestProject1 + UnitTestProject1 + v4.5 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.2.2.10\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + {50532462-8f7f-455c-b4b3-732ed764e2fa} + ExtensionMethods + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + \ No newline at end of file diff --git a/UnitTestProject1/packages.config b/UnitTestProject1/packages.config new file mode 100644 index 0000000..63f7626 --- /dev/null +++ b/UnitTestProject1/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/UseGetFmaterialData.dll b/UseGetFmaterialData.dll new file mode 100644 index 0000000..b7a4420 Binary files /dev/null and b/UseGetFmaterialData.dll differ diff --git a/UseGetFmaterialData/BeforeSaveEventBillPlugIn.cs b/UseGetFmaterialData/BeforeSaveEventBillPlugIn.cs new file mode 100644 index 0000000..b5d97f9 --- /dev/null +++ b/UseGetFmaterialData/BeforeSaveEventBillPlugIn.cs @@ -0,0 +1,195 @@ +using ExtensionMethods; +using Kingdee.BOS.App.Data; +using Kingdee.BOS.Core.Bill.PlugIn; +using Kingdee.BOS.Core.Bill.PlugIn.Args; +using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; +using Kingdee.BOS.Core.Metadata.EntityElement; +using Kingdee.BOS.Orm.DataEntity; +using Kingdee.BOS.Util; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +namespace UseGetFmaterialData +{ + /// + /// 【单据插件】保存前事件 + /// 触发顺序:BeforeDoOperation->BeforeSave + /// + [Description("【单据插件】保存前事件"), HotUpdate] + public class BeforeSaveEventBillPlugIn : AbstractBillPlugIn + { + + public override void BeforeSave(BeforeSaveEventArgs e) + { + base.BeforeSave(e); + this.View.ShowMessage("插件触发了保存前事件:BeforeSave"); + + if (this.Model.DataObject["Id"].Long2Int() == 0) + if (OrgIdCheck()) + { + Entity details = null; + + //其他出库单 明细表 + if (this.View.UserParameterKey.Equals("STK_MisDelivery")) + details = this.View.BusinessInfo.GetEntity("FEntity"); + + //直接调拨单 明细表 + if (this.View.UserParameterKey.Equals("STK_TransferDirect")) + details = this.View.BusinessInfo.GetEntity("FBillEntry"); + + if (details != null) + { + var entrys = this.View.Model.GetEntityDataObject(details); + + if (entrys != null && entrys.Any()) + { + var tempValue2 = this.View.Model.GetValue("FDATE"); + var dateValue = tempValue2.IsNullOrEmptyOrWhiteSpace() ? string.Empty : tempValue2.ToString(); + foreach (var entry in entrys) + { + var rowIndex = this.View.Model.GetRowIndex(details, entry); + var tempValue = entry["MaterialId_Id"]; + var rowValue = tempValue.IsNullOrEmptyOrWhiteSpace() ? string.Empty : tempValue.ToString(); + UpdReferPriceAndExplain(dateValue, rowValue, rowIndex); + } + TotalReferAmount(entrys, details); + } + } + } + } + + + /// + /// 参考金额汇总 + /// + /// + public void TotalReferAmount(DynamicObjectCollection entrys, Entity details) + { + if (entrys == null) + { + //其他出库单 明细表 + if (this.View.UserParameterKey.Equals("STK_MisDelivery")) + details = this.View.BusinessInfo.GetEntity("FEntity"); + + //直接调拨单 明细表 + if (this.View.UserParameterKey.Equals("STK_TransferDirect")) + details = this.View.BusinessInfo.GetEntity("FBillEntry"); + + if (details != null) + entrys = this.View.Model.GetEntityDataObject(details); + } + + var total = 0M; + + if (entrys != null && entrys.Any()) + { + foreach (var entry in entrys) + { + var rowIndex = this.View.Model.GetRowIndex(details, entry); + var tAmount = this.View.Model.GetValue("FReferAmount", rowIndex).ToDecimal(); + total += tAmount; + } + } + + try + { + this.View.Model.SetValue("F_GAT_Decimal1", total); + this.View.Model.SetValue("FTotalReferAmount", total); + } + catch + { + try + { + this.View.Model.SetValue("FTotalReferAmount", total); + this.View.Model.SetValue("F_GAT_Decimal1", total); + } + catch { } + finally { } + } + finally { } + } + + /// + /// 检测组织 + /// + /// + public bool OrgIdCheck() + { + //直接调拨单 调出库存组织 + var org = this.View.Model.GetValue("FStockOutOrgId") as DynamicObject; + //其他出库单 库存组织 + if (org == null) + org = this.View.Model.GetValue("FStockOrgId") as DynamicObject; + + return org != null && Convert.ToInt32(org["Id"]) != 101542; + } + + /// + /// 更新对应行数的参考单价与取价方向 + /// + /// 表头日期 + /// 子表物料id(物料编码) + /// + private void UpdReferPriceAndExplain(string date, string materialId, int row) + { + var returnFlag = false; + + if (date.IsNullOrEmptyOrWhiteSpace()) + returnFlag = true; + + if (!returnFlag && (materialId.IsNullOrEmptyOrWhiteSpace() || materialId.Equals("0"))) + returnFlag = true; + + if (returnFlag) + { + //参考单价 + this.View.Model.SetValue("FReferPrice", "", row); + //参考金额 + this.View.Model.SetValue("FReferAmount", "", row); + ////小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", 0, row); + //参考方向 + this.View.Model.SetValue("FExplain", "", row); + } + else + { + var sqlL = $"EXEC GetFmaterialData {materialId},'{date}'"; + + var dataSet = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{sqlL}"); + + if (dataSet != null && dataSet.Any()) + { + var price = dataSet[0]["Fprice"].ToDecimalR(); + //数量 + var qty = this.View.Model.GetValue("FQty", row).ToDecimal(); + + var amount = (qty * price).ToDecimalR(); + //参考单价 + this.View.Model.SetValue("FReferPrice", (price == 0 ? "" : price.ToString()), row); + + //参考金额 + this.View.Model.SetValue("FReferAmount", (amount == 0 ? "" : amount.ToString()), row); + //小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", amount, row); + + //参考方向 + this.View.Model.SetValue("FExplain", dataSet[0]["FNOTE"], row); + } + else + { + //参考单价 + this.View.Model.SetValue("FReferPrice", "", row); + //参考金额 + this.View.Model.SetValue("FReferAmount", "", row); + //小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", 0, row); + //参考方向 + this.View.Model.SetValue("FExplain", "", row); + } + } + } + } +} diff --git a/UseGetFmaterialData/DataChangedEventFormPlugIn.cs b/UseGetFmaterialData/DataChangedEventFormPlugIn.cs new file mode 100644 index 0000000..d161ca8 --- /dev/null +++ b/UseGetFmaterialData/DataChangedEventFormPlugIn.cs @@ -0,0 +1,261 @@ +using ExtensionMethods; +using Kingdee.BOS.App.Data; +using Kingdee.BOS.Core.DynamicForm.PlugIn; +using Kingdee.BOS.Core.DynamicForm.PlugIn.Args; +using Kingdee.BOS.Core.Metadata.EntityElement; +using Kingdee.BOS.Core.Metadata.Util; +using Kingdee.BOS.Orm.DataEntity; +using Kingdee.BOS.Util; +using System; +using System.ComponentModel; +using System.Linq; +using static System.Net.WebRequestMethods; + +namespace UseGetFmaterialData +{ + [Description("根据日期,物料Id更新参考单价、取价方向、参考金额-控件触发、新增加载触发"), HotUpdate] + + public class DataChangedEventFormPlugIn : AbstractDynamicFormPlugIn + + { + //对应控件数值改变时触发 + public override void DataChanged(DataChangedEventArgs e) + { + + base.DataChanged(e); + + //表头日期 + if (e.Field.Key.EqualsIgnoreCase("FDATE")) + { + if (OrgIdCheck()) + { + Entity details = null; + + //其他出库单 明细表 + if (this.View.UserParameterKey.Equals("STK_MisDelivery")) + details = this.View.BusinessInfo.GetEntity("FEntity"); + + //直接调拨单 明细表 + if (this.View.UserParameterKey.Equals("STK_TransferDirect")) + details = this.View.BusinessInfo.GetEntity("FBillEntry"); + + if (details != null) + { + var entrys = this.View.Model.GetEntityDataObject(details); + + if (entrys != null && entrys.Any()) + { + var dateValue = e.NewValue == null ? string.Empty : e.NewValue.ToString(); + foreach (var entry in entrys) + { + var rowIndex = this.View.Model.GetRowIndex(details, entry); + var tempValue = entry["MaterialId_Id"]; + var rowValue = tempValue == null ? string.Empty : tempValue.ToString(); + UpdReferPriceAndExplain(dateValue, rowValue, rowIndex); + } + TotalReferAmount(entrys, details); + } + } + } + } + + //子表物料id + if (e.Field.Key.EqualsIgnoreCase("FMaterialId")) + { + if (OrgIdCheck()) + { + var rowValue = e.NewValue == null ? string.Empty : e.NewValue.ToString(); + var tempValue = this.View.Model.GetValue("FDATE"); + var dateValue = tempValue == null ? string.Empty : tempValue.ToString(); + UpdReferPriceAndExplain(dateValue, rowValue, e.Row); + TotalReferAmount(null, null); + } + } + + //数量 + if (e.Field.Key.EqualsIgnoreCase("FQty")) + { + + if (OrgIdCheck()) + { + //参考单价 + var referPrice = this.View.Model.GetValue("FReferPrice", e.Row).ToDecimalR(); + var amount = (e.NewValue.ToDecimal() * referPrice).ToDecimalR(); + //参考金额 + this.View.Model.SetValue("FReferAmount", amount, e.Row); + //小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", amount, e.Row); + TotalReferAmount(null, null); + } + } + } + + //新增加载时触发 + public override void AfterCreateNewData(EventArgs e) + { + base.AfterCreateNewData(e); + + if (OrgIdCheck()) + { + Entity details = null; + + //其他出库单 明细表 + if (this.View.UserParameterKey.Equals("STK_MisDelivery")) + details = this.View.BusinessInfo.GetEntity("FEntity"); + + //直接调拨单 明细表 + if (this.View.UserParameterKey.Equals("STK_TransferDirect")) + details = this.View.BusinessInfo.GetEntity("FBillEntry"); + + if (details != null) + { + var entrys = this.View.Model.GetEntityDataObject(details); + + if (entrys != null && entrys.Any()) + { + var tempValue2 = this.View.Model.GetValue("FDATE"); + var dateValue = tempValue2.IsNullOrEmptyOrWhiteSpace() ? string.Empty : tempValue2.ToString(); + foreach (var entry in entrys) + { + var rowIndex = this.View.Model.GetRowIndex(details, entry); + var tempValue = entry["MaterialId_Id"]; + var rowValue = tempValue.IsNullOrEmptyOrWhiteSpace() ? string.Empty : tempValue.ToString(); + UpdReferPriceAndExplain(dateValue, rowValue, rowIndex); + } + TotalReferAmount(entrys, details); + } + } + } + + } + + + /// + /// 参考金额汇总 + /// + /// + public void TotalReferAmount(DynamicObjectCollection entrys, Entity details) + { + if (entrys == null) + { + //其他出库单 明细表 + if (this.View.UserParameterKey.Equals("STK_MisDelivery")) + details = this.View.BusinessInfo.GetEntity("FEntity"); + + //直接调拨单 明细表 + if (this.View.UserParameterKey.Equals("STK_TransferDirect")) + details = this.View.BusinessInfo.GetEntity("FBillEntry"); + + if (details != null) + entrys = this.View.Model.GetEntityDataObject(details); + } + + var total = 0M; + + if (entrys != null && entrys.Any()) + { + foreach (var entry in entrys) + { + var rowIndex = this.View.Model.GetRowIndex(details, entry); + var tAmount = this.View.Model.GetValue("FReferAmount", rowIndex).ToDecimal(); + total += tAmount; + } + } + + try + { + this.View.Model.SetValue("F_GAT_Decimal1", total); + } + catch + { + try + { + this.View.Model.SetValue("FTotalReferAmount", total); + } + catch { } + finally { } + } + finally { } + } + + /// + /// 检测组织 + /// + /// + public bool OrgIdCheck() + { + //直接调拨单 调出库存组织 + var org = this.View.Model.GetValue("FStockOutOrgId") as DynamicObject; + //其他出库单 库存组织 + if (org == null) + org = this.View.Model.GetValue("FStockOrgId") as DynamicObject; + + return org != null && Convert.ToInt32(org["Id"]) == 101542; + } + + /// + /// 更新对应行数的参考单价与取价方向 + /// + /// 表头日期 + /// 子表物料id(物料编码) + /// + private void UpdReferPriceAndExplain(string date, string materialId, int row) + { + var returnFlag = false; + + if (date.IsNullOrEmptyOrWhiteSpace()) + returnFlag = true; + + if (!returnFlag && (materialId.IsNullOrEmptyOrWhiteSpace() || materialId.Equals("0"))) + returnFlag = true; + + if (returnFlag) + { + //参考单价 + this.View.Model.SetValue("FReferPrice", "", row); + //参考金额 + this.View.Model.SetValue("FReferAmount", "", row); + ////小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", 0, row); + //参考方向 + this.View.Model.SetValue("FExplain", "", row); + } + else + { + var sqlL = $"EXEC GetFmaterialData {materialId},'{date}'"; + + var dataSet = DBUtils.ExecuteDynamicObject(this.Context, $"/*dialect*/{sqlL}"); + + if (dataSet != null && dataSet.Any()) + { + var price = dataSet[0]["Fprice"].ToDecimalR(); + //数量 + var qty = this.View.Model.GetValue("FQty", row).ToDecimal(); + + var amount = (qty * price).ToDecimalR(); + //参考单价 + this.View.Model.SetValue("FReferPrice", (price == 0 ? "" : price.ToString()), row); + + //参考金额 + this.View.Model.SetValue("FReferAmount", (amount == 0 ? "" : amount.ToString()), row); + //小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", amount, row); + + //参考方向 + this.View.Model.SetValue("FExplain", dataSet[0]["FNOTE"], row); + } + else + { + //参考单价 + this.View.Model.SetValue("FReferPrice", "", row); + //参考金额 + this.View.Model.SetValue("FReferAmount", "", row); + //小数类型参考金额控件 + //this.View.Model.SetValue("FReferAmountM", 0, row); + //参考方向 + this.View.Model.SetValue("FExplain", "", row); + } + } + } + } +} diff --git a/UseGetFmaterialData/Properties/AssemblyInfo.cs b/UseGetFmaterialData/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..af07156 --- /dev/null +++ b/UseGetFmaterialData/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("UseGetFmaterialData")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UseGetFmaterialData")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("4d6bda2d-fed0-4514-b4cd-ff32c5389247")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UseGetFmaterialData/UseGetFmaterialData.csproj b/UseGetFmaterialData/UseGetFmaterialData.csproj new file mode 100644 index 0000000..3e12908 --- /dev/null +++ b/UseGetFmaterialData/UseGetFmaterialData.csproj @@ -0,0 +1,70 @@ + + + + + Debug + AnyCPU + {4D6BDA2D-FED0-4514-B4CD-FF32C5389247} + Library + Properties + UseGetFmaterialData + UseGetFmaterialData + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.App.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.Core.dll + + + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Kingdee.BOS.DataEntity.dll + + + False + ..\..\..\..\..\Program Files (x86)\Kingdee\K3Cloud\WebSite\bin\Newtonsoft.Json.dll + + + + + + + + + + + + + + + + + {50532462-8f7f-455c-b4b3-732ed764e2fa} + ExtensionMethods + + + + \ No newline at end of file diff --git a/月度生产计划表-预测单.sql b/月度生产计划表-预测单.sql new file mode 100644 index 0000000..7300218 --- /dev/null +++ b/月度生产计划表-预测单.sql @@ -0,0 +1,48 @@ +declare @LCID int +set @LCID = 2052 +SELECT + A.FBILLNO + ,ae.FMATERIALID + ,b.FBILLNO + --,'' AS 'Ʒ' + --,(CASE + -- FEXPUNIT + -- WHEN 'Y' THEN + -- CONVERT ( VARCHAR, BA.FEXPPERIOD ) + '' + -- WHEN 'M' THEN + -- CONVERT ( VARCHAR, ba.FEXPPERIOD) + '' + -- WHEN 'D' THEN + -- CONVERT ( VARCHAR, ba.FEXPPERIOD ) + '' ELSE '' + --END) as 'Ч' + --,'' as '׼' + --,'' as 'ÿ' + --,'' as 'װ' + --,'' as 'װ-ֵ' + --,a.FUNITID + --,'' as 'λ' + --,'' as 'ȫ' + --,BA.FSAFESTOCK AS 'ȫ' + ,AE.m01 as 'Ԥ' + ,AE.s01 as 'ǰ·' + ,AE.s02 as 'ǰ·' + ,AE.s03 as 'ǰһ·' + --,EE_A.FSTOCKINQUAAUXQTY as '' + --,'' as '' + --,(EE_A.FSTOCKINQUAAUXQTY + 0) as 'ϼƿ' + --,'' as 'ƻ' + --,DE.FQTY AS 'ƻ' + --,DE.FREMARK AS 'ע' +FROM + T_PLN_FORECAST A --Ԥⵥ + left join T_PLN_FORECASTENTRY AE on a.FID = ae.FID + left join T_PLN_PLANORDER_B B_b on ae.FENTRYID = b_b.FSALEORDERENTRYID and a.FID = b_b.FSALEORDERID + left join T_PLN_PLANORDER B on b.FID = b_b.FID + --T_PLN_PLANORDER A --ƻ + --LEFT JOIN T_BD_MATERIAL B ON A.FMATERIALID = B.FMATERIALID -- + --LEFT JOIN T_BD_MATERIALSTOCK BA ON BA.FMATERIALID = B.FMATERIALID + --LEFT JOIN T_PLN_FORECASTENTRY DE ON DE.FMATERIALID = B.FMATERIALID --Ԥⵥ + --left join T_PLN_FORECAST d on de.FID = d.FID + --LEFT JOIN T_PRD_MOENTRY EE ON EE.FMATERIALID = B.FMATERIALID -- + --LEFT JOIN T_PRD_MOENTRY_A EE_A ON EE_A.FENTRYID = EE.FENTRYID AND EE.FID =EE_A.FID -- +where a.fdate ='2023-12-01' +-- A.FRELEASETYPE = 1 \ No newline at end of file diff --git a/月度生产计划表.sql b/月度生产计划表.sql new file mode 100644 index 0000000..46a1eb8 --- /dev/null +++ b/月度生产计划表.sql @@ -0,0 +1,60 @@ +--DECLARE @date date,@startDate datetime ,@endDate datetime +--set @date = '2023-07-15' +--select +-- @startDate = dateadd(month, datediff(month, 0, @date), 0) +-- ,@endDate = dateadd(ms,-3, dateadd(month, datediff(month, 0, dateadd(month, 1, @date)), 0)) +--select +--@startDate,@endDate + +declare @LCID int +set @LCID = 2052 +SELECT + A.FMATERIALID + ,a.FBILLNO + ,ee.FSRCBILLNO + --,B_L.FNAME AS '产品名称' + ,(CASE + FEXPUNIT + WHEN 'Y' THEN + CONVERT ( VARCHAR, BA.FEXPPERIOD ) + '年' + WHEN 'M' THEN + CONVERT ( VARCHAR, ba.FEXPPERIOD) + '月' + WHEN 'D' THEN + CONVERT ( VARCHAR, ba.FEXPPERIOD ) + '日' ELSE '' + END) as '有效期' + + ,'' as '有效期' + ,'' as '标准批量' + ,'' as '每批产量(件)' + ,'' as '包装规格' + ,'' as '包装规格' + ,a.FUNITID + ,'' as '单位' + --,C_L.FNAME AS '单位' + ,'' as '安全库存量(件)' + ,BA.FSAFESTOCK AS '安全库存数量' + --,DE.M01 AS '本月预计需求量' + --,DE.S01 AS '前三月发货量' + --,DE.S02 AS '前二月发货量' + --,DE.S03 AS '前一月发货量' + ,EE_A.FSTOCKINQUAAUXQTY as '已入库量' + ,'' as '在生产量' + ,(EE_A.FSTOCKINQUAAUXQTY + 0) as '合计库存量' + ,'' as '计划生产批数' + ,DE.FQTY AS '计划生产量' + ,DE.FREMARK AS '备注' +FROM + T_PLN_PLANORDER A --计划订单 + LEFT JOIN T_BD_MATERIAL B ON A.FMATERIALID = B.FMATERIALID --物料 +-- LEFT JOIN T_BD_MATERIAL_L B_L ON B_L.FMATERIALID = B.FMATERIALID + LEFT JOIN T_BD_MATERIALSTOCK BA ON BA.FMATERIALID = B.FMATERIALID +-- LEFT JOIN T_BD_MATERIALBASE BB ON BB.FMATERIALID = B.FMATERIALID + --LEFT JOIN T_BD_UNIT_L C_L ON C_L.FUNITID = a.FUNITID + LEFT JOIN T_PLN_FORECASTENTRY DE ON DE.FMATERIALID = B.FMATERIALID --预测单 + left join T_PLN_FORECAST d on de.FID = d.FID + LEFT JOIN T_PRD_MOENTRY EE ON EE.FMATERIALID = B.FMATERIALID --生产订单 + LEFT JOIN T_PRD_MOENTRY_A EE_A ON EE_A.FENTRYID = EE.FENTRYID AND EE.FID =EE_A.FID --生产订单 +WHERE + A.FRELEASETYPE = 1 + --AND B_L.FLOCALEID = @LCID + --AND C_L.FLOCALEID = @LCID \ No newline at end of file diff --git a/销售出库单财务信息.sql b/销售出库单财务信息.sql new file mode 100644 index 0000000..0ffb684 --- /dev/null +++ b/销售出库单财务信息.sql @@ -0,0 +1,11 @@ +SELECT + A.FBILLNO, + A.FID, + A.FSTOCKORGID, + A.FDOCUMENTSTATUS, + AF.FBILLALLAMOUNT, + AF.FBILLAMOUNT, + AF.FBILLTAXAMOUNT +FROM + T_SAL_OUTSTOCK A + LEFT JOIN T_SAL_OUTSTOCKFIN AF ON A.FID = AF.FID \ No newline at end of file