python-stdnum branch master updated. 2.1-20-gcd94bf1
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
python-stdnum branch master updated. 2.1-20-gcd94bf1
- From: Commits of the python-stdnum project <python-stdnum-commits [at] lists.arthurdejong.org>
- To: python-stdnum-commits [at] lists.arthurdejong.org
- Reply-to: python-stdnum-users [at] lists.arthurdejong.org, python-stdnum-commits [at] lists.arthurdejong.org
- Subject: python-stdnum branch master updated. 2.1-20-gcd94bf1
- Date: Sat, 3 Jan 2026 14:16:55 +0100 (CET)
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 cd94bf1147508a5132f0439e8d6c1ed3e2a7e14f (commit)
from 293136bc3a83f53bb13eda0806cb6d4b7dfcea0d (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=cd94bf1147508a5132f0439e8d6c1ed3e2a7e14f
commit cd94bf1147508a5132f0439e8d6c1ed3e2a7e14f
Author: dotbit1 <68584562+dotbit1@users.noreply.github.com>
Date: Thu Feb 27 09:57:41 2025 +0200
Support the new Romanian ONRC format
Closes https://github.com/arthurdejong/python-stdnum/pull/465
diff --git a/stdnum/ro/onrc.py b/stdnum/ro/onrc.py
index ea33558..8b2eb5d 100644
--- a/stdnum/ro/onrc.py
+++ b/stdnum/ro/onrc.py
@@ -1,8 +1,8 @@
# onrc.py - functions for handling Romanian ONRC numbers
# coding: utf-8
#
-# Copyright (C) 2020 Dimitrios Josef Moustos
-# Copyright (C) 2020 Arthur de Jong
+# Copyright (C) 2020-2024 Dimitrios Josef Moustos
+# Copyright (C) 2020-2025 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
@@ -23,9 +23,14 @@
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. This number can change when registration information
-changes.
+information about the type of company and registration year.
+
+On 2024-07-26 a new format was introduced and for a while both old and new
+formats need to be valid.
+
+More information:
+
+*
https://targetare.ro/blog/schimbari-importante-la-registrul-comertului-ce-trebuie-sa-stii-despre-noul-format-al-numarului-de-ordine
>>> validate('J52/750/2012')
'J52/750/2012'
@@ -33,7 +38,13 @@ changes.
Traceback (most recent call last):
...
InvalidComponent: ...
-"""
+>>> validate('J2012000750528')
+'J2012000750528'
+>>> validate('J2012000750529')
+Traceback (most recent call last):
+ ...
+InvalidChecksum: ...
+""" # noqa: E501
from __future__ import annotations
@@ -41,18 +52,18 @@ import datetime
import re
from stdnum.exceptions import *
-from stdnum.util import clean
+from stdnum.util import clean, isdigits
# 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})$')
+# as last field for the old format
+_old_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]+$')
+# This pattern should match all valid numbers in the old format
+_old_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])
@@ -69,19 +80,16 @@ def compact(number: str) -> str:
if number[2:3] == '/':
number = number[:1] + '0' + number[1:]
# convert trailing full date to year only
- m = _onrc_fulldate_re.match(number)
+ m = _old_onrc_fulldate_re.match(number)
if m:
number = ''.join(m.groups())
return number
-def validate(number: str) -> str:
- """Check if the number is a valid ONRC."""
- number = compact(number)
- if not _onrc_re.match(number):
+def _validate_old_format(number: str) -> None:
+ # old YJJ/XXXX/AAAA format
+ if not _old_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()
@@ -89,8 +97,58 @@ def validate(number: str) -> str:
raise InvalidComponent()
if len(year) != 4:
raise InvalidLength()
- if int(year) < 1990 or int(year) > datetime.date.today().year:
+ # old format numbers will not be issued after 2024
+ if int(year) < 1990 or int(year) > 2024:
+ raise InvalidComponent()
+
+
+def _calc_check_digit(number: str) -> str:
+ """Calculate the check digit for the new ONRC format."""
+ # replace letters with digits
+ number = str(ord(number[0]) % 10) + number[1:]
+ return str(sum(int(n) for n in number[:-1]) % 10)
+
+
+def _validate_new_format(number: str) -> None:
+ # new YAAAAXXXXXXJJC format, no slashes
+ if not isdigits(number[1:]):
+ raise InvalidFormat()
+ if len(number) != 14:
+ raise InvalidLength()
+ year = int(number[1:5])
+ if year < 1990 or year > datetime.date.today().year:
+ raise InvalidComponent()
+ # the registration year determines which counties are allowed
+ # companies registered after 2024-07-26 have 00 as county code
+ county = int(number[11:13])
+ if year < 2024:
+ if county not in _counties:
+ raise InvalidComponent()
+ elif year == 2024:
+ if county not in _counties.union([0]):
+ raise InvalidComponent()
+ else:
+ if county != 0:
+ raise InvalidComponent()
+ if number[-1] != _calc_check_digit(number):
+ raise InvalidChecksum
+
+
+def validate(number: str) -> str:
+ """Check if the number is a valid ONRC."""
+ number = compact(number)
+ # J: legal entities (e.g., LLC, SA, etc.)
+ # F: sole proprietorships, individual and family businesses
+ # C: cooperative societies.
+ if number[:1] not in 'JFC':
raise InvalidComponent()
+ if '/' in number:
+ # old YJJ/XXXX/AAAA format, still supported but will be phased out,
companies
+ # will get a new number
+ _validate_old_format(number)
+ else:
+ # new YAAAAXXXXXXJJC format, no slashes
+ _validate_new_format(number)
return number
diff --git a/tests/test_ro_onrc.doctest b/tests/test_ro_onrc.doctest
index 6b47a5f..973d00d 100644
--- a/tests/test_ro_onrc.doctest
+++ b/tests/test_ro_onrc.doctest
@@ -1,6 +1,6 @@
test_ro_onrc.doctest - more detailed doctests for the stdnum.ro.onrc module
-Copyright (C) 2020 Arthur de Jong
+Copyright (C) 2020-2025 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
@@ -24,7 +24,7 @@ This file contains more detailed doctests for the
stdnum.ro.onrc module.
>>> from stdnum.exceptions import *
-Test some corner cases.
+Test some corner cases of the old format.
>>> onrc.validate('J/52/750/2012')
'J52/750/2012'
@@ -62,6 +62,40 @@ InvalidComponent: ...
Traceback (most recent call last):
...
InvalidComponent: ...
+>>> onrc.validate('J22/1515/2007/123') # too many components
+Traceback (most recent call last):
+ ...
+InvalidFormat: ...
+
+
+Test some corner cases of the new format.
+
+>>> onrc.validate('J2016012984401')
+'J2016012984401'
+>>> onrc.validate('J201601298440')
+Traceback (most recent call last):
+ ...
+InvalidLength: ...
+>>> onrc.validate('J1822012984405') # year too old
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> onrc.validate('J2112012984408') # year in the future
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> onrc.validate('J2016012984007') # number before 2024 with 0 county
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> onrc.validate('J2024012984994') # number from 2024 with invalid county
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
+>>> onrc.validate('J2025012984401') # number after 2024 with non-0 county
+Traceback (most recent call last):
+ ...
+InvalidComponent: ...
These have been found online and should all be valid numbers.
@@ -72,203 +106,143 @@ These have been found online and should all be valid
numbers.
... C22/4/2018
... C30/2/2009
... F01 /592 /2013
+... F01 587 2023
+... F01 988 2003
... 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 4 2024
... 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
+... J09 49 2023
+... J09 87 2024
... 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 14850 2021
+... J40 1546 2018
+... J40 3509 2020
+... J40 4214 2024
+... J40 4834 2000
+... J40 5302 2020
+... J40 8068 2024
+... J40 8364 2024
+... J40 9214 2024
... 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
...
+... C2005000007045
+... C2005000011220
+... C2009000002022
+... J1992002621040
+... J1993001036400
+... J1994000536225
+... J2007007766403
+... J2012000750528
+... J2016012984401
+... J2021016333409
+... J2024012585407
+... J2024030812006
+... J2024035703000
+... J2024044457006
+... J2025007112004
+... J2025066599008
+... J2025085871002
+...
... '''
>>> [x for x in numbers.splitlines() if x and not onrc.is_valid(x)]
[]
-----------------------------------------------------------------------
Summary of changes:
stdnum/ro/onrc.py | 96 +++++++++++++++++++++------
tests/test_ro_onrc.doctest | 162 +++++++++++++++++++--------------------------
2 files changed, 145 insertions(+), 113 deletions(-)
hooks/post-receive
--
python-stdnum
- python-stdnum branch master updated. 2.1-20-gcd94bf1,
Commits of the python-stdnum project