【NumberValidators】增值稅發票代碼驗證

来源:https://www.cnblogs.com/starfd/archive/2018/08/22/9517505.html
-Advertisement-
Play Games

同大陸身份證驗證一樣,該部分是按照國家增值稅發票代碼的定製規則,進行發票代碼驗證,如果需要查驗發票信息是否正確,應該通過第三方介面(大約一毛錢查驗一次),或者直接上 "國家稅務總局全國增值稅發票查驗平臺" 進行查驗。 目前能識別的增值稅發票代碼包含以下幾類: 增值稅專用發票 , 增值稅普通發票(紙質 ...


同大陸身份證驗證一樣,該部分是按照國家增值稅發票代碼的定製規則,進行發票代碼驗證,如果需要查驗發票信息是否正確,應該通過第三方介面(大約一毛錢查驗一次),或者直接上國家稅務總局全國增值稅發票查驗平臺進行查驗。

目前能識別的增值稅發票代碼包含以下幾類:增值稅專用發票增值稅普通發票(紙質非捲票)增值稅普通發票(捲票)增值稅電子普通發票。在類庫中,增值稅代碼驗證相關的代碼均在NumberValidators.Invoices下,其包含介面定義以及具體實現。

IVATCodeValidator(增值稅代碼識別介面)定義如下:

    /// <summary>
    /// 增值稅發票代碼驗證介面
    /// </summary>
    public interface IVATCodeValidator <out TResult>: IValidator<TResult>
        where TResult : VATCodeValidationResult, new()
    {
        /// <summary>
        /// 用於驗證的字典數據
        /// </summary>
        IValidationDictionary<int, string> Dictionary { get; set; }
        /// <summary>
        /// 生成增值稅發票代碼
        /// </summary>
        /// <param name="areaNumber">行政區劃</param>
        /// <param name="year">年份</param>
        /// <param name="batch">批次</param>
        /// <param name="kind">要生成的發票類型</param>
        /// <returns></returns>
        string GenerateVATCode(int areaNumber, ushort year, ushort batch, VATKind kind);
        /// <summary>
        /// 發票代碼驗證
        /// </summary>
        /// <param name="vatCode">待驗證的發票代碼</param>
        /// <param name="kind">要驗證的發票類型,不指定則傳null</param>
        /// <param name="minYear">允許的最小年份(註:2012年1月1日營改增開始上海試點)</param>
        /// <returns></returns>
        TResult Validate(string vatCode, VATKind? kind = null, ushort minYear = 2012);
    }

增值稅發票代碼驗證定義了兩種驗證結果
VATCodeValidationResult這是預設驗證結果,其定義如下:

    /// <summary>
    /// 增值稅發票代碼驗證結果
    /// </summary>
    public class VATCodeValidationResult : ValidationResult
    {
        /// <summary>
        /// 行政區劃代碼
        /// </summary>
        public int AreaNumber { get; internal set; }
        /// <summary>
        /// 行政區功能變數名稱稱
        /// </summary>
        public string AreaName { get; internal set; }
        /// <summary>
        /// 發票類型
        /// </summary>
        public VATKind? Category { get; internal set; }
        /// <summary>
        /// 印刷年份
        /// </summary>
        public int Year { get; internal set; }
        /// <summary>
        /// 印刷批次
        /// </summary>
        public int Batch { get; internal set; }
        /// <summary>
        /// 發票聯次,僅10位長度和12位長度摺疊票發票才有
        /// </summary>
        public int DuplicateNumber { get; internal set; }
    }

VATCode10ValidationResult是在VATCodeValidationResult的基礎上,額外定義了發票金額版本,其定義如下:

    /// <summary>
    /// 增值稅發票和普通(紙質)專有的驗證結果
    /// </summary>
    public class VATCode10ValidationResult : VATCodeValidationResult
    {
        /// <summary>
        /// 發票金額版本號,僅10位長度發票才有
        /// </summary>
        public AmountVersion AmountVersion { get; internal set; }
    }

可根據IsValid來判斷驗證是否成功,如果驗證失敗,Errors 屬性則包含了驗證失敗的原因,具體的錯誤原因列表如下

        /// <summary>
        /// 發票代碼為空
        /// </summary>
        public const string Empty = "發票代碼為空";
        /// <summary>
        /// 錯誤的發票代碼
        /// </summary>
        public const string Error = "錯誤的發票代碼";
        /// <summary>
        /// 發票年份超出允許的年份範圍
        /// </summary>
        public const string YearOutOfRange = "發票年份超出允許的年份範圍{0} ~ {1}";
        /// <summary>
        /// 發票發行區域識別失敗
        /// </summary>
        public const string InvalidArea = "發票發行區域識別失敗";
        /// <summary>
        /// 無效的發票類別
        /// </summary>
        public const string InvalidKind = "無效的發票類別";
        /// <summary>
        /// 發票類別錯誤,無法生成發票代碼
        /// </summary>
        public const string GenerateWrongKind = "發票類別錯誤,無法生成發票代碼";
        /// <summary>
        /// 無效實現
        /// </summary>
        public const string InvalidImplement = "未能找到或無效的 {0} 位發票代碼實現";
        /// <summary>
        /// 長度不符
        /// </summary>
        public const string LengthOutOfRange = "發票代碼非 {0} 位";

因為目前類庫中已經完整收集了所有發票代碼中支持的行政區劃編號(可在航信官網上查看都有哪些區域存在稅務局),所以暫時不再需要自行傳遞Dictionary來進行支持區域的修正。

目前IVATCodeValidator包含VATCode10Validator以及VATCode12Validator兩種具體實現

  • VATCode10Validator 對應長度為10的發票代碼,包含增值稅專用發票、增值稅普通發票
  • VATCode12Validator 對應長度為12的發票代碼,包含增值稅普通發票、增值稅普通發票(捲票)、增值稅電子普通發票
  • VATCodeValidatorHelper 為靜態類,用於輔助驗證,其內部簡單的封裝了按發票代碼長度調用對應的IVATCodeValidator實現

使用例子如下

            Console.WriteLine("***增值稅發票***");
            var vat10Validator = new VATCode10Validator();
            var vat12Validator = new VATCode12Validator();
            Console.WriteLine("隨機的增值稅發票:" + vat10Validator.GenerateRandomNumber());
            Console.WriteLine("生成指定的增值稅專用發票:" + vat10Validator.GenerateVATCode(3700, 2017, 1, Invoices.VATKind.Special));
            Console.WriteLine("生成指定的10位增值稅普通發票:" + vat10Validator.GenerateVATCode(1100, 2017, 2, Invoices.VATKind.Plain));
            Console.WriteLine("生成指定的12位增值稅普通發票:" + vat12Validator.GenerateVATCode(1100, 2018, 6, Invoices.VATKind.Plain));
            Console.WriteLine("隨機的增值稅電子/捲票/普票:" + vat12Validator.GenerateRandomNumber());
            string[] vatArr = { "031001600311", "3100153130", "011001800304" };
            foreach (var vat in vatArr)
            {
                var valid = VATCodeValidatorHelper.Validate(vat, minYear: 2012);
                Console.WriteLine("{0}驗證結果:{1} 類型{2} 行政區劃名稱({3}) 驗證結果類型:{4}", vat, valid.IsValid, valid.Category, valid.AreaName, valid);
            }

PS:目前1.0版本中VATCode12Validator未支持12位的增值稅普通發票,如果需要支持,需從git上下載代碼後自行生成dll


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ASP.NET Core MVC中所提供的Model Binding功能簡單但實用,其主要目的是將請求中包含的數據映射到action的方法參數中。這樣就避免了開發者像在Web Forms時代那樣需要從Request類中手動獲取數據的繁鎖操作,直接提高了開發效率。此功能繼承自ASP.NET MVC,所 ...
  •  如何測量並報告ASP.NET Core Web API請求的響應時間 介紹 大家都知道性能是API的流行語。而相應時間則是API性能的一個重要並且可測量的參數。在本文中,我們將瞭解如何使用代碼來測量API的響應時間,然後將響應時間數據返回到客戶端。 作者:依樂祝 原文地址:https://www ...
  • 隨便寫寫 首先,假設我們有一個Person類型 其類型定義如下 在正常情況下,我們讓兩個Person類型相加,是不可能的,例如: 那麼如何能讓兩個Person類型相加,然後返回一個Person類型呢 例如,我想讓名字為"張三"年齡為19的Person加上另一個名字為"李四",年齡為20的Person ...
  • 要開發.NET Core應用程式,除了使用強大的Visual Studio之外,還可以使用.NET Core CLI。.NET Core CLI (Command-Line Interface),也就是.NET Core命令行界面,它是一個開發.NET Core應用程式的跨平臺工具鏈。安裝.NET ...
  • 裝箱:裝箱在值類型向引用類型轉換時發生。值類型是要放在棧上的,引用類型它需要放在堆上。 拆箱:拆箱在引用類型向值類型轉換時發生。 臟讀:臟讀是針對事物操作來說的,只有在A,B兩個事物時,A事物對一個值做了修改操作,但是沒有提交事物,這個時候,B事物讀取了A事物的修改值,但是A事物有對這個修改做了取消 ...
  • 引用:https://www.cnblogs.com/dacongge/p/6957074.html 1、JObject:基本的json對象 2、JObject:嵌套子對象(JObject嵌JObject) 3、JArray:基本json對象中的數組 4、JArray: 多個json對象數組 5、J ...
  • 真覺得自己的知識面還是比較窄,在此之前,居然還不知道SqlLocalDb。 SqlLocalDb是啥?其實就是簡化SQL Server的本地資料庫,可以這樣子說,SQL Server既可以作為遠程,也可以做本地, 而SqlLocalDb只能作為本地使用。說的直接一點,SqlLocalDb就是一個輕量 ...
  • 項目屬性-->生成-->允許不安全代碼勾上。 代碼: /// <summary> /// 反色處理 /// </summary> private Bitmap Inverse(Bitmap bmp) { BitmapData srcdat = bmp.LockBits(new Rectangle(P ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...