Client Receipt Controller Documentation
File: /controllers/clientreceiptController.php
Purpose: Manages client payment receipts and bill payment processing with dual payment methods
Last Updated: December 20, 2024
Total Functions: 9
Lines of Code: ~436
---
๐ Overview
The Client Receipt Controller is a comprehensive payment processing system that handles customer payment receipts and bill settlements. It provides dual-mode functionality for both bill-specific payments and general debt payments with integrated accounting journal entries. The system features:
- โข Dual payment method interface (cash/card vs other payment types)
- โข Outstanding bill discovery and payment allocation
- โข Automated accounting journal entry generation
- โข Payment receipt creation and management
- โข Payment reversal and deletion capabilities
- โข Bill payment status tracking and updates
- โข Bank and payment network integration
Primary Functions
- โ Outstanding bill search and display
- โ Payment receipt generation
- โ Bill payment allocation and tracking
- โ Automated accounting entries
- โ Payment method selection (cash/card/bank/etc.)
- โ Payment reversal processing
- โ Receipt deletion and audit trail
- โ Payment history reporting
- โ Bank account integration
Related Controllers
- โข clientPayedDeptController.php - Direct debt payments
- โข sellbillController.php - Sales operations
- โข billreceiptController.php - Optical bill receipts
- โข dailyentry.php - Journal entries
- โข bankController.php - Bank management
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **clientpaymentreceiptt** | Payment receipts | clientpaymentreceipttid, clientid, billid, biltype, payed, paymethod, payedtype, dailyentryid, del | |
| **sellbill** | Sales bills | sellbillid, sellbillclientid, sellbilltotalpayed, sellbillfinalbill, sellbillaftertotalbill, conditions | |
| **bills** | Optical bills | billid, clientid, waitvalue, clientPayReceiptVal, billdate, deleted |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **dailyentry** | Journal entries | dailyentryid, entryComment, entryDate, entryValue, userid | |
| **dailyentrycreditor** | Credit entries | dailyentrycreditorid, dailyentryid, value, accountstreeid | |
| **dailyentrydebtor** | Debit entries | dailyentrydebtorMySqlDAO, dailyentryid, value, accountstreeid | |
| **save** | Cash registers | saveid, savename, savevalue | |
| **bank** | Banks | bankid, bankname, bankbalance | |
| **bankaccount** | Bank accounts | bankaccountid, bankaccounttitle, bankid |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **client** | Customer master data | clientid, clientname, clientdebt, treeId, conditions | |
| **accountstree** | Chart of accounts | accountstreeid, accounttreename, accounttreebalance | |
| **paymentnetwork** | Payment methods | paymentnetworkid, paymentnetworkname, deleted | |
| **user** | System users | userid, username |
๐ Key Functions
1. Default Action - Payment Receipt Form
Location: Line 139-151
Purpose: Display payment receipt creation form with payment method selection
Process Flow:
1. Load payment networks/methods
2. Load bank accounts for selection
3. Set receipt validation flag
4. Display clientreceiptview/show.html
Payment Networks Loading:
$paymentmethod = $paymentNetworksDAO->queryByDeleted(0);
$smarty->assign('paymentmethod', $paymentmethod);
$banks = $bankDAO->queryAll();
$smarty->assign("banks", $banks);
---
2. search Action - Bill Discovery and Payment Interface
Location: Line 152-183
Purpose: Find outstanding bills for customer and provide payment interface
Function Signature:
// Parameters from form
$clientname = filter_input(INPUT_POST, 'clientname'); // Customer ID
$clientdate = filter_input(INPUT_POST, 'clientdate'); // Optional date filter
$paymethod = filter_input(INPUT_POST, 'paymethod'); // Payment method type
Dual Interface Logic:
if ($paymethod == 0) {
// Cash/Card payment interface
if (!empty($clientname)) {
getBillsToPay($clientname, $clientdate);
}
$smarty->display("clientreceiptview/show.html");
} else {
// Other payment methods interface (bank, check, etc.)
$smarty->display("clientreceiptview/secondshow.html");
}
---
3. getBillsToPay() - Outstanding Bills Discovery
Location: Line 256-326
Purpose: Find and format outstanding bills for payment allocation
Function Signature:
function getBillsToPay($clientname, $clientdate)
Bill Query Logic:
// Sales bills with outstanding amounts
$queryString = 'WHERE sellbill.sellbillclientid = ' . $clientname . ' AND sellbillfinalbill !=0';
// Optical bills with outstanding amounts
$queryString1 = 'WHERE bills.clientid = ' . $clientname . ' AND waitvalue !=0';
if (empty($clientdate)) {
// All outstanding bills
$allsellbillData = $mySellbillEx->queryAllforreceipt($queryString);
$allbillsData = $billsEX->queryAllforreceipt($queryString1);
} else {
// Bills for specific date
$queryString .= ' and sellbilldate = ' . $clientdate;
$queryString1 .= ' and billdate = ' . $clientdate;
}
Outstanding Amount Calculation:
foreach ($allbillsData as $value) {
$needToPay = $value->waitvalue - $value->clientPayReceiptVal;
$value->waitvalue = $needToPay;
if ($needToPay < 0) { // Bill totally paid
unset($allbillsData[$i]);
}
$i++;
}
Bill Type Identification:
foreach ($allsellbillData as $value) {
$value->userid = 0; // Type = sellbill
$value->theDate = $value->sellbilldate;
array_push($allDataArr, $value);
}
foreach ($allbillsData as $value) {
$value->userid = 1; // Type = optical bill
$value->theDate = $value->billdate;
array_push($allDataArr, $value);
}
---
4. show Action - Payment Receipt History
Location: Line 184-212
Purpose: Display existing payment receipts with search filters
Search Parameters:
$clientid = filter_input(INPUT_POST, "clientname");
$datefrom = filter_input(INPUT_POST, "datefrom");
$dateto = filter_input(INPUT_POST, "dateto");
$showdel = filter_input(INPUT_POST, "showdel"); // Include deleted receipts
$queryString = " WHERE del = " . $showdel;
if (!empty($clientid)) {
$queryString .= " and clientpaymentreceiptt.clientid= " . $clientid;
}
if (isset($datefrom) && !empty($datefrom)) {
$queryString .= ' and clientpaymentreceiptt.sysdate >= "' . $datefrom . '" ';
}
if (isset($dateto) && !empty($dateto)) {
$queryString .= ' and clientpaymentreceiptt.sysdate <= "' . $dateto . '" ';
}
---
5. delete Action - Payment Removal
Location: Line 213-223
Purpose: Remove payment receipt and reverse all effects
Process Flow:
1. Call remove() function
2. Redirect to show page on success
3. Redirect to error page on failure
---
6. remove() - Payment Reversal Engine
Location: Line 355-370
Purpose: Reverse payment receipt and update all affected records
Function Signature:
function remove()
Reversal Logic:
$id = $_GET['id'];
$clientRecit = $ClientpaymentreceipttDAO->load($id);
if ($clientRecit->biltype == -1) {
// General debt payment reversal
$data = payDebtReverse($clientRecit);
} else {
// Bill-specific payment reversal
$data = payBillReverse($clientRecit);
}
if ($data == 1) {
$clientRecit->del = 1; // Mark as deleted
$ClientpaymentreceipttDAO->update($clientRecit);
}
---
7. payDebtReverse() - General Payment Reversal
Location: Line 372-394
Purpose: Reverse general debt payments (not tied to specific bills)
Function Signature:
function payDebtReverse($clientRecit)
Process Flow:
1. Get save/cash register ID from session
2. Reverse journal entry by ID
3. Update customer debt accordingly
4. Return success status
Journal Entry Reversal:
$data = reverseEntryWithItsID($clientRecit->dailyentryid);
---
8. payBillReverse() - Bill Payment Reversal
Location: Line 396-434
Purpose: Reverse bill-specific payments and update bill balances
Function Signature:
function payBillReverse($clientRecit)
Bill Update Logic:
$billid = $clientRecit->billid;
$billtype = $clientRecit->biltype;
$thevalue = $clientRecit->payed;
// Reverse journal entry first
$data = reverseEntryWithItsID($clientRecit->dailyentryid);
if ($billtype == 0) { // Sales bill
$sellbill = $mySellbillRecord->load($billid);
$sellbill->sellbilltotalpayed = $sellbill->sellbilltotalpayed - $thevalue;
$sellbill->sellbillfinalbill = $sellbill->sellbillfinalbill + $thevalue;
$mySellbillEx->updatePayedAndRemain($sellbill);
} elseif ($billtype == 1) { // Optical bill
$thebill = $billsDAO->load($billid);
$newPay = $thebill->clientPayReceiptVal - $thevalue;
$billsEX->updateClientPayReceiptVal($newPay, $thebill->id);
}
---
9. sortByDate() - Bill Sorting Utility
Location: Line 330-353
Purpose: Sort outstanding bills by date for payment interface
Function Signature:
function sortByDate($type, $allDataArr)
Sorting Algorithm:
$Count = count($allDataArr) - 1;
foreach ($allDataArr as $obj) {
for ($i = 0; $i < $Count; $i++) {
if ($type == "desc") {
if ($allDataArr[$i]->theDate < $allDataArr[$i + 1]->theDate) {
$tempObj = $allDataArr[$i];
$allDataArr[$i] = $allDataArr[$i + 1];
$allDataArr[$i + 1] = $tempObj;
}
} elseif ($type == "asc") {
if ($allDataArr[$i]->theDate > $allDataArr[$i + 1]->theDate) {
$tempObj = $allDataArr[$i + 1];
$allDataArr[$i + 1] = $allDataArr[$i];
$allDataArr[$i] = $tempObj;
}
}
}
}
---
๐ Workflows
Workflow 1: Bill Payment Process
---
Workflow 2: Payment Reversal Process
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default action | Display payment receipt form | |
| `do=search` | Search function | Find outstanding bills for payment | |
| `do=show` | Show function | Display payment receipt history | |
| `do=delete` | Delete function | Remove payment receipt | |
| `do=editprint` | Edit print | View/edit receipt for printing | |
| `do=sucess` | Success page | Display success message | |
| `do=error` | Error page | Display error message |
Search Outstanding Bills (do=search):
- โข
clientname- Customer ID - โข
clientdate- Optional date filter (YYYY-MM-DD) - โข
paymethod- Payment method type (0=cash/card, 1=other)
Receipt History (do=show):
- โข
clientname- Customer ID filter - โข
datefrom- Start date filter - โข
dateto- End date filter - โข
showdel- Include deleted receipts (0/1)
Delete Receipt (do=delete):
- โข
id- Payment receipt ID (GET parameter)
---
๐งฎ Calculation Methods
Outstanding Bill Amount Calculation
// For optical bills - calculate remaining amount to pay
$needToPay = $value->waitvalue - $value->clientPayReceiptVal;
$value->waitvalue = $needToPay;
// Remove fully paid bills
if ($needToPay < 0) {
unset($allbillsData[$i]);
}
Bill Balance Updates After Payment
// Sales bill payment
$sellbill->sellbilltotalpayed = $sellbill->sellbilltotalpayed - $thevalue;
$sellbill->sellbillfinalbill = $sellbill->sellbillfinalbill + $thevalue;
// Optical bill payment
$newPay = $thebill->clientPayReceiptVal - $thevalue;
$billsEX->updateClientPayReceiptVal($newPay, $thebill->id);
---
๐ Security & Permissions
Access Control
- โข Requires authentication via
../public/authentication.php - โข No specific permission level checks mentioned in code
Input Sanitization
- โข Uses
filter_input()for all form parameters - โข Numeric IDs validated as integers
- โข SQL injection prevented by DAO layer
Audit Trail
// Soft delete for audit trail
$clientRecit->del = 1;
$ClientpaymentreceipttDAO->update($clientRecit);
---
๐ Performance Considerations
Database Optimization Tips
1. Indexes Required:
- sellbill(sellbillclientid, sellbillfinalbill, conditions)
- bills(clientid, waitvalue, deleted)
- clientpaymentreceiptt(clientid, sysdate, del)
- clientpaymentreceiptt(dailyentryid)
2. Query Optimization:
- Filter non-zero amounts at database level
- Date filtering with proper indexes
- Avoid N+1 queries in bill loading
3. Memory Management:
- Remove fully paid bills from arrays early
- Sort in PHP rather than database for small datasets
---
๐ Common Issues & Troubleshooting
1. Bills Not Showing in Payment Interface
Issue: Outstanding bills not appearing for customer
Causes:
- โข Bills are fully paid (
sellbillfinalbill = 0orwaitvalue = 0) - โข Bills are cancelled (
conditions != 0) - โข Customer ID mismatch
Debug:
-- Check sales bills
SELECT sellbillid, sellbillfinalbill, conditions
FROM sellbill WHERE sellbillclientid = [ID];
-- Check optical bills
SELECT billid, waitvalue, clientPayReceiptVal, deleted
FROM bills WHERE clientid = [ID];
2. Payment Reversal Fails
Issue: Payment deletion doesn't update bill balances
Cause: Journal entry reversal failure
Debug:
-- Check if journal entry exists
SELECT * FROM dailyentry WHERE dailyentryid = [RECEIPT_DAILYENTRYID];
-- Check payment receipt data
SELECT * FROM clientpaymentreceiptt WHERE clientpaymentreceipttid = [ID];
3. Incorrect Outstanding Amounts
Issue: Bill shows wrong remaining amount
Cause: Calculation error in outstanding amount formula
Fix:
// Verify calculation
$needToPay = $value->waitvalue - $value->clientPayReceiptVal;
if ($needToPay <= 0) {
// Bill is fully paid, should not appear
}
4. Payment Method Interface Issues
Issue: Wrong payment interface displayed
Cause: paymethod parameter not properly handled
Debug:
echo "Payment method: " . $paymethod; // Should be 0 or 1
if ($paymethod == 0) {
echo "Cash/Card interface";
} else {
echo "Bank/Other interface";
}
---
๐งช Testing Scenarios
Test Case 1: Outstanding Bill Discovery
1. Create customer with unpaid bills
2. Search for outstanding bills
3. Verify correct bills appear
4. Verify fully paid bills don't appear
5. Check outstanding amount calculations
Test Case 2: Payment Processing Flow
1. Select customer with outstanding bills
2. Choose payment method
3. Process payment for specific bills
4. Verify bill balances updated
5. Check journal entries created
Test Case 3: Payment Reversal
1. Create payment receipt
2. Verify bill balance changes
3. Delete payment receipt
4. Verify reversal updates:
- Bill balance restored
- Journal entry reversed
- Receipt marked deleted
Test Case 4: Date-Based Filtering
1. Create bills on different dates
2. Filter by specific date
3. Verify only bills from that date appear
4. Test with empty date (all outstanding bills)
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข clientPayedDeptController.md - Direct debt payments
- โข sellbillController.md - Sales operations
- โข dailyentry.md - Journal entry system
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur