Selaa lähdekoodia

新增税率配置文件TaxConfig.json,新增税率工具类TaxHelper

felix 8 kuukautta sitten
vanhempi
commit
2b5ec410c8

+ 38 - 0
AIPlatform.Protocol/Entities/TaxDetailInfo.cs

@@ -0,0 +1,38 @@
+namespace AIPlatform.Protocol.Entities
+{
+    /// <summary>
+    /// 税明细信息
+    /// </summary>
+    public class TaxDetailInfo
+    {
+        /// <summary>
+        /// 税前工资
+        /// </summary>
+        public decimal PreTaxSalary { get; set; }
+
+        /// <summary>
+        /// 个人所得税
+        /// </summary>
+        public decimal PersonalIncomeTax { get; set; }
+
+        /// <summary>
+        /// 增值税
+        /// </summary>
+        public decimal ValueAddedTax { get; set; }
+
+        /// <summary>
+        /// 城建税
+        /// </summary>
+        public decimal UrbanConstructionTax { get; set; }
+
+        /// <summary>
+        /// 系统报税金额
+        /// </summary>
+        public decimal SystemReportedTaxAmount => PreTaxSalary - ValueAddedTax - UrbanConstructionTax;
+
+        /// <summary>
+        /// 税后金额
+        /// </summary>
+        public decimal AfterTaxSalary => PreTaxSalary - ValueAddedTax - UrbanConstructionTax - PersonalIncomeTax;
+    }
+}

+ 186 - 0
AIPlatform.Protocol/TaxConfig.cs

