Skip to content

Commit

Permalink
Add user_id to create transfers (#279)
Browse files Browse the repository at this point in the history
* user_id for transfers

* clabe and balance for users

* tests

* add user_id to Transfer

* Revert "add user_id to Transfer"

This reverts commit e4b419d.

* version

Co-authored-by: pachCode <[email protected]>
  • Loading branch information
rogelioLpz and pachCode authored Jun 20, 2022
1 parent 4029b81 commit 2158a59
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 26 deletions.
3 changes: 3 additions & 0 deletions cuenca/resources/transfers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def create(
descriptor: str,
recipient_name: str,
idempotency_key: Optional[str] = None,
user_id: Optional[str] = None,
) -> 'Transfer':
"""
:param account_number: CLABE
Expand All @@ -47,6 +48,7 @@ def create(
:param recipient_name: name of recipient
:param idempotency_key: must be unique for each transfer to avoid
duplicates
:param user_id: Source user to take the funds
:return: Transfer object
The recommended idempotency_key scheme:
Expand All @@ -65,6 +67,7 @@ def create(
descriptor=descriptor,
recipient_name=recipient_name,
idempotency_key=idempotency_key,
user_id=user_id,
)
return cast('Transfer', cls._create(**req.dict()))

Expand Down
8 changes: 8 additions & 0 deletions cuenca/resources/users.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime as dt
from typing import ClassVar, List, Optional, cast

from clabe import Clabe
from cuenca_validations.types import (
Address,
AddressUpdateRequest,
Expand All @@ -19,6 +20,7 @@
from pydantic import EmailStr

from ..http import Session, session as global_session
from .balance_entries import BalanceEntry
from .base import Creatable, Queryable, Retrievable, Updateable
from .identities import Identity
from .resources import retrieve_uri
Expand All @@ -43,6 +45,12 @@ class User(Creatable, Retrievable, Updateable, Queryable):
proof_of_life: Optional[KYCFile]
beneficiaries: Optional[List[Beneficiary]]
platform_id: Optional[str] = None
clabe: Optional[Clabe] = None

@property
def balance(self) -> int:
be = cast(BalanceEntry, BalanceEntry.first(user_id=self.id))
return be.rolling_balance if be else 0

class Config:
fields = {
Expand Down
2 changes: 1 addition & 1 deletion cuenca/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = '0.12.0'
__version__ = '0.13.0'
CLIENT_VERSION = __version__
API_VERSION = '2020-03-19'
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
requests==2.27.1
cuenca-validations==0.10.12
cuenca-validations==0.10.13
dataclasses>=0.7;python_version<"3.7"
97 changes: 73 additions & 24 deletions tests/resources/cassettes/test_user_create.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,46 @@ interactions:
Content-Type:
- application/json
User-Agent:
- cuenca-python/0.7.15.dev3
- cuenca-python/0.13.0.dev0
X-Cuenca-Api-Version:
- '2020-03-19'
method: POST
uri: https://sandbox.cuenca.com/curp_validations
response:
body:
string: "{\"id\":\"CVkd_IzIDPTSOulVJpQY2urQ\",\"created_at\":\"2022-02-09T17:42:56.383485\",\"names\":\"Jos\xE9\",\"first_surname\":\"L\xF3pez\",\"second_surname\":\"Hern\xE1ndez\",\"date_of_birth\":\"1966-06-06\",\"country_of_birth\":\"MX\",\"state_of_birth\":\"DF\",\"gender\":\"male\",\"nationality\":\"MX\",\"manual_curp\":null,\"calculated_curp\":\"LOHJ660606HDFPRS02\",\"validated_curp\":\"LOHJ660606HDFPRS02\",\"renapo_curp_match\":true,\"renapo_full_match\":true}"
string: "{\"id\":\"CV82OsliJJRBazgSxh2wveXg\",\"created_at\":\"2022-06-16T17:25:41.655304\",\"names\":\"Jos\xE9\",\"first_surname\":\"L\xF3pez\",\"second_surname\":\"Hern\xE1ndez\",\"date_of_birth\":\"1966-06-06\",\"country_of_birth\":\"MX\",\"state_of_birth\":\"YN\",\"gender\":\"female\",\"nationality\":\"MX\",\"manual_curp\":null,\"calculated_curp\":\"LOHJ660606HDFPRS02\",\"validated_curp\":\"LOHJ660606HDFPRS02\",\"renapo_curp_match\":true,\"renapo_full_match\":false}"
headers:
Connection:
- keep-alive
Content-Length:
- '402'
- '405'
Content-Type:
- application/json
Date:
- Wed, 09 Feb 2022 17:42:56 GMT
- Thu, 16 Jun 2022 17:25:41 GMT
X-Request-Time:
- 'value: 0.282'
- 'value: 0.476'
x-amz-apigw-id:
- NSR9EFulCYcFqRA=
- T00fWHuLIAMF3dg=
x-amzn-Remapped-Connection:
- keep-alive
x-amzn-Remapped-Content-Length:
- '402'
- '405'
x-amzn-Remapped-Date:
- Wed, 09 Feb 2022 17:42:56 GMT
- Thu, 16 Jun 2022 17:25:41 GMT
x-amzn-Remapped-Server:
- nginx/1.20.2
- nginx/1.22.0
x-amzn-RequestId:
- ae052cd0-e6d5-4b68-94fd-0ce487426564
- e1f4ecd5-a2e1-4816-97d6-f011bf3b8131
status:
code: 201
message: Created
- request:
body: '{"curp": "LOHJ660606HDFPRS02", "phone_number": "+525511223344", "email_address":
"[email protected]", "profession": "employee", "address": {"street": "calle 1",
"ext_number": "2", "postal_code": "09900", "state": "DF", "country": "MX", "city":
null, "int_number": "3"}}'
null, "int_number": "3", "full_name": null}, "required_level": null, "phone_verification_id":
null, "email_verification_id": null}'
headers:
Accept:
- '*/*'
Expand All @@ -66,43 +67,91 @@ interactions:
Connection:
- keep-alive
Content-Length:
- '265'
- '370'
Content-Type:
- application/json
User-Agent:
- cuenca-python/0.7.15.dev3
- cuenca-python/0.13.0.dev0
X-Cuenca-Api-Version:
- '2020-03-19'
method: POST
uri: https://sandbox.cuenca.com/users
response:
body:
string: "{\"id\":\"USCM-zlFcNQk6ue4gZ_mTGeQ\",\"identity_uri\":\"/identities/IDKWLi_wUoTty6WXXg9xfKFQ\",\"created_at\":\"2022-02-09T17:42:56.965055\",\"updated_at\":\"2022-02-09T17:42:57.008600\",\"platform_id\":\"PTW68GgAc_QPmNCmgajmctLg\",\"level\":0,\"phone_number\":\"+525511223344\",\"email_address\":\"[email protected]\",\"profession\":\"employee\",\"status\":\"active\",\"terms_of_service\":null,\"blacklist_validation_status\":\"not_verified\",\"address\":{\"street\":\"calle
1\",\"ext_number\":\"2\",\"int_number\":\"3\",\"postal_code\":\"09900\",\"state\":\"DF\",\"city\":null,\"country\":\"MX\",\"created_at\":\"2022-02-09T17:42:56.964930\"},\"govt_id\":null,\"proof_of_address\":null,\"proof_of_life\":null,\"beneficiaries\":null,\"names\":\"Jos\xE9\",\"first_surname\":\"L\xF3pez\",\"second_surname\":\"Hern\xE1ndez\",\"curp\":\"LOHJ660606HDFPRS02\",\"required_level\":4}"
string: "{\"id\":\"USlen-v7UQSqqZTGVe3vQmLQ\",\"identity_uri\":\"/identities/IDtyYLgoJTRZq2xAabU5Mbzg\",\"created_at\":\"2022-06-16T17:25:41.983660\",\"updated_at\":\"2022-06-16T17:25:41.984049\",\"platform_id\":\"PTW68GgAc_QPmNCmgajmctLg\",\"level\":0,\"required_level\":4,\"phone_number\":\"+525511223344\",\"email_address\":\"[email protected]\",\"profession\":\"employee\",\"clabe\":null,\"status\":\"active\",\"terms_of_service\":null,\"blacklist_validation_status\":\"not_verified\",\"address\":{\"street\":\"calle
1\",\"ext_number\":\"2\",\"int_number\":\"3\",\"postal_code\":\"09900\",\"state\":\"DF\",\"city\":null,\"country\":\"MX\",\"created_at\":\"2022-06-16T17:25:41.983529\",\"full_name\":null},\"govt_id\":null,\"proof_of_address\":null,\"proof_of_life\":null,\"beneficiaries\":null,\"names\":\"Jos\xE9\",\"first_surname\":\"L\xF3pez\",\"second_surname\":\"Hern\xE1ndez\",\"curp\":\"LOHJ660606HDFPRS02\",\"rfc\":\"LOHJ660606MMA\"}"
headers:
Connection:
- keep-alive
Content-Length:
- '745'
- '816'
Content-Type:
- application/json
Date:
- Wed, 09 Feb 2022 17:42:57 GMT
X-Request-Time:
- 'value: 0.955'
- Thu, 16 Jun 2022 17:25:43 GMT
x-amz-apigw-id:
- NSR9JGSgCYcFgcQ=
- T00fcEBhoAMFYxw=
x-amzn-Remapped-Connection:
- keep-alive
x-amzn-Remapped-Content-Length:
- '745'
- '816'
x-amzn-Remapped-Date:
- Wed, 09 Feb 2022 17:42:57 GMT
- Thu, 16 Jun 2022 17:25:43 GMT
x-amzn-Remapped-Server:
- nginx/1.20.2
- nginx/1.22.0
x-amzn-RequestId:
- 327dc915-14bd-46fe-9abe-288010257709
- 1ba15a8d-b928-47b8-b75e-2294787ad01a
status:
code: 201
message: Created
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- DUMMY
Connection:
- keep-alive
User-Agent:
- cuenca-python/0.13.0.dev0
X-Cuenca-Api-Version:
- '2020-03-19'
method: GET
uri: https://sandbox.cuenca.com/balance_entries?limit=1&user_id=USlen-v7UQSqqZTGVe3vQmLQ
response:
body:
string: '{"items":[],"next_page_uri":null}'
headers:
Connection:
- keep-alive
Content-Length:
- '33'
Content-Type:
- application/json
Date:
- Thu, 16 Jun 2022 17:25:47 GMT
X-Amzn-Trace-Id:
- Root=1-62ab6797-5c1bf24d35a83e7325b4bb7c;Sampled=0
X-Request-Time:
- 'value: 4.092'
x-amz-apigw-id:
- T00fqEtPIAMFyfQ=
x-amzn-Remapped-Connection:
- keep-alive
x-amzn-Remapped-Content-Length:
- '33'
x-amzn-Remapped-Date:
- Thu, 16 Jun 2022 17:25:47 GMT
x-amzn-Remapped-Server:
- nginx/1.22.0
x-amzn-Remapped-x-amzn-RequestId:
- 9e06c5b4-d3e5-431d-b82d-62025c522142
x-amzn-RequestId:
- acd5feab-4a37-4e63-bf2b-ad9acf471246
status:
code: 200
message: OK
version: 1
98 changes: 98 additions & 0 deletions tests/resources/cassettes/test_user_fetch_balance.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
interactions:
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- DUMMY
Connection:
- keep-alive
User-Agent:
- cuenca-python/0.13.0.dev1
X-Cuenca-Api-Version:
- '2020-03-19'
method: GET
uri: https://sandbox.cuenca.com/users/USlen-v7UQSqqZTGVe3vQmLQ
response:
body:
string: '{"id":"USlen-v7UQSqqZTGVe3vQmLQ","created_at":"2022-06-16T17:25:41.983000","updated_at":"2022-06-16T17:28:15.920000","identity_uri":"/identities/IDtyYLgoJTRZq2xAabU5Mbzg","level":1,"required_level":4,"phone_number":"+525511223344","email_address":"[email protected]","profession":"employee","terms_of_service":{"version":"2021-02-01","ip":"201.141.118.106","location":"9.3953792,-99.139584,12"},"status":"active","address":{"street":"calle
1","ext_number":"2","postal_code":"09900","state":"DF","country":"MX","city":null,"int_number":"3","full_name":null},"govt_id":null,"proof_of_address":null,"proof_of_life":null,"beneficiaries":null,"platform_id":"PTW68GgAc_QPmNCmgajmctLg","clabe":"646180157078771514"}'
headers:
Connection:
- keep-alive
Content-Length:
- '704'
Content-Type:
- application/json
Date:
- Thu, 16 Jun 2022 18:10:07 GMT
x-amz-apigw-id:
- T06_7HcyIAMFojg=
x-amzn-Remapped-Connection:
- keep-alive
x-amzn-Remapped-Content-Length:
- '704'
x-amzn-Remapped-Date:
- Thu, 16 Jun 2022 18:10:07 GMT
x-amzn-Remapped-Server:
- nginx/1.22.0
x-amzn-RequestId:
- 6ddcf474-f95c-453f-9529-f9558c88f45c
status:
code: 200
message: OK
- request:
body: null
headers:
Accept:
- '*/*'
Accept-Encoding:
- gzip, deflate
Authorization:
- DUMMY
Connection:
- keep-alive
User-Agent:
- cuenca-python/0.13.0.dev1
X-Cuenca-Api-Version:
- '2020-03-19'
method: GET
uri: https://sandbox.cuenca.com/balance_entries?limit=1&user_id=USlen-v7UQSqqZTGVe3vQmLQ
response:
body:
string: '{"items":[{"id":"LE2RIZfRqk2PKqgT3iKTODZF","created_at":"2022-06-16T17:28:43.893000","user_id":"USlen-v7UQSqqZTGVe3vQmLQ","name":"TECNOLOGIA
EN ENTRETENIMIENTO CALIPLAY S","amount":10000,"descriptor":"Test2","rolling_balance":10000,"type":"credit","related_transaction_uri":"/deposits/SP2XLNMGbLt795Wy8hrCrLL","funding_instrument_uri":"/accounts/ACr66xA29pWqOQOs3FLkH6oA","wallet_id":"default"}],"next_page_uri":null}'
headers:
Connection:
- keep-alive
Content-Length:
- '417'
Content-Type:
- application/json
Date:
- Thu, 16 Jun 2022 18:10:16 GMT
X-Amzn-Trace-Id:
- Root=1-62ab7204-4c26d5e13c22e8ff1cc811d8;Sampled=0
X-Request-Time:
- 'value: 3.708'
x-amz-apigw-id:
- T07AwHGFIAMF5KA=
x-amzn-Remapped-Connection:
- keep-alive
x-amzn-Remapped-Content-Length:
- '417'
x-amzn-Remapped-Date:
- Thu, 16 Jun 2022 18:10:16 GMT
x-amzn-Remapped-Server:
- nginx/1.22.0
x-amzn-Remapped-x-amzn-RequestId:
- 480430da-0659-4277-a370-cb50f9c04dd0
x-amzn-RequestId:
- 9cad408b-e641-4cec-b289-7422a65b07f1
status:
code: 200
message: OK
version: 1
10 changes: 10 additions & 0 deletions tests/resources/test_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def test_user_create(user_request, curp_validation_request):
user = User.create(**user_request)
assert user.id is not None
assert user.level == 0
assert not user.clabe
assert user.balance == 0


@pytest.mark.vcr
Expand All @@ -37,6 +39,14 @@ def test_user_update():
assert all(item in user.to_dict().keys() for item in changes.keys())


@pytest.mark.vcr
def test_user_fetch_balance(user_request, curp_validation_request):
user_id = 'USlen-v7UQSqqZTGVe3vQmLQ'
user = User.retrieve(user_id)
assert user.clabe
assert user.balance == 10000


@pytest.mark.vcr
def test_user_identity_retrieve():
user_id = 'USCM-zlFcNQk6ue4gZ_mTGeQ'
Expand Down

0 comments on commit 2158a59

Please sign in to comment.