cuenca-validations 2.1.46__tar.gz → 2.1.47__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/PKG-INFO +1 -1
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/__init__.py +12 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/enums.py +14 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/queries.py +5 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/requests.py +87 -0
- cuenca_validations-2.1.47/cuenca_validations/version.py +1 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/PKG-INFO +1 -1
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_requests.py +35 -0
- cuenca_validations-2.1.46/cuenca_validations/version.py +0 -1
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/LICENSE +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/README.md +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/__init__.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/card_bins.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/errors.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/py.typed +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/card.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/files.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/general.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/helpers.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/identities.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/morals.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/typing.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/validators.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/SOURCES.txt +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/dependency_links.txt +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/requires.txt +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/top_level.txt +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/setup.cfg +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/setup.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/__init__.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_card.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_errors.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_helpers.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_statement.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_types.py +0 -0
- {cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/tests/test_validators.py +0 -0
{cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/__init__.py
RENAMED
|
@@ -82,6 +82,7 @@ __all__ = [
|
|
|
82
82
|
'Profession',
|
|
83
83
|
'QueryParams',
|
|
84
84
|
'ReferencedClabeRequest',
|
|
85
|
+
'RejectTransferOrderRequest',
|
|
85
86
|
'LegalRfc',
|
|
86
87
|
'Rfc',
|
|
87
88
|
'QuestionnairesRequest',
|
|
@@ -106,6 +107,11 @@ __all__ = [
|
|
|
106
107
|
'TransactionQuery',
|
|
107
108
|
'TransactionStatus',
|
|
108
109
|
'TransferNetwork',
|
|
110
|
+
'TransferOrderLineRequest',
|
|
111
|
+
'TransferOrderLineStatus',
|
|
112
|
+
'TransferOrderQuery',
|
|
113
|
+
'TransferOrderRequest',
|
|
114
|
+
'TransferOrderStatus',
|
|
109
115
|
'TransferQuery',
|
|
110
116
|
'TransferRequest',
|
|
111
117
|
'UpdateTransferRequest',
|
|
@@ -184,6 +190,8 @@ from .enums import (
|
|
|
184
190
|
TrackDataMethod,
|
|
185
191
|
TransactionStatus,
|
|
186
192
|
TransferNetwork,
|
|
193
|
+
TransferOrderLineStatus,
|
|
194
|
+
TransferOrderStatus,
|
|
187
195
|
UserCardNotification,
|
|
188
196
|
UserStatus,
|
|
189
197
|
UserType,
|
|
@@ -238,6 +246,7 @@ from .queries import (
|
|
|
238
246
|
StatementQuery,
|
|
239
247
|
TOSQuery,
|
|
240
248
|
TransactionQuery,
|
|
249
|
+
TransferOrderQuery,
|
|
241
250
|
TransferQuery,
|
|
242
251
|
UserQuery,
|
|
243
252
|
UsersTOSQuery,
|
|
@@ -271,11 +280,14 @@ from .requests import (
|
|
|
271
280
|
PlatformRequest,
|
|
272
281
|
QuestionnairesRequest,
|
|
273
282
|
ReferencedClabeRequest,
|
|
283
|
+
RejectTransferOrderRequest,
|
|
274
284
|
SavingRequest,
|
|
275
285
|
SavingUpdateRequest,
|
|
276
286
|
SessionRequest,
|
|
277
287
|
StrictTransferRequest,
|
|
278
288
|
TOSRequest,
|
|
289
|
+
TransferOrderLineRequest,
|
|
290
|
+
TransferOrderRequest,
|
|
279
291
|
TransferRequest,
|
|
280
292
|
UpdateTransferRequest,
|
|
281
293
|
UserCredentialRequest,
|
|
@@ -761,3 +761,17 @@ class OperatorRole(str, Enum):
|
|
|
761
761
|
class OperatorStatus(str, Enum):
|
|
762
762
|
active = 'active'
|
|
763
763
|
deactivated = 'deactivated'
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
class TransferOrderStatus(str, Enum):
|
|
767
|
+
created = 'created'
|
|
768
|
+
authorizing = 'authorizing'
|
|
769
|
+
authorized = 'authorized'
|
|
770
|
+
rejected = 'rejected'
|
|
771
|
+
expired = 'expired'
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
class TransferOrderLineStatus(str, Enum):
|
|
775
|
+
pending = 'pending'
|
|
776
|
+
invalid = 'invalid'
|
|
777
|
+
submitted = 'submitted'
|
|
@@ -25,6 +25,7 @@ from .enums import (
|
|
|
25
25
|
SessionType,
|
|
26
26
|
TermsOfService,
|
|
27
27
|
TransferNetwork,
|
|
28
|
+
TransferOrderStatus,
|
|
28
29
|
UserStatus,
|
|
29
30
|
)
|
|
30
31
|
from .general import NormalizedName
|
|
@@ -233,3 +234,7 @@ class TOSQuery(QueryParams):
|
|
|
233
234
|
|
|
234
235
|
class UsersTOSQuery(QueryParams):
|
|
235
236
|
type: TermsOfService
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class TransferOrderQuery(QueryParams):
|
|
240
|
+
status: Optional[TransferOrderStatus] = None
|
{cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/requests.py
RENAMED
|
@@ -1009,3 +1009,90 @@ class ReferencedClabeRequest(BaseRequest):
|
|
|
1009
1009
|
|
|
1010
1010
|
class PhoneVerificationAssociationRequest(BaseRequest):
|
|
1011
1011
|
verification_id: str
|
|
1012
|
+
|
|
1013
|
+
|
|
1014
|
+
MAX_TRANSFER_ORDER_BATCH_LINES = 5000
|
|
1015
|
+
MAX_TRANSFER_ORDER_EXPIRATION_HOURS = 24 * 7
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
class TransferOrderLineRequest(BaseRequest):
|
|
1019
|
+
account_number: str
|
|
1020
|
+
recipient_name: str
|
|
1021
|
+
amount: int
|
|
1022
|
+
descriptor: str
|
|
1023
|
+
|
|
1024
|
+
model_config = ConfigDict(
|
|
1025
|
+
json_schema_extra={
|
|
1026
|
+
'example': {
|
|
1027
|
+
'account_number': '646180157034181180',
|
|
1028
|
+
'recipient_name': 'Doroteo Arango',
|
|
1029
|
+
'amount': 100_00,
|
|
1030
|
+
'descriptor': 'Mezcal, pulque y tequila',
|
|
1031
|
+
}
|
|
1032
|
+
},
|
|
1033
|
+
)
|
|
1034
|
+
|
|
1035
|
+
|
|
1036
|
+
class TransferOrderRequest(BaseRequest):
|
|
1037
|
+
account_number: Optional[str] = None
|
|
1038
|
+
recipient_name: Optional[str] = None
|
|
1039
|
+
amount: Optional[int] = None
|
|
1040
|
+
descriptor: Optional[str] = None
|
|
1041
|
+
idempotency_key: str
|
|
1042
|
+
user_id: Optional[str] = None
|
|
1043
|
+
items: Optional[list[TransferOrderLineRequest]] = None
|
|
1044
|
+
expires_in_hours: Optional[int] = Field(
|
|
1045
|
+
default=None,
|
|
1046
|
+
gt=0,
|
|
1047
|
+
le=MAX_TRANSFER_ORDER_EXPIRATION_HOURS,
|
|
1048
|
+
)
|
|
1049
|
+
|
|
1050
|
+
model_config = ConfigDict(
|
|
1051
|
+
json_schema_extra={
|
|
1052
|
+
'example': {
|
|
1053
|
+
'account_number': '646180157034181180',
|
|
1054
|
+
'recipient_name': 'Doroteo Arango',
|
|
1055
|
+
'amount': 100_00,
|
|
1056
|
+
'descriptor': 'Mezcal, pulque y tequila',
|
|
1057
|
+
'idempotency_key': 'UNIQUE-KEY-003',
|
|
1058
|
+
'user_id': 'USWqY5cvkISJOxHyEKjAKf8w',
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
)
|
|
1062
|
+
|
|
1063
|
+
@model_validator(mode='after')
|
|
1064
|
+
def require_unitario_or_batch(self) -> 'TransferOrderRequest':
|
|
1065
|
+
has_items = bool(self.items)
|
|
1066
|
+
has_flat = all(
|
|
1067
|
+
(
|
|
1068
|
+
self.account_number is not None,
|
|
1069
|
+
self.recipient_name is not None,
|
|
1070
|
+
self.amount is not None,
|
|
1071
|
+
self.descriptor is not None,
|
|
1072
|
+
)
|
|
1073
|
+
)
|
|
1074
|
+
if has_items == has_flat:
|
|
1075
|
+
raise ValueError(
|
|
1076
|
+
'Provide either a single transfer (account_number, '
|
|
1077
|
+
'recipient_name, amount, descriptor) or items[] for a batch, '
|
|
1078
|
+
'not both'
|
|
1079
|
+
)
|
|
1080
|
+
if self.items is not None:
|
|
1081
|
+
if len(self.items) > MAX_TRANSFER_ORDER_BATCH_LINES:
|
|
1082
|
+
raise ValueError(
|
|
1083
|
+
'Batch exceeds maximum of '
|
|
1084
|
+
f'{MAX_TRANSFER_ORDER_BATCH_LINES} lines'
|
|
1085
|
+
)
|
|
1086
|
+
if len(self.items) == 0:
|
|
1087
|
+
raise ValueError('items must not be empty')
|
|
1088
|
+
return self
|
|
1089
|
+
|
|
1090
|
+
|
|
1091
|
+
class RejectTransferOrderRequest(BaseRequest):
|
|
1092
|
+
rejection_reason: str
|
|
1093
|
+
|
|
1094
|
+
model_config = ConfigDict(
|
|
1095
|
+
json_schema_extra={
|
|
1096
|
+
'example': {'rejection_reason': 'Monto incorrecto'},
|
|
1097
|
+
},
|
|
1098
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.1.47'
|
|
@@ -9,10 +9,12 @@ from cuenca_validations.types.enums import (
|
|
|
9
9
|
)
|
|
10
10
|
from cuenca_validations.types.queries import OperatorQuery
|
|
11
11
|
from cuenca_validations.types.requests import (
|
|
12
|
+
MAX_TRANSFER_ORDER_BATCH_LINES,
|
|
12
13
|
OperatorLoginRequest,
|
|
13
14
|
OperatorRequest,
|
|
14
15
|
OperatorUpdateRequest,
|
|
15
16
|
PasswordResetRequest,
|
|
17
|
+
TransferOrderRequest,
|
|
16
18
|
UpdateTransferRequest,
|
|
17
19
|
UserTOSAgreementRequest,
|
|
18
20
|
UserUpdateRequest,
|
|
@@ -218,3 +220,36 @@ def test_update_transfer_request_forbids_extra() -> None:
|
|
|
218
220
|
{'status': 'succeeded', 'foo': 'bar'}
|
|
219
221
|
)
|
|
220
222
|
assert 'Extra inputs are not permitted' in str(ex.value)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def test_transfer_order_request_shape() -> None:
|
|
226
|
+
line = {
|
|
227
|
+
'account_number': '646180157034181180',
|
|
228
|
+
'recipient_name': 'Doroteo Arango',
|
|
229
|
+
'amount': 100_00,
|
|
230
|
+
'descriptor': 'Mezcal',
|
|
231
|
+
}
|
|
232
|
+
single = TransferOrderRequest.model_validate(
|
|
233
|
+
{**line, 'idempotency_key': 'single'}
|
|
234
|
+
)
|
|
235
|
+
assert single.items is None
|
|
236
|
+
batch = TransferOrderRequest.model_validate(
|
|
237
|
+
{'idempotency_key': 'batch', 'items': [line]}
|
|
238
|
+
)
|
|
239
|
+
assert batch.items is not None
|
|
240
|
+
|
|
241
|
+
with pytest.raises(ValidationError, match='not both'):
|
|
242
|
+
TransferOrderRequest.model_validate(
|
|
243
|
+
{**line, 'idempotency_key': 'both', 'items': [line]}
|
|
244
|
+
)
|
|
245
|
+
with pytest.raises(ValidationError, match='items must not be empty'):
|
|
246
|
+
TransferOrderRequest.model_validate(
|
|
247
|
+
{**line, 'idempotency_key': 'empty', 'items': []}
|
|
248
|
+
)
|
|
249
|
+
with pytest.raises(ValidationError, match='Batch exceeds maximum'):
|
|
250
|
+
TransferOrderRequest.model_validate(
|
|
251
|
+
{
|
|
252
|
+
'idempotency_key': 'too-many',
|
|
253
|
+
'items': [line] * (MAX_TRANSFER_ORDER_BATCH_LINES + 1),
|
|
254
|
+
}
|
|
255
|
+
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.1.46'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations/types/identities.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/requires.txt
RENAMED
|
File without changes
|
{cuenca_validations-2.1.46 → cuenca_validations-2.1.47}/cuenca_validations.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|