From e8f1ca6022fa7e6e1fe309f4c1b141d85b73ed30 Mon Sep 17 00:00:00 2001 From: Jonathan Finlay Date: Sun, 12 Oct 2014 04:23:12 +0200 Subject: Add Ecuadorian CI and RUC numbers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add modules for Ecuadorian Identification Card (CI - Cédula de identidad) and Fiscal Numbers (RUC - Registro Único de Contribuyentes) --- stdnum/ec/__init__.py | 24 +++++++++++ stdnum/ec/ci.py | 77 ++++++++++++++++++++++++++++++++++ stdnum/ec/ruc.py | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 stdnum/ec/__init__.py create mode 100644 stdnum/ec/ci.py create mode 100644 stdnum/ec/ruc.py diff --git a/stdnum/ec/__init__.py b/stdnum/ec/__init__.py new file mode 100644 index 0000000..18d02a8 --- /dev/null +++ b/stdnum/ec/__init__.py @@ -0,0 +1,24 @@ +# __init__.py - collection of Ecuadorian numbers +# coding: utf-8 +# +# Copyright (C) 2014 Jonathan Finlay +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""Collection of Ecuadorian numbers.""" + +# provide vat as an alias +from stdnum.ec import ruc as vat diff --git a/stdnum/ec/ci.py b/stdnum/ec/ci.py new file mode 100644 index 0000000..4834d58 --- /dev/null +++ b/stdnum/ec/ci.py @@ -0,0 +1,77 @@ +# dni.py - functions for handling Ecuadorian personal identity codes +# coding: utf-8 +# +# Copyright (C) 2014 Jonathan Finlay +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""CI (Cédula de identidad, Ecuadorian personal identity codes). + +The CI is a 10 digit number used to identify Ecuadorian citizens. + +>>> validate('1714307103') +'1714307103' +>>> validate('171430710-3') +'1714307103' +>>> validate('1714307104') # invalid document +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> validate('171430710') # digit missing +Traceback (most recent call last): + ... +InvalidLength: ... +""" + +from stdnum.exceptions import * +from stdnum.util import clean + + +def compact(number): + """Convert the number to the minimal representation. This strips the + number of any valid separators and removes surrounding whitespace.""" + return clean(number, ' -').upper().strip() + + +def checksum(number): + """Calculate the check digit.""" + value = [int(number[x]) * (2 - x % 2) for x in range(9)] + total = sum(map(lambda x: x > 9 and x - 9 or x, value)) + if int(int(number[9] if int(number[9]) != 0 else 10)) != (10 - int(str(total)[-1:])): + return False + return True + + +def validate(number): + """Checks to see if the number provided is a valid CI number. This + checks the length, formatting and check digit.""" + number = compact(number) + if len(number) != 10: + raise InvalidLength() + if not number.isdigit(): + raise InvalidFormat() + if not checksum(number): + raise InvalidChecksum() + return number + + +def is_valid(number): + """Checks to see if the number provided is a valid CI number. This + checks the length, formatting and check digit.""" + try: + return bool(validate(number)) + except ValidationError: + return False diff --git a/stdnum/ec/ruc.py b/stdnum/ec/ruc.py new file mode 100644 index 0000000..c39e73e --- /dev/null +++ b/stdnum/ec/ruc.py @@ -0,0 +1,114 @@ +# cif.py - functions for handling Ecuadorian fiscal numbers +# coding: utf-8 +# +# Copyright (C) 2014 Jonathan Finlay +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +"""RUC (Registro Único de Contribuyentes, Ecuadorian company tax number). + +The RUC is a tax identification number for legal entities. It has 13 digits +where the third digit is a number who denoting the type of entity. + +>>> validate('1714307103001') # Natural entity +'1714307103001' +>>> validate('1768152130001') # Public entity +'1768152130001' +>>> validate('1792060346001') # Juridical entity +'1792060346001' +>>> validate('1792060346-001') +'1792060346001' +>>> validate('1763154690001') # Invalid +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> validate('179206034601') # too short +Traceback (most recent call last): + ... +InvalidLength: ... +""" + +from stdnum.ec import ci +from stdnum.exceptions import * + + +__all__ = ['compact', 'validate', 'is_valid'] + + +# use the same compact function as CI +compact = ci.compact + + +def calc_check_sum(number): + result = 0 + if int(number[2]) == 6: + # 6 = Public RUC + coefficient = "32765432" + result = sum(int(number[i]) * int(coefficient[i]) for i in range(8)) + residue = result % 11 + if residue == 0: + result = residue + else: + result = 11 - residue + elif int(number[2]) == 9: + # 9 = Juridical RUC + coefficient = "432765432" + result = sum(int(number[i]) * int(coefficient[i]) for i in range(9)) + residue = result % 11 + if residue == 0: + result = residue + else: + result = 11 - residue + elif int(number[2]) < 6: + # less than 6 = Natural RUC + coefficient = "212121212" + for i in range(9): + suma = int(number[i]) * int(coefficient[i]) + if suma > 10: + str_sum = str(suma) + suma = int(str_sum[0]) + int(str_sum[1]) + result += suma + residue = result % 10 + if residue == 0: + result = residue + else: + result = 10 - residue + else: + raise InvalidFormat() + return result + + +def validate(number): + """Checks to see if the number provided is a valid RUC number. This + checks the length, formatting, check digit and check sum.""" + number = compact(number) + if len(number) != 13: + raise InvalidLength() + if not number.isdigit(): + raise InvalidFormat() + checker = int(number[8]) if int(number[2]) == 6 else int(number[9]) + if calc_check_sum(number) != checker: + raise InvalidChecksum() + return number + + +def is_valid(number): + """Checks to see if the number provided is a valid RUC number. This + checks the length, formatting and check digit.""" + try: + return bool(validate(number)) + except ValidationError: + return False -- cgit v1.2.3 From f61b855cf64bc1a91b196040b27dd176a3a50890 Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Fri, 17 Oct 2014 18:33:02 +0200 Subject: Use dedicated doctests This moves a number of the existing test cases to dedicated doctest files and extend the tests with more numbers and corner cases. This also fixes a few docstrings. --- stdnum/ec/ci.py | 10 ++-- stdnum/ec/ruc.py | 12 +--- tests/test_ec_ci.doctest | 57 +++++++++++++++++++ tests/test_ec_ruc.doctest | 138 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 15 deletions(-) create mode 100644 tests/test_ec_ci.doctest create mode 100644 tests/test_ec_ruc.doctest diff --git a/stdnum/ec/ci.py b/stdnum/ec/ci.py index 4834d58..bf4ad3e 100644 --- a/stdnum/ec/ci.py +++ b/stdnum/ec/ci.py @@ -1,4 +1,4 @@ -# dni.py - functions for handling Ecuadorian personal identity codes +# ci.py - functions for handling Ecuadorian personal identity codes # coding: utf-8 # # Copyright (C) 2014 Jonathan Finlay @@ -18,15 +18,13 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA -"""CI (Cédula de identidad, Ecuadorian personal identity codes). +"""CI (Cédula de identidad, Ecuadorian personal identity code). The CI is a 10 digit number used to identify Ecuadorian citizens. ->>> validate('1714307103') -'1714307103' >>> validate('171430710-3') '1714307103' ->>> validate('1714307104') # invalid document +>>> validate('1714307104') # invalid check digit Traceback (most recent call last): ... InvalidChecksum: ... @@ -47,7 +45,7 @@ def compact(number): def checksum(number): - """Calculate the check digit.""" + """Calculate a checksum over the number.""" value = [int(number[x]) * (2 - x % 2) for x in range(9)] total = sum(map(lambda x: x > 9 and x - 9 or x, value)) if int(int(number[9] if int(number[9]) != 0 else 10)) != (10 - int(str(total)[-1:])): diff --git a/stdnum/ec/ruc.py b/stdnum/ec/ruc.py index c39e73e..7a4a1c8 100644 --- a/stdnum/ec/ruc.py +++ b/stdnum/ec/ruc.py @@ -1,4 +1,4 @@ -# cif.py - functions for handling Ecuadorian fiscal numbers +# ruc.py - functions for handling Ecuadorian fiscal numbers # coding: utf-8 # # Copyright (C) 2014 Jonathan Finlay @@ -21,17 +21,11 @@ """RUC (Registro Único de Contribuyentes, Ecuadorian company tax number). The RUC is a tax identification number for legal entities. It has 13 digits -where the third digit is a number who denoting the type of entity. +where the third digit is a number denoting the type of entity. ->>> validate('1714307103001') # Natural entity -'1714307103001' ->>> validate('1768152130001') # Public entity -'1768152130001' ->>> validate('1792060346001') # Juridical entity -'1792060346001' >>> validate('1792060346-001') '1792060346001' ->>> validate('1763154690001') # Invalid +>>> validate('1763154690001') # invalid check digit Traceback (most recent call last): ... InvalidChecksum: ... diff --git a/tests/test_ec_ci.doctest b/tests/test_ec_ci.doctest new file mode 100644 index 0000000..2ab58fb --- /dev/null +++ b/tests/test_ec_ci.doctest @@ -0,0 +1,57 @@ +test_ec_ci.doctest - more detailed doctests for stdnum.ec.ci module + +Copyright (C) 2014 Jonathan Finlay +Copyright (C) 2014 Arthur de Jong + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA + + +This file contains more detailed doctests for the stdnum.ec.ci. It tries to +cover more corner cases and detailed functionality that is not really useful +as module documentation. + +>>> from stdnum.ec import ci +>>> from stdnum.exceptions import * + + +Normal values that should just work. + +>>> ci.validate('1714307103') +'1714307103' +>>> ci.validate('171430710-3') +'1714307103' +>>> ci.validate('0602910945') +'0602910945' +>>> ci.validate('0926687856') +'0926687856' +>>> ci.validate('0910005917') +'0910005917' + + +Some invalid numbers. + +>>> ci.validate('1714307104') # invalid check digit +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> ci.validate('171430710') # digit missing +Traceback (most recent call last): + ... +InvalidLength: ... +>>> ci.validate('123A567890') # contains a letter +Traceback (most recent call last): + ... +InvalidFormat: ... diff --git a/tests/test_ec_ruc.doctest b/tests/test_ec_ruc.doctest new file mode 100644 index 0000000..e64346b --- /dev/null +++ b/tests/test_ec_ruc.doctest @@ -0,0 +1,138 @@ +test_ec_ruc.doctest - more detailed doctests for stdnum.ec.ruc module + +Copyright (C) 2014 Jonathan Finlay +Copyright (C) 2014 Arthur de Jong + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA + + +This file contains more detailed doctests for the stdnum.ec.ruc. It tries to +cover more corner cases and detailed functionality that is not really useful +as module documentation. + +>>> from stdnum.ec import ruc +>>> from stdnum.exceptions import * + + +Normal natural RUC values (third digit less than 6) that should just work. + +>>> numbers = ''' +... 0101016905001 +... 0602910945001 +... 0910005917001 +... 0926687856001 +... 1001152287001 +... 1102755442001 +... 1104552037001 +... 1311919078001 +... 1700672486001 +... 1702264233001 +... 1704159860001 +... 1710034065001 +... 1710585264001 +... 1710589373001 +... 1713238234001 +... 1714307103001 +... 1721788659001 +... 1803557964001 +... ''' +>>> [x for x in numbers.splitlines() if x and not ruc.is_valid(x)] +[] + + +Normal public RUC values (third digit is 6) that should just work. + +>>> numbers = ''' +... 0160001910001 +... 0260001060001 +... 0360001040001 +... 0560000540001 +... 0660000280001 +... 0660000600001 +... 0660000870001 +... 0968529830001 +... 1060000420001 +... 1060000690001 +... 1060008080001 +... 1060024600001 +... 1360000630001 +... 1560000780001 +... 1760001040001 +... 1760001550001 +... 1760009880001 +... 1768007390001 +... 1768152130001 +... 2160011760001 +... ''' +>>> [x for x in numbers.splitlines() if x and not ruc.is_valid(x)] +[] + + +Normal juridical RUC values (third digit is 9) that should just work. + +>>> numbers = ''' +... 0190155722001 +... 0490002669001 +... 0590041920001 +... 0790024656001 +... 0990138850001 +... 0992397535001 +... 1190015110001 +... 1390007791001 +... 1390089410001 +... 1390091474001 +... 1790011674001 +... 1790085783001 +... 1790325083001 +... 1791280172001 +... 1791714350001 +... 1792060346001 +... 1792141869001 +... 1792373255001 +... 1890001323001 +... 1890037646001 +... ''' +>>> [x for x in numbers.splitlines() if x and not ruc.is_valid(x)] +[] + + +Values that are invalid in one way or another: + +>>> ruc.validate('179206034601') # too short +Traceback (most recent call last): + ... +InvalidLength: ... +>>> ruc.validate('17920603A6001') # contains a character +Traceback (most recent call last): + ... +InvalidFormat: ... +>>> ruc.validate('0170000610001') # third digit invalid +Traceback (most recent call last): + ... +InvalidComponent: ... + +>>> ruc.validate('1763154690001') # invalid check digit in natural RUC +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> ruc.validate('0160000610001') # invalid check digit in public RUC +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> ruc.validate('0190115799001') # invalid check digit in juridical RUC +Traceback (most recent call last): + ... +InvalidChecksum: ... -- cgit v1.2.3 From 10a044fe6efd05dcb9ead2d17c33f27dbd2b780c Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Fri, 17 Oct 2014 21:12:43 +0200 Subject: Refactor checksum functions Use the CI checks from within the RUC module for natural RUC numbers (thereby eliminating a bug in the RUC checksum calculation) and simplify the checksum functions. --- stdnum/ec/ci.py | 13 ++++++------- stdnum/ec/ruc.py | 57 +++++++++++++++++--------------------------------------- 2 files changed, 23 insertions(+), 47 deletions(-) diff --git a/stdnum/ec/ci.py b/stdnum/ec/ci.py index bf4ad3e..a32c6e3 100644 --- a/stdnum/ec/ci.py +++ b/stdnum/ec/ci.py @@ -2,6 +2,7 @@ # coding: utf-8 # # Copyright (C) 2014 Jonathan Finlay +# Copyright (C) 2014 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -44,13 +45,11 @@ def compact(number): return clean(number, ' -').upper().strip() -def checksum(number): +def _checksum(number): """Calculate a checksum over the number.""" - value = [int(number[x]) * (2 - x % 2) for x in range(9)] - total = sum(map(lambda x: x > 9 and x - 9 or x, value)) - if int(int(number[9] if int(number[9]) != 0 else 10)) != (10 - int(str(total)[-1:])): - return False - return True + fold = lambda x: x - 9 if x > 9 else x + return sum(fold((2 - (i % 2)) * int(n)) + for i, n in enumerate(number)) % 10 def validate(number): @@ -61,7 +60,7 @@ def validate(number): raise InvalidLength() if not number.isdigit(): raise InvalidFormat() - if not checksum(number): + if _checksum(number) != 0: raise InvalidChecksum() return number diff --git a/stdnum/ec/ruc.py b/stdnum/ec/ruc.py index 7a4a1c8..0bc62b5 100644 --- a/stdnum/ec/ruc.py +++ b/stdnum/ec/ruc.py @@ -2,6 +2,7 @@ # coding: utf-8 # # Copyright (C) 2014 Jonathan Finlay +# Copyright (C) 2014 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -46,43 +47,9 @@ __all__ = ['compact', 'validate', 'is_valid'] compact = ci.compact -def calc_check_sum(number): - result = 0 - if int(number[2]) == 6: - # 6 = Public RUC - coefficient = "32765432" - result = sum(int(number[i]) * int(coefficient[i]) for i in range(8)) - residue = result % 11 - if residue == 0: - result = residue - else: - result = 11 - residue - elif int(number[2]) == 9: - # 9 = Juridical RUC - coefficient = "432765432" - result = sum(int(number[i]) * int(coefficient[i]) for i in range(9)) - residue = result % 11 - if residue == 0: - result = residue - else: - result = 11 - residue - elif int(number[2]) < 6: - # less than 6 = Natural RUC - coefficient = "212121212" - for i in range(9): - suma = int(number[i]) * int(coefficient[i]) - if suma > 10: - str_sum = str(suma) - suma = int(str_sum[0]) + int(str_sum[1]) - result += suma - residue = result % 10 - if residue == 0: - result = residue - else: - result = 10 - residue - else: - raise InvalidFormat() - return result +def _checksum(number, weights): + """Calculate a checksum over the number given the weights.""" + return sum(weights[i] * int(n) for i, n in enumerate(number)) % 11 def validate(number): @@ -93,9 +60,19 @@ def validate(number): raise InvalidLength() if not number.isdigit(): raise InvalidFormat() - checker = int(number[8]) if int(number[2]) == 6 else int(number[9]) - if calc_check_sum(number) != checker: - raise InvalidChecksum() + if number[2] < '6': + # 0..5 = natural RUC: CI plus establishment number + ci.validate(number[:10]) + elif number[2] == '6': + # 6 = public RUC + if _checksum(number[:9], (3, 2, 7, 6, 5, 4, 3, 2, 1)) != 0: + raise InvalidChecksum() + elif number[2] == '9': + # 9 = juridical RUC + if _checksum(number[:10], (4, 3, 2, 7, 6, 5, 4, 3, 2, 1)) != 0: + raise InvalidChecksum() + else: + raise InvalidComponent() # third digit wrong return number -- cgit v1.2.3 From e5250be45092363504ff61c868938439ec958985 Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Fri, 17 Oct 2014 21:14:42 +0200 Subject: Validate parts of numbers This raises exceptions when the provice or establishment number part of the number contains invalid values. --- stdnum/ec/ci.py | 4 ++++ stdnum/ec/ruc.py | 8 ++++++++ tests/test_ec_ci.doctest | 8 ++++++++ tests/test_ec_ruc.doctest | 26 ++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/stdnum/ec/ci.py b/stdnum/ec/ci.py index a32c6e3..9343e47 100644 --- a/stdnum/ec/ci.py +++ b/stdnum/ec/ci.py @@ -60,6 +60,10 @@ def validate(number): raise InvalidLength() if not number.isdigit(): raise InvalidFormat() + if number[:2] < '01' or number[:2] > '24': + raise InvalidComponent() # invalid province code + if number[2] > '5': + raise InvalidComponent() # third digit wrong if _checksum(number) != 0: raise InvalidChecksum() return number diff --git a/stdnum/ec/ruc.py b/stdnum/ec/ruc.py index 0bc62b5..8887467 100644 --- a/stdnum/ec/ruc.py +++ b/stdnum/ec/ruc.py @@ -60,15 +60,23 @@ def validate(number): raise InvalidLength() if not number.isdigit(): raise InvalidFormat() + if number[:2] < '01' or number[:2] > '24': + raise InvalidComponent() # invalid province code if number[2] < '6': # 0..5 = natural RUC: CI plus establishment number + if number[-3:] == '000': + raise InvalidComponent() # establishment number wrong ci.validate(number[:10]) elif number[2] == '6': # 6 = public RUC + if number[-4:] == '0000': + raise InvalidComponent() # establishment number wrong if _checksum(number[:9], (3, 2, 7, 6, 5, 4, 3, 2, 1)) != 0: raise InvalidChecksum() elif number[2] == '9': # 9 = juridical RUC + if number[-3:] == '000': + raise InvalidComponent() # establishment number wrong if _checksum(number[:10], (4, 3, 2, 7, 6, 5, 4, 3, 2, 1)) != 0: raise InvalidChecksum() else: diff --git a/tests/test_ec_ci.doctest b/tests/test_ec_ci.doctest index 2ab58fb..08efb8b 100644 --- a/tests/test_ec_ci.doctest +++ b/tests/test_ec_ci.doctest @@ -55,3 +55,11 @@ InvalidLength: ... Traceback (most recent call last): ... InvalidFormat: ... +>>> ci.validate('1784307108') # third digit wrong +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> ci.validate('8814307107') # invalid province code +Traceback (most recent call last): + ... +InvalidComponent: ... diff --git a/tests/test_ec_ruc.doctest b/tests/test_ec_ruc.doctest index e64346b..2f1065f 100644 --- a/tests/test_ec_ruc.doctest +++ b/tests/test_ec_ruc.doctest @@ -136,3 +136,29 @@ InvalidChecksum: ... Traceback (most recent call last): ... InvalidChecksum: ... + +>>> ruc.validate('8810034069001') # invalid province code in natural RUC +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> ruc.validate('8868152120001') # invalid province code in public RUC +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> ruc.validate('8892397539001') # invalid province code in juridical RUC +Traceback (most recent call last): + ... +InvalidComponent: ... + +>>> ruc.validate('0926687856000') # invalid establishment in natural RUC +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> ruc.validate('1760001550000') # invalid establishment in public RUC +Traceback (most recent call last): + ... +InvalidComponent: ... +>>> ruc.validate('0992397535000') # invalid establishment in juridical RUC +Traceback (most recent call last): + ... +InvalidComponent: ... -- cgit v1.2.3