@@ -0,0 +1,186 @@
+using AIPlatform.Protocol.Utilities;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace AIPlatform.Protocol
+{
+    /// <summary>
+    /// 个人所得税参数
+    /// </summary>
+    public class PersonalIncomeTaxParameter
+    {
+        /// <summary>
+        /// 预扣率,单位%
+        /// </summary>
+        public decimal WithHoldingRate { get; set; }
+
+        /// <summary>
+        /// 最少减除费用(税前少于4000时,最少减除费用为800)
+        /// </summary>
+        public decimal MinDeductibleExpenses { get; set; }
+
+        /// <summary>
+        /// 减除费用率,单位%
+        /// </summary>
+        public decimal DeductibleExpensesRate { get; set; }
+
+        /// <summary>
+        /// 速算扣除数
+        /// </summary>
+        public decimal QuickDeductionAmount { get; set; }
+    }
+
+    /// <summary>
+    /// 增值税参数
+    /// </summary>
+    public class ValueAddedTaxParameter
+    {
+        /// <summary>
+        /// 税率,单位%
+        /// </summary>
+        public decimal TaxRate { get; set; }
+    }
+
+    /// <summary>
+    /// 城建税参数
+    /// </summary>
+    public class UrbanConstructionTaxParameter
+    {
+        /// <summary>
+        /// 税率,单位%
+        /// </summary>
+        public decimal TaxRate { get; set; }
+    }
+
+    /// <summary>
+    /// 税率配置信息
+    /// </summary>
+    public class TaxConfigInfo
+    {
+        /// <summary>
+        /// 个人所得税税率表
+        /// </summary>
+        public Dictionary<decimal, PersonalIncomeTaxParameter> PersonalIncomeTaxRateDictionary { get; set; }
+
+        /// <summary>
+        /// 增值税税率表
+        /// </summary>
+        public Dictionary<decimal, ValueAddedTaxParameter> ValueAddedTaxRateDictionary { get; set; }
+
+        /// <summary>
+        /// 城建税税率表
+        /// </summary>
+        public Dictionary<decimal, UrbanConstructionTaxParameter> UrbanConstructionTaxRateDictionary { get; set; }
+    }
+
+    public class TaxConfig : TaxConfigInfo
+    {
+        private static readonly string _configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaxConfig.json");
+
+        public static TaxConfig Instance { get; private set; }
+
+        static TaxConfig()
+        {
+            if (!LoadConfig())
+            {
+                var personalIncomeTaxRateDictionary = new Dictionary<decimal, PersonalIncomeTaxParameter>
+                {
+                    {
+                        20000,
+                        new PersonalIncomeTaxParameter()
+                        {
+                            MinDeductibleExpenses = 800,
+                            DeductibleExpensesRate=20,
+                            WithHoldingRate = 20,
+                            QuickDeductionAmount = 0,
+                        }
+                    },
+                    {
+                        50000,
+                        new PersonalIncomeTaxParameter()
+                        {
+                            MinDeductibleExpenses = 0,
+                            DeductibleExpensesRate=20,
+                            WithHoldingRate = 30,
+                            QuickDeductionAmount = 2000,
+                        }
+                    },
+                    {
+                        decimal.MaxValue,
+                        new PersonalIncomeTaxParameter()
+                        {
+                            MinDeductibleExpenses = 0,
+                            DeductibleExpensesRate=20,
+                            WithHoldingRate = 40,
+                            QuickDeductionAmount = 7000,
+                        }
+                    }
+                };
+                var valueAddedTaxRateDictionary = new Dictionary<decimal, ValueAddedTaxParameter>
+                {
+                    {
+                        500,
+                        new ValueAddedTaxParameter
+                        {
+                            TaxRate = 0
+                        }
+                    },
+                    {
+                        decimal.MaxValue,
+                        new ValueAddedTaxParameter
+                        {
+                            TaxRate = 1
+                        }
+                    }
+                };
+                var urbanConstructionTaxRateDictionary = new Dictionary<decimal, UrbanConstructionTaxParameter>
+                {
+                    {
+                        decimal.MaxValue,
+                        new UrbanConstructionTaxParameter
+                        {
+                            TaxRate = 3.5m
+                        }
+                    }
+                };
+                Instance = new TaxConfig
+                {
+                    PersonalIncomeTaxRateDictionary = personalIncomeTaxRateDictionary,
+                    ValueAddedTaxRateDictionary = valueAddedTaxRateDictionary,
+                    UrbanConstructionTaxRateDictionary = urbanConstructionTaxRateDictionary
+                };
+                Save();
+            }
+        }
+
+        private static bool LoadConfig()
+        {
+            if (!File.Exists(_configPath))
+            {
+                return false;
+            }
+            try
+            {
+                var jsonString = File.ReadAllText(_configPath);
+                Instance = JsonConvert.DeserializeObject<TaxConfig>(jsonString);
+                return true;
+            }
+            catch (Exception ex)
+            {
+                Logger.WriteLineError($"TaxConfigInfo LoadConfig error: {ex}");
+            }
+            return false;
+        }
+
+        private static void Save()
+        {
+            var jsonString = JsonConvert.SerializeObject(Instance, new JsonSerializerSettings
+            {
+                Formatting = Formatting.Indented
+            });
+            File.WriteAllText(_configPath, jsonString);
+        }
+    }
+}

+ 35 - 0
aipsvr/TaxConfig.json

@@ -0,0 +1,35 @@
+{
+  "PersonalIncomeTaxRateDictionary": {
+    "20000": {
+      "WithHoldingRate": 20.0,
+      "MinDeductibleExpenses": 800.0,
+      "DeductibleExpensesRate": 20.0,
+      "QuickDeductionAmount": 0.0
+    },
+    "50000": {
+      "WithHoldingRate": 30.0,
+      "MinDeductibleExpenses": 0.0,
+      "DeductibleExpensesRate": 20.0,
+      "QuickDeductionAmount": 2000.0
+    },
+    "79228162514264337593543950335": {
+      "WithHoldingRate": 40.0,
+      "MinDeductibleExpenses": 0.0,
+      "DeductibleExpensesRate": 20.0,
+      "QuickDeductionAmount": 7000.0
+    }
+  },
+  "ValueAddedTaxRateDictionary": {
+    "500": {
+      "TaxRate": 0.0
+    },
+    "79228162514264337593543950335": {
+      "TaxRate": 1.0
+    }
+  },
+  "UrbanConstructionTaxRateDictionary": {
+    "79228162514264337593543950335": {
+      "TaxRate": 3.5
+    }
+  }
+}

