lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.13-41-gc2284f3

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

python-stdnum branch master updated. 1.13-41-gc2284f3



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  c2284f322679e9527794aaa81e8fbb57792c5a21 (commit)
      from  94e2c6373e191e26beee6153ef2f99adcf31cf45 (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=c2284f322679e9527794aaa81e8fbb57792c5a21

commit c2284f322679e9527794aaa81e8fbb57792c5a21
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Sun Aug 2 17:45:46 2020 +0200

    Add Romanian Trade Register identifier
    
    Closes https://github.com/arthurdejong/python-stdnum/issues/229
    Closes https://github.com/arthurdejong/python-stdnum/pull/234

diff --git a/stdnum/ro/onrc.py b/stdnum/ro/onrc.py
new file mode 100644
index 0000000..da153e9
--- /dev/null
+++ b/stdnum/ro/onrc.py
@@ -0,0 +1,99 @@
+# onrc.py - functions for handling Romanian ONRC numbers
+# coding: utf-8
+#
+# Copyright (C) 2020 Dimitrios Josef Moustos
+# 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
+
+"""ONRC (Ordine din Registrul Comerţului, Romanian Trade Register identifier).
+
+All businesses in Romania have the to register with the National Trade
+Register Office to receive a registration number. The number contains
+information about the type of company, county, a sequence number and
+registration year.
+
+>>> validate('J52/750/2012')
+'J52/750/2012'
+>>> validate('X52/750/2012')
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+"""
+
+import datetime
+import re
+
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+# These characters should all be replaced by slashes
+_cleanup_re = re.compile(r'[ /\\-]+')
+
+# This pattern should match numbers that for some reason have a full date
+# as last field
+_onrc_fulldate_re = 
re.compile(r'^([A-Z][0-9]+/[0-9]+/)\d{2}[.]\d{2}[.](\d{4})$')
+
+# This pattern should match all valid numbers
+_onrc_re = re.compile(r'^[A-Z][0-9]+/[0-9]+/[0-9]+$')
+
+# List of valid counties
+_counties = set(list(range(1, 41)) + [51, 52])
+
+
+def compact(number):
+    """Convert the number to the minimal representation. This strips the
+    number of any valid separators and removes surrounding whitespace."""
+    number = _cleanup_re.sub('/', clean(number).upper().strip())
+    # remove optional slash between first letter and county digits
+    if number[1:2] == '/':
+        number = number[:1] + number[2:]
+    # normalise county number to two digits
+    if number[2:3] == '/':
+        number = number[:1] + '0' + number[1:]
+    # convert trailing full date to year only
+    m = _onrc_fulldate_re.match(number)
+    if m:
+        number = ''.join(m.groups())
+    return number
+
+
+def validate(number):
+    """Check if the number is a valid ONRC."""
+    number = compact(number)
+    if not _onrc_re.match(number):
+        raise InvalidFormat()
+    if number[:1] not in 'JFC':
+        raise InvalidComponent()
+    county, serial, year = number[1:].split('/')
+    if len(serial) > 5:
+        raise InvalidLength()
+    if len(county) not in (1, 2) or int(county) not in _counties:
+        raise InvalidComponent()
+    if len(year) != 4:
+        raise InvalidLength()
+    if int(year) < 1990 or int(year) > datetime.date.today().year:
+        raise InvalidComponent()
+    return number
+
+
+def is_valid(number):
+    """Check if the number is a valid ONRC."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
diff --git a/tests/test_ro_onrc.doctest b/tests/test_ro_onrc.doctest
new file mode 100644
index 0000000..6b47a5f
--- /dev/null
+++ b/tests/test_ro_onrc.doctest
@@ -0,0 +1,274 @@
+test_ro_onrc.doctest - more detailed doctests for the stdnum.ro.onrc module
+
+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 file contains more detailed doctests for the stdnum.ro.onrc module.
+
+>>> from stdnum.ro import onrc
+>>> from stdnum.exceptions import *
+
+
+Test some corner cases.
+
+>>> onrc.validate('J/52/750/2012')
+'J52/750/2012'
+>>> onrc.validate('J52/750/22.11.2012')  # valid, strip date, leave year
+'J52/750/2012'
+>>> onrc.validate('J 52 / 750 / 2012')
+'J52/750/2012'
+>>> onrc.validate('F 26 1132/2007')
+'F26/1132/2007'
+>>> onrc.validate('J22-1515-2007')
+'J22/1515/2007'
+>>> onrc.validate('X52/750/2012')  # fist letter invalid
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> onrc.validate('J52/100000/2012')  # second number too large
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> onrc.validate('J 52 / 750 / 200')  # year too short
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> onrc.validate('J/2/750/2012')  # county is normalised to two digits
+'J02/750/2012'
+>>> onrc.validate('J49/750/2012')  # invalid county
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> onrc.validate('J002 /123 /2015')  # invalid county
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> onrc.validate('J/52/750/2112')  # year in the future
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... C04/32/2005
+... C22/4/2018
+... C30/2/2009
+... F01 /592 /2013
+... F01/1477/2011
+... F04/876/2004
+... F05/696/2006
+... F06/340/2011
+... F07/176/2010
+... F07/477/2003
+... F08/1095/2005
+... F10/841/2012
+... F11/78/2012
+... F12/617/2011
+... F13/1917/2005
+... F14/217/2013
+... F14/218/2016
+... F18/1032/2011
+... F20/491/2013
+... F30/98/2008
+... F31/786/2011
+... F32/639/2013
+... F36/64/2008
+... F37/832/2013
+... F40/682/2004
+... F5/1055/2013
+... F5/2659/2013
+... F5/550/2012
+... F5/678/2013
+... F6/496/2015
+... F8/1302/2013
+... F8/672/2012
+... J 01/585/2002
+... J 40/1323/2005
+... J01/173/2004
+... J01/568/2015
+... J02/1253/2008
+... J02/143/2011
+... J02/169/01.02.2006
+... J02/238/2012
+... J02/310/2004
+... J03/1336/2007
+... J03/179/2004
+... J03/2299/1992
+... J03/442/2002
+... J03/630/2002
+... J03/803/2009
+... J03/920/2002
+... J04/368/2006
+... J04/822/1994
+... J05/1117/2004
+... J05/1464/2011
+... J05/1729/09.09.1991
+... J05/256/2010
+... J05/5114/1994
+... J05/582/2011
+... J06/1282/1994
+... J06/307/2009
+... J06/330/2003
+... J06/52/2001
+... J06/837/2008
+... J07/147/2001
+... J07/208/1998
+... J08/1233/2005
+... J08/1617/1997
+... J08/1716/1997
+... J08/215/27.02.1998
+... J08/2679/2008
+... J08/2720/2007
+... J08/545/2001
+... J08/61/2010
+... J08/68/2003
+... J08/926/2008
+... J09/2118/1994
+... J1/384/13.05.2015
+... J1/398/2005
+... J1/499/2012
+... J1/628/2016
+... J10/460/2012
+... J12/1103/2003
+... J12/1366/2003
+... J12/1701/16.10.1996
+... J12/1811/2002
+... J12/1816/2007
+... J12/1932/1993
+... J12/2322/2002
+... J12/2553/1992
+... J12/3388/2016
+... J12/3828/16.06.2017
+... J12/4365/2006
+... J12/487/2012
+... J12/573/2010
+... J12/595/1991
+... J12/633/2012
+... J12/850/2014
+... J13/197/2012
+... J13/2949/1991
+... J13/529/2006
+... J13/60/2005
+... J13/674/2016
+... J15/1279/1993
+... J15/680/2005
+... J16/1148/2005
+... J16/1930/2013
+... J16/2036/2011
+... J17/1241/1992
+... J17/2697/1992
+... J17/861/2012
+... J18/583/2015
+... J18/877/2006
+... J19/230/2007
+... J19/55/2002
+... J20/2034/1993
+... J21/512/2016
+... J21/565/1992
+... J22/1249/2012
+... J22/1774/2008
+... J22/3673/1994
+... J22/874/1996
+... J22/930/2016
+... J23/134/27.01.2006
+... J23/1657/14.06.2012
+... J23/461/2009
+... J23/4802/2017
+... J23/864/2017
+... J24/1082/2015
+... J24/246/2005
+... J24/908/2006
+... J26/1077/2008
+... J29/264/2014
+... J30/428/1993
+... J30/477/2014
+... J30/482/2014
+... J30/722/08.08.2016
+... J30/734/2014
+... J30/855/1993
+... J30/99/2009
+... J31 / 248 / 1994
+... J32/2241/1994
+... J32/331/2011
+... J32/631/2013
+... J33/277/2011
+... J33/451/2012
+... J35/1056/2008
+... J35/48/2013
+... J35/625/2003
+... J36/25/2001
+... J36/284/2017
+... J36/369/2015
+... J36/637/2018
+... J36/691/2008
+... J37/384/2009
+... J38/163/23.02.2006
+... J39 /771 /2005
+... J40/10944/2006
+... J40/11566/2011
+... J40/11591/2003
+... J40/11591/2009
+... J40/1293/23.10.2014
+... J40/13920/2003
+... J40/1472/1992
+... J40/1498/2010
+... J40/1667/2010
+... J40/17202/2006
+... J40/19473/2006
+... J40/19754/2007
+... J40/20281/2004
+... J40/23948/14.12.1994
+... J40/24874/1994
+... J40/2810/2017
+... J40/2867/2004
+... J40/3758/2008
+... J40/3905/30.03.2015
+... J40/4206/2008
+... J40/4463/2008
+... J40/4502/2011
+... J40/467/1998
+... J40/5139/1998
+... J40/7613/2003
+... J40/7888/1999
+... J40/8005/1995
+... J40/8577/2006
+... J40/8633/2013
+... J40/8910/2007
+... J40/8998/2010
+... J40/9712/2008
+... J5/1243/2016
+... J5/2916/03.09.1993
+... J51/159/2016
+... J51/229/2011
+... J51/74/2009
+... J52/128/2014
+... J52/474/1994
+... J52/60/2004
+... J6/974/2016
+... J7/2/2005
+... j05/1455/2012
+... j30/61/2010
+... j39/151/2019
+... j40/3674/2002
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not onrc.is_valid(x)]
+[]

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

Summary of changes:
 stdnum/ro/onrc.py          |  99 ++++++++++++++++
 tests/test_ro_onrc.doctest | 274 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 373 insertions(+)
 create mode 100644 stdnum/ro/onrc.py
 create mode 100644 tests/test_ro_onrc.doctest


hooks/post-receive
-- 
python-stdnum