Skip to content

Commit

Permalink
Merge pull request #244 from fyntex/release/v0.14.1
Browse files Browse the repository at this point in the history
Release v0.14.1
  • Loading branch information
ycouce-cdd committed Oct 12, 2021
2 parents 79b9e85 + 9b6e3b0 commit 59c37c3
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.14.0
current_version = 0.14.1
commit = True
tag = True

Expand Down
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
History
-------

0.14.1 (2021-10-12)
+++++++++++++++++++++++

* (PR #238, 2021-09-08) rut: Fix RUT clean method to accept '0-0' value
* (PR #241, 2021-09-16) rtc: Make AEC field 'nombre persona autorizada cedente' optional

0.14.0 (2021-08-17)
+++++++++++++++++++++++

Expand Down
2 changes: 1 addition & 1 deletion cl_sii/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
"""


__version__ = '0.14.0'
__version__ = '0.14.1'
12 changes: 10 additions & 2 deletions cl_sii/rtc/data_models_aec.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,25 @@ class CesionAecXml:
'..//Cesion//DocumentoCesion//Cedente//RUTAutorizado//RUT'
"""

cedente_persona_autorizada_nombre: str
cedente_persona_autorizada_nombre: Optional[str]
"""
"Persona Autorizada" by the "cedente" to "Firmar la Transferencia" (name).
.. note:: It might be the "cedente" itself, a "persona natural", etc.
.. note:: It might be the "cedente" itself, a "persona natural", etc. There is a
contradiction regarding the element ``Nombre de la persona autorizada`` about what
the technical documentation states and how it was implemented in the XML schema.
Although the former defines the field as required, the XML schema does not set a
minimum required length, so the field can be empty.
First of the
> Lista de Personas Autorizadas por el Cedente a Firmar la Transferencia
AEC doc XML element (1..3 occurrences of 'RUTAutorizado'):
'..//Cesion//DocumentoCesion//Cedente//RUTAutorizado//Nombre'
.. seealso::
https://github.com/cl-sii-extraoficial/archivos-oficiales/blob/99b15aff252836e1ac311d243636aa3a9e6b89c6/src/docs/rtc/2013-02-11-formato-archivo-electronico-cesion.pdf
https://github.com/cl-sii-extraoficial/archivos-oficiales/blob/99b15aff252836e1ac311d243636aa3a9e6b89c6/src/code/rtc/2019-12-12-schema_cesion/schema_cesion/SiiTypes_v10.xsd#L682-L689
"""

cesionario_razon_social: str
Expand Down
16 changes: 15 additions & 1 deletion cl_sii/rtc/parse_aec.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ def parse_aec_xml(xml_doc: XmlElement) -> data_models_aec.AecXml:
# Parser Functions and Models
###############################################################################

def _empty_str_to_none(v: object) -> object:
"""
Reusable Pydantic validator that converts empty strings to ``None``.
"""
if isinstance(v, str):
if not v.strip():
v = None
return v


def _validate_rut(v: object) -> object:
"""
Reusable Pydantic validator for fields of type :class:`Rut`.
Expand Down Expand Up @@ -228,7 +238,7 @@ class Config:
###########################################################################

rut: Rut
nombre: str
nombre: Optional[str]

###########################################################################
# Custom Methods
Expand All @@ -249,6 +259,10 @@ def parse_xml_to_dict(xml_em: XmlElement) -> Mapping[str, object]:
# Validators
###########################################################################

_empty_str_to_none = pydantic.validator( # type: ignore[pydantic-field]
'nombre', pre=True, allow_reuse=True,
)(_empty_str_to_none)

_validate_rut = pydantic.validator( # type: ignore[pydantic-field]
'rut', pre=True, allow_reuse=True,
)(_validate_rut)
Expand Down
6 changes: 5 additions & 1 deletion cl_sii/rut/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"""
import itertools
import random
import re

from . import constants

Expand Down Expand Up @@ -144,7 +145,10 @@ def __hash__(self) -> int:
def clean_str(cls, value: str) -> str:
# note: unfortunately `value.strip('.')` does not remove all the occurrences of '.' in
# 'value' (only the leading and trailing ones).
return value.strip().lstrip('0').replace('.', '').upper()
clean_value = value.strip().replace('.', '').upper()
# Remove leading zeros except if zero is the only digit, so we can accept the RUT '0-0'.
leading_zero_free_value = re.sub(r'^0+(\d+)', r'\1', clean_value)
return leading_zero_free_value

@classmethod
def calc_dv(cls, rut_digits: str) -> str:
Expand Down
24 changes: 24 additions & 0 deletions tests/test_rut.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class RutTest(unittest.TestCase):
valid_rut_digits_with_dots: str
valid_rut_verbose: str
valid_rut_leading_zero: str
valid_rut_zero_zero: str
valid_rut_zero_zero_dv: str

invalid_rut_canonical: str
invalid_rut_dv: str
Expand All @@ -34,6 +36,8 @@ def setUpClass(cls) -> None:
cls.valid_rut_digits_with_dots = '6.824.160'
cls.valid_rut_verbose = '6.824.160-K'
cls.valid_rut_leading_zero = '06824160-K'
cls.valid_rut_zero_zero = '0-0'
cls.valid_rut_zero_zero_dv = '0'

cls.invalid_rut_canonical = '6824160-0'
cls.invalid_rut_dv = '0'
Expand Down Expand Up @@ -291,6 +295,26 @@ def test_clean_str_leading_zeros(self) -> None:
clean_rut = rut.Rut.clean_str(rut_value)
self.assertEqual(clean_rut, self.valid_rut_canonical)

# RUT 0-0
rut_value = self.valid_rut_zero_zero
clean_rut = rut.Rut.clean_str(rut_value)
self.assertEqual(clean_rut, self.valid_rut_zero_zero)

# RUT 0-0 with one extra leading zero
rut_value = f'0{self.valid_rut_zero_zero}'
clean_rut = rut.Rut.clean_str(rut_value)
self.assertEqual(clean_rut, self.valid_rut_zero_zero)

# RUT 0-0 with two extra leading zero
rut_value = f'00{self.valid_rut_zero_zero}'
clean_rut = rut.Rut.clean_str(rut_value)
self.assertEqual(clean_rut, self.valid_rut_zero_zero)

# RUT 0-0 with eight extra leading zero
rut_value = f'00000000{self.valid_rut_zero_zero}'
clean_rut = rut.Rut.clean_str(rut_value)
self.assertEqual(clean_rut, self.valid_rut_zero_zero)

def test_calc_dv_ok(self) -> None:
dv = rut.Rut.calc_dv(self.valid_rut_digits)
self.assertEqual(dv, self.valid_rut_dv)
Expand Down

0 comments on commit 59c37c3

Please sign in to comment.