+ 87 - 0
aipsvr/Utilities/TaxHelper.cs

@@ -0,0 +1,87 @@
+using AIPlatform.Protocol;
+using AIPlatform.Protocol.Entities;
+using System;
+
+namespace aipsvr.Utilities
+{
+    internal class TaxHelper
+    {
+        /// <summary>
+        /// 计算税前工资对应的税后工资
+        /// </summary>
+        /// <param name="preTaxSalary"></param>
+        /// <returns></returns>
+        /// <exception cref="ArgumentOutOfRangeException"></exception>
+        public static TaxDetailInfo CalculateTaxDetailInfo(decimal preTaxSalary)
+        {
+            if (preTaxSalary < 0)
+            {
+                throw new ArgumentOutOfRangeException("preTaxSalary", "preTaxSalary must be greater than 0");
+            }
+            var valueAddedTax = CalculateValueAddedTax(preTaxSalary);
+            var urbanConstructionTax = CalculateUrbanConstructionTax(preTaxSalary);
+            var personalIncomeTax = CalculatePersonalIncomeTax(preTaxSalary);
+            return new TaxDetailInfo
+            {
+                PreTaxSalary = preTaxSalary,
+                ValueAddedTax = valueAddedTax,
+                UrbanConstructionTax = urbanConstructionTax,
+                PersonalIncomeTax = personalIncomeTax
+            };
+        }
+
+        /// <summary>
+        /// 计算增值税
+        /// </summary>
+        /// <param name="preTaxSalary"></param>
+        /// <returns></returns>
+        private static decimal CalculateValueAddedTax(decimal preTaxSalary)
+        {
+            foreach (var threshold in TaxConfig.Instance.ValueAddedTaxRateDictionary)
+            {
+                if (preTaxSalary <= threshold.Key)
+                {
+                    return Math.Round(preTaxSalary / (1 + threshold.Value.TaxRate / 100) * threshold.Value.TaxRate / 100, 2);
+                }
+            }
+            return 0;
+        }
+        /// <summary>
+        /// 计算城建税
+        /// </summary>
+        private static decimal CalculateUrbanConstructionTax(decimal preTaxSalary)
+        {
+            foreach (var threshold in TaxConfig.Instance.UrbanConstructionTaxRateDictionary)
+            {
+                if (preTaxSalary <= threshold.Key)
+                {
+                    var vat = CalculateValueAddedTax(preTaxSalary);
+                    return Math.Round(vat * threshold.Value.TaxRate / 100, 2);
+                }
+            }
+            return 0;
+        }
+
+        private static decimal CalculatePersonalIncomeTax(decimal preTaxSalary)
+        {
+            foreach (var threshold in TaxConfig.Instance.PersonalIncomeTaxRateDictionary)
+            {
+                var deductibleExpense = preTaxSalary * threshold.Value.DeductibleExpensesRate / 100;
+                if (deductibleExpense < threshold.Value.MinDeductibleExpenses)
+                {
+                    deductibleExpense = threshold.Value.MinDeductibleExpenses;
+                }
+                var taxPayable = preTaxSalary - deductibleExpense;
+                if (taxPayable < 0)
+                {
+                    return 0;
+                }
+                else if (taxPayable <= threshold.Key)
+                {
+                    return Math.Round((taxPayable) * threshold.Value.WithHoldingRate / 100 - threshold.Value.QuickDeductionAmount, 2);
+                }
+            }
+            return 0;
+        }
+    }
+}

+ 3 - 0
aipsvr/aipsvr.csproj

@@ -47,6 +47,9 @@
     <None Update="mongod.exe">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </None>
+    <None Update="TaxConfig.json">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
   <Target Name="PostBuild" AfterTargets="PostBuildEvent">