lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.13-32-g1b7e985

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.13-32-g1b7e985



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  1b7e985ff7dbf60b7f41d004fe39292c25bd2ae5 (commit)
       via  b3891f1eff22c46d0856b1b303781f911c2b2e5a (commit)
      from  127fff17bf612ba8457ea84424ce4d99abd62306 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://arthurdejong.org/git/python-stdnum/commit/?id=1b7e985ff7dbf60b7f41d004fe39292c25bd2ae5

commit 1b7e985ff7dbf60b7f41d004fe39292c25bd2ae5
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sat May 16 16:04:21 2020 +0200

    Add an online check for the South Korean BRN

diff --git a/stdnum/kr/GPKIRootCA1.crt b/stdnum/kr/GPKIRootCA1.crt
new file mode 100644
index 0000000..20fc1c7
--- /dev/null
+++ b/stdnum/kr/GPKIRootCA1.crt
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJLUjEc
+MBoGA1UECgwTR292ZXJubWVudCBvZiBLb3JlYTENMAsGA1UECwwER1BLSTEUMBIG
+A1UEAwwLR1BLSVJvb3RDQTEwHhcNMTEwODAzMDY1MjMwWhcNMzEwODAzMDY1MjMw
+WjBQMQswCQYDVQQGEwJLUjEcMBoGA1UECgwTR292ZXJubWVudCBvZiBLb3JlYTEN
+MAsGA1UECwwER1BLSTEUMBIGA1UEAwwLR1BLSVJvb3RDQTEwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCh/m8EBbDJhGQyN2+g5dTlsgjtaRKqhgj3gkYK
+BgtuXsXkaTVxbf99AvbN3QE8+WCIaPJUd0091UGmLzaBVyW4ct+iUNrX/FXyzjaf
+bNbbl1nfHhaZhkiOTVQhmY5zuj96evEtJMevnxe6iRADOPWnqp+CxT2IzcSFkQCq
+7L2qn8hU2/LpXUvnAYglJZi8t6Ef+r03P1r8dA5OzZ8yV3qhD1R1wsNQtCzMgwcE
+rFRZhFZYuxpfmS5y0fZW0seeTjcdxHiR3whYI5U6AI7DjdWIrT9Cd9ByV4aevkBh
+qkePPIYGmUPXnnqCkdHdnzkMH0WP9TBhD2jTXZKdcFtTyEJrAgMBAAGjQjBAMB0G
+A1UdDgQWBBR4A+sMjKbTVXWkh7Tr0ZpmD0xzizAOBgNVHQ8BAf8EBAMCAQYwDwYD
+VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEARGJWATwo81x7UEQugNbi
+cL8IWXoV51SZVH3kz49fNUjVoq1n2yzfaMddlblbflDNObp/68DxTlSXCeqFHkgi
+/WvyVHERRECXnF0WeeelI+Q8XdF3IJZLT3u5Ss0VAB2loCuC+4hBWSRQu2WZu2Yk
+s9eBN0x6NmtopRmnf2d6VrcFA+WOgUeTjXiDkG52IaPw0w1uTfmRw5epky5idyY2
+bfJ1JeVUINMJnOWpgLkOH3xxakoD8F1Fbi6C3t7MmKupojUq/toUDms6zTk3DIkc
+wd7PALNWL5U8TxNLoroTHSf/lzaOv3o9KDRa0FQo58bPI7MdbRWE4F3mS/ZIrnv7
+jQ==
+-----END CERTIFICATE-----
diff --git a/stdnum/kr/brn.py b/stdnum/kr/brn.py
index c004aa9..652ecf3 100644
--- a/stdnum/kr/brn.py
+++ b/stdnum/kr/brn.py
@@ -2,6 +2,7 @@
 # coding: utf-8
 #
 # Copyright (C) 2020 Leandro Regueiro
+# Copyright (C) 2020 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
@@ -83,3 +84,19 @@ def format(number):
     """Reformat the number to the standard presentation format."""
     number = compact(number)
     return '-'.join([number[:3], number[3:5], number[5:]])
