From fecba0d932b138ebf5cf80303e837af9ea5408ca Mon Sep 17 00:00:00 2001 From: Yinchuan Song <562997+inntran@users.noreply.github.com> Date: Wed, 12 Nov 2025 15:14:12 -0500 Subject: [PATCH 1/4] Add inline documentations to partner and history endpoints. --- src/tmo_api/cli/tmopo.py | 21 ++++++++++++++ src/tmo_api/resources/history.py | 47 ++++++++++++++++++++++++++++++- src/tmo_api/resources/partners.py | 29 +++++++++++++++++-- src/tmo_api/resources/pools.py | 32 ++++++++++++++++++++- 4 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/tmo_api/cli/tmopo.py b/src/tmo_api/cli/tmopo.py index 72537f4..7b2f2c7 100644 --- a/src/tmo_api/cli/tmopo.py +++ b/src/tmo_api/cli/tmopo.py @@ -97,6 +97,12 @@ def execute_shares_action(client, args) -> Any: elif action == "pools-get": # pragma: no cover - exercised via integration tests return pools_resource.get_pool(args.pool) elif action == "pools-partners": # pragma: no cover - exercised via integration tests + # Returns: List of partners with complete financial and contact information + # Financial: BegCapital, Contributions, Distributions, EndCapital, Income, Withdrawals, + # WithdrawalsAndDisbursements, IRR (Internal Rate of Return) + # Contact: Account, SortName, Address, Phone, Email, TIN + # Flags: ERISA, IsACH, AccountType + # Object type: CPartners:#TmoAPI return pools_resource.get_pool_partners(args.pool) elif action == "pools-loans": # pragma: no cover - exercised via integration tests return pools_resource.get_pool_loans(args.pool) @@ -107,8 +113,17 @@ def execute_shares_action(client, args) -> Any: # Partners operations elif action == "partners": + # Requires: Date range (start_date, end_date) for filtering by DateCreated/LastChanged + # Returns: List of partners with contact info, CustomFields, trustee info (TrusteeName, TrusteeAccountRef) + # Contains: Account, Name, Address, Phone, Email, TIN, ERISA flag, IsACH flag, DateCreated, LastChanged + # Object type: CPSSPartners:#TmoAPI return partners_resource.list_all(args.start_date, args.end_date) elif action == "partners-get": # pragma: no cover - exercised via integration tests + # Returns: Single exact matching partner entry + # Contains: Contact info (name, address, phone, email), ACH details, CustomFields, + # trustee info (TrusteeRecID, TrusteeAccountRef), tax info (TIN), delivery options + # Does NOT include: Financial transactions like Contributions/Distributions (use pools-partners for that) + # Object type: CPartner:#TmoAPI return partners_resource.get_partner(args.partner) elif action == "partners-attachments": # pragma: no cover - exercised via integration tests return partners_resource.get_partner_attachments(args.partner) @@ -127,6 +142,12 @@ def execute_shares_action(client, args) -> Any: # History operations elif action == "history": + # Returns: List of share transaction history records + # Contains: Transaction details (Amount, Shares, SharesBalance), dates (DateReceived, DateDeposited), + # partner/pool info (PartnerAccount, PartnerRecId, PoolAccount, PoolRecId), + # payment details (PayAccount, PayName, PayAddress), certificate info, + # ACH details, withholding, penalties, IRR + # Object type: CTransaction:#TmoAPI.Pss return history_resource.get_history(args.start_date, args.end_date, args.partner, args.pool) else: diff --git a/src/tmo_api/resources/history.py b/src/tmo_api/resources/history.py index e34ff76..f31f642 100644 --- a/src/tmo_api/resources/history.py +++ b/src/tmo_api/resources/history.py @@ -31,6 +31,9 @@ def get_history( ) -> List[Any]: """Get share transaction history with optional filtering. + Returns detailed transaction records for share activities including contributions, + withdrawals, distributions, and certificate redemptions. + Args: start_date: Start date for filtering (MM/DD/YYYY format) end_date: End date for filtering (MM/DD/YYYY format) @@ -38,7 +41,49 @@ def get_history( pool_account: Pool account filter Returns: - List of share transaction history records + List of transaction dictionaries (CTransaction:#TmoAPI.Pss), each containing: + + Transaction Details: + - Code: Transaction type (e.g., "PartnerWithdrawal", "Contribution", "Distribution") + - Amount: Transaction amount (negative for withdrawals) + - Shares: Number of shares involved (negative for redemptions) + - SharesBalance: Remaining share balance after transaction + - SharePrice: Price per share + - ShareCost: Cost basis per share + - Description: Transaction description + + Dates and Tracking: + - DateReceived: When transaction was received + - DateDeposited: When funds were deposited + - DateCreated: When record was created + - LastChanged: Last modification timestamp + - CreatedBy: User who created the transaction + + Partner and Pool References: + - PartnerAccount: Partner's account number + - PartnerRecId: Partner's record ID + - PoolAccount: Pool's account number + - PoolRecId: Pool's record ID + + Payment Information: + - PayAccount: Payee account number + - PayName: Payee name + - PayAddress: Payee address + + Certificate and ACH: + - Certificate: Certificate number + - ACH_BatchNumber: ACH batch number + - ACH_TraceNumber: ACH trace number + - ACH_TransNumber: ACH transaction number + + Other: + - Withholding: Tax withholding amount + - Penalty: Penalty amount + - Drip: DRIP (Dividend Reinvestment Plan) flag + - Reference: Reference information + - Notes: Additional notes + - TrustFundAccountRecId: Trust fund account reference + - RecId: Unique transaction record ID Raises: APIError: If the API returns an error diff --git a/src/tmo_api/resources/partners.py b/src/tmo_api/resources/partners.py index 33b6fa7..0b25d9c 100644 --- a/src/tmo_api/resources/partners.py +++ b/src/tmo_api/resources/partners.py @@ -25,11 +25,23 @@ def __init__(self, client: "TMOClient", pool_type: PoolType = PoolType.SHARES) - def get_partner(self, account: str) -> Dict[str, Any]: """Get partner details by Account. + Returns a single partner with complete profile information including contact details, + ACH banking information, custom fields, and trustee information. + Args: account: The partner account identifier Returns: - Partner data dictionary + Partner data dictionary (CPartner:#TmoAPI) containing: + - Contact information: Name, address, phone, email + - ACH details: Bank account, routing number, ACH settings + - CustomFields: Account-specific custom field values + - Trustee info: TrusteeRecID, TrusteeAccountRef, TrusteeAccountType + - Tax info: TIN, TINType + - Delivery options, statement preferences, and other settings + + Note: Does NOT include financial transactions (Contributions/Distributions). + Use pools.get_pool_partners() for financial data. Raises: APIError: If the API returns an error @@ -71,12 +83,25 @@ def list_all( ) -> List[Any]: """List all partners with optional date filtering. + Returns a list of partners with profile information. Date range filters + partners based on DateCreated and LastChanged timestamps. + Args: start_date: Start date for filtering (MM/DD/YYYY format) end_date: End date for filtering (MM/DD/YYYY format) Returns: - List of partners + List of partner dictionaries (CPSSPartners:#TmoAPI), each containing: + - Account: Partner account identifier + - Contact info: FirstName, LastName, MI, SortName, Address (Street, City, State, ZipCode) + - Phone: PhoneHome, PhoneWork, PhoneCell, PhoneFax, PhoneMain + - Email: EmailAddress + - CustomFields: Account-specific custom field values (e.g., Account Type, Interest Rate, Principal Amount) + - Trustee info: TrusteeName, TrusteeAccount, TrusteeAccountRef, TrusteeAccountType + - Tax info: TIN + - Flags: ERISA, IsACH, UsePayee + - Timestamps: DateCreated, LastChanged + - RecID: Unique record identifier Raises: APIError: If the API returns an error diff --git a/src/tmo_api/resources/pools.py b/src/tmo_api/resources/pools.py index 113d1c1..feb1dd0 100644 --- a/src/tmo_api/resources/pools.py +++ b/src/tmo_api/resources/pools.py @@ -56,11 +56,41 @@ def get_pool(self, account: str) -> Pool: def get_pool_partners(self, account: str) -> list: """Get pool partners by account. + Returns comprehensive financial and contact information for all partners + associated with a specific pool, including capital activity and performance metrics. + Args: account: The pool account identifier Returns: - List of pool partners + List of partner dictionaries (CPartners:#TmoAPI), each containing: + + Financial Information: + - BegCapital: Beginning capital balance + - Contributions: Capital contributions made by the partner + - Distributions: Distributions paid out to the partner + - EndCapital: Ending capital balance for the partner + - Income: Income earned + - Withdrawals: Withdrawal amounts + - WithdrawalsAndDisbursements: Total withdrawals and disbursements + - IRR: Internal Rate of Return + + Contact Information: + - Account: Partner account identifier + - SortName: Partner's name + - Address: Street, City, State, ZipCode + - Phone: PhoneHome, PhoneWork, PhoneCell, PhoneFax + - EmailAddress: Partner's email + - TIN: Tax Identification Number + + Other: + - AccountType: Type of account + - ERISA: ERISA flag + - IsACH: ACH flag + - RecID: Unique record identifier + + Note: This combines both financial data and contact information, unlike + partners.get_partner() which only has contact/profile info without transactions. Raises: APIError: If the API returns an error From 2e7216a8c7fc978e19d31bcbf11d335b26658a36 Mon Sep 17 00:00:00 2001 From: Yinchuan Song <562997+inntran@users.noreply.github.com> Date: Wed, 12 Nov 2025 15:15:20 -0500 Subject: [PATCH 2/4] Add returned data structures to documentations --- docs/user-guide/endpoint-comparison.md | 309 +++++++++++++++++++++++++ docs/user-guide/history.md | 226 +++++++++++++++++- docs/user-guide/partners.md | 71 +++++- docs/user-guide/pools.md | 47 +++- 4 files changed, 629 insertions(+), 24 deletions(-) create mode 100644 docs/user-guide/endpoint-comparison.md diff --git a/docs/user-guide/endpoint-comparison.md b/docs/user-guide/endpoint-comparison.md new file mode 100644 index 0000000..3caa1e6 --- /dev/null +++ b/docs/user-guide/endpoint-comparison.md @@ -0,0 +1,309 @@ +# API Endpoint Comparison Guide + +This guide helps you understand the differences between similar endpoints and choose the right one for your use case. + +## Partner Endpoints Comparison + +These three endpoints provide different views of partner data. Understanding their differences helps you choose the right endpoint for your needs. + +### Side-by-Side Comparison + +| Feature | `partners.list_all()` | `partners.get_partner()` | `pools.get_pool_partners()` | +|---------|----------------------|-------------------------|----------------------------| +| **Object Type** | CPSSPartners:#TmoAPI | CPartner:#TmoAPI | CPartners:#TmoAPI | +| **Returns** | List of partners | Single partner | List of partners in pool | +| **Scope** | All partners | One partner | Partners in specific pool | +| **Filtering** | Date range | By account | By pool account | +| | | | | +| **Contact Information** | | | | +| - Name | ✓ Basic | ✓ Complete | ✓ Basic (SortName) | +| - Address | ✓ | ✓ Full + Home | ✓ | +| - Phone | ✓ | ✓ All types | ✓ All types | +| - Email | ✓ | ✓ | ✓ | +| | | | | +| **Financial Data** | | | | +| - Beginning Capital | ✗ | ✗ | ✓ | +| - Contributions | ✗ | ✗ | ✓ | +| - Distributions | ✗ | ✗ | ✓ | +| - Ending Capital | ✗ | ✗ | ✓ | +| - Income | ✗ | ✗ | ✓ | +| - Withdrawals | ✗ | ✗ | ✓ | +| - IRR | ✗ | ✗ | ✓ | +| | | | | +| **Profile Details** | | | | +| - Custom Fields | ✓ | ✓ Complete | ✗ | +| - ACH Details | ✗ | ✓ Complete | ✗ | +| - Trustee Info | ✓ Basic | ✓ Complete (RecID) | ✗ | +| - Tax Info (TIN) | ✓ | ✓ + TINType | ✓ | +| - Settings/Preferences | ✗ | ✓ | ✗ | +| | | | | +| **Timestamps** | | | | +| - DateCreated | ✓ | ✓ (SysCreatedDate) | ✗ | +| - LastChanged | ✓ | ✓ (SysTimeStamp) | ✗ | +| | | | | +| **Flags** | | | | +| - ERISA | ✓ | ✓ | ✓ | +| - IsACH | ✓ | ✗ | ✓ | +| - AccountType | ✗ | ✓ | ✓ | + +### When to Use Each Endpoint + +#### `partners.list_all()` - Partner Directory +**Best for:** +- Finding partners created or modified within a date range +- Bulk operations across multiple partners +- Directory listings with basic contact info +- Searching for partner accounts + +**Example:** +```python +# Find all partners modified in 2024 +partners = client.shares_partners.list_all( + start_date="01/01/2024", + end_date="12/31/2024" +) + +for partner in partners: + print(f"{partner.get('Account')}: {partner.get('FirstName')} {partner.get('LastName')}") + print(f" Created: {partner.get('DateCreated')}") +``` + +**Key Characteristics:** +- Returns multiple partners +- Includes custom fields +- Filtered by creation/modification date +- No financial data +- No ACH details + +--- + +#### `partners.get_partner()` - Complete Profile +**Best for:** +- Viewing complete partner profile +- Getting ACH banking information for payments +- Accessing all settings and preferences +- Partner management tasks + +**Example:** +```python +# Get complete profile for one partner +partner = client.shares_partners.get_partner("P001002") + +print(f"Name: {partner.get('FirstName')} {partner.get('LastName')}") +print(f"Email: {partner.get('EmailAddress')}") +print(f"\nACH Information:") +print(f" Bank: {partner.get('ACH_BankName')}") +print(f" Account: {partner.get('ACH_AccountNumber')}") +print(f" Routing: {partner.get('ACH_RoutingNumber')}") + +print(f"\nCustom Fields:") +for field in partner.get('CustomFields', []): + print(f" {field['Name']}: {field['Value']}") +``` + +**Key Characteristics:** +- Returns single partner +- Most detailed profile information +- Complete ACH banking details +- All custom fields and settings +- No financial transaction data + +--- + +#### `pools.get_pool_partners()` - Financial Snapshot +**Best for:** +- Viewing partner capital balances and activity +- Financial reporting for a specific pool +- Calculating returns (IRR) for pool partners +- Understanding equity positions + +**Example:** +```python +# Get financial data for all partners in a pool +partners = client.shares_pools.get_pool_partners("LENDER-C") + +print(f"Pool LENDER-C Partners:") +for partner in partners: + print(f"\n{partner.get('SortName')} ({partner.get('Account')})") + print(f" Beginning Capital: ${partner.get('BegCapital', 0)}") + print(f" Contributions: ${partner.get('Contributions', 0)}") + print(f" Distributions: ${partner.get('Distributions', 0)}") + print(f" Ending Capital: ${float(partner.get('EndCapital', 0)):,.2f}") + print(f" IRR: {partner.get('IRR')}%") +``` + +**Key Characteristics:** +- Returns partners in specific pool +- Complete financial data (balances, contributions, distributions) +- Performance metrics (IRR) +- Basic contact information +- No ACH details or custom fields + +--- + +### Combining Endpoints for Complete View + +Often you'll need data from multiple endpoints: + +```python +# Get complete partner information (profile + financial) +account = "P001002" +pool_account = "LENDER-C" + +# 1. Get detailed profile +profile = client.shares_partners.get_partner(account) + +# 2. Get financial data from pool +pool_partners = client.shares_pools.get_pool_partners(pool_account) +financial = next((p for p in pool_partners if p.get('Account') == account), None) + +# 3. Display combined information +print(f"Partner Profile and Financial Summary") +print(f"=" * 50) +print(f"Name: {profile.get('FirstName')} {profile.get('LastName')}") +print(f"Email: {profile.get('EmailAddress')}") +print(f"Phone: {profile.get('PhoneHome')}") +print(f"\nACH Information:") +print(f" Bank: {profile.get('ACH_BankName')}") +print(f" Account: {profile.get('ACH_AccountNumber')}") + +if financial: + print(f"\nFinancial Position in Pool {pool_account}:") + print(f" Ending Capital: ${float(financial.get('EndCapital', 0)):,.2f}") + print(f" Total Contributions: ${float(financial.get('Contributions', 0)):,.2f}") + print(f" Total Distributions: ${float(financial.get('Distributions', 0)):,.2f}") + print(f" IRR: {financial.get('IRR')}%") +``` + +--- + +## Transaction History Endpoint + +The `history.get_history()` endpoint serves a different purpose - it provides transaction-level detail rather than profile or balance information. + +### `history.get_history()` - Transaction Detail + +**Object Type:** CTransaction:#TmoAPI.Pss + +**Purpose:** Get detailed transaction history showing individual share activities + +**Best for:** +- Viewing transaction-level detail +- Audit trails and compliance reporting +- Understanding specific share activities over time +- Tracking certificate redemptions and issuances +- ACH transaction tracking and reconciliation + +**Filtering Options:** +- Date range (start_date, end_date) +- Partner account +- Pool account +- Combine any/all filters + +**Key Data Returned:** +- **Transaction Details:** Code (type), Amount, Shares, SharesBalance, SharePrice, Description +- **Dates:** DateReceived, DateDeposited, DateCreated, LastChanged +- **References:** PartnerAccount, PartnerRecId, PoolAccount, PoolRecId +- **Payment Info:** PayAccount, PayName, PayAddress +- **Certificate & ACH:** Certificate number, ACH batch/trace/transaction numbers +- **Other:** Withholding, Penalty, Drip flag, CreatedBy, Notes + +**Example:** +```python +# Get transaction history for a partner in a specific period +history = client.shares_history.get_history( + partner_account="P001002", + pool_account="LENDER-D", + start_date="01/01/2024", + end_date="12/31/2024" +) + +print(f"Transaction History for P001002 in 2024:") +for transaction in history: + print(f"\n{transaction.get('DateReceived')}") + print(f" Type: {transaction.get('Code')}") + print(f" Description: {transaction.get('Description')}") + print(f" Amount: ${transaction.get('Amount', 0):,.2f}") + print(f" Shares: {transaction.get('Shares', 0):,.2f}") + print(f" Balance After: {transaction.get('SharesBalance', 0):,.2f}") + if transaction.get('Certificate'): + print(f" Certificate: {transaction.get('Certificate')}") +``` + +### History vs Pool-Partners + +**Pool-Partners** gives you the current financial snapshot (totals and balances): +- Total contributions to date +- Total distributions to date +- Current ending capital +- Overall IRR + +**History** gives you the transaction-by-transaction detail: +- Each individual contribution with date and amount +- Each individual distribution with date and amount +- How the balance changed over time +- Who created each transaction and when + +**Example - Reconciling the Two:** +```python +account = "P001002" +pool_account = "LENDER-D" + +# Get summary from pool-partners +pool_partners = client.shares_pools.get_pool_partners(pool_account) +partner_summary = next((p for p in pool_partners if p.get('Account') == account), None) + +# Get detail from history +history = client.shares_history.get_history( + partner_account=account, + pool_account=pool_account +) + +# Verify transactions match summary +contributions_detail = sum( + float(t.get('Amount', 0)) + for t in history + if t.get('Code') == 'Contribution' +) + +withdrawals_detail = sum( + abs(float(t.get('Amount', 0))) + for t in history + if t.get('Code') == 'PartnerWithdrawal' +) + +print(f"Reconciliation for {account}:") +print(f"\nSummary (from pool-partners):") +print(f" Total Contributions: ${float(partner_summary.get('Contributions', 0)):,.2f}") +print(f" Total Withdrawals: ${float(partner_summary.get('Withdrawals', 0)):,.2f}") + +print(f"\nDetail (from history transactions):") +print(f" Sum of Contribution transactions: ${contributions_detail:,.2f}") +print(f" Sum of Withdrawal transactions: ${withdrawals_detail:,.2f}") +``` + +--- + +## Quick Decision Guide + +**Need to answer these questions?** + +| Question | Use This Endpoint | +|----------|------------------| +| What's this partner's email and phone? | `partners.get_partner()` | +| What's this partner's ACH bank account? | `partners.get_partner()` | +| What partners were created this month? | `partners.list_all()` | +| What's this partner's current capital balance? | `pools.get_pool_partners()` | +| How much has this partner contributed total? | `pools.get_pool_partners()` | +| What's this partner's return (IRR)? | `pools.get_pool_partners()` | +| When did this partner make their last deposit? | `history.get_history()` | +| What specific transactions occurred in Q1? | `history.get_history()` | +| Which certificate was redeemed on this date? | `history.get_history()` | + +--- + +## Related Documentation + +- [Partners Guide](partners.md) - Detailed partner endpoint documentation +- [Pools Guide](pools.md) - Detailed pools endpoint documentation +- [History Guide](history.md) - Detailed history endpoint documentation diff --git a/docs/user-guide/history.md b/docs/user-guide/history.md index 2293274..fae361a 100644 --- a/docs/user-guide/history.md +++ b/docs/user-guide/history.md @@ -1,38 +1,240 @@ # History -The `HistoryResource` provides methods for retrieving account history. +The `HistoryResource` provides methods for retrieving share transaction history. This includes detailed records of all share activities such as contributions, withdrawals, distributions, and certificate redemptions. + +## Overview + +The SDK provides separate history resources for Shares and Capital pool types: + +```python +import os +from tmo_api import TMOClient + +client = TMOClient( + token=os.environ["TMO_API_TOKEN"], + database=os.environ["TMO_DATABASE"] +) + +# Access shares history resource +shares_history = client.shares_history + +# Access capital history resource +capital_history = client.capital_history +``` ## Methods ### get_history() -Get account history with optional filtering. +Get share transaction history with optional filtering. Returns detailed transaction records for share activities including contributions, withdrawals, distributions, and certificate redemptions. + +**Parameters:** +- `start_date` (str, optional): Start date for filtering (MM/DD/YYYY format) +- `end_date` (str, optional): End date for filtering (MM/DD/YYYY format) +- `partner_account` (str, optional): Partner account filter +- `pool_account` (str, optional): Pool account filter + +**Returns:** `List[Any]` - List of transaction dictionaries (CTransaction:#TmoAPI.Pss) + +**Response Fields:** +Each transaction dictionary contains: + +**Transaction Details:** +- **Code:** Transaction type (e.g., "PartnerWithdrawal", "Contribution", "Distribution") +- **Amount:** Transaction amount (negative for withdrawals) +- **Shares:** Number of shares involved (negative for redemptions) +- **SharesBalance:** Remaining share balance after transaction +- **SharePrice:** Price per share +- **ShareCost:** Cost basis per share +- **Description:** Transaction description + +**Dates and Tracking:** +- **DateReceived:** When transaction was received +- **DateDeposited:** When funds were deposited +- **DateCreated:** When record was created +- **LastChanged:** Last modification timestamp +- **CreatedBy:** User who created the transaction + +**Partner and Pool References:** +- **PartnerAccount:** Partner's account number +- **PartnerRecId:** Partner's record ID +- **PoolAccount:** Pool's account number +- **PoolRecId:** Pool's record ID + +**Payment Information:** +- **PayAccount:** Payee account number +- **PayName:** Payee name +- **PayAddress:** Payee address + +**Certificate and ACH:** +- **Certificate:** Certificate number +- **ACH_BatchNumber:** ACH batch number +- **ACH_TraceNumber:** ACH trace number +- **ACH_TransNumber:** ACH transaction number + +**Other:** +- **Withholding:** Tax withholding amount +- **Penalty:** Penalty amount +- **Drip:** DRIP (Dividend Reinvestment Plan) flag +- **Reference:** Reference information +- **Notes:** Additional notes +- **TrustFundAccountRecId:** Trust fund account reference +- **RecId:** Unique transaction record ID + +**Examples:** ```python # All history -history = client.history.get_history() +history = client.shares_history.get_history() + +for transaction in history: + print(f"Date: {transaction.get('DateReceived')}") + print(f"Type: {transaction.get('Code')}") + print(f"Amount: ${transaction.get('Amount', 0):,.2f}") + print(f"Shares: {transaction.get('Shares', 0):,.2f}") + print(f"Balance: {transaction.get('SharesBalance', 0):,.2f}") # Filter by date range -history = client.history.get_history( +history = client.shares_history.get_history( start_date="01/01/2024", end_date="12/31/2024" ) # Filter by partner account -history = client.history.get_history( - partner_account="PART001" +history = client.shares_history.get_history( + partner_account="P001002" ) # Filter by pool account -history = client.history.get_history( - pool_account="POOL001" +history = client.shares_history.get_history( + pool_account="LENDER-D" +) + +# Combine filters - Get all transactions for a specific partner in a specific pool during a date range +history = client.shares_history.get_history( + start_date="01/01/2024", + end_date="12/31/2024", + partner_account="P001002", + pool_account="LENDER-D" ) -# Combine filters -history = client.history.get_history( +# Analyze withdrawals +withdrawals = [t for t in history if t.get('Code') == 'PartnerWithdrawal'] +total_withdrawn = sum(float(t.get('Amount', 0)) for t in withdrawals) +print(f"Total Withdrawals: ${abs(total_withdrawn):,.2f}") + +# Track certificate redemptions +redemptions = [t for t in history if 'Redeem' in t.get('Description', '')] +for redemption in redemptions: + print(f"Certificate {redemption.get('Certificate')} - {redemption.get('Description')}") + print(f" Amount: ${redemption.get('Amount', 0):,.2f}") + print(f" Shares: {redemption.get('Shares', 0):,.2f}") +``` + +## Common Use Cases + +### 1. Transaction Summary Report + +```python +history = client.shares_history.get_history( start_date="01/01/2024", end_date="12/31/2024", - partner_account="PART001", - pool_account="POOL001" + pool_account="LENDER-D" ) + +# Group by transaction type +from collections import defaultdict +by_type = defaultdict(list) + +for transaction in history: + code = transaction.get('Code') + by_type[code].append(transaction) + +# Summary +for code, transactions in by_type.items(): + total = sum(float(t.get('Amount', 0)) for t in transactions) + print(f"{code}: {len(transactions)} transactions, Total: ${total:,.2f}") +``` + +### 2. Partner Activity Report + +```python +history = client.shares_history.get_history( + partner_account="P001002", + start_date="01/01/2024", + end_date="12/31/2024" +) + +print(f"Transaction history for partner P001002:") +for transaction in history: + print(f"\n{transaction.get('DateReceived')}") + print(f" {transaction.get('Description')}") + print(f" Amount: ${transaction.get('Amount', 0):,.2f}") + print(f" Shares: {transaction.get('Shares', 0):,.2f}") + print(f" Balance: {transaction.get('SharesBalance', 0):,.2f}") + if transaction.get('Certificate'): + print(f" Certificate: {transaction.get('Certificate')}") +``` + +### 3. ACH Transaction Tracking + +```python +history = client.shares_history.get_history( + start_date="01/01/2024", + end_date="12/31/2024" +) + +# Filter ACH transactions +ach_transactions = [ + t for t in history + if t.get('ACH_BatchNumber') or t.get('ACH_TraceNumber') +] + +print(f"Found {len(ach_transactions)} ACH transactions") +for transaction in ach_transactions: + print(f"\nDate: {transaction.get('DateDeposited')}") + print(f" Payee: {transaction.get('PayName')}") + print(f" Amount: ${transaction.get('Amount', 0):,.2f}") + print(f" Batch: {transaction.get('ACH_BatchNumber')}") + print(f" Trace: {transaction.get('ACH_TraceNumber')}") +``` + +### 4. Export to CSV + +```python +import csv + +history = client.shares_history.get_history( + start_date="01/01/2024", + end_date="12/31/2024", + pool_account="LENDER-D" +) + +with open('transaction_history.csv', 'w', newline='') as f: + writer = csv.writer(f) + writer.writerow([ + 'Date', 'Type', 'Description', 'Partner', 'Amount', + 'Shares', 'Balance', 'Certificate', 'Created By' + ]) + + for transaction in history: + writer.writerow([ + transaction.get('DateReceived'), + transaction.get('Code'), + transaction.get('Description'), + transaction.get('PartnerAccount'), + transaction.get('Amount'), + transaction.get('Shares'), + transaction.get('SharesBalance'), + transaction.get('Certificate'), + transaction.get('CreatedBy') + ]) +``` + +## Next Steps + +- [Partners](partners.md) - Working with partners +- [Pools](pools.md) - Working with pools +- [Distributions](distributions.md) - Querying distributions +- [Certificates](certificates.md) - Managing certificates ``` diff --git a/docs/user-guide/partners.md b/docs/user-guide/partners.md index 95c39db..f494806 100644 --- a/docs/user-guide/partners.md +++ b/docs/user-guide/partners.md @@ -26,18 +26,52 @@ capital_partners = client.capital_partners ### get_partner() -Get detailed information about a specific partner. Returns a dictionary containing partner data. +Get detailed information about a specific partner. Returns complete profile information including contact details, ACH banking information, custom fields, and trustee information. **Parameters:** - `account` (str, required): The partner account identifier -**Returns:** `Dict[str, Any]` - Partner data dictionary +**Returns:** `Dict[str, Any]` - Partner data dictionary (CPartner:#TmoAPI) + +**Response Fields:** +- **Contact Information:** FirstName, LastName, MI, FullName, Salutation, EmailAddress +- **Address:** Street, City, State, ZipCode, HomeStreet, HomeCity, HomeState, HomeZipCode +- **Phone Numbers:** PhoneHome, PhoneWork, PhoneCell, PhoneFax, PhoneMain +- **ACH Details:** ACH_AccountNumber, ACH_RoutingNumber, ACH_BankName, ACH_BankAddress, ACH_AccountType, ACH_SecCode, ACH_IndividualId, ACH_IndividualName, ACH_ServiceStatus, ACH_SendDepositNotificationFlag +- **Custom Fields:** Array of custom field objects with Name, Tab, and Value properties +- **Trustee Information:** TrusteeRecID, TrusteeAccountRef, TrusteeAccountType +- **Tax Information:** TIN, TINType +- **Settings:** DeliveryOptions, PrintStatementFor, EmailFormat, Categories, Notes, UsePayee, Payee +- **Registered Shareholder:** RegisteredShareholderName, RegisteredShareholderStreet, RegisteredShareholderCity, RegisteredShareholderState, RegisteredShareholderZipCode +- **Flags:** ERISA, NonResident, HomeAddrEnabled +- **Other:** AccountType, BirthDay, SecurityHeldBy, WPC_PIN, WPC_Publish, GrowthPct +- **Holdback:** Holdback_Use, Holdback_Pct, Holdback_Ref, Holdback_RecID +- **System Fields:** RecID, SysCreatedDate, SysTimeStamp + +**Note:** This endpoint returns profile and contact information but does NOT include financial transaction data (contributions, distributions, capital balances). For financial data, use `pools.get_pool_partners()`. **Example:** ```python -partner = client.shares_partners.get_partner("PART001") -print(f"Partner: {partner.get('Name')}") -print(f"Account: {partner.get('Account')}") +partner = client.shares_partners.get_partner("P001002") + +# Contact information +print(f"Name: {partner.get('FirstName')} {partner.get('LastName')}") +print(f"Email: {partner.get('EmailAddress')}") +print(f"Phone: {partner.get('PhoneHome')}") +print(f"Address: {partner.get('Street')}, {partner.get('City')}, {partner.get('State')} {partner.get('ZipCode')}") + +# ACH information +print(f"ACH Bank: {partner.get('ACH_BankName')}") +print(f"ACH Account: {partner.get('ACH_AccountNumber')}") +print(f"ACH Routing: {partner.get('ACH_RoutingNumber')}") + +# Custom fields +for field in partner.get('CustomFields', []): + print(f"{field['Name']}: {field['Value']}") + +# Trustee information +print(f"Trustee ID: {partner.get('TrusteeRecID')}") +print(f"Trustee Account Ref: {partner.get('TrusteeAccountRef')}") ``` ### get_partner_attachments() @@ -59,13 +93,26 @@ for attachment in attachments: ### list_all() -List all partners with optional date filtering. +List all partners with optional date filtering. Date range filters partners based on their DateCreated and LastChanged timestamps. **Parameters:** - `start_date` (str, optional): Start date in MM/DD/YYYY format - `end_date` (str, optional): End date in MM/DD/YYYY format -**Returns:** `List[Any]` - List of partner data dictionaries +**Returns:** `List[Any]` - List of partner data dictionaries (CPSSPartners:#TmoAPI) + +**Response Fields:** +Each partner dictionary contains: +- **Account:** Partner account identifier +- **Contact Info:** FirstName, LastName, MI, SortName, EmailAddress +- **Address:** Street, City, State, ZipCode +- **Phone Numbers:** PhoneHome, PhoneWork, PhoneCell, PhoneFax, PhoneMain +- **Custom Fields:** Array of custom field objects with Name, Tab, and Value properties +- **Trustee Info:** TrusteeName, TrusteeAccount, TrusteeAccountRef, TrusteeAccountType +- **Tax Info:** TIN +- **Flags:** ERISA, IsACH, UsePayee +- **Timestamps:** DateCreated, LastChanged +- **Other:** RecID, Payee **Example:** ```python @@ -73,11 +120,19 @@ List all partners with optional date filtering. partners = client.shares_partners.list_all() for partner in partners: - print(f"{partner.get('Account')}: {partner.get('Name')}") + print(f"{partner.get('Account')}: {partner.get('FirstName')} {partner.get('LastName')}") + print(f" Email: {partner.get('EmailAddress')}") + print(f" Created: {partner.get('DateCreated')}") + + # Show custom fields + for field in partner.get('CustomFields', []): + print(f" {field['Name']}: {field['Value']}") # Filter by date range partners = client.shares_partners.list_all( start_date="01/01/2024", end_date="12/31/2024" ) + +print(f"Found {len(partners)} partners created/modified in 2024") ``` diff --git a/docs/user-guide/pools.md b/docs/user-guide/pools.md index ae8bf09..843b3f9 100644 --- a/docs/user-guide/pools.md +++ b/docs/user-guide/pools.md @@ -79,19 +79,58 @@ for pool in pools: ### get_pool_partners() -Get partners associated with a pool. +Get comprehensive financial and contact information for all partners associated with a specific pool. This includes capital activity, performance metrics, and contact details. **Parameters:** - `account` (str, required): The pool account identifier -**Returns:** `list` of partner data +**Returns:** `list` of partner dictionaries (CPartners:#TmoAPI) + +**Response Fields:** +Each partner dictionary contains: + +**Financial Information:** +- **BegCapital:** Beginning capital balance +- **Contributions:** Capital contributions made by the partner +- **Distributions:** Distributions paid out to the partner +- **EndCapital:** Ending capital balance for the partner +- **Income:** Income earned +- **Withdrawals:** Withdrawal amounts +- **WithdrawalsAndDisbursements:** Total withdrawals and disbursements +- **IRR:** Internal Rate of Return + +**Contact Information:** +- **Account:** Partner account identifier +- **SortName:** Partner's name +- **Address:** Street, City, State, ZipCode +- **Phone:** PhoneHome, PhoneWork, PhoneCell, PhoneFax +- **EmailAddress:** Partner's email +- **TIN:** Tax Identification Number + +**Other:** +- **AccountType:** Type of account +- **ERISA:** ERISA flag +- **IsACH:** ACH flag +- **RecID:** Unique record identifier + +**Note:** This endpoint combines both financial transaction data and contact information. For contact/profile information only (without financial data), use `partners.get_partner()`. **Example:** ```python -partners = client.shares_pools.get_pool_partners("POOL001") +partners = client.shares_pools.get_pool_partners("LENDER-C") for partner in partners: - print(f"Partner: {partner.get('Name')}") + print(f"\nPartner: {partner.get('SortName')} ({partner.get('Account')})") + print(f" Email: {partner.get('EmailAddress')}") + print(f" Phone: {partner.get('PhoneHome')}") + + # Financial information + print(f" Beginning Capital: ${partner.get('BegCapital', 0):,.2f}") + print(f" Contributions: ${float(partner.get('Contributions', 0)):,.2f}") + print(f" Distributions: ${float(partner.get('Distributions', 0)):,.2f}") + print(f" Ending Capital: ${float(partner.get('EndCapital', 0)):,.2f}") + print(f" Income: ${float(partner.get('Income', 0)):,.2f}") + print(f" IRR: {partner.get('IRR', 0)}%") ``` ### get_pool_loans() From a43f7f8603f40403b05a0df9caeafd556c8ff36c Mon Sep 17 00:00:00 2001 From: Yinchuan Song <562997+inntran@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:27:08 -0500 Subject: [PATCH 3/4] Refactor documentation deployment steps to remove unnecessary push flags --- .github/workflows/docs.yml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 21dc3eb..0bbce4e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -40,34 +40,38 @@ jobs: python -m pip install --upgrade pip pip install -e ".[docs]" - - name: Deploy documentation (main branch) + - name: Build documentation (main branch) if: github.ref_name == 'main' run: | - mike deploy --push --update-aliases latest stable - mike set-default --push latest + mike deploy --update-aliases latest stable + mike set-default latest - - name: Deploy documentation (staging branch) + - name: Build documentation (staging branch) if: github.ref_name == 'staging' run: | - mike deploy --push staging + mike deploy staging - - name: Deploy documentation (develop branch) + - name: Build documentation (develop branch) if: github.ref_name == 'develop' run: | - mike deploy --push dev + mike deploy dev - name: Set default alias when missing (develop) if: github.ref_name == 'develop' run: | DEFAULT_ALIAS=$(mike list --remote 2>/dev/null | awk '/^\*/ {print $2}') if [ -z "$DEFAULT_ALIAS" ]; then - mike set-default --push dev + mike set-default dev fi - - name: Deploy documentation (version tag) + - name: Build documentation (version tag) if: steps.tag.outputs.value != '' run: | VERSION=${{ steps.tag.outputs.value }} VERSION=${VERSION#v} - mike deploy --push --update-aliases $VERSION stable - mike set-default --push $VERSION + mike deploy --update-aliases $VERSION stable + mike set-default $VERSION + + - name: Push documentation to gh-pages + run: | + git push origin gh-pages From 6e4c140a4a33fec1d2c136cb98efcf1caee2f494 Mon Sep 17 00:00:00 2001 From: Yinchuan Song <562997+inntran@users.noreply.github.com> Date: Wed, 12 Nov 2025 16:30:25 -0500 Subject: [PATCH 4/4] =?UTF-8?q?Bump=20version:=200.1.1=20=E2=86=92=200.1.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.toml | 2 +- docs/changelog.md | 13 +++++++++++++ pyproject.toml | 2 +- src/tmo_api/_version.py | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.bumpversion.toml b/.bumpversion.toml index e1e908e..29829c3 100644 --- a/.bumpversion.toml +++ b/.bumpversion.toml @@ -1,5 +1,5 @@ [tool.bumpversion] -current_version = "0.1.1" +current_version = "0.1.2" parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)" serialize = ["{major}.{minor}.{patch}"] search = "{current_version}" diff --git a/docs/changelog.md b/docs/changelog.md index 2add99c..155d9a4 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -4,7 +4,19 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.1.2] - 2025-11-12 +### Added + +- Add inline documentations to partner and history endpoints. +- Add returned data structures to documentations + +### Changed +- Refactor documentation deployment steps to remove unnecessary push flags + ## [0.1.1] - 2025-11-11 +### Fixed + +- Fix tmoapi loading postman collection path issue ## [0.1.0] - 2025-11-10 ### Added @@ -45,6 +57,7 @@ All notable changes to this project will be documented in this file. - Contributing: Development Setup, Testing, Code Style - Changelog +[0.1.2]: https://github.com/inntran/tmo-api-python/releases/tag/v0.1.2 [0.1.1]: https://github.com/inntran/tmo-api-python/releases/tag/v0.1.1 [0.1.0]: https://github.com/inntran/tmo-api-python/releases/tag/v0.1.0 [0.0.1]: https://github.com/inntran/tmo-api-python/releases/tag/v0.0.1 diff --git a/pyproject.toml b/pyproject.toml index a78d8ed..47977d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "tmo-api" -version = "0.1.1" +version = "0.1.2" description = "Wrapper for The Mortgage Office API" readme = "README.md" license = { text = "Apache-2.0" } diff --git a/src/tmo_api/_version.py b/src/tmo_api/_version.py index 3b7ff80..9385bae 100644 --- a/src/tmo_api/_version.py +++ b/src/tmo_api/_version.py @@ -3,4 +3,4 @@ __all__ = ["__version__"] # Keep this in sync with pyproject.toml -__version__ = "0.1.1" +__version__ = "0.1.2"