MirrorReportOnCashAndBanks Documentation

Mirror Report on Cash and Banks Controller Documentation

File: /controllers/mirrorReportOnCashAndBanks.php

Purpose: Generates comprehensive cash flow reconciliation reports for cash registers and bank accounts

Last Updated: December 20, 2024

Total Functions: 1 main action

Lines of Code: ~261

---

๐Ÿ“‹ Overview

The Mirror Report on Cash and Banks Controller provides detailed cash flow reconciliation by comparing opening balances, receipts, payments, and transfers between cash registers and bank accounts. It creates a mirror-like view showing the flow of money through different financial instruments during a specified period.

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Cash Management Tables

Table NamePurposeKey Columns
**save**Cash registers/safessaveid, savename, savecurrentvalue, conditions, saveTreeParentType
**savedaily**Cash register movementssavedailyid, saveid, savedailydate, savedailysavebefore, savedailymodelid, tablename
**bankaccount**Bank accountsaccountid, accountname, accountbeginingbalance, conditions
**accountmovement**Bank account movementsaccountmovementid, accountmovementdate, accountmovementbefore, accountmovementmodelid, tablename
### Transaction Tables

Table NamePurposeKey Columns
**sellbill**Sales transactionssellbillid, sellbilldate, sellbilltotalpayed, conditions
**clientdebtchange**Customer debt changesclientdebtchangeid, clientdebtchangedate, clientdebtchangeamount
**checkdeposit**Check depositscheckdepositid, checkdepositdate, checkdepositamount, conditions
**datedchecked**Post-dated checksdatedcheckedid, checkvalue, done, addtype
**checkwithdrawal**Check withdrawalscheckwithdrawalid, checkwithdrawaldate, checkwithdrawalamount, conditions
**cashtransfer**Cash transferscashtransferid, cashtransferdate, cashtransferamount, type, conditions
### Sales Tables

Table NamePurposeKey Columns
**returnsellbill**Sales returnsreturnsellbillid, returnsellbilldate, returnsellbillaftertotalbill, conditions
### System Tables

Table NamePurposeKey Columns
**programsettings**System configurationprogramsettingsid, reportsPlusHours
---

๐Ÿ”‘ Key Functions

1. Default Action - Cash Flow Mirror Report

Location: Lines 48-253

Purpose: Generate comprehensive cash flow reconciliation report

Function Signature:

// Triggered when: empty $do
$from = filter_input(INPUT_POST, 'from');
$to = filter_input(INPUT_POST, 'to');
$expensetypeid = (int) $_POST['expensetypeid'];

Process Flow:

1. Date Range Processing: Handle date defaults and time adjustments

2. Right Side Calculations (Inflows):

- Previous bank balances

- Previous cash balances

- Daily cash collections from sales

- Customer debt collections

- Customer collections via banks

3. Left Side Calculations (Outflows):

- Supplier payments from cash

- Supplier payments via banks

- Expenses by type

- Cash register expenses

- Bank account expenses

- Cash transfers between accounts

4. Net Calculations: Cash and bank net positions

5. Balance Array Creation: Ensure equal display rows

Date Range Logic:

// Handle automatic date ranges based on system settings
if (empty($startDate) && empty($endDate)) {
    $today = date('Y-m-d');
    $yesterday = date("Y-m-d", strtotime('-1 days'));
    
    if (isset($Programsetting->reportsPlusHours) && !empty($Programsetting->reportsPlusHours)) {
        $reportsPlusHours = $Programsetting->reportsPlusHours + 24;
        $endToday = date('Y-m-d H:i:s', strtotime('+' . $reportsPlusHours . ' hour', strtotime($today)));
        // ... time calculations
    }
}

---

๐Ÿ”„ Workflows

Workflow 1: Cash Flow Analysis

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Select Date Range
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Calculate Right Side (Inflows)
โ†’ Previous bank balances from accountmovement
โ†’ Previous cash balances from savedaily
โ†’ Cash collections from sellbill.sellbilltotalpayed
โ†’ Customer collections via clientdebtchange
โ”‚ โ””โ”€โ†’ Bank collections via checkdeposit & dated checks โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Calculate Left Side (Outflows)
โ†’ Supplier payments via supplierdebtchange
โ†’ Bank payments via checkwithdrawal
โ†’ Expenses by type from expenses table
โ†’ Cash expenses from savedaily
โ†’ Bank expenses from accountmovement
โ”‚ โ””โ”€โ†’ Inter-account transfers from cashtransfer โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Calculate Net Positions
โ†’ Net Cash = Inflows - Outflows + Transfers
โ†’ Net Bank = Inflows - Outflows + Transfers
โ”‚ โ””โ”€โ†’ Net Sales = Sales - Returns โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Generate Balanced Display
โ†’ Create equal-length arrays for left/right
โ†’ Fill shorter array with empty objects
โ”‚ โ””โ”€โ†’ Assign to template variables โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
5Display Mirror Report
โ”‚ โ””โ”€โ†’ Show side-by-side cash flow analysis โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐Ÿงฎ Calculation Methods

