diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2012-02-19 10:55:51 +0100 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2012-02-19 10:55:51 +0100 |
commit | b561d59a0a456d59b824fd3ca22f8868f0955a84 (patch) | |
tree | 41a06827c87e98a02212ad3b30389414a53dcf79 | |
parent | 61af19d29a0f401b209c9536f191600ad59107b3 (diff) |
add a VAT (European Union VAT number) module
git-svn-id: http://arthurdejong.org/svn/python-stdnum/python-stdnum@155 9dea7c4f-944c-4273-ac1a-574ede026edc
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | stdnum/__init__.py | 1 | ||||
-rw-r--r-- | stdnum/eu/__init__.py | 21 | ||||
-rw-r--r-- | stdnum/eu/vat.py | 85 | ||||
-rw-r--r-- | tests/test_eu_vat.doctest | 656 |
5 files changed, 764 insertions, 0 deletions
@@ -60,6 +60,7 @@ Currently this package supports the following formats: * VAT (Moms, Mervärdesskatt, Swedish VAT number) * VAT (United Kingdom (and Isle of Man) VAT registration number) * VAT (Идентификационен номер по ДДС, Bulgarian VAT number) + * VAT (European Union VAT number) * IMEI (International Mobile Equipment Identity) * IMSI (International Mobile Subscriber Identity) * MEID (Mobile Equipment Identifier) diff --git a/stdnum/__init__.py b/stdnum/__init__.py index c1b0570..beac0e5 100644 --- a/stdnum/__init__.py +++ b/stdnum/__init__.py @@ -74,6 +74,7 @@ Currently this package supports the following formats: * VAT (Moms, Mervärdesskatt, Swedish VAT number) * VAT (United Kingdom (and Isle of Man) VAT registration number) * VAT (Идентификационен номер по ДДС, Bulgarian VAT number) + * VAT (European Union VAT number) * IMEI (International Mobile Equipment Identity) * IMSI (International Mobile Subscriber Identity) * MEID (Mobile Equipment Identifier) diff --git a/stdnum/eu/__init__.py b/stdnum/eu/__init__.py new file mode 100644 index 0000000..a00e832 --- /dev/null +++ b/stdnum/eu/__init__.py @@ -0,0 +1,21 @@ +# __init__.py - collection of European Union numbers +# coding: utf-8 +# +# Copyright (C) 2012 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 + +"""Collection of European Union numbers.""" diff --git a/stdnum/eu/vat.py b/stdnum/eu/vat.py new file mode 100644 index 0000000..a408b8f --- /dev/null +++ b/stdnum/eu/vat.py @@ -0,0 +1,85 @@ +# vat.py - functions for handling European VAT numbers +# coding: utf-8 +# +# Copyright (C) 2012 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 + +"""Module for handling various European VAT numbers. + +>>> is_valid('ATU 57194903') +True +>>> is_valid('BE697449992') +True +>>> compact('FR 61 954 506 077') +'FR61954506077' +>>> guess_country('00449544B01') +['nl'] +""" + + +country_codes = set([ + 'at', 'be', 'bg', 'cy', 'cz', 'de', 'dk', 'ee', 'es', 'fi', 'fr', 'gb', + 'gr', 'hu', 'ie', 'it', 'lt', 'lu', 'lv', 'mt', 'nl', 'pl', 'pt', 'ro', + 'se', 'si', 'sk' +]) +"""The collection of country codes that are queried.""" + +_country_modules = dict() + + +def _get_cc_module(cc): + """Get the VAT number module based on the country code.""" + # Greece uses a "wrong" country code + cc = cc.lower() + if cc == 'el': + cc = 'gr' + if cc not in country_codes: + return + if cc not in _country_modules: + # do `from stdnum.CC import vat` instead of `import stdnum.CC.vat` + # to handle the case where vat is an alias + _country_modules[cc] = __import__( + 'stdnum.%s' % cc, globals(), locals(), ['vat']).vat + return _country_modules[cc] + + +def compact(number): + """Convert the number to the minimal representation. This strips the + number of any valid separators and removes surrounding whitespace.""" + number = number.upper().strip() + return number[:2] + _get_cc_module(number[:2]).compact(number[2:]) + + +def is_valid(number): + """Checks to see if the number provided is a valid VAT number. This + performs the country-specific check for the number.""" + try: + number = compact(number) + except: + return False + module = _get_cc_module(number[:2]) + return bool(module) and module.is_valid(number[2:]) + + +def guess_country(number): + """Guess the country code based on the provided number. This checks the + provided number against each of the validation routines and returns + the list of countries for which it is valid. This returns lower case + codes and returns gr (instead of el) for Greece.""" + return [cc + for cc in country_codes + if _get_cc_module(cc).is_valid(number)] diff --git a/tests/test_eu_vat.doctest b/tests/test_eu_vat.doctest new file mode 100644 index 0000000..82ccf8c --- /dev/null +++ b/tests/test_eu_vat.doctest @@ -0,0 +1,656 @@ +test_eu_vat.doctest - more detailed doctests for the stdnum.eu.vat module + +Copyright (C) 2012 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.eu.vat module. It +tries to validate a number of VAT numbers that have been found online. + +>>> from stdnum.eu import vat + + +These have been found online and should all be valid numbers. + +>>> numbers = ''' +... +... ATU 142 43 102 +... ATU 15159209 +... ATU 28560205 +... ATU 34172105 +... ATU 40698107 +... ATU 46276408 +... ATU 49362201 +... ATU 54299806 +... ATU 54300000 +... ATU 56377717 +... ATU 57194903 +... ATU 64487479 +... ATU 64762368 +... ATU 64938009 +... ATU 65020906 +... ATU 65033803 +... ATU 65034704 +... ATU 65480455 +... ATU46080404 +... ATU61195628 +... +... BE (0)468.561.072 +... BE 0202.239.951 +... BE 0220.764.971 +... BE 0248.015.142 +... BE 0402 918 402 +... BE 0407.139.583 +... BE 0408 299 922 +... BE 0441.928.931 +... BE 0450 118 996 +... BE 0462423150 +... BE 0474 621 394 +... BE 0795 013 186 +... BE 0897290877 +... BE 444.503.092 +... BE 456.973.433 +... BE 464 401 356 +... BE413562567 +... BE697449992 +... +... BG 103873594 +... BG 124 551 319 +... BG 130 358 310 +... BG 131 272 009 +... BG 131202360 +... BG 147137471 +... BG 175074752 +... BG 175186242 +... BG 200182590 +... BG 200950556 +... BG130544585 +... Bg 200442771 +... +... CY 10246672X +... CY 10263870R +... CY 10274231F +... CY 10285193Z +... CY- 10277198H +... CY-10008489 A +... CY-10189098G +... CY-10258074Y +... CY-10259033P +... CY00632993 F +... +... CZ 25123891 +... CZ 25577581 +... CZ 26852357 +... CZ 61467839 +... CZ 640229/4448 +... CZ 640903926 +... CZ 6956220612 +... CZ 736028/5163 +... CZ 8058012314 +... CZ26780259 +... CZ48207926 +... CZ49620819 +... CZ6306150004 +... +... DE 118619592 +... DE 125014955 +... DE 129304291 +... DE 168347747 +... DE 181 207 708 +... DE 195131068 +... DE 204 760 908 +... DE 213 806 597 +... DE 221.304.969 +... DE 246 595 415 +... DE 811 363 057 +... DE 811125440 +... DE 811305931 +... DE 813 11 38 75 +... DE 813 184868 +... DE - 113866163 +... DE - 231969187 +... DE - 265265318 +... DE - 267297673 +... DE119263782 +... DE129390950 +... DE136308783 +... DE812847601 +... +... DK 10 50 32 80 +... DK 11 97 56 58 +... DK 12 14 48 22 +... DK 13 20 24 35 +... DK 13 31 04 59 +... DK 16 89 50 16 +... DK 25 18 63 11 +... DK 25 76 63 69 +... DK 25 86 35 26 +... DK 2566 2202 +... DK 26 09 77 89 +... DK 26 57 61 64 +... DK 28 01 76 34 +... DK 28107773 +... DK 29523215 +... DK 30 06 09 46 +... DK 32 27 15 02 +... DK 32329853 +... DK 65 07 04 13 +... DK 90 30 16 59 +... DK-20 04 52 72 +... DK-20 64 64 46 +... DK-27630308 +... DK-27926592 +... DK-28840926 +... DK-31882095 +... DK-33053266 +... DK10150817 +... DK10290813 +... DK26210895 +... DK36149213 +... DK: 21599336 +... +... EE 100 931 558 +... EE 100523487 +... EE 100572933 +... EE 100578209 +... EE 100594102 +... EE 100594403 +... EE 100832107 +... EE 100834066 +... EE 101031389 +... EE 101286639 +... EE 101288941 +... EE101256753 +... +... ES - Q0818001J +... ES 54362315K +... ES A-28184661 +... ES A-60631835 +... ES A-60997582 +... ES A08370314 +... ES A17028366 +... ES B-58378431 +... ES B64240914 +... ES B64717838 +... ES B79110482 +... ES B80975063 +... ES F13005293 +... ES J99216582 +... ES Q-2818015-F +... ES R9600075G +... ES U99216426 +... ES U99216632 +... ES V99218067 +... ES W4003922D +... ES X-5253868-R +... ES X5277343Q +... ES Y5277343F +... ES Z5277343K +... ES- A84409408 +... ES-A08074908 +... ES-B 60432291 +... ES-B18889204 +... ES-B55015432 +... ES-B64995111 +... ES-B96902531 +... ES-x-2482300w +... ESA78109592 +... Es-a58951310 +... +... EL 039868210 +... EL 044824428 +... EL 072130053 +... EL 082499478 +... EL 094012834 +... EL 094064321 +... EL 094068633 +... EL 094237076 +... EL 094263543 +... EL 095217179 +... EL 095304080 +... EL 099548630 +... EL 94051189 +... EL 998386804 +... EL 998408192 +... EL 998722134 +... EL 999038150 +... EL 999107669 +... EL 999533911 +... EL 999698730 +... EL 999715835 +... EL-082857563 +... EL094501040 +... EL098099809 +... EL: 094279805 +... El 800 179 925 +... +... FI 02459042 +... FI 0982651-1 +... FI 10320534 +... FI 18949388 +... FI 20194885 +... FI 20774740 +... FI 2094606-3 +... FI 24416318 +... FI- 01968312 +... FI- 22291259 +... FI-214 95 540 +... FI-22291240 +... FI-24163066 +... FI18261444 +... +... FR 04409414364 +... FR 09434086930 +... FR 114 248 728 36 +... FR 13 393 892 815 +... FR 163 041 877 01 +... FR 18 349 685 099 +... FR 19 552 008 443 +... FR 19552143273 +... FR 20 329 450 738 +... FR 21 448 834 911 +... FR 2143 2146 546 +... FR 22 326 565 603 +... FR 22 379 160 070 +... FR 26 495 205 213 +... FR 28337893168 +... FR 355 92065536 +... FR 36 380 610 451 +... FR 36502095094 +... FR 38 353427495 +... FR 41-343848552 +... FR 53418304010 +... FR 60391548955 +... FR 61 954 506 077 +... FR 63 334 214 293 +... FR 65 444 243 075 +... FR 68 378 838 692 +... FR 70492082151 +... FR 72 483 995 197 +... FR 734 836 491 66 +... FR 736 220 50 318 +... FR 74 397 888 330 +... FR 77 055 501 902 +... FR 77 384 627 170 +... FR 78528824428 +... FR 79 410 964 837 +... FR 83 404 833 048 +... FR 84 323 140 392 +... FR 86 394 303 796 +... FR 86 542 103 569 +... FR 88775649726 +... FR 94016950842 +... FR K 7399859412 +... FR01712030113 +... FR64333266765 +... FR82542065479 +... FR83404833048 +... FR86451397608 +... FR95483929956 +... Fr 40 303 265 045 +... Fr 96 631 620 572 +... fr 71383076817 +... +... GB 002 4257 28 +... GB 003232345 +... GB 100 1950 75 +... GB 100190874 +... GB 102675046 +... GB 232177091 +... GB 242338087388 +... GB 311 405 025 +... GB 362 5866 29 +... GB 417 2280 71 +... GB 436 0630 72 +... GB 495 2781 05 +... GB 507 5768 25 +... GB 521 6763 52 +... GB 586 367 295 +... GB 591 9373 01 +... GB 605 8678 15 +... GB 662 8564 06 +... GB 698 550 577 +... GB 733 4428 41 +... GB 770 381 235 +... GB 784 9117 89 +... GB 808 6365 12 +... GB 812 8333 44 +... GB 818243334 +... GB 823 531 352 +... GB 829 9594 59 +... GB 845788960 +... GB 879 7056 62 +... GB 881 3758 91 +... GB 913 3041 68 +... GB 933210951 +... GB 975 8664 50 +... GB 977 4872 51 +... GB 980780684 +... GB 997 7094 44 +... GB260311213 +... GB653599494 +... GB974053902 +... +... HU -12509403 +... HU 10672101 +... HU 10766172 +... HU 11444923 +... HU 12723650 +... HU 12840937 +... HU 13851909 +... HU 18206373 +... HU 23157653 +... HU 64241281 +... HU-10402434 +... HU-12892312 +... HU-14528114 +... HU11377304 +... HU12078503 +... HU13852467 +... +... IE 0005306C +... IE 4550159S +... IE 4693875V +... IE 4731823J +... IE 632 3420 C +... IE 6324720T +... IE 6339273F +... IE 635 430 5C +... IE 6388047V +... IE 6397893P +... IE 6433435F +... IE 6436390B +... IE 6791517I +... IE 8223200u +... IE 9502346O +... IE 9574173P +... IE 9679477V +... IE 9719156S +... IE 9741812E +... IE 9742129V +... IE-9696131F +... IE6599001W +... IE8D79739I +... IE9Y71814N +... +... IT - 01404480202 +... IT 0 0 6 1 8 2 8 0 4 9 9 +... IT 00 595 000 217 +... IT 00118439991 +... IT 00193180932 +... IT 00520800319 +... IT 00571320076 +... IT 00687120980 +... IT 01189820689 +... IT 01413270396 +... IT 01465210449 +... IT 01501180333 +... IT 01606120226 +... IT 01687870137 +... IT 01720020344 +... IT 01822890388 +... IT 02100550264 +... IT 02109480976 +... IT 02153481201 +... IT 02359210354 +... IT 02408660211 +... IT 02829410980 +... IT 03274440241 +... IT 03367280363 +... IT 04894530635 +... IT 05366960010 +... IT 05460820961 +... IT 05617370969 +... IT 06075960010 +... IT 06729900966 +... IT 06863340961 +... IT 09596821000 +... IT 12920760159 +... IT-01626160210 +... IT-03700020104 +... IT-03827740402 +... IT-09159800011 +... IT00743110157 +... IT02087050155 +... IT: 02331250163 +... +... LT 100001354118 +... LT 100001509912 +... LT 100001799517 +... LT 100001890913 +... LT 100001906711 +... LT 100001919017 +... LT 100002645517 +... LT 100002922012 +... LT 100003619917 +... LT 100005066013 +... LT 100005929611 +... LT 119511515 +... LT 235449811 +... LT 250266219 +... LT 258596610 +... LT 354991917 +... LT 616414610 +... LT 757118413 +... LT-100000979812 +... LT100001251914 +... LT100002894215 +... LT100004801610 +... LT290068995116 +... +... LU 10059929 +... LU 10590281 +... LU 109 676 28 +... LU 11082217 +... LU 13178262 +... LU 150 274 42 +... LU 1871 0830 +... LU 19184853 +... LU 19406747 +... LU 19979983 +... LU 20981643 +... LU 21989666 +... LU 22 22 12 68 +... LU 22690342 +... LU 22991225 +... LU.248.70.640 +... LU: 20993674 +... LU: 2294 4200 +... Lu 19980500 +... +... LV 4000 3521 600 +... LV 40003189718 +... LV 40003282138 +... LV 40003449366 +... LV 40003655379 +... LV 40003718068 +... LV 40003754957 +... LV 40003777428 +... LV 40003939038 +... LV 40008000102 +... LV 40103077610 +... LV 40103157009 +... LV 40103179665 +... LV 40103264016 +... LV 43603009384 +... LV 44103040262 +... LV 5000 399 3021 +... LV 50003087101 +... LV 90000528023 +... LV-40003241337 +... LV-40003467376 +... LV-42103016370 +... LV-42103048183 +... +... MT 1039-6417 +... MT 1167-9112 +... MT 1465 8213 +... MT 1613-4207 +... MT 17025737 +... MT 18740407 +... MT 1894 0705 +... MT 1966 1023 +... MT 19784818 +... MT 2029 1423 +... MT 20630321 +... +... NL 001241 643 B01 +... NL 009122746 B01 +... NL 806753742B01 +... NL 820605876B01 +... NL 8225.69.759 b01 +... NL-812421267 B01 +... NL-8197.38.116.B.01 +... NL.0094.10.806.B.01 +... NL.8143.26.584.B.01 +... NL.8186.43.778.B.01 +... NL001309675B01 +... NL001545668B01 +... NL003376734B77 +... NL00449544B01 +... NL006375054B01 +... NL006866049B01 +... NL007394913B01 +... NL009093503B01 +... NL019077312B01 +... NL066593931B01 +... NL068357370B01 +... NL117621729B01 +... NL167647672B01 +... NL4495445B01 +... NL68357370B01 +... NL802003217B01 +... NL808373894B01 +... NL811705262B01 +... NL813411786B01 +... +... PL 5211754253 +... PL 5262987091 +... PL 584-030-44-72 +... PL 5840154038 +... PL 5840304472 +... PL 5860224115 +... PL 6330005110 +... PL 6661913137 +... PL 687-16-26-585 +... PL 777 26 68 285 +... PL 7780104605 +... PL 7881154591 +... PL 9562197426 +... PL-7532365958 +... PL-951-157-77-68 +... PL5261025421 +... PL6772135826 +... +... PT 500 019 720 +... PT 500135.495 +... PT 501 507 930 +... PT 501 519 246 +... PT 501 964 843 +... PT 502448911 +... PT 502971142 +... PT 504141066 +... PT 506 030 636 +... PT 506835669 +... PT 507 223 730 +... PT 507 757 505 +... PT 507 859 146 +... PT 507297687 +... PT 508 081 327 +... PT 509 250 505 +... PT 509284930 +... PT-505 856 468 +... PT503038083 +... +... RO 11358544 +... RO 13837330 +... RO 14840784 +... RO 1630615123457 +... RO 16621241 +... RO 17832344 +... RO 1822964 +... RO 18341035 +... RO 185 472 90 +... RO 18779508 +... RO 20950021 +... RO 21356044 +... RO 21996566 +... RO 241 30 20 +... RO 24736200 +... RO 3087444 +... RO 4003786 +... RO 4019740 +... RO 4257679 +... RO 573768 +... RO 6010151 +... RO 6322498 +... RO 6655328 +... RO-23867797 +... RO-27849238 +... RO16241790 +... Ro 15071875 +... +... SE 202 100-5000 01 +... SE 390 806 051 401 +... SE 55 62 00-0777 01 +... SE 55 67 59 32 48 01 +... SE 556.383.740.901 +... SE 556058115801 +... SE 556126249301 +... SE 556433592401 +... SE 556700 3552 01 +... SE 556708202801 +... SE 556728341001 +... SE 556848115301 +... SE 720 522 241 201 +... SE-502053602401 +... SE-556 644 662 001 +... SE-556 792 355 101 +... SE-5562245190-01 +... SE-556271210801 +... SE-556666-4438-01 +... SE556043606401 +... Se 556250398601 +... +... SI 26808498 +... SI 29664373 +... SI 3609 7152 +... SI 48673820 +... SI 50223054 +... SI 56633360 +... SI 56951442 +... SI 68297530 +... SI 70310815 +... SI 73567906 +... SI 85390518 +... SI 92351069 +... SI-83815201 +... SI-89036999 +... +... SK 1078449064 +... SK 202 274 96 19 +... SK 2020 237 945 +... SK 2020257679 +... SK 2021 6858 20 +... SK 2021853504 +... SK 2021998528 +... SK 2022193459 +... SK2022193459 +... +... ''' +>>> [ x for x in numbers.splitlines() if x and not vat.is_valid(x) ] +[] |