【NumberValidators】增值税发票代码验证
原文:【NumberValidators】增值税发票代码验证

同大陆身份证验证一样,该部分是按照国家增值税发票代码的定制规则,进行发票代码验证,如果需要查验发票信息是否正确,应该通过第三方接口(大约一毛钱查验一次),或者直接上国家税务总局全国增值税发票查验平台进行查验。

目前能识别的增值税发票代码包含以下几类:增值税专用发票增值税普通发票(纸质非卷票)增值税普通发票(卷票)增值税电子普通发票。在类库中,增值税代码验证相关的代码均在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; }}

VATCode12ValidationResult是在VATCodeValidationResult的基础上,额外定义了增值税电子发票的细分类型,其定义如下:

    /// <summary>/// 除增值税专项发票外的验证结果/// </summary>public class VATCode12ValidationResult : VATCodeValidationResult{/// <summary>/// 增值税电子发票细分类型/// </summary>public ElectronicVATKind? ElectronicVATKind { get; 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

posted on 2019-04-15 22:12 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10713616.html

【NumberValidators】增值税发票代码验证相关推荐

  1. Odoo(Openerp v8)官方模块一览表

    模块名称 技术名称 作者 电子发票管理 account OpenERP SA 会计与财务 account_accountant OpenERP SA 合同管理 account_analytic_ana ...

  2. odoo8 openerp 入门

    调试 跳入(Step In).跳过(Step Over).跳出(Step Out) 首先来讲一下step into step over step return的区别:  step into就是单步执行 ...

  3. odoo开发笔记 -- 官方模块一览表

    模块名称 技术名称 作者 电子发票管理 account OpenERP SA 会计与财务 account_accountant OpenERP SA 合同管理 account_analytic_ana ...

  4. 发票OCR识别技术太屌了,哈哈哈哈

    一般传统的财务增值税发票信息采集步骤分为: 人工整理原始财务发票:财务部门将公司每个月产生的增值税专用发票.增值税普通发票等票据进行分类整理: 财务发票扫描影像:将所有票据进行图像扫描,存储在电脑系统 ...

  5. 增值税发票二维码协议

    二维码解析内容示例 01,10,011001605111,80100798,64.9,20161018,85342965681116380258 01,10,044001500111,81966722 ...

  6. golang开发需要掌握的核心包以及中间件,涵盖项目的各个领域

    常用包 常用包 说明 fmt 实现格式化的输入输出操作,其中的fmt.Printf()和fmt.Println()是开发者使用最为频繁的函数. io 实现了一系列非平台相关的IO相关接口和实现,比如提 ...

  7. golang优秀开源框架和库

    作者:承诺一时的美丽 链接:https://www.jianshu.com/u/6719426bf97e 來源:简书 音频和音乐 用于操纵音频的库. flac - Native Go FLAC解码器. ...

  8. 2018最新精选的Go框架,库和软件的精选列表 一

    2018最新精选的Go框架,库和软件的精选列表 一 音频和音乐 用于操纵音频的库. flac - Native Go FLAC解码器. flac - Native Go FLAC解码器. gaad - ...

  9. 发票识别发票OCR解决方案

    越来越多的发票需要整理,越来越多的时间耗费在发票上,手动录入和人工检索,不仅浪费时间,而且容易出错.人工智能的时代已经来临了,越来越多的工作都会用人工智能的方式来解决,效率的提升不是一星半点.那么对于 ...

最新文章

  1. Druid:一个用于大数据实时处理的开源分布式系统——大数据实时查询和分析的高容错、高性能开源分布式系统...
  2. Python基础训练题-简单数学公式
  3. java每过一段时间执行一次代码(方法)
  4. C++之指针探究(十九):typedef和const指针
  5. 强类型数据集DataSet入门1
  6. 看电影学英语:不速之客[The Vistor] [二]
  7. 嵌入式系统——存储管理方案
  8. java基础学习(7)浅析final,private,public,protected,static等关键以及它们的区别的联系
  9. revit插件有哪些常用的?介绍几个常用的revit插件操作简单
  10. 大话企业IT安全解决方案
  11. 量产HLW8032串口通讯芯片的三相电参数采集系统项目资料
  12. 少有人走的路 读书笔记
  13. Postman保存二进制流数据
  14. ECPC16-E. Jumping(bfs)
  15. 计算机清理垃圾代码,你也可以写代码系列,一键清除系统垃圾文件的代码(超简单)-清除垃圾文件...
  16. kernel 打印时间戳
  17. 【CS229笔记】协方差矩阵概念快速回顾
  18. 建筑垃圾运输车辆监管系统,渣土车管理实施方案,
  19. 1046. Shortest Distance
  20. 【可视化】python-matplotlib画出普通箭头和带注释箭头

热门文章

  1. 梅敬成 三维CAD软件发展历程:过去,现在和未来 (ACIS,Parasolid,OCC, 中望OV,华天CRUX IV )
  2. 下载vs后,移动windows kits文件夹(不使用快捷方式的方法)
  3. Arcgis更换布局模板_适合个人的网站导航静态模板
  4. 出向链路负载均衡之协议分流
  5. 2015-05-22-csharp-MSMQ简介和简单例子
  6. Android——UIL实现图片缓存基本配置及使用
  7. 《当程序员的那些狗日日子》(十七)短暂的混乱
  8. 怎样防止苹果系统更新_苹果手机屏蔽系统更新描述文件链接,可屏蔽ios12更新...
  9. Julia 语言环境安装
  10. 公司起诉CTO拖延研发进度,索赔90万