Skip to content
2 changes: 2 additions & 0 deletions cuenca_validations/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
'BankAccountStatus',
'BatchFileMetadata',
'Beneficiary',
'BeneficiaryRequest',
'BillPaymentQuery',
'CardErrorType',
'CardFundingType',
Expand Down Expand Up @@ -221,6 +222,7 @@
from .requests import (
ApiKeyUpdateRequest,
BankAccountValidationRequest,
BeneficiaryRequest,
CurpValidationRequest,
EndpointRequest,
EndpointUpdateRequest,
Expand Down
10 changes: 7 additions & 3 deletions cuenca_validations/types/identities.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import datetime as dt
from typing import Annotated, Optional
from typing import Annotated, Optional, Union

from pydantic import BaseModel, ConfigDict, Field, SecretStr, StringConstraints
from pydantic_extra_types.phone_numbers import PhoneNumber
Expand Down Expand Up @@ -89,12 +89,12 @@ class AddressRequest(BaseModel):
)


class Beneficiary(BaseModel):
class BaseBeneficiary(BaseModel):
name: str
birth_date: dt.date
phone_number: PhoneNumber
user_relationship: str
percentage: Annotated[int, Field(ge=1, le=100)]

model_config = ConfigDict(
json_schema_extra={
"example": {
Expand All @@ -108,6 +108,10 @@ class Beneficiary(BaseModel):
)


class Beneficiary(BaseBeneficiary):
phone_number: Union[PhoneNumber, str]


class VerificationErrors(BaseModel):
identifier: str = Field(
description='Unique identifier for the step validation'
Expand Down
28 changes: 16 additions & 12 deletions cuenca_validations/types/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
from .helpers import validate_age_requirement
from .identities import (
AddressRequest,
Beneficiary,
BaseBeneficiary,
Curp,
KYCFile,
Password,
Expand Down Expand Up @@ -330,7 +330,7 @@ class UserPldRiskLevelRequest(BaseModel):
level: float = Field(ge=0.0, le=1.0)


class CurpValidationRequest(BaseModel):
class CurpValidationRequest(BaseRequest):
names: Optional[str] = None
first_surname: Optional[str] = None
second_surname: Optional[str] = Field(
Expand Down Expand Up @@ -439,13 +439,13 @@ def __get_pydantic_core_schema__(
)


class UserTOSAgreementRequest(BaseModel):
class UserTOSAgreementRequest(BaseRequest):
tos_id: str
location: Coordinate
signature_image_url: Optional[FileCuencaUrl] = None


class UserRequest(BaseModel):
class UserRequest(BaseRequest):
curp: Curp = Field(
description=(
'Mexican government ID (18 characters). ' 'Must be pre-validated.'
Expand Down Expand Up @@ -495,12 +495,16 @@ def validate_profession(cls, profession: Profession) -> Profession:
return profession


class UserUpdateRequest(BaseModel):
class BeneficiaryRequest(BaseBeneficiary, BaseRequest):
phone_number: PhoneNumber


class UserUpdateRequest(BaseRequest):
profession: Optional[Profession] = None
email_verification_id: Optional[str] = None
phone_verification_id: Optional[str] = None
address: Optional[AddressRequest] = None
beneficiaries: Optional[list[Beneficiary]] = None
beneficiaries: Optional[list[BeneficiaryRequest]] = None
govt_id: Optional[KYCFile] = None
proof_of_address: Optional[KYCFile] = None
proof_of_life: Optional[KYCFile] = None
Expand All @@ -518,7 +522,7 @@ class UserUpdateRequest(BaseModel):
@field_validator('beneficiaries')
@classmethod
def beneficiary_percentage(
cls, beneficiaries: Optional[list[Beneficiary]] = None
cls, beneficiaries: Optional[list[BeneficiaryRequest]] = None
):
if beneficiaries and sum(b.percentage for b in beneficiaries) != 100:
raise ValueError('The total percentage should be 100%')
Expand Down Expand Up @@ -590,7 +594,7 @@ class FileBatchUploadRequest(BaseModel):
user_id: str


class VerificationRequest(BaseModel):
class VerificationRequest(BaseRequest):
type: VerificationType
recipient: Union[EmailStr, PhoneNumber] = Field(
description='Phone or email to validate'
Expand All @@ -614,7 +618,7 @@ def validate_sender(cls, recipient: str, values):
)


class VerificationAttemptRequest(BaseModel):
class VerificationAttemptRequest(BaseRequest):
code: Annotated[
str,
StringConstraints(strict=True, min_length=6, max_length=6),
Expand Down Expand Up @@ -655,11 +659,11 @@ class KYCValidationRequest(BaseRequest):
force: bool = False


class BankAccountValidationRequest(BaseModel):
class BankAccountValidationRequest(BaseRequest):
account_number: Union[Clabe, PaymentCardNumber]


class UserListsRequest(BaseModel):
class UserListsRequest(BaseRequest):
curp: Optional[Curp] = Field(None, description='Curp to review on lists')
rfc: Optional[Rfc] = Field(None, description='Rfc to review on lists')
account_number: Optional[Union[Clabe, PaymentCardNumber]] = Field(
Expand Down Expand Up @@ -758,5 +762,5 @@ class PartnerUpdateRequest(BaseRequest):
shareholders: Optional[list[Shareholder]] = None


class PhoneVerificationAssociationRequest(BaseModel):
class PhoneVerificationAssociationRequest(BaseRequest):
verification_id: str
2 changes: 1 addition & 1 deletion cuenca_validations/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '2.1.16'
__version__ = '2.1.17'
29 changes: 3 additions & 26 deletions tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,9 @@ def test_curp_validation_request():
assert all(field in error_msg for field in required_fields)

req_curp = CurpValidationRequest(**request)
assert req_curp.model_dump() == request
# exclude_none=False to test that the request equals the original dict,
# since normally exclude_none defaults to True in BaseRequest.model_dump()
assert req_curp.model_dump(exclude_none=False) == request

request['date_of_birth'] = dt.date(2006, 5, 17)

Expand Down Expand Up @@ -435,16 +437,11 @@ def test_user_update_request():
percentage=50,
),
],
curp_document_uri='https://sandbox.cuenca.com/files/EF123',
profession=Profession.empleado,
)
update_req = UserUpdateRequest(**request)
beneficiaries = [b.model_dump() for b in update_req.beneficiaries]
assert beneficiaries == request['beneficiaries']
assert (
update_req.curp_document_uri.unicode_string()
== request['curp_document_uri']
)
assert update_req.profession == Profession.empleado

request['beneficiaries'] = [
Expand Down Expand Up @@ -480,26 +477,6 @@ def test_user_update_request():
assert 'The total percentage should be 100%' in str(v)
request.pop('beneficiaries')

tos_request = dict(
terms_of_service=dict(
version='2022-01-01',
ip='127.0.0.1',
location='1111,1111',
type='ifpe',
)
)
UserUpdateRequest(**tos_request)

tos_request = dict(
terms_of_service=dict(
version='2022-01-01',
ip='2001:0db8:0000:0000:0000:ff00:0042:8329',
location='1111,1111',
type='ifpe',
)
)
UserUpdateRequest(**tos_request)

kyc_request = dict(
govt_id=dict(
type='ine',
Expand Down
Loading