Procházet zdrojové kódy

Impl. GB and fixes for backwards compatibility with python2.7

Radu Boncea před 6 roky
rodič
revize
1f5b02c592

+ 5 - 2
pyVat/api.py

@@ -15,8 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-from __future__ import unicode_literals, print_function
-
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 import sys
 

+ 5 - 0
pyVat/validators/at.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 

+ 5 - 0
pyVat/validators/be.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 

+ 5 - 0
pyVat/validators/bg.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 

+ 6 - 1
pyVat/validators/cy.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 
@@ -34,7 +39,7 @@ class Validator(GenericValidator):
         vat_number = str(vat_number)
         if int(vat_number[0]) not in [0, 1, 3, 4, 5, 9]:
             return False
-        if vat_number[:2] == '12':
+        if vat_number[:2] == str('12'):
             return False
 
         odd_digit_mapping = {

+ 10 - 7
pyVat/validators/cz.py

@@ -14,14 +14,17 @@
 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 import math
 import calendar
 import datetime
 from .generic import GenericValidator
 
-
 class Validator(GenericValidator):
     """
     For rules see /docs/VIES-VAT Validation Routines-v15.0.doc
@@ -38,7 +41,7 @@ class Validator(GenericValidator):
 
         # legal entities
         if len(vat_number) == 8:
-            if vat_number[0] == '9':
+            if vat_number[0] == str('9'):
                 return False
             checknum = int (vat_number[7])
             a1 = self.sum_weights(list(range(8,1,-1)), vat_number[:8])
@@ -54,7 +57,7 @@ class Validator(GenericValidator):
         if len(vat_number) == 9:
 
             # special cases
-            if vat_number[0] == '6':
+            if vat_number[0] == str('6'):
                 checknum = int(vat_number[8])
                 a1 = self.sum_weights(list(range(8, 1, -1)), vat_number[1:8])
                 if a1 % 11 == 0:
@@ -87,7 +90,7 @@ class Validator(GenericValidator):
 
                 if monthval>12:
                     monthval = monthval - 50
-                num_days_month = calendar.monthrange( int('19'.join(vat_number[:2])), monthval)[1]
+                num_days_month = calendar.monthrange( int(str('19').join(vat_number[:2])), monthval)[1]
 
                 daysval = int(vat_number[4:6])
                 if daysval<1 or daysval>num_days_month:
@@ -111,9 +114,9 @@ class Validator(GenericValidator):
                     and monthval not in range(51, 63) and monthval not in range(71, 83):
                 return False
 
-            year_prefix = '19'
+            year_prefix = str('19')
             if yearval<13:
-                year_prefix = '20'
+                year_prefix = str('20')
             num_days_month = calendar.monthrange(int(year_prefix.join(vat_number[:2])), monthval)[1]
             daysval = int(vat_number[4:6])
             if daysval < 1 or daysval > num_days_month:

+ 6 - 1
pyVat/validators/de.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 
@@ -34,7 +39,7 @@ class Validator(GenericValidator):
 
         checknum = int (vat_number[8])
 
-        if vat_number[0] == '0':
+        if vat_number[0] == str('0'):
             return False
 
         p = 10

+ 7 - 3
pyVat/validators/dk.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 
@@ -23,6 +28,7 @@ class Validator(GenericValidator):
     """
     For rules see /docs/VIES-VAT Validation Routines-v15.0.doc
     """
+
     def __init__(self):
         self.regexp = re.compile(r'^\d{8}$')
 
@@ -32,11 +38,9 @@ class Validator(GenericValidator):
 
         vat_number = str(vat_number)
 
-
-        if vat_number[0] == '0':
+        if vat_number[0] == str('0'):
             return False
 
-
         r = self.sum_weights([2, 7, 6, 5, 4, 3, 2, 1], vat_number)
         if r % 11 == 0:
             return True

+ 6 - 2
pyVat/validators/ee.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 import math
 from .generic import GenericValidator
@@ -33,8 +38,7 @@ class Validator(GenericValidator):
 
         vat_number = str(vat_number)
 
-
-        if vat_number[:2] != '10':
+        if vat_number[:2] != str('10'):
             return False
 
         checknum = int(vat_number[8])

+ 5 - 0
pyVat/validators/es.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 import math
 from .generic import GenericValidator

+ 5 - 0
pyVat/validators/fi.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 

+ 22 - 6
pyVat/validators/fr.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 import sys
 from .generic import GenericValidator
@@ -25,7 +30,7 @@ class Validator(GenericValidator):
     """
     For rules see /docs/VIES-VAT Validation Routines-v15.0.doc
     """
-    check_caracter_mapping = {
+    ccm = {
         0: '0',
         1: '1',
         2: '2',
@@ -83,14 +88,25 @@ class Validator(GenericValidator):
             checkval = int(vat_number[2:] + '12') % 97
             return int(vat_number[:2]) == checkval
         else:
+            if PY_3_OR_HIGHER:
+                inv_ccm = {v: k for k, v in Validator.ccm.items()}
+            else:
+                inv_ccm = {v: k for k, v in Validator.ccm.iteritems()}
+
+            s1 = inv_ccm[vat_number[0]]
+            s2 = inv_ccm[vat_number[1]]
+
             try:
                 c1 = int(vat_number[0])
             except:
-                c1_is_numeric = False
+                s = s1 * 34 + s2 - 100
             else:
-                c1_is_numeric = True
+                s = s1 * 24 + s2 - 10
+
+            p = s / 11 + 1
+            r1 = s % 11
+            r2 = int(vat_number[2:]) % 11
+
+            return r1 == r2
 
-            inv_ccm = 
 
-            #if c1_is_numeric:
-                # c2 must be numeric as otherwise would have been caught in old style

+ 74 - 0
pyVat/validators/gb.py

@@ -0,0 +1,74 @@
+# Copyright 2018 Agile Geeks
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+# and associated documentation files (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge, publish, distribute,
+# sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
+# is furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all copies or substantial
+# portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+# LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
+import re
+import math
+from .generic import GenericValidator
+
+
+class Validator(GenericValidator):
+    """
+    For rules see /docs/VIES-VAT Validation Routines-v15.0.doc
+    """
+    def __init__(self):
+        self.regexp = re.compile(r'^((\d{9})|(\d{12})|(GD\d{3})|(HA\d{3}))$', re.IGNORECASE)
+
+    def validate(self, vat_number):
+        if super(Validator, self).validate(vat_number) is False:
+            return False
+
+        vat_number = str(vat_number)
+
+        # Format 1
+        if len(vat_number) == 5:
+            ranges = {
+                'GD': range(500),
+                'HA': range(500,1000),
+            }
+            if int(vat_number[2:]) not in ranges[ vat_number[:2] ]:
+                return False
+            return True
+
+        # Format 2
+        c89 = int(vat_number[7:9])
+        r = self.sum_weights(list(range(8, 1, -1)), vat_number[:7]) + c89
+        r1 = r % 97
+        r2 = (r + 55) % 97
+        if (r1 * r2) != 0 or (r1 + r2) == 0:
+            return False
+        if r1 == 0:
+            for rng in [range(100000, 1000000),
+                            range(9490001, 9700001),
+                            range(9990001, 10000000)]:
+                if r1 in rng:
+                    return False
+
+        if r2 == 0:
+            if r1 in range(1, 1000001):
+                return False
+
+        if len(vat_number) == 12:
+            if int(vat_number[9:]) == 0:
+                return False
+
+        return True
+

+ 5 - 0
pyVat/validators/generic.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 
 class GenericValidator(object):

+ 5 - 1
pyVat/validators/gr.py

@@ -15,6 +15,11 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 import math
 from .generic import GenericValidator
@@ -31,7 +36,6 @@ class Validator(GenericValidator):
         if super(Validator, self).validate(vat_number) is False:
             return False
 
-
         vat_number = str(vat_number)
 
         checknum = int(vat_number[8])

+ 11 - 1
pyVat/validators/ro.py

@@ -15,6 +15,16 @@
 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 # OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
+from __future__ import (
+    unicode_literals,
+    print_function,
+    division
+)
 import re
 from .generic import GenericValidator
 
@@ -33,7 +43,7 @@ class Validator(GenericValidator):
 
         vat_number = str(vat_number)
 
-        vat_number = vat_number.rjust(10,'0')
+        vat_number = vat_number.rjust(10,str('0'))
         checksum = int (vat_number[9])
         weights = [7, 5, 3, 2, 1, 7, 5, 3, 2]
         checkval = self.sum_weights(weights, vat_number)

+ 21 - 2
tests/test_validator.py

@@ -241,10 +241,29 @@ class TestValidator(unittest.TestCase):
         validator = Validator('FR00300076964')
         self.assertFalse(validator.validate())
 
+        validator = Validator('FR2A316607779')
+        self.assertTrue(validator.validate())
+
         #  new style
-        #validator = Validator('FR02300076965')
-        #self.assertTrue(validator.validate())
+        validator = Validator('FR0K300076962')
+        self.assertTrue(validator.validate())
 
+    def test_gb(self):
+        # format 1 - 5 chars
+        validator = Validator('GbGD232')
+        self.assertTrue(validator.validate())
+        self.assertEqual(validator.country_code, 'GB')
+        validator = Validator('GBHA232')
+        self.assertFalse(validator.validate())
+        validator = Validator('GBGD755')
+        self.assertFalse(validator.validate())
+        self.assertEqual(validator.country_code, 'GB')
+        validator = Validator('GBHA957')
+        self.assertTrue(validator.validate())
+
+        #format 2
+        validator = Validator('GB434031494')
+        self.assertTrue(validator.validate())
 
 if __name__ == '__main__':
     unittest.main()