+
+
+def check_ftc(number, timeout=30):  # pragma: no cover
+    """Check the number against the Korea Fair Trade Commission website."""
+    from pkg_resources import resource_filename
+    import lxml.html
+    import requests
+    number = compact(number)
+    url = 'https://www.ftc.go.kr/bizCommPop.do'
+    certificate = resource_filename(__name__, 'GPKIRootCA1.crt')
+    document = lxml.html.fromstring(
+        requests.get(url, params={'wrkr_no': number}, timeout=timeout, 
verify=certificate).text)
+    data = dict(zip(
+        [(x.text or '').strip() for x in document.findall('.//th')],
+        [(x.text or '').strip() for x in document.findall('.//td')]))
+    return data or None
diff --git a/tests/test_kr_brn.py b/tests/test_kr_brn.py
new file mode 100644
index 0000000..31cd9d6
--- /dev/null
+++ b/tests/test_kr_brn.py
@@ -0,0 +1,46 @@
+# test_kr_brn.py - functions for testing the online BRN validation
+# coding: utf-8
+#
+# Copyright (C) 2020 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 is a separate test file because it should not be run regularly
+# because it could negatively impact the online service.
+
+"""Extra tests for the stdnum.kr.brn module."""
+
+import os
+import unittest
+
+from stdnum.kr import brn
+
+
+@unittest.skipIf(
+    not os.environ.get('ONLINE_TESTS'),
+    'Do not overload online services')
+class TestFTC(unittest.TestCase):
+    """Test the check provided based on the Korea Fair Trade Commission
+    website."""
+
+    def test_check_ftc(self):
+        """Test stdnum.kr.brn.check_ftc()"""
+        # Test a normal valid number
+        result = brn.check_ftc('109-81-39795')
+        self.assertTrue(result)
+        # Test an invalid number
+        result = brn.check_ftc('109-81-39796')
+        self.assertIsNone(result)

https://arthurdejong.org/git/python-stdnum/commit/?id=b3891f1eff22c46d0856b1b303781f911c2b2e5a

commit b3891f1eff22c46d0856b1b303781f911c2b2e5a
Author: Leandro Regueiro <leandro.regueiro@gmail.com>
Date:   Sat Mar 7 20:56:13 2020 +0100

    Add support for South Korea Business Registration Number
    
    Closes https://github.com/arthurdejong/python-stdnum/pull/197
    Closes https://github.com/arthurdejong/python-stdnum/issues/101

diff --git a/stdnum/kr/__init__.py b/stdnum/kr/__init__.py
index 03cbe0f..b8d75f2 100644
--- a/stdnum/kr/__init__.py
+++ b/stdnum/kr/__init__.py
@@ -19,3 +19,6 @@
 # 02110-1301 USA
 
 """Collection of South Korean numbers."""