Opening Balance Calculation

// Previous bank balances
$BanksFirstPeriodVal = 0;
foreach (R::getAll('select accountid from bankaccount where conditions=0') as $value) {
    $BanksFirstPeriodVal += (float) R::getCell('select accountmovementbefore from accountmovement 
        where accountmovementmodelid=' . $value['accountid'] . ' 
        and accountmovementdate<"' . $startDate . '" 
        order by accountmovementid desc limit 1');
}

Cash Collections Calculation

// Daily cash collections from sales
$billPaymentVal = R::getCell('select sum(sellbilltotalpayed) from sellbill 
    where conditions=0 and sellbilldate >= "' . $startDate . '" 
    and sellbilldate <= "' . $endDate . '"');

Customer Collections via Banks

// Check deposits and dated checks processed through banks
$checkdepositVal = R::getCell('select sum(checkdepositamount) from checkdeposit 
    where conditions=0 and checkdepositdate >= "' . $startDate . '" 
    and checkdepositdate <= "' . $endDate . '"');

$datedCheckedBankClient = R::getCell('select sum(checkValue) from datedchecked
    where addType = 0 and done=1
    and datedCheckedID in (select accountmovementmodelid from accountmovement 
        where tablename="datedCheckedController.php" 
        and accountmovementdate >= "' . $startDate . '" 
        and accountmovementdate <= "' . $endDate . '")');

Transfer Calculation

// Net transfers between cash and bank
$cashtransferSaveToBank = R::getCell('select sum(cashtransferamount) from cashtransfer 
    where type=2 and conditions=0 and cashtransferdate >= "' . $startDate . '" 
    and cashtransferdate <= "' . $endDate . '"');

$cashtransferBankToSave = R::getCell('select sum(cashtransferamount) from cashtransfer 
    where type=1 and conditions=0 and cashtransferdate >= "' . $startDate . '" 
    and cashtransferdate <= "' . $endDate . '"');

$cashTransferNet = $cashtransferSaveToBank - $cashtransferBankToSave;

Expense Filtering

// Cash expenses (excluding duplicates)
$saveOutMoney = R::getCell('select sum(savedailychangeamount) from (
    select savedailychangeamount,savedailychangetype from savedaily 
    where savedailydate >= "' . $startDate . '" and savedailydate <= "' . $endDate . '"
    GROUP BY savedailymodelid,tablename
    HAVING COUNT(*) = 1
) as ttt where savedailychangetype=1');

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
`do=` (empty)Default actionCash flow mirror report
### Required Parameters

Default Behavior

---

๐Ÿ”’ Security & Permissions

Authentication Requirements

include_once("../public/authentication.php");

Input Sanitization

---

๐Ÿ“Š Performance Considerations

Database Optimization

1. Multiple Aggregation Queries: Report executes many SUM queries

2. Date Range Performance: Large date ranges can be slow

3. Required Indexes:

- sellbill(sellbilldate, conditions)

- clientdebtchange(clientdebtchangedate)

- checkdeposit(checkdepositdate, conditions)

- accountmovement(accountmovementdate, tablename)

- savedaily(savedailydate, tablename)

Query Optimization

-- Problematic query that could be optimized
SELECT sum(savedailychangeamount) FROM (
    SELECT savedailychangeamount, savedailychangetype FROM savedaily 
    WHERE savedailydate >= ? AND savedailydate <= ?
    GROUP BY savedailymodelid, tablename
    HAVING COUNT(*) = 1
) as ttt WHERE savedailychangetype = 1

-- Consider creating a view or materialized table for this complex query

---

๐Ÿ› Common Issues & Troubleshooting

1. Unbalanced Cash Flow

Issue: Net cash/bank values don't match actual balances

Cause: Missing transactions or duplicate counting

Debug Steps:

1. Check for unrecorded transactions

2. Verify date range includes all relevant periods

3. Look for duplicate entries in savedaily/accountmovement

2. Date Range Issues

Issue: Unexpected results with date filtering

Cause: Time zone handling or business day logic

Fix:

// Ensure proper date formatting
if (!empty($startDate)) $startDate .= ' 00:00:00';
if (!empty($endDate)) $endDate .= ' 23:59:59';

3. Transfer Discrepancies

Issue: Transfer amounts don't balance between cash and bank

Cause: Different transfer types or missing records

Verification:

-- Verify all transfers are recorded on both sides
SELECT type, SUM(cashtransferamount) 
FROM cashtransfer 
WHERE conditions = 0 
GROUP BY type;

---

๐Ÿงช Testing Scenarios

Test Case 1: Basic Cash Flow Balance

1. Record known cash transactions
2. Record known bank transactions  
3. Run report for test period
4. Verify inflows - outflows = expected net position

Test Case 2: Transfer Verification

1. Create cash-to-bank transfer
2. Run report
3. Verify transfer reduces cash net and increases bank net by same amount

Test Case 3: Date Range Filtering

1. Create transactions across multiple days
2. Run report for partial period
3. Verify only transactions in range are included

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur