Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions fintoc/managers/v2/onboardings_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class OnboardingsManager(ManagerMixin):
"submit",
"upload_document",
"upload_shareholder_document",
"upload_legal_representative_document",
]

def _submit(self, identifier, **kwargs):
Expand All @@ -37,6 +38,16 @@ def _upload_shareholder_document(self, identifier, shareholder_id, file, **kwarg
)
return self._upload(path, {"file": self._build_file_payload(file)})

def _upload_legal_representative_document(
self, identifier, legal_representative_id, slot_key, file, **kwargs
):
"""Upload a document for a legal representative of an onboarding."""
path = (
f"{self._build_path(**kwargs)}/{identifier}"
f"/legal_representatives/{legal_representative_id}/documents/{slot_key}"
)
return self._upload(path, {"file": self._build_file_payload(file)})

@staticmethod
def _build_file_payload(file):
"""
Expand Down
1 change: 1 addition & 0 deletions fintoc/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from .v2.line import Line
from .v2.onboarding import Onboarding
from .v2.onboarding_document import OnboardingDocument
from .v2.onboarding_legal_representative import OnboardingLegalRepresentative
from .v2.onboarding_shareholder import OnboardingShareholder
from .v2.payment_method import PaymentMethod
from .v2.subscription import Subscription as SubscriptionV2
Expand Down
1 change: 1 addition & 0 deletions fintoc/resources/v2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .movement import Movement
from .onboarding import Onboarding
from .onboarding_document import OnboardingDocument
from .onboarding_legal_representative import OnboardingLegalRepresentative
from .onboarding_shareholder import OnboardingShareholder
from .payment_method import PaymentMethod
from .product import Product
Expand Down
1 change: 1 addition & 0 deletions fintoc/resources/v2/onboarding.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Onboarding(ResourceMixin):
"""Represents a Fintoc Onboarding."""

mappings = {
"legal_representatives": "onboarding_legal_representative",
"shareholders": "onboarding_shareholder",
"documents": "onboarding_document",
}
9 changes: 9 additions & 0 deletions fintoc/resources/v2/onboarding_legal_representative.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Module to hold the OnboardingLegalRepresentative resource."""

from fintoc.mixins import ResourceMixin


class OnboardingLegalRepresentative(ResourceMixin):
"""Represents a Fintoc Onboarding Legal Representative."""

mappings = {"documents": "onboarding_document"}
70 changes: 66 additions & 4 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,7 @@ def test_v2_entity_onboarding_create(self):
"""Test creating an onboarding for an entity using v2 API."""
entity_id = "ent_12345"
company_information = {"legal_name": "Acme SpA"}
legal_representative = {"first_name": "Ada", "last_name": "Lovelace"}
legal_representatives = [{"first_name": "Ada", "last_name": "Lovelace"}]
transactional_profile = {"monthly_amount_range": "0-1000"}
shareholders = [
{
Expand All @@ -1313,7 +1313,7 @@ def test_v2_entity_onboarding_create(self):
onboarding = self.fintoc.v2.entities.onboardings.create(
entity_id=entity_id,
company_information=company_information,
legal_representative=legal_representative,
legal_representatives=legal_representatives,
transactional_profile=transactional_profile,
shareholders=shareholders,
)
Expand All @@ -1325,8 +1325,8 @@ def test_v2_entity_onboarding_create(self):
== company_information["legal_name"]
)
assert (
onboarding.json.legal_representative.first_name
== legal_representative["first_name"]
onboarding.json.legal_representatives[0].first_name
== legal_representatives[0]["first_name"]
)
assert (
onboarding.json.transactional_profile.monthly_amount_range
Expand Down Expand Up @@ -1403,10 +1403,39 @@ def test_v2_entity_onboarding_upload_shareholder_document(self, tmp_path):
)
assert getattr(result.headers, "content-type").startswith("multipart/form-data")

def test_v2_entity_onboarding_upload_legal_representative_document(self, tmp_path):
"""Test uploading a legal representative document using v2 API."""
entity_id = "ent_12345"
onboarding_id = "onbprc_12345"
legal_representative_id = "onblr_12345"
slot_key = "identification"
file_path = tmp_path / "id.pdf"
file_path.write_bytes(b"%PDF-1.4 test file")

onboardings = self.fintoc.v2.entities.onboardings
result = onboardings.upload_legal_representative_document(
onboarding_id,
legal_representative_id,
slot_key,
str(file_path),
entity_id=entity_id,
)

assert result.method == "put"
assert result.url == (
f"v2/entities/{entity_id}/onboardings/{onboarding_id}"
f"/legal_representatives/{legal_representative_id}/documents/{slot_key}"
)
assert getattr(result.headers, "content-type").startswith("multipart/form-data")
assert result.json.multipart is True

def test_v2_onboarding_objetization(self):
"""Test that a full onboarding payload is objetized with nested resources."""
from fintoc.resources.v2.onboarding import Onboarding
from fintoc.resources.v2.onboarding_document import OnboardingDocument
from fintoc.resources.v2.onboarding_legal_representative import (
OnboardingLegalRepresentative,
)
from fintoc.resources.v2.onboarding_shareholder import OnboardingShareholder
from fintoc.utils import objetize

Expand All @@ -1420,6 +1449,27 @@ def test_v2_onboarding_objetization(self):
"reviewed_at": None,
"submittable": True,
"data": {"company_information": {"legal_name": "Acme SpA"}},
"legal_representatives": [
{
"id": "onblr_12345",
"object": "onboarding_legal_representative",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "rep@example.com",
"nationality": "mx",
"identification_number": "AAAA010101HDFAAA01",
"position": "Director General",
"documents": [
{
"slot_key": "identification",
"status": "uploaded",
"filename": "id.pdf",
"uploaded_at": "2026-01-15T14:30:00Z",
},
{"slot_key": "power_of_attorney", "status": "missing"},
],
}
],
"shareholders": [
{
"id": "onbsh_12345",
Expand All @@ -1446,6 +1496,18 @@ def test_v2_onboarding_objetization(self):
assert onboarding.object == "onboarding"
assert onboarding.status == "in_progress"
assert onboarding.submittable is True
assert isinstance(
onboarding.legal_representatives[0], OnboardingLegalRepresentative
)
assert onboarding.legal_representatives[0].first_name == "Ada"
assert isinstance(
onboarding.legal_representatives[0].documents[0], OnboardingDocument
)
assert (
onboarding.legal_representatives[0].documents[0].slot_key
== "identification"
)
assert onboarding.legal_representatives[0].documents[1].status == "missing"
assert isinstance(onboarding.shareholders[0], OnboardingShareholder)
assert onboarding.shareholders[0].name == "Ada"
assert isinstance(onboarding.shareholders[0].document, OnboardingDocument)
Expand Down
Loading