From c4fceda660f5f3955e33b8af2ea71d406d634fe9 Mon Sep 17 00:00:00 2001 From: PastSaid <603806070@qq.com> Date: Fri, 8 Dec 2023 23:53:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Extensions/ExtensionMethods.csproj | 47 ++ Extensions/Properties/AssemblyInfo.cs | 36 ++ Extensions/StringExtension.cs | 56 ++ GateDge2023.sln | 69 +++ .../ProductionMaterialRequisition.csproj | 59 ++ .../Properties/AssemblyInfo.cs | 36 ++ .../SaveVerification.cs | 100 ++++ SAL_OUTSTOCK.dll | Bin 0 -> 37376 bytes SAL_OUTSTOCK/IssueAnInvoiceFormPlugIn.cs | 535 +++++++++++++++++ SAL_OUTSTOCK/MergePrintIssueAnInvPlugIn.cs | 560 ++++++++++++++++++ SAL_OUTSTOCK/Properties/AssemblyInfo.cs | 36 ++ SAL_OUTSTOCK/Request/BaseRequest.cs | 72 +++ SAL_OUTSTOCK/Request/GP_FPKJ.cs | 439 ++++++++++++++ SAL_OUTSTOCK/Response/ResultData.cs | 32 + SAL_OUTSTOCK/SAL_OUTSTOCK.csproj | 84 +++ SAL_OUTSTOCK/Utils/AESHepler.cs | 57 ++ SAL_OUTSTOCK/Utils/Base64Helper.cs | 74 +++ SAL_OUTSTOCK/Utils/HttpWebHelper.cs | 99 ++++ SAL_OUTSTOCK/Utils/SHA256Helper.cs | 44 ++ UnPayableInStock/Properties/AssemblyInfo.cs | 36 ++ UnPayableInStock/TUPISSQLFilterPlugIn.cs | 45 ++ UnPayableInStock/UnPayableInStock.csproj | 62 ++ UnitTestProject1/Properties/AssemblyInfo.cs | 20 + UnitTestProject1/UnitTest1.cs | 20 + UnitTestProject1/UnitTestProject1.csproj | 74 +++ UnitTestProject1/packages.config | 5 + UseGetFmaterialData.dll | Bin 0 -> 10240 bytes .../BeforeSaveEventBillPlugIn.cs | 195 ++++++ .../DataChangedEventFormPlugIn.cs | 261 ++++++++ .../Properties/AssemblyInfo.cs | 36 ++ .../UseGetFmaterialData.csproj | 70 +++ 月度生产计划表-预测单.sql | 48 ++ 月度生产计划表.sql | 60 ++ 销售出库单财务信息.sql | 11 + 34 files changed, 3378 insertions(+) create mode 100644 Extensions/ExtensionMethods.csproj create mode 100644 Extensions/Properties/AssemblyInfo.cs create mode 100644 Extensions/StringExtension.cs create mode 100644 GateDge2023.sln create mode 100644 ProductionMaterialRequisition/ProductionMaterialRequisition.csproj create mode 100644 ProductionMaterialRequisition/Properties/AssemblyInfo.cs create mode 100644 ProductionMaterialRequisition/SaveVerification.cs create mode 100644 SAL_OUTSTOCK.dll create mode 100644 SAL_OUTSTOCK/IssueAnInvoiceFormPlugIn.cs create mode 100644 SAL_OUTSTOCK/MergePrintIssueAnInvPlugIn.cs create mode 100644 SAL_OUTSTOCK/Properties/AssemblyInfo.cs create mode 100644 SAL_OUTSTOCK/Request/BaseRequest.cs create mode 100644 SAL_OUTSTOCK/Request/GP_FPKJ.cs create mode 100644 SAL_OUTSTOCK/Response/ResultData.cs create mode 100644 SAL_OUTSTOCK/SAL_OUTSTOCK.csproj create mode 100644 SAL_OUTSTOCK/Utils/AESHepler.cs create mode 100644 SAL_OUTSTOCK/Utils/Base64Helper.cs create mode 100644 SAL_OUTSTOCK/Utils/HttpWebHelper.cs create mode 100644 SAL_OUTSTOCK/Utils/SHA256Helper.cs create mode 100644 UnPayableInStock/Properties/AssemblyInfo.cs create mode 100644 UnPayableInStock/TUPISSQLFilterPlugIn.cs create mode 100644 UnPayableInStock/UnPayableInStock.csproj create mode 100644 UnitTestProject1/Properties/AssemblyInfo.cs create mode 100644 UnitTestProject1/UnitTest1.cs create mode 100644 UnitTestProject1/UnitTestProject1.csproj create mode 100644 UnitTestProject1/packages.config create mode 100644 UseGetFmaterialData.dll create mode 100644 UseGetFmaterialData/BeforeSaveEventBillPlugIn.cs create mode 100644 UseGetFmaterialData/DataChangedEventFormPlugIn.cs create mode 100644 UseGetFmaterialData/Properties/AssemblyInfo.cs create mode 100644 UseGetFmaterialData/UseGetFmaterialData.csproj create mode 100644 月度生产计划表-预测单.sql create mode 100644 月度生产计划表.sql create mode 100644 销售出库单财务信息.sql 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 0000000000000000000000000000000000000000..ce1b34719cd9b3de77ed481c55844d2923b03e2b GIT binary patch literal 37376 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..b7a442023a0bc94a99d2419358b167d1f84ecf8f GIT binary patch literal 10240 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 literal 0 HcmV?d00001 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