PartnerTransferBetween Documentation
Partner Transfer Between Controller Documentation
File: /controllers/partnerTransferBetweenController.php
Purpose: Inter-partner fund transfer management system
Last Updated: December 20, 2024
Total Functions: 6
Lines of Code: ~672
---
๐ Overview
The Partner Transfer Between Controller manages financial transfers between business partners within the system. It provides:
- โข Direct fund transfers between partners
- โข Balance tracking and validation
- โข Accounting integration with daily entries
- โข Transfer history and audit trails
- โข Bank account and cash transfer support
- โข Automatic balance reconciliation
- โข Complete transaction reversal capability
Primary Functions
- โ Inter-partner fund transfers
- โ Balance tracking before/after transfers
- โ Multiple payment method support (cash/bank)
- โ Accounting journal integration
- โ Transfer reversal and cancellation
- โ Complete audit trail maintenance
- โ Date range filtering and reporting
- โ Partner-specific transfer history
Related Controllers
- โข partnerController.php - Partner management
- โข partnerwithdrawalController.php - Partner withdrawals
- โข transfermoneyController.php - Cash transfers
- โข dailyentry.php - Accounting entries
- โข bankaccountController.php - Bank account management
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **partnertransferbetween** | Transfer transactions | partnertransferbetweenid, partneridfrom, partneridto, partnervalue, partnerfrombefore, partnerfromafter, partnertobefore, partnertoafter, dailyentryid, conditions | |
| **partner** | Partner master data | partnerid, partnername, partnermoney, treeId |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **dailyentry** | Accounting journal entries | dailyentryid, entryComment, totalcreditor, totalDebtor | |
| **dailyentrycreditor** | Credit side entries | dailyentrycreditorid, dailyentryid, accountstreeid, value | |
| **dailyentrydebtor** | Debit side entries | dailyentrydebtoryid, dailyentryid, accountstreeid, value | |
| **accountstree** | Chart of accounts | accountstreeid, accountname, parentid |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **bankaccount** | Bank account data | accountid, bankid, accountbeginingbalance, treeId | |
| **accountmovement** | Bank account history | accountmovementid, accountid, amountbefore, amountafter, movementtype | |
| **user** | System users | userid, username, searchinonesave | |
| **youtubelink** | Tutorial videos | youtubelinkid, title, url |
๐ Key Functions
1. add() / Transfer Execution - Core Transfer Logic
Location: Line 290
Purpose: Execute fund transfer between two partners with full accounting integration
Function Signature:
function add()
// Triggered when: do=add
$partneridfrom = $_POST['partneridfrom'];
$partneridto = $_POST['partneridto'];
$partnervalue = $_POST['partnervalue'];
Process Flow:
1. Load partner data for from/to partners
2. Record transfer with before/after balances
3. Generate accounting daily entry
4. Update both partner balances directly
5. Create complete audit trail
Key Features:
// Record exact balances before transfer
$myPartnertransferbetween->partnerfrombefore = $partnerfromdata->partnermoney;
$myPartnertransferbetween->partnerfromafter = $partnerfromdata->partnermoney - $partnervalue;
$myPartnertransferbetween->partnertobefore = $partnertodata->partnermoney;
$myPartnertransferbetween->partnertoafter = $partnertodata->partnermoney + $partnervalue;
// Update partner balances atomically
R::exec("UPDATE `partner` SET `partnermoney`= partnermoney - " . $partnervalue . " WHERE partnerid = '" . $partneridfrom . "' ");
R::exec("UPDATE `partner` SET `partnermoney`= partnermoney + " . $partnervalue . " WHERE partnerid = '" . $partneridto . "' ");
---
2. tempdelete() / Transfer Reversal - Complete Transaction Reversal
Location: Line 329
Purpose: Reverse a transfer by creating an opposite transaction
Function Signature:
function tempdelete($partnertransferbetweenid)
// Creates reverse transaction instead of deletion
Process Flow:
1. Load original transfer record
2. Mark original transfer as deleted (conditions=1)
3. Create reverse transfer record
4. Swap from/to partners in reverse transaction
5. Update partner balances with reverse amounts
6. Reverse the original daily entry
Reversal Logic:
// Original: Partner A โ Partner B ($100)
// Reversal: Partner B โ Partner A ($100)
$myPartnertransferbetween->partneridfrom = $originalTransfer->partneridto;
$myPartnertransferbetween->partneridto = $originalTransfer->partneridfrom;
$myPartnertransferbetween->partnervalue = $originalTransfer->partnervalue;
// Reverse the daily entry
reverseEntryWithItsID($originalTransfer->dailyentryid);
---
3. loadPartner() / Partner Data Loading - Available Partner List
Location: Line 279
Purpose: Load all active partners for transfer selection
Function Signature:
function loadPartner()
// Returns: Array of active partners (conditions=0)
---
4. edit() / Transfer Edit Form - Load Transfer for Editing
Location: Line 367
Purpose: Load transfer data for modification
Function Signature:
function edit()
// URL Parameter: partnertransferbetweenid
// Returns: Transfer record with partner details
---
5. update() / Transfer Update Process - Edit Existing Transfer
Location: Line 250 (within main flow)
Purpose: Update transfer by deleting old and creating new
Process Flow:
1. Load old transfer ID from form
2. Delete/reverse old transfer
3. Create new transfer with updated values
4. Maintain audit trail continuity
---
6. makePartnerTransferDailyEntry() / Accounting Integration - Journal Entry Creation
Location: Line 646
Purpose: Generate proper accounting entries for partner transfers
Function Signature:
function makePartnerTransferDailyEntry($partneridfrom, $partneridto, $partnerMoney)
// Returns: Daily entry ID for linking
Accounting Logic:
// Transfer from Partner A to Partner B
// Debit Partner A account (decrease their equity)
$dailyEntryDebtor->accountstreeid = $partnerFrom['treeId'];
// Credit Partner B account (increase their equity)
$dailyEntryCreditor->accountstreeid = $partnerTo['treeId'];
// Both sides equal the transfer amount
$dailyEntryDebtor->value = $partnerMoney;
$dailyEntryCreditor->value = $partnerMoney;
---
๐ Workflows
Workflow 1: Partner Transfer Execution
---
Workflow 2: Transfer Reversal Process
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default display | Transfer form with partner selection | |
| `do=add` | `add()` | Execute new transfer | |
| `do=show` | Transfer history | Display transfers with filters | |
| `do=tempdelete` | `tempdelete()` | Reverse/cancel transfer | |
| `do=edit` | `edit()` | Load transfer for editing | |
| `do=update` | Update process | Delete old, create new transfer |
New Transfer (do=add):
- โข
partneridfrom- Source partner ID - โข
partneridto- Destination partner ID - โข
partnervalue- Transfer amount - โข
comment- Transfer description
Transfer History (do=show):
- โข
from- Start date filter (optional) - โข
to- End date filter (optional) - โข
partnerid- Specific partner filter (optional)
Transfer Reversal (do=tempdelete):
- โข
partnertransferbetweenid- Transfer ID to reverse
Transfer Edit (do=edit):
- โข
partnertransferbetweenid- Transfer ID to edit
---
๐งฎ Calculation Methods
Balance Calculation
// Before transfer balances
$partnerfrombefore = $partnerfromdata->partnermoney;
$partnertobefore = $partnertodata->partnermoney;
// After transfer balances
$partnerfromafter = $partnerfromdata->partnermoney - $partnervalue;
$partnertoafter = $partnertodata->partnermoney + $partnervalue;
Transfer Impact
// Direct partner balance updates
UPDATE partner SET partnermoney = partnermoney - {amount} WHERE partnerid = {from};
UPDATE partner SET partnermoney = partnermoney + {amount} WHERE partnerid = {to};
Accounting Entry
// Debit source partner (their equity decreases)
$dailyEntryDebtor->value = $partnerMoney;
$dailyEntryDebtor->accountstreeid = $partnerFrom['treeId'];
// Credit destination partner (their equity increases)
$dailyEntryCreditor->value = $partnerMoney;
$dailyEntryCreditor->accountstreeid = $partnerTo['treeId'];
---
๐ Security & Permissions
Authentication Requirements
include_once("../public/authentication.php");
// Required for all operations
Input Validation
- โข Partner IDs validated against active partners
- โข Transfer amounts must be numeric and positive
- โข Prevents self-transfers (same from/to partner)
- โข SQL injection prevention through prepared statements
Data Integrity
- โข Atomic balance updates using direct SQL
- โข Transaction rollback on any failure
- โข Soft delete preserves audit trail
- โข Complete reversal capability
User Permissions
$userData = $myUserRecord->load($_SESSION['userid']);
// User context maintained throughout operations
---
๐ Performance Considerations
Database Optimization
1. Required Indexes:
- partnertransferbetween(partneridfrom, partneridto, partnerdate)
- partnertransferbetween(conditions, partnerdate) - For active transfers
- partner(partnerid, conditions) - For balance lookups
2. Query Optimization:
- Direct SQL updates for balance changes (faster than ORM)
- Efficient date range filtering
- Partner lookup optimization
3. Memory Considerations:
- Transfer history can grow large over time
- Consider pagination for large date ranges
Performance Features
// Efficient partner balance updates
R::exec("UPDATE `partner` SET `partnermoney`= partnermoney - " . $partnervalue . " WHERE partnerid = '" . $partneridfrom . "' ");
// Using direct SQL instead of ORM for better performance
---
๐ Common Issues & Troubleshooting
1. Balance Synchronization Issues
Issue: Partner balances don't match transfer history
Cause: Failed or incomplete transfers
Debug:
-- Check partner balance vs transfer history
SELECT p.partnerid, p.partnername, p.partnermoney,
SUM(CASE WHEN pt.partneridto = p.partnerid THEN pt.partnervalue ELSE 0 END) as received,
SUM(CASE WHEN pt.partneridfrom = p.partnerid THEN pt.partnervalue ELSE 0 END) as sent
FROM partner p
LEFT JOIN partnertransferbetween pt ON (p.partnerid = pt.partneridfrom OR p.partnerid = pt.partneridto)
WHERE pt.conditions = 0
GROUP BY p.partnerid;
2. Transfer Reversal Problems
Issue: Reversed transfer doesn't restore original balances
Cause: Intervening transactions or calculation errors
Fix:
// Verify reversal calculations
$originalFrom = R::getRow('select * from partner where partnerid = ?', [$originalTransfer->partneridfrom]);
$expectedBalance = $originalFrom['partnermoney'] + $originalTransfer->partnervalue;
3. Accounting Entry Mismatches
Issue: Daily entries don't balance after transfers
Cause: Failed entry generation or reversal
Debug:
-- Find unbalanced daily entries
SELECT de.*, pt.partnertransferbetweenid
FROM dailyentry de
JOIN partnertransferbetween pt ON de.dailyentryid = pt.dailyentryid
WHERE de.totalcreditor != de.totalDebtor;
4. Partner Selection Issues
Issue: Inactive partners appear in transfer forms
Cause: Incorrect conditions filtering
Fix:
// Ensure only active partners loaded
$partnerData = $myPartnerRecord->queryByConditions(0); // conditions=0 for active
---
๐งช Testing Scenarios
Test Case 1: Basic Transfer
1. Access transfer form (empty do)
2. Select two different active partners
3. Enter valid transfer amount
4. Submit transfer (do=add)
5. Verify both partner balances updated correctly
6. Check transfer appears in history
7. Confirm accounting entry created
Test Case 2: Transfer Reversal
1. Create a test transfer
2. Note original partner balances
3. Reverse the transfer (tempdelete)
4. Verify balances restored to original amounts
5. Check original transfer marked as deleted
6. Confirm reversal transfer created
7. Verify accounting entries reversed
Test Case 3: Transfer Filtering
1. Create multiple transfers over different dates
2. Test date range filtering
3. Test partner-specific filtering
4. Verify filter combinations work correctly
5. Check empty result handling
Test Case 4: Edge Cases
1. Test transfer to same partner (should fail/prevent)
2. Test zero amount transfer
3. Test negative amount transfer
4. Test transfer with inactive partner
5. Verify proper error handling for each case
Debug Mode Enable
// Add transfer logging
error_log("Transfer: {$partneridfrom} โ {$partneridto}, Amount: {$partnervalue}");
error_log("Before: From={$partnerfrombefore}, To={$partnertobefore}");
error_log("After: From={$partnerfromafter}, To={$partnertoafter}");
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข partnerController.md - Partner management system
- โข partnerwithdrawalController.php - Partner withdrawal management
- โข dailyentry.md - Accounting entry system
- โข transfermoneyController.php - Cash transfer system
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When transfer business rules change