gb.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. # Copyright 2018 Agile Geeks
  2. # Permission is hereby granted, free of charge, to any person obtaining a copy of this software
  3. # and associated documentation files (the "Software"), to deal in the Software without restriction,
  4. # including without limitation the rights to use, copy, modify, merge, publish, distribute,
  5. # sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
  6. # is furnished to do so, subject to the following conditions:
  7. # The above copyright notice and this permission notice shall be included in all copies or substantial
  8. # portions of the Software.
  9. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  10. # LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  11. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  12. # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
  13. # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  14. from __future__ import (
  15. unicode_literals,
  16. print_function,
  17. division
  18. )
  19. import re
  20. import math
  21. from .generic import GenericValidator
  22. class Validator(GenericValidator):
  23. """
  24. For rules see /docs/VIES-VAT Validation Routines-v15.0.doc
  25. """
  26. def __init__(self):
  27. self.regexp = re.compile(r'^((\d{9})|(\d{12})|(GD\d{3})|(HA\d{3}))$', re.IGNORECASE)
  28. def validate(self, vat_number):
  29. if super(Validator, self).validate(vat_number) is False:
  30. return False
  31. vat_number = str(vat_number)
  32. # Format 1
  33. if len(vat_number) == 5:
  34. ranges = {
  35. 'GD': range(500),
  36. 'HA': range(500,1000),
  37. }
  38. if int(vat_number[2:]) not in ranges[ vat_number[:2] ]:
  39. return False
  40. return True
  41. # Format 2
  42. c89 = int(vat_number[7:9])
  43. r = self.sum_weights(list(range(8, 1, -1)), vat_number[:7]) + c89
  44. r1 = r % 97
  45. r2 = (r + 55) % 97
  46. if (r1 * r2) != 0 or (r1 + r2) == 0:
  47. return False
  48. if r1 == 0:
  49. for rng in [range(100000, 1000000),
  50. range(9490001, 9700001),
  51. range(9990001, 10000000)]:
  52. if r1 in rng:
  53. return False
  54. if r2 == 0:
  55. if r1 in range(1, 1000001):
  56. return False
  57. if len(vat_number) == 12:
  58. if int(vat_number[9:]) == 0:
  59. return False
  60. return True