+
+# provide aliases
+from stdnum.kr import brn as vat  # noqa: F401
diff --git a/stdnum/kr/brn.py b/stdnum/kr/brn.py
new file mode 100644
index 0000000..c004aa9
--- /dev/null
+++ b/stdnum/kr/brn.py
@@ -0,0 +1,85 @@
+# brn.py - functions for handling South Korean BRN
+# coding: utf-8
+#
+# Copyright (C) 2020 Leandro Regueiro
+#
+# 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
+
+"""BRN (사업자 등록 번호, South Korea Business Registration Number).
+
+The Business Registration Number is issued by the district tax office in the
+local jurisdiction for tax purposes. The number consists of 10 digits and
+contain the tax office number (3 digits), the type of business (2 digits), a
+serially assigned value (4 digits) and a single check digit.
+
+More information:
+
+* 
https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Korea-TIN.pdf
+
+>>> validate('116-82-00276')
+'1168200276'
+>>> validate('1168200276')
+'1168200276'
+>>> validate(' 116 - 82 - 00276  ')
+'1168200276'
+>>> validate('123456789')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> format('1348672683')
+'134-86-72683'
+"""
+
+from stdnum.exceptions import *
+from stdnum.util import clean, isdigits
+
+
+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, ' -').strip()
+
+
+def validate(number):
+    """Check if the number is a valid South Korea BRN number.
+
+    This checks the length and formatting.
+    """
+    number = compact(number)
+    if len(number) != 10:
+        raise InvalidLength()
+    if not isdigits(number):
+        raise InvalidFormat()
+    if number[:3] < '101' or number[3:5] == '00' or number[5:-1] == '0000':
+        raise InvalidComponent()
+    return number
+
+
+def is_valid(number):
+    """Check if the number is a valid South Korea BRN number."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
+
+
+def format(number):
+    """Reformat the number to the standard presentation format."""
+    number = compact(number)
+    return '-'.join([number[:3], number[3:5], number[5:]])
diff --git a/tests/test_kr_brn.doctest b/tests/test_kr_brn.doctest
new file mode 100644
index 0000000..668a975
--- /dev/null
+++ b/tests/test_kr_brn.doctest
@@ -0,0 +1,303 @@
+test_kr_brn.doctest - more detailed doctests for stdnum.kr.brn module
+
+Copyright (C) 2020 Leandro Regueiro
+
+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.kr.brn module. It
+tries to test more corner cases and detailed functionality that is not really
+useful as module documentation.
+
+>>> from stdnum.kr import brn
+
+
+Tests for some corner cases.
+
+>>> brn.validate('2098206382')
+'2098206382'
+>>> brn.validate('211-86-08983')
+'2118608983'
+>>> brn.validate('317 - 81 - 11175')
+'3178111175'
+>>> brn.validate('220 88 69974')
+'2208869974'
+>>> brn.format('1304717700')
+'130-47-17700'
+>>> brn.validate('80123456785')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> brn.validate('FF34567890')
+Traceback (most recent call last):
+    ...
+InvalidFormat: ...
+>>> brn.validate('100-86-08983')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> brn.validate('211-00-08983')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> brn.validate('211-86-00003')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... 101-82-13065
+... 102-81-03525
+... 102-81-42945
+... 104-81-25258
+... 104-81-36565
+... 104-84-03406
+... 105-17-41513
+... 105-86-61489
+... 106-82-07200
+... 107-82-09351
+... 107-87-13471
+... 107-87-70962
+... 108-19-83613
+... 109-81-33637
+... 109-81-39795
+... 109-81-62393
+... 110-12-39727
+... 110-14-16596
+... 110-81-05034
+... 110-81-07390
+... 110-81-40725
+... 110-84-02173
+... 112-81-30811
+... 113-02-43949
+... 113-81-92367
+... 113-85-26486
+... 113-86-21886
+... 113-86-38602
+... 113-86-46500
+... 113-86-60856
+... 114-81-44645
+... 114-82-62150
+... 114-86-00579
+... 114-86-04968
+... 114-86-61464
+... 116-82-00276
+... 117-81-77714
+... 118-81-09714
+... 119-02-43947
+... 119-19-96781
+... 119-82-08146
+... 119-82-63265
+... 119-86-44529
+... 119-86-79111
+... 119-87-08063
+... 120-81-57465
+... 120-86-39706
+... 1208200052
+... 121-81-25326
+... 121-81-42209
+... 121-81-78347
+... 122-81-62455
+... 124-81-79802
+... 124-86-13144
+... 124-86-65341
+... 124-86-85333
+... 127-11-87351
+... 128-02-41206
+... 128-39-49844
+... 128-81-63302
+... 128-81-77295
+... 129-81-16573
+... 129-81-23356
+... 129-81-30691
+... 129-81-85385
+... 129-86-38970
+... 129-86-39907
+... 130-47-17700
+... 130-81-92528
+... 130-86-35857
+... 130-86-79710
+... 130-86-89294
+... 131-82-00372
+... 131-86-40843
+... 132-81-38608
+... 132-86-04520
+... 133-81-29441
+... 133-81-32077
+... 133-81-40621
+... 134-81-06679
+... 134-86-24634
+... 134-86-44004
+... 134-86-72683
+... 135-09-24640
+... 135-29-80067
+... 135-81-06333
+... 137-86-39058
+... 138-81-03499
+... 138-81-44092
+... 138-81-44277
+... 140-81-67744
+... 141-81-18585
+... 143-81-10463
+... 144-81-25090
+... 148-05-00404
+... 156-23-00883
+... 169-86-00394
+... 183-98-00113
+... 187-82-00055
+... 193-86-00010
+... 201-81-54845
+... 201-81-76228
+... 201-81-99798
+... 201-85-17396
+... 201-86-25781
+... 202-81-04367
+... 202-81-42420
+... 204-06-91556
+... 204-86-46427
+... 205-81-26341
+... 206-18-12345
+... 206-86-50913
+... 208-81-24115
+... 209-82-05326
+... 209-82-06382
+... 211-86-08983
+... 211-86-23306
+... 211-86-39754
+... 211-87-67960
+... 214-11-58465
+... 214-81-04230
+... 214-87-78980
+... 214-87-98889
+... 214-87-99743
+... 214-88-49333
+... 214-88-51159
+... 215-87-86862
+... 217-81-14493
+... 219-01-39810
+... 220 88 69974
+... 220-81-66148
+... 220-81-83676
+... 220-82-05060
+... 220-87-18070
+... 220-87-57205
+... 220-88-75699
+... 220-88-88699
+... 221-81-32210
+... 221-83-01195
+... 222-81-03192
+... 224-81-41168
+... 231-81-02896
+... 275-87-01259
+... 279-81-01263
+... 280-86-01410
+... 301-81-14992
+... 301-81-91475
+... 301-82-62166
+... 301-86-12266
+... 303-12-73313
+... 303-81-44911
+... 303-82-07378
+... 305-81-38564
+... 305-81-70638
+... 305-81-87876
+... 306-81-22629
+... 306-82-00417
+... 308-81-41001
+... 311-81-22413
+... 312-12-25168
+... 312-30-06675
+... 312-81-95317
+... 314-81-25684
+... 314-82-01980
+... 314-86-00956
+... 314-86-42432
+... 314-86-53230
+... 314-86-63209
+... 317 - 81 - 11175
+... 317-81-04543
+... 318-81-02096
+... 321-81-00982
+... 348-13-00692
+... 364-81-00669
+... 374-81-01516
+... 375-10-00859
+... 375-88-00519
+... 383-37-00143
+... 394-92-00410
+... 398-85-00113
+... 402-82-15272
+... 409-86-33769
+... 410-25-53731
+... 410-82-83844
+... 410-86-53770
+... 415-06-83258
+... 415-81-19511
+... 415-82-11025
+... 416-81-48042
+... 417-85-07912
+... 420-87-00883
+... 501-26-78904
+... 503-86-09407
+... 504-81-85233
+... 504-85-11802
+... 506-82-06755
+... 514-81-68599
+... 515-04-62016
+... 515-05-32580
+... 515-07-68272
+... 515-81-10315
+... 515-81-40648
+... 533-85-00526
+... 533-87-01306
+... 568-41-00305
+... 580-21-00836
+... 582-90-00497
+... 602-81-66559
+... 603-81-24270
+... 606-81-54507
+... 606-86-06989
+... 609-81-99124
+... 610-09-84339
+... 610-81-04971
+... 615-82-11718
+... 615-86-09068
+... 616-24-46281
+... 616-25-12643
+... 617-86-11575
+... 621-15-41743
+... 632-11-01006
+... 639-86-00985
+... 649-82-00117
+... 669-81-00996
+... 680-87-00210
+... 682-85-00885
+... 728-86-00316
+... 735-85-00501
+... 760-06-00079
+... 766-88-00563
+... 782-86-00130
+... 809-81-01574
+... 816-81-00840
+... 884-17-01026
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not brn.is_valid(x)]
+[]

-----------------------------------------------------------------------

Summary of changes:
 stdnum/kr/GPKIRootCA1.crt                          |  21 ++
 stdnum/kr/__init__.py                              |   3 +
 stdnum/kr/brn.py                                   | 102 +++++++
 tests/test_kr_brn.doctest                          | 303 +++++++++++++++++++++
 ..._de_handelsregisternummer.py => test_kr_brn.py} |  27 +-
 5 files changed, 442 insertions(+), 14 deletions(-)
 create mode 100644 stdnum/kr/GPKIRootCA1.crt
 create mode 100644 stdnum/kr/brn.py
 create mode 100644 tests/test_kr_brn.doctest
 copy tests/{test_de_handelsregisternummer.py => test_kr_brn.py} (56%)


hooks/post-receive
-- 
python-stdnum